1
0
Fork 0
mirror of https://github.com/pgpainless/pgpainless.git synced 2024-11-19 02:42:05 +01:00

Small clean-ups in OpenPgpMessageInputStream

This commit is contained in:
Paul Schaub 2022-10-29 15:50:34 +02:00
parent 58195c19b1
commit ca49ed087b

View file

@ -479,9 +479,9 @@ public class OpenPgpMessageInputStream extends DecryptionStream {
for (Passphrase passphrase : options.getDecryptionPassphrases()) {
for (PGPPBEEncryptedData skesk : esks.skesks) {
LOGGER.debug("Attempt decryption with provided passphrase");
SymmetricKeyAlgorithm kekAlgorithm = SymmetricKeyAlgorithm.requireFromId(skesk.getAlgorithm());
SymmetricKeyAlgorithm encapsulationAlgorithm = SymmetricKeyAlgorithm.requireFromId(skesk.getAlgorithm());
try {
throwIfUnacceptable(kekAlgorithm);
throwIfUnacceptable(encapsulationAlgorithm);
} catch (UnacceptableAlgorithmException e) {
LOGGER.debug("Skipping SKESK with unacceptable encapsulation algorithm", e);
continue;
@ -489,7 +489,6 @@ public class OpenPgpMessageInputStream extends DecryptionStream {
PBEDataDecryptorFactory decryptorFactory = ImplementationFactory.getInstance()
.getPBEDataDecryptorFactory(passphrase);
if (decryptSKESKAndStream(skesk, decryptorFactory)) {
return true;
}
@ -497,10 +496,11 @@ public class OpenPgpMessageInputStream extends DecryptionStream {
}
List<Tuple<PGPSecretKey, PGPPublicKeyEncryptedData>> postponedDueToMissingPassphrase = new ArrayList<>();
// Try (known) secret keys
for (PGPPublicKeyEncryptedData pkesk : esks.pkesks) {
long keyId = pkesk.getKeyID();
LOGGER.debug("Encountered PKESK with recipient " + KeyIdUtil.formatKeyId(keyId));
LOGGER.debug("Encountered PKESK for recipient " + KeyIdUtil.formatKeyId(keyId));
PGPSecretKeyRing decryptionKeys = getDecryptionKey(keyId);
if (decryptionKeys == null) {
LOGGER.debug("Skipping PKESK because no matching key " + KeyIdUtil.formatKeyId(keyId) + " was provided");
@ -508,14 +508,9 @@ public class OpenPgpMessageInputStream extends DecryptionStream {
}
PGPSecretKey secretKey = decryptionKeys.getSecretKey(keyId);
SubkeyIdentifier decryptionKeyId = new SubkeyIdentifier(decryptionKeys, secretKey.getKeyID());
S2K s2K = secretKey.getS2K();
if (s2K != null) {
int s2kType = s2K.getType();
if (s2kType >= 100 && s2kType <= 110) {
LOGGER.debug("Skipping PKESK because key " + decryptionKeyId + " has unsupported private S2K specifier " + s2kType);
if (hasUnsupportedS2KSpecifier(secretKey, decryptionKeyId)) {
continue;
}
}
LOGGER.debug("Attempt decryption using secret key " + decryptionKeyId);
SecretKeyRingProtector protector = options.getSecretKeyProtector(decryptionKeys);
@ -527,10 +522,7 @@ public class OpenPgpMessageInputStream extends DecryptionStream {
}
PGPPrivateKey privateKey = UnlockSecretKey.unlockSecretKey(secretKey, protector);
PublicKeyDataDecryptorFactory decryptorFactory = ImplementationFactory.getInstance()
.getPublicKeyDataDecryptorFactory(privateKey);
if (decryptPKESKAndStream(decryptionKeyId, decryptorFactory, pkesk)) {
if (decryptWithPrivateKey(privateKey, decryptionKeyId, pkesk)) {
return true;
}
}
@ -541,14 +533,9 @@ public class OpenPgpMessageInputStream extends DecryptionStream {
PGPSecretKeyRing decryptionKeys = decryptionKeyCandidate.getA();
PGPSecretKey secretKey = decryptionKeyCandidate.getB();
SubkeyIdentifier decryptionKeyId = new SubkeyIdentifier(decryptionKeys, secretKey.getKeyID());
S2K s2K = secretKey.getS2K();
if (s2K != null) {
int s2kType = s2K.getType();
if (s2kType >= 100 && s2kType <= 110) {
LOGGER.debug("Skipping PKESK because key " + decryptionKeyId + " has unsupported private S2K specifier " + s2kType);
if (hasUnsupportedS2KSpecifier(secretKey, decryptionKeyId)) {
continue;
}
}
LOGGER.debug("Attempt decryption of anonymous PKESK with key " + decryptionKeyId);
SecretKeyRingProtector protector = options.getSecretKeyProtector(decryptionKeyCandidate.getA());
if (!protector.hasPassphraseFor(secretKey.getKeyID())) {
@ -556,11 +543,9 @@ public class OpenPgpMessageInputStream extends DecryptionStream {
postponedDueToMissingPassphrase.add(new Tuple<>(secretKey, pkesk));
continue;
}
PGPPrivateKey privateKey = UnlockSecretKey.unlockSecretKey(decryptionKeyCandidate.getB(), protector);
PublicKeyDataDecryptorFactory decryptorFactory = ImplementationFactory.getInstance()
.getPublicKeyDataDecryptorFactory(privateKey);
if (decryptPKESKAndStream(decryptionKeyId, decryptorFactory, pkesk)) {
PGPPrivateKey privateKey = UnlockSecretKey.unlockSecretKey(secretKey, protector);
if (decryptWithPrivateKey(privateKey, decryptionKeyId, pkesk)) {
return true;
}
}
@ -571,7 +556,8 @@ public class OpenPgpMessageInputStream extends DecryptionStream {
Set<SubkeyIdentifier> keyIds = new HashSet<>();
for (Tuple<PGPSecretKey, PGPPublicKeyEncryptedData> k : postponedDueToMissingPassphrase) {
PGPSecretKey key = k.getA();
keyIds.add(new SubkeyIdentifier(getDecryptionKey(key.getKeyID()), key.getKeyID()));
PGPSecretKeyRing keys = getDecryptionKey(key.getKeyID());
keyIds.add(new SubkeyIdentifier(keys, key.getKeyID()));
}
if (!keyIds.isEmpty()) {
throw new MissingPassphraseException(keyIds);
@ -584,21 +570,14 @@ public class OpenPgpMessageInputStream extends DecryptionStream {
long keyId = secretKey.getKeyID();
PGPSecretKeyRing decryptionKey = getDecryptionKey(keyId);
SubkeyIdentifier decryptionKeyId = new SubkeyIdentifier(decryptionKey, keyId);
S2K s2K = secretKey.getS2K();
if (s2K != null) {
int s2kType = s2K.getType();
if (s2kType >= 100 && s2kType <= 110) {
LOGGER.debug("Skipping PKESK because key " + decryptionKeyId + " has unsupported private S2K specifier " + s2kType);
if (hasUnsupportedS2KSpecifier(secretKey, decryptionKeyId)) {
continue;
}
}
LOGGER.debug("Attempt decryption with key " + decryptionKeyId + " while interactively requesting its passphrase");
SecretKeyRingProtector protector = options.getSecretKeyProtector(decryptionKey);
PGPPrivateKey privateKey = UnlockSecretKey.unlockSecretKey(secretKey, protector.getDecryptor(keyId));
PublicKeyDataDecryptorFactory decryptorFactory = ImplementationFactory.getInstance()
.getPublicKeyDataDecryptorFactory(privateKey);
if (decryptPKESKAndStream(decryptionKeyId, decryptorFactory, pkesk)) {
PGPPrivateKey privateKey = UnlockSecretKey.unlockSecretKey(secretKey, protector);
if (decryptWithPrivateKey(privateKey, decryptionKeyId, pkesk)) {
return true;
}
}
@ -613,6 +592,27 @@ public class OpenPgpMessageInputStream extends DecryptionStream {
return false;
}
private boolean decryptWithPrivateKey(PGPPrivateKey privateKey,
SubkeyIdentifier decryptionKeyId,
PGPPublicKeyEncryptedData pkesk)
throws PGPException, IOException {
PublicKeyDataDecryptorFactory decryptorFactory = ImplementationFactory.getInstance()
.getPublicKeyDataDecryptorFactory(privateKey);
return decryptPKESKAndStream(decryptionKeyId, decryptorFactory, pkesk);
}
private static boolean hasUnsupportedS2KSpecifier(PGPSecretKey secretKey, SubkeyIdentifier decryptionKeyId) {
S2K s2K = secretKey.getS2K();
if (s2K != null) {
int s2kType = s2K.getType();
if (s2kType >= 100 && s2kType <= 110) {
LOGGER.debug("Skipping PKESK because key " + decryptionKeyId + " has unsupported private S2K specifier " + s2kType);
return true;
}
}
return false;
}
private boolean decryptSKESKAndStream(PGPPBEEncryptedData skesk, PBEDataDecryptorFactory decryptorFactory)
throws IOException, UnacceptableAlgorithmException {
try {
@ -661,14 +661,6 @@ public class OpenPgpMessageInputStream extends DecryptionStream {
return false;
}
private PGPSecretKey getDecryptionKey(PGPSecretKeyRing decryptionKeys, long keyId) {
KeyRingInfo info = PGPainless.inspectKeyRing(decryptionKeys);
if (info.getEncryptionSubkeys(EncryptionPurpose.ANY).contains(info.getPublicKey(keyId))) {
return info.getSecretKey(keyId);
}
return null;
}
private void throwIfUnacceptable(SymmetricKeyAlgorithm algorithm)
throws UnacceptableAlgorithmException {
if (!policy.getSymmetricKeyDecryptionAlgorithmPolicy().isAcceptable(algorithm)) {
@ -883,20 +875,6 @@ public class OpenPgpMessageInputStream extends DecryptionStream {
return resultBuilder.build();
}
static void log(String message) {
LOGGER.debug(message);
// CHECKSTYLE:OFF
System.out.println(message);
// CHECKSTYLE:ON
}
static void log(String message, Throwable e) {
log(message);
// CHECKSTYLE:OFF
e.printStackTrace();
// CHECKSTYLE:ON
}
// In 'OPS LIT("Foo") SIG', OPS is only updated with "Foo"
// In 'OPS[1] OPS LIT("Foo") SIG SIG', OPS[1] (nested) is updated with OPS LIT("Foo") SIG.
// Therefore, we need to handle the innermost signature layer differently when updating with Literal data.