1:
37:
38:
39: package ;
40:
41: import ;
42: import ;
43: import ;
44: import ;
45: import ;
46: import ;
47: import ;
48: import ;
49: import ;
50:
51: import ;
52: import ;
53: import ;
54: import ;
55: import ;
56: import ;
57: import ;
58: import ;
59:
60:
64: public class RSAKeyPairPKCS8Codec
65: implements IKeyPairCodec
66: {
67: private static final Logger log = Logger.getLogger(RSAKeyPairPKCS8Codec.class.getName());
68: private static final OID RSA_ALG_OID = new OID(Registry.RSA_OID_STRING);
69:
70:
71:
72: public int getFormatID()
73: {
74: return PKCS8_FORMAT;
75: }
76:
77:
80: public byte[] encodePublicKey(PublicKey key)
81: {
82: throw new InvalidParameterException("Wrong format for public keys");
83: }
84:
85:
125: public byte[] encodePrivateKey(PrivateKey key)
126: {
127: if (Configuration.DEBUG)
128: log.entering(this.getClass().getName(), "encodePrivateKey()", key);
129: if (! (key instanceof GnuRSAPrivateKey))
130: throw new InvalidParameterException("Wrong key type");
131:
132: GnuRSAPrivateKey pk = (GnuRSAPrivateKey) key;
133: BigInteger n = pk.getN();
134: BigInteger e = pk.getE();
135: BigInteger d = pk.getPrivateExponent();
136: BigInteger p = pk.getPrimeP();
137: BigInteger q = pk.getPrimeQ();
138: BigInteger dP = pk.getPrimeExponentP();
139: BigInteger dQ = pk.getPrimeExponentQ();
140: BigInteger qInv = pk.getCrtCoefficient();
141:
142: DERValue derVersion = new DERValue(DER.INTEGER, BigInteger.ZERO);
143:
144: DERValue derOID = new DERValue(DER.OBJECT_IDENTIFIER, RSA_ALG_OID);
145:
146: ArrayList algorithmID = new ArrayList(2);
147: algorithmID.add(derOID);
148: algorithmID.add(new DERValue(DER.NULL, null));
149: DERValue derAlgorithmID = new DERValue(DER.CONSTRUCTED | DER.SEQUENCE,
150: algorithmID);
151:
152: DERValue derRSAVersion = new DERValue(DER.INTEGER, BigInteger.ZERO);
153: DERValue derN = new DERValue(DER.INTEGER, n);
154: DERValue derE = new DERValue(DER.INTEGER, e);
155: DERValue derD = new DERValue(DER.INTEGER, d);
156: DERValue derP = new DERValue(DER.INTEGER, p);
157: DERValue derQ = new DERValue(DER.INTEGER, q);
158: DERValue derDP = new DERValue(DER.INTEGER, dP);
159: DERValue derDQ = new DERValue(DER.INTEGER, dQ);
160: DERValue derQInv = new DERValue(DER.INTEGER, qInv);
161:
162: ArrayList rsaPrivateKey = new ArrayList();
163: rsaPrivateKey.add(derRSAVersion);
164: rsaPrivateKey.add(derN);
165: rsaPrivateKey.add(derE);
166: rsaPrivateKey.add(derD);
167: rsaPrivateKey.add(derP);
168: rsaPrivateKey.add(derQ);
169: rsaPrivateKey.add(derDP);
170: rsaPrivateKey.add(derDQ);
171: rsaPrivateKey.add(derQInv);
172: DERValue derRSAPrivateKey = new DERValue(DER.CONSTRUCTED | DER.SEQUENCE,
173: rsaPrivateKey);
174: byte[] pkBytes = derRSAPrivateKey.getEncoded();
175: DERValue derPrivateKey = new DERValue(DER.OCTET_STRING, pkBytes);
176:
177: ArrayList pki = new ArrayList(3);
178: pki.add(derVersion);
179: pki.add(derAlgorithmID);
180: pki.add(derPrivateKey);
181: DERValue derPKI = new DERValue(DER.CONSTRUCTED | DER.SEQUENCE, pki);
182:
183: byte[] result;
184: ByteArrayOutputStream baos = new ByteArrayOutputStream();
185: try
186: {
187: DERWriter.write(baos, derPKI);
188: result = baos.toByteArray();
189: }
190: catch (IOException x)
191: {
192: InvalidParameterException y = new InvalidParameterException();
193: y.initCause(x);
194: throw y;
195: }
196: if (Configuration.DEBUG)
197: log.exiting(this.getClass().getName(), "encodePrivateKey()", result);
198: return result;
199: }
200:
201:
204: public PublicKey decodePublicKey(byte[] input)
205: {
206: throw new InvalidParameterException("Wrong format for public keys");
207: }
208:
209:
217: public PrivateKey decodePrivateKey(byte[] input)
218: {
219: if (Configuration.DEBUG)
220: log.entering(this.getClass().getName(), "decodePrivateKey()", input);
221: if (input == null)
222: throw new InvalidParameterException("Input bytes MUST NOT be null");
223:
224: BigInteger version, n, e, d, p, q, dP, dQ, qInv;
225: DERReader der = new DERReader(input);
226: try
227: {
228: DERValue derPKI = der.read();
229: DerUtil.checkIsConstructed(derPKI, "Wrong PrivateKeyInfo field");
230:
231: DERValue derVersion = der.read();
232: DerUtil.checkIsBigInteger(derVersion, "Wrong Version field");
233: version = (BigInteger) derVersion.getValue();
234: if (version.compareTo(BigInteger.ZERO) != 0)
235: throw new InvalidParameterException("Unexpected Version: " + version);
236:
237: DERValue derAlgoritmID = der.read();
238: DerUtil.checkIsConstructed(derAlgoritmID, "Wrong AlgorithmIdentifier field");
239:
240: DERValue derOID = der.read();
241: OID algOID = (OID) derOID.getValue();
242: if (! algOID.equals(RSA_ALG_OID))
243: throw new InvalidParameterException("Unexpected OID: " + algOID);
244:
245:
246: DERValue val = der.read();
247: if (val.getTag() == DER.NULL)
248: val = der.read();
249:
250: byte[] pkBytes = (byte[]) val.getValue();
251: der = new DERReader(pkBytes);
252: DERValue derRSAPrivateKey = der.read();
253: DerUtil.checkIsConstructed(derRSAPrivateKey, "Wrong RSAPrivateKey field");
254:
255: val = der.read();
256: DerUtil.checkIsBigInteger(val, "Wrong RSAPrivateKey Version field");
257: version = (BigInteger) val.getValue();
258: if (version.compareTo(BigInteger.ZERO) != 0)
259: throw new InvalidParameterException("Unexpected RSAPrivateKey Version: "
260: + version);
261:
262: val = der.read();
263: DerUtil.checkIsBigInteger(val, "Wrong modulus field");
264: n = (BigInteger) val.getValue();
265: val = der.read();
266: DerUtil.checkIsBigInteger(val, "Wrong publicExponent field");
267: e = (BigInteger) val.getValue();
268: val = der.read();
269: DerUtil.checkIsBigInteger(val, "Wrong privateExponent field");
270: d = (BigInteger) val.getValue();
271: val = der.read();
272: DerUtil.checkIsBigInteger(val, "Wrong prime1 field");
273: p = (BigInteger) val.getValue();
274: val = der.read();
275: DerUtil.checkIsBigInteger(val, "Wrong prime2 field");
276: q = (BigInteger) val.getValue();
277: val = der.read();
278: DerUtil.checkIsBigInteger(val, "Wrong exponent1 field");
279: dP = (BigInteger) val.getValue();
280: val = der.read();
281: DerUtil.checkIsBigInteger(val, "Wrong exponent2 field");
282: dQ = (BigInteger) val.getValue();
283: val = der.read();
284: DerUtil.checkIsBigInteger(val, "Wrong coefficient field");
285: qInv = (BigInteger) val.getValue();
286: }
287: catch (IOException x)
288: {
289: InvalidParameterException y = new InvalidParameterException();
290: y.initCause(x);
291: throw y;
292: }
293: PrivateKey result = new GnuRSAPrivateKey(Registry.PKCS8_ENCODING_ID,
294: n, e, d, p, q, dP, dQ, qInv);
295: if (Configuration.DEBUG)
296: log.exiting(this.getClass().getName(), "decodePrivateKey()", result);
297: return result;
298: }
299: }