From 61149407526d8d14add394ce7d9e15e7adb00d68 Mon Sep 17 00:00:00 2001 From: gefeili Date: Thu, 5 Sep 2024 14:27:21 +0930 Subject: [PATCH] revert the wrong commit #1768 Implement message decryption using SEIPDv2 and PKESKv6 packets --- .../bcpg/PublicKeyEncSessionPacket.java | 11 - .../openpgp/PGPPublicKeyEncryptedData.java | 90 +---- ...AbstractPublicKeyDataDecryptorFactory.java | 76 ---- .../PublicKeyDataDecryptorFactory.java | 31 +- .../bc/BcPublicKeyDataDecryptorFactory.java | 345 ++++++++---------- .../operator/jcajce/JcaJcePGPUtil.java | 2 +- ...ePublicKeyDataDecryptorFactoryBuilder.java | 96 ++--- .../org/bouncycastle/bcpg/test/AllTests.java | 3 +- .../bcpg/test/EncryptedMessagePacketTest.java | 237 ------------ .../test/PGPv6MessageDecryptionTest.java | 209 ----------- .../openpgp/test/RegressionTest.java | 2 - 11 files changed, 203 insertions(+), 899 deletions(-) delete mode 100644 pg/src/main/java/org/bouncycastle/openpgp/operator/AbstractPublicKeyDataDecryptorFactory.java delete mode 100644 pg/src/test/java/org/bouncycastle/bcpg/test/EncryptedMessagePacketTest.java delete mode 100644 pg/src/test/java/org/bouncycastle/openpgp/test/PGPv6MessageDecryptionTest.java diff --git a/pg/src/main/java/org/bouncycastle/bcpg/PublicKeyEncSessionPacket.java b/pg/src/main/java/org/bouncycastle/bcpg/PublicKeyEncSessionPacket.java index 51b5e7cee2..b75dc5e4c3 100644 --- a/pg/src/main/java/org/bouncycastle/bcpg/PublicKeyEncSessionPacket.java +++ b/pg/src/main/java/org/bouncycastle/bcpg/PublicKeyEncSessionPacket.java @@ -60,23 +60,12 @@ else if (version == VERSION_6) // anon recipient keyVersion = 0; keyFingerprint = new byte[0]; - keyID = 0L; } else { keyVersion = in.read(); keyFingerprint = new byte[keyInfoLen - 1]; in.readFully(keyFingerprint); - // Derived key-ID from fingerprint - // TODO: Replace with getKeyIdentifier - if (keyVersion == PublicKeyPacket.VERSION_4) - { - keyID = FingerprintUtil.keyIdFromV4Fingerprint(keyFingerprint); - } - else - { - keyID = FingerprintUtil.keyIdFromV6Fingerprint(keyFingerprint); - } } } else diff --git a/pg/src/main/java/org/bouncycastle/openpgp/PGPPublicKeyEncryptedData.java b/pg/src/main/java/org/bouncycastle/openpgp/PGPPublicKeyEncryptedData.java index 4825230d4c..792bd3ef19 100644 --- a/pg/src/main/java/org/bouncycastle/openpgp/PGPPublicKeyEncryptedData.java +++ b/pg/src/main/java/org/bouncycastle/openpgp/PGPPublicKeyEncryptedData.java @@ -72,13 +72,13 @@ public int getSymmetricAlgorithm( { if (keyData.getVersion() == PublicKeyEncSessionPacket.VERSION_3) { - byte[] plain = dataDecryptorFactory.recoverSessionData(keyData, encData); + byte[] plain = dataDecryptorFactory.recoverSessionData(keyData.getAlgorithm(), keyData.getEncSessionKey()); // symmetric cipher algorithm is stored in first octet of session data return plain[0]; } else if (keyData.getVersion() == PublicKeyEncSessionPacket.VERSION_6) { - // PKESK v6 stores the cipher algorithm in the SEIPD v2 packet fields. + // PKESK v5 stores the cipher algorithm in the SEIPD v2 packet fields. return ((SymmetricEncIntegrityPacket)encData).getCipherAlgorithm(); } else @@ -98,57 +98,16 @@ public PGPSessionKey getSessionKey( PublicKeyDataDecryptorFactory dataDecryptorFactory) throws PGPException { - byte[] sessionInfo = dataDecryptorFactory.recoverSessionData(keyData, encData); - - // Confirm and discard checksum - if (containsChecksum(keyData.getAlgorithm())) - { - if (!confirmCheckSum(sessionInfo)) - { - throw new PGPException("Key checksum failed."); - } - sessionInfo = Arrays.copyOf(sessionInfo, sessionInfo.length - 2); - } - - byte[] sessionKey = Arrays.copyOfRange(sessionInfo, 1, sessionInfo.length); - int algorithm; - - // OCB (LibrePGP v5 style AEAD) - if (encData instanceof AEADEncDataPacket) + byte[] sessionData = dataDecryptorFactory.recoverSessionData(keyData.getAlgorithm(), keyData.getEncSessionKey()); + if (keyData.getAlgorithm() == PublicKeyAlgorithmTags.X25519 || keyData.getAlgorithm() == PublicKeyAlgorithmTags.X448) { - algorithm = ((AEADEncDataPacket) encData).getAlgorithm(); - } - - // SEIPD (OpenPGP v4 / OpenPGP v6) - else if (encData instanceof SymmetricEncIntegrityPacket) - { - SymmetricEncIntegrityPacket seipd = (SymmetricEncIntegrityPacket) encData; - if (seipd.getVersion() == SymmetricEncIntegrityPacket.VERSION_1) - { - algorithm = sessionInfo[0]; - } - else if (seipd.getVersion() == SymmetricEncIntegrityPacket.VERSION_2) - { - algorithm = seipd.getCipherAlgorithm(); - } - else - { - throw new UnsupportedPacketVersionException("Unsupported SEIPD packet version: " + seipd.getVersion()); - } + return new PGPSessionKey(sessionData[0] & 0xff, Arrays.copyOfRange(sessionData, 1, sessionData.length)); } - // SED (Legacy, no integrity protection!) - else + if (!confirmCheckSum(sessionData)) { - algorithm = sessionInfo[0]; + throw new PGPKeyValidationException("key checksum failed"); } - - return new PGPSessionKey(algorithm & 0xff, sessionKey); - } - - private boolean containsChecksum(int algorithm) - { - return algorithm != PublicKeyAlgorithmTags.X25519 && - algorithm != PublicKeyAlgorithmTags.X448; + return new PGPSessionKey(sessionData[0] & 0xff, Arrays.copyOfRange(sessionData, 1, sessionData.length - 2)); } /** @@ -210,38 +169,13 @@ private InputStream getDataStream( } else { + boolean withIntegrityPacket = encData instanceof SymmetricEncIntegrityPacket; - if (encData instanceof SymmetricEncIntegrityPacket) - { - SymmetricEncIntegrityPacket seipd = (SymmetricEncIntegrityPacket) encData; - // SEIPD v1 (OpenPGP v4) - if (seipd.getVersion() == SymmetricEncIntegrityPacket.VERSION_1) - { - PGPDataDecryptor dataDecryptor = dataDecryptorFactory.createDataDecryptor(true, sessionKey.getAlgorithm(), sessionKey.getKey()); - - BCPGInputStream encIn = encData.getInputStream(); + PGPDataDecryptor dataDecryptor = dataDecryptorFactory.createDataDecryptor(withIntegrityPacket, sessionKey.getAlgorithm(), sessionKey.getKey()); - processSymmetricEncIntegrityPacketDataStream(true, dataDecryptor, encIn); - } - // SEIPD v2 (OpenPGP v6 AEAD) - else - { - PGPDataDecryptor dataDecryptor = dataDecryptorFactory.createDataDecryptor(seipd, sessionKey); - - BCPGInputStream encIn = encData.getInputStream(); - - encStream = new BCPGInputStream(dataDecryptor.getInputStream(encIn)); - } - } - // SED (Symmetrically Encrypted Data without Integrity Protection; Deprecated) - else - { - PGPDataDecryptor dataDecryptor = dataDecryptorFactory.createDataDecryptor(false, sessionKey.getAlgorithm(), sessionKey.getKey()); - - BCPGInputStream encIn = encData.getInputStream(); + BCPGInputStream encIn = encData.getInputStream(); - processSymmetricEncIntegrityPacketDataStream(false, dataDecryptor, encIn); - } + processSymmetricEncIntegrityPacketDataStream(withIntegrityPacket, dataDecryptor, encIn); // // some versions of PGP appear to produce 0 for the extra diff --git a/pg/src/main/java/org/bouncycastle/openpgp/operator/AbstractPublicKeyDataDecryptorFactory.java b/pg/src/main/java/org/bouncycastle/openpgp/operator/AbstractPublicKeyDataDecryptorFactory.java deleted file mode 100644 index 1646a90ea2..0000000000 --- a/pg/src/main/java/org/bouncycastle/openpgp/operator/AbstractPublicKeyDataDecryptorFactory.java +++ /dev/null @@ -1,76 +0,0 @@ -package org.bouncycastle.openpgp.operator; - -import org.bouncycastle.bcpg.InputStreamPacket; -import org.bouncycastle.bcpg.PublicKeyAlgorithmTags; -import org.bouncycastle.bcpg.PublicKeyEncSessionPacket; -import org.bouncycastle.bcpg.SymmetricEncIntegrityPacket; -import org.bouncycastle.bcpg.X25519PublicBCPGKey; -import org.bouncycastle.bcpg.X448PublicBCPGKey; -import org.bouncycastle.openpgp.PGPException; -import org.bouncycastle.util.Arrays; - -public abstract class AbstractPublicKeyDataDecryptorFactory - implements PublicKeyDataDecryptorFactory -{ - - @Override - public final byte[] recoverSessionData(PublicKeyEncSessionPacket pkesk, InputStreamPacket encData) - throws PGPException - { - byte[] sessionData = recoverSessionData(pkesk.getAlgorithm(), pkesk.getEncSessionKey(), pkesk.getVersion()); - return prependSKAlgorithmToSessionData(pkesk, encData, sessionData); - } - - - protected byte[] prependSKAlgorithmToSessionData(PublicKeyEncSessionPacket pkesk, - InputStreamPacket encData, - byte[] decryptedSessionData) - throws PGPException - { - // V6 PKESK packets do not include the session key algorithm, so source it from the SEIPD2 instead - if (!containsSKAlg(pkesk.getVersion())) - { - if (!(encData instanceof SymmetricEncIntegrityPacket) || - ((SymmetricEncIntegrityPacket) encData).getVersion() != SymmetricEncIntegrityPacket.VERSION_2) - { - throw new PGPException("v6 PKESK packet MUST precede v2 SEIPD packet"); - } - - SymmetricEncIntegrityPacket seipd2 = (SymmetricEncIntegrityPacket) encData; - return Arrays.prepend(decryptedSessionData, - (byte) (seipd2.getCipherAlgorithm() & 0xff)); - } - // V3 PKESK does store the session key algorithm either encrypted or unencrypted, depending on the PK algorithm - else - { - switch (pkesk.getAlgorithm()) - { - case PublicKeyAlgorithmTags.X25519: - // X25519 does not encrypt SK algorithm - return Arrays.prepend(decryptedSessionData, - pkesk.getEncSessionKey()[0][X25519PublicBCPGKey.LENGTH + 1]); - case PublicKeyAlgorithmTags.X448: - // X448 does not encrypt SK algorithm - return Arrays.prepend(decryptedSessionData, - pkesk.getEncSessionKey()[0][X448PublicBCPGKey.LENGTH + 1]); - default: - // others already prepended session key algorithm to session key - return decryptedSessionData; - } - } - } - - protected boolean containsSKAlg(int pkeskVersion) - { - return pkeskVersion != PublicKeyEncSessionPacket.VERSION_6; - } - - protected static void checkRange(int pLen, byte[] enc) - throws PGPException - { - if (pLen > enc.length) - { - throw new PGPException("encoded length out of range"); - } - } -} diff --git a/pg/src/main/java/org/bouncycastle/openpgp/operator/PublicKeyDataDecryptorFactory.java b/pg/src/main/java/org/bouncycastle/openpgp/operator/PublicKeyDataDecryptorFactory.java index cc5420ddbc..1d358ff4e2 100644 --- a/pg/src/main/java/org/bouncycastle/openpgp/operator/PublicKeyDataDecryptorFactory.java +++ b/pg/src/main/java/org/bouncycastle/openpgp/operator/PublicKeyDataDecryptorFactory.java @@ -1,39 +1,10 @@ package org.bouncycastle.openpgp.operator; -import org.bouncycastle.bcpg.InputStreamPacket; -import org.bouncycastle.bcpg.PublicKeyEncSessionPacket; import org.bouncycastle.openpgp.PGPException; public interface PublicKeyDataDecryptorFactory extends PGPDataDecryptorFactory { - /** - * Recover the plain session info by decrypting the encrypted session key. - * The session info ALWAYS has the symmetric algorithm ID prefixed, so the return value is: - *
[sym-alg][session-key][checksum]?
- * - * @param pkesk public-key encrypted session-key packet - * @param encData encrypted data (sed/seipd/oed) packet - * @return decrypted session info - * @throws PGPException - */ - byte[] recoverSessionData(PublicKeyEncSessionPacket pkesk, InputStreamPacket encData) + byte[] recoverSessionData(int keyAlgorithm, byte[][] secKeyData) throws PGPException; - - /** - * Recover the plain session info by decrypting the encrypted session key. - * This method returns the decrypted session info as-is (without prefixing missing cipher algorithm), - * so the return value is: - *
[sym-alg]?[session-key][checksum]?
- * - * @deprecated use {@link #recoverSessionData(PublicKeyEncSessionPacket, InputStreamPacket)} instead. - * @param keyAlgorithm public key algorithm - * @param secKeyData encrypted session key data - * @param pkeskVersion version of the PKESK packet - * @return decrypted session info - * @throws PGPException - */ - byte[] recoverSessionData(int keyAlgorithm, byte[][] secKeyData, int pkeskVersion) - throws PGPException; - } diff --git a/pg/src/main/java/org/bouncycastle/openpgp/operator/bc/BcPublicKeyDataDecryptorFactory.java b/pg/src/main/java/org/bouncycastle/openpgp/operator/bc/BcPublicKeyDataDecryptorFactory.java index 5ce728f7be..3d5d066d50 100644 --- a/pg/src/main/java/org/bouncycastle/openpgp/operator/bc/BcPublicKeyDataDecryptorFactory.java +++ b/pg/src/main/java/org/bouncycastle/openpgp/operator/bc/BcPublicKeyDataDecryptorFactory.java @@ -3,14 +3,11 @@ import java.io.IOException; import java.math.BigInteger; -import org.bouncycastle.asn1.cryptlib.CryptlibObjectIdentifiers; import org.bouncycastle.asn1.edec.EdECObjectIdentifiers; import org.bouncycastle.bcpg.AEADEncDataPacket; import org.bouncycastle.bcpg.ECDHPublicBCPGKey; import org.bouncycastle.bcpg.HashAlgorithmTags; -import org.bouncycastle.bcpg.InputStreamPacket; import org.bouncycastle.bcpg.PublicKeyAlgorithmTags; -import org.bouncycastle.bcpg.PublicKeyEncSessionPacket; import org.bouncycastle.bcpg.SymmetricEncIntegrityPacket; import org.bouncycastle.bcpg.SymmetricKeyAlgorithmTags; import org.bouncycastle.bcpg.X25519PublicBCPGKey; @@ -19,6 +16,7 @@ import org.bouncycastle.crypto.BlockCipher; import org.bouncycastle.crypto.BufferedAsymmetricBlockCipher; import org.bouncycastle.crypto.InvalidCipherTextException; +import org.bouncycastle.crypto.RawAgreement; import org.bouncycastle.crypto.Wrapper; import org.bouncycastle.crypto.agreement.ECDHBasicAgreement; import org.bouncycastle.crypto.agreement.X25519Agreement; @@ -34,9 +32,9 @@ import org.bouncycastle.openpgp.PGPException; import org.bouncycastle.openpgp.PGPPrivateKey; import org.bouncycastle.openpgp.PGPSessionKey; -import org.bouncycastle.openpgp.operator.AbstractPublicKeyDataDecryptorFactory; import org.bouncycastle.openpgp.operator.PGPDataDecryptor; import org.bouncycastle.openpgp.operator.PGPPad; +import org.bouncycastle.openpgp.operator.PublicKeyDataDecryptorFactory; import org.bouncycastle.openpgp.operator.RFC6637Utils; import org.bouncycastle.util.Arrays; import org.bouncycastle.util.BigIntegers; @@ -45,7 +43,7 @@ * A decryptor factory for handling public key decryption operations. */ public class BcPublicKeyDataDecryptorFactory - extends AbstractPublicKeyDataDecryptorFactory + implements PublicKeyDataDecryptorFactory { private static final BcPGPKeyConverter KEY_CONVERTER = new BcPGPKeyConverter(); @@ -57,34 +55,146 @@ public BcPublicKeyDataDecryptorFactory(PGPPrivateKey pgpPrivKey) } @Override - public byte[] recoverSessionData(int keyAlgorithm, byte[][] secKeyData, int pkeskVersion) + public byte[] recoverSessionData(int keyAlgorithm, byte[][] secKeyData) throws PGPException { - boolean containsSKAlg = containsSKAlg(pkeskVersion); try { AsymmetricKeyParameter privKey = KEY_CONVERTER.getPrivateKey(pgpPrivKey); if (keyAlgorithm == PublicKeyAlgorithmTags.X25519) { - return recoverX25519SessionData(secKeyData, privKey, containsSKAlg); + return getSessionData(secKeyData[0], privKey, X25519PublicBCPGKey.LENGTH, HashAlgorithmTags.SHA256, + SymmetricKeyAlgorithmTags.AES_128, new X25519Agreement(), "X25519", new PublicKeyParametersOperation() + { + @Override + public AsymmetricKeyParameter getPublicKeyParameters(byte[] pEnc, int pEncOff) + { + return new X25519PublicKeyParameters(pEnc, 0); + } + }); } else if (keyAlgorithm == PublicKeyAlgorithmTags.X448) { - return recoverX448SessionData(secKeyData, privKey, containsSKAlg); + return getSessionData(secKeyData[0], privKey, X448PublicBCPGKey.LENGTH, HashAlgorithmTags.SHA512, + SymmetricKeyAlgorithmTags.AES_256, new X448Agreement(), "X448", new PublicKeyParametersOperation() + { + @Override + public AsymmetricKeyParameter getPublicKeyParameters(byte[] pEnc, int pEncOff) + { + return new X448PublicKeyParameters(pEnc, 0); + } + }); } else if (keyAlgorithm == PublicKeyAlgorithmTags.ECDH) { - return recoverECDHSessionData(secKeyData, privKey); - } - else if (keyAlgorithm == PublicKeyAlgorithmTags.RSA_ENCRYPT || - keyAlgorithm == PublicKeyAlgorithmTags.RSA_GENERAL) - { - return recoverRSASessionData(keyAlgorithm, secKeyData, privKey); + byte[] enc = secKeyData[0]; + byte[] pEnc; + byte[] keyEnc; + int pLen = ((((enc[0] & 0xff) << 8) + (enc[1] & 0xff)) + 7) / 8; + assertOutOfRange(2 + pLen + 1, enc); + + pEnc = new byte[pLen]; + System.arraycopy(enc, 2, pEnc, 0, pLen); + + int keyLen = enc[pLen + 2] & 0xff; + assertOutOfRange(2 + pLen + 1 + keyLen, enc); + + keyEnc = new byte[keyLen]; + System.arraycopy(enc, 2 + pLen + 1, keyEnc, 0, keyLen); + + byte[] secret; + RFC6637KDFCalculator rfc6637KDFCalculator; + byte[] userKeyingMaterial; + int symmetricKeyAlgorithm, hashAlgorithm; + + ECDHPublicBCPGKey ecPubKey = (ECDHPublicBCPGKey)pgpPrivKey.getPublicKeyPacket().getKey(); + // XDH + if (BcUtil.isX25519(ecPubKey.getCurveOID())) + { + if (pEnc.length != 1 + X25519PublicKeyParameters.KEY_SIZE || 0x40 != pEnc[0]) + { + throw new IllegalArgumentException("Invalid Curve25519 public key"); + } + // skip the 0x40 header byte. + secret = BcUtil.getSecret(new X25519Agreement(), privKey, new X25519PublicKeyParameters(pEnc, 1)); + } + else if (ecPubKey.getCurveOID().equals(EdECObjectIdentifiers.id_X448)) + { + if (pEnc.length != 1 + X448PublicKeyParameters.KEY_SIZE || 0x40 != pEnc[0]) + { + throw new IllegalArgumentException("Invalid Curve448 public key"); + } + // skip the 0x40 header byte. + secret = BcUtil.getSecret(new X448Agreement(), privKey, new X448PublicKeyParameters(pEnc, 1)); + } + else + { + ECDomainParameters ecParameters = ((ECPrivateKeyParameters)privKey).getParameters(); + + ECPublicKeyParameters ephPub = new ECPublicKeyParameters(ecParameters.getCurve().decodePoint(pEnc), + ecParameters); + + ECDHBasicAgreement agreement = new ECDHBasicAgreement(); + agreement.init(privKey); + BigInteger S = agreement.calculateAgreement(ephPub); + secret = BigIntegers.asUnsignedByteArray(agreement.getFieldSize(), S); + } + hashAlgorithm = ecPubKey.getHashAlgorithm(); + symmetricKeyAlgorithm = ecPubKey.getSymmetricKeyAlgorithm(); + userKeyingMaterial = RFC6637Utils.createUserKeyingMaterial(pgpPrivKey.getPublicKeyPacket(), new BcKeyFingerprintCalculator()); + rfc6637KDFCalculator = new RFC6637KDFCalculator(new BcPGPDigestCalculatorProvider().get(hashAlgorithm), symmetricKeyAlgorithm); + KeyParameter key = new KeyParameter(rfc6637KDFCalculator.createKey(secret, userKeyingMaterial)); + + return PGPPad.unpadSessionData(unwrapSessionData(keyEnc, symmetricKeyAlgorithm, key)); } else { - return recoverElgamalSessionData(keyAlgorithm, secKeyData, privKey); + AsymmetricBlockCipher c = BcImplProvider.createPublicKeyCipher(keyAlgorithm); + + BufferedAsymmetricBlockCipher c1 = new BufferedAsymmetricBlockCipher(c); + + c1.init(false, privKey); + + if (keyAlgorithm == PublicKeyAlgorithmTags.RSA_ENCRYPT + || keyAlgorithm == PublicKeyAlgorithmTags.RSA_GENERAL) + { + byte[] bi = secKeyData[0]; + + c1.processBytes(bi, 2, bi.length - 2); + } + else + { + ElGamalPrivateKeyParameters parms = (ElGamalPrivateKeyParameters)privKey; + int size = (parms.getParameters().getP().bitLength() + 7) / 8; + byte[] tmp = new byte[size]; + + byte[] bi = secKeyData[0]; // encoded MPI + if (bi.length - 2 > size) // leading Zero? Shouldn't happen but... + { + c1.processBytes(bi, 3, bi.length - 3); + } + else + { + System.arraycopy(bi, 2, tmp, tmp.length - (bi.length - 2), bi.length - 2); + c1.processBytes(tmp, 0, tmp.length); + } + + bi = secKeyData[1]; // encoded MPI + Arrays.fill(tmp, (byte)0); + + if (bi.length - 2 > size) // leading Zero? Shouldn't happen but... + { + c1.processBytes(bi, 3, bi.length - 3); + } + else + { + System.arraycopy(bi, 2, tmp, tmp.length - (bi.length - 2), bi.length - 2); + c1.processBytes(tmp, 0, tmp.length); + } + } + + return c1.doFinal(); } } catch (IOException e) @@ -97,176 +207,6 @@ else if (keyAlgorithm == PublicKeyAlgorithmTags.RSA_ENCRYPT || } } - private byte[] recoverElgamalSessionData(int keyAlgorithm, - byte[][] secKeyData, - AsymmetricKeyParameter privKey) - throws PGPException, InvalidCipherTextException - { - AsymmetricBlockCipher c = BcImplProvider.createPublicKeyCipher(keyAlgorithm); - - BufferedAsymmetricBlockCipher c1 = new BufferedAsymmetricBlockCipher(c); - - c1.init(false, privKey); - - ElGamalPrivateKeyParameters parms = (ElGamalPrivateKeyParameters) privKey; - int size = (parms.getParameters().getP().bitLength() + 7) / 8; - byte[] tmp = new byte[size]; - - byte[] bi = secKeyData[0]; // encoded MPI - if (bi.length - 2 > size) // leading Zero? Shouldn't happen but... - { - c1.processBytes(bi, 3, bi.length - 3); - } - else - { - System.arraycopy(bi, 2, tmp, tmp.length - (bi.length - 2), bi.length - 2); - c1.processBytes(tmp, 0, tmp.length); - } - - bi = secKeyData[1]; // encoded MPI - Arrays.fill(tmp, (byte)0); - - if (bi.length - 2 > size) // leading Zero? Shouldn't happen but... - { - c1.processBytes(bi, 3, bi.length - 3); - } - else - { - System.arraycopy(bi, 2, tmp, tmp.length - (bi.length - 2), bi.length - 2); - c1.processBytes(tmp, 0, tmp.length); - } - - return c1.doFinal(); - } - - private byte[] recoverRSASessionData(int keyAlgorithm, - byte[][] secKeyData, - AsymmetricKeyParameter privKey) - throws PGPException, InvalidCipherTextException - { - AsymmetricBlockCipher c = BcImplProvider.createPublicKeyCipher(keyAlgorithm); - BufferedAsymmetricBlockCipher c1 = new BufferedAsymmetricBlockCipher(c); - c1.init(false, privKey); - byte[] bi = secKeyData[0]; - c1.processBytes(bi, 2, bi.length - 2); - return c1.doFinal(); - } - - private byte[] recoverECDHSessionData(byte[][] secKeyData, - AsymmetricKeyParameter privKey) - throws PGPException, IOException, InvalidCipherTextException - { - byte[] enc = secKeyData[0]; - byte[] pEnc; - byte[] keyEnc; - int pLen = ((((enc[0] & 0xff) << 8) + (enc[1] & 0xff)) + 7) / 8; - checkRange(2 + pLen + 1, enc); - - pEnc = new byte[pLen]; - System.arraycopy(enc, 2, pEnc, 0, pLen); - - int keyLen = enc[pLen + 2] & 0xff; - checkRange(2 + pLen + 1 + keyLen, enc); - - keyEnc = new byte[keyLen]; - System.arraycopy(enc, 2 + pLen + 1, keyEnc, 0, keyLen); - - byte[] secret; - RFC6637KDFCalculator rfc6637KDFCalculator; - byte[] userKeyingMaterial; - int symmetricKeyAlgorithm, hashAlgorithm; - - ECDHPublicBCPGKey ecPubKey = (ECDHPublicBCPGKey)pgpPrivKey.getPublicKeyPacket().getKey(); - // XDH - if (ecPubKey.getCurveOID().equals(CryptlibObjectIdentifiers.curvey25519)) - { - if (pEnc.length != 1 + X25519PublicKeyParameters.KEY_SIZE || 0x40 != pEnc[0]) - { - throw new IllegalArgumentException("Invalid Curve25519 public key"); - } - // skip the 0x40 header byte. - secret = BcUtil.getSecret(new X25519Agreement(), privKey, new X25519PublicKeyParameters(pEnc, 1)); - } - else if (ecPubKey.getCurveOID().equals(EdECObjectIdentifiers.id_X448)) - { - if (pEnc.length != 1 + X448PublicKeyParameters.KEY_SIZE || 0x40 != pEnc[0]) - { - throw new IllegalArgumentException("Invalid Curve448 public key"); - } - // skip the 0x40 header byte. - secret = BcUtil.getSecret(new X448Agreement(), privKey, new X448PublicKeyParameters(pEnc, 1)); - } - else - { - ECDomainParameters ecParameters = ((ECPrivateKeyParameters) privKey).getParameters(); - - ECPublicKeyParameters ephPub = new ECPublicKeyParameters(ecParameters.getCurve().decodePoint(pEnc), - ecParameters); - - ECDHBasicAgreement agreement = new ECDHBasicAgreement(); - agreement.init(privKey); - BigInteger S = agreement.calculateAgreement(ephPub); - secret = BigIntegers.asUnsignedByteArray(agreement.getFieldSize(), S); - } - hashAlgorithm = ecPubKey.getHashAlgorithm(); - symmetricKeyAlgorithm = ecPubKey.getSymmetricKeyAlgorithm(); - userKeyingMaterial = RFC6637Utils.createUserKeyingMaterial(pgpPrivKey.getPublicKeyPacket(), new BcKeyFingerprintCalculator()); - rfc6637KDFCalculator = new RFC6637KDFCalculator(new BcPGPDigestCalculatorProvider().get(hashAlgorithm), symmetricKeyAlgorithm); - KeyParameter key = new KeyParameter(rfc6637KDFCalculator.createKey(secret, userKeyingMaterial)); - - return PGPPad.unpadSessionData(unwrapSessionData(keyEnc, symmetricKeyAlgorithm, key)); - } - - private byte[] recoverX25519SessionData(byte[][] secKeyData, AsymmetricKeyParameter privKey, boolean includesSesKeyAlg) - throws PGPException, InvalidCipherTextException - { - byte[] enc = secKeyData[0]; - // 32 octets ephemeral key - int pLen = X25519PublicBCPGKey.LENGTH; - byte[] ephemeralKey = Arrays.copyOf(enc, pLen); - - // size of following fields - int size = enc[pLen] & 0xff; - checkRange(pLen + 1 + size, enc); - - // encrypted session key - int sesKeyLen = size - (includesSesKeyAlg ? 1 : 0); - int sesKeyOff = pLen + 1 + (includesSesKeyAlg ? 1 : 0); - byte[] keyEnc = Arrays.copyOfRange(enc, sesKeyOff, sesKeyOff + sesKeyLen); - - byte[] secret = BcUtil.getSecret(new X25519Agreement(), privKey, new X25519PublicKeyParameters(ephemeralKey, 0)); - - byte[] hkdfOut = RFC6637KDFCalculator.createKey(HashAlgorithmTags.SHA256, SymmetricKeyAlgorithmTags.AES_128, - Arrays.concatenate(ephemeralKey, pgpPrivKey.getPublicKeyPacket().getKey().getEncoded(), secret), - "OpenPGP X25519"); - - return unwrapSessionData(keyEnc, SymmetricKeyAlgorithmTags.AES_128, new KeyParameter(hkdfOut)); - } - - private byte[] recoverX448SessionData(byte[][] secKeyData, AsymmetricKeyParameter privKey, boolean includesSesKeyAlg) - throws PGPException, InvalidCipherTextException - { - byte[] enc = secKeyData[0]; - // 56 octets ephemeral key - int pLen = X448PublicBCPGKey.LENGTH; - byte[] ephemeralKey = Arrays.copyOf(enc, pLen); - - // size of the following fields - int size = enc[pLen] & 0xff; - checkRange(pLen + 1 + size, enc); - - // encrypted session key - int sesKeyLen = size - (includesSesKeyAlg ? 1 : 0); - int sesKeyOff = pLen + 1 + (includesSesKeyAlg ? 1 : 0); - byte[] encSesKey = Arrays.copyOfRange(enc, sesKeyOff, sesKeyOff + sesKeyLen); - - byte[] secret = BcUtil.getSecret(new X448Agreement(), privKey, new X448PublicKeyParameters(ephemeralKey, 0)); - KeyParameter key = new KeyParameter(RFC6637KDFCalculator.createKey(HashAlgorithmTags.SHA512, SymmetricKeyAlgorithmTags.AES_256, - Arrays.concatenate(ephemeralKey, pgpPrivKey.getPublicKeyPacket().getKey().getEncoded(), secret), "OpenPGP X448")); - - return unwrapSessionData(encSesKey, SymmetricKeyAlgorithmTags.AES_256, key); - } - // OpenPGP v4 @Override public PGPDataDecryptor createDataDecryptor(boolean withIntegrityPacket, int encAlgorithm, byte[] key) @@ -293,6 +233,30 @@ public PGPDataDecryptor createDataDecryptor(SymmetricEncIntegrityPacket seipd, P return BcAEADUtil.createOpenPgpV6DataDecryptor(seipd, sessionKey); } + @FunctionalInterface + private interface PublicKeyParametersOperation + { + AsymmetricKeyParameter getPublicKeyParameters(byte[] pEnc, int pEncOff); + } + + private byte[] getSessionData(byte[] enc, AsymmetricKeyParameter privKey, int pLen, int hashAlgorithm, int symmetricKeyAlgorithm, + RawAgreement agreement, String algorithmName, PublicKeyParametersOperation pkp) + throws PGPException, InvalidCipherTextException + { + byte[] pEnc = new byte[pLen]; + byte[] keyEnc; + System.arraycopy(enc, 0, pEnc, 0, pLen); + int keyLen = enc[pLen] & 0xff; + assertOutOfRange(pLen + 1 + keyLen, enc); + keyEnc = new byte[keyLen - 1]; + System.arraycopy(enc, pLen + 2, keyEnc, 0, keyEnc.length); + byte[] secret = BcUtil.getSecret(agreement, privKey, pkp.getPublicKeyParameters(pEnc, 0)); + KeyParameter key = new KeyParameter(RFC6637KDFCalculator.createKey(hashAlgorithm, symmetricKeyAlgorithm, + Arrays.concatenate(pEnc, pgpPrivKey.getPublicKeyPacket().getKey().getEncoded(), secret), "OpenPGP " + algorithmName)); + + return Arrays.prepend(unwrapSessionData(keyEnc, symmetricKeyAlgorithm, key), enc[pLen + 1]); + } + private static byte[] unwrapSessionData(byte[] keyEnc, int symmetricKeyAlgorithm, KeyParameter key) throws PGPException, InvalidCipherTextException { @@ -300,4 +264,13 @@ private static byte[] unwrapSessionData(byte[] keyEnc, int symmetricKeyAlgorithm c.init(false, key); return c.unwrap(keyEnc, 0, keyEnc.length); } + + private static void assertOutOfRange(int pLen, byte[] enc) + throws PGPException + { + if (pLen > enc.length) + { + throw new PGPException("encoded length out of range"); + } + } } \ No newline at end of file diff --git a/pg/src/main/java/org/bouncycastle/openpgp/operator/jcajce/JcaJcePGPUtil.java b/pg/src/main/java/org/bouncycastle/openpgp/operator/jcajce/JcaJcePGPUtil.java index 51b944e3ff..d87663a715 100644 --- a/pg/src/main/java/org/bouncycastle/openpgp/operator/jcajce/JcaJcePGPUtil.java +++ b/pg/src/main/java/org/bouncycastle/openpgp/operator/jcajce/JcaJcePGPUtil.java @@ -70,7 +70,7 @@ static X9ECParameters getX9Parameters(ASN1ObjectIdentifier curveOID) static HybridValueParameterSpec getHybridValueParameterSpecWithPrepend(byte[] ephmeralPublicKey, PublicKeyPacket pkp, String algorithmName) throws IOException { - return new HybridValueParameterSpec(Arrays.concatenate(ephmeralPublicKey, pkp.getKey().getEncoded()), true, new UserKeyingMaterialSpec(Strings.toByteArray("OpenPGP " + algorithmName))); + return new HybridValueParameterSpec(Arrays.concatenate(ephmeralPublicKey, pkp.getEncoded()), true, new UserKeyingMaterialSpec(Strings.toByteArray("OpenPGP " + algorithmName))); } static Key getSecret(OperatorHelper helper, PublicKey cryptoPublicKey, String keyEncryptionOID, String agreementName, AlgorithmParameterSpec ukmSpec, Key privKey) diff --git a/pg/src/main/java/org/bouncycastle/openpgp/operator/jcajce/JcePublicKeyDataDecryptorFactoryBuilder.java b/pg/src/main/java/org/bouncycastle/openpgp/operator/jcajce/JcePublicKeyDataDecryptorFactoryBuilder.java index 97cd99be06..ecdfa24576 100644 --- a/pg/src/main/java/org/bouncycastle/openpgp/operator/jcajce/JcePublicKeyDataDecryptorFactoryBuilder.java +++ b/pg/src/main/java/org/bouncycastle/openpgp/operator/jcajce/JcePublicKeyDataDecryptorFactoryBuilder.java @@ -39,7 +39,6 @@ import org.bouncycastle.openpgp.PGPPrivateKey; import org.bouncycastle.openpgp.PGPPublicKey; import org.bouncycastle.openpgp.PGPSessionKey; -import org.bouncycastle.openpgp.operator.AbstractPublicKeyDataDecryptorFactory; import org.bouncycastle.openpgp.operator.PGPDataDecryptor; import org.bouncycastle.openpgp.operator.PGPPad; import org.bouncycastle.openpgp.operator.PublicKeyDataDecryptorFactory; @@ -128,12 +127,12 @@ else if (key instanceof RSAKey) public PublicKeyDataDecryptorFactory build(final PrivateKey privKey) { - return new AbstractPublicKeyDataDecryptorFactory() + return new PublicKeyDataDecryptorFactory() { final int expectedPayLoadSize = getExpectedPayloadSize(privKey); @Override - public byte[] recoverSessionData(int keyAlgorithm, byte[][] secKeyData, int pkeskVersion) + public byte[] recoverSessionData(int keyAlgorithm, byte[][] secKeyData) throws PGPException { if (keyAlgorithm == PublicKeyAlgorithmTags.ECDH || keyAlgorithm == PublicKeyAlgorithmTags.X25519 || keyAlgorithm == PublicKeyAlgorithmTags.X448) @@ -171,13 +170,12 @@ public PGPDataDecryptor createDataDecryptor(SymmetricEncIntegrityPacket seipd, P public PublicKeyDataDecryptorFactory build(final PGPPrivateKey privKey) { - return new AbstractPublicKeyDataDecryptorFactory() + return new PublicKeyDataDecryptorFactory() { @Override - public byte[] recoverSessionData(int keyAlgorithm, byte[][] secKeyData, int pkeskVersion) + public byte[] recoverSessionData(int keyAlgorithm, byte[][] secKeyData) throws PGPException { - boolean containsSKAlg = containsSKAlg(pkeskVersion); if (keyAlgorithm == PublicKeyAlgorithmTags.ECDH) { return decryptSessionData(keyConverter, privKey, secKeyData); @@ -185,12 +183,12 @@ public byte[] recoverSessionData(int keyAlgorithm, byte[][] secKeyData, int pkes else if (keyAlgorithm == PublicKeyAlgorithmTags.X25519) { return decryptSessionData(keyConverter, privKey, secKeyData[0], X25519PublicBCPGKey.LENGTH, "X25519withSHA256HKDF", - SymmetricKeyAlgorithmTags.AES_128, EdECObjectIdentifiers.id_X25519, "X25519", containsSKAlg); + SymmetricKeyAlgorithmTags.AES_128, EdECObjectIdentifiers.id_X25519, "X25519"); } else if (keyAlgorithm == PublicKeyAlgorithmTags.X448) { return decryptSessionData(keyConverter, privKey, secKeyData[0], X448PublicBCPGKey.LENGTH, "X448withSHA512HKDF", - SymmetricKeyAlgorithmTags.AES_256, EdECObjectIdentifiers.id_X448, "X448", containsSKAlg); + SymmetricKeyAlgorithmTags.AES_256, EdECObjectIdentifiers.id_X448, "X448"); } PrivateKey jcePrivKey = keyConverter.getPrivateKey(privKey); int expectedPayLoadSize = getExpectedPayloadSize(jcePrivKey); @@ -224,14 +222,6 @@ public PGPDataDecryptor createDataDecryptor(SymmetricEncIntegrityPacket seipd, P }; } - /** - * Decrypt ECDH encrypted session keys. - * @param converter key converter - * @param privKey our private key - * @param secKeyData encrypted session key - * @return decrypted session key - * @throws PGPException - */ private byte[] decryptSessionData(JcaPGPKeyConverter converter, PGPPrivateKey privKey, byte[][] secKeyData) throws PGPException { @@ -243,12 +233,18 @@ private byte[] decryptSessionData(JcaPGPKeyConverter converter, PGPPrivateKey pr byte[] keyEnc; pLen = ((((enc[0] & 0xff) << 8) + (enc[1] & 0xff)) + 7) / 8; - checkRange(2 + pLen + 1, enc); + if ((2 + pLen + 1) > enc.length) + { + throw new PGPException("encoded length out of range"); + } pEnc = new byte[pLen]; System.arraycopy(enc, 2, pEnc, 0, pLen); int keyLen = enc[pLen + 2] & 0xff; - checkRange(2 + pLen + 1 + keyLen, enc); + if ((2 + pLen + 1 + keyLen) > enc.length) + { + throw new PGPException("encoded length out of range"); + } keyEnc = new byte[keyLen]; System.arraycopy(enc, 2 + pLen + 1, keyEnc, 0, keyLen); @@ -299,42 +295,26 @@ else if (ecKey.getCurveOID().equals(EdECObjectIdentifiers.id_X448)) } } - /** - * Decrypt X25519 / X448 encrypted session keys. - * @param converter key converter - * @param privKey our private key - * @param enc encrypted session key - * @param pLen Key length - * @param agreementAlgorithm agreement algorithm - * @param symmetricKeyAlgorithm wrapping algorithm - * @param algorithmIdentifier ephemeral key algorithm identifier - * @param algorithmName public key algorithm name - * @param containsSKAlg whether the PKESK packet is version 3 - * @return decrypted session data - * @throws PGPException - */ private byte[] decryptSessionData(JcaPGPKeyConverter converter, PGPPrivateKey privKey, byte[] enc, int pLen, String agreementAlgorithm, - int symmetricKeyAlgorithm, ASN1ObjectIdentifier algorithmIdentifier, String algorithmName, boolean containsSKAlg) + int symmetricKeyAlgorithm, ASN1ObjectIdentifier algprithmIdentifier, String algorithmName) throws PGPException { try { - // ephemeral key (32 / 56 octets) - byte[] ephemeralKey = Arrays.copyOf(enc, pLen); - - int size = enc[pLen] & 0xff; - - checkRange(pLen + 1 + size, enc); - - // encrypted session key - int sesKeyLen = size - (containsSKAlg ? 1 : 0); - int sesKeyOff = pLen + 1 + (containsSKAlg ? 1 : 0); - byte[] keyEnc = Arrays.copyOfRange(enc, sesKeyOff, sesKeyOff + sesKeyLen); - - PublicKey ephemeralPubKey = getPublicKey(ephemeralKey, algorithmIdentifier, 0); - Key paddedSessionKey = getSessionKey(converter, privKey, agreementAlgorithm, ephemeralPubKey, symmetricKeyAlgorithm, keyEnc, - JcaJcePGPUtil.getHybridValueParameterSpecWithPrepend(ephemeralKey, privKey.getPublicKeyPacket(), algorithmName)); - return paddedSessionKey.getEncoded(); + byte[] pEnc = new byte[pLen]; + System.arraycopy(enc, 0, pEnc, 0, pLen); + int keyLen = enc[pLen] & 0xff; + if ((pLen + 1 + keyLen) > enc.length) + { + throw new PGPException("encoded length out of range"); + } + byte[] keyEnc = new byte[keyLen - 1]; + System.arraycopy(enc, pLen + 2, keyEnc, 0, keyEnc.length); + PublicKey publicKey = getPublicKey(pEnc, algprithmIdentifier, 0); + Key paddedSessionKey = getSessionKey(converter, privKey, agreementAlgorithm, publicKey, symmetricKeyAlgorithm, keyEnc, + JcaJcePGPUtil.getHybridValueParameterSpecWithPrepend(pEnc, privKey.getPublicKeyPacket(), algorithmName)); + symmetricKeyAlgorithm = enc[pLen + 1] & 0xff; + return Arrays.prepend(paddedSessionKey.getEncoded(), (byte)symmetricKeyAlgorithm); } catch (Exception e) { @@ -385,15 +365,6 @@ private void updateWithMPI(Cipher c, int expectedPayloadSize, byte[] encMPI) } } - /** - * Decrypt RSA / Elgamal encrypted session keys. - * @param keyAlgorithm public key algorithm - * @param privKey our private key - * @param expectedPayloadSize payload size - * @param secKeyData ESK data - * @return session data - * @throws PGPException - */ private byte[] decryptSessionData(int keyAlgorithm, PrivateKey privKey, int expectedPayloadSize, byte[][] secKeyData) throws PGPException { @@ -429,13 +400,4 @@ private byte[] decryptSessionData(int keyAlgorithm, PrivateKey privKey, int expe throw new PGPException("exception decrypting session data", e); } } - - private static void checkRange(int pLen, byte[] enc) - throws PGPException - { - if (pLen > enc.length) - { - throw new PGPException("encoded length out of range"); - } - } } diff --git a/pg/src/test/java/org/bouncycastle/bcpg/test/AllTests.java b/pg/src/test/java/org/bouncycastle/bcpg/test/AllTests.java index 860b1a10a6..bc0cd7faaa 100644 --- a/pg/src/test/java/org/bouncycastle/bcpg/test/AllTests.java +++ b/pg/src/test/java/org/bouncycastle/bcpg/test/AllTests.java @@ -23,8 +23,7 @@ public void testPacketParsing() new SignaturePacketTest(), new OnePassSignaturePacketTest(), new OpenPgpMessageTest(), - new FingerprintUtilTest(), - new EncryptedMessagePacketTest() + new FingerprintUtilTest() }; for (int i = 0; i != tests.length; i++) diff --git a/pg/src/test/java/org/bouncycastle/bcpg/test/EncryptedMessagePacketTest.java b/pg/src/test/java/org/bouncycastle/bcpg/test/EncryptedMessagePacketTest.java deleted file mode 100644 index 0ac2800c12..0000000000 --- a/pg/src/test/java/org/bouncycastle/bcpg/test/EncryptedMessagePacketTest.java +++ /dev/null @@ -1,237 +0,0 @@ -package org.bouncycastle.bcpg.test; - -import org.bouncycastle.bcpg.AEADAlgorithmTags; -import org.bouncycastle.bcpg.ArmoredInputStream; -import org.bouncycastle.bcpg.BCPGInputStream; -import org.bouncycastle.bcpg.FingerprintUtil; -import org.bouncycastle.bcpg.PublicKeyAlgorithmTags; -import org.bouncycastle.bcpg.PublicKeyEncSessionPacket; -import org.bouncycastle.bcpg.SymmetricEncIntegrityPacket; -import org.bouncycastle.bcpg.SymmetricKeyAlgorithmTags; -import org.bouncycastle.jce.provider.BouncyCastleProvider; -import org.bouncycastle.openpgp.PGPEncryptedDataList; -import org.bouncycastle.openpgp.PGPException; -import org.bouncycastle.openpgp.PGPLiteralData; -import org.bouncycastle.openpgp.PGPObjectFactory; -import org.bouncycastle.openpgp.PGPPadding; -import org.bouncycastle.openpgp.PGPPrivateKey; -import org.bouncycastle.openpgp.PGPPublicKeyEncryptedData; -import org.bouncycastle.openpgp.PGPSecretKey; -import org.bouncycastle.openpgp.PGPSecretKeyRing; -import org.bouncycastle.openpgp.bc.BcPGPObjectFactory; -import org.bouncycastle.openpgp.jcajce.JcaPGPObjectFactory; -import org.bouncycastle.openpgp.operator.PublicKeyDataDecryptorFactory; -import org.bouncycastle.openpgp.operator.bc.BcPublicKeyDataDecryptorFactory; -import org.bouncycastle.openpgp.operator.jcajce.JcePublicKeyDataDecryptorFactoryBuilder; -import org.bouncycastle.util.Arrays; -import org.bouncycastle.util.encoders.Hex; -import org.bouncycastle.util.io.Streams; - -import java.io.ByteArrayInputStream; -import java.io.IOException; -import java.io.InputStream; -import java.nio.charset.StandardCharsets; - -public class EncryptedMessagePacketTest - extends AbstractPacketTest -{ - // https://www.rfc-editor.org/rfc/rfc9580.html#name-sample-version-6-secret-key - final String V6_SECRET_KEY = "-----BEGIN PGP PRIVATE KEY BLOCK-----\n" + - "\n" + - "xUsGY4d/4xsAAAAg+U2nu0jWCmHlZ3BqZYfQMxmZu52JGggkLq2EVD34laMAGXKB\n" + - "exK+cH6NX1hs5hNhIB00TrJmosgv3mg1ditlsLfCsQYfGwoAAABCBYJjh3/jAwsJ\n" + - "BwUVCg4IDAIWAAKbAwIeCSIhBssYbE8GCaaX5NUt+mxyKwwfHifBilZwj2Ul7Ce6\n" + - "2azJBScJAgcCAAAAAK0oIBA+LX0ifsDm185Ecds2v8lwgyU2kCcUmKfvBXbAf6rh\n" + - "RYWzuQOwEn7E/aLwIwRaLsdry0+VcallHhSu4RN6HWaEQsiPlR4zxP/TP7mhfVEe\n" + - "7XWPxtnMUMtf15OyA51YBMdLBmOHf+MZAAAAIIaTJINn+eUBXbki+PSAld2nhJh/\n" + - "LVmFsS+60WyvXkQ1AE1gCk95TUR3XFeibg/u/tVY6a//1q0NWC1X+yui3O24wpsG\n" + - "GBsKAAAALAWCY4d/4wKbDCIhBssYbE8GCaaX5NUt+mxyKwwfHifBilZwj2Ul7Ce6\n" + - "2azJAAAAAAQBIKbpGG2dWTX8j+VjFM21J0hqWlEg+bdiojWnKfA5AQpWUWtnNwDE\n" + - "M0g12vYxoWM8Y81W+bHBw805I8kWVkXU6vFOi+HWvv/ira7ofJu16NnoUkhclkUr\n" + - "k0mXubZvyl4GBg==\n" + - "-----END PGP PRIVATE KEY BLOCK-----\n"; - - // https://www.rfc-editor.org/rfc/rfc9580.html#name-complete-x25519-aead-ocb-en - final String X25519_AEAD_OCB_MESSAGE = "-----BEGIN PGP MESSAGE-----\n" + - "\n" + - "wV0GIQYSyD8ecG9jCP4VGkF3Q6HwM3kOk+mXhIjR2zeNqZMIhRmHzxjV8bU/gXzO\n" + - "WgBM85PMiVi93AZfJfhK9QmxfdNnZBjeo1VDeVZheQHgaVf7yopqR6W1FT6NOrfS\n" + - "aQIHAgZhZBZTW+CwcW1g4FKlbExAf56zaw76/prQoN+bAzxpohup69LA7JW/Vp0l\n" + - "yZnuSj3hcFj0DfqLTGgr4/u717J+sPWbtQBfgMfG9AOIwwrUBqsFE9zW+f1zdlYo\n" + - "bhF30A+IitsxxA==\n" + - "-----END PGP MESSAGE-----"; - - @Override - public String getName() - { - return "PublicKeyEncryptedDataPacketTest"; - } - - @Override - public void performTest() - throws Exception - { - testX25519AEADOCBTestVector_bc(); - testX25519AEADOCBTestVector_jce(); - testPKESK6SEIPD2FromTestVector(); - testPKESK6SEIPD2(); - } - - private void testPKESK6SEIPD2FromTestVector() - throws IOException, PGPException - { - // https://www.rfc-editor.org/rfc/rfc9580.html#name-sample-version-6-public-key - byte[] pkesk = Hex.decode("c15d06210612c83f" + - "1e706f6308fe151a" + - "417743a1f033790e" + - "93e9978488d1db37" + - "8da99308851987cf" + - "18d5f1b53f817cce" + - "5a004cf393cc8958" + - "bddc065f25f84af5" + - "09b17dd3676418de" + - "a355437956617901" + - "e06957fbca8a6a47" + - "a5b5153e8d3ab7"); - - // https://www.rfc-editor.org/rfc/rfc9580.html#name-sample-v2-seipd-packet - byte[] seipd = Hex.decode("d269020702066164" + - "16535be0b0716d60" + - "e052a56c4c407f9e" + - "b36b0efafe9ad0a0" + - "df9b033c69a21ba9" + - "ebd2c0ec95bf569d" + - "25c999ee4a3de170" + - "58f40dfa8b4c682b" + - "e3fbbbd7b27eb0f5" + - "9bb5005f80c7c6f4" + - "0388c30ad406ab05" + - "13dcd6f9fd737656" + - "286e1177d00f888a" + - "db31c4"); - - ByteArrayInputStream bIn = new ByteArrayInputStream(V6_SECRET_KEY.getBytes(StandardCharsets.UTF_8)); - ArmoredInputStream aIn = new ArmoredInputStream(bIn); - BCPGInputStream pIn = new BCPGInputStream(aIn); - PGPObjectFactory objFac = new BcPGPObjectFactory(pIn); - PGPSecretKeyRing secretKeys = (PGPSecretKeyRing) objFac.nextObject(); - - bIn = new ByteArrayInputStream(Arrays.concatenate(pkesk, seipd)); - pIn = new BCPGInputStream(bIn); - objFac = new BcPGPObjectFactory(pIn); - PGPEncryptedDataList encList = (PGPEncryptedDataList) objFac.nextObject(); - PGPPublicKeyEncryptedData encData = (PGPPublicKeyEncryptedData) encList.get(0); - PGPSecretKey decKey = secretKeys.getSecretKey(encData.getKeyID()); // TODO: getKeyIdentifier() - PGPPrivateKey privKey = decKey.extractPrivateKey(null); - PublicKeyDataDecryptorFactory decryptor = new BcPublicKeyDataDecryptorFactory(privKey); - InputStream in = encData.getDataStream(decryptor); - objFac = new BcPGPObjectFactory(in); - PGPLiteralData literalData = (PGPLiteralData) objFac.nextObject(); - byte[] msg = Streams.readAll(literalData.getDataStream()); - isEncodingEqual("Hello, world!".getBytes(StandardCharsets.UTF_8), msg); - PGPPadding padding = (PGPPadding) objFac.nextObject(); - isEncodingEqual(Hex.decode("c5a293072991628147d72c8f86b7"), padding.getPadding()); - } - - private void testX25519AEADOCBTestVector_bc() - throws IOException, PGPException - { - ByteArrayInputStream bIn = new ByteArrayInputStream(V6_SECRET_KEY.getBytes(StandardCharsets.UTF_8)); - ArmoredInputStream aIn = new ArmoredInputStream(bIn); - BCPGInputStream pIn = new BCPGInputStream(aIn); - PGPObjectFactory objFac = new BcPGPObjectFactory(pIn); - PGPSecretKeyRing secretKeys = (PGPSecretKeyRing) objFac.nextObject(); - - bIn = new ByteArrayInputStream(X25519_AEAD_OCB_MESSAGE.getBytes()); - aIn = new ArmoredInputStream(bIn); - pIn = new BCPGInputStream(aIn); - objFac = new BcPGPObjectFactory(pIn); - PGPEncryptedDataList encList = (PGPEncryptedDataList) objFac.nextObject(); - PGPPublicKeyEncryptedData encData = (PGPPublicKeyEncryptedData) encList.get(0); - PGPSecretKey decKey = secretKeys.getSecretKey(encData.getKeyID()); // TODO: getKeyIdentifier() - PGPPrivateKey privKey = decKey.extractPrivateKey(null); - PublicKeyDataDecryptorFactory decryptor = new BcPublicKeyDataDecryptorFactory(privKey); - InputStream in = encData.getDataStream(decryptor); - objFac = new BcPGPObjectFactory(in); - PGPLiteralData literalData = (PGPLiteralData) objFac.nextObject(); - byte[] plaintext = Streams.readAll(literalData.getDataStream()); - isEncodingEqual("Hello, world!".getBytes(StandardCharsets.UTF_8), plaintext); - PGPPadding padding = (PGPPadding) objFac.nextObject(); - isEncodingEqual(Hex.decode("c5a293072991628147d72c8f86b7"), padding.getPadding()); - } - - private void testX25519AEADOCBTestVector_jce() - throws IOException, PGPException - { - ByteArrayInputStream bIn = new ByteArrayInputStream(V6_SECRET_KEY.getBytes(StandardCharsets.UTF_8)); - ArmoredInputStream aIn = new ArmoredInputStream(bIn); - BCPGInputStream pIn = new BCPGInputStream(aIn); - PGPObjectFactory objFac = new JcaPGPObjectFactory(pIn); - PGPSecretKeyRing secretKeys = (PGPSecretKeyRing) objFac.nextObject(); - - bIn = new ByteArrayInputStream(X25519_AEAD_OCB_MESSAGE.getBytes()); - aIn = new ArmoredInputStream(bIn); - pIn = new BCPGInputStream(aIn); - objFac = new JcaPGPObjectFactory(pIn); - PGPEncryptedDataList encList = (PGPEncryptedDataList) objFac.nextObject(); - PGPPublicKeyEncryptedData encData = (PGPPublicKeyEncryptedData) encList.get(0); - - PGPSecretKey decKey = secretKeys.getSecretKey(encData.getKeyID()); // TODO: getKeyIdentifier() - PGPPrivateKey privKey = decKey.extractPrivateKey(null); - PublicKeyDataDecryptorFactory decryptor = new JcePublicKeyDataDecryptorFactoryBuilder() - .setProvider(new BouncyCastleProvider()) - .setContentProvider(new BouncyCastleProvider()) - .build(privKey); - InputStream in = encData.getDataStream(decryptor); - objFac = new JcaPGPObjectFactory(in); - PGPLiteralData literalData = (PGPLiteralData) objFac.nextObject(); - byte[] plaintext = Streams.readAll(literalData.getDataStream()); - isEncodingEqual("Hello, world!".getBytes(StandardCharsets.UTF_8), plaintext); - PGPPadding padding = (PGPPadding) objFac.nextObject(); - isEncodingEqual(Hex.decode("c5a293072991628147d72c8f86b7"), padding.getPadding()); - } - - private void testPKESK6SEIPD2() - throws IOException - { - String MSG = "-----BEGIN PGP MESSAGE-----\n" + - "\n" + - "wW0GIQYSyD8ecG9jCP4VGkF3Q6HwM3kOk+mXhIjR2zeNqZMIhRk5Bu/DU62hzgRm\n" + - "JYvBYeLA2Nrmz15g69ZN0xAB7SLDRCjjhnK6V7fGns6P1EiSCYbl1uNVBhK0MPGe\n" + - "rU9FY4yUXTnbB6eIXdCw0loCCQIOu95D17wvJJC2a96ou9SGPIoA4Q2dMH5BMS9Z\n" + - "veq3AGgIBdJMF8Ft8PBE30R0cba1O5oQC0Eiscw7fkNnYGuSXagqNXdOBkHDN0fk\n" + - "VWFrxQRbxEVYUWc=\n" + - "=u2kL\n" + - "-----END PGP MESSAGE-----\n"; - byte[] fingerprint = Hex.decode("12C83F1E706F6308FE151A417743A1F033790E93E9978488D1DB378DA9930885"); - ByteArrayInputStream bIn = new ByteArrayInputStream(MSG.getBytes(StandardCharsets.UTF_8)); - ArmoredInputStream aIn = new ArmoredInputStream(bIn); - BCPGInputStream pIn = new BCPGInputStream(aIn); - PublicKeyEncSessionPacket pkesk = (PublicKeyEncSessionPacket) pIn.readPacket(); - isEquals("PKESK version mismatch", - PublicKeyEncSessionPacket.VERSION_6, pkesk.getVersion()); - isEncodingEqual("PKESK fingerprint mismatch", - fingerprint, pkesk.getKeyFingerprint()); - isEquals("PKESK derived key-id mismatch", - FingerprintUtil.keyIdFromV6Fingerprint(fingerprint), pkesk.getKeyID()); - isEquals("PKESK public key alg mismatch", - PublicKeyAlgorithmTags.X25519, pkesk.getAlgorithm()); - - SymmetricEncIntegrityPacket skesk = (SymmetricEncIntegrityPacket) pIn.readPacket(); - isEquals("SKESK version mismatch", - SymmetricEncIntegrityPacket.VERSION_2, skesk.getVersion()); - isEquals("SKESK sym alg mismatch", - SymmetricKeyAlgorithmTags.AES_256, skesk.getCipherAlgorithm()); - isEquals("SKESK AEAD alg mismatch", - AEADAlgorithmTags.OCB, skesk.getAeadAlgorithm()); - isEquals("SKESK chunk size mismatch", - 0x0e, skesk.getChunkSize()); - isEncodingEqual("SKESK salt mismatch", - Hex.decode("BBDE43D7BC2F2490B66BDEA8BBD4863C8A00E10D9D307E41312F59BDEAB70068"), skesk.getSalt()); - } - - public static void main(String[] args) - { - runTest(new EncryptedMessagePacketTest()); - } -} diff --git a/pg/src/test/java/org/bouncycastle/openpgp/test/PGPv6MessageDecryptionTest.java b/pg/src/test/java/org/bouncycastle/openpgp/test/PGPv6MessageDecryptionTest.java deleted file mode 100644 index 88b7e6a16c..0000000000 --- a/pg/src/test/java/org/bouncycastle/openpgp/test/PGPv6MessageDecryptionTest.java +++ /dev/null @@ -1,209 +0,0 @@ -package org.bouncycastle.openpgp.test; - -import org.bouncycastle.bcpg.ArmoredInputStream; -import org.bouncycastle.bcpg.BCPGInputStream; -import org.bouncycastle.bcpg.PublicKeyAlgorithmTags; -import org.bouncycastle.bcpg.PublicKeyEncSessionPacket; -import org.bouncycastle.openpgp.PGPEncryptedDataList; -import org.bouncycastle.openpgp.PGPException; -import org.bouncycastle.openpgp.PGPLiteralData; -import org.bouncycastle.openpgp.PGPObjectFactory; -import org.bouncycastle.openpgp.PGPPrivateKey; -import org.bouncycastle.openpgp.PGPPublicKeyEncryptedData; -import org.bouncycastle.openpgp.PGPSecretKey; -import org.bouncycastle.openpgp.PGPSecretKeyRing; -import org.bouncycastle.openpgp.PGPSessionKey; -import org.bouncycastle.openpgp.PGPSessionKeyEncryptedData; -import org.bouncycastle.openpgp.bc.BcPGPObjectFactory; -import org.bouncycastle.openpgp.operator.PublicKeyDataDecryptorFactory; -import org.bouncycastle.openpgp.operator.SessionKeyDataDecryptorFactory; -import org.bouncycastle.openpgp.operator.bc.BcPublicKeyDataDecryptorFactory; -import org.bouncycastle.openpgp.operator.bc.BcSessionKeyDataDecryptorFactory; -import org.bouncycastle.util.io.Streams; - -import java.io.ByteArrayInputStream; -import java.io.IOException; -import java.io.InputStream; -import java.nio.charset.StandardCharsets; - -public class PGPv6MessageDecryptionTest - extends AbstractPgpKeyPairTest -{ - @Override - public String getName() - { - return "PGPv6MessageDecryptionTest"; - } - - @Override - public void performTest() - throws Exception - { - decryptMessageEncryptedUsingPKESKv6(); - decryptMessageUsingV6GopenpgpTestKey(); - decryptMessageUsingSessionKey(); - } - - private void decryptMessageEncryptedUsingPKESKv6() - throws IOException, PGPException - { - // X25519 test key from rfc9580 - String key = "-----BEGIN PGP PRIVATE KEY BLOCK-----\n" + - "\n" + - "xUsGY4d/4xsAAAAg+U2nu0jWCmHlZ3BqZYfQMxmZu52JGggkLq2EVD34laMAGXKB\n" + - "exK+cH6NX1hs5hNhIB00TrJmosgv3mg1ditlsLfCsQYfGwoAAABCBYJjh3/jAwsJ\n" + - "BwUVCg4IDAIWAAKbAwIeCSIhBssYbE8GCaaX5NUt+mxyKwwfHifBilZwj2Ul7Ce6\n" + - "2azJBScJAgcCAAAAAK0oIBA+LX0ifsDm185Ecds2v8lwgyU2kCcUmKfvBXbAf6rh\n" + - "RYWzuQOwEn7E/aLwIwRaLsdry0+VcallHhSu4RN6HWaEQsiPlR4zxP/TP7mhfVEe\n" + - "7XWPxtnMUMtf15OyA51YBMdLBmOHf+MZAAAAIIaTJINn+eUBXbki+PSAld2nhJh/\n" + - "LVmFsS+60WyvXkQ1AE1gCk95TUR3XFeibg/u/tVY6a//1q0NWC1X+yui3O24wpsG\n" + - "GBsKAAAALAWCY4d/4wKbDCIhBssYbE8GCaaX5NUt+mxyKwwfHifBilZwj2Ul7Ce6\n" + - "2azJAAAAAAQBIKbpGG2dWTX8j+VjFM21J0hqWlEg+bdiojWnKfA5AQpWUWtnNwDE\n" + - "M0g12vYxoWM8Y81W+bHBw805I8kWVkXU6vFOi+HWvv/ira7ofJu16NnoUkhclkUr\n" + - "k0mXubZvyl4GBg==\n" + - "-----END PGP PRIVATE KEY BLOCK-----\n"; - ByteArrayInputStream bIn = new ByteArrayInputStream(key.getBytes(StandardCharsets.UTF_8)); - ArmoredInputStream aIn = new ArmoredInputStream(bIn); - BCPGInputStream pIn = new BCPGInputStream(aIn); - PGPObjectFactory objFac = new BcPGPObjectFactory(pIn); - PGPSecretKeyRing secretKeys = (PGPSecretKeyRing) objFac.nextObject(); - pIn.close(); - aIn.close(); - bIn.close(); - - // created using rpgpie 0.1.1 (rpgp 0.14.0-alpha.0) - String MSG = "-----BEGIN PGP MESSAGE-----\n" + - "\n" + - "wW0GIQYSyD8ecG9jCP4VGkF3Q6HwM3kOk+mXhIjR2zeNqZMIhRk5Bu/DU62hzgRm\n" + - "JYvBYeLA2Nrmz15g69ZN0xAB7SLDRCjjhnK6V7fGns6P1EiSCYbl1uNVBhK0MPGe\n" + - "rU9FY4yUXTnbB6eIXdCw0loCCQIOu95D17wvJJC2a96ou9SGPIoA4Q2dMH5BMS9Z\n" + - "veq3AGgIBdJMF8Ft8PBE30R0cba1O5oQC0Eiscw7fkNnYGuSXagqNXdOBkHDN0fk\n" + - "VWFrxQRbxEVYUWc=\n" + - "=u2kL\n" + - "-----END PGP MESSAGE-----\n"; - bIn = new ByteArrayInputStream(MSG.getBytes(StandardCharsets.UTF_8)); - aIn = new ArmoredInputStream(bIn); - pIn = new BCPGInputStream(aIn); - objFac = new BcPGPObjectFactory(pIn); - PGPEncryptedDataList encList = (PGPEncryptedDataList) objFac.nextObject(); - PGPPublicKeyEncryptedData encData = (PGPPublicKeyEncryptedData) encList.get(0); - - isEquals("PKESK version mismatch", - PublicKeyEncSessionPacket.VERSION_6, encData.getVersion()); - isEquals("Public key algorithm mismatch", - PublicKeyAlgorithmTags.X25519, encData.getAlgorithm()); - PGPSecretKey decryptionKey = secretKeys.getSecretKey(encData.getKeyID()); // TODO: getKeyIdentifier() - isNotNull("Decryption key MUST be identifiable", decryptionKey); - PGPPrivateKey privateKey = decryptionKey.extractPrivateKey(null); - PublicKeyDataDecryptorFactory decryptor = new BcPublicKeyDataDecryptorFactory(privateKey); - InputStream decrypted = encData.getDataStream(decryptor); - PGPObjectFactory decFac = new BcPGPObjectFactory(decrypted); - PGPLiteralData lit = (PGPLiteralData) decFac.nextObject(); - isEncodingEqual("Message plaintext mismatch", - "Hello World :)".getBytes(StandardCharsets.UTF_8), - Streams.readAll(lit.getDataStream())); - } - - private void decryptMessageUsingV6GopenpgpTestKey() - throws IOException, PGPException - { - // Ed448/X448 test key - // Courtesy of @twiss from Proton - String key = "-----BEGIN PGP PRIVATE KEY BLOCK-----\n" + - "\n" + - "xX0GZrnFtRwAAAA5wl2q+bhfNkzHsxlLowaUy0sTOeAsmhseHBvPKKc7yehR\n" + - "8Qs93LbjQHjw3IaqduMRDRs4pZJyV/+AACKFtkkC3ebcyaOvHGaJpc9rx0Z1\n" + - "4YHdd4BG1AJvZuhk8pJ6dQuuQeFtBsQctoktFwlDh0XjnjUrkMLALQYfHAoA\n" + - "AABMBYJmucW1AwsJBwUVCAoMDgQWAAIBApsDAh4JIqEGEvURGalOLHznAmcI\n" + - "MRsEHorGZ2ikxHawiPyOMw+CAOANJwkDBwMJAQcBCQIHAgAAAACbfCBvUoq6\n" + - "bon1bSsp9HLc829xjDINBOvegmk4tMKv392c1LNPJacojQ46YZpkNVhE4sSx\n" + - "Gf/vdUqh62KP+vwm5cXs/f11WmdVnclv7uR9s3a1GI79lwOJiuw3AIXA3VjR\n" + - "+AhmeoAFJRfcjfT3hwwkBdu8E3BQ+1bGqfXGhOPYcDTJOO+vMExGSTEk+A9j\n" + - "DmWnW6snAMd7Bma5xbUaAAAAOAPvCJKYxSQ+SfLb313/tC9N2tGF00x6YJkz\n" + - "JLqLKVDofMHmUC1f8IJFtQ3cLMDhHVY0VxffLXT1AEffhVpafxBdelL69esq\n" + - "2zQtDp5l8Hx7D/sU+W3+KmGLnRki72g7gfoQuio+wk8UcHmfwYm7AHvuwsAN\n" + - "BhgcCgAAACwFgma5xbUCmwwioQYS9REZqU4sfOcCZwgxGwQeisZnaKTEdrCI\n" + - "/I4zD4IA4AAAAACQUiBvjI1gFe4O/GDPwIoX8YSK/qP3IsMAwvidXclpmlLN\n" + - "RzPkkfUzRgZw8+AHZxV62TPWhxrZETAuEaahrQ6HViQRAfk60gLvT37iWZrG\n" + - "BU64272NrJ+UFXrzAEKZ/HK+hIL6yZvYDqIxWBg3Pwt9YxgpOfJ8UeYcrEx3\n" + - "B1Hkd6QprSOLFCj53zZ++q3SZkWYz28gAA==\n" + - "-----END PGP PRIVATE KEY BLOCK-----\n"; - ByteArrayInputStream bIn = new ByteArrayInputStream(key.getBytes(StandardCharsets.UTF_8)); - ArmoredInputStream aIn = new ArmoredInputStream(bIn); - BCPGInputStream pIn = new BCPGInputStream(aIn); - PGPObjectFactory objFac = new BcPGPObjectFactory(pIn); - PGPSecretKeyRing secretKeys = (PGPSecretKeyRing) objFac.nextObject(); - pIn.close(); - aIn.close(); - bIn.close(); - - // created using gosop 430bb02923c123e39815814f6b97a6d501bdde6a - // ./gosop encrypt --profile=rfc9580 cert.asc < msg.plain > msg.asc - String MSG = "-----BEGIN PGP MESSAGE-----\n" + - "\n" + - "wYUGIQaz5Iy7+n5O1bg87Cy2PfSolKK6L8cwIPLJnEeZFjMu2xoAfSM/MwQpXahy\n" + - "Od1pknhDyw3X5EgxQG0EffQCMpaKsNtqvVGYBJ5chuAcV/8gayReP/g6RREGeyj4\n" + - "Vc2dgJ67/KwaP0Z7k7vExHs79U24DsrU088QbYhk/XLvJHWlXXj90loCCQMMIvmD\n" + - "KS5f5WYbntB4N+FspsbQ7GN6taOrAqUtEuKWKzrlhZdtg9qGG4RLCvX1vfL0u6NV\n" + - "Yzk9fGVgty73B8pmyYdefLdWt87ljwr8wGGX/Dl8PSBIE3w=\n" + - "-----END PGP MESSAGE-----\n"; - bIn = new ByteArrayInputStream(MSG.getBytes(StandardCharsets.UTF_8)); - aIn = new ArmoredInputStream(bIn); - pIn = new BCPGInputStream(aIn); - objFac = new BcPGPObjectFactory(pIn); - PGPEncryptedDataList encList = (PGPEncryptedDataList) objFac.nextObject(); - PGPPublicKeyEncryptedData encData = (PGPPublicKeyEncryptedData) encList.get(0); - - isEquals("PKESK version mismatch", - PublicKeyEncSessionPacket.VERSION_6, encData.getVersion()); - isEquals("Public Key algorithm mismatch", - PublicKeyAlgorithmTags.X448, encData.getAlgorithm()); - PGPSecretKey decryptionKey = secretKeys.getSecretKey(encData.getKeyID()); // TODO: getKeyIdentifier() - isNotNull("Decryption key MUST be identifiable", decryptionKey); - PGPPrivateKey privateKey = decryptionKey.extractPrivateKey(null); - PublicKeyDataDecryptorFactory decryptor = new BcPublicKeyDataDecryptorFactory(privateKey); - InputStream decrypted = encData.getDataStream(decryptor); - PGPObjectFactory decFac = new BcPGPObjectFactory(decrypted); - PGPLiteralData lit = (PGPLiteralData) decFac.nextObject(); - isEncodingEqual("Message plaintext mismatch", - "Hello, World!\n".getBytes(StandardCharsets.UTF_8), - Streams.readAll(lit.getDataStream())); - } - - private void decryptMessageUsingSessionKey() - throws IOException, PGPException - { - // created using gosop 430bb02923c123e39815814f6b97a6d501bdde6a - // ./gosop encrypt --profile=rfc9580 cert.asc < msg.plain > msg.asc - String MSG = "-----BEGIN PGP MESSAGE-----\n" + - "\n" + - "wYUGIQaz5Iy7+n5O1bg87Cy2PfSolKK6L8cwIPLJnEeZFjMu2xoAfSM/MwQpXahy\n" + - "Od1pknhDyw3X5EgxQG0EffQCMpaKsNtqvVGYBJ5chuAcV/8gayReP/g6RREGeyj4\n" + - "Vc2dgJ67/KwaP0Z7k7vExHs79U24DsrU088QbYhk/XLvJHWlXXj90loCCQMMIvmD\n" + - "KS5f5WYbntB4N+FspsbQ7GN6taOrAqUtEuKWKzrlhZdtg9qGG4RLCvX1vfL0u6NV\n" + - "Yzk9fGVgty73B8pmyYdefLdWt87ljwr8wGGX/Dl8PSBIE3w=\n" + - "-----END PGP MESSAGE-----\n"; - String SESSION_KEY = "9:47343387303C170873252051978966871EE2EA0F68D975F061AF022B78B165C1"; - - ByteArrayInputStream bIn = new ByteArrayInputStream(MSG.getBytes(StandardCharsets.UTF_8)); - ArmoredInputStream aIn = new ArmoredInputStream(bIn); - BCPGInputStream pIn = new BCPGInputStream(aIn); - PGPObjectFactory objFac = new BcPGPObjectFactory(pIn); - PGPEncryptedDataList encList = (PGPEncryptedDataList) objFac.nextObject(); - PGPSessionKeyEncryptedData encData = encList.extractSessionKeyEncryptedData(); - SessionKeyDataDecryptorFactory decryptor = new BcSessionKeyDataDecryptorFactory( - PGPSessionKey.fromAsciiRepresentation(SESSION_KEY)); - - InputStream decrypted = encData.getDataStream(decryptor); - PGPObjectFactory decFac = new BcPGPObjectFactory(decrypted); - PGPLiteralData lit = (PGPLiteralData) decFac.nextObject(); - isEncodingEqual("Message plaintext mismatch", - "Hello, World!\n".getBytes(StandardCharsets.UTF_8), - Streams.readAll(lit.getDataStream())); - } - - public static void main(String[] args) - { - runTest(new PGPv6MessageDecryptionTest()); - } -} diff --git a/pg/src/test/java/org/bouncycastle/openpgp/test/RegressionTest.java b/pg/src/test/java/org/bouncycastle/openpgp/test/RegressionTest.java index 00c7981412..6c5ea8dd24 100644 --- a/pg/src/test/java/org/bouncycastle/openpgp/test/RegressionTest.java +++ b/pg/src/test/java/org/bouncycastle/openpgp/test/RegressionTest.java @@ -74,8 +74,6 @@ public class RegressionTest new LegacyX25519KeyPairTest(), new LegacyX448KeyPairTest(), - new PGPv6MessageDecryptionTest(), - new Curve25519PrivateKeyEncodingTest(), new EdDSAKeyConversionWithLeadingZeroTest(), new ECDSAKeyPairTest()