List of usage examples for org.bouncycastle.cert.ocsp BasicOCSPResp getExtension
public Extension getExtension(ASN1ObjectIdentifier oid)
From source file:eu.europa.ec.markt.dss.validation102853.ocsp.OnlineOCSPSource.java
License:Open Source License
@Override public BasicOCSPResp getOCSPResponse(final X509Certificate x509Certificate, final X509Certificate issuerX509Certificate) { if (dataLoader == null) { throw new DSSNullException(DataLoader.class); }//from www . ja v a 2s . com try { final String ocspUri = getAccessLocation(x509Certificate); if (LOG.isDebugEnabled()) { LOG.debug("OCSP URI: " + ocspUri); } if (ocspUri == null) { return null; } final byte[] content = buildOCSPRequest(x509Certificate, issuerX509Certificate); final byte[] ocspRespBytes = dataLoader.post(ocspUri, content); final OCSPResp ocspResp = new OCSPResp(ocspRespBytes); /* final int status = ocspResp.getStatus(); System.out.println(status); */ try { final BasicOCSPResp responseObject = (BasicOCSPResp) ocspResp.getResponseObject(); if (ADD_NONCE) { final Extension extension = responseObject .getExtension(OCSPObjectIdentifiers.id_pkix_ocsp_nonce); final DEROctetString receivedNonce = (DEROctetString) extension.getExtnValue(); if (!receivedNonce.equals(nonce)) { throw new DSSException("The OCSP request was the victim of replay attack: nonce[sent:" + nonce + ", received:" + receivedNonce); } } return responseObject; } catch (NullPointerException e) { LOG.error( "OCSP error: Encountered a case when the OCSPResp is initialised with a null OCSP response... (and there are no nullity checks in the OCSPResp implementation)", e); } } catch (OCSPException e) { LOG.error("OCSP error: " + e.getMessage(), e); } catch (IOException e) { throw new DSSException(e); } return null; }
From source file:eu.europa.ec.markt.dss.validation102853.ocsp.SKOnlineOCSPSource.java
License:GNU General Public License
protected void checkNonce(BasicOCSPResp basicOCSPResp, Extension expectedNonceExtension) { final Extension extension = basicOCSPResp.getExtension(OCSPObjectIdentifiers.id_pkix_ocsp_nonce); final DEROctetString expectedNonce = (DEROctetString) expectedNonceExtension.getExtnValue(); final DEROctetString receivedNonce = (DEROctetString) extension.getExtnValue(); if (!receivedNonce.equals(expectedNonce)) { throw new DigiDoc4JException("The OCSP request was the victim of replay attack: nonce[sent:" + expectedNonce + "," + " received:" + receivedNonce); }/* w ww. j a va 2 s . com*/ }
From source file:eu.europa.esig.dss.client.ocsp.OnlineOCSPSource.java
License:Open Source License
private boolean isNonceMatch(final BasicOCSPResp basicOCSPResp) { Extension extension = basicOCSPResp.getExtension(OCSPObjectIdentifiers.id_pkix_ocsp_nonce); DEROctetString derReceivedNonce = (DEROctetString) extension.getExtnValue(); BigInteger receivedNonce = new BigInteger(derReceivedNonce.getOctets()); return receivedNonce.equals(nonceSource.getNonce()); }
From source file:net.maritimecloud.pki.ocsp.OCSPClient.java
License:Open Source License
public CertStatus getCertificateStatus() throws OCSPValidationException { try {/*from w w w. j a v a 2 s .c o m*/ if (null == url) { throw new OCSPValidationException("Certificate not validated by OCSP"); } byte[] encodedOcspRequest = generateOCSPRequest(issuer, certificate.getSerialNumber()).getEncoded(); HttpURLConnection httpConnection; httpConnection = (HttpURLConnection) url.openConnection(); httpConnection.setRequestProperty("Content-Type", "application/ocsp-request"); httpConnection.setRequestProperty("Accept", "application/ocsp-response"); httpConnection.setDoOutput(true); try (DataOutputStream dataOut = new DataOutputStream( new BufferedOutputStream(httpConnection.getOutputStream()))) { dataOut.write(encodedOcspRequest); dataOut.flush(); } InputStream in = (InputStream) httpConnection.getContent(); if (httpConnection.getResponseCode() != HttpURLConnection.HTTP_OK) { throw new OCSPValidationException( "Received HTTP code != 200 [" + httpConnection.getResponseCode() + "]"); } OCSPResp ocspResponse = new OCSPResp(in); BasicOCSPResp basicResponse = (BasicOCSPResp) ocspResponse.getResponseObject(); byte[] receivedNonce = basicResponse.getExtension(OCSPObjectIdentifiers.id_pkix_ocsp_nonce).getExtnId() .getEncoded(); if (!Arrays.equals(receivedNonce, sentNonce)) { throw new OCSPValidationException("Nonce in ocsp response does not match nonce of ocsp request"); } X509CertificateHolder certHolder = basicResponse.getCerts()[0]; if (!basicResponse .isSignatureValid(new JcaContentVerifierProviderBuilder().setProvider("BC").build(issuer))) { if (!certHolder.isValidOn(Date.from(Instant.now()))) { throw new OCSPValidationException("Certificate is not valid today!"); } // Certificate must have a Key Purpose ID for authorized responders if (!ExtendedKeyUsage.fromExtensions(certHolder.getExtensions()) .hasKeyPurposeId(KeyPurposeId.id_kp_OCSPSigning)) { throw new OCSPValidationException( "Certificate does not contain required extension (id_kp_OCSPSigning)"); } // Certificate must be issued by the same CA of the certificate that we are verifying if (!certHolder.isSignatureValid( new JcaContentVerifierProviderBuilder().setProvider("BC").build(issuer))) { throw new OCSPValidationException("Certificate is not signed by the same issuer"); } // Validate signature in OCSP response if (!basicResponse.isSignatureValid( new JcaContentVerifierProviderBuilder().setProvider("BC").build(certHolder))) { throw new OCSPValidationException("Could not validate OCSP response!"); } } else { if (!certHolder.isValidOn(Date.from(Instant.now()))) { throw new OCSPValidationException("Certificate is not valid today!"); } } // SCEE Certificate Policy (?) /*if (null == certHolder.getExtension(OCSPObjectIdentifiers.id_pkix_ocsp_nocheck) || null == certHolder.getExtension(OCSPObjectIdentifiers.id_pkix_ocsp_nocheck).getExtnId()) { throw new OCSPValidationException("Extension id_pkix_ocsp_nocheck not found in certificate"); }*/ SingleResp[] responses = basicResponse.getResponses(); if (responses[0].getCertID().getSerialNumber().equals(certificate.getSerialNumber())) { CertificateStatus status = responses[0].getCertStatus(); if (status == CertificateStatus.GOOD) { return CertStatus.GOOD; } else { if (status instanceof RevokedStatus) { revokedStatus = (RevokedStatus) status; return CertStatus.REVOKED; } else { return CertStatus.UNKNOWN; } } } else { throw new OCSPValidationException( "Serial number of certificate in response ocsp does not match certificate serial number"); } } catch (CertificateEncodingException | OperatorCreationException | OCSPException | IOException ex) { throw new OCSPValidationException("Unable to perform validation through OCSP (" + certificate.getSubjectX500Principal().getName() + ")", ex); } catch (CertException | CertificateException ex) { throw new OCSPValidationException("Unable to perform validation through OCSP (" + certificate.getSubjectX500Principal().getName() + ")", ex); } }
From source file:org.cesecore.certificates.ocsp.OcspResponseInformation.java
License:Open Source License
public OcspResponseInformation(OCSPResp ocspResponse, long maxAge) throws OCSPException { try {/*from ww w .java2 s . c om*/ this.ocspResponse = ocspResponse.getEncoded(); } catch (IOException e) { throw new IllegalStateException("Unexpected IOException caught when encoding ocsp response.", e); } this.maxAge = maxAge; /* * This may seem like a somewhat odd place to perform the below operations (instead of in the end servlet which demanded * this object), but BouncyCastle (up to 1.47) is a bit shy about making their classes serializable. This means that * OCSPResp can't be transmitted, neither can many of the objects it contains such as SingleResp. Luckily we only need * these classes for the diagnostic operations performed below, so we can sum up the result in the boolean member * addCacheHeaders. If BC choose to change their policy, the below code can med moved to a more logical location. * -mikek */ if (ocspResponse.getResponseObject() == null) { if (log.isDebugEnabled()) { log.debug("Will not add cache headers for response to bad request."); } addCacheHeaders = false; } else { final BasicOCSPResp basicOCSPResp = (BasicOCSPResp) ocspResponse.getResponseObject(); final SingleResp[] singleRespones = basicOCSPResp.getResponses(); if (singleRespones.length != 1) { if (log.isDebugEnabled()) { log.debug("Will not add RFC 5019 cache headers: reponse contains multiple embedded responses."); } addCacheHeaders = false; } else if (singleRespones[0].getNextUpdate() == null) { if (log.isDebugEnabled()) { log.debug("Will not add RFC 5019 cache headers: nextUpdate isn't set."); } addCacheHeaders = false; } else if (basicOCSPResp.hasExtensions() && basicOCSPResp.getExtension(OCSPObjectIdentifiers.id_pkix_ocsp_nonce) != null) { if (log.isDebugEnabled()) { log.debug("Will not add RFC 5019 cache headers: response contains a nonce."); } addCacheHeaders = false; } else { nextUpdate = singleRespones[0].getNextUpdate().getTime(); thisUpdate = singleRespones[0].getThisUpdate().getTime(); try { responseHeader = new String(Hex.encode(MessageDigest .getInstance("SHA-1", BouncyCastleProvider.PROVIDER_NAME).digest(this.ocspResponse))); } catch (NoSuchProviderException e) { throw new OcspFailureException("Bouncycastle was not available as a provider", e); } catch (NoSuchAlgorithmException e) { throw new OcspFailureException("SHA-1 was not an available algorithm for MessageDigester", e); } } if (addCacheHeaders && singleRespones[0].getCertStatus() instanceof UnknownStatus) { explicitNoCache = true; } } }
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 w w. j a v 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.digidoc4j.impl.bdoc.OcspNonceValidator.java
License:GNU General Public License
private boolean isOcspResponseValid(BasicOCSPResp latestOcspResponse) { Extension extension = latestOcspResponse.getExtension(new ASN1ObjectIdentifier("1.3.6.1.5.5.7.48.1.2")); if (extension == null) { logger.error("No valid OCSP extension found in signature: " + signature.getId()); return false; }//from w w w.j a va 2 s .c om return isOcspExtensionValid(extension); }
From source file:org.ejbca.core.protocol.ocsp.OcspJunitHelper.java
License:Open Source License
/** * * @param ocspPackage/* w ww . j a va2 s . c o m*/ * @param nonce * @param respCode expected response code, OK = 0, if not 0, response checking will not continue after response code is checked. * @param httpCode, normally 200 for OK or OCSP error. Can be 400 is more than 1 million bytes is sent for example * @return a SingleResp or null if respCode != 0 * @throws IOException * @throws OCSPException * @throws NoSuchProviderException * @throws CertificateException on parsing errors. * @throws OperatorCreationException */ protected SingleResp[] sendOCSPPost(byte[] ocspPackage, String nonce, int respCode, int httpCode) throws IOException, OCSPException, NoSuchProviderException, OperatorCreationException, CertificateException { // POST the OCSP request URL url = new URL(this.sBaseURL + this.urlEnding); HttpURLConnection 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(ocspPackage); os.close(); assertEquals("Response code", httpCode, con.getResponseCode()); if (con.getResponseCode() != 200) { return null; // if it is an http error code we don't need to test any more } // Some appserver (Weblogic) responds with "application/ocsp-response; charset=UTF-8" assertNotNull("No Content-Type in reply.", con.getContentType()); assertTrue(con.getContentType().startsWith("application/ocsp-response")); OCSPResp response = new OCSPResp(IOUtils.toByteArray(con.getInputStream())); assertEquals("Response status not the expected.", respCode, response.getStatus()); if (respCode != 0) { assertNull("According to RFC 2560, responseBytes are not set on error.", response.getResponseObject()); return null; // it messes up testing of invalid signatures... but is needed for the unsuccessful responses } BasicOCSPResp brep = (BasicOCSPResp) response.getResponseObject(); X509CertificateHolder[] chain = brep.getCerts(); assertNotNull( "No certificate chain returned in response (chain == null), is ocsp.includesignercert=false in ocsp.properties?. It should be set to default value for test to run.", chain); boolean verify = brep.isSignatureValid(new JcaContentVerifierProviderBuilder().build(chain[0])); assertTrue("Response failed to verify.", verify); // Check nonce (if we sent one) if (nonce != null) { byte[] noncerep = brep.getExtension(OCSPObjectIdentifiers.id_pkix_ocsp_nonce).getExtnValue() .getEncoded(); assertNotNull(noncerep); ASN1InputStream ain = new ASN1InputStream(noncerep); ASN1OctetString oct = ASN1OctetString.getInstance(ain.readObject()); ain.close(); assertEquals(nonce, new String(oct.getOctets())); } SingleResp[] singleResps = brep.getResponses(); return singleResps; }
From source file:org.ejbca.core.protocol.ocsp.OcspJunitHelper.java
License:Open Source License
/** * * @param ocspPackage// ww w . j av a2 s.co m * @param nonce * @param respCode expected response code, OK = 0, if not 0, response checking will not continue after response code is checked. * @param httpCode, normally 200 for OK or OCSP error. Can be 400 is more than 1 million bytes is sent for example * @return a BasicOCSPResp or null if not found * @throws IOException * @throws OCSPException * @throws NoSuchProviderException * @throws NoSuchAlgorithmException * @throws CertificateException on parsing errors. * @throws OperatorCreationException */ protected BasicOCSPResp sendOCSPGet(byte[] ocspPackage, String nonce, int respCode, int httpCode, boolean shouldIncludeSignCert, X509Certificate signCert) throws IOException, OCSPException, NoSuchProviderException, NoSuchAlgorithmException, OperatorCreationException, CertificateException { // GET the OCSP request String b64 = new String(Base64.encode(ocspPackage, false)); //String urls = URLEncoder.encode(b64, "UTF-8"); // JBoss/Tomcat will not accept escaped '/'-characters by default URL url = new URL(this.sBaseURL + '/' + b64 + this.urlEnding); HttpURLConnection con = (HttpURLConnection) url.openConnection(); if (con.getResponseCode() != httpCode) { log.info("URL when request gave unexpected result: " + url.toString() + " Message was: " + con.getResponseMessage()); } assertEquals("Response code did not match. ", httpCode, con.getResponseCode()); if (con.getResponseCode() != 200) { return null; // if it is an http error code we don't need to test any more } // Some appserver (Weblogic) responds with "application/ocsp-response; charset=UTF-8" assertNotNull(con.getContentType()); assertTrue(con.getContentType().startsWith("application/ocsp-response")); OCSPResp response = new OCSPResp(IOUtils.toByteArray(con.getInputStream())); assertNotNull("Response should not be null.", response); assertEquals("Response status not the expected.", respCode, response.getStatus()); if (respCode != 0) { assertNull("According to RFC 2560, responseBytes are not set on error.", response.getResponseObject()); return null; // it messes up testing of invalid signatures... but is needed for the unsuccessful responses } BasicOCSPResp brep = (BasicOCSPResp) response.getResponseObject(); final X509CertificateHolder signCertHolder; if (!shouldIncludeSignCert) { assertEquals("The signing certificate should not be included in the OCSP response ", 0, brep.getCerts().length); signCertHolder = new JcaX509CertificateHolder(signCert); } else { X509CertificateHolder[] chain = brep.getCerts(); signCertHolder = chain[0]; } boolean verify = brep.isSignatureValid(new JcaContentVerifierProviderBuilder().build(signCertHolder)); assertTrue("Response failed to verify.", verify); // Check nonce (if we sent one) if (nonce != null) { byte[] noncerep = brep.getExtension(OCSPObjectIdentifiers.id_pkix_ocsp_nonce).getExtnValue() .getEncoded(); assertNotNull(noncerep); ASN1InputStream ain = new ASN1InputStream(noncerep); ASN1OctetString oct = ASN1OctetString.getInstance(ain.readObject()); ain.close(); assertEquals(nonce, new String(oct.getOctets())); } return brep; }
From source file:org.ejbca.core.protocol.ocsp.OCSPUnidClient.java
License:Open Source License
private OCSPUnidResponse sendOCSPRequest(byte[] ocspPackage, X509Certificate knownTrustAnchor, boolean useGet) throws IOException, OCSPException, OperatorCreationException, CertificateException, UnrecoverableKeyException, KeyManagementException, NoSuchAlgorithmException, KeyStoreException { final HttpURLConnection con; if (useGet) { String b64 = new String(Base64.encode(ocspPackage, false)); URL url = new URL(httpReqPath + '/' + b64); con = (HttpURLConnection) url.openConnection(); } else {/*from ww w .j a va 2s.c o m*/ // POST the OCSP request URL url = new URL(httpReqPath); con = (HttpURLConnection) getUrlConnection(url); // we are going to do a POST con.setDoOutput(true); con.setRequestMethod("POST"); // POST it con.setRequestProperty("Content-Type", "application/ocsp-request"); OutputStream os = null; try { os = con.getOutputStream(); os.write(ocspPackage); } finally { if (os != null) { os.close(); } } } final OCSPUnidResponse ret = new OCSPUnidResponse(); ret.setHttpReturnCode(con.getResponseCode()); if (ret.getHttpReturnCode() != 200) { if (ret.getHttpReturnCode() == 401) { ret.setErrorCode(OCSPUnidResponse.ERROR_UNAUTHORIZED); } else { ret.setErrorCode(OCSPUnidResponse.ERROR_UNKNOWN); } return ret; } final OCSPResp response; { final InputStream in = con.getInputStream(); if (in != null) { try { response = new OCSPResp(IOUtils.toByteArray(in)); } finally { in.close(); } } else { response = null; } } if (response == null) { ret.setErrorCode(OCSPUnidResponse.ERROR_NO_RESPONSE); return ret; } ret.setResp(response); final BasicOCSPResp brep = (BasicOCSPResp) response.getResponseObject(); if (brep == null) { ret.setErrorCode(OCSPUnidResponse.ERROR_NO_RESPONSE); return ret; } // Compare nonces to see if the server sent the same nonce as we sent final byte[] noncerep = brep.getExtension(OCSPObjectIdentifiers.id_pkix_ocsp_nonce).getExtnValue() .getEncoded(); if (noncerep != null) { ASN1InputStream ain = new ASN1InputStream(noncerep); ASN1OctetString oct = ASN1OctetString.getInstance(ain.readObject()); ain.close(); boolean eq = ArrayUtils.isEquals(this.nonce, oct.getOctets()); if (!eq) { ret.setErrorCode(OCSPUnidResponse.ERROR_INVALID_NONCE); return ret; } } final RespID id = brep.getResponderId(); final DERTaggedObject to = (DERTaggedObject) id.toASN1Object().toASN1Primitive(); final RespID respId; final X509CertificateHolder[] chain = brep.getCerts(); JcaX509CertificateConverter converter = new JcaX509CertificateConverter(); X509Certificate signerCertificate = converter.getCertificate(chain[0]); final PublicKey signerPub = signerCertificate.getPublicKey(); if (to.getTagNo() == 1) { // This is Name respId = new JcaRespID(signerCertificate.getSubjectX500Principal()); } else { // This is KeyHash respId = new JcaRespID(signerPub, SHA1DigestCalculator.buildSha1Instance()); } if (!id.equals(respId)) { // Response responderId does not match signer certificate responderId! ret.setErrorCode(OCSPUnidResponse.ERROR_INVALID_SIGNERID); } if (!brep.isSignatureValid(new JcaContentVerifierProviderBuilder().build(signerPub))) { ret.setErrorCode(OCSPUnidResponse.ERROR_INVALID_SIGNATURE); return ret; } /* * Okay, at this point we have three different variables and six different possible valid use cases. These * variables are: * 1. If the OCSP reply is from a CA (integrated) or an OCSP responder (standalone) * 2. If it was from a CA, then if that CA is self signed or a subCA * 3. If the server (in the integrated case) or keybinding (standalone case) was set to include the certificate chain */ //If we have a chain, verify it if (chain.length > 1) { // end at one shortof chain.length, because the root certificate is (usually) not included in the OCSP response // TODO: improve this when we can pass in the root cert from parameter to properly validate the whole chain for (int i = 0; i + 1 < chain.length; i++) { final X509Certificate cert1 = converter.getCertificate(chain[i]); final X509Certificate cert2 = converter.getCertificate(chain[Math.min(i + 1, chain.length - 1)]); try { cert1.verify(cert2.getPublicKey()); } catch (GeneralSecurityException e) { m_log.info("Verifying problem with", e); m_log.info("Certificate to be verified: " + cert1); m_log.info("Verifying certificate: " + cert2); ret.setErrorCode(OCSPUnidResponse.ERROR_INVALID_SIGNERCERT); return ret; } } } if (CertTools.isCA(signerCertificate)) { //Verify that the signer certificate was the same as the trust anchor if (!signerCertificate.getSerialNumber().equals(knownTrustAnchor.getSerialNumber())) { m_log.info("Signing certificate for integrated OCSP was not the provided trust anchor."); ret.setErrorCode(OCSPUnidResponse.ERROR_INVALID_SIGNERCERT); return ret; } } else if (CertTools.isOCSPCert(signerCertificate)) { //If an OCSP certificate was used to sign try { signerCertificate.verify(knownTrustAnchor.getPublicKey()); } catch (GeneralSecurityException e) { m_log.info("Signing certificate was not signed by known trust anchor."); ret.setErrorCode(OCSPUnidResponse.ERROR_INVALID_SIGNERCERT); return ret; } } else { m_log.info("Signing certificate was not an OCSP certificate."); ret.setErrorCode(OCSPUnidResponse.ERROR_INVALID_SIGNERCERT); return ret; } String fnr = getFnr(brep); if (fnr != null) { ret.setFnr(fnr); } return ret; }