PrivateKeyFactory.java revision e1142c149e244797ce73b0e7fad40816e447a817
1package org.bouncycastle.crypto.util; 2 3import java.io.IOException; 4import java.io.InputStream; 5import java.math.BigInteger; 6 7import org.bouncycastle.asn1.ASN1Encodable; 8import org.bouncycastle.asn1.ASN1InputStream; 9import org.bouncycastle.asn1.ASN1Integer; 10import org.bouncycastle.asn1.ASN1ObjectIdentifier; 11import org.bouncycastle.asn1.ASN1Primitive; 12import org.bouncycastle.asn1.ASN1Sequence; 13import org.bouncycastle.asn1.nist.NISTNamedCurves; 14// BEGIN android-removed 15// import org.bouncycastle.asn1.oiw.ElGamalParameter; 16// END android-removed 17import org.bouncycastle.asn1.oiw.OIWObjectIdentifiers; 18import org.bouncycastle.asn1.pkcs.DHParameter; 19import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers; 20import org.bouncycastle.asn1.pkcs.PrivateKeyInfo; 21import org.bouncycastle.asn1.pkcs.RSAPrivateKey; 22import org.bouncycastle.asn1.sec.ECPrivateKey; 23import org.bouncycastle.asn1.sec.SECNamedCurves; 24// BEGIN android-removed 25// import org.bouncycastle.asn1.teletrust.TeleTrusTNamedCurves; 26// END android-removed 27import org.bouncycastle.asn1.x509.AlgorithmIdentifier; 28import org.bouncycastle.asn1.x509.DSAParameter; 29import org.bouncycastle.asn1.x9.X962NamedCurves; 30import org.bouncycastle.asn1.x9.X962Parameters; 31import org.bouncycastle.asn1.x9.X9ECParameters; 32import org.bouncycastle.asn1.x9.X9ObjectIdentifiers; 33import org.bouncycastle.crypto.params.AsymmetricKeyParameter; 34import org.bouncycastle.crypto.params.DHParameters; 35import org.bouncycastle.crypto.params.DHPrivateKeyParameters; 36import org.bouncycastle.crypto.params.DSAParameters; 37import org.bouncycastle.crypto.params.DSAPrivateKeyParameters; 38import org.bouncycastle.crypto.params.ECDomainParameters; 39import org.bouncycastle.crypto.params.ECPrivateKeyParameters; 40// BEGIN android-removed 41// import org.bouncycastle.crypto.params.ElGamalParameters; 42// import org.bouncycastle.crypto.params.ElGamalPrivateKeyParameters; 43// END android-removed 44import org.bouncycastle.crypto.params.RSAPrivateCrtKeyParameters; 45 46/** 47 * Factory for creating private key objects from PKCS8 PrivateKeyInfo objects. 48 */ 49public class PrivateKeyFactory 50{ 51 /** 52 * Create a private key parameter from a PKCS8 PrivateKeyInfo encoding. 53 * 54 * @param privateKeyInfoData the PrivateKeyInfo encoding 55 * @return a suitable private key parameter 56 * @throws IOException on an error decoding the key 57 */ 58 public static AsymmetricKeyParameter createKey(byte[] privateKeyInfoData) throws IOException 59 { 60 return createKey(PrivateKeyInfo.getInstance(ASN1Primitive.fromByteArray(privateKeyInfoData))); 61 } 62 63 /** 64 * Create a private key parameter from a PKCS8 PrivateKeyInfo encoding read from a 65 * stream. 66 * 67 * @param inStr the stream to read the PrivateKeyInfo encoding from 68 * @return a suitable private key parameter 69 * @throws IOException on an error decoding the key 70 */ 71 public static AsymmetricKeyParameter createKey(InputStream inStr) throws IOException 72 { 73 return createKey(PrivateKeyInfo.getInstance(new ASN1InputStream(inStr).readObject())); 74 } 75 76 /** 77 * Create a private key parameter from the passed in PKCS8 PrivateKeyInfo object. 78 * 79 * @param keyInfo the PrivateKeyInfo object containing the key material 80 * @return a suitable private key parameter 81 * @throws IOException on an error decoding the key 82 */ 83 public static AsymmetricKeyParameter createKey(PrivateKeyInfo keyInfo) throws IOException 84 { 85 AlgorithmIdentifier algId = keyInfo.getPrivateKeyAlgorithm(); 86 87 if (algId.getAlgorithm().equals(PKCSObjectIdentifiers.rsaEncryption)) 88 { 89 RSAPrivateKey keyStructure = RSAPrivateKey.getInstance(keyInfo.parsePrivateKey()); 90 91 return new RSAPrivateCrtKeyParameters(keyStructure.getModulus(), 92 keyStructure.getPublicExponent(), keyStructure.getPrivateExponent(), 93 keyStructure.getPrime1(), keyStructure.getPrime2(), keyStructure.getExponent1(), 94 keyStructure.getExponent2(), keyStructure.getCoefficient()); 95 } 96 // TODO? 97// else if (algId.getObjectId().equals(X9ObjectIdentifiers.dhpublicnumber)) 98 else if (algId.getAlgorithm().equals(PKCSObjectIdentifiers.dhKeyAgreement)) 99 { 100 DHParameter params = DHParameter.getInstance(algId.getParameters()); 101 ASN1Integer derX = (ASN1Integer)keyInfo.parsePrivateKey(); 102 103 BigInteger lVal = params.getL(); 104 int l = lVal == null ? 0 : lVal.intValue(); 105 DHParameters dhParams = new DHParameters(params.getP(), params.getG(), null, l); 106 107 return new DHPrivateKeyParameters(derX.getValue(), dhParams); 108 } 109 // BEGIN android-removed 110 // else if (algId.getAlgorithm().equals(OIWObjectIdentifiers.elGamalAlgorithm)) 111 // { 112 // ElGamalParameter params = new ElGamalParameter((ASN1Sequence)algId.getParameters()); 113 // ASN1Integer = (ASN1Integer)keyInfo.parsePrivateKey(); 114 // 115 // return new ElGamalPrivateKeyParameters(derX.getValue(), new ElGamalParameters( 116 // params.getP(), params.getG())); 117 // } 118 // END android-removed 119 else if (algId.getAlgorithm().equals(X9ObjectIdentifiers.id_dsa)) 120 { 121 ASN1Integer derX = (ASN1Integer)keyInfo.parsePrivateKey(); 122 ASN1Encodable de = algId.getParameters(); 123 124 DSAParameters parameters = null; 125 if (de != null) 126 { 127 DSAParameter params = DSAParameter.getInstance(de.toASN1Primitive()); 128 parameters = new DSAParameters(params.getP(), params.getQ(), params.getG()); 129 } 130 131 return new DSAPrivateKeyParameters(derX.getValue(), parameters); 132 } 133 else if (algId.getAlgorithm().equals(X9ObjectIdentifiers.id_ecPublicKey)) 134 { 135 X962Parameters params = new X962Parameters((ASN1Primitive)algId.getParameters()); 136 137 X9ECParameters x9; 138 if (params.isNamedCurve()) 139 { 140 ASN1ObjectIdentifier oid = ASN1ObjectIdentifier.getInstance(params.getParameters()); 141 x9 = X962NamedCurves.getByOID(oid); 142 143 if (x9 == null) 144 { 145 x9 = SECNamedCurves.getByOID(oid); 146 147 if (x9 == null) 148 { 149 x9 = NISTNamedCurves.getByOID(oid); 150 151 // BEGIN android-removed 152 // if (x9 == null) 153 // { 154 // x9 = TeleTrusTNamedCurves.getByOID(oid); 155 // } 156 // END android-removed 157 } 158 } 159 } 160 else 161 { 162 x9 = X9ECParameters.getInstance(params.getParameters()); 163 } 164 165 ECPrivateKey ec = ECPrivateKey.getInstance(keyInfo.parsePrivateKey()); 166 BigInteger d = ec.getKey(); 167 168 // TODO We lose any named parameters here 169 170 ECDomainParameters dParams = new ECDomainParameters( 171 x9.getCurve(), x9.getG(), x9.getN(), x9.getH(), x9.getSeed()); 172 173 return new ECPrivateKeyParameters(d, dParams); 174 } 175 else 176 { 177 throw new RuntimeException("algorithm identifier in key not recognised"); 178 } 179 } 180} 181