All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.bouncycastle.openpgp.operator.bc.BcPGPKeyConverter Maven / Gradle / Ivy

Go to download

The Bouncy Castle Java APIs for the OpenPGP Protocol. The APIs are designed primarily to be used in conjunction with the BC LTS provider but may also be used with other providers providing cryptographic services.

The newest version!
package org.bouncycastle.openpgp.operator.bc;

import java.io.IOException;
import java.math.BigInteger;
import java.util.Date;

import org.bouncycastle.asn1.ASN1ObjectIdentifier;
import org.bouncycastle.asn1.cryptlib.CryptlibObjectIdentifiers;
import org.bouncycastle.asn1.edec.EdECObjectIdentifiers;
import org.bouncycastle.asn1.gnu.GNUObjectIdentifiers;
import org.bouncycastle.asn1.x509.AlgorithmIdentifier;
import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo;
import org.bouncycastle.asn1.x9.X9ECParameters;
import org.bouncycastle.bcpg.BCPGKey;
import org.bouncycastle.bcpg.DSAPublicBCPGKey;
import org.bouncycastle.bcpg.DSASecretBCPGKey;
import org.bouncycastle.bcpg.ECDHPublicBCPGKey;
import org.bouncycastle.bcpg.ECDSAPublicBCPGKey;
import org.bouncycastle.bcpg.ECPublicBCPGKey;
import org.bouncycastle.bcpg.ECSecretBCPGKey;
import org.bouncycastle.bcpg.Ed25519PublicBCPGKey;
import org.bouncycastle.bcpg.Ed25519SecretBCPGKey;
import org.bouncycastle.bcpg.Ed448PublicBCPGKey;
import org.bouncycastle.bcpg.Ed448SecretBCPGKey;
import org.bouncycastle.bcpg.EdDSAPublicBCPGKey;
import org.bouncycastle.bcpg.EdSecretBCPGKey;
import org.bouncycastle.bcpg.ElGamalPublicBCPGKey;
import org.bouncycastle.bcpg.ElGamalSecretBCPGKey;
import org.bouncycastle.bcpg.OctetArrayBCPGKey;
import org.bouncycastle.bcpg.PublicKeyAlgorithmTags;
import org.bouncycastle.bcpg.PublicKeyPacket;
import org.bouncycastle.bcpg.RSAPublicBCPGKey;
import org.bouncycastle.bcpg.RSASecretBCPGKey;
import org.bouncycastle.bcpg.X25519PublicBCPGKey;
import org.bouncycastle.bcpg.X25519SecretBCPGKey;
import org.bouncycastle.bcpg.X448PublicBCPGKey;
import org.bouncycastle.bcpg.X448SecretBCPGKey;
import org.bouncycastle.crypto.params.AsymmetricKeyParameter;
import org.bouncycastle.crypto.params.DSAParameters;
import org.bouncycastle.crypto.params.DSAPrivateKeyParameters;
import org.bouncycastle.crypto.params.DSAPublicKeyParameters;
import org.bouncycastle.crypto.params.ECNamedDomainParameters;
import org.bouncycastle.crypto.params.ECPrivateKeyParameters;
import org.bouncycastle.crypto.params.ECPublicKeyParameters;
import org.bouncycastle.crypto.params.Ed25519PrivateKeyParameters;
import org.bouncycastle.crypto.params.Ed25519PublicKeyParameters;
import org.bouncycastle.crypto.params.Ed448PrivateKeyParameters;
import org.bouncycastle.crypto.params.Ed448PublicKeyParameters;
import org.bouncycastle.crypto.params.ElGamalParameters;
import org.bouncycastle.crypto.params.ElGamalPrivateKeyParameters;
import org.bouncycastle.crypto.params.ElGamalPublicKeyParameters;
import org.bouncycastle.crypto.params.RSAKeyParameters;
import org.bouncycastle.crypto.params.RSAPrivateCrtKeyParameters;
import org.bouncycastle.crypto.params.X25519PrivateKeyParameters;
import org.bouncycastle.crypto.params.X25519PublicKeyParameters;
import org.bouncycastle.crypto.params.X448PrivateKeyParameters;
import org.bouncycastle.crypto.params.X448PublicKeyParameters;
import org.bouncycastle.crypto.util.PrivateKeyFactory;
import org.bouncycastle.crypto.util.PublicKeyFactory;
import org.bouncycastle.math.ec.ECPoint;
import org.bouncycastle.math.ec.rfc8032.Ed25519;
import org.bouncycastle.math.ec.rfc8032.Ed448;
import org.bouncycastle.openpgp.PGPAlgorithmParameters;
import org.bouncycastle.openpgp.PGPException;
import org.bouncycastle.openpgp.PGPKdfParameters;
import org.bouncycastle.openpgp.PGPPrivateKey;
import org.bouncycastle.openpgp.PGPPublicKey;
import org.bouncycastle.openpgp.operator.PGPKeyConverter;
import org.bouncycastle.util.Arrays;
import org.bouncycastle.util.BigIntegers;

public class BcPGPKeyConverter
    extends PGPKeyConverter
{
    public PGPPrivateKey getPGPPrivateKey(PGPPublicKey pubKey, AsymmetricKeyParameter privKey)
        throws PGPException
    {
        BCPGKey privPk = getPrivateBCPGKey(pubKey, privKey);

        return new PGPPrivateKey(pubKey.getKeyID(), pubKey.getPublicKeyPacket(), privPk);
    }

    /**
     * Create a version 4 PGPPublicKey from the passed in JCA one.
     * 

* Note: the time passed in affects the value of the key's keyID, so you probably only want * to do this once for a JCA key, or make sure you keep track of the time you used. *

* * @param algorithm asymmetric algorithm type representing the public key. * @param pubKey actual public key to associate. * @param time date of creation. * @throws PGPException on key creation problem. * @deprecated use versioned {@link #getPGPPublicKey(int, int, PGPAlgorithmParameters, AsymmetricKeyParameter, Date)} instead */ @Deprecated public PGPPublicKey getPGPPublicKey(int algorithm, PGPAlgorithmParameters algorithmParameters, AsymmetricKeyParameter pubKey, Date time) throws PGPException { return getPGPPublicKey(PublicKeyPacket.VERSION_4, algorithm, algorithmParameters, pubKey, time); } /** * Create a PGPPublicKey from the passed in JCA one. *

* Note: the time passed in affects the value of the key's keyID, so you probably only want * to do this once for a JCA key, or make sure you keep track of the time you used. *

* * @param version key version. * @param algorithm asymmetric algorithm type representing the public key. * @param pubKey actual public key to associate. * @param time date of creation. * @throws PGPException on key creation problem. */ public PGPPublicKey getPGPPublicKey(int version, int algorithm, PGPAlgorithmParameters algorithmParameters, AsymmetricKeyParameter pubKey, Date time) throws PGPException { BCPGKey bcpgKey = getPublicBCPGKey(algorithm, algorithmParameters, pubKey); return new PGPPublicKey(new PublicKeyPacket(version, algorithm, time, bcpgKey), new BcKeyFingerprintCalculator()); } public AsymmetricKeyParameter getPrivateKey(PGPPrivateKey privKey) throws PGPException { PublicKeyPacket pubPk = privKey.getPublicKeyPacket(); BCPGKey privPk = privKey.getPrivateKeyDataPacket(); try { switch (pubPk.getAlgorithm()) { case PublicKeyAlgorithmTags.DSA: { DSAPublicBCPGKey dsaPub = (DSAPublicBCPGKey)pubPk.getKey(); DSASecretBCPGKey dsaPriv = (DSASecretBCPGKey)privPk; return new DSAPrivateKeyParameters(dsaPriv.getX(), new DSAParameters(dsaPub.getP(), dsaPub.getQ(), dsaPub.getG())); } case PublicKeyAlgorithmTags.ECDH: { ECDHPublicBCPGKey ecdhPub = (ECDHPublicBCPGKey)pubPk.getKey(); // Legacy XDH on Curve25519 (legacy X25519) // 1.3.6.1.4.1.3029.1.5.1 & 1.3.101.110 if (BcUtil.isX25519(ecdhPub.getCurveOID())) { return PrivateKeyFactory.createKey(getPrivateKeyInfo(EdECObjectIdentifiers.id_X25519, Arrays.reverseInPlace(BigIntegers.asUnsignedByteArray(((ECSecretBCPGKey)privPk).getX())))); } // Legacy X448 (1.3.101.111) else if (EdECObjectIdentifiers.id_X448.equals(ecdhPub.getCurveOID())) { return PrivateKeyFactory.createKey(getPrivateKeyInfo(EdECObjectIdentifiers.id_X448, Arrays.reverseInPlace(BigIntegers.asUnsignedByteArray(((ECSecretBCPGKey)privPk).getX())))); } // NIST, Brainpool etc. else { return implGetPrivateKeyEC(ecdhPub, (ECSecretBCPGKey)privPk); } } // Modern X25519 (1.3.6.1.4.1.3029.1.5.1 & 1.3.101.110) case PublicKeyAlgorithmTags.X25519: { return PrivateKeyFactory.createKey(getPrivateKeyInfo(EdECObjectIdentifiers.id_X25519, X25519SecretBCPGKey.LENGTH, privPk.getEncoded())); } // Modern X448 (1.3.101.111) case PublicKeyAlgorithmTags.X448: { return PrivateKeyFactory.createKey(getPrivateKeyInfo(EdECObjectIdentifiers.id_X448, X448SecretBCPGKey.LENGTH, privPk.getEncoded())); } case PublicKeyAlgorithmTags.ECDSA: { return implGetPrivateKeyEC((ECDSAPublicBCPGKey) pubPk.getKey(), (ECSecretBCPGKey) privPk); } // Legacy EdDSA (legacy Ed448, legacy Ed25519) case PublicKeyAlgorithmTags.EDDSA_LEGACY: { // Legacy Ed448 (1.3.101.113) if (((EdDSAPublicBCPGKey)pubPk.getKey()).getCurveOID().equals(EdECObjectIdentifiers.id_Ed448)) { return implGetPrivateKeyPKCS8(EdECObjectIdentifiers.id_Ed448, Ed448.SECRET_KEY_SIZE, privPk); } // Legacy Ed25519 (1.3.6.1.4.1.11591.15.1 & 1.3.101.112) return implGetPrivateKeyPKCS8(EdECObjectIdentifiers.id_Ed25519, Ed25519.SECRET_KEY_SIZE, privPk); } // Modern Ed22519 (1.3.6.1.4.1.11591.15.1 & 1.3.101.112) case PublicKeyAlgorithmTags.Ed25519: { return PrivateKeyFactory.createKey(getPrivateKeyInfo(EdECObjectIdentifiers.id_Ed25519, Ed25519SecretBCPGKey.LENGTH, privPk.getEncoded())); } // Modern Ed448 (1.3.101.113) case PublicKeyAlgorithmTags.Ed448: { return PrivateKeyFactory.createKey(getPrivateKeyInfo(EdECObjectIdentifiers.id_Ed448, Ed448SecretBCPGKey.LENGTH, privPk.getEncoded())); } case PublicKeyAlgorithmTags.ELGAMAL_ENCRYPT: case PublicKeyAlgorithmTags.ELGAMAL_GENERAL: { ElGamalPublicBCPGKey elPub = (ElGamalPublicBCPGKey)pubPk.getKey(); ElGamalSecretBCPGKey elPriv = (ElGamalSecretBCPGKey)privPk; return new ElGamalPrivateKeyParameters(elPriv.getX(), new ElGamalParameters(elPub.getP(), elPub.getG())); } case PublicKeyAlgorithmTags.RSA_ENCRYPT: case PublicKeyAlgorithmTags.RSA_GENERAL: case PublicKeyAlgorithmTags.RSA_SIGN: { RSAPublicBCPGKey rsaPub = (RSAPublicBCPGKey)pubPk.getKey(); RSASecretBCPGKey rsaPriv = (RSASecretBCPGKey)privPk; return new RSAPrivateCrtKeyParameters(rsaPriv.getModulus(), rsaPub.getPublicExponent(), rsaPriv.getPrivateExponent(), rsaPriv.getPrimeP(), rsaPriv.getPrimeQ(), rsaPriv.getPrimeExponentP(), rsaPriv.getPrimeExponentQ(), rsaPriv.getCrtCoefficient()); } default: throw new PGPException("unknown public key algorithm encountered: " + pubPk.getAlgorithm()); } } catch (PGPException e) { throw e; } catch (Exception e) { throw new PGPException("Exception constructing key", e); } } public AsymmetricKeyParameter getPublicKey(PGPPublicKey publicKey) throws PGPException { PublicKeyPacket publicPk = publicKey.getPublicKeyPacket(); try { switch (publicPk.getAlgorithm()) { case PublicKeyAlgorithmTags.DSA: { DSAPublicBCPGKey dsaK = (DSAPublicBCPGKey)publicPk.getKey(); return new DSAPublicKeyParameters(dsaK.getY(), new DSAParameters(dsaK.getP(), dsaK.getQ(), dsaK.getG())); } case PublicKeyAlgorithmTags.ECDH: { ECDHPublicBCPGKey ecdhK = (ECDHPublicBCPGKey)publicPk.getKey(); // Legacy XDH on Curve25519 (legacy X25519) // 1.3.6.1.4.1.3029.1.5.1 & 1.3.101.110 if (BcUtil.isX25519(ecdhK.getCurveOID())) { byte[] pEnc = BigIntegers.asUnsignedByteArray(ecdhK.getEncodedPoint()); // skip the 0x40 header byte. if (pEnc.length < 1 || 0x40 != pEnc[0]) { throw new IllegalArgumentException("Invalid Curve25519 public key"); } return implGetPublicKeyX509(EdECObjectIdentifiers.id_X25519, pEnc, 1); } // Legacy X448 (1.3.101.111) else if (ecdhK.getCurveOID().equals(EdECObjectIdentifiers.id_X448)) { byte[] pEnc = BigIntegers.asUnsignedByteArray(ecdhK.getEncodedPoint()); // skip the 0x40 header byte. if (pEnc.length < 1 || 0x40 != pEnc[0]) { throw new IllegalArgumentException("Invalid X448 public key"); } return implGetPublicKeyX509(EdECObjectIdentifiers.id_X448, pEnc, 1); } else { return implGetPublicKeyEC(ecdhK); } } // Modern X25519 (1.3.6.1.4.1.3029.1.5.1 & 1.3.101.110) case PublicKeyAlgorithmTags.X25519: { return implGetPublicKeyX509((X25519PublicBCPGKey)publicPk.getKey(), EdECObjectIdentifiers.id_X25519); } // Modern X448 (1.3.101.111) case PublicKeyAlgorithmTags.X448: { return implGetPublicKeyX509((X448PublicBCPGKey)publicPk.getKey(), EdECObjectIdentifiers.id_X448); } case PublicKeyAlgorithmTags.ECDSA: { return implGetPublicKeyEC((ECDSAPublicBCPGKey)publicPk.getKey()); } // Legacy EdDSA (legacy Ed448, legacy Ed25519) case PublicKeyAlgorithmTags.EDDSA_LEGACY: { EdDSAPublicBCPGKey eddsaK = (EdDSAPublicBCPGKey)publicPk.getKey(); byte[] pEnc = BigIntegers.asUnsignedByteArray(eddsaK.getEncodedPoint()); if (pEnc.length < 1) { throw new IllegalArgumentException("Invalid EdDSA public key"); } // Legacy Ed25519 (1.3.6.1.4.1.11591.15.1 & 1.3.101.112) if (!eddsaK.getCurveOID().equals(EdECObjectIdentifiers.id_Ed448)) { return implGetPublicKeyX509(EdECObjectIdentifiers.id_Ed25519, pEnc, pEnc[0] == 0x40 ? 1 : 0); } // Legacy Ed448 (1.3.101.113) if (eddsaK.getCurveOID().equals(EdECObjectIdentifiers.id_Ed448)) { return implGetPublicKeyX509(EdECObjectIdentifiers.id_Ed448, pEnc, pEnc[0] == 0x40 ? 1 : 0); } throw new IllegalArgumentException("Invalid EdDSA public key"); } // Modern Ed22519 (1.3.6.1.4.1.11591.15.1 & 1.3.101.112) case PublicKeyAlgorithmTags.Ed25519: { return implGetPublicKeyX509((Ed25519PublicBCPGKey)publicPk.getKey(), EdECObjectIdentifiers.id_Ed25519); } // Modern Ed448 (1.3.101.113) case PublicKeyAlgorithmTags.Ed448: { return implGetPublicKeyX509((Ed448PublicBCPGKey)publicPk.getKey(), EdECObjectIdentifiers.id_Ed448); } case PublicKeyAlgorithmTags.ELGAMAL_ENCRYPT: case PublicKeyAlgorithmTags.ELGAMAL_GENERAL: { ElGamalPublicBCPGKey elK = (ElGamalPublicBCPGKey) publicPk.getKey(); return new ElGamalPublicKeyParameters(elK.getY(), new ElGamalParameters(elK.getP(), elK.getG())); } case PublicKeyAlgorithmTags.RSA_ENCRYPT: case PublicKeyAlgorithmTags.RSA_GENERAL: case PublicKeyAlgorithmTags.RSA_SIGN: { RSAPublicBCPGKey rsaK = (RSAPublicBCPGKey)publicPk.getKey(); return new RSAKeyParameters(false, rsaK.getModulus(), rsaK.getPublicExponent()); } default: throw new PGPException("unknown public key algorithm encountered: " + publicKey.getAlgorithm()); } } catch (PGPException e) { throw e; } catch (Exception e) { throw new PGPException("exception constructing public key", e); } } private BCPGKey getPrivateBCPGKey(PGPPublicKey pubKey, AsymmetricKeyParameter privKey) throws PGPException { switch (pubKey.getAlgorithm()) { case PublicKeyAlgorithmTags.DSA: { DSAPrivateKeyParameters dsK = (DSAPrivateKeyParameters)privKey; return new DSASecretBCPGKey(dsK.getX()); } case PublicKeyAlgorithmTags.ECDH: { // Legacy XDH on Curve25519 (legacy X25519) // 1.3.6.1.4.1.3029.1.5.1 & 1.3.101.110 if (privKey instanceof X25519PrivateKeyParameters) { return new ECSecretBCPGKey(new BigInteger(1, Arrays.reverseInPlace(((X25519PrivateKeyParameters)privKey).getEncoded()))); } // Legacy X448 (1.3.101.111) else if (privKey instanceof X448PrivateKeyParameters) { return new ECSecretBCPGKey(new BigInteger(1, Arrays.reverseInPlace(((X448PrivateKeyParameters)privKey).getEncoded()))); } // NIST, Brainpool etc. else { ECPrivateKeyParameters ecK = (ECPrivateKeyParameters)privKey; return new ECSecretBCPGKey(ecK.getD()); } } // Modern X25519 (1.3.6.1.4.1.3029.1.5.1 & 1.3.101.110) case PublicKeyAlgorithmTags.X25519: { return new X25519SecretBCPGKey(((X25519PrivateKeyParameters)privKey).getEncoded()); } // Modern X448 (1.3.101.111) case PublicKeyAlgorithmTags.X448: { return new X448SecretBCPGKey(((X448PrivateKeyParameters)privKey).getEncoded()); } case PublicKeyAlgorithmTags.ECDSA: { ECPrivateKeyParameters ecK = (ECPrivateKeyParameters)privKey; return new ECSecretBCPGKey(ecK.getD()); } // Legacy EdDSA case PublicKeyAlgorithmTags.EDDSA_LEGACY: { // Legacy Ed25519 (1.3.101.112 & 1.3.6.1.4.1.11591.15.1) if (privKey instanceof Ed25519PrivateKeyParameters) { return new EdSecretBCPGKey(new BigInteger(1, ((Ed25519PrivateKeyParameters)privKey).getEncoded())); } // Legacy Ed448 (1.3.101.113) else { return new EdSecretBCPGKey(new BigInteger(1, ((Ed448PrivateKeyParameters) privKey).getEncoded())); } } // Modern Ed22519 (1.3.6.1.4.1.11591.15.1 & 1.3.101.112) case PublicKeyAlgorithmTags.Ed25519: { return new Ed25519SecretBCPGKey(((Ed25519PrivateKeyParameters)privKey).getEncoded()); } // Modern Ed448 (1.3.101.113) case PublicKeyAlgorithmTags.Ed448: { return new Ed448SecretBCPGKey(((Ed448PrivateKeyParameters)privKey).getEncoded()); } case PublicKeyAlgorithmTags.ELGAMAL_ENCRYPT: case PublicKeyAlgorithmTags.ELGAMAL_GENERAL: { ElGamalPrivateKeyParameters esK = (ElGamalPrivateKeyParameters)privKey; return new ElGamalSecretBCPGKey(esK.getX()); } case PublicKeyAlgorithmTags.RSA_ENCRYPT: case PublicKeyAlgorithmTags.RSA_GENERAL: case PublicKeyAlgorithmTags.RSA_SIGN: { RSAPrivateCrtKeyParameters rsK = (RSAPrivateCrtKeyParameters)privKey; return new RSASecretBCPGKey(rsK.getExponent(), rsK.getP(), rsK.getQ()); } default: throw new PGPException("unknown public key algorithm encountered: " + pubKey.getAlgorithm()); } } private BCPGKey getPublicBCPGKey(int algorithm, PGPAlgorithmParameters algorithmParameters, AsymmetricKeyParameter pubKey) throws PGPException { switch (algorithm) { case PublicKeyAlgorithmTags.RSA_GENERAL: case PublicKeyAlgorithmTags.RSA_ENCRYPT: case PublicKeyAlgorithmTags.RSA_SIGN: { RSAKeyParameters rK = (RSAKeyParameters)pubKey; return new RSAPublicBCPGKey(rK.getModulus(), rK.getExponent()); } case PublicKeyAlgorithmTags.DSA: { DSAPublicKeyParameters dK = (DSAPublicKeyParameters)pubKey; DSAParameters dP = dK.getParameters(); return new DSAPublicBCPGKey(dP.getP(), dP.getQ(), dP.getG(), dK.getY()); } case PublicKeyAlgorithmTags.ELGAMAL_ENCRYPT: case PublicKeyAlgorithmTags.ELGAMAL_GENERAL: { ElGamalPublicKeyParameters eK = (ElGamalPublicKeyParameters)pubKey; ElGamalParameters eS = eK.getParameters(); return new ElGamalPublicBCPGKey(eS.getP(), eS.getG(), eK.getY()); } // NIST, Brainpool, Legacy X25519, Legacy X448 case PublicKeyAlgorithmTags.ECDH: { // Legacy X25519 (1.3.6.1.4.1.3029.1.5.1 & 1.3.101.110) if (pubKey instanceof X25519PublicKeyParameters) { byte[] pointEnc = new byte[1 + X25519PublicKeyParameters.KEY_SIZE]; pointEnc[0] = 0x40; ((X25519PublicKeyParameters)pubKey).encode(pointEnc, 1); PGPKdfParameters kdfParams = implGetKdfParameters(CryptlibObjectIdentifiers.curvey25519, algorithmParameters); return new ECDHPublicBCPGKey(CryptlibObjectIdentifiers.curvey25519, new BigInteger(1, pointEnc), kdfParams.getHashAlgorithm(), kdfParams.getSymmetricWrapAlgorithm()); } // Legacy X448 (1.3.101.111) if (pubKey instanceof X448PublicKeyParameters) { byte[] pointEnc = new byte[1 + X448PublicKeyParameters.KEY_SIZE]; pointEnc[0] = 0x40; ((X448PublicKeyParameters)pubKey).encode(pointEnc, 1); PGPKdfParameters kdfParams = implGetKdfParameters(EdECObjectIdentifiers.id_X448, algorithmParameters); return new ECDHPublicBCPGKey(EdECObjectIdentifiers.id_X448, new BigInteger(1, pointEnc), kdfParams.getHashAlgorithm(), kdfParams.getSymmetricWrapAlgorithm()); } // NIST, Brainpool etc. ECPublicKeyParameters ecK = (ECPublicKeyParameters)pubKey; ECNamedDomainParameters parameters = (ECNamedDomainParameters)ecK.getParameters(); PGPKdfParameters kdfParams = implGetKdfParameters(parameters.getName(), algorithmParameters); return new ECDHPublicBCPGKey(parameters.getName(), ecK.getQ(), kdfParams.getHashAlgorithm(), kdfParams.getSymmetricWrapAlgorithm()); } case PublicKeyAlgorithmTags.ECDSA: { ECPublicKeyParameters ecK = (ECPublicKeyParameters)pubKey; ECNamedDomainParameters parameters = (ECNamedDomainParameters)ecK.getParameters(); return new ECDSAPublicBCPGKey(parameters.getName(), ecK.getQ()); } // Legacy Ed255519, Legacy Ed448 case PublicKeyAlgorithmTags.EDDSA_LEGACY: { // Legacy Ed25519 (1.3.6.1.4.1.11591.15.1 & 1.3.101.112) if (pubKey instanceof Ed25519PublicKeyParameters) { byte[] pointEnc = new byte[1 + Ed25519PublicKeyParameters.KEY_SIZE]; pointEnc[0] = 0x40; ((Ed25519PublicKeyParameters)pubKey).encode(pointEnc, 1); return new EdDSAPublicBCPGKey(GNUObjectIdentifiers.Ed25519, new BigInteger(1, pointEnc)); } // Legacy Ed448 (1.3.101.113) else if (pubKey instanceof Ed448PublicKeyParameters) { byte[] pointEnc = new byte[1 + Ed448PublicKeyParameters.KEY_SIZE]; pointEnc[0] = 0x40; ((Ed448PublicKeyParameters)pubKey).encode(pointEnc, 1); return new EdDSAPublicBCPGKey(EdECObjectIdentifiers.id_Ed448, new BigInteger(1, pointEnc)); } else { throw new PGPException("Unknown LegacyEdDSA key type: " + pubKey.getClass().getName()); } } // Modern Ed22519 (1.3.6.1.4.1.11591.15.1 & 1.3.101.112) case PublicKeyAlgorithmTags.Ed25519: { byte[] pointEnc = new byte[Ed25519PublicKeyParameters.KEY_SIZE]; ((Ed25519PublicKeyParameters)pubKey).encode(pointEnc, 0); return new Ed25519PublicBCPGKey(pointEnc); } // Modern Ed448 (1.3.101.113) case PublicKeyAlgorithmTags.Ed448: { byte[] pointEnc = new byte[Ed448PublicKeyParameters.KEY_SIZE]; ((Ed448PublicKeyParameters)pubKey).encode(pointEnc, 0); return new Ed448PublicBCPGKey(pointEnc); } // Modern X25519 (1.3.6.1.4.1.3029.1.5.1 & 1.3.101.110) case PublicKeyAlgorithmTags.X25519: { byte[] pointEnc = new byte[X25519PublicKeyParameters.KEY_SIZE]; ((X25519PublicKeyParameters)pubKey).encode(pointEnc, 0); return new X25519PublicBCPGKey(pointEnc); } // Modern X448 (1.3.101.111) case PublicKeyAlgorithmTags.X448: { byte[] pointEnc = new byte[X448PublicKeyParameters.KEY_SIZE]; ((X448PublicKeyParameters)pubKey).encode(pointEnc, 0); return new X448PublicBCPGKey(pointEnc); } default: { throw new PGPException("unknown public key algorithm encountered: " + algorithm); } } } private AsymmetricKeyParameter implGetPublicKeyX509(OctetArrayBCPGKey eddsaK, ASN1ObjectIdentifier algorithm) throws IOException { byte[] pEnc = Arrays.clone(eddsaK.getKey()); return PublicKeyFactory.createKey(new SubjectPublicKeyInfo(new AlgorithmIdentifier(algorithm), Arrays.copyOfRange(pEnc, 0, pEnc.length))); } private AsymmetricKeyParameter implGetPublicKeyX509(ASN1ObjectIdentifier algorithm, byte[] pEnc, int pEncOff) throws IOException { return PublicKeyFactory.createKey(new SubjectPublicKeyInfo(new AlgorithmIdentifier(algorithm), Arrays.copyOfRange(pEnc, pEncOff, pEnc.length))); } private ECNamedDomainParameters implGetParametersEC(ECPublicBCPGKey ecPub) { ASN1ObjectIdentifier curveOID = ecPub.getCurveOID(); X9ECParameters x9 = BcUtil.getX9Parameters(curveOID); return new ECNamedDomainParameters(curveOID, x9.getCurve(), x9.getG(), x9.getN(), x9.getH()); } private AsymmetricKeyParameter implGetPrivateKeyEC(ECPublicBCPGKey ecPub, ECSecretBCPGKey ecPriv) throws PGPException { ECNamedDomainParameters parameters = implGetParametersEC(ecPub); return new ECPrivateKeyParameters(ecPriv.getX(), parameters); } private AsymmetricKeyParameter implGetPrivateKeyPKCS8(ASN1ObjectIdentifier algorithm, int keySize, BCPGKey privPk) throws IOException { return PrivateKeyFactory.createKey(getPrivateKeyInfo(algorithm, BigIntegers.asUnsignedByteArray(keySize, ((EdSecretBCPGKey)privPk).getX()))); } private AsymmetricKeyParameter implGetPublicKeyEC(ECPublicBCPGKey ecPub) throws PGPException { ECNamedDomainParameters parameters = implGetParametersEC(ecPub); ECPoint pubPoint = BcUtil.decodePoint(ecPub.getEncodedPoint(), parameters.getCurve()); return new ECPublicKeyParameters(pubPoint, parameters); } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy