key edit: fix crash when create date was after expiry date, change from gregorian calendar to calendar with creation from instance, experimental result status for decrypt activity

This commit is contained in:
Dominik Schürmann
2014-04-14 01:11:08 +02:00
parent 55bad4cac7
commit 13ffd2038d
20 changed files with 210 additions and 171 deletions

View File

@@ -600,7 +600,6 @@ public class PgpDecryptVerify {
throw new InvalidDataException();
}
// go through all signatures
// and find out for which signature we have a key in our database
Long masterKeyId = null;

View File

@@ -65,20 +65,21 @@ import java.security.NoSuchProviderException;
import java.security.SecureRandom;
import java.security.SignatureException;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.Iterator;
import java.util.List;
import java.util.TimeZone;
/** This class is the single place where ALL operations that actually modify a PGP public or secret
/**
* This class is the single place where ALL operations that actually modify a PGP public or secret
* key take place.
*
* <p/>
* Note that no android specific stuff should be done here, ie no imports from com.android.
*
* <p/>
* All operations support progress reporting to a ProgressDialogUpdater passed on initialization.
* This indicator may be null.
*
*/
public class PgpKeyOperation {
private ProgressDialogUpdater mProgress;
@@ -129,7 +130,7 @@ public class PgpKeyOperation {
public PGPSecretKey createKey(int algorithmChoice, int keySize, String passphrase,
boolean isMasterKey)
throws NoSuchAlgorithmException, PGPException, NoSuchProviderException,
PgpGeneralMsgIdException, InvalidAlgorithmParameterException {
PgpGeneralMsgIdException, InvalidAlgorithmParameterException {
if (keySize < 512) {
throw new PgpGeneralMsgIdException(R.string.error_key_size_minimum512bit);
@@ -190,13 +191,13 @@ public class PgpKeyOperation {
PGPEncryptedData.CAST5, sha1Calc)
.setProvider(Constants.BOUNCY_CASTLE_PROVIDER_NAME).build(passphrase.toCharArray());
return new PGPSecretKey(keyPair.getPrivateKey(), keyPair.getPublicKey(),
sha1Calc, isMasterKey, keyEncryptor);
return new PGPSecretKey(keyPair.getPrivateKey(), keyPair.getPublicKey(),
sha1Calc, isMasterKey, keyEncryptor);
}
public PGPSecretKeyRing changeSecretKeyPassphrase(PGPSecretKeyRing keyRing, String oldPassphrase,
String newPassphrase)
throws IOException, PGPException, NoSuchProviderException {
String newPassphrase)
throws IOException, PGPException, NoSuchProviderException {
updateProgress(R.string.progress_building_key, 0, 100);
if (oldPassphrase == null) {
@@ -261,13 +262,13 @@ public class PgpKeyOperation {
hashedPacketsGen.setPreferredCompressionAlgorithms(true, PREFERRED_COMPRESSION_ALGORITHMS);
if (saveParcel.keysExpiryDates.get(0) != null) {
GregorianCalendar creationDate = new GregorianCalendar(TimeZone.getTimeZone("UTC"));
Calendar creationDate = Calendar.getInstance(TimeZone.getTimeZone("UTC"));
creationDate.setTime(masterPublicKey.getCreationTime());
GregorianCalendar expiryDate = saveParcel.keysExpiryDates.get(0);
Calendar expiryDate = saveParcel.keysExpiryDates.get(0);
//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!
long numDays = (expiryDate.getTimeInMillis() / 86400000) -
(creationDate.getTimeInMillis() / 86400000);
(creationDate.getTimeInMillis() / 86400000);
if (numDays <= 0) {
throw new PgpGeneralMsgIdException(R.string.error_expiry_must_come_after_creation);
}
@@ -336,13 +337,13 @@ public class PgpKeyOperation {
hashedPacketsGen.setKeyFlags(false, usageId);
if (saveParcel.keysExpiryDates.get(i) != null) {
GregorianCalendar creationDate = new GregorianCalendar(TimeZone.getTimeZone("UTC"));
Calendar creationDate = Calendar.getInstance(TimeZone.getTimeZone("UTC"));
creationDate.setTime(subPublicKey.getCreationTime());
GregorianCalendar expiryDate = saveParcel.keysExpiryDates.get(i);
Calendar expiryDate = saveParcel.keysExpiryDates.get(i);
//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!
long numDays = (expiryDate.getTimeInMillis() / 86400000) -
(creationDate.getTimeInMillis() / 86400000);
(creationDate.getTimeInMillis() / 86400000);
if (numDays <= 0) {
throw new PgpGeneralMsgIdException(R.string.error_expiry_must_come_after_creation);
}
@@ -437,13 +438,13 @@ public class PgpKeyOperation {
hashedPacketsGen.setPreferredCompressionAlgorithms(true, PREFERRED_COMPRESSION_ALGORITHMS);
if (saveParcel.keysExpiryDates.get(0) != null) {
GregorianCalendar creationDate = new GregorianCalendar(TimeZone.getTimeZone("UTC"));
Calendar creationDate = Calendar.getInstance(TimeZone.getTimeZone("UTC"));
creationDate.setTime(masterPublicKey.getCreationTime());
GregorianCalendar expiryDate = saveParcel.keysExpiryDates.get(0);
Calendar expiryDate = saveParcel.keysExpiryDates.get(0);
//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!
long numDays = (expiryDate.getTimeInMillis() / 86400000) -
(creationDate.getTimeInMillis() / 86400000);
(creationDate.getTimeInMillis() / 86400000);
if (numDays <= 0) {
throw new PgpGeneralMsgIdException(R.string.error_expiry_must_come_after_creation);
}
@@ -455,13 +456,13 @@ public class PgpKeyOperation {
}
if (saveParcel.primaryIDChanged ||
!saveParcel.originalIDs.get(0).equals(saveParcel.userIds.get(0))) {
!saveParcel.originalIDs.get(0).equals(saveParcel.userIds.get(0))) {
anyIDChanged = true;
ArrayList<Pair<String, PGPSignature>> sigList = new ArrayList<Pair<String, PGPSignature>>();
for (String userId : saveParcel.userIds) {
String origID = saveParcel.originalIDs.get(userIDIndex);
if (origID.equals(userId) && !saveParcel.newIDs[userIDIndex] &&
!userId.equals(saveParcel.originalPrimaryID) && userIDIndex != 0) {
!userId.equals(saveParcel.originalPrimaryID) && userIDIndex != 0) {
Iterator<PGPSignature> origSigs = masterPublicKey.getSignaturesForID(origID);
// TODO: make sure this iterator only has signatures we are interested in
while (origSigs.hasNext()) {
@@ -489,7 +490,7 @@ public class PgpKeyOperation {
}
for (Pair<String, PGPSignature> toAdd : sigList) {
masterPublicKey =
PGPPublicKey.addCertification(masterPublicKey, toAdd.first, toAdd.second);
PGPPublicKey.addCertification(masterPublicKey, toAdd.first, toAdd.second);
}
} else {
for (String userId : saveParcel.userIds) {
@@ -511,7 +512,7 @@ public class PgpKeyOperation {
masterPublicKey = PGPPublicKey.removeCertification(masterPublicKey, origID);
}
masterPublicKey =
PGPPublicKey.addCertification(masterPublicKey, userId, certification);
PGPPublicKey.addCertification(masterPublicKey, userId, certification);
}
userIDIndex++;
}
@@ -606,14 +607,14 @@ public class PgpKeyOperation {
hashedPacketsGen.setKeyFlags(false, usageId);
if (saveParcel.keysExpiryDates.get(i) != null) {
GregorianCalendar creationDate = new GregorianCalendar(TimeZone.getTimeZone("UTC"));
Calendar creationDate = Calendar.getInstance(TimeZone.getTimeZone("UTC"));
creationDate.setTime(subPublicKey.getCreationTime());
GregorianCalendar expiryDate = saveParcel.keysExpiryDates.get(i);
Calendar expiryDate = saveParcel.keysExpiryDates.get(i);
// 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!
long numDays = (expiryDate.getTimeInMillis() / 86400000) -
(creationDate.getTimeInMillis() / 86400000);
(creationDate.getTimeInMillis() / 86400000);
if (numDays <= 0) {
throw new PgpGeneralMsgIdException(R.string.error_expiry_must_come_after_creation);
}
@@ -696,18 +697,19 @@ public class PgpKeyOperation {
* Certify the given pubkeyid with the given masterkeyid.
*
* @param certificationKey Certifying key
* @param publicKey public key to certify
* @param userIds User IDs to certify, must not be null or empty
* @param passphrase Passphrase of the secret key
* @param publicKey public key to certify
* @param userIds User IDs to certify, must not be null or empty
* @param passphrase Passphrase of the secret key
* @return A keyring with added certifications
*/
public PGPPublicKey certifyKey(PGPSecretKey certificationKey, PGPPublicKey publicKey,
List<String> userIds, String passphrase)
throws PgpGeneralMsgIdException, NoSuchAlgorithmException, NoSuchProviderException,
PGPException, SignatureException {
PGPException, SignatureException {
// create a signatureGenerator from the supplied masterKeyId and passphrase
PGPSignatureGenerator signatureGenerator; {
PGPSignatureGenerator signatureGenerator;
{
if (certificationKey == null) {
throw new PgpGeneralMsgIdException(R.string.error_signature_failed);
@@ -744,14 +746,16 @@ public class PgpKeyOperation {
return publicKey;
}
/** Simple static subclass that stores two values.
*
/**
* Simple static subclass that stores two values.
* <p/>
* This is only used to return a pair of values in one function above. We specifically don't use
* com.android.Pair to keep this class free from android dependencies.
*/
public static class Pair<K, V> {
public final K first;
public final V second;
public Pair(K first, V second) {
this.first = first;
this.second = second;