Docjar: A Java Source and Docuemnt Enginecom.*    java.*    javax.*    org.*    all    new    plug-in

Quick Search    Search Deep

Source code: cryptix/jce/provider/keyfactory/PBEKeyFactory.java


1   /* $Id: PBEKeyFactory.java,v 1.1 2000/06/09 21:37:31 pw Exp $
2    *
3    * Copyright (C) 1995-2000 The Cryptix Foundation Limited.
4    * All rights reserved.
5    *
6    * Use, modification, copying and distribution of this software is subject
7    * the terms and conditions of the Cryptix General Licence. You should have
8    * received a copy of the Cryptix General License along with this library;
9    * if not, you can download a copy from http://www.cryptix.org/ .
10   */
11  package cryptix.jce.provider.keyfactory;
12  
13  
14  import cryptix.jce.provider.key.RawSecretKey;
15  
16  import java.lang.reflect.Constructor;
17  import java.lang.reflect.Array;
18  import java.lang.reflect.InvocationTargetException;
19  
20  import java.security.InvalidKeyException;
21  
22  import java.security.spec.InvalidKeySpecException;
23  import java.security.spec.KeySpec;
24  
25  import javax.crypto.SecretKey;
26  import javax.crypto.SecretKeyFactorySpi;
27  import javax.crypto.spec.PBEKeySpec;
28  
29  
30  /**
31   * This is a KeyFactory for PBE.
32   * It converts key specs and secret keys into PBEKeys.
33   * It is based (as any cipher) on a service provider interface.
34   * This is SecretKeyFactorySpi as PBE ciphers are using
35   * secret key ciphers.
36   *
37   * @author: Josef Hartmann (jhartmann@bigfoot.com)
38   * @version: $Revision: 1.1 $
39   */
40  
41  public final class PBEKeyFactory extends SecretKeyFactorySpi
42  {
43  
44      /** Internal storage for the PBEKeySpec. */
45      private PBEKeySpec pbeKeySpec = null;
46  
47      /**
48       * This method generates a secret key based
49       * on the given KeySpec.
50       * Either decode data of the key or regenerate the key based
51       * on the keyspec.
52       *
53       * @param keySpec KeySpec Instance of PBEKeySpec
54       * @returns: SecretKey based on KeySpec.
55       * @exception: InvalidKeySpecException if something goes wrong.
56       */
57      protected SecretKey engineGenerateSecret(KeySpec keySpec)
58      throws InvalidKeySpecException
59      {
60          // Check if parameter is valid.
61          if ((keySpec==null) || !(keySpec instanceof PBEKeySpec))
62          {
63              // FIXME: Anything else to do here?
64              // We could do keySpec.getEncoded()
65              throw new InvalidKeySpecException(
66                  "Cannot generate SecretKey using given KeySpec.");
67          }
68          else
69          {
70              // FIXME: We could get a KeySpec which is not a PBEKeySpec
71              // so it should be possible to convert it!
72          }
73  
74          // keySpec is valid -> cast keySpec
75          pbeKeySpec = (PBEKeySpec) keySpec;
76  
77          // create RawSecretKey using the keySpec.
78          RawSecretKey key = new RawSecretKey("PBE",new String(pbeKeySpec.getPassword()).getBytes());
79  
80          return key;
81      }
82  
83  
84      /**
85       * This method returns a key specification of the given secret key
86       * using the provided key spec class as the output format.
87       *
88       *
89       * @param key SecretKey The key to use for creating the key specification.
90       * @param keySpec Class The key format of the returning KeySpec value.
91       * @returns The key specification in the requested format.
92       * @exception InvalidKeySpecException If something goes wrong.
93       */
94      protected KeySpec engineGetKeySpec(SecretKey key, Class keySpec)
95      throws InvalidKeySpecException
96      {
97          if ((key==null)||(keySpec == null))
98          {
99              throw new InvalidKeySpecException("Null parameter provided.");
100         }
101 
102         Class specClass = null;
103         try
104         {
105             specClass = Class.forName("javax.crypto.spec.PBEKeySpec");
106         }
107         catch (ClassNotFoundException cnfe)
108         {
109             throw new InvalidKeySpecException("Cannot create"
110                                     +" KeySpec class not found!");
111         }
112 
113         // Check if keySpec is the same as or a super class (interface) of
114         // PBEKeySpec.
115 
116         if (keySpec.isAssignableFrom(specClass))
117         {
118 
119             byte [] keyData = key.getEncoded();
120             char [] rawKeyData = new char[keyData.length];
121 
122             // use System.arraycopy?
123             for (int i=0; i<keyData.length; i++)
124             {
125                 rawKeyData[i] = (char)(keyData[i]);
126             }
127 
128             // Use reflection to detect constructor of keySpec and create it.
129             // FIXME: MAYBE JUST DO WHAT (PW) does in BlockParameters.java
130             // (jh)
131 
132             Object [] initArgs = new Object[] {rawKeyData};
133 
134             // This is the parameter type the constructor should take.
135             Class [] constructorArgs = {char[].class};
136 
137             KeySpec pks = null;
138 
139             // Get constructors.
140             try
141             {
142                 Constructor specConstructor =
143                         keySpec.getConstructor(constructorArgs);
144 
145                 pks = (KeySpec) specConstructor.newInstance(initArgs);
146 
147             }
148             catch (InstantiationException e)
149             {
150                 throw new InvalidKeySpecException("InvalidKeySpec.");
151             }
152             catch (IllegalAccessException e)
153             {
154                 throw new InvalidKeySpecException("IllegalAccess.");
155             }
156             catch (IllegalArgumentException e)
157             {
158                 throw new InvalidKeySpecException("Illegal constr. argument.");
159             }
160             catch (InvocationTargetException e)
161             {
162                 throw new InvalidKeySpecException("InvocationTargetException.");
163             }
164             catch (NoSuchMethodException e)
165             {
166                 throw new InvalidKeySpecException("Method not found.");
167             }
168 
169             return pks;
170         }
171         else
172         {
173             throw new InvalidKeySpecException("Cannot assign to KeySpec.");
174         }
175 
176     }
177 
178 
179     /**
180      * This method translates a secret key of an untrusted or
181      * unknown provider into a "valid" secret key.
182      *
183      * status: pending, not tested.
184      *
185      * @param key SecretKey Key to translate.
186      * @returns A secret key.
187      * @exception InvalidKeyException
188      */
189     protected SecretKey engineTranslateKey(SecretKey key)
190     throws InvalidKeyException
191     {
192         if (key == null)
193         {
194             throw new InvalidKeyException();
195         }
196         else
197         {
198             if ((key instanceof RawSecretKey)&&(key.getAlgorithm()=="PBE"))
199             {
200                 // Nothing to do key is fine.
201                 return key;
202             }
203             else
204             {
205                 // create a key using PBEKeySpec
206                 try
207                 {
208                     KeySpec tmpKs = this.engineGetKeySpec(key, null);
209                     return engineGenerateSecret(tmpKs);
210                 }
211                 catch (InvalidKeySpecException ikse)
212                 {
213                     throw new InvalidKeyException("Translation not possible.");
214                 }
215 
216             }
217 
218         }
219 
220         // throw new InvalidKeyException();
221 
222     }
223 
224 }