List of usage examples for org.bouncycastle.cert.ocsp BasicOCSPResp isSignatureValid
public boolean isSignatureValid(ContentVerifierProvider verifierProvider) throws OCSPException
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.ejbca.core.protocol.ocsp.OcspJunitHelper.java
License:Open Source License
/** * * @param ocspPackage/* w w w .j ava2 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 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/*from w ww .j a va 2 s.c om*/ * @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 {//ww w . j a v a 2 s . c om // 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; }
From source file:org.ejbca.core.protocol.ocsp.ProtocolLookupServerHttpTest.java
License:Open Source License
private BasicOCSPResp sendOCSPPost(byte[] ocspPackage, boolean trust) throws IOException, OCSPException, GeneralSecurityException, OperatorCreationException { // POST the OCSP request URL url = new URL(httpReqPath + '/' + resourceOcsp); HttpURLConnection con = (HttpURLConnection) getUrlConnection(url, trust); // we are going to do a POST con.setDoOutput(true);//from w ww .j a v a 2 s . c om con.setRequestMethod("POST"); // POST it con.setRequestProperty("Content-Type", "application/ocsp-request"); OutputStream os = con.getOutputStream(); os.write(ocspPackage); os.close(); assertEquals("Response code", 200, con.getResponseCode()); assertEquals("Content-Type", "application/ocsp-response", con.getContentType()); ByteArrayOutputStream baos = new ByteArrayOutputStream(); // This works for small requests, and OCSP requests are small InputStream in = con.getInputStream(); int b = in.read(); while (b != -1) { baos.write(b); b = in.read(); } baos.flush(); in.close(); byte[] respBytes = baos.toByteArray(); OCSPResp response = new OCSPResp(respBytes); assertEquals("Response status not zero.", response.getStatus(), 0); BasicOCSPResp brep = (BasicOCSPResp) response.getResponseObject(); X509CertificateHolder[] chain = brep.getCerts(); boolean verify = brep.isSignatureValid(new JcaContentVerifierProviderBuilder().build(chain[0])); assertTrue("Response failed to verify.", verify); return brep; }
From source file:org.ejbca.core.protocol.ocsp.ProtocolOcspHttpPerfTest.java
License:Open Source License
private SingleResp sendOCSPPost(byte[] ocspPackage, String nonce) throws IOException, OCSPException, NoSuchProviderException, OperatorCreationException, CertificateException { // POST the OCSP request URL url = new URL(httpReqPath + '/' + resourceOcsp); HttpURLConnection con = (HttpURLConnection) url.openConnection(); // we are going to do a POST con.setDoOutput(true);//from ww w . j a v a 2 s . co m con.setRequestMethod("POST"); // POST it con.setRequestProperty("Content-Type", "application/ocsp-request"); OutputStream os = con.getOutputStream(); os.write(ocspPackage); os.close(); assertEquals("Response code", 200, con.getResponseCode()); assertEquals("Content-Type", "application/ocsp-response", con.getContentType()); ByteArrayOutputStream baos = new ByteArrayOutputStream(); // This works for small requests, and OCSP requests are small InputStream in = con.getInputStream(); int b = in.read(); while (b != -1) { baos.write(b); b = in.read(); } baos.flush(); in.close(); byte[] respBytes = baos.toByteArray(); OCSPResp response = new OCSPResp(respBytes); assertEquals("Response status not zero.", response.getStatus(), 0); BasicOCSPResp brep = (BasicOCSPResp) response.getResponseObject(); X509CertificateHolder[] chain = brep.getCerts(); 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(); assertEquals("No of SingResps should be 1.", singleResps.length, 1); SingleResp singleResp = singleResps[0]; return singleResp; }
From source file:org.ejbca.core.protocol.ocsp.ProtocolOcspHttpStandaloneTest.java
License:Open Source License
private void testVerifyHttpGetHeaders(X509Certificate caCertificate, BigInteger serialNumber) throws Exception { // An OCSP request, ocspTestCert is already created in earlier tests OCSPReqBuilder gen = new OCSPReqBuilder(); gen.addRequest(new JcaCertificateID(SHA1DigestCalculator.buildSha1Instance(), caCertificate, serialNumber)); OCSPReq req = gen.build();/* w w w . j av a 2s . com*/ String reqString = new String(Base64.encode(req.getEncoded(), false)); URL url = new URL(httpReqPath + '/' + resourceOcsp + '/' + URLEncoder.encode(reqString, "UTF-8")); log.debug("OCSP Request: " + url.toExternalForm()); HttpURLConnection con = (HttpURLConnection) url.openConnection(); assertEquals( "Response code did not match. (Make sure you allow encoded slashes in your appserver.. add -Dorg.apache.tomcat.util.buf.UDecoder.ALLOW_ENCODED_SLASH=true in Tomcat)", 200, con.getResponseCode()); // 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())); assertEquals("Response status not the expected.", OCSPRespBuilder.SUCCESSFUL, response.getStatus()); BasicOCSPResp brep = (BasicOCSPResp) response.getResponseObject(); // Just output the headers to stdout so we can visually inspect them if // something goes wrong Set<String> keys = con.getHeaderFields().keySet(); for (String field : keys) { List<String> values = con.getHeaderFields().get(field); for (String value : values) { log.info(field + ": " + value); } } String eTag = con.getHeaderField("ETag"); assertNotNull( "RFC 5019 6.2: No 'ETag' HTTP header present as it SHOULD. (Make sure ocsp.untilNextUpdate and ocsp.maxAge are configured for this test)", eTag); assertTrue("ETag is messed up.", ("\"" + new String( Hex.encode(MessageDigest.getInstance("SHA-1", "BC").digest(response.getEncoded()))) + "\"") .equals(eTag)); long date = con.getHeaderFieldDate("Date", -1); assertTrue("RFC 5019 6.2: No 'Date' HTTP header present as it SHOULD.", date != -1); long lastModified = con.getHeaderFieldDate("Last-Modified", -1); assertTrue("RFC 5019 6.2: No 'Last-Modified' HTTP header present as it SHOULD.", lastModified != -1); // assertTrue("Last-Modified is after response was sent", // lastModified<=date); This will not hold on JBoss AS due to the // caching of the Date-header long expires = con.getExpiration(); assertTrue("Expires is before response was sent", expires >= date); assertTrue("RFC 5019 6.2: No 'Expires' HTTP header present as it SHOULD.", expires != 0); String cacheControl = con.getHeaderField("Cache-Control"); assertNotNull("RFC 5019 6.2: No 'Cache-Control' HTTP header present as it SHOULD.", cacheControl); assertTrue("RFC 5019 6.2: No 'public' HTTP header Cache-Control present as it SHOULD.", cacheControl.contains("public")); assertTrue("RFC 5019 6.2: No 'no-transform' HTTP header Cache-Control present as it SHOULD.", cacheControl.contains("no-transform")); assertTrue("RFC 5019 6.2: No 'must-revalidate' HTTP header Cache-Control present as it SHOULD.", cacheControl.contains("must-revalidate")); Matcher matcher = Pattern.compile(".*max-age\\s*=\\s*(\\d+).*").matcher(cacheControl); assertTrue("RFC 5019 6.2: No 'max-age' HTTP header Cache-Control present as it SHOULD.", matcher.matches()); int maxAge = Integer.parseInt(matcher.group(1)); log.debug("maxAge=" + maxAge + " (expires-lastModified)/1000=" + ((expires - lastModified) / 1000)); assertTrue( "thisUpdate and nextUpdate should not be the same (Make sure ocsp.untilNextUpdate and ocsp.maxAge are configured for this test)", expires != lastModified); assertTrue("RFC 5019 6.2: [maxAge] SHOULD be 'later than thisUpdate but earlier than nextUpdate'.", maxAge < (expires - lastModified) / 1000); // assertTrue("Response cannot be produced after it was sent.", // brep.getProducedAt().getTime() <= date); This might not hold on JBoss // AS due to the caching of the Date-header X509CertificateHolder[] chain = brep.getCerts(); boolean verify = brep.isSignatureValid(new JcaContentVerifierProviderBuilder().build(chain[0])); assertTrue("Response failed to verify.", verify); assertNull("No nonce should be present.", brep.getExtension(OCSPObjectIdentifiers.id_pkix_ocsp_nonce)); SingleResp[] singleResps = brep.getResponses(); assertNotNull("SingleResps should not be null.", singleResps); assertTrue("Expected a single SingleResp in the repsonse.", singleResps.length == 1); assertEquals("Serno in response does not match serno in request.", singleResps[0].getCertID().getSerialNumber(), serialNumber); assertEquals("Status is not null (null is 'good')", singleResps[0].getCertStatus(), null); assertTrue( "RFC 5019 6.2: Last-Modified SHOULD 'be the same as the thisUpdate timestamp in the request itself'", singleResps[0].getThisUpdate().getTime() == lastModified); assertTrue("RFC 5019 6.2: Expires SHOULD 'be the same as the nextUpdate timestamp in the request itself'", singleResps[0].getNextUpdate().getTime() == expires); assertTrue("Response cannot be produced before it was last modified..", brep.getProducedAt().getTime() >= singleResps[0].getThisUpdate().getTime()); }
From source file:org.ejbca.core.protocol.ocsp.ProtocolOcspHttpStandaloneTest.java
License:Open Source License
private void testNextUpdateThisUpdate(X509Certificate caCertificate, BigInteger serialNumber) throws Exception { // And an OCSP request OCSPReqBuilder gen = new OCSPReqBuilder(); gen.addRequest(new JcaCertificateID(SHA1DigestCalculator.buildSha1Instance(), caCertificate, serialNumber)); OCSPReq req = gen.build();// w w w . j a v a 2s . c o m // POST the request and receive a singleResponse URL url = new URL(httpReqPath + '/' + resourceOcsp); HttpURLConnection con = (HttpURLConnection) url.openConnection(); con.setDoOutput(true); con.setRequestMethod("POST"); con.setRequestProperty("Content-Type", "application/ocsp-request"); OutputStream os = con.getOutputStream(); os.write(req.getEncoded()); os.close(); assertEquals("Response code", 200, con.getResponseCode()); // 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())); assertEquals("Response status not the expected.", 0, response.getStatus()); BasicOCSPResp brep = (BasicOCSPResp) response.getResponseObject(); X509CertificateHolder[] chain = brep.getCerts(); boolean verify = brep.isSignatureValid(new JcaContentVerifierProviderBuilder().build(chain[0])); assertTrue("Response failed to verify.", verify); SingleResp[] singleResps = brep.getResponses(); assertEquals("No of SingResps should be 1.", 1, singleResps.length); CertificateID certId = singleResps[0].getCertID(); assertEquals("Serno in response does not match serno in request.", certId.getSerialNumber(), serialNumber); assertNull("Status is not null.", singleResps[0].getCertStatus()); Date thisUpdate = singleResps[0].getThisUpdate(); Date nextUpdate = singleResps[0].getNextUpdate(); Date producedAt = brep.getProducedAt(); assertNotNull("thisUpdate was not set.", thisUpdate); assertNotNull("nextUpdate was not set. (This test requires ocsp.untilNextUpdate to be configured.)", nextUpdate); assertNotNull("producedAt was not set.", producedAt); assertTrue("nextUpdate cannot be before thisUpdate.", !nextUpdate.before(thisUpdate)); assertTrue("producedAt cannot be before thisUpdate.", !producedAt.before(thisUpdate)); }
From source file:org.ejbca.core.protocol.ocsp.ProtocolOcspHttpTest.java
License:Open Source License
/** * Verify that Internal OCSP responses are signed by CA signing key. *//*from w w w. ja v a2 s . c om*/ @Test public void test17OCSPResponseSignature() throws Exception { // Get user and ocspTestCert that we know... loadUserCert(caid); this.helper.reloadKeys(); // 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(OCSPObjectIdentifiers.id_pkix_ocsp_nonce, false, new DEROctetString("123456789".getBytes())); gen.setRequestExtensions(new Extensions(extensions)); OCSPReq req = gen.build(); // POST the OCSP request URL url = new URL(httpReqPath + '/' + resourceOcsp); 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(req.getEncoded()); os.close(); assertTrue("HTTP error", con.getResponseCode() == 200); // 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())); assertTrue("Response status not the expected.", response.getStatus() != 200); BasicOCSPResp brep = (BasicOCSPResp) response.getResponseObject(); boolean verify = brep .isSignatureValid(new JcaContentVerifierProviderBuilder().build(cacert.getPublicKey())); assertTrue("Signature verification", verify); }
From source file:org.jivesoftware.openfire.net.OCSPChecker.java
License:Open Source License
@Override public void check(Certificate cert, Collection<String> unresolvedCritExts) throws CertPathValidatorException { Log.debug("OCSPChecker: check called"); InputStream in = null;//from ww w . j ava2s.c o m OutputStream out = null; try { // Examine OCSP properties X509Certificate responderCert = null; boolean haveResponderCert = true; //defaults to issuers cert X500Principal responderSubjectName = null; boolean haveIssuerCert = false; // If we set the subject name, we need to find the certificate if (ocspServerSubject != null) { haveResponderCert = false; responderSubjectName = new X500Principal(ocspServerSubject); } X509Certificate issuerCert = null; X509Certificate currCert = (X509Certificate) cert; // Set the issuer certificate if we were passed a chain if (certIndex != 0) { issuerCert = (X509Certificate) (certs[certIndex]); haveIssuerCert = true; if (haveResponderCert) { responderCert = certs[certIndex]; } } if (!haveIssuerCert || !haveResponderCert) { if (!haveResponderCert) { Log.debug("OCSPChecker: Looking for responder's certificate"); } if (!haveIssuerCert) { Log.debug("OCSPChecker: Looking for issuer's certificate"); } // Extract the anchor certs Iterator anchors = pkixParams.getTrustAnchors().iterator(); if (!anchors.hasNext()) { throw new CertPathValidatorException("Must specify at least one trust anchor"); } X500Principal certIssuerName = currCert.getIssuerX500Principal(); while (anchors.hasNext() && (!haveIssuerCert || !haveResponderCert)) { TrustAnchor anchor = (TrustAnchor) anchors.next(); X509Certificate anchorCert = anchor.getTrustedCert(); X500Principal anchorSubjectName = anchorCert.getSubjectX500Principal(); // Check if this anchor cert is the issuer cert if (!haveIssuerCert && certIssuerName.equals(anchorSubjectName)) { issuerCert = anchorCert; haveIssuerCert = true; //If we have not set the responderCert at this point, set it to the issuer if (haveResponderCert && responderCert == null) { responderCert = anchorCert; Log.debug("OCSPChecker: Responder's certificate = issuer certificate"); } } // Check if this anchor cert is the responder cert if (!haveResponderCert) { if (responderSubjectName != null && responderSubjectName.equals(anchorSubjectName)) { responderCert = anchorCert; haveResponderCert = true; } } } if (issuerCert == null) { //No trust anchor was found matching the issuer throw new CertPathValidatorException("No trusted certificate for " + currCert.getIssuerDN()); } // Check cert stores if responder cert has not yet been found if (!haveResponderCert) { Log.debug("OCSPChecker: Searching cert stores for responder's certificate"); if (responderSubjectName != null) { X509CertSelector filter = new X509CertSelector(); filter.setSubject(responderSubjectName.getName()); List<CertStore> certStores = pkixParams.getCertStores(); for (CertStore certStore : certStores) { Iterator i = certStore.getCertificates(filter).iterator(); if (i.hasNext()) { responderCert = (X509Certificate) i.next(); haveResponderCert = true; break; } } } } } // Could not find the responder cert if (!haveResponderCert) { throw new CertPathValidatorException("Cannot find the responder's certificate."); } // Construct an OCSP Request OCSPReqBuilder gen = new OCSPReqBuilder(); CertificateID certID = new CertificateID( new JcaDigestCalculatorProviderBuilder().setProvider("BC").build().get(CertificateID.HASH_SHA1), new X509CertificateHolder(issuerCert.getEncoded()), currCert.getSerialNumber()); gen.addRequest(certID); OCSPReq ocspRequest = gen.build(); URL url; if (ocspServerUrl != null) { try { url = new URL(ocspServerUrl); } catch (MalformedURLException e) { throw new CertPathValidatorException(e); } } else { throw new CertPathValidatorException("Must set OCSP Server URL"); } HttpURLConnection con = (HttpURLConnection) url.openConnection(); Log.debug("OCSPChecker: connecting to OCSP service at: " + url); con.setDoOutput(true); con.setDoInput(true); con.setRequestMethod("POST"); con.setRequestProperty("Content-type", "application/ocsp-request"); con.setRequestProperty("Accept", "application/ocsp-response"); byte[] bytes = ocspRequest.getEncoded(); con.setRequestProperty("Content-length", String.valueOf(bytes.length)); out = con.getOutputStream(); out.write(bytes); out.flush(); // Check the response if (con.getResponseCode() != HttpURLConnection.HTTP_OK) { Log.debug("OCSPChecker: Received HTTP error: " + con.getResponseCode() + " - " + con.getResponseMessage()); } in = con.getInputStream(); OCSPResp ocspResponse = new OCSPResp(in); BigInteger serialNumber = currCert.getSerialNumber(); BasicOCSPResp brep = (BasicOCSPResp) ocspResponse.getResponseObject(); try { if (!brep.isSignatureValid(new JcaContentVerifierProviderBuilder().setProvider("BC") .build(responderCert.getPublicKey()))) { throw new CertPathValidatorException("OCSP response is not verified"); } } catch (Exception e) { throw new CertPathValidatorException("OCSP response could not be verified (" + e.getMessage() + ")", null, cp, certIndex); } SingleResp[] singleResp = brep.getResponses(); boolean foundResponse = false; for (SingleResp resp : singleResp) { CertificateID respCertID = resp.getCertID(); if (respCertID.equals(certID)) { Object status = resp.getCertStatus(); if (status == CertificateStatus.GOOD) { Log.debug("OCSPChecker: Status of certificate (with serial number " + serialNumber.toString() + ") is: good"); foundResponse = true; break; } else if (status instanceof org.bouncycastle.cert.ocsp.RevokedStatus) { Log.debug("OCSPChecker: Status of certificate (with serial number " + serialNumber.toString() + ") is: revoked"); throw new CertPathValidatorException("Certificate has been revoked", null, cp, certIndex); } else if (status instanceof org.bouncycastle.cert.ocsp.UnknownStatus) { Log.debug("OCSPChecker: Status of certificate (with serial number " + serialNumber.toString() + ") is: unknown"); throw new CertPathValidatorException("Certificate's revocation status is unknown", null, cp, certIndex); } else { Log.debug("Status of certificate (with serial number " + serialNumber.toString() + ") is: not recognized"); throw new CertPathValidatorException("Unknown OCSP response for certificate", null, cp, certIndex); } } } // Check that response applies to the cert that was supplied if (!foundResponse) { throw new CertPathValidatorException("No certificates in the OCSP response match the " + "certificate supplied in the OCSP request."); } } catch (CertPathValidatorException cpve) { throw cpve; } catch (Exception e) { throw new CertPathValidatorException(e); } finally { if (in != null) { try { in.close(); } catch (IOException ioe) { throw new CertPathValidatorException(ioe); } } if (out != null) { try { out.close(); } catch (IOException ioe) { throw new CertPathValidatorException(ioe); } } } }