KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > ejbca > core > model > ca > caadmin > X509CA


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;
15
16 import java.io.ByteArrayInputStream JavaDoc;
17 import java.io.ByteArrayOutputStream JavaDoc;
18 import java.io.IOException JavaDoc;
19 import java.io.ObjectInputStream JavaDoc;
20 import java.io.ObjectOutputStream JavaDoc;
21 import java.io.Serializable JavaDoc;
22 import java.math.BigInteger JavaDoc;
23 import java.security.InvalidKeyException JavaDoc;
24 import java.security.KeyPair JavaDoc;
25 import java.security.NoSuchAlgorithmException JavaDoc;
26 import java.security.NoSuchProviderException JavaDoc;
27 import java.security.PublicKey JavaDoc;
28 import java.security.SignatureException JavaDoc;
29 import java.security.cert.CRL JavaDoc;
30 import java.security.cert.CRLException JavaDoc;
31 import java.security.cert.CertStore JavaDoc;
32 import java.security.cert.Certificate JavaDoc;
33 import java.security.cert.CollectionCertStoreParameters JavaDoc;
34 import java.security.cert.X509CRL JavaDoc;
35 import java.security.cert.X509Certificate JavaDoc;
36 import java.util.ArrayList JavaDoc;
37 import java.util.Arrays JavaDoc;
38 import java.util.Collection JavaDoc;
39 import java.util.Date JavaDoc;
40 import java.util.HashMap JavaDoc;
41 import java.util.Iterator JavaDoc;
42 import java.util.List JavaDoc;
43 import java.util.StringTokenizer JavaDoc;
44 import java.util.Vector JavaDoc;
45
46 import org.apache.commons.lang.StringUtils;
47 import org.apache.log4j.Logger;
48 import org.bouncycastle.asn1.ASN1EncodableVector;
49 import org.bouncycastle.asn1.ASN1InputStream;
50 import org.bouncycastle.asn1.ASN1OctetString;
51 import org.bouncycastle.asn1.ASN1Sequence;
52 import org.bouncycastle.asn1.DERIA5String;
53 import org.bouncycastle.asn1.DERObjectIdentifier;
54 import org.bouncycastle.asn1.DEROctetString;
55 import org.bouncycastle.asn1.DERSequence;
56 import org.bouncycastle.asn1.DERTaggedObject;
57 import org.bouncycastle.asn1.DERUTF8String;
58 import org.bouncycastle.asn1.x509.Attribute;
59 import org.bouncycastle.asn1.x509.AuthorityInformationAccess;
60 import org.bouncycastle.asn1.x509.AuthorityKeyIdentifier;
61 import org.bouncycastle.asn1.x509.BasicConstraints;
62 import org.bouncycastle.asn1.x509.CRLDistPoint;
63 import org.bouncycastle.asn1.x509.CRLNumber;
64 import org.bouncycastle.asn1.x509.DisplayText;
65 import org.bouncycastle.asn1.x509.DistributionPoint;
66 import org.bouncycastle.asn1.x509.DistributionPointName;
67 import org.bouncycastle.asn1.x509.ExtendedKeyUsage;
68 import org.bouncycastle.asn1.x509.GeneralName;
69 import org.bouncycastle.asn1.x509.GeneralNames;
70 import org.bouncycastle.asn1.x509.PolicyInformation;
71 import org.bouncycastle.asn1.x509.PolicyQualifierId;
72 import org.bouncycastle.asn1.x509.PolicyQualifierInfo;
73 import org.bouncycastle.asn1.x509.SubjectKeyIdentifier;
74 import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo;
75 import org.bouncycastle.asn1.x509.UserNotice;
76 import org.bouncycastle.asn1.x509.X509DefaultEntryConverter;
77 import org.bouncycastle.asn1.x509.X509Extensions;
78 import org.bouncycastle.asn1.x509.X509Name;
79 import org.bouncycastle.asn1.x509.X509NameEntryConverter;
80 import org.bouncycastle.asn1.x509.X509ObjectIdentifiers;
81 import org.bouncycastle.asn1.x509.qualified.ETSIQCObjectIdentifiers;
82 import org.bouncycastle.asn1.x509.qualified.Iso4217CurrencyCode;
83 import org.bouncycastle.asn1.x509.qualified.MonetaryValue;
84 import org.bouncycastle.asn1.x509.qualified.QCStatement;
85 import org.bouncycastle.asn1.x509.qualified.RFC3739QCObjectIdentifiers;
86 import org.bouncycastle.asn1.x509.qualified.SemanticsInformation;
87 import org.bouncycastle.cms.CMSEnvelopedData;
88 import org.bouncycastle.cms.CMSEnvelopedDataGenerator;
89 import org.bouncycastle.cms.CMSProcessable;
90 import org.bouncycastle.cms.CMSProcessableByteArray;
91 import org.bouncycastle.cms.CMSSignedData;
92 import org.bouncycastle.cms.CMSSignedDataGenerator;
93 import org.bouncycastle.cms.CMSSignedGenerator;
94 import org.bouncycastle.cms.RecipientInformation;
95 import org.bouncycastle.cms.RecipientInformationStore;
96 import org.bouncycastle.jce.X509KeyUsage;
97 import org.bouncycastle.x509.X509V2CRLGenerator;
98 import org.bouncycastle.x509.X509V3CertificateGenerator;
99 import org.ejbca.core.ejb.ca.sign.SernoGenerator;
100 import org.ejbca.core.model.InternalResources;
101 import org.ejbca.core.model.SecConst;
102 import org.ejbca.core.model.ca.SignRequestSignatureException;
103 import org.ejbca.core.model.ca.caadmin.extendedcaservices.CmsCAService;
104 import org.ejbca.core.model.ca.caadmin.extendedcaservices.CmsCAServiceInfo;
105 import org.ejbca.core.model.ca.caadmin.extendedcaservices.ExtendedCAServiceInfo;
106 import org.ejbca.core.model.ca.caadmin.extendedcaservices.ExtendedCAServiceNotActiveException;
107 import org.ejbca.core.model.ca.caadmin.extendedcaservices.ExtendedCAServiceRequest;
108 import org.ejbca.core.model.ca.caadmin.extendedcaservices.ExtendedCAServiceRequestException;
109 import org.ejbca.core.model.ca.caadmin.extendedcaservices.ExtendedCAServiceResponse;
110 import org.ejbca.core.model.ca.caadmin.extendedcaservices.IllegalExtendedCAServiceRequestException;
111 import org.ejbca.core.model.ca.caadmin.extendedcaservices.OCSPCAServiceRequest;
112 import org.ejbca.core.model.ca.caadmin.extendedcaservices.XKMSCAService;
113 import org.ejbca.core.model.ca.caadmin.extendedcaservices.XKMSCAServiceInfo;
114 import org.ejbca.core.model.ca.catoken.CAToken;
115 import org.ejbca.core.model.ca.catoken.CATokenConstants;
116 import org.ejbca.core.model.ca.catoken.CATokenOfflineException;
117 import org.ejbca.core.model.ca.catoken.NullCAToken;
118 import org.ejbca.core.model.ca.certextensions.CertificateExtension;
119 import org.ejbca.core.model.ca.certextensions.CertificateExtensionFactory;
120 import org.ejbca.core.model.ca.certificateprofiles.CertificateProfile;
121 import org.ejbca.core.model.ca.crl.RevokedCertInfo;
122 import org.ejbca.core.model.ra.UserDataVO;
123 import org.ejbca.util.CertTools;
124 import org.ejbca.util.cert.PrintableStringEntryConverter;
125 import org.ejbca.util.cert.SubjectDirAttrExtension;
126
127
128
129
130 /**
131  * X509CA is a implementation of a CA and holds data specific for Certificate and CRL generation
132  * according to the X509 standard.
133  *
134  * @version $Id: X509CA.java,v 1.50.2.8 2007/08/09 09:10:30 anatom Exp $
135  */

136 public class X509CA extends CA implements Serializable JavaDoc {
137
138     private static final Logger log = Logger.getLogger(X509CA.class);
139
140     /** Internal localization of logs and errors */
141     private static final InternalResources intres = InternalResources.getInstance();
142
143     // Default Values
144
public static final float LATEST_VERSION = 11;
145
146     private byte[] keyId = new byte[] { 1, 2, 3, 4, 5 };
147     
148     
149     // protected fields.
150
protected static final String JavaDoc POLICYID = "policyid";
151     protected static final String JavaDoc SUBJECTALTNAME = "subjectaltname";
152     protected static final String JavaDoc USEAUTHORITYKEYIDENTIFIER = "useauthoritykeyidentifier";
153     protected static final String JavaDoc AUTHORITYKEYIDENTIFIERCRITICAL = "authoritykeyidentifiercritical";
154     protected static final String JavaDoc USECRLNUMBER = "usecrlnumber";
155     protected static final String JavaDoc CRLNUMBERCRITICAL = "crlnumbercritical";
156     protected static final String JavaDoc DEFAULTCRLDISTPOINT = "defaultcrldistpoint";
157     protected static final String JavaDoc DEFAULTCRLISSUER = "defaultcrlissuer";
158     protected static final String JavaDoc DEFAULTOCSPSERVICELOCATOR = "defaultocspservicelocator";
159     protected static final String JavaDoc USEUTF8POLICYTEXT = "useutf8policytext";
160     protected static final String JavaDoc USEPRINTABLESTRINGSUBJECTDN = "useprintablestringsubjectdn";
161
162     // Public Methods
163
/** Creates a new instance of CA, this constuctor should be used when a new CA is created */
164     public X509CA(X509CAInfo cainfo) {
165       super(cainfo);
166       
167       data.put(POLICYID, cainfo.getPolicyId());
168       data.put(SUBJECTALTNAME, cainfo.getSubjectAltName());
169       setUseAuthorityKeyIdentifier(cainfo.getUseAuthorityKeyIdentifier());
170       setAuthorityKeyIdentifierCritical(cainfo.getAuthorityKeyIdentifierCritical());
171       setUseCRLNumber(cainfo.getUseCRLNumber());
172       setCRLNumberCritical(cainfo.getCRLNumberCritical());
173       setDefaultCRLDistPoint(cainfo.getDefaultCRLDistPoint());
174       setDefaultCRLIssuer(cainfo.getDefaultCRLIssuer());
175       setDefaultOCSPServiceLocator(cainfo.getDefaultOCSPServiceLocator());
176       setFinishUser(cainfo.getFinishUser());
177       setUseUTF8PolicyText(cainfo.getUseUTF8PolicyText());
178       setUsePrintableStringSubjectDN(cainfo.getUsePrintableStringSubjectDN());
179       
180       data.put(CA.CATYPE, new Integer JavaDoc(CAInfo.CATYPE_X509));
181       data.put(VERSION, new Float JavaDoc(LATEST_VERSION));
182     }
183     
184    /** Constructor used when retrieving existing X509CA from database.
185  * @throws IllegalKeyStoreException */

186     public X509CA(HashMap JavaDoc data, int caId, String JavaDoc subjectDN, String JavaDoc name, int status, Date JavaDoc updateTime) throws IllegalKeyStoreException{
187         super(data);
188         ArrayList JavaDoc externalcaserviceinfos = new ArrayList JavaDoc();
189         Iterator JavaDoc iter = getExternalCAServiceTypes().iterator();
190         while(iter.hasNext()){
191             ExtendedCAServiceInfo info = this.getExtendedCAServiceInfo(((Integer JavaDoc) iter.next()).intValue());
192             if (info != null) {
193                 externalcaserviceinfos.add(info);
194             }
195         }
196         CAInfo info = new X509CAInfo(subjectDN, name, status, updateTime, getSubjectAltName() ,getCertificateProfileId(),
197                   getValidity(), getExpireTime(), getCAType(), getSignedBy(), getCertificateChain(),
198                   getCAToken(caId).getCATokenInfo(), getDescription(), getRevokationReason(), getRevokationDate(), getPolicyId(), getCRLPeriod(), getCRLIssueInterval(), getCRLOverlapTime(), getCRLPublishers(),
199                   getUseAuthorityKeyIdentifier(), getAuthorityKeyIdentifierCritical(),
200                   getUseCRLNumber(), getCRLNumberCritical(), getDefaultCRLDistPoint(), getDefaultCRLIssuer(), getDefaultOCSPServiceLocator(), getFinishUser(), externalcaserviceinfos,
201                   getUseUTF8PolicyText(), getApprovalSettings(), getNumOfRequiredApprovals(), getUsePrintableStringSubjectDN());
202         super.setCAInfo(info);
203     }
204
205     // Public Methods.
206
public String JavaDoc getPolicyId(){ return (String JavaDoc) data.get(POLICYID);}
207     public void setPolicyId(String JavaDoc policyid){ data.put(POLICYID, policyid);}
208     
209     public String JavaDoc getSubjectAltName() { return (String JavaDoc) data.get(SUBJECTALTNAME);}
210     
211     public boolean getUseAuthorityKeyIdentifier(){
212       return ((Boolean JavaDoc)data.get(USEAUTHORITYKEYIDENTIFIER)).booleanValue();
213     }
214     public void setUseAuthorityKeyIdentifier(boolean useauthoritykeyidentifier) {
215       data.put(USEAUTHORITYKEYIDENTIFIER, Boolean.valueOf(useauthoritykeyidentifier));
216     }
217     
218     public boolean getAuthorityKeyIdentifierCritical(){
219       return ((Boolean JavaDoc)data.get(AUTHORITYKEYIDENTIFIERCRITICAL)).booleanValue();
220     }
221     public void setAuthorityKeyIdentifierCritical(boolean authoritykeyidentifiercritical) {
222       data.put(AUTHORITYKEYIDENTIFIERCRITICAL, Boolean.valueOf(authoritykeyidentifiercritical));
223     }
224
225     public boolean getUseCRLNumber(){return ((Boolean JavaDoc)data.get(USECRLNUMBER)).booleanValue();}
226     public void setUseCRLNumber(boolean usecrlnumber) {data.put(USECRLNUMBER, Boolean.valueOf(usecrlnumber));}
227     
228     public boolean getCRLNumberCritical(){return ((Boolean JavaDoc)data.get(CRLNUMBERCRITICAL)).booleanValue();}
229     public void setCRLNumberCritical(boolean crlnumbercritical) {data.put(CRLNUMBERCRITICAL, Boolean.valueOf(crlnumbercritical));}
230     
231     public String JavaDoc getDefaultCRLDistPoint(){return (String JavaDoc) data.get(DEFAULTCRLDISTPOINT);}
232     public void setDefaultCRLDistPoint(String JavaDoc defailtcrldistpoint) {
233         if(defailtcrldistpoint == null){
234             data.put(DEFAULTCRLDISTPOINT, "");
235         }else{
236             data.put(DEFAULTCRLDISTPOINT, defailtcrldistpoint);
237         }
238     }
239     public String JavaDoc getDefaultCRLIssuer(){return (String JavaDoc) data.get(DEFAULTCRLISSUER);}
240     public void setDefaultCRLIssuer(String JavaDoc defailtcrlissuer) {
241         if(defailtcrlissuer == null){
242             data.put(DEFAULTCRLISSUER, "");
243         }else{
244             data.put(DEFAULTCRLISSUER, defailtcrlissuer);
245         }
246     }
247     
248     public String JavaDoc getDefaultOCSPServiceLocator(){return (String JavaDoc) data.get(DEFAULTOCSPSERVICELOCATOR);}
249     public void setDefaultOCSPServiceLocator(String JavaDoc defaultocsplocator) {
250         if(defaultocsplocator == null){
251             data.put(DEFAULTOCSPSERVICELOCATOR, "");
252         }else{
253             data.put(DEFAULTOCSPSERVICELOCATOR, defaultocsplocator);
254         }
255     }
256
257     public boolean getUseUTF8PolicyText(){
258         return ((Boolean JavaDoc)data.get(USEUTF8POLICYTEXT)).booleanValue();
259       }
260       public void setUseUTF8PolicyText(boolean useutf8) {
261         data.put(USEUTF8POLICYTEXT, Boolean.valueOf(useutf8));
262       }
263
264
265       public boolean getUsePrintableStringSubjectDN(){
266           return ((Boolean JavaDoc)data.get(USEPRINTABLESTRINGSUBJECTDN)).booleanValue();
267       }
268       public void setUsePrintableStringSubjectDN(boolean useprintablestring) {
269           data.put(USEPRINTABLESTRINGSUBJECTDN, Boolean.valueOf(useprintablestring));
270       }
271     
272       public void updateCA(CAInfo cainfo) throws Exception JavaDoc{
273           super.updateCA(cainfo);
274           X509CAInfo info = (X509CAInfo) cainfo;
275           
276           setUseAuthorityKeyIdentifier(info.getUseAuthorityKeyIdentifier());
277           setAuthorityKeyIdentifierCritical(info.getAuthorityKeyIdentifierCritical());
278           setUseCRLNumber(info.getUseCRLNumber());
279           setCRLNumberCritical(info.getCRLNumberCritical());
280           setDefaultCRLDistPoint(info.getDefaultCRLDistPoint());
281           setDefaultCRLIssuer(info.getDefaultCRLIssuer());
282           setDefaultOCSPServiceLocator(info.getDefaultOCSPServiceLocator());
283           setUseUTF8PolicyText(info.getUseUTF8PolicyText());
284           setUsePrintableStringSubjectDN(info.getUsePrintableStringSubjectDN());
285
286       }
287     
288
289     public byte[] createPKCS7(Certificate JavaDoc cert, boolean includeChain) throws SignRequestSignatureException {
290         // First verify that we signed this certificate
291
try {
292             if (cert != null)
293                 cert.verify(getCAToken().getPublicKey(SecConst.CAKEYPURPOSE_CERTSIGN));
294         } catch (Exception JavaDoc e) {
295             throw new SignRequestSignatureException("Cannot verify certificate in createPKCS7(), did I sign this?");
296         }
297         Collection JavaDoc chain = getCertificateChain();
298         ArrayList JavaDoc certList = new ArrayList JavaDoc();
299         if (cert != null) {
300             certList.add(cert);
301         }
302         if (includeChain) {
303             certList.addAll(chain);
304         }
305         try {
306             CMSProcessable msg = new CMSProcessableByteArray("EJBCA".getBytes());
307             CertStore JavaDoc certs = CertStore.getInstance("Collection", new CollectionCertStoreParameters JavaDoc(certList), "BC");
308             CMSSignedDataGenerator gen = new CMSSignedDataGenerator();
309             if (getCAToken().getPrivateKey(SecConst.CAKEYPURPOSE_CERTSIGN) == null) {
310                 String JavaDoc msg1 = "createPKCS7: Private key does not exist!";
311                 log.debug(msg1);
312                 throw new SignRequestSignatureException(msg1);
313             }
314             gen.addSigner(getCAToken().getPrivateKey(SecConst.CAKEYPURPOSE_CERTSIGN), (X509Certificate JavaDoc)getCACertificate(), CMSSignedGenerator.DIGEST_SHA1);
315             gen.addCertificatesAndCRLs(certs);
316             CMSSignedData s = null;
317             CAToken catoken = getCAToken();
318             if (catoken != null && !(catoken instanceof NullCAToken)) {
319                 log.debug("createPKCS7: Provider="+catoken.getProvider()+" using algorithm "+getCAToken().getPrivateKey(SecConst.CAKEYPURPOSE_CERTSIGN).getAlgorithm());
320                 s = gen.generate(msg, true, catoken.getProvider());
321             } else {
322                 String JavaDoc msg1 = "CA Token does not exist!";
323                 log.debug(msg);
324                 throw new SignRequestSignatureException(msg1);
325             }
326             return s.getEncoded();
327         } catch (CATokenOfflineException e) {
328             throw new javax.ejb.EJBException JavaDoc(e);
329         } catch (Exception JavaDoc e) {
330             throw new javax.ejb.EJBException JavaDoc(e);
331         }
332     }
333     
334     
335     public Certificate JavaDoc generateCertificate(UserDataVO subject,
336                                            PublicKey JavaDoc publicKey,
337                                            int keyusage,
338                                            Date JavaDoc notBefore,
339                                            Date JavaDoc notAfter,
340                                            CertificateProfile certProfile) throws Exception JavaDoc{
341                                                
342                 
343         final String JavaDoc sigAlg = getCAToken().getCATokenInfo().getSignatureAlgorithm();
344         Date JavaDoc firstDate = new Date JavaDoc();
345         // Set back startdate ten minutes to avoid some problems with wrongly set clocks.
346
firstDate.setTime(firstDate.getTime() - 10 * 60 * 1000);
347         Date JavaDoc lastDate = new Date JavaDoc();
348         if ( (notBefore != null) && (certProfile.getAllowValidityOverride()) ) {
349             // If we allow the client (or ra) to specify the startdate
350
firstDate = notBefore;
351             if (log.isDebugEnabled()) {
352                 log.debug("Using notBefore validity from request: "+firstDate);
353             }
354         }
355         if ( (notAfter == null) || (!certProfile.getAllowValidityOverride()) ) {
356             // validity in days = validity*24*60*60*1000 milliseconds
357
long val = certProfile.getValidity();
358             if (log.isDebugEnabled()) {
359                 log.debug("Using validity from profile: "+val);
360             }
361             lastDate.setTime(lastDate.getTime() + ( val * 24 * 60 * 60 * 1000));
362         } else {
363             // only if not null and we allow validity override
364
lastDate = notAfter;
365             if (log.isDebugEnabled()) {
366                 log.debug("Using notAfter validity from request: "+lastDate);
367             }
368         }
369         // Do not allow last date to be before first date
370
if (!lastDate.after(firstDate)) {
371             // Setting it to the same is silly as well but what the heck
372
lastDate = firstDate;
373         }
374         X509Certificate JavaDoc cacert = (X509Certificate JavaDoc)getCACertificate();
375
376         String JavaDoc dn = subject.getDN();
377         // Check if this is a root CA we are creating
378
boolean isRootCA = false;
379         if (certProfile.getType() == CertificateProfile.TYPE_ROOTCA) {
380             isRootCA = true;
381         }
382
383         // If our desired after date is after the CA expires, we will not allow this
384
// The CA will only issue certificates with maximum the same validity time as it-self
385
// We will not limit validity of a self signed cert (RootCA), because it is a renewal.
386
if ( !isRootCA ) {
387             if (lastDate.after(cacert.getNotAfter())) {
388                 String JavaDoc msg = intres.getLocalizedMessage("signsession.limitingvalidity", lastDate.toString(), cacert.getNotAfter());
389                 log.info(msg);
390                 lastDate = cacert.getNotAfter();
391             }
392         }
393         X509V3CertificateGenerator certgen = new X509V3CertificateGenerator();
394         // Serialnumber is random bits, where random generator is initialized by the
395
// serno generator.
396
BigInteger JavaDoc serno = SernoGenerator.instance().getSerno();
397         certgen.setSerialNumber(serno);
398         certgen.setNotBefore(firstDate);
399         certgen.setNotAfter(lastDate);
400         certgen.setSignatureAlgorithm(sigAlg);
401
402         // Make DNs
403
if(certProfile.getUseSubjectDNSubSet()){
404           dn= certProfile.createSubjectDNSubSet(dn);
405         }
406         
407         if(certProfile.getUseCNPostfix()){
408           dn = CertTools.insertCNPostfix(dn,certProfile.getCNPostfix());
409         }
410         
411         String JavaDoc altName = subject.getSubjectAltName();
412         if(certProfile.getUseSubjectAltNameSubSet()){
413             altName = certProfile.createSubjectAltNameSubSet(altName);
414         }
415         
416         X509NameEntryConverter converter = null;
417         if (getUsePrintableStringSubjectDN()) {
418             converter = new PrintableStringEntryConverter();
419         } else {
420             converter = new X509DefaultEntryConverter();
421         }
422         certgen.setSubjectDN(CertTools.stringToBcX509Name(dn, converter));
423         // We must take the issuer DN directly from the CA-certificate otherwise we risk re-ordering the DN
424
// which many applications do not like.
425
if (isRootCA) {
426             // This will be an initial root CA, since no CA-certificate exists
427
// Or it is a root CA, since the cert is self signed. If it is a root CA we want to use the same encoding for subject and issuer,
428
// it might have changed over the years.
429
if (log.isDebugEnabled()) {
430                 log.debug("Using subject DN also as issuer DN, because it is a root CA");
431             }
432             X509Name caname = CertTools.stringToBcX509Name(getSubjectDN(), converter);
433             certgen.setIssuerDN(caname);
434         } else {
435             if (log.isDebugEnabled()) {
436                 log.debug("Using issuer DN directly from the CA certificate");
437             }
438             certgen.setIssuerDN(cacert.getSubjectX500Principal());
439         }
440         certgen.setPublicKey(publicKey);
441
442         // Basic constranits, all subcerts are NOT CAs
443
if (certProfile.getUseBasicConstraints() == true) {
444             BasicConstraints bc = new BasicConstraints(false);
445             if ((certProfile.getType() == CertificateProfile.TYPE_SUBCA)
446                 || (certProfile.getType() == CertificateProfile.TYPE_ROOTCA)){
447                 if(certProfile.getUsePathLengthConstraint()){
448                     bc = new BasicConstraints(certProfile.getPathLengthConstraint());
449                 }else{
450                     bc = new BasicConstraints(true);
451                 }
452             }
453                             
454             certgen.addExtension(
455                 X509Extensions.BasicConstraints.getId(),
456                 certProfile.getBasicConstraintsCritical(),
457                 bc);
458         }
459         // Key usage
460
int newKeyUsage = -1;
461         if (certProfile.getAllowKeyUsageOverride() && (keyusage >= 0)) {
462             newKeyUsage = keyusage;
463         } else {
464             newKeyUsage = CertTools.sunKeyUsageToBC(certProfile.getKeyUsage());
465         }
466         if ( (certProfile.getUseKeyUsage() == true) && (newKeyUsage >=0) ){
467             X509KeyUsage ku = new X509KeyUsage(newKeyUsage);
468             certgen.addExtension(
469                 X509Extensions.KeyUsage.getId(),
470                 certProfile.getKeyUsageCritical(),
471                 ku);
472         }
473         // Extended Key usage
474
if (certProfile.getUseExtendedKeyUsage() == true) {
475             // Get extended key usage from certificate profile
476
Collection JavaDoc c = certProfile.getExtendedKeyUsageAsOIDStrings();
477             Vector JavaDoc usage = new Vector JavaDoc();
478             Iterator JavaDoc iter = c.iterator();
479             while (iter.hasNext()) {
480                 usage.add(new DERObjectIdentifier((String JavaDoc)iter.next()));
481             }
482             // Don't add empty key usage extension
483
if (!usage.isEmpty()) {
484                 ExtendedKeyUsage eku = new ExtendedKeyUsage(usage);
485                 // Extended Key Usage may be either critical or non-critical
486
certgen.addExtension(
487                     X509Extensions.ExtendedKeyUsage.getId(),
488                     certProfile.getExtendedKeyUsageCritical(),
489                     eku);
490             }
491         }
492         // Subject key identifier
493
if (certProfile.getUseSubjectKeyIdentifier() == true) {
494             SubjectPublicKeyInfo spki =
495                 new SubjectPublicKeyInfo(
496                     (ASN1Sequence) new ASN1InputStream(new ByteArrayInputStream JavaDoc(publicKey.getEncoded())).readObject());
497             SubjectKeyIdentifier ski = new SubjectKeyIdentifier(spki);
498             certgen.addExtension(
499                 X509Extensions.SubjectKeyIdentifier.getId(),
500                 certProfile.getSubjectKeyIdentifierCritical(), ski);
501         }
502         // Authority key identifier
503
if (certProfile.getUseAuthorityKeyIdentifier() == true) {
504             AuthorityKeyIdentifier aki = null;
505             // Default value is that we calculate it from scratch!
506
// (If this is a root CA we must calculate the AuthorityKeyIdentifier from scratch)
507
// (If the CA signing this cert does not have a SubjectKeyIdentifier we must calculate the AuthorityKeyIdentifier from scratch)
508
try{
509                 byte[] keybytes = getCAToken().getPublicKey(SecConst.CAKEYPURPOSE_CERTSIGN).getEncoded();
510                 SubjectPublicKeyInfo apki = new SubjectPublicKeyInfo((ASN1Sequence) new ASN1InputStream(new ByteArrayInputStream JavaDoc(keybytes)).readObject());
511                 aki = new AuthorityKeyIdentifier(apki);
512             }catch(CATokenOfflineException e){
513                 log.debug("X509CA: CA Token Offline Exception: ", e);
514                 throw e;
515             }
516             
517             // If we have a CA-certificate (i.e. this is not a Root CA), we must take the authority key identifier from
518
// the CA-certificates SubjectKeyIdentifier if it exists. If we don't do that we will get the wrong identifier if the
519
// CA does not follow RFC3280 (guess if MS-CA follows RFC3280?)
520
if ( (cacert != null) && (!isRootCA) ) {
521                 byte[] akibytes = CertTools.getSubjectKeyId(cacert);
522                 if (akibytes != null) {
523                     // TODO: The code below is snipped from AuthorityKeyIdentifier.java in BC 1.36, because there is no method there
524
// to set only a pre-computed key identifier
525
// This should be replaced when such a method is added to BC
526
ASN1OctetString keyidentifier = new DEROctetString(akibytes);
527                     ASN1EncodableVector v = new ASN1EncodableVector();
528                     v.add(new DERTaggedObject(false, 0, keyidentifier));
529                     ASN1Sequence seq = new DERSequence(v);
530                     
531                     aki = new AuthorityKeyIdentifier(seq);
532                     log.debug("Using AuthorityKeyIdentifier from CA-certificates SubjectKeyIdentifier.");
533                 }
534             }
535             certgen.addExtension(
536                 X509Extensions.AuthorityKeyIdentifier.getId(),
537                 certProfile.getAuthorityKeyIdentifierCritical(), aki);
538         }
539         
540          // Subject Alternative name
541
if ( (certProfile.getUseSubjectAlternativeName() == true) && (altName != null) && (altName.length() > 0) ) {
542             GeneralNames san = CertTools.getGeneralNamesFromAltName(altName);
543             if (san != null) {
544                 certgen.addExtension(X509Extensions.SubjectAlternativeName.getId(), certProfile.getSubjectAlternativeNameCritical(), san);
545             }
546         }
547         
548         // Certificate Policies
549
if ( (certProfile.getUseCertificatePolicies() == true) && (StringUtils.isNotEmpty(certProfile.getCertificatePolicyId())) ) {
550             int displayencoding = DisplayText.CONTENT_TYPE_BMPSTRING;
551             if (getUseUTF8PolicyText()) {
552                 displayencoding = DisplayText.CONTENT_TYPE_UTF8STRING;
553             }
554             String JavaDoc policyId = certProfile.getCertificatePolicyId();
555             String JavaDoc cpsurl = certProfile.getCpsUrl();
556             String JavaDoc usernotice = certProfile.getUserNoticeText();
557             ASN1EncodableVector policys = new ASN1EncodableVector();
558             if (StringUtils.isNotEmpty(policyId )) {
559                 StringTokenizer JavaDoc tokenizer = new StringTokenizer JavaDoc(policyId, ";", false);
560                 while (tokenizer.hasMoreTokens()) {
561                     String JavaDoc id = tokenizer.nextToken();
562                     PolicyInformation pi = getPolicyInformation(id, cpsurl, usernotice, displayencoding);
563                     // We only support a cpsurl and usernotice on the first policyid
564
cpsurl = null;
565                     usernotice = null;
566                     if (pi != null) {
567                         policys.add(pi);
568                     }
569                 }
570                 // Add the final extension
571
DERSequence seq = new DERSequence(policys);
572                 certgen.addExtension(X509Extensions.CertificatePolicies.getId(),
573                         certProfile.getCertificatePoliciesCritical(), seq);
574             }
575         }
576
577          // CRL Distribution point URI
578
if (certProfile.getUseCRLDistributionPoint() == true) {
579              String JavaDoc crldistpoint = certProfile.getCRLDistributionPointURI();
580              String JavaDoc crlissuer=certProfile.getCRLIssuer();
581              if(certProfile.getUseDefaultCRLDistributionPoint()){
582                  crldistpoint = getDefaultCRLDistPoint();
583                  crlissuer = getDefaultCRLIssuer();
584              }
585              // Multiple CDPs are spearated with the ';' sign
586
ArrayList JavaDoc dpns = new ArrayList JavaDoc();
587             if (StringUtils.isNotEmpty(crldistpoint)) {
588                 StringTokenizer JavaDoc tokenizer = new StringTokenizer JavaDoc(crldistpoint, ";", false);
589                 while (tokenizer.hasMoreTokens()) {
590                     // 6 is URI
591
String JavaDoc uri = tokenizer.nextToken();
592                     GeneralName gn = new GeneralName(6, new DERIA5String(uri));
593                     log.debug("Added CRL distpoint: "+uri);
594                     ASN1EncodableVector vec = new ASN1EncodableVector();
595                     vec.add(gn);
596                     GeneralNames gns = new GeneralNames(new DERSequence(vec));
597                     DistributionPointName dpn = new DistributionPointName(0, gns);
598                     dpns.add(dpn);
599                 }
600             }
601             // CRL issuer works much like Dist point URI. If separated by ; it is put in the same global distPoint as the URI,
602
// if there is more of one of them, the one with more is put in an own global distPoint.
603
ArrayList JavaDoc issuers = new ArrayList JavaDoc();
604             if (StringUtils.isNotEmpty(crlissuer)) {
605                 StringTokenizer JavaDoc tokenizer = new StringTokenizer JavaDoc(crlissuer, ";", false);
606                 while (tokenizer.hasMoreTokens()) {
607                     String JavaDoc issuer = tokenizer.nextToken();
608                     GeneralName gn = new GeneralName(new X509Name(issuer));
609                     log.debug("Added CRL issuer: "+issuer);
610                     ASN1EncodableVector vec = new ASN1EncodableVector();
611                     vec.add(gn);
612                     GeneralNames gns = new GeneralNames(new DERSequence(vec));
613                     issuers.add(gns);
614                 }
615             }
616             ArrayList JavaDoc distpoints = new ArrayList JavaDoc();
617             if ( (issuers.size() > 0) || (dpns.size() > 0) ) {
618                 int i = dpns.size();
619                 if (issuers.size() > i) {
620                     i = issuers.size();
621                 }
622                 for (int j = 0; j < i; j++) {
623                     DistributionPointName dpn = null;
624                     GeneralNames issuer = null;
625                     if (dpns.size() > j) {
626                         dpn = (DistributionPointName)dpns.get(j);
627                     }
628                     if (issuers.size() > j) {
629                         issuer = (GeneralNames)issuers.get(j);
630                     }
631                     if ( (dpn != null) || (issuer != null) ) {
632                         distpoints.add(new DistributionPoint(dpn, null, issuer));
633                     }
634                 }
635             }
636             if (distpoints.size() > 0) {
637                 CRLDistPoint ext = new CRLDistPoint((DistributionPoint[])distpoints.toArray(new DistributionPoint[0]));
638                 certgen.addExtension(X509Extensions.CRLDistributionPoints.getId(),
639                     certProfile.getCRLDistributionPointCritical(), ext);
640             }
641          }
642          // Authority Information Access (OCSP url)
643
if (certProfile.getUseOCSPServiceLocator() == true) {
644              String JavaDoc ocspUrl = certProfile.getOCSPServiceLocatorURI();
645              if(certProfile.getUseDefaultOCSPServiceLocator()){
646                  ocspUrl = getDefaultOCSPServiceLocator();
647              }
648              if (StringUtils.isNotEmpty(ocspUrl)) {
649                  // OCSP access location is a URL (GeneralName no 6)
650
GeneralName ocspLocation = new GeneralName(6, new DERIA5String(ocspUrl));
651                  certgen.addExtension(X509Extensions.AuthorityInfoAccess.getId(),
652                      false, new AuthorityInformationAccess(X509ObjectIdentifiers.ocspAccessMethod, ocspLocation));
653              }
654          }
655          
656          // Microsoft Template
657
if (certProfile.getUseMicrosoftTemplate() == true) {
658              String JavaDoc mstemplate = certProfile.getMicrosoftTemplate();
659              DERObjectIdentifier oid = new DERObjectIdentifier(CertTools.OID_MSTEMPLATE);
660              certgen.addExtension(oid, false, new DERIA5String(mstemplate));
661          }
662          
663          // QCStatement (rfc3739)
664
if (certProfile.getUseQCStatement() == true) {
665              String JavaDoc names = certProfile.getQCStatementRAName();
666              GeneralNames san = CertTools.getGeneralNamesFromAltName(names);
667              SemanticsInformation si = null;
668              if (san != null) {
669                  if (StringUtils.isNotEmpty(certProfile.getQCSemanticsId())) {
670                      si = new SemanticsInformation(new DERObjectIdentifier(certProfile.getQCSemanticsId()), san.getNames());
671                  } else {
672                      si = new SemanticsInformation(san.getNames());
673                  }
674              } else if (StringUtils.isNotEmpty(certProfile.getQCSemanticsId())) {
675                  si = new SemanticsInformation(new DERObjectIdentifier(certProfile.getQCSemanticsId()));
676              }
677              ArrayList JavaDoc qcs = new ArrayList JavaDoc();
678              QCStatement qc = null;
679              // First the standard rfc3739 QCStatement with an optional SematicsInformation
680
DERObjectIdentifier pkixQcSyntax = RFC3739QCObjectIdentifiers.id_qcs_pkixQCSyntax_v1;
681              if (certProfile.getUsePkixQCSyntaxV2()) {
682                  pkixQcSyntax = RFC3739QCObjectIdentifiers.id_qcs_pkixQCSyntax_v2;
683              }
684              if ( (si != null) ) {
685                  qc = new QCStatement(pkixQcSyntax, si);
686                  qcs.add(qc);
687              } else {
688                  qc = new QCStatement(pkixQcSyntax);
689                  qcs.add(qc);
690              }
691              // ETSI Statement that the certificate is a Qualified Certificate
692
if (certProfile.getUseQCEtsiQCCompliance()) {
693                  qc = new QCStatement(ETSIQCObjectIdentifiers.id_etsi_qcs_QcCompliance);
694                  qcs.add(qc);
695              }
696              // ETSI Statement regarding limit on the value of transactions
697
if (certProfile.getUseQCEtsiValueLimit()) {
698                  // Both value and currency must be availabel for this extension
699
if ( (certProfile.getQCEtsiValueLimit() > 0) && (certProfile.getQCEtsiValueLimitCurrency() != null) ) {
700                      int limit = certProfile.getQCEtsiValueLimit();
701                      // The exponent should be default 0
702
int exponent = certProfile.getQCEtsiValueLimitExp();
703                      MonetaryValue value = new MonetaryValue(new Iso4217CurrencyCode(certProfile.getQCEtsiValueLimitCurrency()), limit, exponent);
704                      qc = new QCStatement(ETSIQCObjectIdentifiers.id_etsi_qcs_LimiteValue, value);
705                      qcs.add(qc);
706                  }
707              }
708              // ETSI Statement claiming that the private key resides in a Signature Creation Device
709
if (certProfile.getUseQCEtsiSignatureDevice()) {
710                  qc = new QCStatement(ETSIQCObjectIdentifiers.id_etsi_qcs_QcSSCD);
711                  qcs.add(qc);
712              }
713              // Custom UTF8String QC-statement:
714
// qcStatement-YourCustom QC-STATEMENT ::= { SYNTAX YourCustomUTF8String
715
// IDENTIFIED BY youroid }
716
// -- This statement gives you the possibility to define your own QC-statement
717
// -- using an OID and a simple UTF8String, with describing text. A sample text could for example be:
718
// -- This certificate, according to Act. No. xxxx Electronic Signature Law is a qualified electronic certificate
719
//
720
// YourCustomUTF8String ::= UTF8String
721
if (certProfile.getUseQCCustomString()) {
722                  if (!StringUtils.isEmpty(certProfile.getQCCustomStringOid()) && !StringUtils.isEmpty(certProfile.getQCCustomStringText())) {
723                      DERUTF8String str = new DERUTF8String(certProfile.getQCCustomStringText());
724                      DERObjectIdentifier oid = new DERObjectIdentifier(certProfile.getQCCustomStringOid());
725                      qc = new QCStatement(oid, str);
726                      qcs.add(qc);
727                  }
728              }
729              if (qcs.size() > 0) {
730                  ASN1EncodableVector vec = new ASN1EncodableVector();
731                  Iterator JavaDoc iter = qcs.iterator();
732                  while (iter.hasNext()) {
733                      QCStatement q = (QCStatement)iter.next();
734                      vec.add(q);
735                  }
736                  certgen.addExtension(CertTools.QCSTATEMENTS_OBJECTID, certProfile.getQCStatementCritical(), new DERSequence(vec));
737              }
738          }
739          
740          // Subject Directory Attributes
741
if (certProfile.getUseSubjectDirAttributes() == true) {
742              // Get the attributes from ExtendedInformation
743
String JavaDoc dirAttrString = subject.getExtendedinformation().getSubjectDirectoryAttributes();
744              if (StringUtils.isNotEmpty(dirAttrString)) {
745                  // Subject Directory Attributes is a sequence of Attribute
746
Collection JavaDoc attr = SubjectDirAttrExtension.getSubjectDirectoryAttributes(dirAttrString);
747                  ASN1EncodableVector vec = new ASN1EncodableVector();
748                  Iterator JavaDoc iter = attr.iterator();
749                  while (iter.hasNext()) {
750                      Attribute a = (Attribute)iter.next();
751                      vec.add(a);
752                  }
753                  // Subject Directory Attributes must always be non-critical
754
certgen.addExtension(X509Extensions.SubjectDirectoryAttributes, false, new DERSequence(vec));
755              }
756              
757          }
758
759          // Check for Certificate Extensions
760
CertificateExtensionFactory fact = CertificateExtensionFactory.getInstance();
761          List JavaDoc usedCertExt = certProfile.getUsedCertificateExtensions();
762          Iterator JavaDoc certExtIter = usedCertExt.iterator();
763          while(certExtIter.hasNext()){
764              Integer JavaDoc id = (Integer JavaDoc) certExtIter.next();
765              CertificateExtension certExt = fact.getCertificateExtensions(id);
766              certgen.addExtension(new DERObjectIdentifier(certExt.getOID()),certExt.isCriticalFlag(),certExt.getValue(subject, this, certProfile));
767          }
768          
769          X509Certificate JavaDoc cert;
770          try{
771            cert = certgen.generate(getCAToken().getPrivateKey(SecConst.CAKEYPURPOSE_CERTSIGN),
772                                             getCAToken().getProvider());
773          }catch(CATokenOfflineException e){
774              log.debug("X509CA : CA Token STATUS OFFLINE: ", e);
775              throw e;
776          }
777         
778         // Verify before returning
779
cert.verify(getCAToken().getPublicKey(SecConst.CAKEYPURPOSE_CERTSIGN));
780         log.debug(">X509CA: generate certificate, CA "+ this.getCAId() + " for DN: " + subject.getDN());
781       return cert;
782     }
783
784     
785     public CRL JavaDoc generateCRL(Vector JavaDoc certs, int crlnumber)
786     throws CATokenOfflineException, IllegalKeyStoreException, IOException JavaDoc, SignatureException JavaDoc, NoSuchProviderException JavaDoc, InvalidKeyException JavaDoc, CRLException JavaDoc, NoSuchAlgorithmException JavaDoc {
787         final String JavaDoc sigAlg= getCAToken().getCATokenInfo().getSignatureAlgorithm();
788
789         Date JavaDoc thisUpdate = new Date JavaDoc();
790         Date JavaDoc nextUpdate = new Date JavaDoc();
791
792         // crlperiod is hours = crlperiod*60*60*1000 milliseconds
793
nextUpdate.setTime(nextUpdate.getTime() + (getCRLPeriod() * (long)(60 * 60 * 1000)));
794         X509V2CRLGenerator crlgen = new X509V2CRLGenerator();
795         crlgen.setThisUpdate(thisUpdate);
796         crlgen.setNextUpdate(nextUpdate);
797         crlgen.setSignatureAlgorithm(sigAlg);
798         // Make DNs
799
X509Certificate JavaDoc cacert = (X509Certificate JavaDoc)getCACertificate();
800         if (cacert == null) {
801             // This is an initial root CA, since no CA-certificate exists
802
X509Name caname = CertTools.stringToBcX509Name(getSubjectDN());
803             crlgen.setIssuerDN(caname);
804         } else {
805             crlgen.setIssuerDN(cacert.getSubjectX500Principal());
806         }
807         if (certs != null) {
808             Iterator JavaDoc it = certs.iterator();
809             while( it.hasNext() ) {
810                 RevokedCertInfo certinfo = (RevokedCertInfo)it.next();
811                 crlgen.addCRLEntry(certinfo.getUserCertificate(), certinfo.getRevocationDate(), certinfo.getReason());
812             }
813         }
814
815         // Authority key identifier
816
if (getUseAuthorityKeyIdentifier() == true) {
817             SubjectPublicKeyInfo apki = new SubjectPublicKeyInfo((ASN1Sequence)new ASN1InputStream(
818                 new ByteArrayInputStream JavaDoc(getCAToken().getPublicKey(SecConst.CAKEYPURPOSE_CRLSIGN).getEncoded())).readObject());
819             AuthorityKeyIdentifier aki = new AuthorityKeyIdentifier(apki);
820             crlgen.addExtension(X509Extensions.AuthorityKeyIdentifier.getId(), getAuthorityKeyIdentifierCritical(), aki);
821         }
822         // CRLNumber extension
823
if (getUseCRLNumber() == true) {
824             CRLNumber crlnum = new CRLNumber(BigInteger.valueOf(crlnumber));
825             crlgen.addExtension(X509Extensions.CRLNumber.getId(), this.getCRLNumberCritical(), crlnum);
826         }
827         
828         X509CRL JavaDoc crl;
829         crl = crlgen.generate(getCAToken().getPrivateKey(SecConst.CAKEYPURPOSE_CRLSIGN),getCAToken().getProvider());
830         // Verify before sending back
831
crl.verify(getCAToken().getPublicKey(SecConst.CAKEYPURPOSE_CRLSIGN));
832
833         return crl;
834     }
835     
836     /** Implemtation of UpgradableDataHashMap function getLatestVersion */
837     public float getLatestVersion(){
838        return LATEST_VERSION;
839     }
840
841     /** Implemtation of UpgradableDataHashMap function upgrade.
842      */

843     public void upgrade(){
844         if(Float.compare(LATEST_VERSION, getVersion()) != 0) {
845             // New version of the class, upgrade
846
log.info("Upgrading X509CA with version "+getVersion());
847
848             if (data.get(DEFAULTOCSPSERVICELOCATOR) == null) {
849                 setDefaultCRLDistPoint("");
850                 setDefaultOCSPServiceLocator("");
851             }
852             if (data.get(CRLISSUEINTERVAL) == null) {
853                 setCRLIssueInterval(0);
854             }
855             if (data.get(CRLOVERLAPTIME) == null) {
856                 // Default value 10 minutes
857
setCRLOverlapTime(10);
858             }
859             boolean useprintablestring = true;
860             if (data.get("alwaysuseutf8subjectdn") == null) {
861                 // Default value false
862
setUseUTF8PolicyText(false);
863             } else {
864                 // Use the same value as we had before when we had alwaysuseutf8subjectdn
865
boolean useutf8 = ((Boolean JavaDoc)data.get("alwaysuseutf8subjectdn")).booleanValue();
866                 setUseUTF8PolicyText(useutf8);
867                 // If we had checked to use utf8 on an old CA, we do not want to use PrintableString after upgrading
868
useprintablestring = !useutf8;
869             }
870             if (data.get(USEPRINTABLESTRINGSUBJECTDN) == null) {
871                 // Default value true (as before)
872
setUsePrintableStringSubjectDN(useprintablestring);
873             }
874             if (data.get(DEFAULTCRLISSUER) == null) {
875                 setDefaultCRLIssuer(null);
876             }
877             
878             
879             data.put(VERSION, new Float JavaDoc(LATEST_VERSION));
880         }
881     }
882
883     /**
884      * Method to upgrade new (or existing externacaservices)
885      * This method needs to be called outside the regular upgrade
886      * since the CA isn't instansiated in the regular upgrade.
887      *
888      */

889     public boolean upgradeExtendedCAServices() {
890         boolean retval = false;
891         Collection JavaDoc extendedServiceTypes = getExternalCAServiceTypes();
892
893         if(getCAInfo().getStatus() != SecConst.CA_EXTERNAL){
894             // Create XKMS service if it does not exist
895
if (!extendedServiceTypes.contains(new Integer JavaDoc(ExtendedCAServiceInfo.TYPE_XKMSEXTENDEDSERVICE))){
896
897                 String JavaDoc keytype = CATokenConstants.KEYALGORITHM_RSA;
898                 String JavaDoc keyspec = "2048";
899
900                 XKMSCAServiceInfo xKMSCAInfo = new XKMSCAServiceInfo(ExtendedCAServiceInfo.STATUS_INACTIVE,
901                         "CN=XKMSCertificate, " + getSubjectDN(),
902                         "",
903                         keyspec,
904                         keytype);
905
906                 XKMSCAService xkmsservice = new XKMSCAService(xKMSCAInfo);
907                 try {
908                     xkmsservice.init(this);
909                     retval = true;
910                 } catch (Exception JavaDoc e) {
911                     CAInfo info = this.getCAInfo();
912                     String JavaDoc caname = null;
913                     if (info != null) {
914                         caname = info.getName();
915                     }
916                     log.error(intres.getLocalizedMessage("signsession.errorupgradingxkmsservice",caname), e);
917                 }
918                 setExtendedCAService(xkmsservice);
919                 extendedServiceTypes.add(new Integer JavaDoc(ExtendedCAServiceInfo.TYPE_XKMSEXTENDEDSERVICE));
920                 data.put(EXTENDEDCASERVICES, extendedServiceTypes);
921             }
922
923             // Create CMS service if it does not exist
924
if (!extendedServiceTypes.contains(new Integer JavaDoc(ExtendedCAServiceInfo.TYPE_CMSEXTENDEDSERVICE))){
925
926                 String JavaDoc keytype = CATokenConstants.KEYALGORITHM_RSA;
927                 String JavaDoc keyspec = "2048";
928
929                 CmsCAServiceInfo cmsCAInfo = new CmsCAServiceInfo(ExtendedCAServiceInfo.STATUS_INACTIVE,
930                         "CN=CMSCertificate, " + getSubjectDN(),
931                         "",
932                         keyspec,
933                         keytype);
934
935                 CmsCAService cmsservice = new CmsCAService(cmsCAInfo);
936                 try {
937                     cmsservice.init(this);
938                     retval = true;
939                 } catch (Exception JavaDoc e) {
940                     CAInfo info = this.getCAInfo();
941                     String JavaDoc caname = null;
942                     if (info != null) {
943                         caname = info.getName();
944                     }
945                     log.error(intres.getLocalizedMessage("signsession.errorupgradingcmsservice",caname), e);
946                 }
947                 setExtendedCAService(cmsservice);
948                 extendedServiceTypes.add(new Integer JavaDoc(ExtendedCAServiceInfo.TYPE_CMSEXTENDEDSERVICE));
949                 data.put(EXTENDEDCASERVICES, extendedServiceTypes);
950             }
951         }
952         return retval;
953     }
954     
955     /**
956      * Method used to perform an extended service.
957      */

958     public ExtendedCAServiceResponse extendedService(ExtendedCAServiceRequest request)
959       throws ExtendedCAServiceRequestException, IllegalExtendedCAServiceRequestException, ExtendedCAServiceNotActiveException{
960           log.debug(">extendedService()");
961           if(request instanceof OCSPCAServiceRequest) {
962               OCSPCAServiceRequest ocspServiceReq = (OCSPCAServiceRequest)request;
963               boolean useCACert = ocspServiceReq.useCACert();
964               try {
965                   if (useCACert) {
966                       ocspServiceReq.setPrivKey(getCAToken().getPrivateKey(SecConst.CAKEYPURPOSE_CERTSIGN));
967                       ocspServiceReq.setPrivKeyProvider(getCAToken().getProvider());
968                       X509Certificate JavaDoc[] signerChain = (X509Certificate JavaDoc[])getCertificateChain().toArray(new X509Certificate JavaDoc[0]);
969                       List JavaDoc chain = Arrays.asList(signerChain);
970                       ocspServiceReq.setCertificateChain(chain);
971                       // Super class handles signing with the OCSP signing certificate
972
log.debug("<extendedService(super with ca cert)");
973                       return super.extendedService(ocspServiceReq);
974                   } else {
975                       // Super class handles signing with the OCSP signing certificate
976
log.debug("<extendedService(super no ca cert)");
977                       return super.extendedService(request);
978                   }
979               } catch (IllegalKeyStoreException ike) {
980                   throw new ExtendedCAServiceRequestException(ike);
981               } catch (CATokenOfflineException ctoe) {
982                   throw new ExtendedCAServiceRequestException(ctoe);
983               } catch (IllegalArgumentException JavaDoc e) {
984                   log.error("IllegalArgumentException: ", e);
985                   throw new IllegalExtendedCAServiceRequestException(e);
986               }
987           } else {
988               log.debug("<extendedService(super)");
989               return super.extendedService(request);
990           }
991     }
992     
993     public byte[] encryptKeys(KeyPair JavaDoc keypair) throws IOException JavaDoc, CATokenOfflineException{
994         ByteArrayOutputStream JavaDoc baos = new ByteArrayOutputStream JavaDoc();
995         ObjectOutputStream JavaDoc os = new ObjectOutputStream JavaDoc(baos);
996         os.writeObject(keypair);
997         
998         CertTools.installBCProvider();
999             
1000        CMSEnvelopedDataGenerator edGen = new CMSEnvelopedDataGenerator();
1001       
1002        CMSEnvelopedData ed;
1003        try {
1004            edGen.addKeyTransRecipient( this.getCAToken().getPublicKey(SecConst.CAKEYPURPOSE_KEYENCRYPT), this.keyId);
1005            ed = edGen.generate(
1006                    new CMSProcessableByteArray(baos.toByteArray()), CMSEnvelopedDataGenerator.AES256_CBC,"BC");
1007        } catch (Exception JavaDoc e) {
1008            log.error("-encryptKeys: ", e);
1009            throw new IOException JavaDoc(e.getMessage());
1010        }
1011                
1012        
1013        return ed.getEncoded();
1014    }
1015    
1016    public KeyPair JavaDoc decryptKeys(byte[] data) throws Exception JavaDoc {
1017        CMSEnvelopedData ed = new CMSEnvelopedData(data);
1018             
1019        RecipientInformationStore recipients = ed.getRecipientInfos();
1020        Iterator JavaDoc it = recipients.getRecipients().iterator();
1021        RecipientInformation recipient = (RecipientInformation) it.next();
1022        ObjectInputStream JavaDoc ois = null;
1023        byte[] recdata = recipient.getContent(getCAToken().getPrivateKey(SecConst.CAKEYPURPOSE_KEYENCRYPT),getCAToken().getProvider());
1024        ois = new ObjectInputStream JavaDoc(new ByteArrayInputStream JavaDoc(recdata));
1025                        
1026        return (KeyPair JavaDoc) ois.readObject();
1027    }
1028    
1029    
1030    /**
1031     * Obtains the Policy Notice
1032     *
1033     * @param policyOID,
1034     * OID of the policy
1035     * @param cps,
1036     * url to cps document
1037     * @param unotice,
1038     * user notice text
1039     * @param displayencoding,
1040     * the encoding used for UserNotice text, DisplayText.CONTENT_TYPE_BMPSTRING, CONTENT_TYPE_UTF8STRING, CONTENT_TYPE_IA5STRING or CONTENT_TYPE_VISIBLESTRING
1041     *
1042     * @return
1043     */

1044    private PolicyInformation getPolicyInformation(String JavaDoc policyOID, String JavaDoc cps, String JavaDoc unotice, int displayencoding) {
1045        
1046        ASN1EncodableVector qualifiers = new ASN1EncodableVector();
1047        if ((unotice != null) && !StringUtils.isEmpty(unotice.trim())) {
1048            // Normally we would just use 'DisplayText(unotice)' here. IE has problems with UTF8 though, so lets stick with BMSSTRING to satisfy Bills sick needs.
1049
UserNotice un = new UserNotice(null, new DisplayText(displayencoding, unotice));
1050            PolicyQualifierInfo pqiUNOTICE = new PolicyQualifierInfo(PolicyQualifierId.id_qt_unotice, un);
1051            qualifiers.add(pqiUNOTICE);
1052        }
1053        if ((cps != null) && !StringUtils.isEmpty(cps.trim())) {
1054            PolicyQualifierInfo pqiCPS = new PolicyQualifierInfo(cps);
1055            qualifiers.add(pqiCPS);
1056        }
1057        PolicyInformation policyInformation = null;
1058        if ( StringUtils.isNotEmpty(policyOID) && (qualifiers.size() > 0) ) {
1059            policyInformation = new PolicyInformation(new DERObjectIdentifier(policyOID), new DERSequence(qualifiers));
1060        } else {
1061            policyInformation = new PolicyInformation(new DERObjectIdentifier(policyOID));
1062        }
1063        
1064        return policyInformation;
1065    }
1066}
Popular Tags