Fix save keyring, improve signature verification
This commit is contained in:
@@ -19,6 +19,7 @@
|
|||||||
package org.sufficientlysecure.keychain.pgp;
|
package org.sufficientlysecure.keychain.pgp;
|
||||||
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
|
import android.net.Uri;
|
||||||
|
|
||||||
import org.openintents.openpgp.OpenPgpSignatureResult;
|
import org.openintents.openpgp.OpenPgpSignatureResult;
|
||||||
import org.spongycastle.bcpg.ArmoredInputStream;
|
import org.spongycastle.bcpg.ArmoredInputStream;
|
||||||
@@ -382,52 +383,44 @@ public class PgpDecryptVerify {
|
|||||||
currentProgress += 10;
|
currentProgress += 10;
|
||||||
}
|
}
|
||||||
|
|
||||||
long signatureKeyId = 0;
|
|
||||||
if (dataChunk instanceof PGPOnePassSignatureList) {
|
if (dataChunk instanceof PGPOnePassSignatureList) {
|
||||||
updateProgress(R.string.progress_processing_signature, currentProgress, 100);
|
updateProgress(R.string.progress_processing_signature, currentProgress, 100);
|
||||||
|
|
||||||
signatureResult = new OpenPgpSignatureResult();
|
signatureResult = new OpenPgpSignatureResult();
|
||||||
PGPOnePassSignatureList sigList = (PGPOnePassSignatureList) dataChunk;
|
PGPOnePassSignatureList sigList = (PGPOnePassSignatureList) dataChunk;
|
||||||
|
Long masterKeyId = null;
|
||||||
for (int i = 0; i < sigList.size(); ++i) {
|
for (int i = 0; i < sigList.size(); ++i) {
|
||||||
signature = sigList.get(i);
|
|
||||||
|
|
||||||
// TODO: rework this code, seems wonky!
|
|
||||||
try {
|
try {
|
||||||
signatureKey = ProviderHelper
|
Uri uri = KeyRings.buildUnifiedKeyRingsFindBySubkeyUri(
|
||||||
.getPGPPublicKeyRingWithKeyId(mContext, signature.getKeyID()).getPublicKey();
|
Long.toString(sigList.get(i).getKeyID()));
|
||||||
|
masterKeyId = ProviderHelper.getMasterKeyId(mContext, uri);
|
||||||
|
signatureIndex = i;
|
||||||
} catch (ProviderHelper.NotFoundException e) {
|
} catch (ProviderHelper.NotFoundException e) {
|
||||||
Log.d(Constants.TAG, "key not found!");
|
Log.d(Constants.TAG, "key not found!");
|
||||||
}
|
}
|
||||||
if (signatureKeyId == 0) {
|
|
||||||
signatureKeyId = signature.getKeyID();
|
|
||||||
}
|
|
||||||
if (signatureKey == null) {
|
|
||||||
signature = null;
|
|
||||||
} else {
|
|
||||||
signatureIndex = i;
|
|
||||||
signatureKeyId = signature.getKeyID();
|
|
||||||
String userId = null;
|
|
||||||
try {
|
|
||||||
PGPPublicKeyRing signKeyRing = ProviderHelper.getPGPPublicKeyRingWithKeyId(
|
|
||||||
mContext, signatureKeyId);
|
|
||||||
userId = PgpKeyHelper.getMainUserId(signKeyRing.getPublicKey());
|
|
||||||
} catch (ProviderHelper.NotFoundException e) {
|
|
||||||
Log.d(Constants.TAG, "key not found!");
|
|
||||||
}
|
|
||||||
signatureResult.setUserId(userId);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
signatureResult.setKeyId(signatureKeyId);
|
if(masterKeyId == null) {
|
||||||
|
try {
|
||||||
|
signatureKey = ProviderHelper
|
||||||
|
.getPGPPublicKeyRing(mContext, masterKeyId).getPublicKey();
|
||||||
|
} catch (ProviderHelper.NotFoundException e) {
|
||||||
|
// can't happen
|
||||||
|
}
|
||||||
|
|
||||||
if (signature != null) {
|
signature = sigList.get(signatureIndex);
|
||||||
|
signatureResult.setUserId(PgpKeyHelper.getMainUserId(signatureKey));
|
||||||
|
signatureResult.setKeyId(signature.getKeyID());
|
||||||
JcaPGPContentVerifierBuilderProvider contentVerifierBuilderProvider =
|
JcaPGPContentVerifierBuilderProvider contentVerifierBuilderProvider =
|
||||||
new JcaPGPContentVerifierBuilderProvider()
|
new JcaPGPContentVerifierBuilderProvider()
|
||||||
.setProvider(Constants.BOUNCY_CASTLE_PROVIDER_NAME);
|
.setProvider(Constants.BOUNCY_CASTLE_PROVIDER_NAME);
|
||||||
|
|
||||||
signature.init(contentVerifierBuilderProvider, signatureKey);
|
signature.init(contentVerifierBuilderProvider, signatureKey);
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
if(!sigList.isEmpty()) {
|
||||||
|
signatureResult.setKeyId(sigList.get(0).getKeyID());
|
||||||
|
}
|
||||||
|
|
||||||
Log.d(Constants.TAG, "SIGNATURE_UNKNOWN_PUB_KEY");
|
Log.d(Constants.TAG, "SIGNATURE_UNKNOWN_PUB_KEY");
|
||||||
signatureResult.setStatus(OpenPgpSignatureResult.SIGNATURE_UNKNOWN_PUB_KEY);
|
signatureResult.setStatus(OpenPgpSignatureResult.SIGNATURE_UNKNOWN_PUB_KEY);
|
||||||
}
|
}
|
||||||
@@ -500,7 +493,7 @@ public class PgpDecryptVerify {
|
|||||||
boolean validSignature = signature.verify(messageSignature);
|
boolean validSignature = signature.verify(messageSignature);
|
||||||
|
|
||||||
// TODO: implement CERTIFIED!
|
// TODO: implement CERTIFIED!
|
||||||
if (validKeyBinding & validSignature) {
|
if (validKeyBinding && validSignature) {
|
||||||
Log.d(Constants.TAG, "SIGNATURE_SUCCESS_UNCERTIFIED");
|
Log.d(Constants.TAG, "SIGNATURE_SUCCESS_UNCERTIFIED");
|
||||||
signatureResult.setStatus(OpenPgpSignatureResult.SIGNATURE_SUCCESS_UNCERTIFIED);
|
signatureResult.setStatus(OpenPgpSignatureResult.SIGNATURE_SUCCESS_UNCERTIFIED);
|
||||||
} else {
|
} else {
|
||||||
@@ -654,7 +647,7 @@ public class PgpDecryptVerify {
|
|||||||
boolean validKeyBinding = verifyKeyBinding(mContext, signature, signatureKey);
|
boolean validKeyBinding = verifyKeyBinding(mContext, signature, signatureKey);
|
||||||
boolean validSignature = signature.verify();
|
boolean validSignature = signature.verify();
|
||||||
|
|
||||||
if (validKeyBinding & validSignature) {
|
if (validKeyBinding && validSignature) {
|
||||||
Log.d(Constants.TAG, "SIGNATURE_SUCCESS_UNCERTIFIED");
|
Log.d(Constants.TAG, "SIGNATURE_SUCCESS_UNCERTIFIED");
|
||||||
signatureResult.setStatus(OpenPgpSignatureResult.SIGNATURE_SUCCESS_UNCERTIFIED);
|
signatureResult.setStatus(OpenPgpSignatureResult.SIGNATURE_SUCCESS_UNCERTIFIED);
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@@ -18,8 +18,6 @@
|
|||||||
|
|
||||||
package org.sufficientlysecure.keychain.pgp;
|
package org.sufficientlysecure.keychain.pgp;
|
||||||
|
|
||||||
import android.util.Pair;
|
|
||||||
|
|
||||||
import org.spongycastle.bcpg.CompressionAlgorithmTags;
|
import org.spongycastle.bcpg.CompressionAlgorithmTags;
|
||||||
import org.spongycastle.bcpg.HashAlgorithmTags;
|
import org.spongycastle.bcpg.HashAlgorithmTags;
|
||||||
import org.spongycastle.bcpg.SymmetricKeyAlgorithmTags;
|
import org.spongycastle.bcpg.SymmetricKeyAlgorithmTags;
|
||||||
@@ -220,29 +218,26 @@ public class PgpKeyOperation {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private Pair<PGPSecretKeyRing, PGPPublicKeyRing> buildNewSecretKey(
|
public Pair<PGPSecretKeyRing, PGPPublicKeyRing> buildNewSecretKey(
|
||||||
ArrayList<String> userIds, ArrayList<PGPSecretKey> keys,
|
SaveKeyringParcel saveParcel)
|
||||||
ArrayList<GregorianCalendar> keysExpiryDates,
|
|
||||||
ArrayList<Integer> keysUsages,
|
|
||||||
String newPassphrase, String oldPassphrase)
|
|
||||||
throws PgpGeneralMsgIdException, PGPException, SignatureException, IOException {
|
throws PgpGeneralMsgIdException, PGPException, SignatureException, IOException {
|
||||||
|
|
||||||
int usageId = keysUsages.get(0);
|
int usageId = saveParcel.keysUsages.get(0);
|
||||||
boolean canSign;
|
boolean canSign;
|
||||||
String mainUserId = userIds.get(0);
|
String mainUserId = saveParcel.userIds.get(0);
|
||||||
|
|
||||||
PGPSecretKey masterKey = keys.get(0);
|
PGPSecretKey masterKey = saveParcel.keys.get(0);
|
||||||
|
|
||||||
// this removes all userIds and certifications previously attached to the masterPublicKey
|
// this removes all userIds and certifications previously attached to the masterPublicKey
|
||||||
PGPPublicKey masterPublicKey = masterKey.getPublicKey();
|
PGPPublicKey masterPublicKey = masterKey.getPublicKey();
|
||||||
|
|
||||||
PBESecretKeyDecryptor keyDecryptor = new JcePBESecretKeyDecryptorBuilder().setProvider(
|
PBESecretKeyDecryptor keyDecryptor = new JcePBESecretKeyDecryptorBuilder().setProvider(
|
||||||
Constants.BOUNCY_CASTLE_PROVIDER_NAME).build(oldPassphrase.toCharArray());
|
Constants.BOUNCY_CASTLE_PROVIDER_NAME).build(saveParcel.oldPassphrase.toCharArray());
|
||||||
PGPPrivateKey masterPrivateKey = masterKey.extractPrivateKey(keyDecryptor);
|
PGPPrivateKey masterPrivateKey = masterKey.extractPrivateKey(keyDecryptor);
|
||||||
|
|
||||||
updateProgress(R.string.progress_certifying_master_key, 20, 100);
|
updateProgress(R.string.progress_certifying_master_key, 20, 100);
|
||||||
|
|
||||||
for (String userId : userIds) {
|
for (String userId : saveParcel.userIds) {
|
||||||
PGPContentSignerBuilder signerBuilder = new JcaPGPContentSignerBuilder(
|
PGPContentSignerBuilder signerBuilder = new JcaPGPContentSignerBuilder(
|
||||||
masterPublicKey.getAlgorithm(), HashAlgorithmTags.SHA1)
|
masterPublicKey.getAlgorithm(), HashAlgorithmTags.SHA1)
|
||||||
.setProvider(Constants.BOUNCY_CASTLE_PROVIDER_NAME);
|
.setProvider(Constants.BOUNCY_CASTLE_PROVIDER_NAME);
|
||||||
@@ -265,10 +260,10 @@ public class PgpKeyOperation {
|
|||||||
hashedPacketsGen.setPreferredHashAlgorithms(true, PREFERRED_HASH_ALGORITHMS);
|
hashedPacketsGen.setPreferredHashAlgorithms(true, PREFERRED_HASH_ALGORITHMS);
|
||||||
hashedPacketsGen.setPreferredCompressionAlgorithms(true, PREFERRED_COMPRESSION_ALGORITHMS);
|
hashedPacketsGen.setPreferredCompressionAlgorithms(true, PREFERRED_COMPRESSION_ALGORITHMS);
|
||||||
|
|
||||||
if (keysExpiryDates.get(0) != null) {
|
if (saveParcel.keysExpiryDates.get(0) != null) {
|
||||||
GregorianCalendar creationDate = new GregorianCalendar(TimeZone.getTimeZone("UTC"));
|
GregorianCalendar creationDate = new GregorianCalendar(TimeZone.getTimeZone("UTC"));
|
||||||
creationDate.setTime(masterPublicKey.getCreationTime());
|
creationDate.setTime(masterPublicKey.getCreationTime());
|
||||||
GregorianCalendar expiryDate = keysExpiryDates.get(0);
|
GregorianCalendar expiryDate = saveParcel.keysExpiryDates.get(0);
|
||||||
//note that the below, (a/c) - (b/c) is *not* the same as (a - b) /c
|
//note that the below, (a/c) - (b/c) is *not* the same as (a - b) /c
|
||||||
//here we purposefully ignore partial days in each date - long type has no fractional part!
|
//here we purposefully ignore partial days in each date - long type has no fractional part!
|
||||||
long numDays = (expiryDate.getTimeInMillis() / 86400000) -
|
long numDays = (expiryDate.getTimeInMillis() / 86400000) -
|
||||||
@@ -295,7 +290,7 @@ public class PgpKeyOperation {
|
|||||||
PBESecretKeyEncryptor keyEncryptor = new JcePBESecretKeyEncryptorBuilder(
|
PBESecretKeyEncryptor keyEncryptor = new JcePBESecretKeyEncryptorBuilder(
|
||||||
PGPEncryptedData.CAST5, sha1Calc)
|
PGPEncryptedData.CAST5, sha1Calc)
|
||||||
.setProvider(Constants.BOUNCY_CASTLE_PROVIDER_NAME).build(
|
.setProvider(Constants.BOUNCY_CASTLE_PROVIDER_NAME).build(
|
||||||
newPassphrase.toCharArray());
|
saveParcel.newPassphrase.toCharArray());
|
||||||
|
|
||||||
PGPKeyRingGenerator keyGen = new PGPKeyRingGenerator(PGPSignature.POSITIVE_CERTIFICATION,
|
PGPKeyRingGenerator keyGen = new PGPKeyRingGenerator(PGPSignature.POSITIVE_CERTIFICATION,
|
||||||
masterKeyPair, mainUserId, sha1Calc, hashedPacketsGen.generate(),
|
masterKeyPair, mainUserId, sha1Calc, hashedPacketsGen.generate(),
|
||||||
@@ -303,15 +298,15 @@ public class PgpKeyOperation {
|
|||||||
|
|
||||||
updateProgress(R.string.progress_adding_sub_keys, 40, 100);
|
updateProgress(R.string.progress_adding_sub_keys, 40, 100);
|
||||||
|
|
||||||
for (int i = 1; i < keys.size(); ++i) {
|
for (int i = 1; i < saveParcel.keys.size(); ++i) {
|
||||||
updateProgress(40 + 40 * (i - 1) / (keys.size() - 1), 100);
|
updateProgress(40 + 40 * (i - 1) / (saveParcel.keys.size() - 1), 100);
|
||||||
|
|
||||||
PGPSecretKey subKey = keys.get(i);
|
PGPSecretKey subKey = saveParcel.keys.get(i);
|
||||||
PGPPublicKey subPublicKey = subKey.getPublicKey();
|
PGPPublicKey subPublicKey = subKey.getPublicKey();
|
||||||
|
|
||||||
PBESecretKeyDecryptor keyDecryptor2 = new JcePBESecretKeyDecryptorBuilder()
|
PBESecretKeyDecryptor keyDecryptor2 = new JcePBESecretKeyDecryptorBuilder()
|
||||||
.setProvider(Constants.BOUNCY_CASTLE_PROVIDER_NAME).build(
|
.setProvider(Constants.BOUNCY_CASTLE_PROVIDER_NAME).build(
|
||||||
oldPassphrase.toCharArray());
|
saveParcel.oldPassphrase.toCharArray());
|
||||||
PGPPrivateKey subPrivateKey = subKey.extractPrivateKey(keyDecryptor2);
|
PGPPrivateKey subPrivateKey = subKey.extractPrivateKey(keyDecryptor2);
|
||||||
|
|
||||||
// TODO: now used without algorithm and creation time?! (APG 1)
|
// TODO: now used without algorithm and creation time?! (APG 1)
|
||||||
@@ -320,7 +315,7 @@ public class PgpKeyOperation {
|
|||||||
hashedPacketsGen = new PGPSignatureSubpacketGenerator();
|
hashedPacketsGen = new PGPSignatureSubpacketGenerator();
|
||||||
unhashedPacketsGen = new PGPSignatureSubpacketGenerator();
|
unhashedPacketsGen = new PGPSignatureSubpacketGenerator();
|
||||||
|
|
||||||
usageId = keysUsages.get(i);
|
usageId = saveParcel.keysUsages.get(i);
|
||||||
canSign = (usageId & KeyFlags.SIGN_DATA) > 0; //todo - separate function for this
|
canSign = (usageId & KeyFlags.SIGN_DATA) > 0; //todo - separate function for this
|
||||||
if (canSign) {
|
if (canSign) {
|
||||||
Date todayDate = new Date(); //both sig times the same
|
Date todayDate = new Date(); //both sig times the same
|
||||||
@@ -340,10 +335,10 @@ public class PgpKeyOperation {
|
|||||||
}
|
}
|
||||||
hashedPacketsGen.setKeyFlags(false, usageId);
|
hashedPacketsGen.setKeyFlags(false, usageId);
|
||||||
|
|
||||||
if (keysExpiryDates.get(i) != null) {
|
if (saveParcel.keysExpiryDates.get(i) != null) {
|
||||||
GregorianCalendar creationDate = new GregorianCalendar(TimeZone.getTimeZone("UTC"));
|
GregorianCalendar creationDate = new GregorianCalendar(TimeZone.getTimeZone("UTC"));
|
||||||
creationDate.setTime(subPublicKey.getCreationTime());
|
creationDate.setTime(subPublicKey.getCreationTime());
|
||||||
GregorianCalendar expiryDate = keysExpiryDates.get(i);
|
GregorianCalendar expiryDate = saveParcel.keysExpiryDates.get(i);
|
||||||
//note that the below, (a/c) - (b/c) is *not* the same as (a - b) /c
|
//note that the below, (a/c) - (b/c) is *not* the same as (a - b) /c
|
||||||
//here we purposefully ignore partial days in each date - long type has no fractional part!
|
//here we purposefully ignore partial days in each date - long type has no fractional part!
|
||||||
long numDays = (expiryDate.getTimeInMillis() / 86400000) -
|
long numDays = (expiryDate.getTimeInMillis() / 86400000) -
|
||||||
@@ -383,11 +378,6 @@ public class PgpKeyOperation {
|
|||||||
saveParcel.newPassphrase = "";
|
saveParcel.newPassphrase = "";
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mKR == null) {
|
|
||||||
return buildNewSecretKey(saveParcel.userIDs, saveParcel.keys, saveParcel.keysExpiryDates,
|
|
||||||
saveParcel.keysUsages, saveParcel.newPassphrase, saveParcel.oldPassphrase); //new Keyring
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
IDs - NB This might not need to happen later, if we change the way the primary ID is chosen
|
IDs - NB This might not need to happen later, if we change the way the primary ID is chosen
|
||||||
remove deleted ids
|
remove deleted ids
|
||||||
@@ -421,7 +411,7 @@ public class PgpKeyOperation {
|
|||||||
|
|
||||||
int usageId = saveParcel.keysUsages.get(0);
|
int usageId = saveParcel.keysUsages.get(0);
|
||||||
boolean canSign;
|
boolean canSign;
|
||||||
String mainUserId = saveParcel.userIDs.get(0);
|
String mainUserId = saveParcel.userIds.get(0);
|
||||||
|
|
||||||
PBESecretKeyDecryptor keyDecryptor = new JcePBESecretKeyDecryptorBuilder().setProvider(
|
PBESecretKeyDecryptor keyDecryptor = new JcePBESecretKeyDecryptorBuilder().setProvider(
|
||||||
Constants.BOUNCY_CASTLE_PROVIDER_NAME).build(saveParcel.oldPassphrase.toCharArray());
|
Constants.BOUNCY_CASTLE_PROVIDER_NAME).build(saveParcel.oldPassphrase.toCharArray());
|
||||||
@@ -465,10 +455,10 @@ public class PgpKeyOperation {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (saveParcel.primaryIDChanged ||
|
if (saveParcel.primaryIDChanged ||
|
||||||
!saveParcel.originalIDs.get(0).equals(saveParcel.userIDs.get(0))) {
|
!saveParcel.originalIDs.get(0).equals(saveParcel.userIds.get(0))) {
|
||||||
anyIDChanged = true;
|
anyIDChanged = true;
|
||||||
ArrayList<Pair<String, PGPSignature>> sigList = new ArrayList<Pair<String, PGPSignature>>();
|
ArrayList<Pair<String, PGPSignature>> sigList = new ArrayList<Pair<String, PGPSignature>>();
|
||||||
for (String userId : saveParcel.userIDs) {
|
for (String userId : saveParcel.userIds) {
|
||||||
String origID = saveParcel.originalIDs.get(userIDIndex);
|
String origID = saveParcel.originalIDs.get(userIDIndex);
|
||||||
if (origID.equals(userId) && !saveParcel.newIDs[userIDIndex] &&
|
if (origID.equals(userId) && !saveParcel.newIDs[userIDIndex] &&
|
||||||
!userId.equals(saveParcel.originalPrimaryID) && userIDIndex != 0) {
|
!userId.equals(saveParcel.originalPrimaryID) && userIDIndex != 0) {
|
||||||
@@ -502,7 +492,7 @@ public class PgpKeyOperation {
|
|||||||
PGPPublicKey.addCertification(masterPublicKey, toAdd.first, toAdd.second);
|
PGPPublicKey.addCertification(masterPublicKey, toAdd.first, toAdd.second);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
for (String userId : saveParcel.userIDs) {
|
for (String userId : saveParcel.userIds) {
|
||||||
String origID = saveParcel.originalIDs.get(userIDIndex);
|
String origID = saveParcel.originalIDs.get(userIDIndex);
|
||||||
if (!origID.equals(userId) || saveParcel.newIDs[userIDIndex]) {
|
if (!origID.equals(userId) || saveParcel.newIDs[userIDIndex]) {
|
||||||
anyIDChanged = true;
|
anyIDChanged = true;
|
||||||
@@ -530,7 +520,7 @@ public class PgpKeyOperation {
|
|||||||
ArrayList<Pair<String, PGPSignature>> sigList = new ArrayList<Pair<String, PGPSignature>>();
|
ArrayList<Pair<String, PGPSignature>> sigList = new ArrayList<Pair<String, PGPSignature>>();
|
||||||
if (saveParcel.moddedKeys[0]) {
|
if (saveParcel.moddedKeys[0]) {
|
||||||
userIDIndex = 0;
|
userIDIndex = 0;
|
||||||
for (String userId : saveParcel.userIDs) {
|
for (String userId : saveParcel.userIds) {
|
||||||
String origID = saveParcel.originalIDs.get(userIDIndex);
|
String origID = saveParcel.originalIDs.get(userIDIndex);
|
||||||
if (!(origID.equals(saveParcel.originalPrimaryID) && !saveParcel.primaryIDChanged)) {
|
if (!(origID.equals(saveParcel.originalPrimaryID) && !saveParcel.primaryIDChanged)) {
|
||||||
Iterator<PGPSignature> sigs = masterPublicKey.getSignaturesForID(userId);
|
Iterator<PGPSignature> sigs = masterPublicKey.getSignaturesForID(userId);
|
||||||
|
|||||||
@@ -480,9 +480,9 @@ public class KeychainIntentService extends IntentService
|
|||||||
} else if (ACTION_SAVE_KEYRING.equals(action)) {
|
} else if (ACTION_SAVE_KEYRING.equals(action)) {
|
||||||
try {
|
try {
|
||||||
/* Input */
|
/* Input */
|
||||||
SaveKeyringParcel saveParams = data.getParcelable(SAVE_KEYRING_PARCEL);
|
SaveKeyringParcel saveParcel = data.getParcelable(SAVE_KEYRING_PARCEL);
|
||||||
String oldPassphrase = saveParams.oldPassphrase;
|
String oldPassphrase = saveParcel.oldPassphrase;
|
||||||
String newPassphrase = saveParams.newPassphrase;
|
String newPassphrase = saveParcel.newPassphrase;
|
||||||
boolean canSign = true;
|
boolean canSign = true;
|
||||||
|
|
||||||
if (data.containsKey(SAVE_KEYRING_CAN_SIGN)) {
|
if (data.containsKey(SAVE_KEYRING_CAN_SIGN)) {
|
||||||
@@ -493,7 +493,7 @@ public class KeychainIntentService extends IntentService
|
|||||||
newPassphrase = oldPassphrase;
|
newPassphrase = oldPassphrase;
|
||||||
}
|
}
|
||||||
|
|
||||||
long masterKeyId = saveParams.keys.get(0).getKeyID();
|
long masterKeyId = saveParcel.keys.get(0).getKeyID();
|
||||||
|
|
||||||
/* Operation */
|
/* Operation */
|
||||||
if (!canSign) {
|
if (!canSign) {
|
||||||
@@ -506,10 +506,16 @@ public class KeychainIntentService extends IntentService
|
|||||||
setProgress(R.string.progress_done, 100, 100);
|
setProgress(R.string.progress_done, 100, 100);
|
||||||
} else {
|
} else {
|
||||||
PgpKeyOperation keyOperations = new PgpKeyOperation(new ProgressScaler(this, 0, 90, 100));
|
PgpKeyOperation keyOperations = new PgpKeyOperation(new ProgressScaler(this, 0, 90, 100));
|
||||||
PGPSecretKeyRing privkey = ProviderHelper.getPGPSecretKeyRing(this, masterKeyId);
|
PgpKeyOperation.Pair<PGPSecretKeyRing, PGPPublicKeyRing> pair;
|
||||||
PGPPublicKeyRing pubkey = ProviderHelper.getPGPPublicKeyRing(this, masterKeyId);
|
try {
|
||||||
PgpKeyOperation.Pair<PGPSecretKeyRing,PGPPublicKeyRing> pair =
|
PGPSecretKeyRing privkey = ProviderHelper.getPGPSecretKeyRing(this, masterKeyId);
|
||||||
keyOperations.buildSecretKey(privkey, pubkey, saveParams);
|
PGPPublicKeyRing pubkey = ProviderHelper.getPGPPublicKeyRing(this, masterKeyId);
|
||||||
|
|
||||||
|
pair = keyOperations.buildSecretKey(privkey, pubkey, saveParcel); // edit existing
|
||||||
|
} catch (ProviderHelper.NotFoundException e) {
|
||||||
|
pair = keyOperations.buildNewSecretKey(saveParcel); //new Keyring
|
||||||
|
}
|
||||||
|
|
||||||
setProgress(R.string.progress_saving_key_ring, 90, 100);
|
setProgress(R.string.progress_saving_key_ring, 90, 100);
|
||||||
// save the pair
|
// save the pair
|
||||||
ProviderHelper.saveKeyRing(this, pair.second, pair.first);
|
ProviderHelper.saveKeyRing(this, pair.second, pair.first);
|
||||||
@@ -654,16 +660,16 @@ public class KeychainIntentService extends IntentService
|
|||||||
ArrayList<Long> secretMasterKeyIds = new ArrayList<Long>();
|
ArrayList<Long> secretMasterKeyIds = new ArrayList<Long>();
|
||||||
|
|
||||||
String selection = null;
|
String selection = null;
|
||||||
if(!exportAll) {
|
if (!exportAll) {
|
||||||
selection = KeychainDatabase.Tables.KEYS + "." + KeyRings.MASTER_KEY_ID + " IN( ";
|
selection = KeychainDatabase.Tables.KEYS + "." + KeyRings.MASTER_KEY_ID + " IN( ";
|
||||||
for(long l : masterKeyIds) {
|
for (long l : masterKeyIds) {
|
||||||
selection += Long.toString(l) + ",";
|
selection += Long.toString(l) + ",";
|
||||||
}
|
}
|
||||||
selection = selection.substring(0, selection.length()-1) + " )";
|
selection = selection.substring(0, selection.length() - 1) + " )";
|
||||||
}
|
}
|
||||||
|
|
||||||
Cursor cursor = getContentResolver().query(KeyRings.buildUnifiedKeyRingsUri(),
|
Cursor cursor = getContentResolver().query(KeyRings.buildUnifiedKeyRingsUri(),
|
||||||
new String[]{ KeyRings.MASTER_KEY_ID, KeyRings.HAS_SECRET },
|
new String[]{KeyRings.MASTER_KEY_ID, KeyRings.HAS_SECRET},
|
||||||
selection, null, null);
|
selection, null, null);
|
||||||
try {
|
try {
|
||||||
cursor.moveToFirst();
|
cursor.moveToFirst();
|
||||||
@@ -671,9 +677,9 @@ public class KeychainIntentService extends IntentService
|
|||||||
// export public either way
|
// export public either way
|
||||||
publicMasterKeyIds.add(cursor.getLong(0));
|
publicMasterKeyIds.add(cursor.getLong(0));
|
||||||
// add secret if available (and requested)
|
// add secret if available (and requested)
|
||||||
if(exportSecret && cursor.getInt(1) != 0)
|
if (exportSecret && cursor.getInt(1) != 0)
|
||||||
secretMasterKeyIds.add(cursor.getLong(0));
|
secretMasterKeyIds.add(cursor.getLong(0));
|
||||||
} while(cursor.moveToNext());
|
} while (cursor.moveToNext());
|
||||||
} finally {
|
} finally {
|
||||||
cursor.close();
|
cursor.close();
|
||||||
}
|
}
|
||||||
@@ -757,13 +763,13 @@ public class KeychainIntentService extends IntentService
|
|||||||
// verify downloaded key by comparing fingerprints
|
// verify downloaded key by comparing fingerprints
|
||||||
if (entry.getFingerPrintHex() != null) {
|
if (entry.getFingerPrintHex() != null) {
|
||||||
String downloadedKeyFp = PgpKeyHelper.convertFingerprintToHex(
|
String downloadedKeyFp = PgpKeyHelper.convertFingerprintToHex(
|
||||||
downloadedKey.getPublicKey().getFingerprint());
|
downloadedKey.getPublicKey().getFingerprint());
|
||||||
if (downloadedKeyFp.equals(entry.getFingerPrintHex())) {
|
if (downloadedKeyFp.equals(entry.getFingerPrintHex())) {
|
||||||
Log.d(Constants.TAG, "fingerprint of downloaded key is the same as " +
|
Log.d(Constants.TAG, "fingerprint of downloaded key is the same as " +
|
||||||
"the requested fingerprint!");
|
"the requested fingerprint!");
|
||||||
} else {
|
} else {
|
||||||
throw new PgpGeneralException("fingerprint of downloaded key is " +
|
throw new PgpGeneralException("fingerprint of downloaded key is " +
|
||||||
"NOT the same as the requested fingerprint!");
|
"NOT the same as the requested fingerprint!");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -29,7 +29,7 @@ import java.util.GregorianCalendar;
|
|||||||
|
|
||||||
public class SaveKeyringParcel implements Parcelable {
|
public class SaveKeyringParcel implements Parcelable {
|
||||||
|
|
||||||
public ArrayList<String> userIDs;
|
public ArrayList<String> userIds;
|
||||||
public ArrayList<String> originalIDs;
|
public ArrayList<String> originalIDs;
|
||||||
public ArrayList<String> deletedIDs;
|
public ArrayList<String> deletedIDs;
|
||||||
public boolean[] newIDs;
|
public boolean[] newIDs;
|
||||||
@@ -47,7 +47,7 @@ public class SaveKeyringParcel implements Parcelable {
|
|||||||
public SaveKeyringParcel() {}
|
public SaveKeyringParcel() {}
|
||||||
|
|
||||||
private SaveKeyringParcel(Parcel source) {
|
private SaveKeyringParcel(Parcel source) {
|
||||||
userIDs = (ArrayList<String>) source.readSerializable();
|
userIds = (ArrayList<String>) source.readSerializable();
|
||||||
originalIDs = (ArrayList<String>) source.readSerializable();
|
originalIDs = (ArrayList<String>) source.readSerializable();
|
||||||
deletedIDs = (ArrayList<String>) source.readSerializable();
|
deletedIDs = (ArrayList<String>) source.readSerializable();
|
||||||
newIDs = source.createBooleanArray();
|
newIDs = source.createBooleanArray();
|
||||||
@@ -70,7 +70,7 @@ public class SaveKeyringParcel implements Parcelable {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void writeToParcel(Parcel destination, int flags) {
|
public void writeToParcel(Parcel destination, int flags) {
|
||||||
destination.writeSerializable(userIDs); //might not be the best method to store.
|
destination.writeSerializable(userIds); //might not be the best method to store.
|
||||||
destination.writeSerializable(originalIDs);
|
destination.writeSerializable(originalIDs);
|
||||||
destination.writeSerializable(deletedIDs);
|
destination.writeSerializable(deletedIDs);
|
||||||
destination.writeBooleanArray(newIDs);
|
destination.writeBooleanArray(newIDs);
|
||||||
|
|||||||
@@ -568,7 +568,7 @@ public class EditKeyActivity extends ActionBarActivity implements EditorListener
|
|||||||
intent.setAction(KeychainIntentService.ACTION_SAVE_KEYRING);
|
intent.setAction(KeychainIntentService.ACTION_SAVE_KEYRING);
|
||||||
|
|
||||||
SaveKeyringParcel saveParams = new SaveKeyringParcel();
|
SaveKeyringParcel saveParams = new SaveKeyringParcel();
|
||||||
saveParams.userIDs = getUserIds(mUserIdsView);
|
saveParams.userIds = getUserIds(mUserIdsView);
|
||||||
saveParams.originalIDs = mUserIdsView.getOriginalIDs();
|
saveParams.originalIDs = mUserIdsView.getOriginalIDs();
|
||||||
saveParams.deletedIDs = mUserIdsView.getDeletedIDs();
|
saveParams.deletedIDs = mUserIdsView.getDeletedIDs();
|
||||||
saveParams.newIDs = toPrimitiveArray(mUserIdsView.getNewIDFlags());
|
saveParams.newIDs = toPrimitiveArray(mUserIdsView.getNewIDFlags());
|
||||||
|
|||||||
@@ -24,6 +24,7 @@ import android.nfc.NfcAdapter;
|
|||||||
import android.nfc.NfcAdapter.CreateNdefMessageCallback;
|
import android.nfc.NfcAdapter.CreateNdefMessageCallback;
|
||||||
import android.nfc.NfcAdapter.OnNdefPushCompleteCallback;
|
import android.nfc.NfcAdapter.OnNdefPushCompleteCallback;
|
||||||
import android.nfc.NfcEvent;
|
import android.nfc.NfcEvent;
|
||||||
|
import android.os.AsyncTask;
|
||||||
import android.os.Build;
|
import android.os.Build;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.os.Handler;
|
import android.os.Handler;
|
||||||
@@ -62,13 +63,29 @@ public class ViewKeyActivityJB extends ViewKeyActivity implements CreateNdefMess
|
|||||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
|
||||||
// Check for available NFC Adapter
|
// Check for available NFC Adapter
|
||||||
mNfcAdapter = NfcAdapter.getDefaultAdapter(this);
|
mNfcAdapter = NfcAdapter.getDefaultAdapter(this);
|
||||||
if (mNfcAdapter != null) {
|
|
||||||
// init nfc
|
// AsyncTask<NfcAdapter, Void, Void> registerTask =
|
||||||
// Register callback to set NDEF message
|
// new AsyncTask<NfcAdapter, Void, Void>() {
|
||||||
mNfcAdapter.setNdefPushMessageCallback(this, this);
|
// protected Void doInBackground(NfcAdapter... adapter) {
|
||||||
// Register callback to listen for message-sent success
|
// if (adapter != null) {
|
||||||
mNfcAdapter.setOnNdefPushCompleteCallback(this, this);
|
// // init nfc
|
||||||
}
|
// // Register callback to set NDEF message
|
||||||
|
// adapter.setNdefPushMessageCallback(ViewKeyActivityJB.this, ViewKeyActivityJB.this);
|
||||||
|
// // Register callback to listen for message-sent success
|
||||||
|
// adapter.setOnNdefPushCompleteCallback(this, this);
|
||||||
|
// }
|
||||||
|
// return null;
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// protected void onProgressUpdate() {
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// protected void onPostExecute(Void result) {
|
||||||
|
//
|
||||||
|
// }
|
||||||
|
// };
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -83,20 +100,21 @@ public class ViewKeyActivityJB extends ViewKeyActivity implements CreateNdefMess
|
|||||||
* guarantee that this activity starts when receiving a beamed message. For now, this code
|
* guarantee that this activity starts when receiving a beamed message. For now, this code
|
||||||
* uses the tag dispatch system.
|
* uses the tag dispatch system.
|
||||||
*/
|
*/
|
||||||
try {
|
// try {
|
||||||
// get public keyring as byte array
|
// get public keyring as byte array
|
||||||
mSharedKeyringBytes = ProviderHelper.getPGPKeyRing(this, mDataUri).getEncoded();
|
// event.nfcAdapter.
|
||||||
|
// mSharedKeyringBytes = ProviderHelper.getPGPKeyRing(this, mDataUri).getEncoded();
|
||||||
NdefMessage msg = new NdefMessage(NdefRecord.createMime(Constants.NFC_MIME,
|
//
|
||||||
mSharedKeyringBytes), NdefRecord.createApplicationRecord(Constants.PACKAGE_NAME));
|
// NdefMessage msg = new NdefMessage(NdefRecord.createMime(Constants.NFC_MIME,
|
||||||
return msg;
|
// mSharedKeyringBytes), NdefRecord.createApplicationRecord(Constants.PACKAGE_NAME));
|
||||||
} catch(IOException e) {
|
// return msg;
|
||||||
Log.e(Constants.TAG, "Error parsing keyring", e);
|
// } catch(IOException e) {
|
||||||
|
// Log.e(Constants.TAG, "Error parsing keyring", e);
|
||||||
|
// return null;
|
||||||
|
// } catch (ProviderHelper.NotFoundException e) {
|
||||||
|
// Log.e(Constants.TAG, "key not found!", e);
|
||||||
return null;
|
return null;
|
||||||
} catch (ProviderHelper.NotFoundException e) {
|
// }
|
||||||
Log.e(Constants.TAG, "key not found!", e);
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
Reference in New Issue
Block a user