From 7cb752aaf746dc0b473afeb9e892b7fbc12666c5 Mon Sep 17 00:00:00 2001 From: Roberto Tyley Date: Mon, 14 Jul 2014 22:38:01 +0100 Subject: Execute become-spongy.sh https://github.com/rtyley/spongycastle/blob/3040af/become-spongy.sh --- .../bc/BcPublicKeyDataDecryptorFactory.java | 139 +++++++++++++++++++++ 1 file changed, 139 insertions(+) create mode 100644 pg/src/main/java/org/spongycastle/openpgp/operator/bc/BcPublicKeyDataDecryptorFactory.java (limited to 'pg/src/main/java/org/spongycastle/openpgp/operator/bc/BcPublicKeyDataDecryptorFactory.java') diff --git a/pg/src/main/java/org/spongycastle/openpgp/operator/bc/BcPublicKeyDataDecryptorFactory.java b/pg/src/main/java/org/spongycastle/openpgp/operator/bc/BcPublicKeyDataDecryptorFactory.java new file mode 100644 index 00000000..4c5124bb --- /dev/null +++ b/pg/src/main/java/org/spongycastle/openpgp/operator/bc/BcPublicKeyDataDecryptorFactory.java @@ -0,0 +1,139 @@ +package org.spongycastle.openpgp.operator.bc; + +import org.spongycastle.asn1.nist.NISTNamedCurves; +import org.spongycastle.asn1.x9.X9ECParameters; +import org.spongycastle.bcpg.ECDHPublicBCPGKey; +import org.spongycastle.bcpg.ECSecretBCPGKey; +import org.spongycastle.crypto.AsymmetricBlockCipher; +import org.spongycastle.crypto.BlockCipher; +import org.spongycastle.crypto.BufferedAsymmetricBlockCipher; +import org.spongycastle.crypto.InvalidCipherTextException; +import org.spongycastle.crypto.Wrapper; +import org.spongycastle.crypto.params.AsymmetricKeyParameter; +import org.spongycastle.crypto.params.ElGamalPrivateKeyParameters; +import org.spongycastle.crypto.params.KeyParameter; +import org.spongycastle.math.ec.ECPoint; +import org.spongycastle.openpgp.PGPException; +import org.spongycastle.openpgp.PGPPrivateKey; +import org.spongycastle.openpgp.PGPPublicKey; +import org.spongycastle.openpgp.operator.PGPDataDecryptor; +import org.spongycastle.openpgp.operator.PGPPad; +import org.spongycastle.openpgp.operator.PublicKeyDataDecryptorFactory; +import org.spongycastle.openpgp.operator.RFC6637KDFCalculator; + +/** + * A decryptor factory for handling public key decryption operations. + */ +public class BcPublicKeyDataDecryptorFactory + implements PublicKeyDataDecryptorFactory +{ + private BcPGPKeyConverter keyConverter = new BcPGPKeyConverter(); + private PGPPrivateKey privKey; + + public BcPublicKeyDataDecryptorFactory(PGPPrivateKey privKey) + { + this.privKey = privKey; + } + + public byte[] recoverSessionData(int keyAlgorithm, byte[][] secKeyData) + throws PGPException + { + try + { + if (keyAlgorithm != PGPPublicKey.ECDH) + { + AsymmetricBlockCipher c = BcImplProvider.createPublicKeyCipher(keyAlgorithm); + + AsymmetricKeyParameter key = keyConverter.getPrivateKey(privKey); + + BufferedAsymmetricBlockCipher c1 = new BufferedAsymmetricBlockCipher(c); + + c1.init(false, key); + + if (keyAlgorithm == PGPPublicKey.RSA_ENCRYPT + || keyAlgorithm == PGPPublicKey.RSA_GENERAL) + { + byte[] bi = secKeyData[0]; + + c1.processBytes(bi, 2, bi.length - 2); + } + else + { + BcPGPKeyConverter converter = new BcPGPKeyConverter(); + ElGamalPrivateKeyParameters parms = (ElGamalPrivateKeyParameters)converter.getPrivateKey(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 + for (int i = 0; i != tmp.length; i++) + { + tmp[i] = 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(); + } + else + { + ECDHPublicBCPGKey ecKey = (ECDHPublicBCPGKey)privKey.getPublicKeyPacket().getKey(); + X9ECParameters x9Params = NISTNamedCurves.getByOID(ecKey.getCurveOID()); + + byte[] enc = secKeyData[0]; + + int pLen = ((((enc[0] & 0xff) << 8) + (enc[1] & 0xff)) + 7) / 8; + byte[] pEnc = new byte[pLen]; + + System.arraycopy(enc, 2, pEnc, 0, pLen); + + byte[] keyEnc = new byte[enc[pLen + 2]]; + + System.arraycopy(enc, 2 + pLen + 1, keyEnc, 0, keyEnc.length); + + Wrapper c = BcImplProvider.createWrapper(ecKey.getSymmetricKeyAlgorithm()); + + ECPoint S = x9Params.getCurve().decodePoint(pEnc).multiply(((ECSecretBCPGKey)privKey.getPrivateKeyDataPacket()).getX()).normalize(); + + RFC6637KDFCalculator rfc6637KDFCalculator = new RFC6637KDFCalculator(new BcPGPDigestCalculatorProvider().get(ecKey.getHashAlgorithm()), ecKey.getSymmetricKeyAlgorithm()); + KeyParameter key = new KeyParameter(rfc6637KDFCalculator.createKey(ecKey.getCurveOID(), S, new BcKeyFingerprintCalculator().calculateFingerprint(privKey.getPublicKeyPacket()))); + + c.init(false, key); + + return PGPPad.unpadSessionData(c.unwrap(keyEnc, 0, keyEnc.length)); + } + } + catch (InvalidCipherTextException e) + { + throw new PGPException("exception encrypting session info: " + e.getMessage(), e); + } + + } + + public PGPDataDecryptor createDataDecryptor(boolean withIntegrityPacket, int encAlgorithm, byte[] key) + throws PGPException + { + BlockCipher engine = BcImplProvider.createBlockCipher(encAlgorithm); + + return BcUtil.createDataDecryptor(withIntegrityPacket, engine, key); + } +} -- cgit v1.2.3