List of usage examples for org.bouncycastle.cert.ocsp CertificateID getSerialNumber
public BigInteger getSerialNumber()
From source file:Controllers.OCSPController.java
License:Apache License
/** * Method to do OCSP response to client. * * @param requestBytes//from w w w.j a v a 2 s.com * @param mode * * @return * * @throws NotImplementedException */ private byte[] processOcspRequest(byte[] requestBytes, OCSP_PROCESS_MODE mode) throws NotImplementedException { try { // get request info OCSPReq ocspRequest = new OCSPReq(requestBytes); X509CertificateHolder[] requestCerts = ocspRequest.getCerts(); Req[] requestList = ocspRequest.getRequestList(); // setup response BasicOCSPRespBuilder responseBuilder = new BasicOCSPRespBuilder( new RespID(x509CertificateHolder.getSubject())); LOG.info("OCSP request version: " + ocspRequest.getVersionNumber() + ", Requester name: " + ocspRequest.getRequestorName() + ", is signed: " + ocspRequest.isSigned() + ", has extensions: " + ocspRequest.hasExtensions() + ", number of additional certificates: " + requestCerts.length + ", number of certificate ids to verify: " + requestList.length); int ocspResult = OCSPRespBuilder.SUCCESSFUL; switch (mode) { case AUTO: LOG.error("Auto OCSP server is not implemented in this version."); throw new NotImplementedException(); case GOOD: LOG.warn("Mocked mode, server will always return Good ocsp response"); for (Req req : requestList) { CertificateID certId = req.getCertID(); String serialNumber = "0x" + certId.getSerialNumber().toString(16); LOG.debug(String.format("Processing request for cert serial number:[%s]", serialNumber)); CertificateStatus certificateStatus = CertificateStatus.GOOD; Calendar thisUpdate = new GregorianCalendar(); Date now = thisUpdate.getTime(); thisUpdate.add(Calendar.DAY_OF_MONTH, 7); Date nexUpdate = thisUpdate.getTime(); responseBuilder.addResponse(certId, certificateStatus, now, nexUpdate, null); } break; case REVOKED: LOG.warn("Mocked mode, server will always return REVOKED ocsp response"); for (Req req : requestList) { CertificateID certId = req.getCertID(); String serialNumber = "0x" + certId.getSerialNumber().toString(16); LOG.debug(String.format("Processing request for cert serial number:[%s]", serialNumber)); Calendar cal = new GregorianCalendar(); cal.add(Calendar.DAY_OF_MONTH, -7);//Set revoked 7 days ago. CertificateStatus certificateStatus = new RevokedStatus(cal.getTime(), 16); Calendar thisUpdate = new GregorianCalendar(); Date now = thisUpdate.getTime(); thisUpdate.add(Calendar.DAY_OF_MONTH, 7); Date nexUpdate = thisUpdate.getTime(); responseBuilder.addResponse(certId, certificateStatus, now, nexUpdate, null); } break; case UNKNOWN: LOG.warn("Mocked mode, server will always return Known ocsp response"); for (Req req : requestList) { CertificateID certId = req.getCertID(); String serialNumber = "0x" + certId.getSerialNumber().toString(16); LOG.debug(String.format("Processing request for cert serial number:[%s]", serialNumber)); CertificateStatus certificateStatus = new UnknownStatus(); Calendar thisUpdate = new GregorianCalendar(); Date now = thisUpdate.getTime(); thisUpdate.add(Calendar.DAY_OF_MONTH, 7); Date nexUpdate = thisUpdate.getTime(); responseBuilder.addResponse(certId, certificateStatus, now, nexUpdate, null); } break; } // process nonce Extension extNonce = ocspRequest.getExtension(new ASN1ObjectIdentifier("1.3.6.1.5.5.7.48.1.2")); if (extNonce != null) { LOG.debug("Nonce is present in the request"); responseBuilder.setResponseExtensions(new Extensions(extNonce)); } else { LOG.info("Nonce is not present in the request"); if (bRequireNonce) { LOG.info("Nonce is required, fail the request"); ocspResult = OCSPRespBuilder.UNAUTHORIZED; } } X509CertificateHolder[] chain = { x509CertificateHolder }; ContentSigner signer = new JcaContentSignerBuilder("SHA1withRSA").setProvider("BC").build(privateKey); BasicOCSPResp ocspResponse = responseBuilder.build(signer, chain, Calendar.getInstance().getTime()); OCSPRespBuilder ocspResponseBuilder = new OCSPRespBuilder(); byte[] encoded = ocspResponseBuilder.build(ocspResult, ocspResponse).getEncoded(); LOG.info("Sending OCSP response to client, size: " + encoded.length); return encoded; } catch (Exception e) { LOG.error("Exception during processing OCSP request: " + e.getMessage()); e.printStackTrace(); } return null; }
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 www. j a 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//from www .java 2 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.apache.nifi.web.security.x509.ocsp.OcspCertificateValidator.java
License:Apache License
/** * Gets the OCSP status for the specified subject and issuer certificates. * * @param ocspStatusKey status key//ww w . j a v a2 s. com * @return ocsp status */ private OcspStatus getOcspStatus(final OcspRequest ocspStatusKey) { final X509Certificate subjectCertificate = ocspStatusKey.getSubjectCertificate(); final X509Certificate issuerCertificate = ocspStatusKey.getIssuerCertificate(); // initialize the default status final OcspStatus ocspStatus = new OcspStatus(); ocspStatus.setVerificationStatus(VerificationStatus.Unknown); ocspStatus.setValidationStatus(ValidationStatus.Unknown); try { // prepare the request final BigInteger subjectSerialNumber = subjectCertificate.getSerialNumber(); final DigestCalculatorProvider calculatorProviderBuilder = new JcaDigestCalculatorProviderBuilder() .setProvider("BC").build(); final CertificateID certificateId = new CertificateID( calculatorProviderBuilder.get(CertificateID.HASH_SHA1), new X509CertificateHolder(issuerCertificate.getEncoded()), subjectSerialNumber); // generate the request final OCSPReqBuilder requestGenerator = new OCSPReqBuilder(); requestGenerator.addRequest(certificateId); // Create a nonce to avoid replay attack BigInteger nonce = BigInteger.valueOf(System.currentTimeMillis()); Extension ext = new Extension(OCSPObjectIdentifiers.id_pkix_ocsp_nonce, true, new DEROctetString(nonce.toByteArray())); requestGenerator.setRequestExtensions(new Extensions(new Extension[] { ext })); final OCSPReq ocspRequest = requestGenerator.build(); // perform the request final Response response = getClientResponse(ocspRequest); // ensure the request was completed successfully if (Response.Status.OK.getStatusCode() != response.getStatusInfo().getStatusCode()) { logger.warn(String.format("OCSP request was unsuccessful (%s).", response.getStatus())); return ocspStatus; } // interpret the response OCSPResp ocspResponse = new OCSPResp(response.readEntity(InputStream.class)); // verify the response status switch (ocspResponse.getStatus()) { case OCSPRespBuilder.SUCCESSFUL: ocspStatus.setResponseStatus(OcspStatus.ResponseStatus.Successful); break; case OCSPRespBuilder.INTERNAL_ERROR: ocspStatus.setResponseStatus(OcspStatus.ResponseStatus.InternalError); break; case OCSPRespBuilder.MALFORMED_REQUEST: ocspStatus.setResponseStatus(OcspStatus.ResponseStatus.MalformedRequest); break; case OCSPRespBuilder.SIG_REQUIRED: ocspStatus.setResponseStatus(OcspStatus.ResponseStatus.SignatureRequired); break; case OCSPRespBuilder.TRY_LATER: ocspStatus.setResponseStatus(OcspStatus.ResponseStatus.TryLater); break; case OCSPRespBuilder.UNAUTHORIZED: ocspStatus.setResponseStatus(OcspStatus.ResponseStatus.Unauthorized); break; default: ocspStatus.setResponseStatus(OcspStatus.ResponseStatus.Unknown); break; } // only proceed if the response was successful if (ocspResponse.getStatus() != OCSPRespBuilder.SUCCESSFUL) { logger.warn(String.format("OCSP request was unsuccessful (%s).", ocspStatus.getResponseStatus().toString())); return ocspStatus; } // ensure the appropriate response object final Object ocspResponseObject = ocspResponse.getResponseObject(); if (ocspResponseObject == null || !(ocspResponseObject instanceof BasicOCSPResp)) { logger.warn(String.format("Unexpected OCSP response object: %s", ocspResponseObject)); return ocspStatus; } // get the response object final BasicOCSPResp basicOcspResponse = (BasicOCSPResp) ocspResponse.getResponseObject(); // attempt to locate the responder certificate final X509CertificateHolder[] responderCertificates = basicOcspResponse.getCerts(); if (responderCertificates.length != 1) { logger.warn(String.format("Unexpected number of OCSP responder certificates: %s", responderCertificates.length)); return ocspStatus; } // get the responder certificate final X509Certificate trustedResponderCertificate = getTrustedResponderCertificate( responderCertificates[0], issuerCertificate); if (trustedResponderCertificate != null) { // verify the response if (basicOcspResponse.isSignatureValid(new JcaContentVerifierProviderBuilder().setProvider("BC") .build(trustedResponderCertificate.getPublicKey()))) { ocspStatus.setVerificationStatus(VerificationStatus.Verified); } else { ocspStatus.setVerificationStatus(VerificationStatus.Unverified); } } else { ocspStatus.setVerificationStatus(VerificationStatus.Unverified); } // validate the response final SingleResp[] responses = basicOcspResponse.getResponses(); for (SingleResp singleResponse : responses) { final CertificateID responseCertificateId = singleResponse.getCertID(); final BigInteger responseSerialNumber = responseCertificateId.getSerialNumber(); if (responseSerialNumber.equals(subjectSerialNumber)) { Object certStatus = singleResponse.getCertStatus(); // interpret the certificate status if (CertificateStatus.GOOD == certStatus) { ocspStatus.setValidationStatus(ValidationStatus.Good); } else if (certStatus instanceof RevokedStatus) { ocspStatus.setValidationStatus(ValidationStatus.Revoked); } else { ocspStatus.setValidationStatus(ValidationStatus.Unknown); } } } } catch (final OCSPException | IOException | ProcessingException | OperatorCreationException e) { logger.error(e.getMessage(), e); } catch (CertificateException e) { e.printStackTrace(); } return ocspStatus; }
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"); }// w w w . j a v a 2s . c om 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.cesecore.certificates.ocsp.OcspResponseGeneratorSessionBean.java
License:Open Source License
private boolean checkAddArchiveCuttoff(String caCertificateSubjectDn, CertificateID certId) { if (OcspConfiguration.getExpiredArchiveCutoff() == -1) { return false; }// w w w.j av a 2 s.c om CertificateInfo info = certificateStoreSession.findFirstCertificateInfo(caCertificateSubjectDn, certId.getSerialNumber()); Date expDate = info.getExpireDate(); if (expDate.before(new Date())) { log.info("Certificate with serial number '" + certId.getSerialNumber() + "' is not valid. " + "Adding singleExtension id-pkix-ocsp-archive-cutoff"); return true; } return false; }
From source file:org.cesecore.util.PKIXCertRevocationStatusChecker.java
License:Open Source License
/** * Sends an OCSP request, gets a response and verifies the response as much as possible before returning it to the caller. * /* w ww . j av a 2 s .c om*/ * @return The OCSP response, or null of no correct response could be obtained. */ private SingleResp getOCSPResponse(final String ocspurl, final OCSPReq ocspRequest, final Certificate cert, final byte[] nonce, int expectedOcspRespCode, int expectedHttpRespCode) { if (log.isDebugEnabled()) { log.debug("Sending OCSP request to " + ocspurl + " regarding certificate with SubjectDN: " + CertTools.getSubjectDN(cert) + " - IssuerDN: " + CertTools.getIssuerDN(cert)); } //----------------------- Open connection and send the request --------------// OCSPResp response = null; HttpURLConnection con = null; try { final URL url = new URL(ocspurl); con = (HttpURLConnection) url.openConnection(); // we are going to do a POST con.setDoOutput(true); con.setRequestMethod("POST"); // POST it con.setRequestProperty("Content-Type", "application/ocsp-request"); OutputStream os = con.getOutputStream(); os.write(ocspRequest.getEncoded()); os.close(); final int httpRespCode = ((HttpURLConnection) con).getResponseCode(); if (httpRespCode != expectedHttpRespCode) { log.info("HTTP response from OCSP request was " + httpRespCode + ". Expected " + expectedHttpRespCode); handleContentOfErrorStream(con.getErrorStream()); return null; // if it is an http error code we don't need to test any more } InputStream is = con.getInputStream(); response = new OCSPResp(IOUtils.toByteArray(is)); is.close(); } catch (IOException e) { log.info("Unable to get an OCSP response. " + e.getLocalizedMessage()); if (con != null) { handleContentOfErrorStream(con.getErrorStream()); } return null; } // ------------ Verify the response signature --------------// BasicOCSPResp brep = null; try { brep = (BasicOCSPResp) response.getResponseObject(); if ((expectedOcspRespCode != OCSPRespBuilder.SUCCESSFUL) && (brep != null)) { log.warn("According to RFC 2560, responseBytes are not set on error, but we got some."); return null; // it messes up testing of invalid signatures... but is needed for the unsuccessful responses } if (brep == null) { log.warn("Cannot extract OCSP response object. OCSP response status: " + response.getStatus()); return null; } X509CertificateHolder[] chain = brep.getCerts(); boolean verify = brep.isSignatureValid(new JcaContentVerifierProviderBuilder() .setProvider(BouncyCastleProvider.PROVIDER_NAME).build(chain[0])); if (!verify) { log.warn("OCSP response signature was not valid"); return null; } } catch (OCSPException | OperatorCreationException | CertificateException e) { if (log.isDebugEnabled()) { log.debug("Failed to obtain or verify OCSP response. " + e.getLocalizedMessage()); } return null; } // ------------- Verify the nonce ---------------// byte[] noncerep; try { noncerep = brep.getExtension(OCSPObjectIdentifiers.id_pkix_ocsp_nonce).getExtnValue().getEncoded(); } catch (IOException e) { if (log.isDebugEnabled()) { log.debug("Failed to read extension from OCSP response. " + e.getLocalizedMessage()); } return null; } if (noncerep == null) { log.warn("Sent an OCSP request containing a nonce, but the OCSP response does not contain a nonce"); return null; } try { ASN1InputStream ain = new ASN1InputStream(noncerep); ASN1OctetString oct = ASN1OctetString.getInstance(ain.readObject()); ain.close(); if (!Arrays.equals(nonce, oct.getOctets())) { log.warn("The nonce in the OCSP request and the OCSP response do not match"); return null; } } catch (IOException e) { if (log.isDebugEnabled()) { log.debug("Failed to read extension from OCSP response. " + e.getLocalizedMessage()); } return null; } // ------------ Extract the single response and verify that it concerns a cert with the right serialnumber ----// SingleResp[] singleResps = brep.getResponses(); if ((singleResps == null) || (singleResps.length == 0)) { if (log.isDebugEnabled()) { log.debug("The OCSP response object contained no responses."); } return null; } SingleResp singleResponse = singleResps[0]; CertificateID certId = singleResponse.getCertID(); if (!certId.getSerialNumber().equals(CertTools.getSerialNumber(cert))) { if (log.isDebugEnabled()) { log.debug( "Certificate serialnumber in response does not match certificate serialnumber in request."); } return null; } // ------------ Return the single response ---------------// return singleResponse; }
From source file:org.ejbca.core.protocol.ocsp.OcspJunitHelper.java
License:Open Source License
private void verifyStatus(int caid, X509Certificate cacert, BigInteger certSerial, int ocspResponseStatus, Status expectedStatus, int expectedReason, Date expectedRevTime) throws NoSuchProviderException, IOException, OCSPException, OperatorCreationException, CertificateException { // And an OCSP request final OCSPReqBuilder gen = new OCSPReqBuilder(); gen.addRequest(new JcaCertificateID(SHA1DigestCalculator.buildSha1Instance(), cacert, certSerial)); log.debug("ocspTestCert.getSerialNumber() = " + certSerial); final String sNonce = "123456789"; Extension[] extensions = new Extension[1]; extensions[0] = new Extension(OCSPObjectIdentifiers.id_pkix_ocsp_nonce, false, new DEROctetString(sNonce.getBytes())); gen.setRequestExtensions(new Extensions(extensions)); final OCSPReq req = gen.build(); // Send the request and receive a singleResponse final SingleResp[] singleResps = sendOCSPPost(req.getEncoded(), sNonce, ocspResponseStatus, 200); // if we expected internal error, we should not expect any data, and can not make any more tests if (ocspResponseStatus == OCSPRespBuilder.INTERNAL_ERROR) { return;/*from w w w.j a v a2 s.c om*/ } if (ocspResponseStatus == OCSPRespBuilder.UNAUTHORIZED) { return; } assertEquals("No of SingleResps should be 1.", 1, singleResps.length); final SingleResp singleResp = singleResps[0]; final CertificateID certId = singleResp.getCertID(); assertEquals("Serno in response does not match serno in request.", certId.getSerialNumber(), certSerial); final Object status = singleResp.getCertStatus(); final String statusClassName = status != null ? status.getClass().getName() : "GOOD";// status==null means GOOD switch (expectedStatus) { case Unknown: assertTrue("Status is not Unknown: " + statusClassName, status instanceof UnknownStatus); break; case Good: if (status != CertificateStatus.GOOD) { log.debug("Certificate status: " + status.getClass().getName()); } assertEquals("Status is not Good, was: " + statusClassName + ".", CertificateStatus.GOOD, status); break; case Revoked: assertTrue("Status is not Revoked: " + statusClassName, status instanceof RevokedStatus); final int reason = ((RevokedStatus) status).getRevocationReason(); assertEquals("Wrong revocation reason", expectedReason, reason); if (expectedRevTime != null) { final Date revTime = ((RevokedStatus) status).getRevocationTime(); assertEquals("Wrong revocation time", expectedRevTime, revTime); } break; } }
From source file:org.ejbca.core.protocol.ocsp.ProtocolLookupServerHttpTest.java
License:Open Source License
/** * Tests ocsp message with good status and a valid unid * /* w ww . j a v a 2s . com*/ * @throws Exception error */ @Test public void test01OcspGoodWithFnr() throws Exception { // Make user that we know... boolean userExists = false; try { endEntityManagementSession.addUser(admin, "unidtest", "foo123", "C=SE,O=AnaTom,surname=Jansson,serialNumber=123456789,CN=UNIDTest", null, "unidtest@anatom.se", false, SecConst.EMPTY_ENDENTITYPROFILE, CertificateProfileConstants.CERTPROFILE_FIXED_ENDUSER, EndEntityTypes.ENDUSER.toEndEntityType(), SecConst.TOKEN_SOFT_PEM, 0, caid); log.debug( "created user: unidtest, foo123, C=SE, O=AnaTom,surname=Jansson,serialNumber=123456789, CN=UNIDTest"); } catch (EndEntityExistsException e) { userExists = true; } if (userExists) { log.debug("User unidtest already exists."); EndEntityInformation userData = new EndEntityInformation("unidtest", "C=SE,O=AnaTom,surname=Jansson,serialNumber=123456789,CN=UNIDTest", caid, null, "unidtest@anatom.se", EndEntityConstants.STATUS_NEW, EndEntityTypes.ENDUSER.toEndEntityType(), SecConst.EMPTY_ENDENTITYPROFILE, CertificateProfileConstants.CERTPROFILE_FIXED_ENDUSER, null, null, SecConst.TOKEN_SOFT_PEM, 0, null); userData.setPassword("foo123"); endEntityManagementSession.changeUser(admin, userData, false); log.debug("Reset status to NEW"); } // Generate certificate for the new user // user that we know exists... ocspTestCert = (X509Certificate) signSession.createCertificate(admin, "unidtest", "foo123", new PublicKeyWrapper(keys.getPublic())); assertNotNull("Failed to create certificate", ocspTestCert); // And an OCSP request OCSPReqBuilder gen = new OCSPReqBuilder(); gen.addRequest(new JcaCertificateID(SHA1DigestCalculator.buildSha1Instance(), cacert, ocspTestCert.getSerialNumber())); Extension[] extensions = new Extension[1]; extensions[0] = new Extension(FnrFromUnidExtension.FnrFromUnidOid, false, new DEROctetString("123456789".getBytes())); gen.setRequestExtensions(new Extensions(extensions)); OCSPReq req = gen.build(); // Send the request and receive a BasicResponse BasicOCSPResp brep = sendOCSPPost(req.getEncoded(), true); assertEquals(getFnr(brep), "654321"); SingleResp[] singleResps = brep.getResponses(); assertEquals("No of SingResps should be 1.", singleResps.length, 1); SingleResp singleResp = singleResps[0]; CertificateID certId = singleResp.getCertID(); assertEquals("Serno in response does not match serno in request.", certId.getSerialNumber(), ocspTestCert.getSerialNumber()); Object status = singleResp.getCertStatus(); assertEquals("Status is not null (good)", status, null); }
From source file:org.ejbca.core.protocol.ocsp.ProtocolLookupServerHttpTest.java
License:Open Source License
/** * Tests ocsp message with bad status and a valid unid * /* www . j av a2s. c om*/ * @throws Exception error */ @Test public void test02OcspBadWithFnr() throws Exception { revocationSession.revokeCertificate(admin, ocspTestCert, null, RevokedCertInfo.REVOCATION_REASON_KEYCOMPROMISE, null); // And an OCSP request OCSPReqBuilder gen = new OCSPReqBuilder(); gen.addRequest(new JcaCertificateID(SHA1DigestCalculator.buildSha1Instance(), cacert, ocspTestCert.getSerialNumber())); Extension[] extensions = new Extension[1]; extensions[0] = new Extension(FnrFromUnidExtension.FnrFromUnidOid, false, new DEROctetString("123456789".getBytes())); gen.setRequestExtensions(new Extensions(extensions)); OCSPReq req = gen.build(); // Send the request and receive a BasicResponse BasicOCSPResp brep = sendOCSPPost(req.getEncoded(), true); // When a certificate is revoked the FNR must not be returned assertEquals(getFnr(brep), null); SingleResp[] singleResps = brep.getResponses(); assertEquals("No of SingResps should be 1.", singleResps.length, 1); SingleResp singleResp = singleResps[0]; CertificateID certId = singleResp.getCertID(); assertEquals("Serno in response does not match serno in request.", certId.getSerialNumber(), ocspTestCert.getSerialNumber()); Object status = singleResp.getCertStatus(); assertTrue("Status is not RevokedStatus", status instanceof RevokedStatus); RevokedStatus rev = (RevokedStatus) status; assertTrue("Status does not have reason", rev.hasRevocationReason()); int reason = rev.getRevocationReason(); assertEquals("Wrong revocation reason", reason, RevokedCertInfo.REVOCATION_REASON_KEYCOMPROMISE); }