1 13 14 package org.ejbca.core.model.ca.caadmin; 15 16 import java.io.ByteArrayInputStream ; 17 import java.io.ByteArrayOutputStream ; 18 import java.io.IOException ; 19 import java.io.ObjectInputStream ; 20 import java.io.ObjectOutputStream ; 21 import java.io.Serializable ; 22 import java.math.BigInteger ; 23 import java.security.InvalidKeyException ; 24 import java.security.KeyPair ; 25 import java.security.NoSuchAlgorithmException ; 26 import java.security.NoSuchProviderException ; 27 import java.security.PublicKey ; 28 import java.security.SignatureException ; 29 import java.security.cert.CRL ; 30 import java.security.cert.CRLException ; 31 import java.security.cert.CertStore ; 32 import java.security.cert.Certificate ; 33 import java.security.cert.CollectionCertStoreParameters ; 34 import java.security.cert.X509CRL ; 35 import java.security.cert.X509Certificate ; 36 import java.util.ArrayList ; 37 import java.util.Arrays ; 38 import java.util.Collection ; 39 import java.util.Date ; 40 import java.util.HashMap ; 41 import java.util.Iterator ; 42 import java.util.List ; 43 import java.util.StringTokenizer ; 44 import java.util.Vector ; 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 136 public class X509CA extends CA implements Serializable { 137 138 private static final Logger log = Logger.getLogger(X509CA.class); 139 140 141 private static final InternalResources intres = InternalResources.getInstance(); 142 143 public static final float LATEST_VERSION = 11; 145 146 private byte[] keyId = new byte[] { 1, 2, 3, 4, 5 }; 147 148 149 protected static final String POLICYID = "policyid"; 151 protected static final String SUBJECTALTNAME = "subjectaltname"; 152 protected static final String USEAUTHORITYKEYIDENTIFIER = "useauthoritykeyidentifier"; 153 protected static final String AUTHORITYKEYIDENTIFIERCRITICAL = "authoritykeyidentifiercritical"; 154 protected static final String USECRLNUMBER = "usecrlnumber"; 155 protected static final String CRLNUMBERCRITICAL = "crlnumbercritical"; 156 protected static final String DEFAULTCRLDISTPOINT = "defaultcrldistpoint"; 157 protected static final String DEFAULTCRLISSUER = "defaultcrlissuer"; 158 protected static final String DEFAULTOCSPSERVICELOCATOR = "defaultocspservicelocator"; 159 protected static final String USEUTF8POLICYTEXT = "useutf8policytext"; 160 protected static final String USEPRINTABLESTRINGSUBJECTDN = "useprintablestringsubjectdn"; 161 162 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 (CAInfo.CATYPE_X509)); 181 data.put(VERSION, new Float (LATEST_VERSION)); 182 } 183 184 186 public X509CA(HashMap data, int caId, String subjectDN, String name, int status, Date updateTime) throws IllegalKeyStoreException{ 187 super(data); 188 ArrayList externalcaserviceinfos = new ArrayList (); 189 Iterator iter = getExternalCAServiceTypes().iterator(); 190 while(iter.hasNext()){ 191 ExtendedCAServiceInfo info = this.getExtendedCAServiceInfo(((Integer ) 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 String getPolicyId(){ return (String ) data.get(POLICYID);} 207 public void setPolicyId(String policyid){ data.put(POLICYID, policyid);} 208 209 public String getSubjectAltName() { return (String ) data.get(SUBJECTALTNAME);} 210 211 public boolean getUseAuthorityKeyIdentifier(){ 212 return ((Boolean )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 )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 )data.get(USECRLNUMBER)).booleanValue();} 226 public void setUseCRLNumber(boolean usecrlnumber) {data.put(USECRLNUMBER, Boolean.valueOf(usecrlnumber));} 227 228 public boolean getCRLNumberCritical(){return ((Boolean )data.get(CRLNUMBERCRITICAL)).booleanValue();} 229 public void setCRLNumberCritical(boolean crlnumbercritical) {data.put(CRLNUMBERCRITICAL, Boolean.valueOf(crlnumbercritical));} 230 231 public String getDefaultCRLDistPoint(){return (String ) data.get(DEFAULTCRLDISTPOINT);} 232 public void setDefaultCRLDistPoint(String defailtcrldistpoint) { 233 if(defailtcrldistpoint == null){ 234 data.put(DEFAULTCRLDISTPOINT, ""); 235 }else{ 236 data.put(DEFAULTCRLDISTPOINT, defailtcrldistpoint); 237 } 238 } 239 public String getDefaultCRLIssuer(){return (String ) data.get(DEFAULTCRLISSUER);} 240 public void setDefaultCRLIssuer(String defailtcrlissuer) { 241 if(defailtcrlissuer == null){ 242 data.put(DEFAULTCRLISSUER, ""); 243 }else{ 244 data.put(DEFAULTCRLISSUER, defailtcrlissuer); 245 } 246 } 247 248 public String getDefaultOCSPServiceLocator(){return (String ) data.get(DEFAULTOCSPSERVICELOCATOR);} 249 public void setDefaultOCSPServiceLocator(String 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 )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 )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 { 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 cert, boolean includeChain) throws SignRequestSignatureException { 290 try { 292 if (cert != null) 293 cert.verify(getCAToken().getPublicKey(SecConst.CAKEYPURPOSE_CERTSIGN)); 294 } catch (Exception e) { 295 throw new SignRequestSignatureException("Cannot verify certificate in createPKCS7(), did I sign this?"); 296 } 297 Collection chain = getCertificateChain(); 298 ArrayList certList = new ArrayList (); 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 certs = CertStore.getInstance("Collection", new CollectionCertStoreParameters (certList), "BC"); 308 CMSSignedDataGenerator gen = new CMSSignedDataGenerator(); 309 if (getCAToken().getPrivateKey(SecConst.CAKEYPURPOSE_CERTSIGN) == null) { 310 String 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 )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 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 (e); 329 } catch (Exception e) { 330 throw new javax.ejb.EJBException (e); 331 } 332 } 333 334 335 public Certificate generateCertificate(UserDataVO subject, 336 PublicKey publicKey, 337 int keyusage, 338 Date notBefore, 339 Date notAfter, 340 CertificateProfile certProfile) throws Exception { 341 342 343 final String sigAlg = getCAToken().getCATokenInfo().getSignatureAlgorithm(); 344 Date firstDate = new Date (); 345 firstDate.setTime(firstDate.getTime() - 10 * 60 * 1000); 347 Date lastDate = new Date (); 348 if ( (notBefore != null) && (certProfile.getAllowValidityOverride()) ) { 349 firstDate = notBefore; 351 if (log.isDebugEnabled()) { 352 log.debug("Using notBefore validity from request: "+firstDate); 353 } 354 } 355 if ( (notAfter == null) || (!certProfile.getAllowValidityOverride()) ) { 356 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 lastDate = notAfter; 365 if (log.isDebugEnabled()) { 366 log.debug("Using notAfter validity from request: "+lastDate); 367 } 368 } 369 if (!lastDate.after(firstDate)) { 371 lastDate = firstDate; 373 } 374 X509Certificate cacert = (X509Certificate )getCACertificate(); 375 376 String dn = subject.getDN(); 377 boolean isRootCA = false; 379 if (certProfile.getType() == CertificateProfile.TYPE_ROOTCA) { 380 isRootCA = true; 381 } 382 383 if ( !isRootCA ) { 387 if (lastDate.after(cacert.getNotAfter())) { 388 String 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 BigInteger serno = SernoGenerator.instance().getSerno(); 397 certgen.setSerialNumber(serno); 398 certgen.setNotBefore(firstDate); 399 certgen.setNotAfter(lastDate); 400 certgen.setSignatureAlgorithm(sigAlg); 401 402 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 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 if (isRootCA) { 426 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 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 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 if (certProfile.getUseExtendedKeyUsage() == true) { 475 Collection c = certProfile.getExtendedKeyUsageAsOIDStrings(); 477 Vector usage = new Vector (); 478 Iterator iter = c.iterator(); 479 while (iter.hasNext()) { 480 usage.add(new DERObjectIdentifier((String )iter.next())); 481 } 482 if (!usage.isEmpty()) { 484 ExtendedKeyUsage eku = new ExtendedKeyUsage(usage); 485 certgen.addExtension( 487 X509Extensions.ExtendedKeyUsage.getId(), 488 certProfile.getExtendedKeyUsageCritical(), 489 eku); 490 } 491 } 492 if (certProfile.getUseSubjectKeyIdentifier() == true) { 494 SubjectPublicKeyInfo spki = 495 new SubjectPublicKeyInfo( 496 (ASN1Sequence) new ASN1InputStream(new ByteArrayInputStream (publicKey.getEncoded())).readObject()); 497 SubjectKeyIdentifier ski = new SubjectKeyIdentifier(spki); 498 certgen.addExtension( 499 X509Extensions.SubjectKeyIdentifier.getId(), 500 certProfile.getSubjectKeyIdentifierCritical(), ski); 501 } 502 if (certProfile.getUseAuthorityKeyIdentifier() == true) { 504 AuthorityKeyIdentifier aki = null; 505 try{ 509 byte[] keybytes = getCAToken().getPublicKey(SecConst.CAKEYPURPOSE_CERTSIGN).getEncoded(); 510 SubjectPublicKeyInfo apki = new SubjectPublicKeyInfo((ASN1Sequence) new ASN1InputStream(new ByteArrayInputStream (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 ( (cacert != null) && (!isRootCA) ) { 521 byte[] akibytes = CertTools.getSubjectKeyId(cacert); 522 if (akibytes != null) { 523 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 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 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 policyId = certProfile.getCertificatePolicyId(); 555 String cpsurl = certProfile.getCpsUrl(); 556 String usernotice = certProfile.getUserNoticeText(); 557 ASN1EncodableVector policys = new ASN1EncodableVector(); 558 if (StringUtils.isNotEmpty(policyId )) { 559 StringTokenizer tokenizer = new StringTokenizer (policyId, ";", false); 560 while (tokenizer.hasMoreTokens()) { 561 String id = tokenizer.nextToken(); 562 PolicyInformation pi = getPolicyInformation(id, cpsurl, usernotice, displayencoding); 563 cpsurl = null; 565 usernotice = null; 566 if (pi != null) { 567 policys.add(pi); 568 } 569 } 570 DERSequence seq = new DERSequence(policys); 572 certgen.addExtension(X509Extensions.CertificatePolicies.getId(), 573 certProfile.getCertificatePoliciesCritical(), seq); 574 } 575 } 576 577 if (certProfile.getUseCRLDistributionPoint() == true) { 579 String crldistpoint = certProfile.getCRLDistributionPointURI(); 580 String crlissuer=certProfile.getCRLIssuer(); 581 if(certProfile.getUseDefaultCRLDistributionPoint()){ 582 crldistpoint = getDefaultCRLDistPoint(); 583 crlissuer = getDefaultCRLIssuer(); 584 } 585 ArrayList dpns = new ArrayList (); 587 if (StringUtils.isNotEmpty(crldistpoint)) { 588 StringTokenizer tokenizer = new StringTokenizer (crldistpoint, ";", false); 589 while (tokenizer.hasMoreTokens()) { 590 String 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 ArrayList issuers = new ArrayList (); 604 if (StringUtils.isNotEmpty(crlissuer)) { 605 StringTokenizer tokenizer = new StringTokenizer (crlissuer, ";", false); 606 while (tokenizer.hasMoreTokens()) { 607 String 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 distpoints = new ArrayList (); 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 if (certProfile.getUseOCSPServiceLocator() == true) { 644 String ocspUrl = certProfile.getOCSPServiceLocatorURI(); 645 if(certProfile.getUseDefaultOCSPServiceLocator()){ 646 ocspUrl = getDefaultOCSPServiceLocator(); 647 } 648 if (StringUtils.isNotEmpty(ocspUrl)) { 649 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 if (certProfile.getUseMicrosoftTemplate() == true) { 658 String mstemplate = certProfile.getMicrosoftTemplate(); 659 DERObjectIdentifier oid = new DERObjectIdentifier(CertTools.OID_MSTEMPLATE); 660 certgen.addExtension(oid, false, new DERIA5String(mstemplate)); 661 } 662 663 if (certProfile.getUseQCStatement() == true) { 665 String 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 qcs = new ArrayList (); 678 QCStatement qc = null; 679 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 if (certProfile.getUseQCEtsiQCCompliance()) { 693 qc = new QCStatement(ETSIQCObjectIdentifiers.id_etsi_qcs_QcCompliance); 694 qcs.add(qc); 695 } 696 if (certProfile.getUseQCEtsiValueLimit()) { 698 if ( (certProfile.getQCEtsiValueLimit() > 0) && (certProfile.getQCEtsiValueLimitCurrency() != null) ) { 700 int limit = certProfile.getQCEtsiValueLimit(); 701 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 if (certProfile.getUseQCEtsiSignatureDevice()) { 710 qc = new QCStatement(ETSIQCObjectIdentifiers.id_etsi_qcs_QcSSCD); 711 qcs.add(qc); 712 } 713 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 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 if (certProfile.getUseSubjectDirAttributes() == true) { 742 String dirAttrString = subject.getExtendedinformation().getSubjectDirectoryAttributes(); 744 if (StringUtils.isNotEmpty(dirAttrString)) { 745 Collection attr = SubjectDirAttrExtension.getSubjectDirectoryAttributes(dirAttrString); 747 ASN1EncodableVector vec = new ASN1EncodableVector(); 748 Iterator iter = attr.iterator(); 749 while (iter.hasNext()) { 750 Attribute a = (Attribute)iter.next(); 751 vec.add(a); 752 } 753 certgen.addExtension(X509Extensions.SubjectDirectoryAttributes, false, new DERSequence(vec)); 755 } 756 757 } 758 759 CertificateExtensionFactory fact = CertificateExtensionFactory.getInstance(); 761 List usedCertExt = certProfile.getUsedCertificateExtensions(); 762 Iterator certExtIter = usedCertExt.iterator(); 763 while(certExtIter.hasNext()){ 764 Integer id = (Integer ) 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 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 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 generateCRL(Vector certs, int crlnumber) 786 throws CATokenOfflineException, IllegalKeyStoreException, IOException , SignatureException , NoSuchProviderException , InvalidKeyException , CRLException , NoSuchAlgorithmException { 787 final String sigAlg= getCAToken().getCATokenInfo().getSignatureAlgorithm(); 788 789 Date thisUpdate = new Date (); 790 Date nextUpdate = new Date (); 791 792 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 X509Certificate cacert = (X509Certificate )getCACertificate(); 800 if (cacert == null) { 801 X509Name caname = CertTools.stringToBcX509Name(getSubjectDN()); 803 crlgen.setIssuerDN(caname); 804 } else { 805 crlgen.setIssuerDN(cacert.getSubjectX500Principal()); 806 } 807 if (certs != null) { 808 Iterator 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 if (getUseAuthorityKeyIdentifier() == true) { 817 SubjectPublicKeyInfo apki = new SubjectPublicKeyInfo((ASN1Sequence)new ASN1InputStream( 818 new ByteArrayInputStream (getCAToken().getPublicKey(SecConst.CAKEYPURPOSE_CRLSIGN).getEncoded())).readObject()); 819 AuthorityKeyIdentifier aki = new AuthorityKeyIdentifier(apki); 820 crlgen.addExtension(X509Extensions.AuthorityKeyIdentifier.getId(), getAuthorityKeyIdentifierCritical(), aki); 821 } 822 if (getUseCRLNumber() == true) { 824 CRLNumber crlnum = new CRLNumber(BigInteger.valueOf(crlnumber)); 825 crlgen.addExtension(X509Extensions.CRLNumber.getId(), this.getCRLNumberCritical(), crlnum); 826 } 827 828 X509CRL crl; 829 crl = crlgen.generate(getCAToken().getPrivateKey(SecConst.CAKEYPURPOSE_CRLSIGN),getCAToken().getProvider()); 830 crl.verify(getCAToken().getPublicKey(SecConst.CAKEYPURPOSE_CRLSIGN)); 832 833 return crl; 834 } 835 836 837 public float getLatestVersion(){ 838 return LATEST_VERSION; 839 } 840 841 843 public void upgrade(){ 844 if(Float.compare(LATEST_VERSION, getVersion()) != 0) { 845 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 setCRLOverlapTime(10); 858 } 859 boolean useprintablestring = true; 860 if (data.get("alwaysuseutf8subjectdn") == null) { 861 setUseUTF8PolicyText(false); 863 } else { 864 boolean useutf8 = ((Boolean )data.get("alwaysuseutf8subjectdn")).booleanValue(); 866 setUseUTF8PolicyText(useutf8); 867 useprintablestring = !useutf8; 869 } 870 if (data.get(USEPRINTABLESTRINGSUBJECTDN) == null) { 871 setUsePrintableStringSubjectDN(useprintablestring); 873 } 874 if (data.get(DEFAULTCRLISSUER) == null) { 875 setDefaultCRLIssuer(null); 876 } 877 878 879 data.put(VERSION, new Float (LATEST_VERSION)); 880 } 881 } 882 883 889 public boolean upgradeExtendedCAServices() { 890 boolean retval = false; 891 Collection extendedServiceTypes = getExternalCAServiceTypes(); 892 893 if(getCAInfo().getStatus() != SecConst.CA_EXTERNAL){ 894 if (!extendedServiceTypes.contains(new Integer (ExtendedCAServiceInfo.TYPE_XKMSEXTENDEDSERVICE))){ 896 897 String keytype = CATokenConstants.KEYALGORITHM_RSA; 898 String 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 e) { 911 CAInfo info = this.getCAInfo(); 912 String 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 (ExtendedCAServiceInfo.TYPE_XKMSEXTENDEDSERVICE)); 920 data.put(EXTENDEDCASERVICES, extendedServiceTypes); 921 } 922 923 if (!extendedServiceTypes.contains(new Integer (ExtendedCAServiceInfo.TYPE_CMSEXTENDEDSERVICE))){ 925 926 String keytype = CATokenConstants.KEYALGORITHM_RSA; 927 String 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 e) { 940 CAInfo info = this.getCAInfo(); 941 String 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 (ExtendedCAServiceInfo.TYPE_CMSEXTENDEDSERVICE)); 949 data.put(EXTENDEDCASERVICES, extendedServiceTypes); 950 } 951 } 952 return retval; 953 } 954 955 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 [] signerChain = (X509Certificate [])getCertificateChain().toArray(new X509Certificate [0]); 969 List chain = Arrays.asList(signerChain); 970 ocspServiceReq.setCertificateChain(chain); 971 log.debug("<extendedService(super with ca cert)"); 973 return super.extendedService(ocspServiceReq); 974 } else { 975 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 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 keypair) throws IOException , CATokenOfflineException{ 994 ByteArrayOutputStream baos = new ByteArrayOutputStream (); 995 ObjectOutputStream os = new ObjectOutputStream (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 e) { 1008 log.error("-encryptKeys: ", e); 1009 throw new IOException (e.getMessage()); 1010 } 1011 1012 1013 return ed.getEncoded(); 1014 } 1015 1016 public KeyPair decryptKeys(byte[] data) throws Exception { 1017 CMSEnvelopedData ed = new CMSEnvelopedData(data); 1018 1019 RecipientInformationStore recipients = ed.getRecipientInfos(); 1020 Iterator it = recipients.getRecipients().iterator(); 1021 RecipientInformation recipient = (RecipientInformation) it.next(); 1022 ObjectInputStream ois = null; 1023 byte[] recdata = recipient.getContent(getCAToken().getPrivateKey(SecConst.CAKEYPURPOSE_KEYENCRYPT),getCAToken().getProvider()); 1024 ois = new ObjectInputStream (new ByteArrayInputStream (recdata)); 1025 1026 return (KeyPair ) ois.readObject(); 1027 } 1028 1029 1030 1044 private PolicyInformation getPolicyInformation(String policyOID, String cps, String unotice, int displayencoding) { 1045 1046 ASN1EncodableVector qualifiers = new ASN1EncodableVector(); 1047 if ((unotice != null) && !StringUtils.isEmpty(unotice.trim())) { 1048 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 |