List of usage examples for org.bouncycastle.cert.ocsp CertificateID getIssuerNameHash
public byte[] getIssuerNameHash()
From source file:eu.europa.ec.markt.dss.DSSRevocationUtils.java
License:Open Source License
/** * fix for certId.equals methods that doesn't work very well. * * @param certId {@code CertificateID} * @param singleResp {@code SingleResp}/*from w ww . ja v a2 s .c o m*/ * @return true if the certificate matches this included in {@code SingleResp} */ public static boolean matches(final CertificateID certId, final SingleResp singleResp) { final CertificateID singleRespCertID = singleResp.getCertID(); final ASN1ObjectIdentifier singleRespCertIDHashAlgOID = singleRespCertID.getHashAlgOID(); final byte[] singleRespCertIDIssuerKeyHash = singleRespCertID.getIssuerKeyHash(); final byte[] singleRespCertIDIssuerNameHash = singleRespCertID.getIssuerNameHash(); final BigInteger singleRespCertIDSerialNumber = singleRespCertID.getSerialNumber(); final ASN1ObjectIdentifier certIdHashAlgOID = certId.getHashAlgOID(); final byte[] certIdIssuerKeyHash = certId.getIssuerKeyHash(); final byte[] certIdIssuerNameHash = certId.getIssuerNameHash(); final BigInteger certIdSerialNumber = certId.getSerialNumber(); // certId.equals fails in comparing the algoIdentifier because AlgoIdentifier params in null in one case and DERNull in another case return singleRespCertIDHashAlgOID.equals(certIdHashAlgOID) && Arrays.areEqual(singleRespCertIDIssuerKeyHash, certIdIssuerKeyHash) && Arrays.areEqual(singleRespCertIDIssuerNameHash, certIdIssuerNameHash) && singleRespCertIDSerialNumber.equals(certIdSerialNumber); }
From source file:eu.europa.esig.dss.DSSRevocationUtils.java
License:Open Source License
/** * fix for certId.equals methods that doesn't work very well. * * @param certId// ww w. ja v a2 s . c o m * {@code CertificateID} * @param singleResp * {@code SingleResp} * @return true if the certificate matches this included in * {@code SingleResp} */ public static boolean matches(final CertificateID certId, final SingleResp singleResp) { final CertificateID singleRespCertID = singleResp.getCertID(); final ASN1ObjectIdentifier singleRespCertIDHashAlgOID = singleRespCertID.getHashAlgOID(); final byte[] singleRespCertIDIssuerKeyHash = singleRespCertID.getIssuerKeyHash(); final byte[] singleRespCertIDIssuerNameHash = singleRespCertID.getIssuerNameHash(); final BigInteger singleRespCertIDSerialNumber = singleRespCertID.getSerialNumber(); final ASN1ObjectIdentifier certIdHashAlgOID = certId.getHashAlgOID(); final byte[] certIdIssuerKeyHash = certId.getIssuerKeyHash(); final byte[] certIdIssuerNameHash = certId.getIssuerNameHash(); final BigInteger certIdSerialNumber = certId.getSerialNumber(); // certId.equals fails in comparing the algoIdentifier because // AlgoIdentifier params in null in one case and DERNull in another case return singleRespCertIDHashAlgOID.equals(certIdHashAlgOID) && Arrays.areEqual(singleRespCertIDIssuerKeyHash, certIdIssuerKeyHash) && Arrays.areEqual(singleRespCertIDIssuerNameHash, certIdIssuerNameHash) && singleRespCertIDSerialNumber.equals(certIdSerialNumber); }
From source file:org.cesecore.certificates.ocsp.cache.OcspSigningCache.java
License:Open Source License
/** @return a cache identifier based on the provided CertificateID. */ public static int getCacheIdFromCertificateID(final CertificateID certID) { // Use bitwise XOR of the hashcodes for IssuerNameHash and IssuerKeyHash to produce the integer. int result = new BigInteger(certID.getIssuerNameHash()).hashCode() ^ new BigInteger(certID.getIssuerKeyHash()).hashCode(); if (log.isDebugEnabled()) { log.debug("Using getIssuerNameHash " + new BigInteger(certID.getIssuerNameHash()).toString(16) + " and getIssuerKeyHash " + new BigInteger(certID.getIssuerKeyHash()).toString(16) + " to produce id " + result); }//w w w. ja v a 2 s .com return result; }
From source file:org.cesecore.certificates.ocsp.OcspResponseGeneratorSessionBean.java
License:Open Source License
@Override public OcspResponseInformation getOcspResponse(final byte[] request, final X509Certificate[] requestCertificates, String remoteAddress, String remoteHost, StringBuffer requestUrl, final AuditLogger auditLogger, final TransactionLogger transactionLogger) throws MalformedRequestException, OCSPException { //Check parameters if (auditLogger == null) { throw new InvalidParameterException( "Illegal to pass a null audit logger to OcspResponseSession.getOcspResponse"); }/*from www . j a va2s .co m*/ if (transactionLogger == null) { throw new InvalidParameterException( "Illegal to pass a null transaction logger to OcspResponseSession.getOcspResponse"); } // Validate byte array. if (request.length > MAX_REQUEST_SIZE) { final String msg = intres.getLocalizedMessage("request.toolarge", MAX_REQUEST_SIZE, request.length); throw new MalformedRequestException(msg); } byte[] respBytes = null; final Date startTime = new Date(); OCSPResp ocspResponse = null; // Start logging process time after we have received the request if (transactionLogger.isEnabled()) { transactionLogger.paramPut(PatternLogger.PROCESS_TIME, PatternLogger.PROCESS_TIME); } if (auditLogger.isEnabled()) { auditLogger.paramPut(PatternLogger.PROCESS_TIME, PatternLogger.PROCESS_TIME); auditLogger.paramPut(AuditLogger.OCSPREQUEST, new String(Hex.encode(request))); } OCSPReq req; long maxAge = OcspConfiguration.getMaxAge(CertificateProfileConstants.CERTPROFILE_NO_PROFILE); OCSPRespBuilder responseGenerator = new OCSPRespBuilder(); try { req = translateRequestFromByteArray(request, remoteAddress, transactionLogger); // Get the certificate status requests that are inside this OCSP req Req[] ocspRequests = req.getRequestList(); if (ocspRequests.length <= 0) { String infoMsg = intres.getLocalizedMessage("ocsp.errornoreqentities"); log.info(infoMsg); throw new MalformedRequestException(infoMsg); } final int maxRequests = 100; if (ocspRequests.length > maxRequests) { String infoMsg = intres.getLocalizedMessage("ocsp.errortoomanyreqentities", maxRequests); log.info(infoMsg); throw new MalformedRequestException(infoMsg); } if (log.isDebugEnabled()) { log.debug("The OCSP request contains " + ocspRequests.length + " simpleRequests."); } if (transactionLogger.isEnabled()) { transactionLogger.paramPut(TransactionLogger.NUM_CERT_ID, ocspRequests.length); transactionLogger.paramPut(TransactionLogger.STATUS, OCSPRespBuilder.SUCCESSFUL); } if (auditLogger.isEnabled()) { auditLogger.paramPut(AuditLogger.STATUS, OCSPRespBuilder.SUCCESSFUL); } OcspSigningCacheEntry ocspSigningCacheEntry = null; long nextUpdate = OcspConfiguration .getUntilNextUpdate(CertificateProfileConstants.CERTPROFILE_NO_PROFILE); // Add standard response extensions Map<ASN1ObjectIdentifier, Extension> responseExtensions = getStandardResponseExtensions(req); // Look for extension OIDs final Collection<String> extensionOids = OcspConfiguration.getExtensionOids(); // Look over the status requests List<OCSPResponseItem> responseList = new ArrayList<OCSPResponseItem>(); boolean addExtendedRevokedExtension = false; Date producedAt = null; for (Req ocspRequest : ocspRequests) { CertificateID certId = ocspRequest.getCertID(); ASN1ObjectIdentifier certIdhash = certId.getHashAlgOID(); if (!OIWObjectIdentifiers.idSHA1.equals(certIdhash) && !NISTObjectIdentifiers.id_sha256.equals(certIdhash)) { throw new InvalidAlgorithmException( "CertID with SHA1 and SHA256 are supported, not: " + certIdhash.getId()); } if (transactionLogger.isEnabled()) { transactionLogger.paramPut(TransactionLogger.SERIAL_NOHEX, certId.getSerialNumber().toByteArray()); transactionLogger.paramPut(TransactionLogger.DIGEST_ALGOR, certId.getHashAlgOID().toString()); transactionLogger.paramPut(TransactionLogger.ISSUER_NAME_HASH, certId.getIssuerNameHash()); transactionLogger.paramPut(TransactionLogger.ISSUER_KEY, certId.getIssuerKeyHash()); } if (auditLogger.isEnabled()) { auditLogger.paramPut(AuditLogger.ISSUER_KEY, certId.getIssuerKeyHash()); auditLogger.paramPut(AuditLogger.SERIAL_NOHEX, certId.getSerialNumber().toByteArray()); auditLogger.paramPut(AuditLogger.ISSUER_NAME_HASH, certId.getIssuerNameHash()); } byte[] hashbytes = certId.getIssuerNameHash(); String hash = null; if (hashbytes != null) { hash = new String(Hex.encode(hashbytes)); } String infoMsg = intres.getLocalizedMessage("ocsp.inforeceivedrequest", certId.getSerialNumber().toString(16), hash, remoteAddress); log.info(infoMsg); // Locate the CA which gave out the certificate ocspSigningCacheEntry = OcspSigningCache.INSTANCE.getEntry(certId); if (ocspSigningCacheEntry == null) { //Could it be that we haven't updated the OCSP Signing Cache? ocspSigningCacheEntry = findAndAddMissingCacheEntry(certId); } if (ocspSigningCacheEntry != null) { if (transactionLogger.isEnabled()) { // This will be the issuer DN of the signing certificate, whether an OCSP responder or an internal CA String issuerNameDn = CertTools .getIssuerDN(ocspSigningCacheEntry.getFullCertificateChain().get(0)); transactionLogger.paramPut(TransactionLogger.ISSUER_NAME_DN, issuerNameDn); } } else { /* * if the certId was issued by an unknown CA * * The algorithm here: * We will sign the response with the CA that issued the last certificate(certId) in the request. If the issuing CA is not available on * this server, we sign the response with the default responderId (from params in web.xml). We have to look up the ca-certificate for * each certId in the request though, as we will check for revocation on the ca-cert as well when checking for revocation on the certId. */ // We could not find certificate for this request so get certificate for default responder ocspSigningCacheEntry = OcspSigningCache.INSTANCE.getDefaultEntry(); if (ocspSigningCacheEntry != null) { String errMsg = intres.getLocalizedMessage("ocsp.errorfindcacertusedefault", new String(Hex.encode(certId.getIssuerNameHash()))); log.info(errMsg); // If we can not find the CA, answer UnknowStatus responseList.add(new OCSPResponseItem(certId, new UnknownStatus(), nextUpdate)); if (transactionLogger.isEnabled()) { transactionLogger.paramPut(TransactionLogger.CERT_STATUS, OCSPResponseItem.OCSP_UNKNOWN); transactionLogger.writeln(); } continue; } else { GlobalOcspConfiguration ocspConfiguration = (GlobalOcspConfiguration) globalConfigurationSession .getCachedConfiguration(GlobalOcspConfiguration.OCSP_CONFIGURATION_ID); String defaultResponder = ocspConfiguration.getOcspDefaultResponderReference(); String errMsg = intres.getLocalizedMessage("ocsp.errorfindcacert", new String(Hex.encode(certId.getIssuerNameHash())), defaultResponder); log.error(errMsg); // If we are responding to multiple requests, the last found ocspSigningCacheEntry will be used in the end // so even if there are not any one now, it might be later when it is time to sign the responses. // Since we only will sign the entire response once if there is at least one valid ocspSigningCacheEntry // we might as well include the unknown requests. responseList.add(new OCSPResponseItem(certId, new UnknownStatus(), nextUpdate)); continue; } } final org.bouncycastle.cert.ocsp.CertificateStatus certStatus; // Check if the cacert (or the default responderid) is revoked X509Certificate caCertificate = ocspSigningCacheEntry.getIssuerCaCertificate(); final CertificateStatus signerIssuerCertStatus = ocspSigningCacheEntry .getIssuerCaCertificateStatus(); final String caCertificateSubjectDn = CertTools.getSubjectDN(caCertificate); CertificateStatusHolder certificateStatusHolder = null; if (signerIssuerCertStatus.equals(CertificateStatus.REVOKED)) { /* * According to chapter 2.7 in RFC2560: * * 2.7 CA Key Compromise If an OCSP responder knows that a particular CA's private key has been compromised, it MAY return the revoked * state for all certificates issued by that CA. */ // If we've ended up here it's because the signer issuer certificate was revoked. certStatus = new RevokedStatus( new RevokedInfo(new ASN1GeneralizedTime(signerIssuerCertStatus.revocationDate), CRLReason.lookup(signerIssuerCertStatus.revocationReason))); infoMsg = intres.getLocalizedMessage("ocsp.signcertissuerrevoked", CertTools.getSerialNumberAsString(caCertificate), CertTools.getSubjectDN(caCertificate)); log.info(infoMsg); responseList.add(new OCSPResponseItem(certId, certStatus, nextUpdate)); if (transactionLogger.isEnabled()) { transactionLogger.paramPut(TransactionLogger.CERT_STATUS, OCSPResponseItem.OCSP_REVOKED); transactionLogger.writeln(); } } else { /** * Here is the actual check for the status of the sought certificate (easy to miss). Here we grab just the status if there aren't * any OIDs defined (default case), but if there are we'll probably need the certificate as well. If that's the case, we'll grab * the certificate in the same transaction. */ final CertificateStatus status; if (extensionOids.isEmpty()) { status = certificateStoreSession.getStatus(caCertificateSubjectDn, certId.getSerialNumber()); } else { certificateStatusHolder = certificateStoreSession .getCertificateAndStatus(caCertificateSubjectDn, certId.getSerialNumber()); status = certificateStatusHolder.getCertificateStatus(); } // If we have an OcspKeyBinding configured for this request, we override the default value if (ocspSigningCacheEntry.isUsingSeparateOcspSigningCertificate()) { nextUpdate = ocspSigningCacheEntry.getOcspKeyBinding().getUntilNextUpdate() * 1000L; } // If we have an explicit value configured for this certificate profile, we override the the current value with this value if (status.certificateProfileId != CertificateProfileConstants.CERTPROFILE_NO_PROFILE && OcspConfiguration.isUntilNextUpdateConfigured(status.certificateProfileId)) { nextUpdate = OcspConfiguration.getUntilNextUpdate(status.certificateProfileId); } // If we have an OcspKeyBinding configured for this request, we override the default value if (ocspSigningCacheEntry.isUsingSeparateOcspSigningCertificate()) { maxAge = ocspSigningCacheEntry.getOcspKeyBinding().getMaxAge() * 1000L; } // If we have an explicit value configured for this certificate profile, we override the the current value with this value if (status.certificateProfileId != CertificateProfileConstants.CERTPROFILE_NO_PROFILE && OcspConfiguration.isMaxAgeConfigured(status.certificateProfileId)) { maxAge = OcspConfiguration.getMaxAge(status.certificateProfileId); } final String sStatus; boolean addArchiveCutoff = false; if (status.equals(CertificateStatus.NOT_AVAILABLE)) { // No revocation info available for this cert, handle it if (log.isDebugEnabled()) { log.debug("Unable to find revocation information for certificate with serial '" + certId.getSerialNumber().toString(16) + "'" + " from issuer '" + caCertificateSubjectDn + "'"); } /* * If we do not treat non existing certificates as good or revoked * OR * we don't actually handle requests for the CA issuing the certificate asked about * then we return unknown * */ if (OcspConfigurationCache.INSTANCE.isNonExistingGood(requestUrl, ocspSigningCacheEntry.getOcspKeyBinding()) && OcspSigningCache.INSTANCE.getEntry(certId) != null) { sStatus = "good"; certStatus = null; // null means "good" in OCSP if (transactionLogger.isEnabled()) { transactionLogger.paramPut(TransactionLogger.CERT_STATUS, OCSPResponseItem.OCSP_GOOD); } } else if (OcspConfigurationCache.INSTANCE.isNonExistingRevoked(requestUrl, ocspSigningCacheEntry.getOcspKeyBinding()) && OcspSigningCache.INSTANCE.getEntry(certId) != null) { sStatus = "revoked"; certStatus = new RevokedStatus(new RevokedInfo(new ASN1GeneralizedTime(new Date(0)), CRLReason.lookup(CRLReason.certificateHold))); if (transactionLogger.isEnabled()) { transactionLogger.paramPut(TransactionLogger.CERT_STATUS, OCSPResponseItem.OCSP_REVOKED); } addExtendedRevokedExtension = true; } else { sStatus = "unknown"; certStatus = new UnknownStatus(); if (transactionLogger.isEnabled()) { transactionLogger.paramPut(TransactionLogger.CERT_STATUS, OCSPResponseItem.OCSP_UNKNOWN); } } } else if (status.equals(CertificateStatus.REVOKED)) { // Revocation info available for this cert, handle it sStatus = "revoked"; certStatus = new RevokedStatus( new RevokedInfo(new ASN1GeneralizedTime(status.revocationDate), CRLReason.lookup(status.revocationReason))); if (transactionLogger.isEnabled()) { transactionLogger.paramPut(TransactionLogger.CERT_STATUS, OCSPResponseItem.OCSP_REVOKED); } // If we have an explicit value configured for this certificate profile, we override the the current value with this value if (status.certificateProfileId != CertificateProfileConstants.CERTPROFILE_NO_PROFILE && OcspConfiguration .isRevokedUntilNextUpdateConfigured(status.certificateProfileId)) { nextUpdate = OcspConfiguration.getRevokedUntilNextUpdate(status.certificateProfileId); } // If we have an explicit value configured for this certificate profile, we override the the current value with this value if (status.certificateProfileId != CertificateProfileConstants.CERTPROFILE_NO_PROFILE && OcspConfiguration.isRevokedMaxAgeConfigured(status.certificateProfileId)) { maxAge = OcspConfiguration.getRevokedMaxAge(status.certificateProfileId); } } else { sStatus = "good"; certStatus = null; if (transactionLogger.isEnabled()) { transactionLogger.paramPut(TransactionLogger.CERT_STATUS, OCSPResponseItem.OCSP_GOOD); } addArchiveCutoff = checkAddArchiveCuttoff(caCertificateSubjectDn, certId); } if (log.isDebugEnabled()) { log.debug("Set nextUpdate=" + nextUpdate + ", and maxAge=" + maxAge + " for certificateProfileId=" + status.certificateProfileId); } infoMsg = intres.getLocalizedMessage("ocsp.infoaddedstatusinfo", sStatus, certId.getSerialNumber().toString(16), caCertificateSubjectDn); log.info(infoMsg); OCSPResponseItem respItem = new OCSPResponseItem(certId, certStatus, nextUpdate); if (addArchiveCutoff) { addArchiveCutoff(respItem); producedAt = new Date(); } responseList.add(respItem); if (transactionLogger.isEnabled()) { transactionLogger.writeln(); } } for (String oidstr : extensionOids) { boolean useAlways = false; if (oidstr.startsWith("*")) { oidstr = oidstr.substring(1, oidstr.length()); useAlways = true; } ASN1ObjectIdentifier oid = new ASN1ObjectIdentifier(oidstr); Extension extension = null; if (!useAlways) { // Only check if extension exists if we are not already bound to use it if (req.hasExtensions()) { extension = req.getExtension(oid); } } //If found, or if it should be used anyway if (useAlways || extension != null) { // We found an extension, call the extension class if (log.isDebugEnabled()) { log.debug("Found OCSP extension oid: " + oidstr); } OCSPExtension extObj = OcspExtensionsCache.INSTANCE.getExtensions().get(oidstr); if (extObj != null) { // Find the certificate from the certId if (certificateStatusHolder != null && certificateStatusHolder.getCertificate() != null) { X509Certificate cert = (X509Certificate) certificateStatusHolder.getCertificate(); // Call the OCSP extension Map<ASN1ObjectIdentifier, Extension> retext = extObj.process(requestCertificates, remoteAddress, remoteHost, cert, certStatus); if (retext != null) { // Add the returned X509Extensions to the responseExtension we will add to the basic OCSP response responseExtensions.putAll(retext); } else { String errMsg = intres.getLocalizedMessage("ocsp.errorprocessextension", extObj.getClass().getName(), Integer.valueOf(extObj.getLastErrorCode())); log.error(errMsg); } } } } } } if (addExtendedRevokedExtension) { // id-pkix-ocsp-extended-revoke OBJECT IDENTIFIER ::= {id-pkix-ocsp 9} final ASN1ObjectIdentifier extendedRevokedOID = new ASN1ObjectIdentifier( OCSPObjectIdentifiers.id_pkix_ocsp + ".9"); try { responseExtensions.put(extendedRevokedOID, new Extension(extendedRevokedOID, false, DERNull.INSTANCE.getEncoded())); } catch (IOException e) { throw new IllegalStateException("Could not get encodig from DERNull.", e); } } if (ocspSigningCacheEntry != null) { // Add responseExtensions Extensions exts = new Extensions(responseExtensions.values().toArray(new Extension[0])); // generate the signed response object BasicOCSPResp basicresp = signOcspResponse(req, responseList, exts, ocspSigningCacheEntry, producedAt); ocspResponse = responseGenerator.build(OCSPRespBuilder.SUCCESSFUL, basicresp); if (auditLogger.isEnabled()) { auditLogger.paramPut(AuditLogger.STATUS, OCSPRespBuilder.SUCCESSFUL); } if (transactionLogger.isEnabled()) { transactionLogger.paramPut(TransactionLogger.STATUS, OCSPRespBuilder.SUCCESSFUL); } } else { // Only unknown CAs in requests and no default responder's cert, return an unsigned response if (log.isDebugEnabled()) { log.debug(intres.getLocalizedMessage("ocsp.errornocacreateresp")); } ocspResponse = responseGenerator.build(OCSPRespBuilder.UNAUTHORIZED, null); if (auditLogger.isEnabled()) { auditLogger.paramPut(AuditLogger.STATUS, OCSPRespBuilder.UNAUTHORIZED); } if (transactionLogger.isEnabled()) { transactionLogger.paramPut(TransactionLogger.STATUS, OCSPRespBuilder.UNAUTHORIZED); } } } catch (SignRequestException e) { if (transactionLogger.isEnabled()) { transactionLogger.paramPut(PatternLogger.PROCESS_TIME, PatternLogger.PROCESS_TIME); } if (auditLogger.isEnabled()) { auditLogger.paramPut(PatternLogger.PROCESS_TIME, PatternLogger.PROCESS_TIME); } String errMsg = intres.getLocalizedMessage("ocsp.errorprocessreq", e.getMessage()); log.info(errMsg); // No need to log the full exception here // RFC 2560: responseBytes are not set on error. ocspResponse = responseGenerator.build(OCSPRespBuilder.SIG_REQUIRED, null); if (transactionLogger.isEnabled()) { transactionLogger.paramPut(TransactionLogger.STATUS, OCSPRespBuilder.SIG_REQUIRED); transactionLogger.writeln(); } if (auditLogger.isEnabled()) { auditLogger.paramPut(AuditLogger.STATUS, OCSPRespBuilder.SIG_REQUIRED); } } catch (SignRequestSignatureException e) { if (transactionLogger.isEnabled()) { transactionLogger.paramPut(PatternLogger.PROCESS_TIME, PatternLogger.PROCESS_TIME); } if (auditLogger.isEnabled()) { auditLogger.paramPut(PatternLogger.PROCESS_TIME, PatternLogger.PROCESS_TIME); } String errMsg = intres.getLocalizedMessage("ocsp.errorprocessreq", e.getMessage()); log.info(errMsg); // No need to log the full exception here // RFC 2560: responseBytes are not set on error. ocspResponse = responseGenerator.build(OCSPRespBuilder.UNAUTHORIZED, null); if (transactionLogger.isEnabled()) { transactionLogger.paramPut(TransactionLogger.STATUS, OCSPRespBuilder.UNAUTHORIZED); transactionLogger.writeln(); } if (auditLogger.isEnabled()) { auditLogger.paramPut(AuditLogger.STATUS, OCSPRespBuilder.UNAUTHORIZED); } } catch (InvalidAlgorithmException e) { if (transactionLogger.isEnabled()) { transactionLogger.paramPut(PatternLogger.PROCESS_TIME, PatternLogger.PROCESS_TIME); } if (auditLogger.isEnabled()) { auditLogger.paramPut(PatternLogger.PROCESS_TIME, PatternLogger.PROCESS_TIME); } String errMsg = intres.getLocalizedMessage("ocsp.errorprocessreq", e.getMessage()); log.info(errMsg); // No need to log the full exception here // RFC 2560: responseBytes are not set on error. ocspResponse = responseGenerator.build(OCSPRespBuilder.MALFORMED_REQUEST, null); if (transactionLogger.isEnabled()) { transactionLogger.paramPut(TransactionLogger.STATUS, OCSPRespBuilder.MALFORMED_REQUEST); transactionLogger.writeln(); } if (auditLogger.isEnabled()) { auditLogger.paramPut(AuditLogger.STATUS, OCSPRespBuilder.MALFORMED_REQUEST); } } catch (NoSuchAlgorithmException e) { ocspResponse = processDefaultError(responseGenerator, transactionLogger, auditLogger, e); } catch (CertificateException e) { ocspResponse = processDefaultError(responseGenerator, transactionLogger, auditLogger, e); } catch (CryptoTokenOfflineException e) { ocspResponse = processDefaultError(responseGenerator, transactionLogger, auditLogger, e); } try { respBytes = ocspResponse.getEncoded(); if (auditLogger.isEnabled()) { auditLogger.paramPut(AuditLogger.OCSPRESPONSE, new String(Hex.encode(respBytes))); auditLogger.writeln(); auditLogger.flush(); } if (transactionLogger.isEnabled()) { transactionLogger.flush(); } if (OcspConfiguration.getLogSafer()) { // See if the Errorhandler has found any problems if (hasErrorHandlerFailedSince(startTime)) { log.info("ProbableErrorhandler reported error, cannot answer request"); // RFC 2560: responseBytes are not set on error. ocspResponse = responseGenerator.build(OCSPRespBuilder.INTERNAL_ERROR, null); } // See if the Appender has reported any problems if (!CanLogCache.INSTANCE.canLog()) { log.info("SaferDailyRollingFileAppender reported error, cannot answer request"); // RFC 2560: responseBytes are not set on error. ocspResponse = responseGenerator.build(OCSPRespBuilder.INTERNAL_ERROR, null); } } } catch (IOException e) { log.error("Unexpected IOException caught.", e); if (transactionLogger.isEnabled()) { transactionLogger.flush(); } if (auditLogger.isEnabled()) { auditLogger.flush(); } } return new OcspResponseInformation(ocspResponse, maxAge); }
From source file:org.jruby.ext.openssl.OCSPBasicResponse.java
License:Common Public License
private boolean matchIssuerId(X509Cert signerCA, CertificateID certId, List<SingleResp> singleResponses) throws IOException { Ruby runtime = getRuntime();//w ww . j a va 2 s . c o m if (certId == null) { //gotta check em all for (SingleResp resp : singleResponses) { CertificateID tempId = resp.getCertID(); if (!matchIssuerId(signerCA, tempId, null)) return false; } return true; } else { // we have a matching cid ASN1ObjectIdentifier alg = certId.getHashAlgOID(); String sym = ASN1.oid2Sym(runtime, alg); MessageDigest md = Digest.getDigest(runtime, sym); byte[] issuerNameDigest = md.digest(signerCA.getIssuer().getX500Name().getEncoded()); byte[] issuerKeyDigest = md.digest(signerCA.getAuxCert().getPublicKey().getEncoded()); if (!issuerNameDigest.equals(certId.getIssuerNameHash())) return false; if (!issuerKeyDigest.equals(certId.getIssuerKeyHash())) return false; return true; } }
From source file:org.keycloak.common.util.OCSPUtils.java
License:Apache License
private static boolean compareCertIDs(JcaCertificateID idLeft, CertificateID idRight) { if (idLeft == idRight) return true; if (idLeft == null || idRight == null) return false; return Arrays.equals(idLeft.getIssuerKeyHash(), idRight.getIssuerKeyHash()) && Arrays.equals(idLeft.getIssuerNameHash(), idRight.getIssuerNameHash()) && idLeft.getSerialNumber().equals(idRight.getSerialNumber()); }
From source file:org.xipki.ocsp.client.impl.AbstractOCSPRequestor.java
License:Open Source License
@Override public OCSPResp ask(final X509Certificate issuerCert, final BigInteger[] serialNumbers, final URL responderUrl, final RequestOptions requestOptions, final RequestResponseDebug debug) throws OCSPResponseException, OCSPRequestorException { if (requestOptions == null) { throw new IllegalArgumentException("requestOptions could not be null"); }//from ww w. j a v a2 s. co m byte[] nonce = null; if (requestOptions.isUseNonce()) { nonce = nextNonce(requestOptions.getNonceLen()); } OCSPReq ocspReq = buildRequest(issuerCert, serialNumbers, nonce, requestOptions); byte[] encodedReq; try { encodedReq = ocspReq.getEncoded(); } catch (IOException e) { throw new OCSPRequestorException("could not encode OCSP request: " + e.getMessage(), e); } RequestResponsePair msgPair = null; if (debug != null) { msgPair = new RequestResponsePair(); debug.add(msgPair); msgPair.setRequest(encodedReq); } byte[] encodedResp; try { encodedResp = send(encodedReq, responderUrl, requestOptions); } catch (IOException e) { throw new ResponderUnreachableException("IOException: " + e.getMessage(), e); } if (debug != null) { msgPair.setRequest(encodedResp); } OCSPResp ocspResp; try { ocspResp = new OCSPResp(encodedResp); } catch (IOException e) { throw new InvalidOCSPResponseException("IOException: " + e.getMessage(), e); } Object respObject; try { respObject = ocspResp.getResponseObject(); } catch (OCSPException e) { throw new InvalidOCSPResponseException("responseObject is invalid"); } if (ocspResp.getStatus() != 0) { return ocspResp; } if (respObject instanceof BasicOCSPResp == false) { return ocspResp; } BasicOCSPResp basicOCSPResp = (BasicOCSPResp) respObject; if (nonce != null) { Extension nonceExtn = basicOCSPResp.getExtension(OCSPObjectIdentifiers.id_pkix_ocsp_nonce); if (nonceExtn == null) { throw new OCSPNonceUnmatchedException(nonce, null); } byte[] receivedNonce = nonceExtn.getExtnValue().getOctets(); if (Arrays.equals(nonce, receivedNonce) == false) { throw new OCSPNonceUnmatchedException(nonce, receivedNonce); } } SingleResp[] singleResponses = basicOCSPResp.getResponses(); final int countSingleResponses = singleResponses == null ? 0 : singleResponses.length; if (countSingleResponses != serialNumbers.length) { StringBuilder sb = new StringBuilder(100); sb.append("response with ").append(countSingleResponses).append(" singleRessponse"); if (countSingleResponses > 1) { sb.append("s"); } sb.append(" is returned, expected is ").append(serialNumbers.length); throw new OCSPTargetUnmatchedException(sb.toString()); } CertificateID certID = ocspReq.getRequestList()[0].getCertID(); ASN1ObjectIdentifier issuerHashAlg = certID.getHashAlgOID(); byte[] issuerKeyHash = certID.getIssuerKeyHash(); byte[] issuerNameHash = certID.getIssuerNameHash(); if (serialNumbers.length == 1) { SingleResp m = singleResponses[0]; CertificateID cid = m.getCertID(); boolean issuerMatch = issuerHashAlg.equals(cid.getHashAlgOID()) && Arrays.equals(issuerKeyHash, cid.getIssuerKeyHash()) && Arrays.equals(issuerNameHash, cid.getIssuerNameHash()); if (issuerMatch == false) { throw new OCSPTargetUnmatchedException("the issuer is not requested"); } BigInteger serialNumber = cid.getSerialNumber(); if (serialNumbers[0].equals(serialNumber) == false) { throw new OCSPTargetUnmatchedException("the serialNumber is not requested"); } } else { List<BigInteger> tmpSerials1 = Arrays.asList(serialNumbers); List<BigInteger> tmpSerials2 = new ArrayList<>(tmpSerials1); for (int i = 0; i < singleResponses.length; i++) { SingleResp m = singleResponses[i]; CertificateID cid = m.getCertID(); boolean issuerMatch = issuerHashAlg.equals(cid.getHashAlgOID()) && Arrays.equals(issuerKeyHash, cid.getIssuerKeyHash()) && Arrays.equals(issuerNameHash, cid.getIssuerNameHash()); if (issuerMatch == false) { throw new OCSPTargetUnmatchedException( "the issuer specified in singleResponse[" + i + "] is not requested"); } BigInteger serialNumber = cid.getSerialNumber(); if (tmpSerials2.remove(serialNumber) == false) { if (tmpSerials1.contains(serialNumber)) { throw new OCSPTargetUnmatchedException( "serialNumber " + serialNumber + "is contained in at least two singleResponses"); } else { throw new OCSPTargetUnmatchedException( "the serialNumber specified in singleResponse[" + i + "] is not requested"); } } } } return ocspResp; }
From source file:org.xipki.ocsp.server.impl.OcspServer.java
License:Open Source License
public OcspRespWithCacheInfo answer(final Responder responder, final OCSPReq request, final AuditEvent auditEvent, final boolean viaGet) { ResponderOption responderOption = responder.getResponderOption(); RequestOption requestOption = responder.getRequestOption(); ResponseOption responseOption = responder.getResponseOption(); ResponderSigner signer = responder.getSigner(); AuditOption auditOption = responder.getAuditOption(); CertprofileOption certprofileOption = responder.getCertprofileOption(); int version = request.getVersionNumber(); if (requestOption.isVersionAllowed(version) == false) { String message = "invalid request version " + version; LOG.warn(message);/*from ww w . j av a 2s . c o m*/ if (auditEvent != null) { fillAuditEvent(auditEvent, AuditLevel.INFO, AuditStatus.FAILED, message); } return createUnsuccessfullOCSPResp(OcspResponseStatus.malformedRequest); } try { OcspRespWithCacheInfo resp = checkSignature(request, requestOption, auditEvent); if (resp != null) { return resp; } boolean couldCacheInfo = viaGet; List<Extension> responseExtensions = new ArrayList<>(2); Req[] requestList = request.getRequestList(); int n = requestList.length; Set<ASN1ObjectIdentifier> criticalExtensionOIDs = new HashSet<>(); Set<?> tmp = request.getCriticalExtensionOIDs(); if (tmp != null) { for (Object oid : tmp) { criticalExtensionOIDs.add((ASN1ObjectIdentifier) oid); } } RespID respID = new RespID(signer.getResponderId()); BasicOCSPRespBuilder basicOcspBuilder = new BasicOCSPRespBuilder(respID); ASN1ObjectIdentifier extensionType = OCSPObjectIdentifiers.id_pkix_ocsp_nonce; criticalExtensionOIDs.remove(extensionType); Extension nonceExtn = request.getExtension(extensionType); if (nonceExtn != null) { byte[] nonce = nonceExtn.getExtnValue().getOctets(); int len = nonce.length; int min = requestOption.getNonceMinLen(); int max = requestOption.getNonceMaxLen(); if (len < min || len > max) { LOG.warn("length of nonce {} not within [{},{}]", new Object[] { len, min, max }); if (auditEvent != null) { StringBuilder sb = new StringBuilder(); sb.append("length of nonce ").append(len); sb.append(" not within [").append(min).append(", ").append(max); fillAuditEvent(auditEvent, AuditLevel.INFO, AuditStatus.FAILED, sb.toString()); } return createUnsuccessfullOCSPResp(OcspResponseStatus.malformedRequest); } couldCacheInfo = false; responseExtensions.add(nonceExtn); } else if (requestOption.isNonceRequired()) { String message = "nonce required, but is not present in the request"; LOG.warn(message); if (auditEvent != null) { fillAuditEvent(auditEvent, AuditLevel.INFO, AuditStatus.FAILED, message); } return createUnsuccessfullOCSPResp(OcspResponseStatus.malformedRequest); } boolean includeExtendedRevokeExtension = false; long cacheThisUpdate = 0; long cacheNextUpdate = Long.MAX_VALUE; for (int i = 0; i < n; i++) { AuditChildEvent childAuditEvent = null; if (auditEvent != null) { childAuditEvent = new AuditChildEvent(); auditEvent.addChildAuditEvent(childAuditEvent); } Req req = requestList[i]; CertificateID certID = req.getCertID(); String certIdHashAlgo = certID.getHashAlgOID().getId(); HashAlgoType reqHashAlgo = HashAlgoType.getHashAlgoType(certIdHashAlgo); if (reqHashAlgo == null) { LOG.warn("unknown CertID.hashAlgorithm {}", certIdHashAlgo); if (childAuditEvent != null) { fillAuditEvent(childAuditEvent, AuditLevel.INFO, AuditStatus.FAILED, "unknown CertID.hashAlgorithm " + certIdHashAlgo); } return createUnsuccessfullOCSPResp(OcspResponseStatus.malformedRequest); } else if (requestOption.allows(reqHashAlgo) == false) { LOG.warn("CertID.hashAlgorithm {} not allowed", certIdHashAlgo); if (childAuditEvent != null) { fillAuditEvent(childAuditEvent, AuditLevel.INFO, AuditStatus.FAILED, "CertID.hashAlgorithm " + certIdHashAlgo + " not allowed"); } return createUnsuccessfullOCSPResp(OcspResponseStatus.malformedRequest); } CertStatusInfo certStatusInfo = null; CertStatusStore answeredStore = null; boolean exceptionOccurs = false; for (CertStatusStore store : responder.getStores()) { try { certStatusInfo = store.getCertStatus(reqHashAlgo, certID.getIssuerNameHash(), certID.getIssuerKeyHash(), certID.getSerialNumber(), responseOption.isIncludeCerthash(), responseOption.getCertHashAlgo(), certprofileOption); if (certStatusInfo.getCertStatus() != CertStatus.ISSUER_UNKNOWN) { answeredStore = store; break; } } catch (CertStatusStoreException e) { exceptionOccurs = true; final String message = "getCertStatus() of CertStatusStore " + store.getName(); if (LOG.isErrorEnabled()) { LOG.error(LogUtil.buildExceptionLogFormat(message), e.getClass().getName(), e.getMessage()); } LOG.debug(message, e); } } if (certStatusInfo == null) { if (childAuditEvent != null) { fillAuditEvent(childAuditEvent, AuditLevel.ERROR, AuditStatus.FAILED, "no CertStatusStore can answer the request"); } if (exceptionOccurs) { return createUnsuccessfullOCSPResp(OcspResponseStatus.tryLater); } else { certStatusInfo = CertStatusInfo.getIssuerUnknownCertStatusInfo(new Date(), null); } } else if (answeredStore != null) { if (responderOption.isInheritCaRevocation()) { CertRevocationInfo caRevInfo = answeredStore.getCARevocationInfo(reqHashAlgo, certID.getIssuerNameHash(), certID.getIssuerKeyHash()); if (caRevInfo != null) { CertStatus certStatus = certStatusInfo.getCertStatus(); boolean replaced = false; if (certStatus == CertStatus.GOOD || certStatus == CertStatus.UNKNOWN) { replaced = true; } else if (certStatus == CertStatus.REVOKED) { if (certStatusInfo.getRevocationInfo().getRevocationTime() .after(caRevInfo.getRevocationTime())) { replaced = true; } } if (replaced) { CertRevocationInfo newRevInfo; if (caRevInfo.getReason() == CRLReason.CA_COMPROMISE) { newRevInfo = caRevInfo; } else { newRevInfo = new CertRevocationInfo(CRLReason.CA_COMPROMISE, caRevInfo.getRevocationTime(), caRevInfo.getInvalidityTime()); } certStatusInfo = CertStatusInfo.getRevokedCertStatusInfo(newRevInfo, certStatusInfo.getCertHashAlgo(), certStatusInfo.getCertHash(), certStatusInfo.getThisUpdate(), certStatusInfo.getNextUpdate(), certStatusInfo.getCertprofile()); } } } } if (childAuditEvent != null) { String certprofile = certStatusInfo.getCertprofile(); String auditCertType; if (certprofile != null) { auditCertType = auditOption.getCertprofileMapping().get(certprofile); if (auditCertType == null) { auditCertType = certprofile; } } else { auditCertType = "UNKNOWN"; } childAuditEvent.addEventData(new AuditEventData("certType", auditCertType)); } // certStatusInfo could not be null in any case, since at least one store is configured Date thisUpdate = certStatusInfo.getThisUpdate(); if (thisUpdate == null) { thisUpdate = new Date(); } Date nextUpdate = certStatusInfo.getNextUpdate(); List<Extension> extensions = new LinkedList<>(); boolean unknownAsRevoked = false; CertificateStatus bcCertStatus = null; switch (certStatusInfo.getCertStatus()) { case GOOD: bcCertStatus = null; break; case ISSUER_UNKNOWN: couldCacheInfo = false; bcCertStatus = new UnknownStatus(); break; case UNKNOWN: case IGNORE: couldCacheInfo = false; if (responderOption.getMode() == OCSPMode.RFC2560) { bcCertStatus = new UnknownStatus(); } else// (ocspMode == OCSPMode.RFC6960) { unknownAsRevoked = true; includeExtendedRevokeExtension = true; bcCertStatus = new RevokedStatus(new Date(0L), CRLReason.CERTIFICATE_HOLD.getCode()); } break; case REVOKED: CertRevocationInfo revInfo = certStatusInfo.getRevocationInfo(); ASN1GeneralizedTime revTime = new ASN1GeneralizedTime(revInfo.getRevocationTime()); org.bouncycastle.asn1.x509.CRLReason _reason = null; if (responseOption.isIncludeRevReason()) { _reason = org.bouncycastle.asn1.x509.CRLReason.lookup(revInfo.getReason().getCode()); } RevokedInfo _revInfo = new RevokedInfo(revTime, _reason); bcCertStatus = new RevokedStatus(_revInfo); Date invalidityDate = revInfo.getInvalidityTime(); if (responseOption.isIncludeInvalidityDate() && invalidityDate != null && invalidityDate.equals(revTime) == false) { Extension extension = new Extension(Extension.invalidityDate, false, new ASN1GeneralizedTime(invalidityDate).getEncoded()); extensions.add(extension); } break; } byte[] certHash = certStatusInfo.getCertHash(); if (certHash != null) { ASN1ObjectIdentifier hashAlgoOid = new ASN1ObjectIdentifier( certStatusInfo.getCertHashAlgo().getOid()); AlgorithmIdentifier aId = new AlgorithmIdentifier(hashAlgoOid, DERNull.INSTANCE); CertHash bcCertHash = new CertHash(aId, certHash); byte[] encodedCertHash; try { encodedCertHash = bcCertHash.getEncoded(); } catch (IOException e) { final String message = "answer() bcCertHash.getEncoded"; if (LOG.isErrorEnabled()) { LOG.error(LogUtil.buildExceptionLogFormat(message), e.getClass().getName(), e.getMessage()); } LOG.debug(message, e); if (childAuditEvent != null) { fillAuditEvent(childAuditEvent, AuditLevel.ERROR, AuditStatus.FAILED, "CertHash.getEncoded() with IOException"); } return createUnsuccessfullOCSPResp(OcspResponseStatus.internalError); } Extension extension = new Extension(ISISMTTObjectIdentifiers.id_isismtt_at_certHash, false, encodedCertHash); extensions.add(extension); } if (certStatusInfo.getArchiveCutOff() != null) { Extension extension = new Extension(OCSPObjectIdentifiers.id_pkix_ocsp_archive_cutoff, false, new ASN1GeneralizedTime(certStatusInfo.getArchiveCutOff()).getEncoded()); extensions.add(extension); } String certStatusText; if (bcCertStatus instanceof UnknownStatus) { certStatusText = "unknown"; } else if (bcCertStatus instanceof RevokedStatus) { certStatusText = unknownAsRevoked ? "unknown_as_revoked" : "revoked"; } else if (bcCertStatus == null) { certStatusText = "good"; } else { certStatusText = "should-not-happen"; } if (childAuditEvent != null) { childAuditEvent.setLevel(AuditLevel.INFO); childAuditEvent.setStatus(AuditStatus.SUCCESSFUL); childAuditEvent.addEventData(new AuditEventData("certStatus", certStatusText)); } if (LOG.isDebugEnabled()) { StringBuilder sb = new StringBuilder(); sb.append("certHashAlgo: ").append(certID.getHashAlgOID().getId()).append(", "); String hexCertHash = null; if (certHash != null) { hexCertHash = Hex.toHexString(certHash).toUpperCase(); } sb.append("issuerKeyHash: ").append(Hex.toHexString(certID.getIssuerKeyHash()).toUpperCase()) .append(", "); sb.append("issuerNameHash: ").append(Hex.toHexString(certID.getIssuerNameHash()).toUpperCase()) .append(", "); sb.append("serialNumber: ").append(certID.getSerialNumber()).append(", "); sb.append("certStatus: ").append(certStatusText).append(", "); sb.append("thisUpdate: ").append(thisUpdate).append(", "); sb.append("nextUpdate: ").append(nextUpdate).append(", "); sb.append("certHash: ").append(hexCertHash); LOG.debug(sb.toString()); } basicOcspBuilder.addResponse(certID, bcCertStatus, thisUpdate, nextUpdate, CollectionUtil.isEmpty(extensions) ? null : new Extensions(extensions.toArray(new Extension[0]))); cacheThisUpdate = Math.max(cacheThisUpdate, thisUpdate.getTime()); if (nextUpdate != null) { cacheNextUpdate = Math.min(cacheNextUpdate, nextUpdate.getTime()); } } if (includeExtendedRevokeExtension) { responseExtensions.add(new Extension(ObjectIdentifiers.id_pkix_ocsp_extendedRevoke, true, DERNull.INSTANCE.getEncoded())); } if (CollectionUtil.isNotEmpty(responseExtensions)) { basicOcspBuilder .setResponseExtensions(new Extensions(responseExtensions.toArray(new Extension[0]))); } ConcurrentContentSigner concurrentSigner = null; if (responderOption.getMode() != OCSPMode.RFC2560) { extensionType = ObjectIdentifiers.id_pkix_ocsp_prefSigAlgs; criticalExtensionOIDs.remove(extensionType); Extension ext = request.getExtension(extensionType); if (ext != null) { ASN1Sequence preferredSigAlgs = ASN1Sequence.getInstance(ext.getParsedValue()); concurrentSigner = signer.getSignerForPreferredSigAlgs(preferredSigAlgs); } } if (CollectionUtil.isNotEmpty(criticalExtensionOIDs)) { return createUnsuccessfullOCSPResp(OcspResponseStatus.malformedRequest); } if (concurrentSigner == null) { concurrentSigner = signer.getFirstSigner(); } ContentSigner singleSigner; try { singleSigner = concurrentSigner.borrowContentSigner(); } catch (NoIdleSignerException e) { return createUnsuccessfullOCSPResp(OcspResponseStatus.tryLater); } X509CertificateHolder[] certsInResp; EmbedCertsMode certsMode = responseOption.getEmbedCertsMode(); if (certsMode == null || certsMode == EmbedCertsMode.SIGNER) { certsInResp = new X509CertificateHolder[] { signer.getBcCertificate() }; } else if (certsMode == EmbedCertsMode.SIGNER_AND_CA) { certsInResp = signer.getBcCertificateChain(); } else { // NONE certsInResp = null; } BasicOCSPResp basicOcspResp; try { basicOcspResp = basicOcspBuilder.build(singleSigner, certsInResp, new Date()); } catch (OCSPException e) { final String message = "answer() basicOcspBuilder.build"; if (LOG.isErrorEnabled()) { LOG.error(LogUtil.buildExceptionLogFormat(message), e.getClass().getName(), e.getMessage()); } LOG.debug(message, e); if (auditEvent != null) { fillAuditEvent(auditEvent, AuditLevel.ERROR, AuditStatus.FAILED, "BasicOCSPRespBuilder.build() with OCSPException"); } return createUnsuccessfullOCSPResp(OcspResponseStatus.internalError); } finally { concurrentSigner.returnContentSigner(singleSigner); } OCSPRespBuilder ocspRespBuilder = new OCSPRespBuilder(); try { OCSPResp ocspResp = ocspRespBuilder.build(OcspResponseStatus.successfull.getStatus(), basicOcspResp); if (couldCacheInfo) { ResponseCacheInfo cacheInfo = new ResponseCacheInfo(cacheThisUpdate); if (cacheNextUpdate != Long.MAX_VALUE) { cacheInfo.setNextUpdate(cacheNextUpdate); } return new OcspRespWithCacheInfo(ocspResp, cacheInfo); } else { return new OcspRespWithCacheInfo(ocspResp, null); } } catch (OCSPException e) { final String message = "answer() ocspRespBuilder.build"; if (LOG.isErrorEnabled()) { LOG.error(LogUtil.buildExceptionLogFormat(message), e.getClass().getName(), e.getMessage()); } LOG.debug(message, e); if (auditEvent != null) { fillAuditEvent(auditEvent, AuditLevel.ERROR, AuditStatus.FAILED, "OCSPRespBuilder.build() with OCSPException"); } return createUnsuccessfullOCSPResp(OcspResponseStatus.internalError); } } catch (Throwable t) { final String message = "Throwable"; if (LOG.isErrorEnabled()) { LOG.error(LogUtil.buildExceptionLogFormat(message), t.getClass().getName(), t.getMessage()); } LOG.debug(message, t); if (auditEvent != null) { fillAuditEvent(auditEvent, AuditLevel.ERROR, AuditStatus.FAILED, "internal error"); } return createUnsuccessfullOCSPResp(OcspResponseStatus.internalError); } }
From source file:org.xipki.pki.ocsp.client.impl.AbstractOcspRequestor.java
License:Open Source License
@Override public OCSPResp ask(final X509Certificate issuerCert, final BigInteger[] serialNumbers, final URL responderUrl, final RequestOptions requestOptions, final RequestResponseDebug debug) throws OcspResponseException, OcspRequestorException { ParamUtil.requireNonNull("issuerCert", issuerCert); ParamUtil.requireNonNull("requestOptions", requestOptions); ParamUtil.requireNonNull("responderUrl", responderUrl); byte[] nonce = null; if (requestOptions.isUseNonce()) { nonce = nextNonce(requestOptions.getNonceLen()); }/* www . j av a 2s . co m*/ OCSPReq ocspReq = buildRequest(issuerCert, serialNumbers, nonce, requestOptions); byte[] encodedReq; try { encodedReq = ocspReq.getEncoded(); } catch (IOException ex) { throw new OcspRequestorException("could not encode OCSP request: " + ex.getMessage(), ex); } RequestResponsePair msgPair = null; if (debug != null) { msgPair = new RequestResponsePair(); debug.add(msgPair); msgPair.setRequest(encodedReq); } byte[] encodedResp; try { encodedResp = send(encodedReq, responderUrl, requestOptions); } catch (IOException ex) { throw new ResponderUnreachableException("IOException: " + ex.getMessage(), ex); } if (msgPair != null) { msgPair.setResponse(encodedResp); } OCSPResp ocspResp; try { ocspResp = new OCSPResp(encodedResp); } catch (IOException ex) { throw new InvalidOcspResponseException("IOException: " + ex.getMessage(), ex); } Object respObject; try { respObject = ocspResp.getResponseObject(); } catch (OCSPException ex) { throw new InvalidOcspResponseException("responseObject is invalid"); } if (ocspResp.getStatus() != 0) { return ocspResp; } if (!(respObject instanceof BasicOCSPResp)) { return ocspResp; } BasicOCSPResp basicOcspResp = (BasicOCSPResp) respObject; if (nonce != null) { Extension nonceExtn = basicOcspResp.getExtension(OCSPObjectIdentifiers.id_pkix_ocsp_nonce); if (nonceExtn == null) { throw new OcspNonceUnmatchedException(nonce, null); } byte[] receivedNonce = nonceExtn.getExtnValue().getOctets(); if (!Arrays.equals(nonce, receivedNonce)) { throw new OcspNonceUnmatchedException(nonce, receivedNonce); } } SingleResp[] singleResponses = basicOcspResp.getResponses(); if (singleResponses == null || singleResponses.length == 0) { StringBuilder sb = new StringBuilder(100); sb.append("response with no singleResponse is returned, expected is "); sb.append(serialNumbers.length); throw new OcspTargetUnmatchedException(sb.toString()); } final int countSingleResponses = singleResponses.length; if (countSingleResponses != serialNumbers.length) { StringBuilder sb = new StringBuilder(100); sb.append("response with ").append(countSingleResponses).append(" singleResponse"); if (countSingleResponses > 1) { sb.append("s"); } sb.append(" is returned, expected is ").append(serialNumbers.length); throw new OcspTargetUnmatchedException(sb.toString()); } CertificateID certId = ocspReq.getRequestList()[0].getCertID(); ASN1ObjectIdentifier issuerHashAlg = certId.getHashAlgOID(); byte[] issuerKeyHash = certId.getIssuerKeyHash(); byte[] issuerNameHash = certId.getIssuerNameHash(); if (serialNumbers.length == 1) { SingleResp singleResp = singleResponses[0]; CertificateID cid = singleResp.getCertID(); boolean issuerMatch = issuerHashAlg.equals(cid.getHashAlgOID()) && Arrays.equals(issuerKeyHash, cid.getIssuerKeyHash()) && Arrays.equals(issuerNameHash, cid.getIssuerNameHash()); if (!issuerMatch) { throw new OcspTargetUnmatchedException("the issuer is not requested"); } BigInteger serialNumber = cid.getSerialNumber(); if (!serialNumbers[0].equals(serialNumber)) { throw new OcspTargetUnmatchedException("the serialNumber is not requested"); } } else { List<BigInteger> tmpSerials1 = Arrays.asList(serialNumbers); List<BigInteger> tmpSerials2 = new ArrayList<>(tmpSerials1); for (int i = 0; i < countSingleResponses; i++) { SingleResp singleResp = singleResponses[i]; CertificateID cid = singleResp.getCertID(); boolean issuerMatch = issuerHashAlg.equals(cid.getHashAlgOID()) && Arrays.equals(issuerKeyHash, cid.getIssuerKeyHash()) && Arrays.equals(issuerNameHash, cid.getIssuerNameHash()); if (!issuerMatch) { throw new OcspTargetUnmatchedException( "the issuer specified in singleResponse[" + i + "] is not requested"); } BigInteger serialNumber = cid.getSerialNumber(); if (!tmpSerials2.remove(serialNumber)) { if (tmpSerials1.contains(serialNumber)) { throw new OcspTargetUnmatchedException("serialNumber " + LogUtil.formatCsn(serialNumber) + "is contained in at least two singleResponses"); } else { throw new OcspTargetUnmatchedException("serialNumber " + LogUtil.formatCsn(serialNumber) + " specified in singleResponse[" + i + "] is not requested"); } } } // end for } // end if return ocspResp; }
From source file:org.xipki.pki.ocsp.client.shell.OcspStatusCmd.java
License:Open Source License
@Override protected Object processResponse(final OCSPResp response, final X509Certificate respIssuer, final IssuerHash issuerHash, final List<BigInteger> serialNumbers, final Map<BigInteger, byte[]> encodedCerts) throws Exception { ParamUtil.requireNonNull("response", response); ParamUtil.requireNonNull("issuerHash", issuerHash); ParamUtil.requireNonNull("serialNumbers", serialNumbers); BasicOCSPResp basicResp = OcspUtils.extractBasicOcspResp(response); boolean extendedRevoke = basicResp.getExtension(ObjectIdentifiers.id_pkix_ocsp_extendedRevoke) != null; SingleResp[] singleResponses = basicResp.getResponses(); if (singleResponses == null || singleResponses.length == 0) { throw new CmdFailure("received no status from server"); }/*from w ww .j a v a 2 s . c o m*/ final int n = singleResponses.length; if (n != serialNumbers.size()) { throw new CmdFailure("received status with " + n + " single responses from server, but " + serialNumbers.size() + " were requested"); } Date[] thisUpdates = new Date[n]; for (int i = 0; i < n; i++) { thisUpdates[i] = singleResponses[i].getThisUpdate(); } // check the signature if available if (null == basicResp.getSignature()) { println("response is not signed"); } else { X509CertificateHolder[] responderCerts = basicResp.getCerts(); if (responderCerts == null || responderCerts.length < 1) { throw new CmdFailure("no responder certificate is contained in the response"); } ResponderID respId = basicResp.getResponderId().toASN1Primitive(); X500Name respIdByName = respId.getName(); byte[] respIdByKey = respId.getKeyHash(); X509CertificateHolder respSigner = null; for (X509CertificateHolder cert : responderCerts) { if (respIdByName != null) { if (cert.getSubject().equals(respIdByName)) { respSigner = cert; } } else { byte[] spkiSha1 = HashAlgoType.SHA1 .hash(cert.getSubjectPublicKeyInfo().getPublicKeyData().getBytes()); if (Arrays.equals(respIdByKey, spkiSha1)) { respSigner = cert; } } if (respSigner != null) { break; } } if (respSigner == null) { throw new CmdFailure("no responder certificate match the ResponderId"); } boolean validOn = true; for (Date thisUpdate : thisUpdates) { validOn = respSigner.isValidOn(thisUpdate); if (!validOn) { throw new CmdFailure("responder certificate is not valid on " + thisUpdate); } } if (validOn) { PublicKey responderPubKey = KeyUtil.generatePublicKey(respSigner.getSubjectPublicKeyInfo()); ContentVerifierProvider cvp = securityFactory.getContentVerifierProvider(responderPubKey); boolean sigValid = basicResp.isSignatureValid(cvp); if (!sigValid) { throw new CmdFailure("response is equipped with invalid signature"); } // verify the OCSPResponse signer if (respIssuer != null) { boolean certValid = true; X509Certificate jceRespSigner = X509Util.toX509Cert(respSigner.toASN1Structure()); if (X509Util.issues(respIssuer, jceRespSigner)) { try { jceRespSigner.verify(respIssuer.getPublicKey()); } catch (SignatureException ex) { certValid = false; } } if (!certValid) { throw new CmdFailure("response is equipped with valid signature but the" + " OCSP signer is not trusted"); } } else { println("response is equipped with valid signature"); } // end if(respIssuer) } // end if(validOn) if (verbose.booleanValue()) { println("responder is " + X509Util.getRfc4519Name(responderCerts[0].getSubject())); } } // end if for (int i = 0; i < n; i++) { if (n > 1) { println("---------------------------- " + i + "----------------------------"); } SingleResp singleResp = singleResponses[i]; CertificateStatus singleCertStatus = singleResp.getCertStatus(); String status; if (singleCertStatus == null) { status = "good"; } else if (singleCertStatus instanceof RevokedStatus) { RevokedStatus revStatus = (RevokedStatus) singleCertStatus; Date revTime = revStatus.getRevocationTime(); Date invTime = null; Extension ext = singleResp.getExtension(Extension.invalidityDate); if (ext != null) { invTime = ASN1GeneralizedTime.getInstance(ext.getParsedValue()).getDate(); } if (revStatus.hasRevocationReason()) { int reason = revStatus.getRevocationReason(); if (extendedRevoke && reason == CrlReason.CERTIFICATE_HOLD.getCode() && revTime.getTime() == 0) { status = "unknown (RFC6960)"; } else { StringBuilder sb = new StringBuilder("revoked, reason = "); sb.append(CrlReason.forReasonCode(reason).getDescription()); sb.append(", revocationTime = ").append(revTime); if (invTime != null) { sb.append(", invalidityTime = ").append(invTime); } status = sb.toString(); } } else { status = "revoked, no reason, revocationTime = " + revTime; } } else if (singleCertStatus instanceof UnknownStatus) { status = "unknown (RFC2560)"; } else { status = "ERROR"; } StringBuilder msg = new StringBuilder(); CertificateID certId = singleResp.getCertID(); HashAlgoType hashAlgo = HashAlgoType.getNonNullHashAlgoType(certId.getHashAlgOID()); boolean issuerMatch = issuerHash.match(hashAlgo, certId.getIssuerNameHash(), certId.getIssuerKeyHash()); BigInteger serialNumber = certId.getSerialNumber(); msg.append("issuer matched: ").append(issuerMatch); msg.append("\nserialNumber: ").append(LogUtil.formatCsn(serialNumber)); msg.append("\nCertificate status: ").append(status); if (verbose.booleanValue()) { msg.append("\nthisUpdate: ").append(singleResp.getThisUpdate()); msg.append("\nnextUpdate: ").append(singleResp.getNextUpdate()); Extension extension = singleResp.getExtension(ISISMTTObjectIdentifiers.id_isismtt_at_certHash); if (extension != null) { msg.append("\nCertHash is provided:\n"); ASN1Encodable extensionValue = extension.getParsedValue(); CertHash certHash = CertHash.getInstance(extensionValue); ASN1ObjectIdentifier hashAlgOid = certHash.getHashAlgorithm().getAlgorithm(); byte[] hashValue = certHash.getCertificateHash(); msg.append("\tHash algo : ").append(hashAlgOid.getId()).append("\n"); msg.append("\tHash value: ").append(Hex.toHexString(hashValue)).append("\n"); if (encodedCerts != null) { byte[] encodedCert = encodedCerts.get(serialNumber); MessageDigest md = MessageDigest.getInstance(hashAlgOid.getId()); byte[] expectedHashValue = md.digest(encodedCert); if (Arrays.equals(expectedHashValue, hashValue)) { msg.append("\tThis matches the requested certificate"); } else { msg.append("\tThis differs from the requested certificate"); } } } // end if (extension != null) extension = singleResp.getExtension(OCSPObjectIdentifiers.id_pkix_ocsp_archive_cutoff); if (extension != null) { ASN1Encodable extensionValue = extension.getParsedValue(); ASN1GeneralizedTime time = ASN1GeneralizedTime.getInstance(extensionValue); msg.append("\nArchive-CutOff: "); msg.append(time.getTimeString()); } AlgorithmIdentifier sigAlg = basicResp.getSignatureAlgorithmID(); if (sigAlg == null) { msg.append(("\nresponse is not signed")); } else { String sigAlgName = AlgorithmUtil.getSignatureAlgoName(sigAlg); if (sigAlgName == null) { sigAlgName = "unknown"; } msg.append("\nresponse is signed with ").append(sigAlgName); } // extensions msg.append("\nExtensions: "); List<?> extensionOids = basicResp.getExtensionOIDs(); if (extensionOids == null || extensionOids.size() == 0) { msg.append("-"); } else { int size = extensionOids.size(); for (int j = 0; j < size; j++) { ASN1ObjectIdentifier extensionOid = (ASN1ObjectIdentifier) extensionOids.get(j); String name = EXTENSION_OIDNAME_MAP.get(extensionOid); if (name == null) { msg.append(extensionOid.getId()); } else { msg.append(name); } if (j != size - 1) { msg.append(", "); } } } } // end if (verbose.booleanValue()) println(msg.toString()); } // end for println(""); return null; }