certify: add some subscopes in PgpKeyOperation for readability
note this commit introduces NO semantical changes whatsoever!
This commit is contained in:
@@ -215,106 +215,118 @@ public class PgpKeyOperation {
|
|||||||
|
|
||||||
updateProgress(R.string.progress_preparing_master_key, 10, 100);
|
updateProgress(R.string.progress_preparing_master_key, 10, 100);
|
||||||
|
|
||||||
int usageId = keysUsages.get(0);
|
// prepare keyring generator with given master public and secret key
|
||||||
boolean canSign =
|
PGPKeyRingGenerator keyGen;
|
||||||
(usageId == Id.choice.usage.sign_only || usageId == Id.choice.usage.sign_and_encrypt);
|
PGPPublicKey masterPublicKey; {
|
||||||
boolean canEncrypt =
|
|
||||||
(usageId == Id.choice.usage.encrypt_only || usageId == Id.choice.usage.sign_and_encrypt);
|
|
||||||
|
|
||||||
String mainUserId = userIds.get(0);
|
String mainUserId = userIds.get(0);
|
||||||
|
|
||||||
PGPSecretKey masterKey = keys.get(0);
|
// prepare the master key pair
|
||||||
|
PGPKeyPair masterKeyPair; {
|
||||||
|
|
||||||
// this removes all userIds and certifications previously attached to the masterPublicKey
|
PGPSecretKey masterKey = keys.get(0);
|
||||||
PGPPublicKey tmpKey = masterKey.getPublicKey();
|
|
||||||
PGPPublicKey masterPublicKey = new PGPPublicKey(tmpKey.getAlgorithm(),
|
|
||||||
tmpKey.getKey(new BouncyCastleProvider()), tmpKey.getCreationTime());
|
|
||||||
|
|
||||||
// already done by code above:
|
// this removes all userIds and certifications previously attached to the masterPublicKey
|
||||||
// PGPPublicKey masterPublicKey = masterKey.getPublicKey();
|
PGPPublicKey tmpKey = masterKey.getPublicKey();
|
||||||
// // Somehow, the PGPPublicKey already has an empty certification attached to it when the
|
masterPublicKey = new PGPPublicKey(tmpKey.getAlgorithm(),
|
||||||
// // keyRing is generated the first time, we remove that when it exists, before adding the
|
tmpKey.getKey(new BouncyCastleProvider()), tmpKey.getCreationTime());
|
||||||
// new
|
|
||||||
// // ones
|
|
||||||
// PGPPublicKey masterPublicKeyRmCert = PGPPublicKey.removeCertification(masterPublicKey,
|
|
||||||
// "");
|
|
||||||
// if (masterPublicKeyRmCert != null) {
|
|
||||||
// masterPublicKey = masterPublicKeyRmCert;
|
|
||||||
// }
|
|
||||||
|
|
||||||
PBESecretKeyDecryptor keyDecryptor = new JcePBESecretKeyDecryptorBuilder().setProvider(
|
// already done by code above:
|
||||||
Constants.BOUNCY_CASTLE_PROVIDER_NAME).build(oldPassPhrase.toCharArray());
|
// PGPPublicKey masterPublicKey = masterKey.getPublicKey();
|
||||||
PGPPrivateKey masterPrivateKey = masterKey.extractPrivateKey(keyDecryptor);
|
// // Somehow, the PGPPublicKey already has an empty certification attached to it when the
|
||||||
|
// // keyRing is generated the first time, we remove that when it exists, before adding the
|
||||||
|
// new
|
||||||
|
// // ones
|
||||||
|
// PGPPublicKey masterPublicKeyRmCert = PGPPublicKey.removeCertification(masterPublicKey,
|
||||||
|
// "");
|
||||||
|
// if (masterPublicKeyRmCert != null) {
|
||||||
|
// masterPublicKey = masterPublicKeyRmCert;
|
||||||
|
// }
|
||||||
|
|
||||||
updateProgress(R.string.progress_certifying_master_key, 20, 100);
|
PBESecretKeyDecryptor keyDecryptor = new JcePBESecretKeyDecryptorBuilder().setProvider(
|
||||||
|
Constants.BOUNCY_CASTLE_PROVIDER_NAME).build(oldPassPhrase.toCharArray());
|
||||||
|
PGPPrivateKey masterPrivateKey = masterKey.extractPrivateKey(keyDecryptor);
|
||||||
|
|
||||||
// TODO: if we are editing a key, keep old certs, don't remake certs we don't have to.
|
updateProgress(R.string.progress_certifying_master_key, 20, 100);
|
||||||
|
|
||||||
for (String userId : userIds) {
|
// TODO: if we are editing a key, keep old certs, don't remake certs we don't have to.
|
||||||
PGPContentSignerBuilder signerBuilder = new JcaPGPContentSignerBuilder(
|
|
||||||
masterPublicKey.getAlgorithm(), HashAlgorithmTags.SHA1)
|
|
||||||
.setProvider(Constants.BOUNCY_CASTLE_PROVIDER_NAME);
|
|
||||||
PGPSignatureGenerator sGen = new PGPSignatureGenerator(signerBuilder);
|
|
||||||
|
|
||||||
sGen.init(PGPSignature.POSITIVE_CERTIFICATION, masterPrivateKey);
|
for (String userId : userIds) {
|
||||||
|
PGPContentSignerBuilder signerBuilder = new JcaPGPContentSignerBuilder(
|
||||||
|
masterPublicKey.getAlgorithm(), HashAlgorithmTags.SHA1)
|
||||||
|
.setProvider(Constants.BOUNCY_CASTLE_PROVIDER_NAME);
|
||||||
|
PGPSignatureGenerator sGen = new PGPSignatureGenerator(signerBuilder);
|
||||||
|
|
||||||
PGPSignature certification = sGen.generateCertification(userId, masterPublicKey);
|
sGen.init(PGPSignature.POSITIVE_CERTIFICATION, masterPrivateKey);
|
||||||
|
|
||||||
masterPublicKey = PGPPublicKey.addCertification(masterPublicKey, userId, certification);
|
PGPSignature certification = sGen.generateCertification(userId, masterPublicKey);
|
||||||
}
|
|
||||||
|
|
||||||
PGPKeyPair masterKeyPair = new PGPKeyPair(masterPublicKey, masterPrivateKey);
|
masterPublicKey = PGPPublicKey.addCertification(masterPublicKey, userId, certification);
|
||||||
|
}
|
||||||
|
|
||||||
PGPSignatureSubpacketGenerator hashedPacketsGen = new PGPSignatureSubpacketGenerator();
|
masterKeyPair = new PGPKeyPair(masterPublicKey, masterPrivateKey);
|
||||||
PGPSignatureSubpacketGenerator unhashedPacketsGen = new PGPSignatureSubpacketGenerator();
|
|
||||||
|
|
||||||
int keyFlags = KeyFlags.CERTIFY_OTHER | KeyFlags.SIGN_DATA;
|
|
||||||
if (canEncrypt) {
|
|
||||||
keyFlags |= KeyFlags.ENCRYPT_COMMS | KeyFlags.ENCRYPT_STORAGE;
|
|
||||||
}
|
|
||||||
hashedPacketsGen.setKeyFlags(true, keyFlags);
|
|
||||||
|
|
||||||
hashedPacketsGen.setPreferredSymmetricAlgorithms(true, PREFERRED_SYMMETRIC_ALGORITHMS);
|
|
||||||
hashedPacketsGen.setPreferredHashAlgorithms(true, PREFERRED_HASH_ALGORITHMS);
|
|
||||||
hashedPacketsGen.setPreferredCompressionAlgorithms(true, PREFERRED_COMPRESSION_ALGORITHMS);
|
|
||||||
|
|
||||||
if (keysExpiryDates.get(0) != null) {
|
|
||||||
GregorianCalendar creationDate = new GregorianCalendar(TimeZone.getTimeZone("UTC"));
|
|
||||||
creationDate.setTime(masterPublicKey.getCreationTime());
|
|
||||||
GregorianCalendar expiryDate = 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);
|
|
||||||
if (numDays <= 0) {
|
|
||||||
throw new PgpGeneralException(
|
|
||||||
mContext.getString(R.string.error_expiry_must_come_after_creation));
|
|
||||||
}
|
}
|
||||||
hashedPacketsGen.setKeyExpirationTime(false, numDays * 86400);
|
|
||||||
} else {
|
PGPSignatureSubpacketGenerator hashedPacketsGen;
|
||||||
//do this explicitly, although since we're rebuilding,
|
PGPSignatureSubpacketGenerator unhashedPacketsGen; {
|
||||||
hashedPacketsGen.setKeyExpirationTime(false, 0);
|
|
||||||
//this happens anyway
|
hashedPacketsGen = new PGPSignatureSubpacketGenerator();
|
||||||
|
unhashedPacketsGen = new PGPSignatureSubpacketGenerator();
|
||||||
|
|
||||||
|
int usageId = keysUsages.get(0);
|
||||||
|
boolean canEncrypt =
|
||||||
|
(usageId == Id.choice.usage.encrypt_only || usageId == Id.choice.usage.sign_and_encrypt);
|
||||||
|
|
||||||
|
int keyFlags = KeyFlags.CERTIFY_OTHER | KeyFlags.SIGN_DATA;
|
||||||
|
if (canEncrypt) {
|
||||||
|
keyFlags |= KeyFlags.ENCRYPT_COMMS | KeyFlags.ENCRYPT_STORAGE;
|
||||||
|
}
|
||||||
|
hashedPacketsGen.setKeyFlags(true, keyFlags);
|
||||||
|
|
||||||
|
hashedPacketsGen.setPreferredSymmetricAlgorithms(true, PREFERRED_SYMMETRIC_ALGORITHMS);
|
||||||
|
hashedPacketsGen.setPreferredHashAlgorithms(true, PREFERRED_HASH_ALGORITHMS);
|
||||||
|
hashedPacketsGen.setPreferredCompressionAlgorithms(true, PREFERRED_COMPRESSION_ALGORITHMS);
|
||||||
|
|
||||||
|
if (keysExpiryDates.get(0) != null) {
|
||||||
|
GregorianCalendar creationDate = new GregorianCalendar(TimeZone.getTimeZone("UTC"));
|
||||||
|
creationDate.setTime(masterPublicKey.getCreationTime());
|
||||||
|
GregorianCalendar expiryDate = 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);
|
||||||
|
if (numDays <= 0) {
|
||||||
|
throw new PgpGeneralException(
|
||||||
|
mContext.getString(R.string.error_expiry_must_come_after_creation));
|
||||||
|
}
|
||||||
|
hashedPacketsGen.setKeyExpirationTime(false, numDays * 86400);
|
||||||
|
} else {
|
||||||
|
//do this explicitly, although since we're rebuilding,
|
||||||
|
hashedPacketsGen.setKeyExpirationTime(false, 0);
|
||||||
|
//this happens anyway
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
updateProgress(R.string.progress_building_master_key, 30, 100);
|
||||||
|
|
||||||
|
// define hashing and signing algos
|
||||||
|
PGPDigestCalculator sha1Calc = new JcaPGPDigestCalculatorProviderBuilder().build().get(
|
||||||
|
HashAlgorithmTags.SHA1);
|
||||||
|
PGPContentSignerBuilder certificationSignerBuilder = new JcaPGPContentSignerBuilder(
|
||||||
|
masterKeyPair.getPublicKey().getAlgorithm(), HashAlgorithmTags.SHA1);
|
||||||
|
|
||||||
|
// Build key encrypter based on passphrase
|
||||||
|
PBESecretKeyEncryptor keyEncryptor = new JcePBESecretKeyEncryptorBuilder(
|
||||||
|
PGPEncryptedData.CAST5, sha1Calc)
|
||||||
|
.setProvider(Constants.BOUNCY_CASTLE_PROVIDER_NAME).build(
|
||||||
|
newPassPhrase.toCharArray());
|
||||||
|
|
||||||
|
keyGen = new PGPKeyRingGenerator(PGPSignature.POSITIVE_CERTIFICATION,
|
||||||
|
masterKeyPair, mainUserId, sha1Calc, hashedPacketsGen.generate(),
|
||||||
|
unhashedPacketsGen.generate(), certificationSignerBuilder, keyEncryptor);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
updateProgress(R.string.progress_building_master_key, 30, 100);
|
|
||||||
|
|
||||||
// define hashing and signing algos
|
|
||||||
PGPDigestCalculator sha1Calc = new JcaPGPDigestCalculatorProviderBuilder().build().get(
|
|
||||||
HashAlgorithmTags.SHA1);
|
|
||||||
PGPContentSignerBuilder certificationSignerBuilder = new JcaPGPContentSignerBuilder(
|
|
||||||
masterKeyPair.getPublicKey().getAlgorithm(), HashAlgorithmTags.SHA1);
|
|
||||||
|
|
||||||
// Build key encrypter based on passphrase
|
|
||||||
PBESecretKeyEncryptor keyEncryptor = new JcePBESecretKeyEncryptorBuilder(
|
|
||||||
PGPEncryptedData.CAST5, sha1Calc)
|
|
||||||
.setProvider(Constants.BOUNCY_CASTLE_PROVIDER_NAME).build(
|
|
||||||
newPassPhrase.toCharArray());
|
|
||||||
|
|
||||||
PGPKeyRingGenerator keyGen = new PGPKeyRingGenerator(PGPSignature.POSITIVE_CERTIFICATION,
|
|
||||||
masterKeyPair, mainUserId, sha1Calc, hashedPacketsGen.generate(),
|
|
||||||
unhashedPacketsGen.generate(), certificationSignerBuilder, keyEncryptor);
|
|
||||||
|
|
||||||
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 < keys.size(); ++i) {
|
||||||
@@ -323,23 +335,23 @@ public class PgpKeyOperation {
|
|||||||
PGPSecretKey subKey = keys.get(i);
|
PGPSecretKey subKey = keys.get(i);
|
||||||
PGPPublicKey subPublicKey = subKey.getPublicKey();
|
PGPPublicKey subPublicKey = subKey.getPublicKey();
|
||||||
|
|
||||||
PBESecretKeyDecryptor keyDecryptor2 = new JcePBESecretKeyDecryptorBuilder()
|
PBESecretKeyDecryptor keyDecryptor = new JcePBESecretKeyDecryptorBuilder()
|
||||||
.setProvider(Constants.BOUNCY_CASTLE_PROVIDER_NAME).build(
|
.setProvider(Constants.BOUNCY_CASTLE_PROVIDER_NAME).build(
|
||||||
oldPassPhrase.toCharArray());
|
oldPassPhrase.toCharArray());
|
||||||
PGPPrivateKey subPrivateKey = subKey.extractPrivateKey(keyDecryptor2);
|
PGPPrivateKey subPrivateKey = subKey.extractPrivateKey(keyDecryptor);
|
||||||
|
|
||||||
// TODO: now used without algorithm and creation time?! (APG 1)
|
// TODO: now used without algorithm and creation time?! (APG 1)
|
||||||
PGPKeyPair subKeyPair = new PGPKeyPair(subPublicKey, subPrivateKey);
|
PGPKeyPair subKeyPair = new PGPKeyPair(subPublicKey, subPrivateKey);
|
||||||
|
|
||||||
hashedPacketsGen = new PGPSignatureSubpacketGenerator();
|
PGPSignatureSubpacketGenerator hashedPacketsGen = new PGPSignatureSubpacketGenerator();
|
||||||
unhashedPacketsGen = new PGPSignatureSubpacketGenerator();
|
PGPSignatureSubpacketGenerator unhashedPacketsGen = new PGPSignatureSubpacketGenerator();
|
||||||
|
|
||||||
keyFlags = 0;
|
int keyFlags = 0;
|
||||||
|
|
||||||
usageId = keysUsages.get(i);
|
int usageId = keysUsages.get(i);
|
||||||
canSign =
|
boolean canSign =
|
||||||
(usageId == Id.choice.usage.sign_only || usageId == Id.choice.usage.sign_and_encrypt);
|
(usageId == Id.choice.usage.sign_only || usageId == Id.choice.usage.sign_and_encrypt);
|
||||||
canEncrypt =
|
boolean canEncrypt =
|
||||||
(usageId == Id.choice.usage.encrypt_only || usageId == Id.choice.usage.sign_and_encrypt);
|
(usageId == Id.choice.usage.encrypt_only || usageId == Id.choice.usage.sign_and_encrypt);
|
||||||
if (canSign) {
|
if (canSign) {
|
||||||
Date todayDate = new Date(); //both sig times the same
|
Date todayDate = new Date(); //both sig times the same
|
||||||
@@ -402,37 +414,41 @@ public class PgpKeyOperation {
|
|||||||
if (passphrase == null) {
|
if (passphrase == null) {
|
||||||
throw new PgpGeneralException("Unable to obtain passphrase");
|
throw new PgpGeneralException("Unable to obtain passphrase");
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
|
// create a signatureGenerator from the supplied masterKeyId and passphrase
|
||||||
|
PGPSignatureGenerator signatureGenerator; {
|
||||||
|
|
||||||
|
PGPSecretKey certificationKey = PgpKeyHelper.getCertificationKey(mContext, masterKeyId);
|
||||||
|
if (certificationKey == null) {
|
||||||
|
throw new PgpGeneralException(mContext.getString(R.string.error_signature_failed));
|
||||||
|
}
|
||||||
|
|
||||||
|
PBESecretKeyDecryptor keyDecryptor = new JcePBESecretKeyDecryptorBuilder().setProvider(
|
||||||
|
Constants.BOUNCY_CASTLE_PROVIDER_NAME).build(passphrase.toCharArray());
|
||||||
|
PGPPrivateKey signaturePrivateKey = certificationKey.extractPrivateKey(keyDecryptor);
|
||||||
|
if (signaturePrivateKey == null) {
|
||||||
|
throw new PgpGeneralException(
|
||||||
|
mContext.getString(R.string.error_could_not_extract_private_key));
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: SHA256 fixed?
|
||||||
|
JcaPGPContentSignerBuilder contentSignerBuilder = new JcaPGPContentSignerBuilder(
|
||||||
|
certificationKey.getPublicKey().getAlgorithm(), PGPUtil.SHA256)
|
||||||
|
.setProvider(Constants.BOUNCY_CASTLE_PROVIDER_NAME);
|
||||||
|
|
||||||
|
signatureGenerator = new PGPSignatureGenerator(contentSignerBuilder);
|
||||||
|
signatureGenerator.init(PGPSignature.DIRECT_KEY, signaturePrivateKey);
|
||||||
|
}
|
||||||
|
|
||||||
|
{ // supply signatureGenerator with a SubpacketVector
|
||||||
|
PGPSignatureSubpacketGenerator spGen = new PGPSignatureSubpacketGenerator();
|
||||||
|
PGPSignatureSubpacketVector packetVector = spGen.generate();
|
||||||
|
signatureGenerator.setHashedSubpackets(packetVector);
|
||||||
|
}
|
||||||
|
|
||||||
|
// fetch public key ring, add the certification and return it
|
||||||
PGPPublicKeyRing pubring = ProviderHelper
|
PGPPublicKeyRing pubring = ProviderHelper
|
||||||
.getPGPPublicKeyRingByKeyId(mContext, pubKeyId);
|
.getPGPPublicKeyRingByKeyId(mContext, pubKeyId);
|
||||||
|
|
||||||
PGPSecretKey certificationKey = PgpKeyHelper.getCertificationKey(mContext, masterKeyId);
|
|
||||||
if (certificationKey == null) {
|
|
||||||
throw new PgpGeneralException(mContext.getString(R.string.error_signature_failed));
|
|
||||||
}
|
|
||||||
|
|
||||||
PBESecretKeyDecryptor keyDecryptor = new JcePBESecretKeyDecryptorBuilder().setProvider(
|
|
||||||
Constants.BOUNCY_CASTLE_PROVIDER_NAME).build(passphrase.toCharArray());
|
|
||||||
PGPPrivateKey signaturePrivateKey = certificationKey.extractPrivateKey(keyDecryptor);
|
|
||||||
if (signaturePrivateKey == null) {
|
|
||||||
throw new PgpGeneralException(
|
|
||||||
mContext.getString(R.string.error_could_not_extract_private_key));
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO: SHA256 fixed?
|
|
||||||
JcaPGPContentSignerBuilder contentSignerBuilder = new JcaPGPContentSignerBuilder(
|
|
||||||
certificationKey.getPublicKey().getAlgorithm(), PGPUtil.SHA256)
|
|
||||||
.setProvider(Constants.BOUNCY_CASTLE_PROVIDER_NAME);
|
|
||||||
|
|
||||||
PGPSignatureGenerator signatureGenerator = new PGPSignatureGenerator(
|
|
||||||
contentSignerBuilder);
|
|
||||||
|
|
||||||
signatureGenerator.init(PGPSignature.DIRECT_KEY, signaturePrivateKey);
|
|
||||||
|
|
||||||
PGPSignatureSubpacketGenerator spGen = new PGPSignatureSubpacketGenerator();
|
|
||||||
|
|
||||||
PGPSignatureSubpacketVector packetVector = spGen.generate();
|
|
||||||
signatureGenerator.setHashedSubpackets(packetVector);
|
|
||||||
|
|
||||||
PGPPublicKey signedKey = PGPPublicKey.addCertification(pubring.getPublicKey(pubKeyId),
|
PGPPublicKey signedKey = PGPPublicKey.addCertification(pubring.getPublicKey(pubKeyId),
|
||||||
signatureGenerator.generate());
|
signatureGenerator.generate());
|
||||||
pubring = PGPPublicKeyRing.insertPublicKey(pubring, signedKey);
|
pubring = PGPPublicKeyRing.insertPublicKey(pubring, signedKey);
|
||||||
|
|||||||
Reference in New Issue
Block a user