001: package org.bouncycastle.crypto.util;
002:
003: import org.bouncycastle.asn1.ASN1InputStream;
004: import org.bouncycastle.asn1.ASN1Object;
005: import org.bouncycastle.asn1.ASN1Sequence;
006: import org.bouncycastle.asn1.DERInteger;
007: import org.bouncycastle.asn1.DERObject;
008: import org.bouncycastle.asn1.DERObjectIdentifier;
009: import org.bouncycastle.asn1.nist.NISTNamedCurves;
010: import org.bouncycastle.asn1.oiw.ElGamalParameter;
011: import org.bouncycastle.asn1.oiw.OIWObjectIdentifiers;
012: import org.bouncycastle.asn1.pkcs.DHParameter;
013: import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers;
014: import org.bouncycastle.asn1.pkcs.PrivateKeyInfo;
015: import org.bouncycastle.asn1.pkcs.RSAPrivateKeyStructure;
016: import org.bouncycastle.asn1.sec.ECPrivateKeyStructure;
017: import org.bouncycastle.asn1.sec.SECNamedCurves;
018: import org.bouncycastle.asn1.teletrust.TeleTrusTNamedCurves;
019: import org.bouncycastle.asn1.x509.AlgorithmIdentifier;
020: import org.bouncycastle.asn1.x509.DSAParameter;
021: import org.bouncycastle.asn1.x9.X962NamedCurves;
022: import org.bouncycastle.asn1.x9.X962Parameters;
023: import org.bouncycastle.asn1.x9.X9ECParameters;
024: import org.bouncycastle.asn1.x9.X9ObjectIdentifiers;
025: import org.bouncycastle.crypto.params.AsymmetricKeyParameter;
026: import org.bouncycastle.crypto.params.DHParameters;
027: import org.bouncycastle.crypto.params.DHPrivateKeyParameters;
028: import org.bouncycastle.crypto.params.DSAParameters;
029: import org.bouncycastle.crypto.params.DSAPrivateKeyParameters;
030: import org.bouncycastle.crypto.params.ECDomainParameters;
031: import org.bouncycastle.crypto.params.ECPrivateKeyParameters;
032: import org.bouncycastle.crypto.params.ElGamalParameters;
033: import org.bouncycastle.crypto.params.ElGamalPrivateKeyParameters;
034: import org.bouncycastle.crypto.params.RSAPrivateCrtKeyParameters;
035:
036: import java.io.IOException;
037: import java.io.InputStream;
038:
039: /**
040: * Factory for creating private key objects from PKCS8 PrivateKeyInfo objects.
041: */
042: public class PrivateKeyFactory {
043: /**
044: * Create a private key parameter from a PKCS8 PrivateKeyInfo encoding.
045: *
046: * @param privateKeyInfoData the PrivateKeyInfo encoding
047: * @return a suitable private key parameter
048: * @throws IOException on an error decoding the key
049: */
050: public static AsymmetricKeyParameter createKey(
051: byte[] privateKeyInfoData) throws IOException {
052: return createKey(PrivateKeyInfo.getInstance(ASN1Object
053: .fromByteArray(privateKeyInfoData)));
054: }
055:
056: /**
057: * Create a private key parameter from a PKCS8 PrivateKeyInfo encoding read from a stream.
058: *
059: * @param inStr the stream to read the PrivateKeyInfo encoding from
060: * @return a suitable private key parameter
061: * @throws IOException on an error decoding the key
062: */
063: public static AsymmetricKeyParameter createKey(InputStream inStr)
064: throws IOException {
065: return createKey(PrivateKeyInfo
066: .getInstance(new ASN1InputStream(inStr).readObject()));
067: }
068:
069: /**
070: * Create a private key parameter from the passed in PKCS8 PrivateKeyInfo object.
071: *
072: * @param keyInfo the PrivateKeyInfo object containing the key material
073: * @return a suitable private key parameter
074: * @throws IOException on an error decoding the key
075: */
076: public static AsymmetricKeyParameter createKey(
077: PrivateKeyInfo keyInfo) throws IOException {
078: AlgorithmIdentifier algId = keyInfo.getAlgorithmId();
079:
080: if (algId.getObjectId().equals(
081: PKCSObjectIdentifiers.rsaEncryption)) {
082: RSAPrivateKeyStructure keyStructure = new RSAPrivateKeyStructure(
083: (ASN1Sequence) keyInfo.getPrivateKey());
084:
085: return new RSAPrivateCrtKeyParameters(keyStructure
086: .getModulus(), keyStructure.getPublicExponent(),
087: keyStructure.getPrivateExponent(), keyStructure
088: .getPrime1(), keyStructure.getPrime2(),
089: keyStructure.getExponent1(), keyStructure
090: .getExponent2(), keyStructure
091: .getCoefficient());
092: } else if (algId.getObjectId().equals(
093: PKCSObjectIdentifiers.dhKeyAgreement)) {
094: DHParameter params = new DHParameter((ASN1Sequence) keyInfo
095: .getAlgorithmId().getParameters());
096: DERInteger derX = (DERInteger) keyInfo.getPrivateKey();
097:
098: return new DHPrivateKeyParameters(derX.getValue(),
099: new DHParameters(params.getP(), params.getG()));
100: } else if (algId.getObjectId().equals(
101: OIWObjectIdentifiers.elGamalAlgorithm)) {
102: ElGamalParameter params = new ElGamalParameter(
103: (ASN1Sequence) keyInfo.getAlgorithmId()
104: .getParameters());
105: DERInteger derX = (DERInteger) keyInfo.getPrivateKey();
106:
107: return new ElGamalPrivateKeyParameters(derX.getValue(),
108: new ElGamalParameters(params.getP(), params.getG()));
109: } else if (algId.getObjectId().equals(
110: X9ObjectIdentifiers.id_dsa)) {
111: DSAParameter params = new DSAParameter(
112: (ASN1Sequence) keyInfo.getAlgorithmId()
113: .getParameters());
114: DERInteger derX = (DERInteger) keyInfo.getPrivateKey();
115:
116: return new DSAPrivateKeyParameters(derX.getValue(),
117: new DSAParameters(params.getP(), params.getQ(),
118: params.getG()));
119: } else if (algId.getObjectId().equals(
120: X9ObjectIdentifiers.id_ecPublicKey)) {
121: X962Parameters params = new X962Parameters(
122: (DERObject) keyInfo.getAlgorithmId()
123: .getParameters());
124: ECDomainParameters dParams = null;
125:
126: if (params.isNamedCurve()) {
127: DERObjectIdentifier oid = (DERObjectIdentifier) params
128: .getParameters();
129: X9ECParameters ecP = X962NamedCurves.getByOID(oid);
130:
131: if (ecP == null) {
132: ecP = SECNamedCurves.getByOID(oid);
133:
134: if (ecP == null) {
135: ecP = NISTNamedCurves.getByOID(oid);
136:
137: if (ecP == null) {
138: ecP = TeleTrusTNamedCurves.getByOID(oid);
139: }
140: }
141: }
142:
143: dParams = new ECDomainParameters(ecP.getCurve(), ecP
144: .getG(), ecP.getN(), ecP.getH(), ecP.getSeed());
145: } else {
146: X9ECParameters ecP = new X9ECParameters(
147: (ASN1Sequence) params.getParameters());
148: dParams = new ECDomainParameters(ecP.getCurve(), ecP
149: .getG(), ecP.getN(), ecP.getH(), ecP.getSeed());
150: }
151:
152: ECPrivateKeyStructure ec = new ECPrivateKeyStructure(
153: (ASN1Sequence) keyInfo.getPrivateKey());
154:
155: return new ECPrivateKeyParameters(ec.getKey(), dParams);
156: } else {
157: throw new RuntimeException(
158: "algorithm identifier in key not recognised");
159: }
160: }
161: }
|