List of usage examples for org.bouncycastle.asn1.x509 X509ExtensionsGenerator X509ExtensionsGenerator
X509ExtensionsGenerator
From source file:com.otterca.common.crypto.SimplePolicyGeneratorImpl.java
License:Apache License
/** * @see com.otterca.common.crypto.X509ExtensionGenerator#getExtension(X500Principal, * X509Certificate)/* www . j a v a 2 s. c om*/ */ @Override public byte[] getExtension(X500Principal subject, X509Certificate issuer) throws IOException { X509ExtensionsGenerator generator = new X509ExtensionsGenerator(); List<PolicyInformation> policies = new ArrayList<PolicyInformation>(); PolicyInformation info = getCpsPolicyInformation(); if (info != null) { policies.add(info); } info = getUserNoticePolicyInformation(); if (info != null) { policies.add(info); } byte[] bytes = null; if (!policies.isEmpty()) { CertificatePolicies certificatePolicies = new CertificatePolicies( policies.toArray(emptyPolicyInformationArray)); generator.addExtension(X509Extensions.CertificatePolicies, false, certificatePolicies); bytes = generator.generate().getEncoded(); } return bytes; }
From source file:org.ejbca.core.model.ca.caadmin.X509CA.java
License:Open Source License
/** * sequence is ignored by X509CA// w w w . j a v a2s.co m */ public Certificate generateCertificate(UserDataVO subject, X509Name requestX509Name, PublicKey publicKey, int keyusage, Date notBefore, Date notAfter, CertificateProfile certProfile, X509Extensions extensions, String sequence, PublicKey caPublicKey, PrivateKey caPrivateKey, String provider) throws Exception { // We must only allow signing to take place if the CA itself if on line, even if the token is on-line. // We have to allow expired as well though, so we can renew expired CAs if ((getStatus() != SecConst.CA_ACTIVE) && ((getStatus() != SecConst.CA_EXPIRED))) { String msg = intres.getLocalizedMessage("error.caoffline", getName(), getStatus()); if (log.isDebugEnabled()) { log.debug(msg); // This is something we handle so no need to log with higher priority } throw new CAOfflineException(msg); } final String sigAlg; if (certProfile.getSignatureAlgorithm() == null) { sigAlg = getCAInfo().getCATokenInfo().getSignatureAlgorithm(); } else { sigAlg = certProfile.getSignatureAlgorithm(); } final X509Certificate cacert = (X509Certificate) getCACertificate(); String dn = subject.getCertificateDN(); // Check if this is a root CA we are creating final boolean isRootCA = certProfile.getType() == CertificateProfile.TYPE_ROOTCA; // Get certificate validity time notBefore and notAfter final CertificateValidity val = new CertificateValidity(subject, certProfile, notBefore, notAfter, cacert, isRootCA); final X509V3CertificateGenerator certgen = new X509V3CertificateGenerator(); { // Serialnumber is either random bits, where random generator is initialized by the serno generator. // Or a custom serial number defined in the end entity object final ExtendedInformation ei = subject.getExtendedinformation(); BigInteger customSN = ei != null ? ei.certificateSerialNumber() : null; if (customSN != null) { if (!certProfile.getAllowCertSerialNumberOverride()) { final String msg = intres.getLocalizedMessage( "signsession.certprof_not_allowing_cert_sn_override_using_normal", customSN.toString(16)); log.info(msg); customSN = null; } else { if (log.isDebugEnabled()) { log.debug("Using custom serial number: " + customSN.toString(16)); } } } final BigInteger serno = customSN != null ? customSN : SernoGenerator.instance().getSerno(); certgen.setSerialNumber(serno); } certgen.setNotBefore(val.getNotBefore()); certgen.setNotAfter(val.getNotAfter()); certgen.setSignatureAlgorithm(sigAlg); // Make DNs if (certProfile.getUseSubjectDNSubSet()) { dn = certProfile.createSubjectDNSubSet(dn); } if (certProfile.getUseCNPostfix()) { dn = CertTools.insertCNPostfix(dn, certProfile.getCNPostfix()); } X509NameEntryConverter converter = null; if (getUsePrintableStringSubjectDN()) { converter = new PrintableStringEntryConverter(); } else { converter = new X509DefaultEntryConverter(); } // Will we use LDAP DN order (CN first) or X500 DN order (CN last) for the subject DN boolean ldapdnorder = true; if ((getUseLdapDNOrder() == false) || (certProfile.getUseLdapDnOrder() == false)) { ldapdnorder = false; } X509Name subjectDNName = CertTools.stringToBcX509Name(dn, converter, ldapdnorder); if (certProfile.getAllowDNOverride() && (requestX509Name != null)) { subjectDNName = requestX509Name; if (log.isDebugEnabled()) { log.debug("Using X509Name from request instead of user's registered."); } } if (log.isDebugEnabled()) { log.debug("Using subjectDN: " + subjectDNName.toString()); } certgen.setSubjectDN(subjectDNName); // We must take the issuer DN directly from the CA-certificate otherwise we risk re-ordering the DN // which many applications do not like. if (isRootCA) { // This will be an initial root CA, since no CA-certificate exists // 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, // it might have changed over the years. if (log.isDebugEnabled()) { log.debug("Using subject DN also as issuer DN, because it is a root CA"); } certgen.setIssuerDN(subjectDNName); } else { javax.security.auth.x500.X500Principal issuerPrincipal = cacert.getSubjectX500Principal(); if (log.isDebugEnabled()) { log.debug("Using issuer DN directly from the CA certificate: " + issuerPrincipal.getName()); } certgen.setIssuerDN(issuerPrincipal); } certgen.setPublicKey(publicKey); // // X509 Certificate Extensions // // Extensions we will add to the certificate, later when we have filled the structure with // everything we want. X509ExtensionsGenerator extgen = new X509ExtensionsGenerator(); // First we check if there is general extension override, and add all extensions from // the request in that case if (certProfile.getAllowExtensionOverride() && extensions != null) { Enumeration en = extensions.oids(); while (en != null && en.hasMoreElements()) { DERObjectIdentifier oid = (DERObjectIdentifier) en.nextElement(); X509Extension ext = extensions.getExtension(oid); if (log.isDebugEnabled()) { log.debug("Overriding extension with oid: " + oid); } extgen.addExtension(oid, ext.isCritical(), ext.getValue().getOctets()); } } // Second we see if there is Key usage override X509Extensions overridenexts = extgen.generate(); if (certProfile.getAllowKeyUsageOverride() && (keyusage >= 0)) { if (log.isDebugEnabled()) { log.debug("AllowKeyUsageOverride=true. Using KeyUsage from parameter: " + keyusage); } if ((certProfile.getUseKeyUsage() == true) && (keyusage >= 0)) { X509KeyUsage ku = new X509KeyUsage(keyusage); // We don't want to try to add custom extensions with the same oid if we have already added them // from the request, if AllowExtensionOverride is enabled. // Two extensions with the same oid is not allowed in the standard. if (overridenexts.getExtension(X509Extensions.KeyUsage) == null) { extgen.addExtension(X509Extensions.KeyUsage, certProfile.getKeyUsageCritical(), ku); } else { if (log.isDebugEnabled()) { log.debug( "KeyUsage was already overridden by an extension, not using KeyUsage from parameter."); } } } } // Third, check for standard Certificate Extensions that should be added. // Standard certificate extensions are defined in CertificateProfile and CertificateExtensionFactory // and implemented in package org.ejbca.core.model.certextensions.standard CertificateExtensionFactory fact = CertificateExtensionFactory.getInstance(); List<String> usedStdCertExt = certProfile.getUsedStandardCertificateExtensions(); Iterator<String> certStdExtIter = usedStdCertExt.iterator(); overridenexts = extgen.generate(); while (certStdExtIter.hasNext()) { String oid = certStdExtIter.next(); // We don't want to try to add standard extensions with the same oid if we have already added them // from the request, if AllowExtensionOverride is enabled. // Two extensions with the same oid is not allowed in the standard. if (overridenexts.getExtension(new DERObjectIdentifier(oid)) == null) { CertificateExtension certExt = fact.getStandardCertificateExtension(oid, certProfile); if (certExt != null) { byte[] value = certExt.getValueEncoded(subject, this, certProfile, publicKey, caPublicKey); if (value != null) { extgen.addExtension(new DERObjectIdentifier(certExt.getOID()), certExt.isCriticalFlag(), value); } } } else { if (log.isDebugEnabled()) { log.debug("Extension with oid " + oid + " has been overridden, standard extension will not be added."); } } } // Fourth, check for custom Certificate Extensions that should be added. // Custom certificate extensions is defined in certextensions.properties fact = CertificateExtensionFactory.getInstance(); List<Integer> usedCertExt = certProfile.getUsedCertificateExtensions(); Iterator<Integer> certExtIter = usedCertExt.iterator(); while (certExtIter.hasNext()) { Integer id = certExtIter.next(); CertificateExtension certExt = fact.getCertificateExtensions(id); if (certExt != null) { // We don't want to try to add custom extensions with the same oid if we have already added them // from the request, if AllowExtensionOverride is enabled. // Two extensions with the same oid is not allowed in the standard. if (overridenexts.getExtension(new DERObjectIdentifier(certExt.getOID())) == null) { byte[] value = certExt.getValueEncoded(subject, this, certProfile, publicKey, caPublicKey); if (value != null) { extgen.addExtension(new DERObjectIdentifier(certExt.getOID()), certExt.isCriticalFlag(), value); } } else { if (log.isDebugEnabled()) { log.debug("Extension with oid " + certExt.getOID() + " has been overridden, custom extension will not be added."); } } } } // Finally add extensions to certificate generator X509Extensions exts = extgen.generate(); Enumeration en = exts.oids(); while (en.hasMoreElements()) { DERObjectIdentifier oid = (DERObjectIdentifier) en.nextElement(); X509Extension ext = exts.getExtension(oid); certgen.addExtension(oid, ext.isCritical(), ext.getValue().getOctets()); } // // End of extensions // X509Certificate cert; if (log.isTraceEnabled()) { log.trace(">certgen.generate"); } cert = certgen.generate(caPrivateKey, provider); if (log.isTraceEnabled()) { log.trace("<certgen.generate"); } // Verify using the CA certificate before returning // If we can not verify the issued certificate using the CA certificate we don't want to issue this cert // because something is wrong... PublicKey verifyKey; // We must use the configured public key if this is a rootCA, because then we can renew our own certificate, after changing // the keys. In this case the _new_ key will not match the current CA certificate. if ((cacert != null) && (!isRootCA)) { verifyKey = cacert.getPublicKey(); } else { verifyKey = caPublicKey; } cert.verify(verifyKey); // If we have a CA-certificate, verify that we have all path verification stuff correct if (cacert != null) { byte[] aki = CertTools.getAuthorityKeyId(cert); byte[] ski = CertTools.getSubjectKeyId(isRootCA ? cert : cacert); if ((aki != null) && (ski != null)) { boolean eq = Arrays.equals(aki, ski); if (!eq) { String akistr = new String(Hex.encode(aki)); String skistr = new String(Hex.encode(ski)); log.error(intres.getLocalizedMessage("signsession.errorpathverifykeyid", akistr, skistr)); } } Principal issuerDN = cert.getIssuerX500Principal(); Principal subjectDN = cacert.getSubjectX500Principal(); if ((issuerDN != null) && (subjectDN != null)) { boolean eq = issuerDN.equals(subjectDN); if (!eq) { log.error(intres.getLocalizedMessage("signsession.errorpathverifydn", issuerDN.getName(), subjectDN.getName())); } } } if (log.isDebugEnabled()) { log.debug("X509CA: generated certificate, CA " + this.getCAId() + " for DN: " + subject.getCertificateDN()); } return cert; }