KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > ejbca > core > model > ca > caadmin > extendedcaservices > XKMSCAService


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.caadmin.extendedcaservices;
15
16 import java.io.UnsupportedEncodingException JavaDoc;
17 import java.security.KeyPair JavaDoc;
18 import java.security.KeyStore JavaDoc;
19 import java.security.PrivateKey JavaDoc;
20 import java.security.cert.Certificate JavaDoc;
21 import java.security.cert.X509Certificate JavaDoc;
22 import java.util.ArrayList JavaDoc;
23 import java.util.HashMap JavaDoc;
24 import java.util.List JavaDoc;
25
26 import org.apache.log4j.Logger;
27 import org.apache.xml.security.exceptions.XMLSecurityException;
28 import org.apache.xml.security.signature.XMLSignatureException;
29 import org.ejbca.core.ejb.ServiceLocator;
30 import org.ejbca.core.model.InternalResources;
31 import org.ejbca.core.model.ca.caadmin.CA;
32 import org.ejbca.core.model.ca.caadmin.IllegalKeyStoreException;
33 import org.ejbca.core.model.ca.certificateprofiles.XKMSCertificateProfile;
34 import org.ejbca.core.model.ra.UserDataVO;
35 import org.ejbca.util.Base64;
36 import org.ejbca.util.CertTools;
37 import org.ejbca.util.KeyTools;
38 import org.w3c.dom.Document JavaDoc;
39
40
41
42 /** Handles and maintains the CA-part of the XKMS functionality.
43  * The service have it's own certificate used for signing and encryption
44  *
45  * @author Philip Vendil
46  * @version $Id: XKMSCAService.java,v 1.2.2.1 2007/02/23 10:35:14 anatom Exp $
47  */

48 public class XKMSCAService extends ExtendedCAService implements java.io.Serializable JavaDoc{
49
50     private static Logger m_log = Logger.getLogger(XKMSCAService.class);
51     /** Internal localization of logs and errors */
52     private static final InternalResources intres = InternalResources.getInstance();
53
54     public static final float LATEST_VERSION = 1;
55     
56     public static final String JavaDoc SERVICENAME = "XKMSCASERVICE";
57
58     private PrivateKey JavaDoc xKMSkey = null;
59     private List JavaDoc xKMScertificatechain = null;
60     
61     private XKMSCAServiceInfo info = null;
62     
63     private static final String JavaDoc XKMSKEYSTORE = "xkmskeystore";
64     private static final String JavaDoc KEYSPEC = "keyspec";
65     private static final String JavaDoc KEYALGORITHM = "keyalgorithm";
66     private static final String JavaDoc SUBJECTDN = "subjectdn";
67     private static final String JavaDoc SUBJECTALTNAME = "subjectaltname";
68     
69     private static final String JavaDoc PRIVATESIGNKEYALIAS = "privatesignkeyalias";
70
71
72             
73     public XKMSCAService(ExtendedCAServiceInfo serviceinfo) {
74       m_log.debug("XKMSCAService : constructor " + serviceinfo.getStatus());
75       CertTools.installBCProvider();
76       // Currently only RSA keys are supported
77
XKMSCAServiceInfo info = (XKMSCAServiceInfo) serviceinfo;
78       data = new HashMap JavaDoc();
79       data.put(EXTENDEDCASERVICETYPE, new Integer JavaDoc(ExtendedCAServiceInfo.TYPE_XKMSEXTENDEDSERVICE));
80
81       data.put(KEYSPEC, info.getKeySpec());
82       data.put(KEYALGORITHM, info.getKeyAlgorithm());
83       setSubjectDN(info.getSubjectDN());
84       setSubjectAltName(info.getSubjectAltName());
85       setStatus(serviceinfo.getStatus());
86         
87       data.put(VERSION, new Float JavaDoc(LATEST_VERSION));
88     }
89     
90     public XKMSCAService(HashMap JavaDoc data) throws IllegalArgumentException JavaDoc, IllegalKeyStoreException {
91       CertTools.installBCProvider();
92       loadData(data);
93       if(data.get(XKMSKEYSTORE) != null){
94          // lookup keystore passwords
95
String JavaDoc keystorepass = ServiceLocator.getInstance().getString("java:comp/env/XKMSKeyStorePass");
96          if (keystorepass == null)
97              throw new IllegalArgumentException JavaDoc("Missing XKMSKeyStorePass property.");
98                
99         try {
100             m_log.debug("Loading XKMS keystore");
101             KeyStore JavaDoc keystore=KeyStore.getInstance("PKCS12", "BC");
102             keystore.load(new java.io.ByteArrayInputStream JavaDoc(Base64.decode(((String JavaDoc) data.get(XKMSKEYSTORE)).getBytes())),keystorepass.toCharArray());
103             m_log.debug("Finished loading XKMS keystore");
104       
105             this.xKMSkey = (PrivateKey JavaDoc) keystore.getKey(PRIVATESIGNKEYALIAS, null);
106             // Due to a bug in Glassfish, we need to make sure all certificates in this
107
// Array i of SUNs own provider
108
//this.xKMScertificatechain = Arrays.asList(keystore.getCertificateChain(PRIVATESIGNKEYALIAS));
109
this.xKMScertificatechain = CertTools.getCertCollectionFromArray(keystore.getCertificateChain(PRIVATESIGNKEYALIAS), "SUN");
110             this.info = new XKMSCAServiceInfo(getStatus(),
111                                               getSubjectDN(),
112                                               getSubjectAltName(),
113                                               (String JavaDoc)data.get(KEYSPEC),
114                                               (String JavaDoc) data.get(KEYALGORITHM),
115                                               this.xKMScertificatechain);
116       
117         } catch (Exception JavaDoc e) {
118             throw new IllegalKeyStoreException(e);
119         }
120         
121         data.put(EXTENDEDCASERVICETYPE, new Integer JavaDoc(ExtendedCAServiceInfo.TYPE_XKMSEXTENDEDSERVICE));
122      }
123    }
124     
125     
126
127    /*
128     * @see org.ejbca.core.model.ca.caadmin.extendedcaservices.ExtendedCAService#extendedService(org.ejbca.core.model.ca.caadmin.extendedcaservices.ExtendedCAServiceRequest)
129     */

130    public void init(CA ca) throws Exception JavaDoc {
131      m_log.debug("XKMSCAService : init ");
132      // lookup keystore passwords
133
String JavaDoc keystorepass = ServiceLocator.getInstance().getString("java:comp/env/XKMSKeyStorePass");
134      if (keystorepass == null)
135        throw new IllegalArgumentException JavaDoc("Missing XKMSKeyStorePass property.");
136         
137       // Currently only RSA keys are supported
138
XKMSCAServiceInfo info = (XKMSCAServiceInfo) getExtendedCAServiceInfo();
139                   
140      // Create XKMS KeyStore
141
KeyStore JavaDoc keystore = KeyStore.getInstance("PKCS12", "BC");
142      keystore.load(null, null);
143       
144      KeyPair JavaDoc xKMSkeys = KeyTools.genKeys(info.getKeySpec(), info.getKeyAlgorithm());
145           
146      Certificate JavaDoc xKMSCertificate =
147       ca.generateCertificate(new UserDataVO("NOUSERNAME",
148                                             info.getSubjectDN(),
149                                             0,
150                                             info.getSubjectAltName(),
151                                             "NOEMAIL",
152                                             0,0,0,0, null,null,0,0,null)
153                            , xKMSkeys.getPublic(),
154                            -1, // KeyUsage
155
ca.getValidity(),
156                            new XKMSCertificateProfile());
157       
158      xKMScertificatechain = new ArrayList JavaDoc();
159      xKMScertificatechain.add(xKMSCertificate);
160      xKMScertificatechain.addAll(ca.getCertificateChain());
161      this.xKMSkey = xKMSkeys.getPrivate();
162               
163      keystore.setKeyEntry(PRIVATESIGNKEYALIAS,xKMSkeys.getPrivate(),null,(Certificate JavaDoc[]) xKMScertificatechain.toArray(new Certificate JavaDoc[xKMScertificatechain.size()]));
164      java.io.ByteArrayOutputStream JavaDoc baos = new java.io.ByteArrayOutputStream JavaDoc();
165      keystore.store(baos, keystorepass.toCharArray());
166      data.put(XKMSKEYSTORE, new String JavaDoc(Base64.encode(baos.toByteArray())));
167      // Store XKMS KeyStore
168

169      setStatus(info.getStatus());
170      this.info = new XKMSCAServiceInfo(info.getStatus(),
171                                       getSubjectDN(),
172                                       getSubjectAltName(),
173                                       (String JavaDoc)data.get(KEYSPEC),
174                                       (String JavaDoc) data.get(KEYALGORITHM),
175                                       xKMScertificatechain);
176       
177    }
178
179    /*
180     * @see org.ejbca.core.model.ca.caadmin.extendedcaservices.ExtendedCAService#extendedService(org.ejbca.core.model.ca.caadmin.extendedcaservices.ExtendedCAServiceRequest)
181     */

182    public void update(ExtendedCAServiceInfo serviceinfo, CA ca) throws Exception JavaDoc{
183        XKMSCAServiceInfo info = (XKMSCAServiceInfo) serviceinfo;
184        m_log.debug("XKMSCAService : update " + serviceinfo.getStatus());
185        setStatus(serviceinfo.getStatus());
186        if(info.getRenewFlag()){
187          // Renew The XKMS Signers certificate.
188
this.init(ca);
189        }
190              
191        // Only status is updated
192
this.info = new XKMSCAServiceInfo(serviceinfo.getStatus(),
193                                           getSubjectDN(),
194                                           getSubjectAltName(),
195                                           (String JavaDoc) data.get(KEYSPEC),
196                                           (String JavaDoc) data.get(KEYALGORITHM),
197                                           xKMScertificatechain);
198                                                                                                                                   
199    }
200
201
202
203     /*
204      * @see org.ejbca.core.model.ca.caadmin.extendedcaservices.ExtendedCAService#extendedService(org.ejbca.core.model.ca.caadmin.extendedcaservices.ExtendedCAServiceRequest)
205      */

206     public ExtendedCAServiceResponse extendedService(ExtendedCAServiceRequest request) throws ExtendedCAServiceRequestException, IllegalExtendedCAServiceRequestException,ExtendedCAServiceNotActiveException {
207         m_log.debug(">extendedService");
208         if (!(request instanceof XKMSCAServiceRequest)) {
209             throw new IllegalExtendedCAServiceRequestException();
210         }
211         if (this.getStatus() != ExtendedCAServiceInfo.STATUS_ACTIVE) {
212             String JavaDoc msg = intres.getLocalizedMessage("caservice.notactive");
213             m_log.error(msg);
214             throw new ExtendedCAServiceNotActiveException(msg);
215         }
216         ExtendedCAServiceResponse returnval = null;
217         X509Certificate JavaDoc signerCert = (X509Certificate JavaDoc) xKMScertificatechain.get(0);
218         XKMSCAServiceRequest xKMSServiceReq = (XKMSCAServiceRequest)request;
219         
220         Document JavaDoc doc = xKMSServiceReq.getDoc();
221         if(xKMSServiceReq.isSign()){
222             try{
223
224                 org.apache.xml.security.signature.XMLSignature xmlSig = new org.apache.xml.security.signature.XMLSignature(doc, "", org.apache.xml.security.signature.XMLSignature.ALGO_ID_SIGNATURE_RSA_SHA1, org.apache.xml.security.c14n.Canonicalizer.ALGO_ID_C14N_EXCL_OMIT_COMMENTS);
225                 org.apache.xml.security.transforms.Transforms transforms = new org.apache.xml.security.transforms.Transforms(doc);
226                 transforms.addTransform(org.apache.xml.security.transforms.Transforms.TRANSFORM_ENVELOPED_SIGNATURE);
227                 transforms.addTransform(org.apache.xml.security.transforms.Transforms.TRANSFORM_C14N_EXCL_OMIT_COMMENTS);
228                 xmlSig.addDocument("#" + xKMSServiceReq.getId(), transforms, org.apache.xml.security.utils.Constants.ALGO_ID_DIGEST_SHA1);
229                 xmlSig.addKeyInfo(signerCert);
230                 doc.getDocumentElement().insertBefore( xmlSig.getElement() ,doc.getDocumentElement().getFirstChild());
231                 xmlSig.sign(xKMSkey);
232                 
233                 returnval = new XKMSCAServiceResponse(doc);
234             }catch (XMLSignatureException e) {
235                 throw new ExtendedCAServiceRequestException(e);
236             } catch (XMLSecurityException e) {
237                 throw new ExtendedCAServiceRequestException(e);
238             }
239         }
240         
241         m_log.debug("<extendedService");
242         return returnval;
243     }
244
245     
246     public float getLatestVersion() {
247         return LATEST_VERSION;
248     }
249
250     public void upgrade() {
251         if(Float.compare(LATEST_VERSION, getVersion()) != 0) {
252           // New version of the class, upgrade
253

254
255           data.put(VERSION, new Float JavaDoc(LATEST_VERSION));
256         }
257     }
258
259     /*
260      * @see org.ejbca.core.model.ca.caadmin.extendedcaservices.ExtendedCAService#getExtendedCAServiceInfo()
261      */

262     public ExtendedCAServiceInfo getExtendedCAServiceInfo() {
263         if(info == null){
264           info = new XKMSCAServiceInfo(getStatus(),
265                                       getSubjectDN(),
266                                       getSubjectAltName(),
267                                       (String JavaDoc) data.get(KEYSPEC),
268                                       (String JavaDoc) data.get(KEYALGORITHM),
269                                       xKMScertificatechain);
270         }
271         
272         return this.info;
273     }
274     
275     
276     public String JavaDoc getSubjectDN(){
277         String JavaDoc retval = null;
278         String JavaDoc str = (String JavaDoc)data.get(SUBJECTDN);
279          try {
280             retval = new String JavaDoc(Base64.decode((str).getBytes("UTF-8")));
281         } catch (UnsupportedEncodingException JavaDoc e) {
282             m_log.error("Could not decode XKMS data from Base64",e);
283         } catch (ArrayIndexOutOfBoundsException JavaDoc e) {
284             // This is an old CA, where it's not Base64encoded
285
m_log.debug("Old non base64 encoded DN: "+str);
286             retval = str;
287         }
288         
289         return retval;
290     }
291     
292     public void setSubjectDN(String JavaDoc dn){
293         
294          try {
295             data.put(SUBJECTDN,new String JavaDoc(Base64.encode(dn.getBytes("UTF-8"),false)));
296         } catch (UnsupportedEncodingException JavaDoc e) {
297             m_log.error("Could not encode XKMS data from Base64",e);
298         }
299     }
300     
301     public String JavaDoc getSubjectAltName(){
302         String JavaDoc retval = null;
303         String JavaDoc str= (String JavaDoc) data.get(SUBJECTALTNAME);
304          try {
305             retval = new String JavaDoc(Base64.decode((str).getBytes("UTF-8")));
306         } catch (UnsupportedEncodingException JavaDoc e) {
307             m_log.error("Could not decode XKMS data from Base64",e);
308         } catch (ArrayIndexOutOfBoundsException JavaDoc e) {
309             // This is an old CA, where it's not Base64encoded
310
m_log.debug("Old non base64 encoded altname: "+str);
311             retval = str;
312         }
313         
314         return retval;
315     }
316     
317     public void setSubjectAltName(String JavaDoc dn){
318         
319          try {
320             data.put(SUBJECTALTNAME,new String JavaDoc(Base64.encode(dn.getBytes("UTF-8"), false)));
321         } catch (UnsupportedEncodingException JavaDoc e) {
322             m_log.error("Could not encode XKMS data from Base64",e);
323         }
324     }
325 }
326
327
Popular Tags