1package org.bouncycastle.jce.provider;
2
3import java.lang.reflect.Constructor;
4import java.security.InvalidKeyException;
5import java.security.spec.InvalidKeySpecException;
6import java.security.spec.KeySpec;
7
8import javax.crypto.SecretKey;
9import javax.crypto.SecretKeyFactorySpi;
10import javax.crypto.spec.DESKeySpec;
11import javax.crypto.spec.DESedeKeySpec;
12import javax.crypto.spec.PBEKeySpec;
13import javax.crypto.spec.SecretKeySpec;
14
15import org.bouncycastle.asn1.DERObjectIdentifier;
16import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers;
17import org.bouncycastle.crypto.CipherParameters;
18import org.bouncycastle.crypto.params.DESParameters;
19import org.bouncycastle.crypto.params.KeyParameter;
20import org.bouncycastle.crypto.params.ParametersWithIV;
21
22public class JCESecretKeyFactory
23    extends SecretKeyFactorySpi
24    implements PBE
25{
26    protected String                algName;
27    protected DERObjectIdentifier   algOid;
28
29    protected JCESecretKeyFactory(
30        String               algName,
31        DERObjectIdentifier  algOid)
32    {
33        this.algName = algName;
34        this.algOid = algOid;
35    }
36
37    protected SecretKey engineGenerateSecret(
38        KeySpec keySpec)
39    throws InvalidKeySpecException
40    {
41        if (keySpec instanceof SecretKeySpec)
42        {
43            return (SecretKey)keySpec;
44        }
45
46        throw new InvalidKeySpecException("Invalid KeySpec");
47    }
48
49    protected KeySpec engineGetKeySpec(
50        SecretKey key,
51        Class keySpec)
52    throws InvalidKeySpecException
53    {
54        if (keySpec == null)
55        {
56            throw new InvalidKeySpecException("keySpec parameter is null");
57        }
58        if (key == null)
59        {
60            throw new InvalidKeySpecException("key parameter is null");
61        }
62
63        if (SecretKeySpec.class.isAssignableFrom(keySpec))
64        {
65            return new SecretKeySpec(key.getEncoded(), algName);
66        }
67
68        try
69        {
70            Class[] parameters = { byte[].class };
71
72            Constructor c = keySpec.getConstructor(parameters);
73            Object[]    p = new Object[1];
74
75            p[0] = key.getEncoded();
76
77            return (KeySpec)c.newInstance(p);
78        }
79        catch (Exception e)
80        {
81            throw new InvalidKeySpecException(e.toString());
82        }
83    }
84
85    protected SecretKey engineTranslateKey(
86        SecretKey key)
87    throws InvalidKeyException
88    {
89        if (key == null)
90        {
91            throw new InvalidKeyException("key parameter is null");
92        }
93
94        if (!key.getAlgorithm().equalsIgnoreCase(algName))
95        {
96            throw new InvalidKeyException("Key not of type " + algName + ".");
97        }
98
99        return new SecretKeySpec(key.getEncoded(), algName);
100    }
101
102    /*
103     * classes that inherit from us
104     */
105
106    static public class PBEKeyFactory
107        extends JCESecretKeyFactory
108    {
109        private boolean forCipher;
110        private int     scheme;
111        private int     digest;
112        private int     keySize;
113        private int     ivSize;
114
115        public PBEKeyFactory(
116            String              algorithm,
117            DERObjectIdentifier oid,
118            boolean             forCipher,
119            int                 scheme,
120            int                 digest,
121            int                 keySize,
122            int                 ivSize)
123        {
124            super(algorithm, oid);
125
126            this.forCipher = forCipher;
127            this.scheme = scheme;
128            this.digest = digest;
129            this.keySize = keySize;
130            this.ivSize = ivSize;
131        }
132
133        protected SecretKey engineGenerateSecret(
134            KeySpec keySpec)
135            throws InvalidKeySpecException
136        {
137            if (keySpec instanceof PBEKeySpec)
138            {
139                PBEKeySpec          pbeSpec = (PBEKeySpec)keySpec;
140                CipherParameters    param;
141
142                if (pbeSpec.getSalt() == null)
143                {
144                    return new JCEPBEKey(this.algName, this.algOid, scheme, digest, keySize, ivSize, pbeSpec, null);
145                }
146
147                if (forCipher)
148                {
149                    param = Util.makePBEParameters(pbeSpec, scheme, digest, keySize, ivSize);
150                }
151                else
152                {
153                    param = Util.makePBEMacParameters(pbeSpec, scheme, digest, keySize);
154                }
155
156                return new JCEPBEKey(this.algName, this.algOid, scheme, digest, keySize, ivSize, pbeSpec, param);
157            }
158
159            throw new InvalidKeySpecException("Invalid KeySpec");
160        }
161    }
162
163    static public class DESPBEKeyFactory
164        extends JCESecretKeyFactory
165    {
166        private boolean forCipher;
167        private int     scheme;
168        private int     digest;
169        private int     keySize;
170        private int     ivSize;
171
172        public DESPBEKeyFactory(
173            String              algorithm,
174            DERObjectIdentifier oid,
175            boolean             forCipher,
176            int                 scheme,
177            int                 digest,
178            int                 keySize,
179            int                 ivSize)
180        {
181            super(algorithm, oid);
182
183            this.forCipher = forCipher;
184            this.scheme = scheme;
185            this.digest = digest;
186            this.keySize = keySize;
187            this.ivSize = ivSize;
188        }
189
190        protected SecretKey engineGenerateSecret(
191            KeySpec keySpec)
192        throws InvalidKeySpecException
193        {
194            if (keySpec instanceof PBEKeySpec)
195            {
196                PBEKeySpec pbeSpec = (PBEKeySpec)keySpec;
197                CipherParameters    param;
198
199                if (pbeSpec.getSalt() == null)
200                {
201                    return new JCEPBEKey(this.algName, this.algOid, scheme, digest, keySize, ivSize, pbeSpec, null);
202                }
203
204                if (forCipher)
205                {
206                    param = Util.makePBEParameters(pbeSpec, scheme, digest, keySize, ivSize);
207                }
208                else
209                {
210                    param = Util.makePBEMacParameters(pbeSpec, scheme, digest, keySize);
211                }
212
213                if (param instanceof ParametersWithIV)
214                {
215                    KeyParameter    kParam = (KeyParameter)((ParametersWithIV)param).getParameters();
216
217                    DESParameters.setOddParity(kParam.getKey());
218                }
219                else
220                {
221                    KeyParameter    kParam = (KeyParameter)param;
222
223                    DESParameters.setOddParity(kParam.getKey());
224                }
225
226                return new JCEPBEKey(this.algName, this.algOid, scheme, digest, keySize, ivSize, pbeSpec, param);
227            }
228
229            throw new InvalidKeySpecException("Invalid KeySpec");
230        }
231    }
232
233    static public class DES
234        extends JCESecretKeyFactory
235    {
236        public DES()
237        {
238            super("DES", null);
239        }
240
241        protected SecretKey engineGenerateSecret(
242            KeySpec keySpec)
243        throws InvalidKeySpecException
244        {
245            if (keySpec instanceof DESKeySpec)
246            {
247                DESKeySpec desKeySpec = (DESKeySpec)keySpec;
248                return new SecretKeySpec(desKeySpec.getKey(), "DES");
249            }
250
251            return super.engineGenerateSecret(keySpec);
252        }
253    }
254
255    static public class DESede
256        extends JCESecretKeyFactory
257    {
258        public DESede()
259        {
260            super("DESede", null);
261        }
262
263        protected KeySpec engineGetKeySpec(
264            SecretKey key,
265            Class keySpec)
266        throws InvalidKeySpecException
267        {
268            if (keySpec == null)
269            {
270                throw new InvalidKeySpecException("keySpec parameter is null");
271            }
272            if (key == null)
273            {
274                throw new InvalidKeySpecException("key parameter is null");
275            }
276
277            if (SecretKeySpec.class.isAssignableFrom(keySpec))
278            {
279                return new SecretKeySpec(key.getEncoded(), algName);
280            }
281            else if (DESedeKeySpec.class.isAssignableFrom(keySpec))
282            {
283                byte[]  bytes = key.getEncoded();
284
285                try
286                {
287                    if (bytes.length == 16)
288                    {
289                        byte[]  longKey = new byte[24];
290
291                        System.arraycopy(bytes, 0, longKey, 0, 16);
292                        System.arraycopy(bytes, 0, longKey, 16, 8);
293
294                        return new DESedeKeySpec(longKey);
295                    }
296                    else
297                    {
298                        return new DESedeKeySpec(bytes);
299                    }
300                }
301                catch (Exception e)
302                {
303                    throw new InvalidKeySpecException(e.toString());
304                }
305            }
306
307            throw new InvalidKeySpecException("Invalid KeySpec");
308        }
309
310        protected SecretKey engineGenerateSecret(
311            KeySpec keySpec)
312        throws InvalidKeySpecException
313        {
314            if (keySpec instanceof DESedeKeySpec)
315            {
316                DESedeKeySpec desKeySpec = (DESedeKeySpec)keySpec;
317                return new SecretKeySpec(desKeySpec.getKey(), "DESede");
318            }
319
320            return super.engineGenerateSecret(keySpec);
321        }
322    }
323
324   /**
325    * PBEWithMD5AndDES
326    */
327   static public class PBEWithMD5AndDES
328       extends DESPBEKeyFactory
329   {
330       public PBEWithMD5AndDES()
331       {
332           super("PBEwithMD5andDES", null, true, PKCS5S1, MD5, 64, 64);
333       }
334   }
335
336   /**
337    * PBEWithMD5AndRC2
338    */
339   static public class PBEWithMD5AndRC2
340       extends PBEKeyFactory
341   {
342       public PBEWithMD5AndRC2()
343       {
344           super("PBEwithMD5andRC2", null, true, PKCS5S1, MD5, 64, 64);
345       }
346   }
347
348   /**
349    * PBEWithSHA1AndDES
350    */
351   static public class PBEWithSHA1AndDES
352       extends PBEKeyFactory
353   {
354       public PBEWithSHA1AndDES()
355       {
356           super("PBEwithSHA1andDES", null, true, PKCS5S1, SHA1, 64, 64);
357       }
358   }
359
360   /**
361    * PBEWithSHA1AndRC2
362    */
363   static public class PBEWithSHA1AndRC2
364       extends PBEKeyFactory
365   {
366       public PBEWithSHA1AndRC2()
367       {
368           super("PBEwithSHA1andRC2", null, true, PKCS5S1, SHA1, 64, 64);
369       }
370   }
371
372   /**
373    * PBEWithSHAAnd3-KeyTripleDES-CBC
374    */
375   static public class PBEWithSHAAndDES3Key
376       extends PBEKeyFactory
377   {
378       public PBEWithSHAAndDES3Key()
379       {
380           super("PBEwithSHAandDES3Key-CBC", PKCSObjectIdentifiers.pbeWithSHAAnd3_KeyTripleDES_CBC, true, PKCS12, SHA1, 192, 64);
381       }
382   }
383
384   /**
385    * PBEWithSHAAnd2-KeyTripleDES-CBC
386    */
387   static public class PBEWithSHAAndDES2Key
388       extends PBEKeyFactory
389   {
390       public PBEWithSHAAndDES2Key()
391       {
392           super("PBEwithSHAandDES2Key-CBC", PKCSObjectIdentifiers.pbeWithSHAAnd2_KeyTripleDES_CBC, true, PKCS12, SHA1, 128, 64);
393       }
394   }
395// BEGIN android-removed
396//   /**
397//    * PBEWithSHAAnd128BitRC2-CBC
398//    */
399//   static public class PBEWithSHAAnd128BitRC2
400//       extends PBEKeyFactory
401//   {
402//       public PBEWithSHAAnd128BitRC2()
403//       {
404//           super("PBEwithSHAand128BitRC2-CBC", PKCSObjectIdentifiers.pbeWithSHAAnd128BitRC2_CBC, true, PKCS12, SHA1, 128, 64);
405//       }
406//   }
407// END android-removed
408
409   /**
410    * PBEWithSHAAnd40BitRC2-CBC
411    */
412   static public class PBEWithSHAAnd40BitRC2
413       extends PBEKeyFactory
414   {
415       public PBEWithSHAAnd40BitRC2()
416       {
417           super("PBEwithSHAand40BitRC2-CBC", PKCSObjectIdentifiers.pbewithSHAAnd40BitRC2_CBC, true, PKCS12, SHA1, 40, 64);
418       }
419   }
420
421// BEGIN android-removed
422//   /**
423//    * PBEWithSHAAndTwofish-CBC
424//    */
425//   static public class PBEWithSHAAndTwofish
426//       extends PBEKeyFactory
427//   {
428//       public PBEWithSHAAndTwofish()
429//       {
430//           super("PBEwithSHAandTwofish-CBC", null, true, PKCS12, SHA1, 256, 128);
431//       }
432//   }
433//
434//   /**
435//    * PBEWithSHAAndIDEA-CBC
436//    */
437//   static public class PBEWithSHAAndIDEA
438//       extends PBEKeyFactory
439//   {
440//       public PBEWithSHAAndIDEA()
441//       {
442//           super("PBEwithSHAandIDEA-CBC", null, true, PKCS12, SHA1, 128, 64);
443//       }
444//   }
445//
446//   /**
447//    * PBEWithSHAAnd128BitRC4
448//    */
449//   static public class PBEWithSHAAnd128BitRC4
450//       extends PBEKeyFactory
451//   {
452//       public PBEWithSHAAnd128BitRC4()
453//       {
454//           super("PBEWithSHAAnd128BitRC4", PKCSObjectIdentifiers.pbeWithSHAAnd128BitRC4, true, PKCS12, SHA1, 128, 0);
455//       }
456//   }
457//
458//   /**
459//    * PBEWithSHAAnd40BitRC4
460//    */
461//   static public class PBEWithSHAAnd40BitRC4
462//       extends PBEKeyFactory
463//   {
464//       public PBEWithSHAAnd40BitRC4()
465//       {
466//           super("PBEWithSHAAnd128BitRC4", PKCSObjectIdentifiers.pbeWithSHAAnd128BitRC4, true, PKCS12, SHA1, 40, 0);
467//       }
468//   }
469//
470//   /**
471//    * PBEWithHmacRIPEMD160
472//    */
473//   public static class PBEWithRIPEMD160
474//       extends PBEKeyFactory
475//   {
476//       public PBEWithRIPEMD160()
477//       {
478//           super("PBEwithHmacRIPEMD160", null, false, PKCS12, RIPEMD160, 160, 0);
479//       }
480//   }
481// END android-removed
482
483   /**
484    * PBEWithHmacSHA
485    */
486   public static class PBEWithSHA
487       extends PBEKeyFactory
488   {
489       public PBEWithSHA()
490       {
491           super("PBEwithHmacSHA", null, false, PKCS12, SHA1, 160, 0);
492       }
493   }
494
495// BEGIN android-removed
496//   /**
497//    * PBEWithHmacTiger
498//    */
499//   public static class PBEWithTiger
500//       extends PBEKeyFactory
501//   {
502//       public PBEWithTiger()
503//       {
504//           super("PBEwithHmacTiger", null, false, PKCS12, TIGER, 192, 0);
505//       }
506//   }
507// END android-removed
508
509   /**
510    * PBEWithSHA1And128BitAES-BC
511    */
512   static public class PBEWithSHAAnd128BitAESBC
513       extends PBEKeyFactory
514   {
515       public PBEWithSHAAnd128BitAESBC()
516       {
517           super("PBEWithSHA1And128BitAES-CBC-BC", null, true, PKCS12, SHA1, 128, 128);
518       }
519   }
520
521   /**
522    * PBEWithSHA1And192BitAES-BC
523    */
524   static public class PBEWithSHAAnd192BitAESBC
525       extends PBEKeyFactory
526   {
527       public PBEWithSHAAnd192BitAESBC()
528       {
529           super("PBEWithSHA1And192BitAES-CBC-BC", null, true, PKCS12, SHA1, 192, 128);
530       }
531   }
532
533   /**
534    * PBEWithSHA1And256BitAES-BC
535    */
536   static public class PBEWithSHAAnd256BitAESBC
537       extends PBEKeyFactory
538   {
539       public PBEWithSHAAnd256BitAESBC()
540       {
541           super("PBEWithSHA1And256BitAES-CBC-BC", null, true, PKCS12, SHA1, 256, 128);
542       }
543   }
544
545   /**
546    * PBEWithSHA256And128BitAES-BC
547    */
548   static public class PBEWithSHA256And128BitAESBC
549       extends PBEKeyFactory
550   {
551       public PBEWithSHA256And128BitAESBC()
552       {
553           super("PBEWithSHA256And128BitAES-CBC-BC", null, true, PKCS12, SHA256, 128, 128);
554       }
555   }
556
557   /**
558    * PBEWithSHA256And192BitAES-BC
559    */
560   static public class PBEWithSHA256And192BitAESBC
561       extends PBEKeyFactory
562   {
563       public PBEWithSHA256And192BitAESBC()
564       {
565           super("PBEWithSHA256And192BitAES-CBC-BC", null, true, PKCS12, SHA256, 192, 128);
566       }
567   }
568
569   /**
570    * PBEWithSHA256And256BitAES-BC
571    */
572   static public class PBEWithSHA256And256BitAESBC
573       extends PBEKeyFactory
574   {
575       public PBEWithSHA256And256BitAESBC()
576       {
577           super("PBEWithSHA256And256BitAES-CBC-BC", null, true, PKCS12, SHA256, 256, 128);
578       }
579   }
580
581   /**
582    * PBEWithMD5And128BitAES-OpenSSL
583    */
584   static public class PBEWithMD5And128BitAESCBCOpenSSL
585       extends PBEKeyFactory
586   {
587       public PBEWithMD5And128BitAESCBCOpenSSL()
588       {
589           super("PBEWithMD5And128BitAES-CBC-OpenSSL", null, true, OPENSSL, MD5, 128, 128);
590       }
591   }
592
593   /**
594    * PBEWithMD5And192BitAES-OpenSSL
595    */
596   static public class PBEWithMD5And192BitAESCBCOpenSSL
597       extends PBEKeyFactory
598   {
599       public PBEWithMD5And192BitAESCBCOpenSSL()
600       {
601           super("PBEWithMD5And192BitAES-CBC-OpenSSL", null, true, OPENSSL, MD5, 192, 128);
602       }
603   }
604
605   /**
606    * PBEWithMD5And256BitAES-OpenSSL
607    */
608   static public class PBEWithMD5And256BitAESCBCOpenSSL
609       extends PBEKeyFactory
610   {
611       public PBEWithMD5And256BitAESCBCOpenSSL()
612       {
613           super("PBEWithMD5And256BitAES-CBC-OpenSSL", null, true, OPENSSL, MD5, 256, 128);
614       }
615   }
616}
617