KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > ejbca > core > model > ca > catoken > SoftCAToken


1 /*************************************************************************
2  * *
3  * EJBCA: The OpenSource Certificate Authority *
4  * *
5  * This software is free software; you can redistribute it and/or *
6  * modify it under the terms of the GNU Lesser General Public *
7  * License as published by the Free Software Foundation; either *
8  * version 2.1 of the License, or any later version. *
9  * *
10  * See terms of license at gnu.org. *
11  * *
12  *************************************************************************/

13  
14 package org.ejbca.core.model.ca.catoken;
15
16 import java.security.KeyPair JavaDoc;
17 import java.security.KeyStore JavaDoc;
18 import java.security.PrivateKey JavaDoc;
19 import java.security.PublicKey JavaDoc;
20 import java.security.cert.Certificate JavaDoc;
21 import java.security.cert.X509Certificate JavaDoc;
22 import java.security.interfaces.RSAPublicKey JavaDoc;
23 import java.util.Enumeration JavaDoc;
24 import java.util.HashMap JavaDoc;
25
26 import javax.naming.InitialContext JavaDoc;
27
28 import org.apache.log4j.Logger;
29 import org.bouncycastle.jce.ECNamedCurveTable;
30 import org.bouncycastle.jce.interfaces.ECPrivateKey;
31 import org.bouncycastle.jce.interfaces.ECPublicKey;
32 import org.ejbca.core.ejb.ServiceLocator;
33 import org.ejbca.core.model.InternalResources;
34 import org.ejbca.core.model.SecConst;
35 import org.ejbca.core.model.ca.caadmin.IllegalKeyStoreException;
36 import org.ejbca.util.Base64;
37 import org.ejbca.util.CertTools;
38 import org.ejbca.util.KeyTools;
39
40 /** Handles maintenance of the soft devices producing signatures and handling the private key
41  * and stored in database.
42  *
43  * @version $Id: SoftCAToken.java,v 1.7.2.1 2007/04/02 08:22:54 jeklund Exp $
44  */

45 public class SoftCAToken extends CAToken implements java.io.Serializable JavaDoc{
46
47     /** Log4j instance */
48     private static final Logger log = Logger.getLogger(SoftCAToken.class);
49     /** Internal localization of logs and errors */
50     private static final InternalResources intres = InternalResources.getInstance();
51
52     /** When upgradeing this version, you must up the version of the CA as well,
53      * otherwise the upgraded CA token will not be stored in the database.
54      */

55     public static final float LATEST_VERSION = 3;
56     
57     private static final String JavaDoc PROVIDER = "BC";
58
59     private PrivateKey JavaDoc privateSignKey = null;
60     private PrivateKey JavaDoc privateDecKey = null;
61     private PublicKey JavaDoc publicSignKey = null;
62     private PublicKey JavaDoc publicEncKey = null;
63     private Certificate JavaDoc encCert = null;
64     
65     private static final String JavaDoc PRIVATESIGNKEYALIAS = "privatesignkeyalias";
66     private static final String JavaDoc PRIVATEDECKEYALIAS = "privatedeckeyalias";
67     
68     protected static final String JavaDoc SIGNKEYSPEC = "SIGNKEYSPEC";
69     protected static final String JavaDoc ENCKEYSPEC = "ENCKEYSPEC";
70     protected static final String JavaDoc SIGNKEYALGORITHM = "SIGNKEYALGORITHM";
71     protected static final String JavaDoc ENCKEYALGORITHM = "ENCKEYALGORITHM";
72     protected static final String JavaDoc KEYSTORE = "KEYSTORE";
73
74     /** Old provided for upgrade purposes from 3.3. -> 3.4 */
75     protected static final String JavaDoc KEYALGORITHM = "KEYALGORITHM";
76     /** Old provided for upgrade purposes from 3.3. -> 3.4 */
77     protected static final String JavaDoc KEYSIZE = "KEYSIZE";
78
79     public SoftCAToken(){
80       data = new HashMap JavaDoc();
81       data.put(CATOKENTYPE, new Integer JavaDoc(CATokenInfo.CATOKENTYPE_P12));
82       data.put(VERSION, new Float JavaDoc(LATEST_VERSION));
83     }
84     
85     public SoftCAToken(HashMap JavaDoc data) throws IllegalArgumentException JavaDoc, IllegalKeyStoreException {
86       loadData(data);
87       if(data.get(KEYSTORE) != null){
88           // lookup keystore passwords
89
String JavaDoc keystorepass = ServiceLocator.getInstance().getString("java:comp/env/keyStorePass");
90           if (keystorepass == null)
91               throw new IllegalArgumentException JavaDoc("Missing keyStorePass property.");
92           try {
93               KeyStore JavaDoc keystore=KeyStore.getInstance("PKCS12", "BC");
94               keystore.load(new java.io.ByteArrayInputStream JavaDoc(Base64.decode(((String JavaDoc) data.get(KEYSTORE)).getBytes())),keystorepass.toCharArray());
95               
96               this.privateSignKey = (PrivateKey JavaDoc) keystore.getKey(PRIVATESIGNKEYALIAS, null);
97               this.privateDecKey = (PrivateKey JavaDoc) keystore.getKey(PRIVATEDECKEYALIAS, null);
98               
99               this.publicSignKey = keystore.getCertificateChain(PRIVATESIGNKEYALIAS)[0].getPublicKey();
100               this.encCert = keystore.getCertificateChain(PRIVATEDECKEYALIAS)[0];
101               this.publicEncKey = this.encCert.getPublicKey();
102               
103           } catch (Exception JavaDoc e) {
104               throw new IllegalKeyStoreException(e);
105           }
106           
107           data.put(CATOKENTYPE, new Integer JavaDoc(CATokenInfo.CATOKENTYPE_P12));
108       }
109    }
110     
111    /**
112     * Method that generates the keys that will be used by the CAToken.
113     */

114    public void generateKeys(CATokenInfo catokeninfo) throws Exception JavaDoc{
115
116        // Get key store password
117
String JavaDoc keystorepass = ServiceLocator.getInstance().getString("java:comp/env/keyStorePass");
118        // Currently only RSA keys are supported
119
SoftCATokenInfo info = (SoftCATokenInfo) catokeninfo;
120        String JavaDoc signkeyspec = info.getSignKeySpec();
121        KeyStore JavaDoc keystore = KeyStore.getInstance("PKCS12", "BC");
122        keystore.load(null, null);
123        
124        // generate sign keys.
125
KeyPair JavaDoc signkeys = KeyTools.genKeys(signkeyspec, info.getSignKeyAlgorithm());
126        // generate dummy certificate
127
Certificate JavaDoc[] certchain = new Certificate JavaDoc[1];
128        certchain[0] = CertTools.genSelfCert("CN=dummy", 36500, null, signkeys.getPrivate(), signkeys.getPublic(), info.getSignatureAlgorithm(), true);
129        
130        keystore.setKeyEntry(PRIVATESIGNKEYALIAS,signkeys.getPrivate(),null, certchain);
131        
132        // generate enc keys.
133
// Encryption keys must be RSA still
134
String JavaDoc enckeyspec = info.getEncKeySpec();
135        KeyPair JavaDoc enckeys = KeyTools.genKeys(enckeyspec, info.getEncKeyAlgorithm());
136        // generate dummy certificate
137
certchain[0] = CertTools.genSelfCert("CN=dummy2", 36500, null, enckeys.getPrivate(), enckeys.getPublic(), info.getEncryptionAlgorithm(), true);
138        this.encCert = certchain[0];
139        keystore.setKeyEntry(PRIVATEDECKEYALIAS,enckeys.getPrivate(),null,certchain);
140        java.io.ByteArrayOutputStream JavaDoc baos = new java.io.ByteArrayOutputStream JavaDoc();
141        keystore.store(baos, keystorepass.toCharArray());
142        data.put(KEYSTORE, new String JavaDoc(Base64.encode(baos.toByteArray())));
143        data.put(SIGNKEYSPEC, signkeyspec);
144        data.put(SIGNKEYALGORITHM, info.getSignKeyAlgorithm());
145        data.put(SIGNATUREALGORITHM, info.getSignatureAlgorithm());
146        data.put(ENCKEYSPEC, enckeyspec);
147        data.put(ENCKEYALGORITHM, info.getEncKeyAlgorithm());
148        data.put(ENCRYPTIONALGORITHM, info.getEncryptionAlgorithm());
149        // initalize CAToken
150
this.publicSignKey = signkeys.getPublic();
151        this.privateSignKey = signkeys.getPrivate();
152               
153        this.publicEncKey = enckeys.getPublic();
154        this.privateDecKey = enckeys.getPrivate();
155    }
156    
157    /**
158     * Method that import CA token keys from a P12 file. Was originally used when upgrading from
159     * old EJBCA versions. Only supports SHA1 and SHA256 with RSA or ECDSA.
160     */

161    public void importKeysFromP12(PrivateKey JavaDoc p12privatekey, PublicKey JavaDoc p12publickey, PrivateKey JavaDoc p12PrivateEncryptionKey,
162                                     PublicKey JavaDoc p12PublicEncryptionKey, Certificate JavaDoc[] caSignatureCertChain) throws Exception JavaDoc{
163       // lookup keystore passwords
164
InitialContext JavaDoc ictx = new InitialContext JavaDoc();
165       String JavaDoc keystorepass = (String JavaDoc) ictx.lookup("java:comp/env/keyStorePass");
166       if (keystorepass == null)
167         throw new IllegalArgumentException JavaDoc("Missing keyStorePass property.");
168         
169        // Currently only RSA keys are supported
170
KeyStore JavaDoc keystore = KeyStore.getInstance("PKCS12", "BC");
171        keystore.load(null,null);
172
173        // Assume that the same hash algorithm is used for signing that was used to sign this CA cert
174
String JavaDoc certSignatureAlgorithm = ((X509Certificate JavaDoc) caSignatureCertChain[0]).getSigAlgName();
175        String JavaDoc signatureAlgorithm = null;
176        String JavaDoc keyAlg = null;
177        if ( p12publickey instanceof RSAPublicKey JavaDoc ) {
178            keyAlg = CATokenInfo.KEYALGORITHM_RSA;
179            if (certSignatureAlgorithm.indexOf("256") == -1) {
180                signatureAlgorithm = CATokenInfo.SIGALG_SHA1_WITH_RSA;
181            } else {
182                signatureAlgorithm = CATokenInfo.SIGALG_SHA256_WITH_RSA;
183            }
184        } else {
185            keyAlg = CATokenInfo.KEYALGORITHM_ECDSA;
186            if (certSignatureAlgorithm.indexOf("256") == -1) {
187                signatureAlgorithm = CATokenInfo.SIGALG_SHA1_WITH_ECDSA;
188            } else {
189                signatureAlgorithm = CATokenInfo.SIGALG_SHA256_WITH_ECDSA;
190            }
191        }
192        
193        // import sign keys.
194
String JavaDoc keyspec = null;
195        if ( p12publickey instanceof RSAPublicKey JavaDoc ) {
196            keyspec = Integer.toString( ((RSAPublicKey JavaDoc) p12publickey).getModulus().bitLength() );
197            log.debug("KeySize="+keyspec);
198        } else {
199             Enumeration JavaDoc en = ECNamedCurveTable.getNames();
200             while ( en.hasMoreElements() ) {
201                 String JavaDoc currentCurveName = (String JavaDoc) en.nextElement();
202                 if ( (ECNamedCurveTable.getParameterSpec(currentCurveName)).getCurve().equals( ((ECPrivateKey) p12privatekey).getParameters().getCurve() ) ) {
203                     keyspec = currentCurveName;
204                     break;
205                 }
206             }
207
208            if ( keyspec==null ) {
209                keyspec = "unknown";
210            }
211            p12privatekey = (ECPrivateKey) p12privatekey;
212            p12publickey = (ECPublicKey) p12publickey;
213            log.debug("ECName="+keyspec);
214        }
215        keystore.setKeyEntry(PRIVATESIGNKEYALIAS, p12privatekey, null, caSignatureCertChain);
216        data.put(SIGNKEYSPEC, keyspec);
217        data.put(SIGNKEYALGORITHM, keyAlg);
218        data.put(SIGNATUREALGORITHM, signatureAlgorithm);
219
220        // generate enc keys.
221
// Encryption keys must be RSA still
222
String JavaDoc encryptionSignatureAlgorithm = signatureAlgorithm;
223        keyAlg = CATokenInfo.KEYALGORITHM_RSA;
224        keyspec = "2048";
225        if ( signatureAlgorithm.equals(CATokenInfo.SIGALG_SHA256_WITH_ECDSA) ) {
226            encryptionSignatureAlgorithm = CATokenInfo.SIGALG_SHA256_WITH_RSA;
227        } else if ( signatureAlgorithm.equals(CATokenInfo.SIGALG_SHA1_WITH_ECDSA) ) {
228            encryptionSignatureAlgorithm = CATokenInfo.SIGALG_SHA1_WITH_RSA;
229        }
230        KeyPair JavaDoc enckeys = null;
231        if ( p12PublicEncryptionKey == null || p12PrivateEncryptionKey == null ) {
232            enckeys = KeyTools.genKeys(keyspec, keyAlg);
233        }
234        else {
235            enckeys = new KeyPair JavaDoc(p12PublicEncryptionKey, p12PrivateEncryptionKey);
236        }
237        // generate dummy certificate
238
Certificate JavaDoc[] certchain = new Certificate JavaDoc[1];
239        certchain[0] = CertTools.genSelfCert("CN=dummy2", 36500, null, enckeys.getPrivate(), enckeys.getPublic(), encryptionSignatureAlgorithm, true);
240        this.encCert = certchain[0];
241        keystore.setKeyEntry(PRIVATEDECKEYALIAS,enckeys.getPrivate(),null,certchain);
242      
243        java.io.ByteArrayOutputStream JavaDoc baos = new java.io.ByteArrayOutputStream JavaDoc();
244        keystore.store(baos, keystorepass.toCharArray());
245        data.put(KEYSTORE, new String JavaDoc(Base64.encode(baos.toByteArray())));
246        data.put(ENCKEYSPEC, keyspec);
247        data.put(ENCKEYALGORITHM, keyAlg);
248        data.put(ENCRYPTIONALGORITHM, encryptionSignatureAlgorithm);
249        
250        // initalize CAToken
251
this.publicSignKey = p12publickey;
252        this.privateSignKey = p12privatekey;
253        
254        this.publicEncKey = enckeys.getPublic();
255        this.privateDecKey = enckeys.getPrivate();
256    }
257    
258    public CATokenInfo getCATokenInfo(){
259      SoftCATokenInfo info = new SoftCATokenInfo();
260      
261      info.setSignKeySpec((String JavaDoc) data.get(SIGNKEYSPEC));
262      info.setSignKeyAlgorithm((String JavaDoc) data.get(SIGNKEYALGORITHM));
263      info.setSignatureAlgorithm((String JavaDoc) data.get(SIGNATUREALGORITHM));
264      
265      info.setEncKeySpec((String JavaDoc) data.get(ENCKEYSPEC));
266      info.setEncKeyAlgorithm((String JavaDoc) data.get(ENCKEYALGORITHM));
267      info.setEncryptionAlgorithm((String JavaDoc) data.get(ENCRYPTIONALGORITHM));
268      
269      return info;
270    }
271    
272    /**
273     * Updates the CAToken data saved in database.
274     */

275     public void updateCATokenInfo(CATokenInfo catokeninfo){
276        // Do nothing, no data can be updated after the keys are generated.
277
}
278    
279    /**
280     * @see org.ejbca.core.model.ca.catoken.CAToken
281     *
282     * @return PrivateKey object
283     */

284     public PrivateKey JavaDoc getPrivateKey(int purpose){
285       if(purpose == SecConst.CAKEYPURPOSE_KEYENCRYPT)
286         return this.privateDecKey;
287         
288       return privateSignKey;
289     }
290
291    /**
292     * @see org.ejbca.core.model.ca.catoken.CAToken
293     *
294     * @return PublicKey object
295     */

296     public PublicKey JavaDoc getPublicKey(int purpose){
297      if(purpose == SecConst.CAKEYPURPOSE_KEYENCRYPT)
298        return this.publicEncKey;
299      
300       return publicSignKey;
301     }
302     
303
304     /** Returns the signature Provider that should be used to sign things with
305      * the PrivateKey object returned by this signingdevice implementation.
306      * @return String the name of the Provider
307      */

308     public String JavaDoc getProvider(){
309       return PROVIDER;
310     }
311
312     /** Implemtation of UpgradableDataHashMap function getLatestVersion */
313     public float getLatestVersion(){
314        return LATEST_VERSION;
315     }
316
317     /** Implemtation of UpgradableDataHashMap function upgrade. */
318
319     public void upgrade(){
320         if(Float.compare(LATEST_VERSION, getVersion()) != 0) {
321             // New version of the class, upgrade
322
String JavaDoc msg = intres.getLocalizedMessage("catoken.upgradesoft", new Float JavaDoc(getVersion()));
323             log.info(msg);
324             if(data.get(SIGNKEYALGORITHM) == null) {
325                 String JavaDoc oldKeyAlg = (String JavaDoc)data.get(KEYALGORITHM);
326                 data.put(SIGNKEYALGORITHM, oldKeyAlg);
327                 data.put(ENCKEYALGORITHM, oldKeyAlg);
328             }
329             if(data.get(SIGNKEYSPEC) == null) {
330                 Integer JavaDoc oldKeySize = ((Integer JavaDoc) data.get(KEYSIZE));
331                 data.put(SIGNKEYSPEC, oldKeySize.toString());
332                 data.put(ENCKEYSPEC, oldKeySize.toString());
333             }
334             if(data.get(ENCRYPTIONALGORITHM) == null) {
335                 String JavaDoc signAlg = (String JavaDoc)data.get(SIGNATUREALGORITHM);
336                 data.put(ENCRYPTIONALGORITHM, signAlg);
337             }
338             
339             data.put(VERSION, new Float JavaDoc(LATEST_VERSION));
340         }
341     }
342
343     /**
344      * Method doing nothing.
345      *
346      * @see org.ejbca.core.model.ca.catoken.CAToken#activate(java.lang.String)
347      */

348     public void activate(String JavaDoc authenticationcode) throws CATokenAuthenticationFailedException, CATokenOfflineException {
349         // Do nothing
350
}
351
352     /**
353      * @see org.ejbca.core.model.ca.catoken.CAToken#deactivate()
354      */

355     public boolean deactivate() {
356         // Do nothing
357
return true;
358     }
359     
360     
361 }
362
363
Popular Tags