1 13 14 package org.ejbca.core.model.ca.caadmin.extendedcaservices; 15 16 import java.io.UnsupportedEncodingException ; 17 import java.security.KeyPair ; 18 import java.security.KeyStore ; 19 import java.security.PrivateKey ; 20 import java.security.cert.Certificate ; 21 import java.security.cert.X509Certificate ; 22 import java.util.ArrayList ; 23 import java.util.HashMap ; 24 import java.util.List ; 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 ; 39 40 41 42 48 public class XKMSCAService extends ExtendedCAService implements java.io.Serializable { 49 50 private static Logger m_log = Logger.getLogger(XKMSCAService.class); 51 52 private static final InternalResources intres = InternalResources.getInstance(); 53 54 public static final float LATEST_VERSION = 1; 55 56 public static final String SERVICENAME = "XKMSCASERVICE"; 57 58 private PrivateKey xKMSkey = null; 59 private List xKMScertificatechain = null; 60 61 private XKMSCAServiceInfo info = null; 62 63 private static final String XKMSKEYSTORE = "xkmskeystore"; 64 private static final String KEYSPEC = "keyspec"; 65 private static final String KEYALGORITHM = "keyalgorithm"; 66 private static final String SUBJECTDN = "subjectdn"; 67 private static final String SUBJECTALTNAME = "subjectaltname"; 68 69 private static final String PRIVATESIGNKEYALIAS = "privatesignkeyalias"; 70 71 72 73 public XKMSCAService(ExtendedCAServiceInfo serviceinfo) { 74 m_log.debug("XKMSCAService : constructor " + serviceinfo.getStatus()); 75 CertTools.installBCProvider(); 76 XKMSCAServiceInfo info = (XKMSCAServiceInfo) serviceinfo; 78 data = new HashMap (); 79 data.put(EXTENDEDCASERVICETYPE, new Integer (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 (LATEST_VERSION)); 88 } 89 90 public XKMSCAService(HashMap data) throws IllegalArgumentException , IllegalKeyStoreException { 91 CertTools.installBCProvider(); 92 loadData(data); 93 if(data.get(XKMSKEYSTORE) != null){ 94 String keystorepass = ServiceLocator.getInstance().getString("java:comp/env/XKMSKeyStorePass"); 96 if (keystorepass == null) 97 throw new IllegalArgumentException ("Missing XKMSKeyStorePass property."); 98 99 try { 100 m_log.debug("Loading XKMS keystore"); 101 KeyStore keystore=KeyStore.getInstance("PKCS12", "BC"); 102 keystore.load(new java.io.ByteArrayInputStream (Base64.decode(((String ) data.get(XKMSKEYSTORE)).getBytes())),keystorepass.toCharArray()); 103 m_log.debug("Finished loading XKMS keystore"); 104 105 this.xKMSkey = (PrivateKey ) keystore.getKey(PRIVATESIGNKEYALIAS, null); 106 this.xKMScertificatechain = CertTools.getCertCollectionFromArray(keystore.getCertificateChain(PRIVATESIGNKEYALIAS), "SUN"); 110 this.info = new XKMSCAServiceInfo(getStatus(), 111 getSubjectDN(), 112 getSubjectAltName(), 113 (String )data.get(KEYSPEC), 114 (String ) data.get(KEYALGORITHM), 115 this.xKMScertificatechain); 116 117 } catch (Exception e) { 118 throw new IllegalKeyStoreException(e); 119 } 120 121 data.put(EXTENDEDCASERVICETYPE, new Integer (ExtendedCAServiceInfo.TYPE_XKMSEXTENDEDSERVICE)); 122 } 123 } 124 125 126 127 130 public void init(CA ca) throws Exception { 131 m_log.debug("XKMSCAService : init "); 132 String keystorepass = ServiceLocator.getInstance().getString("java:comp/env/XKMSKeyStorePass"); 134 if (keystorepass == null) 135 throw new IllegalArgumentException ("Missing XKMSKeyStorePass property."); 136 137 XKMSCAServiceInfo info = (XKMSCAServiceInfo) getExtendedCAServiceInfo(); 139 140 KeyStore keystore = KeyStore.getInstance("PKCS12", "BC"); 142 keystore.load(null, null); 143 144 KeyPair xKMSkeys = KeyTools.genKeys(info.getKeySpec(), info.getKeyAlgorithm()); 145 146 Certificate 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, ca.getValidity(), 156 new XKMSCertificateProfile()); 157 158 xKMScertificatechain = new ArrayList (); 159 xKMScertificatechain.add(xKMSCertificate); 160 xKMScertificatechain.addAll(ca.getCertificateChain()); 161 this.xKMSkey = xKMSkeys.getPrivate(); 162 163 keystore.setKeyEntry(PRIVATESIGNKEYALIAS,xKMSkeys.getPrivate(),null,(Certificate []) xKMScertificatechain.toArray(new Certificate [xKMScertificatechain.size()])); 164 java.io.ByteArrayOutputStream baos = new java.io.ByteArrayOutputStream (); 165 keystore.store(baos, keystorepass.toCharArray()); 166 data.put(XKMSKEYSTORE, new String (Base64.encode(baos.toByteArray()))); 167 169 setStatus(info.getStatus()); 170 this.info = new XKMSCAServiceInfo(info.getStatus(), 171 getSubjectDN(), 172 getSubjectAltName(), 173 (String )data.get(KEYSPEC), 174 (String ) data.get(KEYALGORITHM), 175 xKMScertificatechain); 176 177 } 178 179 182 public void update(ExtendedCAServiceInfo serviceinfo, CA ca) throws Exception { 183 XKMSCAServiceInfo info = (XKMSCAServiceInfo) serviceinfo; 184 m_log.debug("XKMSCAService : update " + serviceinfo.getStatus()); 185 setStatus(serviceinfo.getStatus()); 186 if(info.getRenewFlag()){ 187 this.init(ca); 189 } 190 191 this.info = new XKMSCAServiceInfo(serviceinfo.getStatus(), 193 getSubjectDN(), 194 getSubjectAltName(), 195 (String ) data.get(KEYSPEC), 196 (String ) data.get(KEYALGORITHM), 197 xKMScertificatechain); 198 199 } 200 201 202 203 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 msg = intres.getLocalizedMessage("caservice.notactive"); 213 m_log.error(msg); 214 throw new ExtendedCAServiceNotActiveException(msg); 215 } 216 ExtendedCAServiceResponse returnval = null; 217 X509Certificate signerCert = (X509Certificate ) xKMScertificatechain.get(0); 218 XKMSCAServiceRequest xKMSServiceReq = (XKMSCAServiceRequest)request; 219 220 Document 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 254 255 data.put(VERSION, new Float (LATEST_VERSION)); 256 } 257 } 258 259 262 public ExtendedCAServiceInfo getExtendedCAServiceInfo() { 263 if(info == null){ 264 info = new XKMSCAServiceInfo(getStatus(), 265 getSubjectDN(), 266 getSubjectAltName(), 267 (String ) data.get(KEYSPEC), 268 (String ) data.get(KEYALGORITHM), 269 xKMScertificatechain); 270 } 271 272 return this.info; 273 } 274 275 276 public String getSubjectDN(){ 277 String retval = null; 278 String str = (String )data.get(SUBJECTDN); 279 try { 280 retval = new String (Base64.decode((str).getBytes("UTF-8"))); 281 } catch (UnsupportedEncodingException e) { 282 m_log.error("Could not decode XKMS data from Base64",e); 283 } catch (ArrayIndexOutOfBoundsException e) { 284 m_log.debug("Old non base64 encoded DN: "+str); 286 retval = str; 287 } 288 289 return retval; 290 } 291 292 public void setSubjectDN(String dn){ 293 294 try { 295 data.put(SUBJECTDN,new String (Base64.encode(dn.getBytes("UTF-8"),false))); 296 } catch (UnsupportedEncodingException e) { 297 m_log.error("Could not encode XKMS data from Base64",e); 298 } 299 } 300 301 public String getSubjectAltName(){ 302 String retval = null; 303 String str= (String ) data.get(SUBJECTALTNAME); 304 try { 305 retval = new String (Base64.decode((str).getBytes("UTF-8"))); 306 } catch (UnsupportedEncodingException e) { 307 m_log.error("Could not decode XKMS data from Base64",e); 308 } catch (ArrayIndexOutOfBoundsException e) { 309 m_log.debug("Old non base64 encoded altname: "+str); 311 retval = str; 312 } 313 314 return retval; 315 } 316 317 public void setSubjectAltName(String dn){ 318 319 try { 320 data.put(SUBJECTALTNAME,new String (Base64.encode(dn.getBytes("UTF-8"), false))); 321 } catch (UnsupportedEncodingException e) { 322 m_log.error("Could not encode XKMS data from Base64",e); 323 } 324 } 325 } 326 327 | Popular Tags |