package org.bouncycastle.crypto.util; import java.io.IOException; import org.bouncycastle.asn1.ASN1OctetString; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.DERBitString; import org.bouncycastle.asn1.DERInteger; import org.bouncycastle.asn1.DERObject; import org.bouncycastle.asn1.DERObjectIdentifier; import org.bouncycastle.asn1.DEROctetString; // BEGIN android-removed // import org.bouncycastle.asn1.oiw.ElGamalParameter; // END android-removed import org.bouncycastle.asn1.oiw.OIWObjectIdentifiers; import org.bouncycastle.asn1.pkcs.DHParameter; import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; import org.bouncycastle.asn1.x509.DSAParameter; import org.bouncycastle.asn1.x509.RSAPublicKeyStructure; import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo; import org.bouncycastle.asn1.x509.X509ObjectIdentifiers; // BEGIN android-removed // import org.bouncycastle.asn1.x9.X962NamedCurves; // import org.bouncycastle.asn1.x9.X962Parameters; // import org.bouncycastle.asn1.x9.X9ECParameters; // import org.bouncycastle.asn1.x9.X9ECPoint; // END android-removed import org.bouncycastle.asn1.x9.X9ObjectIdentifiers; import org.bouncycastle.crypto.params.AsymmetricKeyParameter; import org.bouncycastle.crypto.params.DHParameters; import org.bouncycastle.crypto.params.DHPublicKeyParameters; import org.bouncycastle.crypto.params.DSAParameters; import org.bouncycastle.crypto.params.DSAPublicKeyParameters; // BEGIN android-removed // import org.bouncycastle.crypto.params.ECDomainParameters; // import org.bouncycastle.crypto.params.ECPublicKeyParameters; // import org.bouncycastle.crypto.params.ElGamalParameters; // import org.bouncycastle.crypto.params.ElGamalPublicKeyParameters; // END android-removed import org.bouncycastle.crypto.params.RSAKeyParameters; /** * Factory to create asymmetric public key parameters for asymmetric ciphers * from range of ASN.1 encoded SubjectPublicKeyInfo objects. */ public class PublicKeyFactory { /** * Create a public key from the passed in SubjectPublicKeyInfo * * @param keyInfo the SubjectPublicKeyInfo containing the key data * @return the appropriate key parameter * @throws IOException on an error decoding the key */ public static AsymmetricKeyParameter createKey( SubjectPublicKeyInfo keyInfo) throws IOException { AlgorithmIdentifier algId = keyInfo.getAlgorithmId(); if (algId.getObjectId().equals(PKCSObjectIdentifiers.rsaEncryption) || algId.getObjectId().equals(X509ObjectIdentifiers.id_ea_rsa)) { RSAPublicKeyStructure pubKey = new RSAPublicKeyStructure((ASN1Sequence)keyInfo.getPublicKey()); return new RSAKeyParameters(false, pubKey.getModulus(), pubKey.getPublicExponent()); } else if (algId.getObjectId().equals(PKCSObjectIdentifiers.dhKeyAgreement) || algId.getObjectId().equals(X9ObjectIdentifiers.dhpublicnumber)) { DHParameter params = new DHParameter((ASN1Sequence)keyInfo.getAlgorithmId().getParameters()); DERInteger derY = (DERInteger)keyInfo.getPublicKey(); return new DHPublicKeyParameters(derY.getValue(), new DHParameters(params.getP(), params.getG())); } // BEGIN android-removed // else if (algId.getObjectId().equals(OIWObjectIdentifiers.elGamalAlgorithm)) // { // ElGamalParameter params = new ElGamalParameter((ASN1Sequence)keyInfo.getAlgorithmId().getParameters()); // DERInteger derY = (DERInteger)keyInfo.getPublicKey(); // // return new ElGamalPublicKeyParameters(derY.getValue(), new ElGamalParameters(params.getP(), params.getG())); // } // END android-removed else if (algId.getObjectId().equals(X9ObjectIdentifiers.id_dsa) || algId.getObjectId().equals(OIWObjectIdentifiers.dsaWithSHA1)) { DSAParameter params = new DSAParameter((ASN1Sequence)keyInfo.getAlgorithmId().getParameters()); DERInteger derY = (DERInteger)keyInfo.getPublicKey(); return new DSAPublicKeyParameters(derY.getValue(), new DSAParameters(params.getP(), params.getQ(), params.getG())); } // BEGIN android-removed // else if (algId.getObjectId().equals(X9ObjectIdentifiers.id_ecPublicKey)) // { // X962Parameters params = new X962Parameters((DERObject)keyInfo.getAlgorithmId().getParameters()); // ECDomainParameters dParams = null; // // if (params.isNamedCurve()) // { // DERObjectIdentifier oid = (DERObjectIdentifier)params.getParameters(); // X9ECParameters ecP = X962NamedCurves.getByOID(oid); // // dParams = new ECDomainParameters( // ecP.getCurve(), // ecP.getG(), // ecP.getN(), // ecP.getH(), // ecP.getSeed()); // } // else // { // X9ECParameters ecP = new X9ECParameters( // (ASN1Sequence)params.getParameters()); // dParams = new ECDomainParameters( // ecP.getCurve(), // ecP.getG(), // ecP.getN(), // ecP.getH(), // ecP.getSeed()); // } // // DERBitString bits = keyInfo.getPublicKeyData(); // byte[] data = bits.getBytes(); // ASN1OctetString key = new DEROctetString(data); // // X9ECPoint derQ = new X9ECPoint(dParams.getCurve(), key); // // return new ECPublicKeyParameters(derQ.getPoint(), dParams); // } // BEGIN android-removed else { throw new RuntimeException("algorithm identifier in key not recognised"); } } }