001: package org.bouncycastle.crypto.util;
002:
003: import org.bouncycastle.asn1.ASN1InputStream;
004: import org.bouncycastle.asn1.ASN1Object;
005: import org.bouncycastle.asn1.ASN1OctetString;
006: import org.bouncycastle.asn1.ASN1Sequence;
007: import org.bouncycastle.asn1.DERBitString;
008: import org.bouncycastle.asn1.DERInteger;
009: import org.bouncycastle.asn1.DERObject;
010: import org.bouncycastle.asn1.DERObjectIdentifier;
011: import org.bouncycastle.asn1.DEROctetString;
012: import org.bouncycastle.asn1.nist.NISTNamedCurves;
013: import org.bouncycastle.asn1.oiw.ElGamalParameter;
014: import org.bouncycastle.asn1.oiw.OIWObjectIdentifiers;
015: import org.bouncycastle.asn1.pkcs.DHParameter;
016: import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers;
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.x509.RSAPublicKeyStructure;
022: import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo;
023: import org.bouncycastle.asn1.x509.X509ObjectIdentifiers;
024: import org.bouncycastle.asn1.x9.X962NamedCurves;
025: import org.bouncycastle.asn1.x9.X962Parameters;
026: import org.bouncycastle.asn1.x9.X9ECParameters;
027: import org.bouncycastle.asn1.x9.X9ECPoint;
028: import org.bouncycastle.asn1.x9.X9ObjectIdentifiers;
029: import org.bouncycastle.crypto.params.AsymmetricKeyParameter;
030: import org.bouncycastle.crypto.params.DHParameters;
031: import org.bouncycastle.crypto.params.DHPublicKeyParameters;
032: import org.bouncycastle.crypto.params.DSAParameters;
033: import org.bouncycastle.crypto.params.DSAPublicKeyParameters;
034: import org.bouncycastle.crypto.params.ECDomainParameters;
035: import org.bouncycastle.crypto.params.ECPublicKeyParameters;
036: import org.bouncycastle.crypto.params.ElGamalParameters;
037: import org.bouncycastle.crypto.params.ElGamalPublicKeyParameters;
038: import org.bouncycastle.crypto.params.RSAKeyParameters;
039:
040: import java.io.IOException;
041: import java.io.InputStream;
042:
043: /**
044: * Factory to create asymmetric public key parameters for asymmetric ciphers
045: * from range of ASN.1 encoded SubjectPublicKeyInfo objects.
046: */
047: public class PublicKeyFactory {
048: /**
049: * Create a public key from a SubjectPublicKeyInfo encoding
050: *
051: * @param keyInfoData the SubjectPublicKeyInfo encoding
052: * @return the appropriate key parameter
053: * @throws IOException on an error decoding the key
054: */
055: public static AsymmetricKeyParameter createKey(byte[] keyInfoData)
056: throws IOException {
057: return createKey(SubjectPublicKeyInfo.getInstance(ASN1Object
058: .fromByteArray(keyInfoData)));
059: }
060:
061: /**
062: * Create a public key from a SubjectPublicKeyInfo encoding read from a stream
063: *
064: * @param inStr the stream to read the SubjectPublicKeyInfo encoding from
065: * @return the appropriate key parameter
066: * @throws IOException on an error decoding the key
067: */
068: public static AsymmetricKeyParameter createKey(InputStream inStr)
069: throws IOException {
070: return createKey(SubjectPublicKeyInfo
071: .getInstance(new ASN1InputStream(inStr).readObject()));
072: }
073:
074: /**
075: * Create a public key from the passed in SubjectPublicKeyInfo
076: *
077: * @param keyInfo the SubjectPublicKeyInfo containing the key data
078: * @return the appropriate key parameter
079: * @throws IOException on an error decoding the key
080: */
081: public static AsymmetricKeyParameter createKey(
082: SubjectPublicKeyInfo keyInfo) throws IOException {
083: AlgorithmIdentifier algId = keyInfo.getAlgorithmId();
084:
085: if (algId.getObjectId().equals(
086: PKCSObjectIdentifiers.rsaEncryption)
087: || algId.getObjectId().equals(
088: X509ObjectIdentifiers.id_ea_rsa)) {
089: RSAPublicKeyStructure pubKey = new RSAPublicKeyStructure(
090: (ASN1Sequence) keyInfo.getPublicKey());
091:
092: return new RSAKeyParameters(false, pubKey.getModulus(),
093: pubKey.getPublicExponent());
094: } else if (algId.getObjectId().equals(
095: PKCSObjectIdentifiers.dhKeyAgreement)
096: || algId.getObjectId().equals(
097: X9ObjectIdentifiers.dhpublicnumber)) {
098: DHParameter params = new DHParameter((ASN1Sequence) keyInfo
099: .getAlgorithmId().getParameters());
100: DERInteger derY = (DERInteger) keyInfo.getPublicKey();
101:
102: return new DHPublicKeyParameters(derY.getValue(),
103: new DHParameters(params.getP(), params.getG()));
104: } else if (algId.getObjectId().equals(
105: OIWObjectIdentifiers.elGamalAlgorithm)) {
106: ElGamalParameter params = new ElGamalParameter(
107: (ASN1Sequence) keyInfo.getAlgorithmId()
108: .getParameters());
109: DERInteger derY = (DERInteger) keyInfo.getPublicKey();
110:
111: return new ElGamalPublicKeyParameters(derY.getValue(),
112: new ElGamalParameters(params.getP(), params.getG()));
113: } else if (algId.getObjectId().equals(
114: X9ObjectIdentifiers.id_dsa)
115: || algId.getObjectId().equals(
116: OIWObjectIdentifiers.dsaWithSHA1)) {
117: DSAParameter params = new DSAParameter(
118: (ASN1Sequence) keyInfo.getAlgorithmId()
119: .getParameters());
120: DERInteger derY = (DERInteger) keyInfo.getPublicKey();
121:
122: return new DSAPublicKeyParameters(derY.getValue(),
123: new DSAParameters(params.getP(), params.getQ(),
124: params.getG()));
125: } else if (algId.getObjectId().equals(
126: X9ObjectIdentifiers.id_ecPublicKey)) {
127: X962Parameters params = new X962Parameters(
128: (DERObject) keyInfo.getAlgorithmId()
129: .getParameters());
130: ECDomainParameters dParams = null;
131:
132: if (params.isNamedCurve()) {
133: DERObjectIdentifier oid = (DERObjectIdentifier) params
134: .getParameters();
135: X9ECParameters ecP = X962NamedCurves.getByOID(oid);
136:
137: if (ecP == null) {
138: ecP = SECNamedCurves.getByOID(oid);
139:
140: if (ecP == null) {
141: ecP = NISTNamedCurves.getByOID(oid);
142:
143: if (ecP == null) {
144: ecP = TeleTrusTNamedCurves.getByOID(oid);
145: }
146: }
147: }
148:
149: dParams = new ECDomainParameters(ecP.getCurve(), ecP
150: .getG(), ecP.getN(), ecP.getH(), ecP.getSeed());
151: } else {
152: X9ECParameters ecP = new X9ECParameters(
153: (ASN1Sequence) params.getParameters());
154: dParams = new ECDomainParameters(ecP.getCurve(), ecP
155: .getG(), ecP.getN(), ecP.getH(), ecP.getSeed());
156: }
157:
158: DERBitString bits = keyInfo.getPublicKeyData();
159: byte[] data = bits.getBytes();
160: ASN1OctetString key = new DEROctetString(data);
161:
162: X9ECPoint derQ = new X9ECPoint(dParams.getCurve(), key);
163:
164: return new ECPublicKeyParameters(derQ.getPoint(), dParams);
165: } else {
166: throw new RuntimeException(
167: "algorithm identifier in key not recognised");
168: }
169: }
170: }
|