PublicKeyFactory.java revision 5db505e1f6a68c8d5dfdb0fed0b8607dea7bed96
1524b2626c2d018f330ae7423c858ef73ea0424b5Chia-I Wupackage org.bouncycastle.crypto.util; 2524b2626c2d018f330ae7423c858ef73ea0424b5Chia-I Wu 3524b2626c2d018f330ae7423c858ef73ea0424b5Chia-I Wuimport java.io.IOException; 4524b2626c2d018f330ae7423c858ef73ea0424b5Chia-I Wuimport java.io.InputStream; 5524b2626c2d018f330ae7423c858ef73ea0424b5Chia-I Wuimport java.math.BigInteger; 6524b2626c2d018f330ae7423c858ef73ea0424b5Chia-I Wu 7524b2626c2d018f330ae7423c858ef73ea0424b5Chia-I Wuimport org.bouncycastle.asn1.ASN1Encodable; 8524b2626c2d018f330ae7423c858ef73ea0424b5Chia-I Wuimport org.bouncycastle.asn1.ASN1InputStream; 9524b2626c2d018f330ae7423c858ef73ea0424b5Chia-I Wuimport org.bouncycastle.asn1.ASN1Integer; 10524b2626c2d018f330ae7423c858ef73ea0424b5Chia-I Wuimport org.bouncycastle.asn1.ASN1ObjectIdentifier; 11524b2626c2d018f330ae7423c858ef73ea0424b5Chia-I Wuimport org.bouncycastle.asn1.ASN1OctetString; 12524b2626c2d018f330ae7423c858ef73ea0424b5Chia-I Wuimport org.bouncycastle.asn1.ASN1Primitive; 13524b2626c2d018f330ae7423c858ef73ea0424b5Chia-I Wuimport org.bouncycastle.asn1.ASN1Sequence; 14524b2626c2d018f330ae7423c858ef73ea0424b5Chia-I Wuimport org.bouncycastle.asn1.DEROctetString; 15524b2626c2d018f330ae7423c858ef73ea0424b5Chia-I Wu// BEGIN android-removed 16524b2626c2d018f330ae7423c858ef73ea0424b5Chia-I Wu// import org.bouncycastle.asn1.oiw.ElGamalParameter; 17524b2626c2d018f330ae7423c858ef73ea0424b5Chia-I Wu// END android-removed 18524b2626c2d018f330ae7423c858ef73ea0424b5Chia-I Wuimport org.bouncycastle.asn1.oiw.OIWObjectIdentifiers; 19524b2626c2d018f330ae7423c858ef73ea0424b5Chia-I Wuimport org.bouncycastle.asn1.pkcs.DHParameter; 20524b2626c2d018f330ae7423c858ef73ea0424b5Chia-I Wuimport org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers; 21524b2626c2d018f330ae7423c858ef73ea0424b5Chia-I Wuimport org.bouncycastle.asn1.pkcs.RSAPublicKey; 22524b2626c2d018f330ae7423c858ef73ea0424b5Chia-I Wuimport org.bouncycastle.asn1.x509.AlgorithmIdentifier; 23524b2626c2d018f330ae7423c858ef73ea0424b5Chia-I Wuimport org.bouncycastle.asn1.x509.DSAParameter; 24524b2626c2d018f330ae7423c858ef73ea0424b5Chia-I Wuimport org.bouncycastle.asn1.x509.SubjectPublicKeyInfo; 25524b2626c2d018f330ae7423c858ef73ea0424b5Chia-I Wuimport org.bouncycastle.asn1.x509.X509ObjectIdentifiers; 26524b2626c2d018f330ae7423c858ef73ea0424b5Chia-I Wuimport org.bouncycastle.asn1.x9.DHDomainParameters; 27524b2626c2d018f330ae7423c858ef73ea0424b5Chia-I Wuimport org.bouncycastle.asn1.x9.DHPublicKey; 28524b2626c2d018f330ae7423c858ef73ea0424b5Chia-I Wuimport org.bouncycastle.asn1.x9.DHValidationParms; 29524b2626c2d018f330ae7423c858ef73ea0424b5Chia-I Wuimport org.bouncycastle.asn1.x9.ECNamedCurveTable; 30524b2626c2d018f330ae7423c858ef73ea0424b5Chia-I Wuimport org.bouncycastle.asn1.x9.X962Parameters; 31524b2626c2d018f330ae7423c858ef73ea0424b5Chia-I Wuimport org.bouncycastle.asn1.x9.X9ECParameters; 32524b2626c2d018f330ae7423c858ef73ea0424b5Chia-I Wuimport org.bouncycastle.asn1.x9.X9ECPoint; 33d38afcd2f286e924e0f9b7f484712ac19e3f98fcChia-I Wuimport org.bouncycastle.asn1.x9.X9ObjectIdentifiers; 34524b2626c2d018f330ae7423c858ef73ea0424b5Chia-I Wuimport org.bouncycastle.crypto.params.AsymmetricKeyParameter; 35524b2626c2d018f330ae7423c858ef73ea0424b5Chia-I Wuimport org.bouncycastle.crypto.params.DHParameters; 36524b2626c2d018f330ae7423c858ef73ea0424b5Chia-I Wuimport org.bouncycastle.crypto.params.DHPublicKeyParameters; 37524b2626c2d018f330ae7423c858ef73ea0424b5Chia-I Wuimport org.bouncycastle.crypto.params.DHValidationParameters; 38524b2626c2d018f330ae7423c858ef73ea0424b5Chia-I Wuimport org.bouncycastle.crypto.params.DSAParameters; 39524b2626c2d018f330ae7423c858ef73ea0424b5Chia-I Wuimport org.bouncycastle.crypto.params.DSAPublicKeyParameters; 40524b2626c2d018f330ae7423c858ef73ea0424b5Chia-I Wuimport org.bouncycastle.crypto.params.ECDomainParameters; 41524b2626c2d018f330ae7423c858ef73ea0424b5Chia-I Wuimport org.bouncycastle.crypto.params.ECPublicKeyParameters; 42524b2626c2d018f330ae7423c858ef73ea0424b5Chia-I Wu// BEGIN android-removed 43524b2626c2d018f330ae7423c858ef73ea0424b5Chia-I Wu// import org.bouncycastle.crypto.params.ElGamalParameters; 44524b2626c2d018f330ae7423c858ef73ea0424b5Chia-I Wu// import org.bouncycastle.crypto.params.ElGamalPublicKeyParameters; 45524b2626c2d018f330ae7423c858ef73ea0424b5Chia-I Wu// END android-removed 46524b2626c2d018f330ae7423c858ef73ea0424b5Chia-I Wuimport org.bouncycastle.crypto.params.RSAKeyParameters; 47524b2626c2d018f330ae7423c858ef73ea0424b5Chia-I Wu 48524b2626c2d018f330ae7423c858ef73ea0424b5Chia-I Wu/** 49524b2626c2d018f330ae7423c858ef73ea0424b5Chia-I Wu * Factory to create asymmetric public key parameters for asymmetric ciphers from range of 50524b2626c2d018f330ae7423c858ef73ea0424b5Chia-I Wu * ASN.1 encoded SubjectPublicKeyInfo objects. 51524b2626c2d018f330ae7423c858ef73ea0424b5Chia-I Wu */ 52524b2626c2d018f330ae7423c858ef73ea0424b5Chia-I Wupublic class PublicKeyFactory 53d38afcd2f286e924e0f9b7f484712ac19e3f98fcChia-I Wu{ 54524b2626c2d018f330ae7423c858ef73ea0424b5Chia-I Wu /** 55524b2626c2d018f330ae7423c858ef73ea0424b5Chia-I Wu * Create a public key from a SubjectPublicKeyInfo encoding 56524b2626c2d018f330ae7423c858ef73ea0424b5Chia-I Wu * 57f141abdc8fdbff41e16b0ce53fa3fa8fba32a7f9Chia-I Wu * @param keyInfoData the SubjectPublicKeyInfo encoding 58524b2626c2d018f330ae7423c858ef73ea0424b5Chia-I Wu * @return the appropriate key parameter 59f141abdc8fdbff41e16b0ce53fa3fa8fba32a7f9Chia-I Wu * @throws IOException on an error decoding the key 60f141abdc8fdbff41e16b0ce53fa3fa8fba32a7f9Chia-I Wu */ 61524b2626c2d018f330ae7423c858ef73ea0424b5Chia-I Wu public static AsymmetricKeyParameter createKey(byte[] keyInfoData) throws IOException 62524b2626c2d018f330ae7423c858ef73ea0424b5Chia-I Wu { 63524b2626c2d018f330ae7423c858ef73ea0424b5Chia-I Wu return createKey(SubjectPublicKeyInfo.getInstance(ASN1Primitive.fromByteArray(keyInfoData))); 64524b2626c2d018f330ae7423c858ef73ea0424b5Chia-I Wu } 65524b2626c2d018f330ae7423c858ef73ea0424b5Chia-I Wu 66524b2626c2d018f330ae7423c858ef73ea0424b5Chia-I Wu /** 67524b2626c2d018f330ae7423c858ef73ea0424b5Chia-I Wu * Create a public key from a SubjectPublicKeyInfo encoding read from a stream 68524b2626c2d018f330ae7423c858ef73ea0424b5Chia-I Wu * 69524b2626c2d018f330ae7423c858ef73ea0424b5Chia-I Wu * @param inStr the stream to read the SubjectPublicKeyInfo encoding from 70524b2626c2d018f330ae7423c858ef73ea0424b5Chia-I Wu * @return the appropriate key parameter 71524b2626c2d018f330ae7423c858ef73ea0424b5Chia-I Wu * @throws IOException on an error decoding the key 72524b2626c2d018f330ae7423c858ef73ea0424b5Chia-I Wu */ 73524b2626c2d018f330ae7423c858ef73ea0424b5Chia-I Wu public static AsymmetricKeyParameter createKey(InputStream inStr) throws IOException 74524b2626c2d018f330ae7423c858ef73ea0424b5Chia-I Wu { 75524b2626c2d018f330ae7423c858ef73ea0424b5Chia-I Wu return createKey(SubjectPublicKeyInfo.getInstance(new ASN1InputStream(inStr).readObject())); 76524b2626c2d018f330ae7423c858ef73ea0424b5Chia-I Wu } 77524b2626c2d018f330ae7423c858ef73ea0424b5Chia-I Wu 78524b2626c2d018f330ae7423c858ef73ea0424b5Chia-I Wu /** 79524b2626c2d018f330ae7423c858ef73ea0424b5Chia-I Wu * Create a public key from the passed in SubjectPublicKeyInfo 80524b2626c2d018f330ae7423c858ef73ea0424b5Chia-I Wu * 81524b2626c2d018f330ae7423c858ef73ea0424b5Chia-I Wu * @param keyInfo the SubjectPublicKeyInfo containing the key data 82524b2626c2d018f330ae7423c858ef73ea0424b5Chia-I Wu * @return the appropriate key parameter 83f141abdc8fdbff41e16b0ce53fa3fa8fba32a7f9Chia-I Wu * @throws IOException on an error decoding the key 84524b2626c2d018f330ae7423c858ef73ea0424b5Chia-I Wu */ 85524b2626c2d018f330ae7423c858ef73ea0424b5Chia-I Wu public static AsymmetricKeyParameter createKey(SubjectPublicKeyInfo keyInfo) throws IOException 86524b2626c2d018f330ae7423c858ef73ea0424b5Chia-I Wu { 87524b2626c2d018f330ae7423c858ef73ea0424b5Chia-I Wu AlgorithmIdentifier algId = keyInfo.getAlgorithm(); 88524b2626c2d018f330ae7423c858ef73ea0424b5Chia-I Wu 89524b2626c2d018f330ae7423c858ef73ea0424b5Chia-I Wu if (algId.getAlgorithm().equals(PKCSObjectIdentifiers.rsaEncryption) 90524b2626c2d018f330ae7423c858ef73ea0424b5Chia-I Wu || algId.getAlgorithm().equals(X509ObjectIdentifiers.id_ea_rsa)) 91524b2626c2d018f330ae7423c858ef73ea0424b5Chia-I Wu { 92524b2626c2d018f330ae7423c858ef73ea0424b5Chia-I Wu RSAPublicKey pubKey = RSAPublicKey.getInstance(keyInfo.parsePublicKey()); 93f141abdc8fdbff41e16b0ce53fa3fa8fba32a7f9Chia-I Wu 94524b2626c2d018f330ae7423c858ef73ea0424b5Chia-I Wu return new RSAKeyParameters(false, pubKey.getModulus(), pubKey.getPublicExponent()); 95524b2626c2d018f330ae7423c858ef73ea0424b5Chia-I Wu } 96524b2626c2d018f330ae7423c858ef73ea0424b5Chia-I Wu else if (algId.getAlgorithm().equals(X9ObjectIdentifiers.dhpublicnumber)) 97524b2626c2d018f330ae7423c858ef73ea0424b5Chia-I Wu { 98524b2626c2d018f330ae7423c858ef73ea0424b5Chia-I Wu DHPublicKey dhPublicKey = DHPublicKey.getInstance(keyInfo.parsePublicKey()); 99524b2626c2d018f330ae7423c858ef73ea0424b5Chia-I Wu 100524b2626c2d018f330ae7423c858ef73ea0424b5Chia-I Wu BigInteger y = dhPublicKey.getY().getValue(); 101524b2626c2d018f330ae7423c858ef73ea0424b5Chia-I Wu 102524b2626c2d018f330ae7423c858ef73ea0424b5Chia-I Wu DHDomainParameters dhParams = DHDomainParameters.getInstance(algId.getParameters()); 103524b2626c2d018f330ae7423c858ef73ea0424b5Chia-I Wu 104524b2626c2d018f330ae7423c858ef73ea0424b5Chia-I Wu BigInteger p = dhParams.getP().getValue(); 105524b2626c2d018f330ae7423c858ef73ea0424b5Chia-I Wu BigInteger g = dhParams.getG().getValue(); 106524b2626c2d018f330ae7423c858ef73ea0424b5Chia-I Wu BigInteger q = dhParams.getQ().getValue(); 107524b2626c2d018f330ae7423c858ef73ea0424b5Chia-I Wu 108524b2626c2d018f330ae7423c858ef73ea0424b5Chia-I Wu BigInteger j = null; 109524b2626c2d018f330ae7423c858ef73ea0424b5Chia-I Wu if (dhParams.getJ() != null) 110524b2626c2d018f330ae7423c858ef73ea0424b5Chia-I Wu { 111524b2626c2d018f330ae7423c858ef73ea0424b5Chia-I Wu j = dhParams.getJ().getValue(); 112524b2626c2d018f330ae7423c858ef73ea0424b5Chia-I Wu } 113524b2626c2d018f330ae7423c858ef73ea0424b5Chia-I Wu 114524b2626c2d018f330ae7423c858ef73ea0424b5Chia-I Wu DHValidationParameters validation = null; 115524b2626c2d018f330ae7423c858ef73ea0424b5Chia-I Wu DHValidationParms dhValidationParms = dhParams.getValidationParms(); 116524b2626c2d018f330ae7423c858ef73ea0424b5Chia-I Wu if (dhValidationParms != null) 117524b2626c2d018f330ae7423c858ef73ea0424b5Chia-I Wu { 118524b2626c2d018f330ae7423c858ef73ea0424b5Chia-I Wu byte[] seed = dhValidationParms.getSeed().getBytes(); 119524b2626c2d018f330ae7423c858ef73ea0424b5Chia-I Wu BigInteger pgenCounter = dhValidationParms.getPgenCounter().getValue(); 120524b2626c2d018f330ae7423c858ef73ea0424b5Chia-I Wu 121524b2626c2d018f330ae7423c858ef73ea0424b5Chia-I Wu // TODO Check pgenCounter size? 122524b2626c2d018f330ae7423c858ef73ea0424b5Chia-I Wu 123524b2626c2d018f330ae7423c858ef73ea0424b5Chia-I Wu validation = new DHValidationParameters(seed, pgenCounter.intValue()); 124524b2626c2d018f330ae7423c858ef73ea0424b5Chia-I Wu } 125524b2626c2d018f330ae7423c858ef73ea0424b5Chia-I Wu 126524b2626c2d018f330ae7423c858ef73ea0424b5Chia-I Wu return new DHPublicKeyParameters(y, new DHParameters(p, g, q, j, validation)); 127524b2626c2d018f330ae7423c858ef73ea0424b5Chia-I Wu } 128524b2626c2d018f330ae7423c858ef73ea0424b5Chia-I Wu else if (algId.getAlgorithm().equals(PKCSObjectIdentifiers.dhKeyAgreement)) 129524b2626c2d018f330ae7423c858ef73ea0424b5Chia-I Wu { 130524b2626c2d018f330ae7423c858ef73ea0424b5Chia-I Wu DHParameter params = DHParameter.getInstance(algId.getParameters()); 131524b2626c2d018f330ae7423c858ef73ea0424b5Chia-I Wu ASN1Integer derY = (ASN1Integer)keyInfo.parsePublicKey(); 132524b2626c2d018f330ae7423c858ef73ea0424b5Chia-I Wu 133524b2626c2d018f330ae7423c858ef73ea0424b5Chia-I Wu BigInteger lVal = params.getL(); 134524b2626c2d018f330ae7423c858ef73ea0424b5Chia-I Wu int l = lVal == null ? 0 : lVal.intValue(); 135524b2626c2d018f330ae7423c858ef73ea0424b5Chia-I Wu DHParameters dhParams = new DHParameters(params.getP(), params.getG(), null, l); 136524b2626c2d018f330ae7423c858ef73ea0424b5Chia-I Wu 137524b2626c2d018f330ae7423c858ef73ea0424b5Chia-I Wu return new DHPublicKeyParameters(derY.getValue(), dhParams); 138524b2626c2d018f330ae7423c858ef73ea0424b5Chia-I Wu } 139524b2626c2d018f330ae7423c858ef73ea0424b5Chia-I Wu // BEGIN android-removed 140524b2626c2d018f330ae7423c858ef73ea0424b5Chia-I Wu // else if (algId.getAlgorithm().equals(OIWObjectIdentifiers.elGamalAlgorithm)) 141524b2626c2d018f330ae7423c858ef73ea0424b5Chia-I Wu // { 142524b2626c2d018f330ae7423c858ef73ea0424b5Chia-I Wu // ElGamalParameter params = new ElGamalParameter((ASN1Sequence)algId.getParameters()); 143524b2626c2d018f330ae7423c858ef73ea0424b5Chia-I Wu // ASN1Integer derY = (ASN1Integer)keyInfo.parsePublicKey(); 144524b2626c2d018f330ae7423c858ef73ea0424b5Chia-I Wu // 145524b2626c2d018f330ae7423c858ef73ea0424b5Chia-I Wu // return new ElGamalPublicKeyParameters(derY.getValue(), new ElGamalParameters( 146524b2626c2d018f330ae7423c858ef73ea0424b5Chia-I Wu // params.getP(), params.getG())); 147524b2626c2d018f330ae7423c858ef73ea0424b5Chia-I Wu // } 148524b2626c2d018f330ae7423c858ef73ea0424b5Chia-I Wu // END android-removed 149524b2626c2d018f330ae7423c858ef73ea0424b5Chia-I Wu else if (algId.getAlgorithm().equals(X9ObjectIdentifiers.id_dsa) 150524b2626c2d018f330ae7423c858ef73ea0424b5Chia-I Wu || algId.getAlgorithm().equals(OIWObjectIdentifiers.dsaWithSHA1)) 151524b2626c2d018f330ae7423c858ef73ea0424b5Chia-I Wu { 152524b2626c2d018f330ae7423c858ef73ea0424b5Chia-I Wu ASN1Integer derY = (ASN1Integer)keyInfo.parsePublicKey(); 153524b2626c2d018f330ae7423c858ef73ea0424b5Chia-I Wu ASN1Encodable de = algId.getParameters(); 154524b2626c2d018f330ae7423c858ef73ea0424b5Chia-I Wu 155524b2626c2d018f330ae7423c858ef73ea0424b5Chia-I Wu DSAParameters parameters = null; 156524b2626c2d018f330ae7423c858ef73ea0424b5Chia-I Wu if (de != null) 157524b2626c2d018f330ae7423c858ef73ea0424b5Chia-I Wu { 158524b2626c2d018f330ae7423c858ef73ea0424b5Chia-I Wu DSAParameter params = DSAParameter.getInstance(de.toASN1Primitive()); 159524b2626c2d018f330ae7423c858ef73ea0424b5Chia-I Wu parameters = new DSAParameters(params.getP(), params.getQ(), params.getG()); 160524b2626c2d018f330ae7423c858ef73ea0424b5Chia-I Wu } 161524b2626c2d018f330ae7423c858ef73ea0424b5Chia-I Wu 162524b2626c2d018f330ae7423c858ef73ea0424b5Chia-I Wu return new DSAPublicKeyParameters(derY.getValue(), parameters); 163524b2626c2d018f330ae7423c858ef73ea0424b5Chia-I Wu } 164524b2626c2d018f330ae7423c858ef73ea0424b5Chia-I Wu else if (algId.getAlgorithm().equals(X9ObjectIdentifiers.id_ecPublicKey)) 165524b2626c2d018f330ae7423c858ef73ea0424b5Chia-I Wu { 166524b2626c2d018f330ae7423c858ef73ea0424b5Chia-I Wu X962Parameters params = X962Parameters.getInstance(algId.getParameters()); 167524b2626c2d018f330ae7423c858ef73ea0424b5Chia-I Wu 168524b2626c2d018f330ae7423c858ef73ea0424b5Chia-I Wu X9ECParameters x9; 169524b2626c2d018f330ae7423c858ef73ea0424b5Chia-I Wu if (params.isNamedCurve()) 170524b2626c2d018f330ae7423c858ef73ea0424b5Chia-I Wu { 171524b2626c2d018f330ae7423c858ef73ea0424b5Chia-I Wu ASN1ObjectIdentifier oid = (ASN1ObjectIdentifier)params.getParameters(); 172524b2626c2d018f330ae7423c858ef73ea0424b5Chia-I Wu x9 = ECNamedCurveTable.getByOID(oid); 173524b2626c2d018f330ae7423c858ef73ea0424b5Chia-I Wu } 174524b2626c2d018f330ae7423c858ef73ea0424b5Chia-I Wu else 175524b2626c2d018f330ae7423c858ef73ea0424b5Chia-I Wu { 176524b2626c2d018f330ae7423c858ef73ea0424b5Chia-I Wu x9 = X9ECParameters.getInstance(params.getParameters()); 177524b2626c2d018f330ae7423c858ef73ea0424b5Chia-I Wu } 178524b2626c2d018f330ae7423c858ef73ea0424b5Chia-I Wu 179524b2626c2d018f330ae7423c858ef73ea0424b5Chia-I Wu ASN1OctetString key = new DEROctetString(keyInfo.getPublicKeyData().getBytes()); 180524b2626c2d018f330ae7423c858ef73ea0424b5Chia-I Wu X9ECPoint derQ = new X9ECPoint(x9.getCurve(), key); 181524b2626c2d018f330ae7423c858ef73ea0424b5Chia-I Wu 182524b2626c2d018f330ae7423c858ef73ea0424b5Chia-I Wu // TODO We lose any named parameters here 183524b2626c2d018f330ae7423c858ef73ea0424b5Chia-I Wu 184524b2626c2d018f330ae7423c858ef73ea0424b5Chia-I Wu ECDomainParameters dParams = new ECDomainParameters( 185524b2626c2d018f330ae7423c858ef73ea0424b5Chia-I Wu x9.getCurve(), x9.getG(), x9.getN(), x9.getH(), x9.getSeed()); 186524b2626c2d018f330ae7423c858ef73ea0424b5Chia-I Wu 187524b2626c2d018f330ae7423c858ef73ea0424b5Chia-I Wu return new ECPublicKeyParameters(derQ.getPoint(), dParams); 188524b2626c2d018f330ae7423c858ef73ea0424b5Chia-I Wu } 189524b2626c2d018f330ae7423c858ef73ea0424b5Chia-I Wu else 190524b2626c2d018f330ae7423c858ef73ea0424b5Chia-I Wu { 191524b2626c2d018f330ae7423c858ef73ea0424b5Chia-I Wu throw new RuntimeException("algorithm identifier in key not recognised"); 192524b2626c2d018f330ae7423c858ef73ea0424b5Chia-I Wu } 193524b2626c2d018f330ae7423c858ef73ea0424b5Chia-I Wu } 194524b2626c2d018f330ae7423c858ef73ea0424b5Chia-I Wu} 195524b2626c2d018f330ae7423c858ef73ea0424b5Chia-I Wu