1
0
Fork 0
mirror of https://github.com/pgpainless/pgpainless.git synced 2024-12-23 11:27:57 +01:00

Fix isEncryptedFor()

This commit is contained in:
Paul Schaub 2022-11-22 16:22:01 +01:00
parent 2c7801b759
commit b36b5413e2
3 changed files with 35 additions and 17 deletions

View file

@ -698,6 +698,9 @@ public class MessageMetadata {
* @return recipients * @return recipients
*/ */
public @Nonnull List<Long> getRecipients() { public @Nonnull List<Long> getRecipients() {
if (recipients == null) {
return new ArrayList<>();
}
return new ArrayList<>(recipients); return new ArrayList<>(recipients);
} }

View file

@ -428,7 +428,7 @@ public class OpenPgpMessageInputStream extends DecryptionStream {
} }
// attempt decryption // attempt decryption
if (decryptPKESKAndStream(subkeyIdentifier, decryptorFactory, pkesk)) { if (decryptPKESKAndStream(esks, subkeyIdentifier, decryptorFactory, pkesk)) {
return true; return true;
} }
} }
@ -473,7 +473,7 @@ public class OpenPgpMessageInputStream extends DecryptionStream {
PBEDataDecryptorFactory decryptorFactory = ImplementationFactory.getInstance() PBEDataDecryptorFactory decryptorFactory = ImplementationFactory.getInstance()
.getPBEDataDecryptorFactory(passphrase); .getPBEDataDecryptorFactory(passphrase);
if (decryptSKESKAndStream(skesk, decryptorFactory)) { if (decryptSKESKAndStream(esks, skesk, decryptorFactory)) {
return true; return true;
} }
} }
@ -506,7 +506,7 @@ public class OpenPgpMessageInputStream extends DecryptionStream {
} }
PGPPrivateKey privateKey = UnlockSecretKey.unlockSecretKey(secretKey, protector); PGPPrivateKey privateKey = UnlockSecretKey.unlockSecretKey(secretKey, protector);
if (decryptWithPrivateKey(privateKey, decryptionKeyId, pkesk)) { if (decryptWithPrivateKey(esks, privateKey, decryptionKeyId, pkesk)) {
return true; return true;
} }
} }
@ -529,7 +529,7 @@ public class OpenPgpMessageInputStream extends DecryptionStream {
} }
PGPPrivateKey privateKey = UnlockSecretKey.unlockSecretKey(secretKey, protector); PGPPrivateKey privateKey = UnlockSecretKey.unlockSecretKey(secretKey, protector);
if (decryptWithPrivateKey(privateKey, decryptionKeyId, pkesk)) { if (decryptWithPrivateKey(esks, privateKey, decryptionKeyId, pkesk)) {
return true; return true;
} }
} }
@ -561,7 +561,7 @@ public class OpenPgpMessageInputStream extends DecryptionStream {
LOGGER.debug("Attempt decryption with key " + decryptionKeyId + " while interactively requesting its passphrase"); LOGGER.debug("Attempt decryption with key " + decryptionKeyId + " while interactively requesting its passphrase");
SecretKeyRingProtector protector = options.getSecretKeyProtector(decryptionKey); SecretKeyRingProtector protector = options.getSecretKeyProtector(decryptionKey);
PGPPrivateKey privateKey = UnlockSecretKey.unlockSecretKey(secretKey, protector); PGPPrivateKey privateKey = UnlockSecretKey.unlockSecretKey(secretKey, protector);
if (decryptWithPrivateKey(privateKey, decryptionKeyId, pkesk)) { if (decryptWithPrivateKey(esks, privateKey, decryptionKeyId, pkesk)) {
return true; return true;
} }
} }
@ -576,13 +576,14 @@ public class OpenPgpMessageInputStream extends DecryptionStream {
return false; return false;
} }
private boolean decryptWithPrivateKey(PGPPrivateKey privateKey, private boolean decryptWithPrivateKey(SortedESKs esks,
PGPPrivateKey privateKey,
SubkeyIdentifier decryptionKeyId, SubkeyIdentifier decryptionKeyId,
PGPPublicKeyEncryptedData pkesk) PGPPublicKeyEncryptedData pkesk)
throws PGPException, IOException { throws PGPException, IOException {
PublicKeyDataDecryptorFactory decryptorFactory = ImplementationFactory.getInstance() PublicKeyDataDecryptorFactory decryptorFactory = ImplementationFactory.getInstance()
.getPublicKeyDataDecryptorFactory(privateKey); .getPublicKeyDataDecryptorFactory(privateKey);
return decryptPKESKAndStream(decryptionKeyId, decryptorFactory, pkesk); return decryptPKESKAndStream(esks, decryptionKeyId, decryptorFactory, pkesk);
} }
private static boolean hasUnsupportedS2KSpecifier(PGPSecretKey secretKey, SubkeyIdentifier decryptionKeyId) { private static boolean hasUnsupportedS2KSpecifier(PGPSecretKey secretKey, SubkeyIdentifier decryptionKeyId) {
@ -597,17 +598,23 @@ public class OpenPgpMessageInputStream extends DecryptionStream {
return false; return false;
} }
private boolean decryptSKESKAndStream(PGPPBEEncryptedData skesk, PBEDataDecryptorFactory decryptorFactory) private boolean decryptSKESKAndStream(SortedESKs esks,
PGPPBEEncryptedData symEsk,
PBEDataDecryptorFactory decryptorFactory)
throws IOException, UnacceptableAlgorithmException { throws IOException, UnacceptableAlgorithmException {
try { try {
InputStream decrypted = skesk.getDataStream(decryptorFactory); InputStream decrypted = symEsk.getDataStream(decryptorFactory);
SessionKey sessionKey = new SessionKey(skesk.getSessionKey(decryptorFactory)); SessionKey sessionKey = new SessionKey(symEsk.getSessionKey(decryptorFactory));
throwIfUnacceptable(sessionKey.getAlgorithm()); throwIfUnacceptable(sessionKey.getAlgorithm());
MessageMetadata.EncryptedData encryptedData = new MessageMetadata.EncryptedData( MessageMetadata.EncryptedData encryptedData = new MessageMetadata.EncryptedData(
sessionKey.getAlgorithm(), metadata.depth + 1); sessionKey.getAlgorithm(), metadata.depth + 1);
encryptedData.sessionKey = sessionKey; encryptedData.sessionKey = sessionKey;
encryptedData.recipients = new ArrayList<>();
for (PGPPublicKeyEncryptedData pkesk : esks.pkesks) {
encryptedData.recipients.add(pkesk.getKeyID());
}
LOGGER.debug("Successfully decrypted data with passphrase"); LOGGER.debug("Successfully decrypted data with passphrase");
IntegrityProtectedInputStream integrityProtected = new IntegrityProtectedInputStream(decrypted, skesk, options); IntegrityProtectedInputStream integrityProtected = new IntegrityProtectedInputStream(decrypted, symEsk, options);
nestedInputStream = new OpenPgpMessageInputStream(integrityProtected, options, encryptedData, policy); nestedInputStream = new OpenPgpMessageInputStream(integrityProtected, options, encryptedData, policy);
return true; return true;
} catch (UnacceptableAlgorithmException e) { } catch (UnacceptableAlgorithmException e) {
@ -618,23 +625,28 @@ public class OpenPgpMessageInputStream extends DecryptionStream {
return false; return false;
} }
private boolean decryptPKESKAndStream(SubkeyIdentifier decryptionKeyId, private boolean decryptPKESKAndStream(SortedESKs esks,
SubkeyIdentifier decryptionKeyId,
PublicKeyDataDecryptorFactory decryptorFactory, PublicKeyDataDecryptorFactory decryptorFactory,
PGPPublicKeyEncryptedData pkesk) PGPPublicKeyEncryptedData asymEsk)
throws IOException, UnacceptableAlgorithmException { throws IOException, UnacceptableAlgorithmException {
try { try {
InputStream decrypted = pkesk.getDataStream(decryptorFactory); InputStream decrypted = asymEsk.getDataStream(decryptorFactory);
SessionKey sessionKey = new SessionKey(pkesk.getSessionKey(decryptorFactory)); SessionKey sessionKey = new SessionKey(asymEsk.getSessionKey(decryptorFactory));
throwIfUnacceptable(sessionKey.getAlgorithm()); throwIfUnacceptable(sessionKey.getAlgorithm());
MessageMetadata.EncryptedData encryptedData = new MessageMetadata.EncryptedData( MessageMetadata.EncryptedData encryptedData = new MessageMetadata.EncryptedData(
SymmetricKeyAlgorithm.requireFromId(pkesk.getSymmetricAlgorithm(decryptorFactory)), SymmetricKeyAlgorithm.requireFromId(asymEsk.getSymmetricAlgorithm(decryptorFactory)),
metadata.depth + 1); metadata.depth + 1);
encryptedData.decryptionKey = decryptionKeyId; encryptedData.decryptionKey = decryptionKeyId;
encryptedData.sessionKey = sessionKey; encryptedData.sessionKey = sessionKey;
encryptedData.recipients = new ArrayList<>();
for (PGPPublicKeyEncryptedData pkesk : esks.pkesks) {
encryptedData.recipients.add(pkesk.getKeyID());
}
LOGGER.debug("Successfully decrypted data with key " + decryptionKeyId); LOGGER.debug("Successfully decrypted data with key " + decryptionKeyId);
IntegrityProtectedInputStream integrityProtected = new IntegrityProtectedInputStream(decrypted, pkesk, options); IntegrityProtectedInputStream integrityProtected = new IntegrityProtectedInputStream(decrypted, asymEsk, options);
nestedInputStream = new OpenPgpMessageInputStream(integrityProtected, options, encryptedData, policy); nestedInputStream = new OpenPgpMessageInputStream(integrityProtected, options, encryptedData, policy);
return true; return true;
} catch (UnacceptableAlgorithmException e) { } catch (UnacceptableAlgorithmException e) {

View file

@ -170,6 +170,7 @@ public class DecryptOrVerify {
// The metadata object contains information about the message // The metadata object contains information about the message
MessageMetadata metadata = decryptionStream.getMetadata(); MessageMetadata metadata = decryptionStream.getMetadata();
assertTrue(metadata.isEncrypted()); // message was encrypted assertTrue(metadata.isEncrypted()); // message was encrypted
assertTrue(metadata.isEncryptedFor(secretKey));
assertFalse(metadata.isVerifiedSigned()); // We did not do any signature verification assertFalse(metadata.isVerifiedSigned()); // We did not do any signature verification
// The output stream now contains the decrypted message // The output stream now contains the decrypted message
@ -202,6 +203,7 @@ public class DecryptOrVerify {
// metadata with information on the message, like signatures // metadata with information on the message, like signatures
MessageMetadata metadata = decryptionStream.getMetadata(); MessageMetadata metadata = decryptionStream.getMetadata();
assertTrue(metadata.isEncrypted()); // messages was in fact encrypted assertTrue(metadata.isEncrypted()); // messages was in fact encrypted
assertTrue(metadata.isEncryptedFor(certificate));
assertTrue(metadata.isVerifiedSigned()); // the signatures were actually correct assertTrue(metadata.isVerifiedSigned()); // the signatures were actually correct
assertTrue(metadata.isVerifiedSignedBy(certificate)); // the signatures could be verified using the certificate assertTrue(metadata.isVerifiedSignedBy(certificate)); // the signatures could be verified using the certificate
@ -233,6 +235,7 @@ public class DecryptOrVerify {
// Get the metadata object for information about the message // Get the metadata object for information about the message
MessageMetadata metadata = verificationStream.getMetadata(); MessageMetadata metadata = verificationStream.getMetadata();
assertTrue(metadata.isVerifiedSigned()); // signatures were verified successfully assertTrue(metadata.isVerifiedSigned()); // signatures were verified successfully
assertTrue(metadata.isVerifiedSignedBy(certificate));
// The output stream we piped to now contains the message // The output stream we piped to now contains the message
assertEquals(PLAINTEXT, out.toString()); assertEquals(PLAINTEXT, out.toString());
} }