View Javadoc

1   /**
2    *
3    *  Licensed to the Apache Software Foundation (ASF) under one or more
4    *  contributor license agreements.  See the NOTICE file distributed with
5    *  this work for additional information regarding copyright ownership.
6    *  The ASF licenses this file to You under the Apache License, Version 2.0
7    *  (the "License"); you may not use this file except in compliance with
8    *  the License.  You may obtain a copy of the License at
9    *
10   *     http://www.apache.org/licenses/LICENSE-2.0
11   *
12   *  Unless required by applicable law or agreed to in writing, software
13   *  distributed under the License is distributed on an "AS IS" BASIS,
14   *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15   *  See the License for the specific language governing permissions and
16   *  limitations under the License.
17   */
18  
19  package org.apache.geronimo.util.jce.provider;
20  
21  import java.io.ByteArrayInputStream;
22  import java.io.IOException;
23  import java.io.InputStream;
24  import java.security.InvalidKeyException;
25  import java.security.Key;
26  import java.security.KeyFactorySpi;
27  import java.security.PrivateKey;
28  import java.security.PublicKey;
29  import java.security.interfaces.DSAPrivateKey;
30  import java.security.interfaces.DSAPublicKey;
31  import java.security.interfaces.RSAPrivateCrtKey;
32  import java.security.interfaces.RSAPrivateKey;
33  import java.security.interfaces.RSAPublicKey;
34  import java.security.spec.DSAPrivateKeySpec;
35  import java.security.spec.DSAPublicKeySpec;
36  import java.security.spec.InvalidKeySpecException;
37  import java.security.spec.KeySpec;
38  import java.security.spec.PKCS8EncodedKeySpec;
39  import java.security.spec.RSAPrivateCrtKeySpec;
40  import java.security.spec.RSAPrivateKeySpec;
41  import java.security.spec.RSAPublicKeySpec;
42  import java.security.spec.X509EncodedKeySpec;
43  
44  import javax.crypto.interfaces.DHPrivateKey;
45  import javax.crypto.interfaces.DHPublicKey;
46  import javax.crypto.spec.DHPrivateKeySpec;
47  import javax.crypto.spec.DHPublicKeySpec;
48  
49  import org.apache.geronimo.util.asn1.ASN1InputStream;
50  import org.apache.geronimo.util.asn1.ASN1Sequence;
51  import org.apache.geronimo.util.asn1.cryptopro.CryptoProObjectIdentifiers;
52  import org.apache.geronimo.util.asn1.oiw.OIWObjectIdentifiers;
53  import org.apache.geronimo.util.asn1.pkcs.PKCSObjectIdentifiers;
54  import org.apache.geronimo.util.asn1.pkcs.PrivateKeyInfo;
55  import org.apache.geronimo.util.asn1.pkcs.RSAPrivateKeyStructure;
56  import org.apache.geronimo.util.asn1.x509.AlgorithmIdentifier;
57  import org.apache.geronimo.util.asn1.x509.SubjectPublicKeyInfo;
58  import org.apache.geronimo.util.asn1.x509.X509ObjectIdentifiers;
59  import org.apache.geronimo.util.asn1.x9.X9ObjectIdentifiers;
60  import org.apache.geronimo.util.jce.provider.JCEDHPrivateKey;
61  import org.apache.geronimo.util.jce.provider.JCEDHPublicKey;
62  
63  public abstract class JDKKeyFactory
64      extends KeyFactorySpi
65  {
66      public JDKKeyFactory()
67      {
68      }
69  
70      protected KeySpec engineGetKeySpec(
71          Key    key,
72          Class    spec)
73      throws InvalidKeySpecException
74      {
75         if (spec.isAssignableFrom(PKCS8EncodedKeySpec.class) && key.getFormat().equals("PKCS#8"))
76         {
77                 return new PKCS8EncodedKeySpec(key.getEncoded());
78         }
79         else if (spec.isAssignableFrom(X509EncodedKeySpec.class) && key.getFormat().equals("X.509"))
80         {
81                 return new X509EncodedKeySpec(key.getEncoded());
82         }
83         else if (spec.isAssignableFrom(RSAPublicKeySpec.class) && key instanceof RSAPublicKey)
84         {
85              RSAPublicKey    k = (RSAPublicKey)key;
86  
87              return new RSAPublicKeySpec(k.getModulus(), k.getPublicExponent());
88         }
89         else if (spec.isAssignableFrom(RSAPrivateKeySpec.class) && key instanceof RSAPrivateKey)
90         {
91              RSAPrivateKey    k = (RSAPrivateKey)key;
92  
93              return new RSAPrivateKeySpec(k.getModulus(), k.getPrivateExponent());
94         }
95         else if (spec.isAssignableFrom(RSAPrivateCrtKeySpec.class) && key instanceof RSAPrivateCrtKey)
96         {
97              RSAPrivateCrtKey    k = (RSAPrivateCrtKey)key;
98  
99              return new RSAPrivateCrtKeySpec(
100                             k.getModulus(), k.getPublicExponent(),
101                             k.getPrivateExponent(),
102                             k.getPrimeP(), k.getPrimeQ(),
103                             k.getPrimeExponentP(), k.getPrimeExponentQ(),
104                             k.getCrtCoefficient());
105        }
106        else if (spec.isAssignableFrom(DHPrivateKeySpec.class) && key instanceof DHPrivateKey)
107        {
108            DHPrivateKey k = (DHPrivateKey)key;
109 
110            return new DHPrivateKeySpec(k.getX(), k.getParams().getP(), k.getParams().getG());
111        }
112        else if (spec.isAssignableFrom(DHPublicKeySpec.class) && key instanceof DHPublicKey)
113        {
114            DHPublicKey k = (DHPublicKey)key;
115 
116            return new DHPublicKeySpec(k.getY(), k.getParams().getP(), k.getParams().getG());
117        }
118 
119         throw new RuntimeException("not implemented yet " + key + " " + spec);
120     }
121 
122     protected Key engineTranslateKey(
123         Key    key)
124         throws InvalidKeyException
125     {
126         if (key instanceof RSAPublicKey)
127         {
128             return new JCERSAPublicKey((RSAPublicKey)key);
129         }
130         else if (key instanceof RSAPrivateCrtKey)
131         {
132             return new JCERSAPrivateCrtKey((RSAPrivateCrtKey)key);
133         }
134         else if (key instanceof RSAPrivateKey)
135         {
136             return new JCERSAPrivateKey((RSAPrivateKey)key);
137         }
138         else if (key instanceof DHPublicKey)
139         {
140             return new JCEDHPublicKey((DHPublicKey)key);
141         }
142         else if (key instanceof DHPrivateKey)
143         {
144             return new JCEDHPrivateKey((DHPrivateKey)key);
145         }
146         else if (key instanceof DSAPublicKey)
147         {
148             return new JDKDSAPublicKey((DSAPublicKey)key);
149         }
150         else if (key instanceof DSAPrivateKey)
151         {
152             return new JDKDSAPrivateKey((DSAPrivateKey)key);
153         }
154         throw new InvalidKeyException("key type unknown");
155     }
156 
157     /**
158      * create a public key from the given DER encoded input stream.
159      */
160     static PublicKey createPublicKeyFromDERStream(
161         InputStream         in)
162         throws IOException
163     {
164         return createPublicKeyFromPublicKeyInfo(
165                 new SubjectPublicKeyInfo((ASN1Sequence)(new ASN1InputStream(in).readObject())));
166     }
167 
168     /**
169      * create a public key from the given public key info object.
170      */
171     static PublicKey createPublicKeyFromPublicKeyInfo(
172         SubjectPublicKeyInfo         info)
173     {
174         AlgorithmIdentifier     algId = info.getAlgorithmId();
175 
176         if (algId.getObjectId().equals(PKCSObjectIdentifiers.rsaEncryption)
177             || algId.getObjectId().equals(X509ObjectIdentifiers.id_ea_rsa))
178         {
179               return new JCERSAPublicKey(info);
180         }
181         else if (algId.getObjectId().equals(PKCSObjectIdentifiers.dhKeyAgreement))
182         {
183               return new JCEDHPublicKey(info);
184         }
185         else if (algId.getObjectId().equals(X9ObjectIdentifiers.dhpublicnumber))
186         {
187               return new JCEDHPublicKey(info);
188         }
189         else if (algId.getObjectId().equals(X9ObjectIdentifiers.id_dsa))
190         {
191               return new JDKDSAPublicKey(info);
192         }
193         else if (algId.getObjectId().equals(OIWObjectIdentifiers.dsaWithSHA1))
194         {
195               return new JDKDSAPublicKey(info);
196         }
197         else
198         {
199             throw new RuntimeException("algorithm identifier in key not recognised");
200         }
201     }
202 
203     /**
204      * create a private key from the given DER encoded input stream.
205      */
206     static PrivateKey createPrivateKeyFromDERStream(
207         InputStream         in)
208         throws IOException
209     {
210         return createPrivateKeyFromPrivateKeyInfo(
211                 new PrivateKeyInfo((ASN1Sequence)(new ASN1InputStream(in).readObject())));
212     }
213 
214     /**
215      * create a private key from the given public key info object.
216      */
217     static PrivateKey createPrivateKeyFromPrivateKeyInfo(
218         PrivateKeyInfo      info)
219     {
220         AlgorithmIdentifier     algId = info.getAlgorithmId();
221 
222         if (algId.getObjectId().equals(PKCSObjectIdentifiers.rsaEncryption))
223         {
224               return new JCERSAPrivateCrtKey(info);
225         }
226         else if (algId.getObjectId().equals(PKCSObjectIdentifiers.dhKeyAgreement))
227         {
228               return new JCEDHPrivateKey(info);
229         }
230         else if (algId.getObjectId().equals(X9ObjectIdentifiers.id_dsa))
231         {
232               return new JDKDSAPrivateKey(info);
233         }
234         else
235         {
236             throw new RuntimeException("algorithm identifier in key not recognised");
237         }
238     }
239 
240     public static class RSA
241         extends JDKKeyFactory
242     {
243         public RSA()
244         {
245         }
246 
247         protected PrivateKey engineGeneratePrivate(
248             KeySpec    keySpec)
249             throws InvalidKeySpecException
250         {
251             if (keySpec instanceof PKCS8EncodedKeySpec)
252             {
253                 try
254                 {
255                     return JDKKeyFactory.createPrivateKeyFromDERStream(
256                                 new ByteArrayInputStream(((PKCS8EncodedKeySpec)keySpec).getEncoded()));
257                 }
258                 catch (Exception e)
259                 {
260                     //
261                     // in case it's just a RSAPrivateKey object...
262                     //
263                     try
264                     {
265                         return new JCERSAPrivateCrtKey(
266                             new RSAPrivateKeyStructure(
267                                 (ASN1Sequence)new ASN1InputStream(new ByteArrayInputStream(((PKCS8EncodedKeySpec)keySpec).getEncoded())).readObject()));
268                     }
269                     catch (Exception ex)
270                     {
271                         throw new InvalidKeySpecException(ex.toString());
272                     }
273                 }
274             }
275             else if (keySpec instanceof RSAPrivateCrtKeySpec)
276             {
277                 return new JCERSAPrivateCrtKey((RSAPrivateCrtKeySpec)keySpec);
278             }
279             else if (keySpec instanceof RSAPrivateKeySpec)
280             {
281                 return new JCERSAPrivateKey((RSAPrivateKeySpec)keySpec);
282             }
283 
284             throw new InvalidKeySpecException("Unknown KeySpec type.");
285         }
286 
287         protected PublicKey engineGeneratePublic(
288             KeySpec    keySpec)
289             throws InvalidKeySpecException
290         {
291             if (keySpec instanceof X509EncodedKeySpec)
292             {
293                 try
294                 {
295                     return JDKKeyFactory.createPublicKeyFromDERStream(
296                                 new ByteArrayInputStream(((X509EncodedKeySpec)keySpec).getEncoded()));
297                 }
298                 catch (Exception e)
299                 {
300                     throw new InvalidKeySpecException(e.toString());
301                 }
302             }
303             else if (keySpec instanceof RSAPublicKeySpec)
304             {
305                 return new JCERSAPublicKey((RSAPublicKeySpec)keySpec);
306             }
307 
308             throw new InvalidKeySpecException("Unknown KeySpec type.");
309         }
310     }
311 
312     public static class DH
313         extends JDKKeyFactory
314     {
315         public DH()
316         {
317         }
318 
319         protected PrivateKey engineGeneratePrivate(
320             KeySpec    keySpec)
321             throws InvalidKeySpecException
322         {
323             if (keySpec instanceof PKCS8EncodedKeySpec)
324             {
325                 try
326                 {
327                     return JDKKeyFactory.createPrivateKeyFromDERStream(
328                                 new ByteArrayInputStream(((PKCS8EncodedKeySpec)keySpec).getEncoded()));
329                 }
330                 catch (Exception e)
331                 {
332                     throw new InvalidKeySpecException(e.toString());
333                 }
334             }
335             else if (keySpec instanceof DHPrivateKeySpec)
336             {
337                 return new JCEDHPrivateKey((DHPrivateKeySpec)keySpec);
338             }
339 
340             throw new InvalidKeySpecException("Unknown KeySpec type.");
341         }
342 
343         protected PublicKey engineGeneratePublic(
344             KeySpec    keySpec)
345             throws InvalidKeySpecException
346         {
347             if (keySpec instanceof X509EncodedKeySpec)
348             {
349                 try
350                 {
351                     return JDKKeyFactory.createPublicKeyFromDERStream(
352                                 new ByteArrayInputStream(((X509EncodedKeySpec)keySpec).getEncoded()));
353                 }
354                 catch (Exception e)
355                 {
356                     throw new InvalidKeySpecException(e.toString());
357                 }
358             }
359             else if (keySpec instanceof DHPublicKeySpec)
360             {
361                 return new JCEDHPublicKey((DHPublicKeySpec)keySpec);
362             }
363 
364             throw new InvalidKeySpecException("Unknown KeySpec type.");
365         }
366     }
367 
368     public static class DSA
369         extends JDKKeyFactory
370     {
371         public DSA()
372         {
373         }
374 
375         protected PrivateKey engineGeneratePrivate(
376             KeySpec    keySpec)
377             throws InvalidKeySpecException
378         {
379             if (keySpec instanceof PKCS8EncodedKeySpec)
380             {
381                 try
382                 {
383                     return JDKKeyFactory.createPrivateKeyFromDERStream(
384                                 new ByteArrayInputStream(((PKCS8EncodedKeySpec)keySpec).getEncoded()));
385                 }
386                 catch (Exception e)
387                 {
388                     throw new InvalidKeySpecException(e.toString());
389                 }
390             }
391             else if (keySpec instanceof DSAPrivateKeySpec)
392             {
393                 return new JDKDSAPrivateKey((DSAPrivateKeySpec)keySpec);
394             }
395 
396             throw new InvalidKeySpecException("Unknown KeySpec type.");
397         }
398 
399         protected PublicKey engineGeneratePublic(
400             KeySpec    keySpec)
401             throws InvalidKeySpecException
402         {
403             if (keySpec instanceof X509EncodedKeySpec)
404             {
405                 try
406                 {
407                     return JDKKeyFactory.createPublicKeyFromDERStream(
408                                 new ByteArrayInputStream(((X509EncodedKeySpec)keySpec).getEncoded()));
409                 }
410                 catch (Exception e)
411                 {
412                     throw new InvalidKeySpecException(e.toString());
413                 }
414             }
415             else if (keySpec instanceof DSAPublicKeySpec)
416             {
417                 return new JDKDSAPublicKey((DSAPublicKeySpec)keySpec);
418             }
419 
420             throw new InvalidKeySpecException("Unknown KeySpec type.");
421         }
422     }
423 
424 
425     public static class EC
426         extends JDKKeyFactory
427     {
428         String  algorithm;
429 
430         public EC()
431         {
432             this("EC");
433         }
434 
435         public EC(
436             String  algorithm)
437         {
438             this.algorithm = algorithm;
439         }
440 
441         protected PrivateKey engineGeneratePrivate(
442             KeySpec    keySpec)
443             throws InvalidKeySpecException
444         {
445             if (keySpec instanceof PKCS8EncodedKeySpec)
446             {
447                 try
448                 {
449                     return JDKKeyFactory.createPrivateKeyFromDERStream(
450                                 new ByteArrayInputStream(((PKCS8EncodedKeySpec)keySpec).getEncoded()));
451                 }
452                 catch (Exception e)
453                 {
454                     throw new InvalidKeySpecException(e.toString());
455                 }
456             }
457 
458             throw new InvalidKeySpecException("Unknown KeySpec type.");
459         }
460 
461         protected PublicKey engineGeneratePublic(
462             KeySpec    keySpec)
463             throws InvalidKeySpecException
464         {
465             if (keySpec instanceof X509EncodedKeySpec)
466             {
467                 try
468                 {
469                     return JDKKeyFactory.createPublicKeyFromDERStream(
470                                 new ByteArrayInputStream(((X509EncodedKeySpec)keySpec).getEncoded()));
471                 }
472                 catch (Exception e)
473                 {
474                     throw new InvalidKeySpecException(e.toString());
475                 }
476             }
477 
478             throw new InvalidKeySpecException("Unknown KeySpec type.");
479         }
480     }
481 }