package org.spongycastle.openpgp.operator.bc; import java.util.Date; import org.spongycastle.bcpg.BCPGKey; import org.spongycastle.bcpg.DSAPublicBCPGKey; import org.spongycastle.bcpg.DSASecretBCPGKey; import org.spongycastle.bcpg.ElGamalPublicBCPGKey; import org.spongycastle.bcpg.ElGamalSecretBCPGKey; import org.spongycastle.bcpg.PublicKeyAlgorithmTags; import org.spongycastle.bcpg.PublicKeyPacket; import org.spongycastle.bcpg.RSAPublicBCPGKey; import org.spongycastle.bcpg.RSASecretBCPGKey; import org.spongycastle.crypto.params.AsymmetricKeyParameter; import org.spongycastle.crypto.params.DSAParameters; import org.spongycastle.crypto.params.DSAPrivateKeyParameters; import org.spongycastle.crypto.params.DSAPublicKeyParameters; import org.spongycastle.crypto.params.ElGamalParameters; import org.spongycastle.crypto.params.ElGamalPrivateKeyParameters; import org.spongycastle.crypto.params.ElGamalPublicKeyParameters; import org.spongycastle.crypto.params.RSAKeyParameters; import org.spongycastle.crypto.params.RSAPrivateCrtKeyParameters; import org.spongycastle.openpgp.PGPException; import org.spongycastle.openpgp.PGPPrivateKey; import org.spongycastle.openpgp.PGPPublicKey; public class BcPGPKeyConverter { /** * Create a PGPPublicKey from the passed in JCA one. * <p/> * 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. */ public PGPPublicKey getPGPPublicKey(int algorithm, AsymmetricKeyParameter pubKey, Date time) throws PGPException { BCPGKey bcpgKey; if (pubKey instanceof RSAKeyParameters) { RSAKeyParameters rK = (RSAKeyParameters)pubKey; bcpgKey = new RSAPublicBCPGKey(rK.getModulus(), rK.getExponent()); } else if (pubKey instanceof DSAPublicKeyParameters) { DSAPublicKeyParameters dK = (DSAPublicKeyParameters)pubKey; DSAParameters dP = dK.getParameters(); bcpgKey = new DSAPublicBCPGKey(dP.getP(), dP.getQ(), dP.getG(), dK.getY()); } else if (pubKey instanceof ElGamalPublicKeyParameters) { ElGamalPublicKeyParameters eK = (ElGamalPublicKeyParameters)pubKey; ElGamalParameters eS = eK.getParameters(); bcpgKey = new ElGamalPublicBCPGKey(eS.getP(), eS.getG(), eK.getY()); } else { throw new PGPException("unknown key class"); } return new PGPPublicKey(new PublicKeyPacket(algorithm, time, bcpgKey), new BcKeyFingerprintCalculator()); } public PGPPrivateKey getPGPPrivateKey(PGPPublicKey pubKey, AsymmetricKeyParameter privKey) throws PGPException { BCPGKey privPk; switch (pubKey.getAlgorithm()) { case PGPPublicKey.RSA_ENCRYPT: case PGPPublicKey.RSA_SIGN: case PGPPublicKey.RSA_GENERAL: RSAPrivateCrtKeyParameters rsK = (RSAPrivateCrtKeyParameters)privKey; privPk = new RSASecretBCPGKey(rsK.getExponent(), rsK.getP(), rsK.getQ()); break; case PGPPublicKey.DSA: DSAPrivateKeyParameters dsK = (DSAPrivateKeyParameters)privKey; privPk = new DSASecretBCPGKey(dsK.getX()); break; case PGPPublicKey.ELGAMAL_ENCRYPT: case PGPPublicKey.ELGAMAL_GENERAL: ElGamalPrivateKeyParameters esK = (ElGamalPrivateKeyParameters)privKey; privPk = new ElGamalSecretBCPGKey(esK.getX()); break; default: throw new PGPException("unknown key class"); } return new PGPPrivateKey(pubKey.getKeyID(), pubKey.getPublicKeyPacket(), privPk); } public AsymmetricKeyParameter getPublicKey(PGPPublicKey publicKey) throws PGPException { PublicKeyPacket publicPk = publicKey.getPublicKeyPacket(); try { switch (publicPk.getAlgorithm()) { 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()); case PublicKeyAlgorithmTags.DSA: DSAPublicBCPGKey dsaK = (DSAPublicBCPGKey)publicPk.getKey(); return new DSAPublicKeyParameters(dsaK.getY(), new DSAParameters(dsaK.getP(), dsaK.getQ(), dsaK.getG())); case PublicKeyAlgorithmTags.ELGAMAL_ENCRYPT: case PublicKeyAlgorithmTags.ELGAMAL_GENERAL: ElGamalPublicBCPGKey elK = (ElGamalPublicBCPGKey)publicPk.getKey(); return new ElGamalPublicKeyParameters(elK.getY(), new ElGamalParameters(elK.getP(), elK.getG())); default: throw new PGPException("unknown public key algorithm encountered"); } } catch (PGPException e) { throw e; } catch (Exception e) { throw new PGPException("exception constructing public key", e); } } public AsymmetricKeyParameter getPrivateKey(PGPPrivateKey privKey) throws PGPException { PublicKeyPacket pubPk = privKey.getPublicKeyPacket(); BCPGKey privPk = privKey.getPrivateKeyDataPacket(); try { switch (pubPk.getAlgorithm()) { case PGPPublicKey.RSA_ENCRYPT: case PGPPublicKey.RSA_GENERAL: case PGPPublicKey.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()); case PGPPublicKey.DSA: DSAPublicBCPGKey dsaPub = (DSAPublicBCPGKey)pubPk.getKey(); DSASecretBCPGKey dsaPriv = (DSASecretBCPGKey)privPk; return new DSAPrivateKeyParameters(dsaPriv.getX(), new DSAParameters(dsaPub.getP(), dsaPub.getQ(), dsaPub.getG())); case PGPPublicKey.ELGAMAL_ENCRYPT: case PGPPublicKey.ELGAMAL_GENERAL: ElGamalPublicBCPGKey elPub = (ElGamalPublicBCPGKey)pubPk.getKey(); ElGamalSecretBCPGKey elPriv = (ElGamalSecretBCPGKey)privPk; return new ElGamalPrivateKeyParameters(elPriv.getX(), new ElGamalParameters(elPub.getP(), elPub.getG())); default: throw new PGPException("unknown public key algorithm encountered"); } } catch (PGPException e) { throw e; } catch (Exception e) { throw new PGPException("Exception constructing key", e); } } }