List of usage examples for java.security.cert X509Certificate getPublicKey
public abstract PublicKey getPublicKey();
From source file:org.cesecore.certificates.ca.X509CA.java
@Override public void createOrRemoveLinkCertificate(final CryptoToken cryptoToken, final boolean createLinkCertificate, final CertificateProfile certProfile) throws CryptoTokenOfflineException { byte[] ret = null; if (createLinkCertificate) { try {/*from w w w . j ava 2 s. c om*/ final CAToken catoken = getCAToken(); // Check if the input was a CA certificate, which is the same CA as this. If all is true we should create a NewWithOld link-certificate final X509Certificate currentCaCert = (X509Certificate) getCACertificate(); if (log.isDebugEnabled()) { log.debug("We will create a link certificate."); } final X509CAInfo info = (X509CAInfo) getCAInfo(); final EndEntityInformation cadata = new EndEntityInformation("nobody", info.getSubjectDN(), info.getSubjectDN().hashCode(), info.getSubjectAltName(), null, 0, new EndEntityType(EndEntityTypes.INVALID), 0, info.getCertificateProfileId(), null, null, 0, 0, null); final PublicKey previousCaPublicKey = cryptoToken .getPublicKey(catoken.getAliasFromPurpose(CATokenConstants.CAKEYPURPOSE_CERTSIGN_PREVIOUS)); final PrivateKey previousCaPrivateKey = cryptoToken.getPrivateKey( catoken.getAliasFromPurpose(CATokenConstants.CAKEYPURPOSE_CERTSIGN_PREVIOUS)); final String provider = cryptoToken.getSignProviderName(); // The sequence is ignored later, but we fetch the same previous for now to do this the same way as for CVC.. final String ignoredKeySequence = catoken.getProperties() .getProperty(CATokenConstants.PREVIOUS_SEQUENCE_PROPERTY); final Certificate retcert = generateCertificate(cadata, null, currentCaCert.getPublicKey(), -1, currentCaCert.getNotBefore(), currentCaCert.getNotAfter(), certProfile, null, ignoredKeySequence, previousCaPublicKey, previousCaPrivateKey, provider, null); log.info(intres.getLocalizedMessage("cvc.info.createlinkcert", cadata.getDN(), cadata.getDN())); ret = retcert.getEncoded(); } catch (CryptoTokenOfflineException e) { throw e; } catch (Exception e) { throw new RuntimeException("Bad CV CA certificate.", e); } } updateLatestLinkCertificate(ret); }
From source file:org.cesecore.certificates.ca.X509CA.java
/** * Sequence is ignored by X509CA. The ctParams argument will NOT be kept after the function call returns, * and is allowed to contain references to session beans. * /*from w w w . ja v a2s.c om*/ * @throws CAOfflineException if the CA wasn't active * @throws InvalidAlgorithmException if the signing algorithm in the certificate profile (or the CA Token if not found) was invalid. * @throws IllegalValidityException if validity was invalid * @throws IllegalNameException if the name specified in the certificate request was invalid * @throws CertificateExtensionException if any of the certificate extensions were invalid * @throws OperatorCreationException if CA's private key contained an unknown algorithm or provider * @throws CertificateCreateException if an error occurred when trying to create a certificate. * @throws SignatureException if the CA's certificate's and request's certificate's and signature algorithms differ */ private Certificate generateCertificate(final EndEntityInformation subject, final RequestMessage request, final PublicKey publicKey, final int keyusage, final Date notBefore, final Date notAfter, final CertificateProfile certProfile, final Extensions extensions, final String sequence, final PublicKey caPublicKey, final PrivateKey caPrivateKey, final String provider, CertificateGenerationParams certGenParams) throws CAOfflineException, InvalidAlgorithmException, IllegalValidityException, IllegalNameException, CertificateExtensionException, OperatorCreationException, CertificateCreateException, SignatureException { // We must only allow signing to take place if the CA itself is 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() != CAConstants.CA_ACTIVE) && ((getStatus() != CAConstants.CA_EXPIRED))) { final 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 = getCAToken().getSignatureAlgorithm(); } else { sigAlg = certProfile.getSignatureAlgorithm(); } // Check that the signature algorithm is one of the allowed ones if (!ArrayUtils.contains(AlgorithmConstants.AVAILABLE_SIGALGS, sigAlg)) { final String msg = intres.getLocalizedMessage("createcert.invalidsignaturealg", sigAlg); throw new InvalidAlgorithmException(msg); } // Check if this is a root CA we are creating final boolean isRootCA = certProfile.getType() == CertificateConstants.CERTTYPE_ROOTCA; final X509Certificate cacert = (X509Certificate) getCACertificate(); // Check CA certificate PrivateKeyUsagePeriod if it exists (throws CAOfflineException if it exists and is not within this time) CertificateValidity.checkPrivateKeyUsagePeriod(cacert); // Get certificate validity time notBefore and notAfter final CertificateValidity val = new CertificateValidity(subject, certProfile, notBefore, notAfter, cacert, isRootCA); final BigInteger serno; { // 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(); if (certProfile.getAllowCertSerialNumberOverride()) { if (ei != null && ei.certificateSerialNumber() != null) { serno = ei.certificateSerialNumber(); } else { serno = SernoGeneratorRandom.instance().getSerno(); } } else { serno = SernoGeneratorRandom.instance().getSerno(); if ((ei != null) && (ei.certificateSerialNumber() != null)) { final String msg = intres.getLocalizedMessage( "createcert.certprof_not_allowing_cert_sn_override_using_normal", ei.certificateSerialNumber().toString(16)); log.info(msg); } } } // Make DNs String dn = subject.getCertificateDN(); if (certProfile.getUseSubjectDNSubSet()) { dn = certProfile.createSubjectDNSubSet(dn); } final X500NameStyle nameStyle; if (getUsePrintableStringSubjectDN()) { nameStyle = PrintableStringNameStyle.INSTANCE; } else { nameStyle = CeSecoreNameStyle.INSTANCE; } if (certProfile.getUseCNPostfix()) { dn = CertTools.insertCNPostfix(dn, certProfile.getCNPostfix(), nameStyle); } // Will we use LDAP DN order (CN first) or X500 DN order (CN last) for the subject DN final boolean ldapdnorder; if ((getUseLdapDNOrder() == false) || (certProfile.getUseLdapDnOrder() == false)) { ldapdnorder = false; } else { ldapdnorder = true; } final X500Name subjectDNName; if (certProfile.getAllowDNOverride() && (request != null) && (request.getRequestX500Name() != null)) { subjectDNName = request.getRequestX500Name(); if (log.isDebugEnabled()) { log.debug("Using X509Name from request instead of user's registered."); } } else { final ExtendedInformation ei = subject.getExtendedinformation(); if (certProfile.getAllowDNOverrideByEndEntityInformation() && ei != null && ei.getRawSubjectDn() != null) { final String stripped = StringTools.strip(ei.getRawSubjectDn()); final String escapedPluses = CertTools.handleUnescapedPlus(stripped); final String emptiesRemoved = DNFieldsUtil.removeAllEmpties(escapedPluses); final X500Name subjectDNNameFromEei = CertTools.stringToUnorderedX500Name(emptiesRemoved, CeSecoreNameStyle.INSTANCE); if (subjectDNNameFromEei.toString().length() > 0) { subjectDNName = subjectDNNameFromEei; if (log.isDebugEnabled()) { log.debug( "Using X500Name from end entity information instead of user's registered subject DN fields."); log.debug("ExtendedInformation.getRawSubjectDn(): " + ei.getRawSubjectDn() + " will use: " + CeSecoreNameStyle.INSTANCE.toString(subjectDNName)); } } else { subjectDNName = CertTools.stringToBcX500Name(dn, nameStyle, ldapdnorder); } } else { subjectDNName = CertTools.stringToBcX500Name(dn, nameStyle, ldapdnorder); } } // Make sure the DN does not contain dangerous characters if (StringTools.hasStripChars(subjectDNName.toString())) { if (log.isTraceEnabled()) { log.trace("DN with illegal name: " + subjectDNName); } final String msg = intres.getLocalizedMessage("createcert.illegalname"); throw new IllegalNameException(msg); } if (log.isDebugEnabled()) { log.debug("Using subjectDN: " + subjectDNName.toString()); } // We must take the issuer DN directly from the CA-certificate otherwise we risk re-ordering the DN // which many applications do not like. X500Name issuerDNName; 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"); } issuerDNName = subjectDNName; } else { issuerDNName = X500Name.getInstance(cacert.getSubjectX500Principal().getEncoded()); if (log.isDebugEnabled()) { log.debug("Using issuer DN directly from the CA certificate: " + issuerDNName.toString()); } } SubjectPublicKeyInfo pkinfo; try { pkinfo = new SubjectPublicKeyInfo((ASN1Sequence) ASN1Primitive.fromByteArray(publicKey.getEncoded())); } catch (IOException e) { throw new IllegalStateException("Caught unexpected IOException.", e); } final X509v3CertificateBuilder certbuilder = new X509v3CertificateBuilder(issuerDNName, serno, val.getNotBefore(), val.getNotAfter(), subjectDNName, pkinfo); // Only created and used if Certificate Transparency is enabled final X509v3CertificateBuilder precertbuilder = certProfile.isUseCertificateTransparencyInCerts() ? new X509v3CertificateBuilder(issuerDNName, serno, val.getNotBefore(), val.getNotAfter(), subjectDNName, pkinfo) : null; // Check that the certificate fulfills name constraints if (cacert instanceof X509Certificate) { GeneralNames altNameGNs = null; String altName = subject.getSubjectAltName(); if (certProfile.getUseSubjectAltNameSubSet()) { altName = certProfile.createSubjectAltNameSubSet(altName); } if (altName != null && altName.length() > 0) { altNameGNs = CertTools.getGeneralNamesFromAltName(altName); } CertTools.checkNameConstraints((X509Certificate) cacert, subjectDNName, altNameGNs); } // If the subject has Name Constraints, then name constraints must be enabled in the certificate profile! if (subject.getExtendedinformation() != null) { final ExtendedInformation ei = subject.getExtendedinformation(); final List<String> permittedNC = ei.getNameConstraintsPermitted(); final List<String> excludedNC = ei.getNameConstraintsExcluded(); if ((permittedNC != null && !permittedNC.isEmpty()) || (excludedNC != null && !excludedNC.isEmpty())) { if (!certProfile.getUseNameConstraints()) { throw new CertificateCreateException( "Tried to issue a certificate with Name Constraints without having enabled NC in the certificate profile."); } } } // // X509 Certificate Extensions // // Extensions we will add to the certificate, later when we have filled the structure with // everything we want. final ExtensionsGenerator extgen = new ExtensionsGenerator(); // First we check if there is general extension override, and add all extensions from // the request in that case if (certProfile.getAllowExtensionOverride() && extensions != null) { ASN1ObjectIdentifier[] oids = extensions.getExtensionOIDs(); for (ASN1ObjectIdentifier oid : oids) { final Extension ext = extensions.getExtension(oid); if (log.isDebugEnabled()) { log.debug("Overriding extension with oid: " + oid); } try { extgen.addExtension(oid, ext.isCritical(), ext.getParsedValue()); } catch (IOException e) { throw new IllegalStateException("Caught unexpected IOException.", e); } } } // Second we see if there is Key usage override Extensions 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)) { final KeyUsage ku = new KeyUsage(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(Extension.keyUsage) == null) { try { extgen.addExtension(Extension.keyUsage, certProfile.getKeyUsageCritical(), ku); } catch (IOException e) { throw new IllegalStateException("Caught unexpected IOException.", e); } } 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 final CertificateExtensionFactory fact = CertificateExtensionFactory.getInstance(); final List<String> usedStdCertExt = certProfile.getUsedStandardCertificateExtensions(); final Iterator<String> certStdExtIter = usedStdCertExt.iterator(); overridenexts = extgen.generate(); while (certStdExtIter.hasNext()) { final 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 ASN1ObjectIdentifier(oid)) == null) { final CertificateExtension certExt = fact.getStandardCertificateExtension(oid, certProfile); if (certExt != null) { final byte[] value = certExt.getValueEncoded(subject, this, certProfile, publicKey, caPublicKey, val); if (value != null) { extgen.addExtension(new ASN1ObjectIdentifier(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 final List<Integer> usedCertExt = certProfile.getUsedCertificateExtensions(); final Iterator<Integer> certExtIter = usedCertExt.iterator(); while (certExtIter.hasNext()) { final Integer id = certExtIter.next(); final 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 ASN1ObjectIdentifier(certExt.getOID())) == null) { final byte[] value = certExt.getValueEncoded(subject, this, certProfile, publicKey, caPublicKey, val); if (value != null) { extgen.addExtension(new ASN1ObjectIdentifier(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 final Extensions exts = extgen.generate(); ASN1ObjectIdentifier[] oids = exts.getExtensionOIDs(); try { for (ASN1ObjectIdentifier oid : oids) { final Extension extension = exts.getExtension(oid); if (oid.equals(Extension.subjectAlternativeName)) { // subjectAlternativeName extension value needs special handling ExtensionsGenerator sanExtGen = getSubjectAltNameExtensionForCert(extension, precertbuilder != null); Extensions sanExts = sanExtGen.generate(); Extension eext = sanExts.getExtension(oid); certbuilder.addExtension(oid, eext.isCritical(), eext.getParsedValue()); // adding subjetAlternativeName extension to certbuilder if (precertbuilder != null) { // if a pre-certificate is to be published to a CTLog eext = getSubjectAltNameExtensionForCTCert(extension).generate().getExtension(oid); precertbuilder.addExtension(oid, eext.isCritical(), eext.getParsedValue()); // adding subjectAlternativeName extension to precertbuilder eext = sanExts.getExtension(new ASN1ObjectIdentifier("1.3.6.1.4.1.11129.2.4.6")); if (eext != null) { certbuilder.addExtension(eext.getExtnId(), eext.isCritical(), eext.getParsedValue()); // adding nrOfRedactedLabels extension to certbuilder } } } else { // if not a subjectAlternativeName extension, just add it to both certbuilder and precertbuilder final boolean isCritical = extension.isCritical(); // We must get the raw octets here in order to be able to create invalid extensions that is not constructed from proper ASN.1 final byte[] value = extension.getExtnValue().getOctets(); certbuilder.addExtension(extension.getExtnId(), isCritical, value); if (precertbuilder != null) { precertbuilder.addExtension(extension.getExtnId(), isCritical, value); } } } // Add Certificate Transparency extension. It needs to access the certbuilder and // the CA key so it has to be processed here inside X509CA. if (ct != null && certProfile.isUseCertificateTransparencyInCerts() && certGenParams.getConfiguredCTLogs() != null && certGenParams.getCTAuditLogCallback() != null) { // Create pre-certificate // A critical extension is added to prevent this cert from being used ct.addPreCertPoison(precertbuilder); // Sign pre-certificate /* * TODO: Should be able to use a special CT signing certificate. * It should have CA=true and ExtKeyUsage=PRECERTIFICATE_SIGNING_OID, * and should not have any other key usages. */ final ContentSigner signer = new BufferingContentSigner( new JcaContentSignerBuilder(sigAlg).setProvider(provider).build(caPrivateKey), 20480); final X509CertificateHolder certHolder = precertbuilder.build(signer); final X509Certificate cert = (X509Certificate) CertTools .getCertfromByteArray(certHolder.getEncoded()); // Get certificate chain final List<Certificate> chain = new ArrayList<Certificate>(); chain.add(cert); chain.addAll(getCertificateChain()); // Submit to logs and get signed timestamps byte[] sctlist = null; try { sctlist = ct.fetchSCTList(chain, certProfile, certGenParams.getConfiguredCTLogs()); } finally { // Notify that pre-cert has been successfully or unsuccessfully submitted so it can be audit logged. certGenParams.getCTAuditLogCallback().logPreCertSubmission(this, subject, cert, sctlist != null); } if (sctlist != null) { // can be null if the CTLog has been deleted from the configuration ASN1ObjectIdentifier sctOid = new ASN1ObjectIdentifier(CertificateTransparency.SCTLIST_OID); certbuilder.addExtension(sctOid, false, new DEROctetString(sctlist)); } } else { if (log.isDebugEnabled()) { String cause = ""; if (ct == null) { cause += "CT is not available in this version of EJBCA."; } else { if (!certProfile.isUseCertificateTransparencyInCerts()) { cause += "CT is not enabled in the certificate profile. "; } if (certGenParams == null) { cause += "Certificate generation parameters was null."; } else if (certGenParams.getCTAuditLogCallback() == null) { cause += "No CT audit logging callback was passed to X509CA."; } else if (certGenParams.getConfiguredCTLogs() == null) { cause += "There are no CT logs configured in System Configuration."; } } log.debug("Not logging to CT. " + cause); } } } catch (CertificateException e) { throw new CertificateCreateException( "Could not process CA's private key when parsing Certificate Transparency extension.", e); } catch (IOException e) { throw new CertificateCreateException( "IOException was caught when parsing Certificate Transparency extension.", e); } catch (CTLogException e) { throw new CertificateCreateException( "An exception occurred because too many CT servers were down to satisfy the certificate profile.", e); } // // End of extensions // if (log.isTraceEnabled()) { log.trace(">certgen.generate"); } final ContentSigner signer = new BufferingContentSigner( new JcaContentSignerBuilder(sigAlg).setProvider(provider).build(caPrivateKey), 20480); final X509CertificateHolder certHolder = certbuilder.build(signer); X509Certificate cert; try { cert = (X509Certificate) CertTools.getCertfromByteArray(certHolder.getEncoded()); } catch (IOException e) { throw new IllegalStateException("Unexpected IOException caught when parsing certificate holder.", e); } catch (CertificateException e) { throw new CertificateCreateException("Could not create certificate from CA's private key,", e); } 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... final 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; } try { cert.verify(verifyKey); } catch (InvalidKeyException e) { throw new CertificateCreateException("CA's public key was invalid,", e); } catch (NoSuchAlgorithmException e) { throw new CertificateCreateException(e); } catch (NoSuchProviderException e) { throw new IllegalStateException("Provider was unknown", e); } catch (CertificateException e) { throw new CertificateCreateException(e); } // If we have a CA-certificate, verify that we have all path verification stuff correct if (cacert != null) { final byte[] aki = CertTools.getAuthorityKeyId(cert); final byte[] ski = CertTools.getSubjectKeyId(isRootCA ? cert : cacert); if ((aki != null) && (ski != null)) { final boolean eq = Arrays.equals(aki, ski); if (!eq) { final String akistr = new String(Hex.encode(aki)); final String skistr = new String(Hex.encode(ski)); final String msg = intres.getLocalizedMessage("createcert.errorpathverifykeyid", akistr, skistr); log.error(msg); // This will differ if we create link certificates, NewWithOld, therefore we can not throw an exception here. } } final Principal issuerDN = cert.getIssuerX500Principal(); final Principal caSubjectDN = cacert.getSubjectX500Principal(); if ((issuerDN != null) && (caSubjectDN != null)) { final boolean eq = issuerDN.equals(caSubjectDN); if (!eq) { final String msg = intres.getLocalizedMessage("createcert.errorpathverifydn", issuerDN.getName(), caSubjectDN.getName()); log.error(msg); throw new CertificateCreateException(msg); } } } // Before returning from this method, we will set the private key and provider in the request message, in case the response message needs to be signed if (request != null) { request.setResponseKeyInfo(caPrivateKey, provider); } if (log.isDebugEnabled()) { log.debug("X509CA: generated certificate, CA " + this.getCAId() + " for DN: " + subject.getCertificateDN()); } return cert; }
From source file:org.cesecore.certificates.ca.X509CA.java
/** * Generate a CRL or a deltaCRL/*from w w w . j a v a 2s . c om*/ * * @param certs * list of revoked certificates * @param crlnumber * CRLNumber for this CRL * @param isDeltaCRL * true if we should generate a DeltaCRL * @param basecrlnumber * caseCRLNumber for a delta CRL, use 0 for full CRLs * @param certProfile * certificate profile for CRL Distribution point in the CRL, or null * @return CRL * @throws CryptoTokenOfflineException * @throws IllegalCryptoTokenException * @throws IOException * @throws SignatureException * @throws NoSuchProviderException * @throws InvalidKeyException * @throws CRLException * @throws NoSuchAlgorithmException */ private X509CRLHolder generateCRL(CryptoToken cryptoToken, Collection<RevokedCertInfo> certs, long crlPeriod, int crlnumber, boolean isDeltaCRL, int basecrlnumber) throws CryptoTokenOfflineException, IllegalCryptoTokenException, IOException, SignatureException, NoSuchProviderException, InvalidKeyException, CRLException, NoSuchAlgorithmException { final String sigAlg = getCAInfo().getCAToken().getSignatureAlgorithm(); if (log.isDebugEnabled()) { log.debug("generateCRL(" + certs.size() + ", " + crlPeriod + ", " + crlnumber + ", " + isDeltaCRL + ", " + basecrlnumber); } // Make DNs final X509Certificate cacert = (X509Certificate) getCACertificate(); final X500Name issuer; if (cacert == null) { // This is an initial root CA, since no CA-certificate exists // (I don't think we can ever get here!!!) final X500NameStyle nameStyle; if (getUsePrintableStringSubjectDN()) { nameStyle = PrintableStringNameStyle.INSTANCE; } else { nameStyle = CeSecoreNameStyle.INSTANCE; } issuer = CertTools.stringToBcX500Name(getSubjectDN(), nameStyle, getUseLdapDNOrder()); } else { issuer = X500Name.getInstance(cacert.getSubjectX500Principal().getEncoded()); } final Date thisUpdate = new Date(); final Date nextUpdate = new Date(); nextUpdate.setTime(nextUpdate.getTime() + crlPeriod); final X509v2CRLBuilder crlgen = new X509v2CRLBuilder(issuer, thisUpdate); crlgen.setNextUpdate(nextUpdate); if (certs != null) { if (log.isDebugEnabled()) { log.debug("Adding " + certs.size() + " revoked certificates to CRL. Free memory=" + Runtime.getRuntime().freeMemory()); } final Iterator<RevokedCertInfo> it = certs.iterator(); while (it.hasNext()) { final RevokedCertInfo certinfo = (RevokedCertInfo) it.next(); crlgen.addCRLEntry(certinfo.getUserCertificate(), certinfo.getRevocationDate(), certinfo.getReason()); } if (log.isDebugEnabled()) { log.debug("Finished adding " + certs.size() + " revoked certificates to CRL. Free memory=" + Runtime.getRuntime().freeMemory()); } } // Authority key identifier if (getUseAuthorityKeyIdentifier() == true) { byte[] caSkid = (cacert != null ? CertTools.getSubjectKeyId(cacert) : null); if (caSkid != null) { // Use subject key id from CA certificate AuthorityKeyIdentifier aki = new AuthorityKeyIdentifier(caSkid); crlgen.addExtension(Extension.authorityKeyIdentifier, getAuthorityKeyIdentifierCritical(), aki); } else { // Generate from SHA1 of public key ASN1InputStream asn1InputStream = new ASN1InputStream(new ByteArrayInputStream(cryptoToken .getPublicKey(getCAToken().getAliasFromPurpose(CATokenConstants.CAKEYPURPOSE_CRLSIGN)) .getEncoded())); try { SubjectPublicKeyInfo apki = new SubjectPublicKeyInfo( (ASN1Sequence) asn1InputStream.readObject()); AuthorityKeyIdentifier aki = new AuthorityKeyIdentifier(apki); crlgen.addExtension(Extension.authorityKeyIdentifier, getAuthorityKeyIdentifierCritical(), aki); } finally { asn1InputStream.close(); } } } // Authority Information Access final ASN1EncodableVector accessList = new ASN1EncodableVector(); if (getAuthorityInformationAccess() != null) { for (String url : getAuthorityInformationAccess()) { if (StringUtils.isNotEmpty(url)) { GeneralName accessLocation = new GeneralName(GeneralName.uniformResourceIdentifier, new DERIA5String(url)); accessList.add(new AccessDescription(AccessDescription.id_ad_caIssuers, accessLocation)); } } } if (accessList.size() > 0) { AuthorityInformationAccess authorityInformationAccess = AuthorityInformationAccess .getInstance(new DERSequence(accessList)); // "This CRL extension MUST NOT be marked critical." according to rfc4325 crlgen.addExtension(Extension.authorityInfoAccess, false, authorityInformationAccess); } // CRLNumber extension if (getUseCRLNumber() == true) { CRLNumber crlnum = new CRLNumber(BigInteger.valueOf(crlnumber)); crlgen.addExtension(Extension.cRLNumber, this.getCRLNumberCritical(), crlnum); } if (isDeltaCRL) { // DeltaCRLIndicator extension CRLNumber basecrlnum = new CRLNumber(BigInteger.valueOf(basecrlnumber)); crlgen.addExtension(Extension.deltaCRLIndicator, true, basecrlnum); } // CRL Distribution point URI and Freshest CRL DP if (getUseCrlDistributionPointOnCrl()) { String crldistpoint = getDefaultCRLDistPoint(); List<DistributionPoint> distpoints = generateDistributionPoints(crldistpoint); if (distpoints.size() > 0) { IssuingDistributionPoint idp = new IssuingDistributionPoint( distpoints.get(0).getDistributionPoint(), false, false, null, false, false); // According to the RFC, IDP must be a critical extension. // Nonetheless, at the moment, Mozilla is not able to correctly // handle the IDP extension and discards the CRL if it is critical. crlgen.addExtension(Extension.issuingDistributionPoint, getCrlDistributionPointOnCrlCritical(), idp); } if (!isDeltaCRL) { String crlFreshestDP = getCADefinedFreshestCRL(); List<DistributionPoint> freshestDistPoints = generateDistributionPoints(crlFreshestDP); if (freshestDistPoints.size() > 0) { CRLDistPoint ext = new CRLDistPoint((DistributionPoint[]) freshestDistPoints .toArray(new DistributionPoint[freshestDistPoints.size()])); // According to the RFC, the Freshest CRL extension on a // CRL must not be marked as critical. Therefore it is // hardcoded as not critical and is independent of // getCrlDistributionPointOnCrlCritical(). crlgen.addExtension(Extension.freshestCRL, false, ext); } } } final X509CRLHolder crl; if (log.isDebugEnabled()) { log.debug("Signing CRL. Free memory=" + Runtime.getRuntime().freeMemory()); } final String alias = getCAToken().getAliasFromPurpose(CATokenConstants.CAKEYPURPOSE_CRLSIGN); try { final ContentSigner signer = new BufferingContentSigner(new JcaContentSignerBuilder(sigAlg) .setProvider(cryptoToken.getSignProviderName()).build(cryptoToken.getPrivateKey(alias)), 20480); crl = crlgen.build(signer); } catch (OperatorCreationException e) { // Very fatal error throw new RuntimeException("Can not create Jca content signer: ", e); } if (log.isDebugEnabled()) { log.debug("Finished signing CRL. Free memory=" + Runtime.getRuntime().freeMemory()); } // Verify using the CA certificate before returning // If we can not verify the issued CRL using the CA certificate we don't want to issue this CRL // because something is wrong... final PublicKey verifyKey; if (cacert != null) { verifyKey = cacert.getPublicKey(); if (log.isTraceEnabled()) { log.trace("Got the verify key from the CA certificate."); } } else { verifyKey = cryptoToken.getPublicKey(alias); if (log.isTraceEnabled()) { log.trace("Got the verify key from the CA token."); } } try { final ContentVerifierProvider verifier = new JcaContentVerifierProviderBuilder().build(verifyKey); if (!crl.isSignatureValid(verifier)) { throw new SignatureException("Error verifying CRL to be returned."); } } catch (OperatorCreationException e) { // Very fatal error throw new RuntimeException("Can not create Jca content signer: ", e); } catch (CertException e) { throw new SignatureException(e.getMessage(), e); } if (log.isDebugEnabled()) { log.debug("Returning CRL. Free memory=" + Runtime.getRuntime().freeMemory()); } return crl; }
From source file:org.cesecore.certificates.ocsp.OcspResponseGeneratorSessionBean.java
/** * Select the preferred OCSP response sigAlg according to RFC6960 Section 4.4.7 in the following order: * //from w ww. j a va 2 s . c om * 1. Select an algorithm specified as a preferred signature algorithm in the client request if it is * an acceptable algorithm by EJBCA. * 2. Select the signature algorithm used to sign a certificate revocation list (CRL) issued by the * certificate issuer providing status information for the certificate specified by CertID. * (NOT APPLIED) * 3. Select the signature algorithm used to sign the OCSPRequest if it is an acceptable algorithm in EJBCA. * 4. Select a signature algorithm that has been advertised as being the default signature algorithm for * the signing service using an out-of-band mechanism. * 5. Select a mandatory or recommended signature algorithm specified for the version of OCSP in use, aka. * specified in the properties file. * * The acceptable algorithm by EJBCA are the algorithms specified in ocsp.properties file in 'ocsp.signaturealgorithm' * * @param req * @param ocspSigningCacheEntry * @param signerCert * @return */ private String getSigAlg(OCSPReq req, final OcspSigningCacheEntry ocspSigningCacheEntry, final X509Certificate signerCert) { String sigAlg = null; PublicKey pk = signerCert.getPublicKey(); // Start with the preferred signature algorithm in the OCSP request final Extension preferredSigAlgExtension = req .getExtension(new ASN1ObjectIdentifier(OCSPObjectIdentifiers.id_pkix_ocsp + ".8")); if (preferredSigAlgExtension != null) { final ASN1Sequence preferredSignatureAlgorithms = ASN1Sequence .getInstance(preferredSigAlgExtension.getParsedValue()); for (int i = 0; i < preferredSignatureAlgorithms.size(); i++) { final ASN1Encodable asn1Encodable = preferredSignatureAlgorithms.getObjectAt(i); final ASN1ObjectIdentifier algorithmOid; if (asn1Encodable instanceof ASN1ObjectIdentifier) { // Handle client requests that were adapted to EJBCA 6.1.0's implementation log.info( "OCSP request's PreferredSignatureAlgorithms did not contain an PreferredSignatureAlgorithm, but instead an algorithm OID." + " This will not be supported in a future versions of EJBCA."); algorithmOid = (ASN1ObjectIdentifier) asn1Encodable; } else { // Handle client requests that provide a proper AlgorithmIdentifier as specified in RFC 6960 + RFC 5280 final ASN1Sequence preferredSignatureAlgorithm = ASN1Sequence.getInstance(asn1Encodable); final AlgorithmIdentifier algorithmIdentifier = AlgorithmIdentifier .getInstance(preferredSignatureAlgorithm.getObjectAt(0)); algorithmOid = algorithmIdentifier.getAlgorithm(); } if (algorithmOid != null) { sigAlg = AlgorithmTools.getAlgorithmNameFromOID(algorithmOid); if (sigAlg != null && OcspConfiguration.isAcceptedSignatureAlgorithm(sigAlg) && AlgorithmTools.isCompatibleSigAlg(pk, sigAlg)) { if (log.isDebugEnabled()) { log.debug( "Using OCSP response signature algorithm extracted from OCSP request extension. " + algorithmOid); } return sigAlg; } } } } // the signature algorithm used to sign the OCSPRequest if (req.getSignatureAlgOID() != null) { sigAlg = AlgorithmTools.getAlgorithmNameFromOID(req.getSignatureAlgOID()); if (OcspConfiguration.isAcceptedSignatureAlgorithm(sigAlg) && AlgorithmTools.isCompatibleSigAlg(pk, sigAlg)) { if (log.isDebugEnabled()) { log.debug( "OCSP response signature algorithm: the signature algorithm used to sign the OCSPRequest. " + sigAlg); } return sigAlg; } } // The signature algorithm that has been advertised as being the default signature algorithm for the signing service using an // out-of-band mechanism. if (ocspSigningCacheEntry.isUsingSeparateOcspSigningCertificate()) { // If we have an OcspKeyBinding we use this configuration to override the default sigAlg = ocspSigningCacheEntry.getOcspKeyBinding().getSignatureAlgorithm(); if (log.isDebugEnabled()) { log.debug( "OCSP response signature algorithm: the signature algorithm that has been advertised as being the default signature algorithm " + "for the signing service using an out-of-band mechanism. " + sigAlg); } return sigAlg; } // The signature algorithm specified for the version of OCSP in use. String sigAlgs = OcspConfiguration.getSignatureAlgorithm(); sigAlg = getSigningAlgFromAlgSelection(sigAlgs, pk); if (log.isDebugEnabled()) { log.debug("Using configured signature algorithm to sign OCSP response. " + sigAlg); } return sigAlg; }
From source file:org.cesecore.certificates.ocsp.OcspResponseGeneratorSessionBean.java
/** * Checks the signature on an OCSP request. Does not check for revocation of the signer certificate * /*from www . java 2 s . co m*/ * @param clientRemoteAddr The IP address or host name of the remote client that sent the request, can be null. * @param req The signed OCSPReq * @return X509Certificate which is the certificate that signed the OCSP request * @throws SignRequestSignatureException if signature verification fail, or if the signing certificate is not authorized * @throws SignRequestException if there is no signature on the OCSPReq * @throws OCSPException if the request can not be parsed to retrieve certificates * @throws NoSuchProviderException if the BC provider is not installed * @throws CertificateException if the certificate can not be parsed * @throws NoSuchAlgorithmException if the certificate contains an unsupported algorithm * @throws InvalidKeyException if the certificate, or CA key is invalid */ private X509Certificate checkRequestSignature(String clientRemoteAddr, OCSPReq req) throws SignRequestException, SignRequestSignatureException, CertificateException, NoSuchAlgorithmException { X509Certificate signercert = null; // Get all certificates embedded in the request (probably a certificate chain) try { final X509CertificateHolder[] certs = req.getCerts(); String signerSubjectDn = null; // We must find a certificate to verify the signature with... boolean verifyOK = false; for (int i = 0; i < certs.length; i++) { final X509Certificate certificate = certificateConverter.getCertificate(certs[i]); try { if (req.isSignatureValid( new JcaContentVerifierProviderBuilder().build(certificate.getPublicKey()))) { signercert = certificate; // if the request signature verifies by this certificate, this is the signer cert signerSubjectDn = CertTools.getSubjectDN(signercert); log.info(intres.getLocalizedMessage("ocsp.infosigner", signerSubjectDn)); verifyOK = true; // Check that the signer certificate can be verified by one of the CA-certificates that we answer for final X509Certificate signerca = CaCertificateCache.INSTANCE .findLatestBySubjectDN(HashID.getFromIssuerDN(signercert)); if (signerca != null) { try { signercert.verify(signerca.getPublicKey()); final Date now = new Date(); if (log.isDebugEnabled()) { log.debug("Checking validity. Now: " + now + ", signerNotAfter: " + signercert.getNotAfter()); } try { // Check validity of the request signing certificate CertTools.checkValidity(signercert, now); } catch (CertificateNotYetValidException e) { log.info(intres.getLocalizedMessage("ocsp.infosigner.certnotyetvalid", signerSubjectDn, CertTools.getIssuerDN(signercert), e.getMessage())); verifyOK = false; } catch (CertificateExpiredException e) { log.info(intres.getLocalizedMessage("ocsp.infosigner.certexpired", signerSubjectDn, CertTools.getIssuerDN(signercert), e.getMessage())); verifyOK = false; } try { // Check validity of the CA certificate CertTools.checkValidity(signerca, now); } catch (CertificateNotYetValidException e) { log.info(intres.getLocalizedMessage("ocsp.infosigner.certnotyetvalid", CertTools.getSubjectDN(signerca), CertTools.getIssuerDN(signerca), e.getMessage())); verifyOK = false; } catch (CertificateExpiredException e) { log.info(intres.getLocalizedMessage("ocsp.infosigner.certexpired", CertTools.getSubjectDN(signerca), CertTools.getIssuerDN(signerca), e.getMessage())); verifyOK = false; } } catch (SignatureException e) { log.info(intres.getLocalizedMessage("ocsp.infosigner.invalidcertsignature", signerSubjectDn, CertTools.getIssuerDN(signercert), e.getMessage())); verifyOK = false; } catch (InvalidKeyException e) { log.info(intres.getLocalizedMessage("ocsp.infosigner.invalidcertsignature", signerSubjectDn, CertTools.getIssuerDN(signercert), e.getMessage())); verifyOK = false; } } else { log.info(intres.getLocalizedMessage("ocsp.infosigner.nocacert", signerSubjectDn, CertTools.getIssuerDN(signercert))); verifyOK = false; } break; } } catch (OperatorCreationException e) { // Very fatal error throw new EJBException("Can not create Jca content signer: ", e); } } if (!verifyOK) { if (signerSubjectDn == null && certs.length > 0) { signerSubjectDn = CertTools.getSubjectDN(certificateConverter.getCertificate(certs[0])); } String errMsg = intres.getLocalizedMessage("ocsp.errorinvalidsignature", signerSubjectDn); log.info(errMsg); throw new SignRequestSignatureException(errMsg); } } catch (OCSPException e) { throw new CryptoProviderException("BouncyCastle was not initialized properly.", e); } catch (NoSuchProviderException e) { throw new CryptoProviderException("BouncyCastle was not found as a provider.", e); } return signercert; }
From source file:org.cesecore.certificates.ocsp.OcspResponseGeneratorSessionBean.java
private BasicOCSPResp generateBasicOcspResp(Extensions exts, List<OCSPResponseItem> responses, String sigAlg, X509Certificate signerCert, OcspSigningCacheEntry ocspSigningCacheEntry, Date producedAt) throws OCSPException, NoSuchProviderException, CryptoTokenOfflineException { final PrivateKey signerKey = ocspSigningCacheEntry.getPrivateKey(); final String provider = ocspSigningCacheEntry.getSignatureProviderName(); BasicOCSPResp returnval = null;/*from w ww.jav a 2 s . c o m*/ BasicOCSPRespBuilder basicRes = new BasicOCSPRespBuilder(ocspSigningCacheEntry.getRespId()); if (responses != null) { for (OCSPResponseItem item : responses) { basicRes.addResponse(item.getCertID(), item.getCertStatus(), item.getThisUpdate(), item.getNextUpdate(), item.getExtensions()); } } if (exts != null) { @SuppressWarnings("rawtypes") Enumeration oids = exts.oids(); if (oids.hasMoreElements()) { basicRes.setResponseExtensions(exts); } } final X509Certificate[] chain = ocspSigningCacheEntry.getResponseCertChain(); if (log.isDebugEnabled()) { log.debug("The response certificate chain contains " + chain.length + " certificates"); } /* * The below code breaks the EJB standard by creating its own thread pool and creating a single thread (of the HsmResponseThread * type). The reason for this is that the HSM may deadlock when requesting an OCSP response, which we need to guard against. Since * there is no way of performing this action within the EJB3.0 standard, we are consciously creating threads here. * * Note that this does in no way break the spirit of the EJB standard, which is to not interrupt EJB's transaction handling by * competing with its own thread pool, since these operations have no database impact. */ final Future<BasicOCSPResp> task = service .submit(new HsmResponseThread(basicRes, sigAlg, signerKey, chain, provider, producedAt)); try { returnval = task.get(HsmResponseThread.HSM_TIMEOUT_SECONDS, TimeUnit.SECONDS); } catch (InterruptedException e) { task.cancel(true); throw new Error("OCSP response retrieval was interrupted while running. This should not happen", e); } catch (ExecutionException e) { task.cancel(true); throw new OcspFailureException("Failure encountered while retrieving OCSP response.", e); } catch (TimeoutException e) { task.cancel(true); throw new CryptoTokenOfflineException("HSM timed out while trying to get OCSP response", e); } if (log.isDebugEnabled()) { log.debug("Signing OCSP response with OCSP signer cert: " + signerCert.getSubjectDN().getName()); } if (!returnval.getResponderId().equals(ocspSigningCacheEntry.getRespId())) { log.error("Response responderId does not match signer certificate responderId!"); throw new OcspFailureException("Response responderId does not match signer certificate responderId!"); } if (!ocspSigningCacheEntry.checkResponseSignatureVerified()) { // We only check the response signature the first time for each OcspSigningCacheEntry to detect a misbehaving HSM. // The client is still responsible for validating the signature, see RFC 6960 Section 3.2.2 boolean verify; try { verify = returnval .isSignatureValid(new JcaContentVerifierProviderBuilder().build(signerCert.getPublicKey())); } catch (OperatorCreationException e) { // Very fatal error throw new EJBException("Can not create Jca content signer: ", e); } if (verify) { if (log.isDebugEnabled()) { log.debug("The OCSP response is verifying."); } } else { log.error("The response is NOT verifying! Attempted to sign using " + CertTools.getSubjectDN(signerCert) + " but signature was not valid."); throw new OcspFailureException("Attempted to sign using " + CertTools.getSubjectDN(signerCert) + " but signature was not valid."); } } return returnval; }
From source file:org.cesecore.certificates.ocsp.OcspResponseGeneratorSessionBean.java
@Override public String healthCheck() { final StringBuilder sb = new StringBuilder(); // Check that there are no ACTIVE OcspKeyBindings that are not in the cache before checking usability.. for (InternalKeyBindingInfo internalKeyBindingInfo : internalKeyBindingMgmtSession .getAllInternalKeyBindingInfos(OcspKeyBinding.IMPLEMENTATION_ALIAS)) { if (internalKeyBindingInfo.getStatus().equals(InternalKeyBindingStatus.ACTIVE)) { final Certificate ocspCertificate = certificateStoreSession .findCertificateByFingerprint(internalKeyBindingInfo.getCertificateId()); final X509Certificate issuingCertificate = certificateStoreSession .findLatestX509CertificateBySubject(CertTools.getIssuerDN(ocspCertificate)); OcspSigningCacheEntry ocspSigningCacheEntry = null; if (issuingCertificate != null) { final List<CertificateID> certIds = OcspSigningCache .getCertificateIDFromCertificate(issuingCertificate); // We only need to use the first certId type to find an entry in the cache, certIds.get(0), since all of them should be in the cache ocspSigningCacheEntry = OcspSigningCache.INSTANCE.getEntry(certIds.get(0)); if (ocspSigningCacheEntry == null) { //Could be a cache issue? try { ocspSigningCacheEntry = findAndAddMissingCacheEntry(certIds.get(0)); } catch (CertificateEncodingException e) { throw new IllegalStateException("Could not process certificate", e); }/* w ww . ja v a2 s . c o m*/ } } else { log.info("Can not find issuer certificate from subject DN '" + CertTools.getIssuerDN(ocspCertificate) + "'."); } if (ocspSigningCacheEntry == null) { final String errMsg = intres.getLocalizedMessage("ocsp.signingkeynotincache", internalKeyBindingInfo.getName()); sb.append('\n').append(errMsg); log.error(errMsg); } } } if (!sb.toString().equals("")) { return sb.toString(); } try { final Collection<OcspSigningCacheEntry> ocspSigningCacheEntries = OcspSigningCache.INSTANCE .getEntries(); if (ocspSigningCacheEntries.isEmpty()) { // Only report this in the server log. It is not an erroneous state to have no ACTIVE OcspKeyBindings. if (log.isDebugEnabled()) { log.debug(intres.getLocalizedMessage("ocsp.errornosignkeys")); } } else { for (OcspSigningCacheEntry ocspSigningCacheEntry : ocspSigningCacheEntries) { // Only verify non-CA responders final X509Certificate ocspSigningCertificate = ocspSigningCacheEntry .getOcspSigningCertificate(); if (ocspSigningCertificate == null) { continue; } final String subjectDn = CertTools .getSubjectDN(ocspSigningCacheEntry.getCaCertificateChain().get(0)); final String serialNumberForLog = CertTools .getSerialNumberAsString(ocspSigningCacheEntry.getOcspSigningCertificate()); final String errMsg = intres.getLocalizedMessage("ocsp.errorocspkeynotusable", subjectDn, serialNumberForLog); final PrivateKey privateKey = ocspSigningCacheEntry.getPrivateKey(); if (privateKey == null) { sb.append('\n').append(errMsg); log.error("No key available. " + errMsg); continue; } if (OcspConfiguration.getHealthCheckCertificateValidity() && !CertTools.isCertificateValid(ocspSigningCertificate)) { sb.append('\n').append(errMsg); continue; } if (OcspConfiguration.getHealthCheckSignTest()) { try { final String providerName = ocspSigningCacheEntry.getSignatureProviderName(); KeyTools.testKey(privateKey, ocspSigningCertificate.getPublicKey(), providerName); } catch (InvalidKeyException e) { // thrown by testKey sb.append('\n').append(errMsg); log.error("Key not working. SubjectDN '" + subjectDn + "'. Error comment '" + errMsg + "'. Message '" + e.getMessage()); continue; } } if (log.isDebugEnabled()) { final String name = ocspSigningCacheEntry.getOcspKeyBinding().getName(); log.debug("Test of \"" + name + "\" OK!"); } } } } catch (Exception e) { final String errMsg = intres.getLocalizedMessage("ocsp.errorloadsigningcerts"); log.error(errMsg, e); sb.append(errMsg).append(": ").append(errMsg); } return sb.toString(); }
From source file:org.cesecore.certificates.ocsp.CanLogCache.java
private BasicOCSPRespGenerator createOcspResponseGenerator(OCSPReq req, X509Certificate respondercert, int respIdType) throws OCSPException, NotSupportedException { if (null == req) { throw new IllegalArgumentException(); }// w ww. j a v a2 s. c om BasicOCSPRespGenerator res = null; if (respIdType == OcspConfiguration.RESPONDERIDTYPE_NAME) { res = new BasicOCSPRespGenerator(new RespID(respondercert.getSubjectX500Principal())); } else { res = new BasicOCSPRespGenerator(respondercert.getPublicKey()); } X509Extensions reqexts = req.getRequestExtensions(); if (reqexts != null) { X509Extension ext = reqexts.getExtension(OCSPObjectIdentifiers.id_pkix_ocsp_response); if (null != ext) { // log.debug("Found extension AcceptableResponses"); ASN1OctetString oct = ext.getValue(); try { ASN1Sequence seq = ASN1Sequence.getInstance( new ASN1InputStream(new ByteArrayInputStream(oct.getOctets())).readObject()); @SuppressWarnings("unchecked") Enumeration<DERObjectIdentifier> en = seq.getObjects(); boolean supportsResponseType = false; while (en.hasMoreElements()) { DERObjectIdentifier oid = en.nextElement(); // log.debug("Found oid: "+oid.getId()); if (oid.equals(OCSPObjectIdentifiers.id_pkix_ocsp_basic)) { // This is the response type we support, so we are happy! Break the loop. supportsResponseType = true; log.debug("Response type supported: " + oid.getId()); continue; } } if (!supportsResponseType) { throw new NotSupportedException( "Required response type not supported, this responder only supports id-pkix-ocsp-basic."); } } catch (IOException e) { } } } return res; }
From source file:org.cesecore.certificates.ocsp.CanLogCache.java
/** * Checks the signature on an OCSP request and checks that it is signed by an allowed CA. Does not check for revocation of the signer certificate * // w ww.j av a 2 s.co m * @param clientRemoteAddr The IP address or host name of the remote client that sent the request, can be null. * @param req The signed OCSPReq * @return X509Certificate which is the certificate that signed the OCSP request * @throws SignRequestSignatureException if signature verification fail, or if the signing certificate is not authorized * @throws SignRequestException if there is no signature on the OCSPReq * @throws OCSPException if the request can not be parsed to retrieve certificates * @throws NoSuchProviderException if the BC provider is not installed * @throws CertificateException if the certificate can not be parsed * @throws NoSuchAlgorithmException if the certificate contains an unsupported algorithm * @throws InvalidKeyException if the certificate, or CA key is invalid */ private X509Certificate checkRequestSignature(String clientRemoteAddr, OCSPReq req) throws SignRequestException, SignRequestSignatureException, CertificateException, NoSuchAlgorithmException { X509Certificate signercert = null; if (!req.isSigned()) { String infoMsg = intres.getLocalizedMessage("ocsp.errorunsignedreq", clientRemoteAddr); log.info(infoMsg); throw new SignRequestException(infoMsg); } // Get all certificates embedded in the request (probably a certificate chain) try { X509Certificate[] certs = req.getCerts("BC"); // Set, as a try, the signer to be the first certificate, so we have a name to log... String signer = null; if (certs.length > 0) { signer = CertTools.getSubjectDN(certs[0]); } // We must find a certificate to verify the signature with... boolean verifyOK = false; for (int i = 0; i < certs.length; i++) { if (req.verify(certs[i].getPublicKey(), "BC") == true) { signercert = certs[i]; signer = CertTools.getSubjectDN(signercert); Date now = new Date(); String signerissuer = CertTools.getIssuerDN(signercert); String infoMsg = intres.getLocalizedMessage("ocsp.infosigner", signer); log.info(infoMsg); verifyOK = true; /* * Also check that the signer certificate can be verified by one of the CA-certificates that we answer for */ X509Certificate signerca = certificateStoreSession .findLatestX509CertificateBySubject(CertTools.getIssuerDN(certs[i])); String subject = signer; String issuer = signerissuer; if (signerca != null) { try { signercert.verify(signerca.getPublicKey()); if (log.isDebugEnabled()) { log.debug("Checking validity. Now: " + now + ", signerNotAfter: " + signercert.getNotAfter()); } CertTools.checkValidity(signercert, now); // Move the error message string to the CA cert subject = CertTools.getSubjectDN(signerca); issuer = CertTools.getIssuerDN(signerca); CertTools.checkValidity(signerca, now); } catch (SignatureException e) { infoMsg = intres.getLocalizedMessage("ocsp.infosigner.invalidcertsignature", subject, issuer, e.getMessage()); log.info(infoMsg); verifyOK = false; } catch (InvalidKeyException e) { infoMsg = intres.getLocalizedMessage("ocsp.infosigner.invalidcertsignature", subject, issuer, e.getMessage()); log.info(infoMsg); verifyOK = false; } catch (CertificateNotYetValidException e) { infoMsg = intres.getLocalizedMessage("ocsp.infosigner.certnotyetvalid", subject, issuer, e.getMessage()); log.info(infoMsg); verifyOK = false; } catch (CertificateExpiredException e) { infoMsg = intres.getLocalizedMessage("ocsp.infosigner.certexpired", subject, issuer, e.getMessage()); log.info(infoMsg); verifyOK = false; } } else { infoMsg = intres.getLocalizedMessage("ocsp.infosigner.nocacert", signer, signerissuer); log.info(infoMsg); verifyOK = false; } break; } } if (!verifyOK) { String errMsg = intres.getLocalizedMessage("ocsp.errorinvalidsignature", signer); log.info(errMsg); throw new SignRequestSignatureException(errMsg); } } catch (OCSPException e) { throw new CryptoProviderException("BouncyCastle was not initialized properly.", e); } catch (NoSuchProviderException e) { throw new CryptoProviderException("BouncyCastle was not found as a provider.", e); } return signercert; }
From source file:org.cesecore.certificates.ocsp.CanLogCache.java
private BasicOCSPResp signOcspResponse(OCSPReq req, List<OCSPResponseItem> responseList, X509Extensions exts, final X509Certificate[] signerChain, final PrivateKey privateKey, String privateKeyProvider) throws CADoesntExistsException, ExtendedCAServiceRequestException, IllegalExtendedCAServiceRequestException, ExtendedCAServiceNotActiveException, AuthorizationDeniedException, CryptoTokenOfflineException, IllegalCryptoTokenException { final X509Certificate[] certChain = Arrays.asList(signerChain).toArray(new X509Certificate[0]); final X509Certificate signerCert = certChain[0]; final String sigAlgs = OcspConfiguration.getSignatureAlgorithm(); final PublicKey pk = signerCert.getPublicKey(); final String sigAlg = getSigningAlgFromAlgSelection(sigAlgs, pk); if (log.isDebugEnabled()) { log.debug("Signing algorithm: " + sigAlg); }//from w ww. j a va 2 s. com final boolean includeChain = OcspConfiguration.getIncludeCertChain(); if (log.isDebugEnabled()) { log.debug("Include chain: " + includeChain); } final X509Certificate[] chain; if (includeChain) { chain = certChain; } else { chain = new X509Certificate[1]; chain[0] = signerCert; } try { final int respIdType = OcspConfiguration.getResponderIdType(); final BasicOCSPResp ocspresp = generateBasicOcspResp(req, exts, responseList, sigAlg, signerCert, privateKey, privateKeyProvider, chain, respIdType); // Now we can use the returned OCSPServiceResponse to get private key and cetificate chain to sign the ocsp response if (log.isDebugEnabled()) { Collection<X509Certificate> coll = Arrays.asList(chain); log.debug("Cert chain for OCSP signing is of size " + coll.size()); } if (isCertificateValid(signerCert)) { return ocspresp; } else { throw new OcspFailureException("Response was not validly signed."); } } catch (OCSPException ocspe) { throw new OcspFailureException(ocspe); } catch (NoSuchProviderException nspe) { throw new OcspFailureException(nspe); } catch (NotSupportedException e) { log.info("OCSP Request type not supported: ", e); throw new OcspFailureException(e); } catch (IllegalArgumentException e) { log.error("IllegalArgumentException: ", e); throw new OcspFailureException(e); } }