List of usage examples for org.bouncycastle.cert.ocsp BasicOCSPResp getExtension
public Extension getExtension(ASN1ObjectIdentifier oid)
From source file:org.ejbca.core.protocol.ocsp.OCSPUnidClient.java
License:Open Source License
private String getFnr(BasicOCSPResp brep) throws IOException { Extension fnrrep = brep.getExtension(FnrFromUnidExtension.FnrFromUnidOid); if (fnrrep == null) { return null; }// w ww. j ava2s .c om ASN1InputStream aIn = new ASN1InputStream(new ByteArrayInputStream(fnrrep.getExtnValue().getEncoded())); ASN1OctetString octs = (ASN1OctetString) aIn.readObject(); aIn = new ASN1InputStream(new ByteArrayInputStream(octs.getOctets())); FnrFromUnidExtension fnrobj = FnrFromUnidExtension.getInstance(aIn.readObject()); return fnrobj.getFnr(); }
From source file:org.ejbca.core.protocol.ocsp.ProtocolLookupServerHttpTest.java
License:Open Source License
private String getFnr(BasicOCSPResp brep) throws IOException { byte[] fnrrep = brep.getExtension(FnrFromUnidExtension.FnrFromUnidOid).getExtnValue().getEncoded(); if (fnrrep == null) { return null; }/*from w ww.ja v a 2s .c o m*/ assertNotNull(fnrrep); ASN1InputStream aIn = new ASN1InputStream(new ByteArrayInputStream(fnrrep)); ASN1OctetString octs = (ASN1OctetString) aIn.readObject(); aIn = new ASN1InputStream(new ByteArrayInputStream(octs.getOctets())); FnrFromUnidExtension fnrobj = FnrFromUnidExtension.getInstance(aIn.readObject()); return fnrobj.getFnr(); }
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 ava 2 s .c o 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();//from ww w .ja v a 2 s . c o m 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.ProtocolOcspHttpTest.java
License:Open Source License
/** * This test tests the feature of extensions of setting a '*' in front of the value in ocsp.extensionoid * forces that extension to be used for all requests. * /* w w w.j a v a2s.c o m*/ * @throws Exception */ @Test public void testUseAlwaysExtensions() throws Exception { log.trace(">testUseAlwaysExtensions"); final String EXTENSION_OID = "ocsp.extensionoid"; final String EXTENSION_CLASS = "ocsp.extensionclass"; final String oldOidValue = cesecoreConfigurationProxySession.getConfigurationValue(EXTENSION_OID); final String oldClass = cesecoreConfigurationProxySession.getConfigurationValue(EXTENSION_CLASS); try { cesecoreConfigurationProxySession.setConfigurationValue(EXTENSION_OID, "*" + OcspCertHashExtension.CERT_HASH_OID); cesecoreConfigurationProxySession.setConfigurationValue(EXTENSION_CLASS, "org.ejbca.core.protocol.ocsp.extension.certhash.OcspCertHashExtension"); ocspResponseGeneratorSession.reloadOcspExtensionsCache(); // An OCSP request, ocspTestCert is already created in earlier tests OCSPReqBuilder gen = new OCSPReqBuilder(); loadUserCert(this.caid); this.helper.reloadKeys(); gen.addRequest(new JcaCertificateID(SHA1DigestCalculator.buildSha1Instance(), cacert, ocspTestCert.getSerialNumber())); OCSPReq req = gen.build(); BasicOCSPResp response = helper.sendOCSPGet(req.getEncoded(), null, OCSPRespBuilder.SUCCESSFUL, 200); if (response == null) { throw new Exception("Could not retrieve response, test could not continue."); } Extension responseExtension = response .getExtension(new ASN1ObjectIdentifier(OcspCertHashExtension.CERT_HASH_OID)); assertNotNull("No extension sent with reply", responseExtension); } finally { cesecoreConfigurationProxySession.setConfigurationValue(EXTENSION_OID, oldOidValue); cesecoreConfigurationProxySession.setConfigurationValue(EXTENSION_CLASS, oldClass); ocspResponseGeneratorSession.reloadOcspExtensionsCache(); log.trace("<testUseAlwaysExtensions"); } }
From source file:org.ejbca.core.protocol.ocsp.ProtocolOcspHttpTest.java
License:Open Source License
/** * This test tests that the OCSP response contains the extension "id-pkix-ocsp-extended-revoke" in case the * status of an unknown cert is returned as revoked. * //from ww w . j ava2 s . c o m * @throws Exception */ @Test public void testExtendedRevokedExtension() throws Exception { OCSPReqBuilder gen = new OCSPReqBuilder(); gen.addRequest(new JcaCertificateID(SHA1DigestCalculator.buildSha1Instance(), cacert, new BigInteger("1"))); OCSPReq req = gen.build(); BasicOCSPResp response = helper.sendOCSPGet(req.getEncoded(), null, OCSPRespBuilder.SUCCESSFUL, 200); assertNotNull("Could not retrieve response, test could not continue.", response); assertTrue(response.getResponses()[0].getCertStatus() instanceof UnknownStatus); // RFC 6960: id-pkix-ocsp-extended-revoke OBJECT IDENTIFIER ::= {id-pkix-ocsp 9} Extension responseExtension = response .getExtension(new ASN1ObjectIdentifier(OCSPObjectIdentifiers.id_pkix_ocsp + ".9")); assertNull("Wrong extension sent with reply", responseExtension); final Map<String, String> map = new HashMap<String, String>(); map.put(OcspConfiguration.NONE_EXISTING_IS_REVOKED, "true"); this.helper.alterConfig(map); gen = new OCSPReqBuilder(); gen.addRequest(new JcaCertificateID(SHA1DigestCalculator.buildSha1Instance(), cacert, new BigInteger("1"))); req = gen.build(); response = helper.sendOCSPGet(req.getEncoded(), null, OCSPRespBuilder.SUCCESSFUL, 200); assertNotNull("Could not retrieve response, test could not continue.", response); assertTrue(response.getResponses()[0].getCertStatus() instanceof RevokedStatus); responseExtension = response .getExtension(new ASN1ObjectIdentifier(OCSPObjectIdentifiers.id_pkix_ocsp + ".9")); assertNotNull("No extension sent with reply", responseExtension); assertEquals(DERNull.INSTANCE, responseExtension.getParsedValue()); }
From source file:org.ejbca.core.protocol.ocsp.ProtocolOcspHttpTest.java
License:Open Source License
/** * This test tests that the OCSP response for a status unknown contains the header "cache-control" with the value "no-cache, must-revalidate" * /*from www. j a va 2s . c om*/ * @throws Exception */ @Test public void testUnknownStatusCacheControlHeader() throws Exception { // set ocsp configuration Map<String, String> map = new HashMap<String, String>(); map.put(OcspConfiguration.UNTIL_NEXT_UPDATE, "1"); this.helper.alterConfig(map); OCSPReqBuilder gen = new OCSPReqBuilder(); gen.addRequest(new JcaCertificateID(SHA1DigestCalculator.buildSha1Instance(), cacert, new BigInteger("1"))); OCSPReq req = gen.build(); String sBaseURL = httpReqPath + '/' + resourceOcsp; String urlEnding = ""; String b64 = new String(Base64.encode(req.getEncoded(), false)); //String urls = URLEncoder.encode(b64, "UTF-8"); // JBoss/Tomcat will not accept escaped '/'-characters by default URL url = new URL(sBaseURL + '/' + b64 + urlEnding); HttpURLConnection con = (HttpURLConnection) url.openConnection(); if (con.getResponseCode() != 200) { log.info("URL when request gave unexpected result: " + url.toString() + " Message was: " + con.getResponseMessage()); } assertEquals("Response code did not match. ", 200, con.getResponseCode()); assertNotNull(con.getContentType()); assertTrue(con.getContentType().startsWith("application/ocsp-response")); assertNotNull("No Cache-Control in reply.", con.getHeaderField("Cache-Control")); assertEquals("no-cache, must-revalidate", con.getHeaderField("Cache-Control")); // Create a GET request using Nonce extension, in this case we should have no cache-control header gen = new OCSPReqBuilder(); gen.addRequest(new JcaCertificateID(SHA1DigestCalculator.buildSha1Instance(), cacert, new BigInteger("1"))); Extension[] extensions = new Extension[1]; extensions[0] = new Extension(OCSPObjectIdentifiers.id_pkix_ocsp_nonce, false, new DEROctetString("123456789".getBytes())); gen.setRequestExtensions(new Extensions(extensions)); req = gen.build(); b64 = new String(Base64.encode(req.getEncoded(), false)); url = new URL(sBaseURL + '/' + b64 + urlEnding); con = (HttpURLConnection) url.openConnection(); if (con.getResponseCode() != 200) { log.info("URL when request gave unexpected result: " + url.toString() + " Message was: " + con.getResponseMessage()); } assertEquals("Response code did not match. ", 200, con.getResponseCode()); assertNotNull(con.getContentType()); assertTrue(con.getContentType().startsWith("application/ocsp-response")); OCSPResp response = new OCSPResp(IOUtils.toByteArray(con.getInputStream())); BasicOCSPResp brep = (BasicOCSPResp) response.getResponseObject(); byte[] noncerep = brep.getExtension(OCSPObjectIdentifiers.id_pkix_ocsp_nonce).getExtnValue().getEncoded(); // Make sure we have a nonce in the response, we should have since we sent one in the request assertNotNull("Response should have nonce since we sent a nonce in the request", noncerep); ASN1InputStream ain = new ASN1InputStream(noncerep); ASN1OctetString oct = ASN1OctetString.getInstance(ain.readObject()); ain.close(); assertEquals("Response Nonce was not the same as the request Nonce, it must be", "123456789", new String(oct.getOctets())); assertNull( "Cache-Control in reply although we used Nonce in the request. Responses with Nonce should not have a Cache-control header.", con.getHeaderField("Cache-Control")); }
From source file:org.keycloak.common.util.OCSPUtils.java
License:Apache License
private static void verifyResponse(BasicOCSPResp basicOcspResponse, X509Certificate issuerCertificate, X509Certificate responderCertificate, byte[] requestNonce, Date date) throws NoSuchProviderException, NoSuchAlgorithmException, CertificateNotYetValidException, CertificateExpiredException, CertPathValidatorException { List<X509CertificateHolder> certs = new ArrayList<>(Arrays.asList(basicOcspResponse.getCerts())); X509Certificate signingCert = null; try {/* w w w .j a v a 2 s. c o m*/ certs.add(new JcaX509CertificateHolder(issuerCertificate)); if (responderCertificate != null) { certs.add(new JcaX509CertificateHolder(responderCertificate)); } } catch (CertificateEncodingException e) { e.printStackTrace(); } if (certs.size() > 0) { X500Name responderName = basicOcspResponse.getResponderId().toASN1Primitive().getName(); byte[] responderKey = basicOcspResponse.getResponderId().toASN1Primitive().getKeyHash(); if (responderName != null) { logger.log(Level.INFO, "Responder Name: {0}", responderName.toString()); for (X509CertificateHolder certHolder : certs) { try { X509Certificate tempCert = new JcaX509CertificateConverter().setProvider("BC") .getCertificate(certHolder); X500Name respName = new X500Name(tempCert.getSubjectX500Principal().getName()); if (responderName.equals(respName)) { signingCert = tempCert; logger.log(Level.INFO, "Found a certificate whose principal \"{0}\" matches the responder name \"{1}\"", new Object[] { tempCert.getSubjectDN().getName(), responderName.toString() }); break; } } catch (CertificateException e) { logger.log(Level.FINE, e.getMessage()); } } } else if (responderKey != null) { SubjectKeyIdentifier responderSubjectKey = new SubjectKeyIdentifier(responderKey); logger.log(Level.INFO, "Responder Key: {0}", Arrays.toString(responderKey)); for (X509CertificateHolder certHolder : certs) { try { X509Certificate tempCert = new JcaX509CertificateConverter().setProvider("BC") .getCertificate(certHolder); SubjectKeyIdentifier subjectKeyIdentifier = null; if (certHolder.getExtensions() != null) { subjectKeyIdentifier = SubjectKeyIdentifier.fromExtensions(certHolder.getExtensions()); } if (subjectKeyIdentifier != null) { logger.log(Level.INFO, "Certificate: {0}\nSubject Key Id: {1}", new Object[] { tempCert.getSubjectDN().getName(), Arrays.toString(subjectKeyIdentifier.getKeyIdentifier()) }); } if (subjectKeyIdentifier != null && responderSubjectKey.equals(subjectKeyIdentifier)) { signingCert = tempCert; logger.log(Level.INFO, "Found a signer certificate \"{0}\" with the subject key extension value matching the responder key", signingCert.getSubjectDN().getName()); break; } subjectKeyIdentifier = new JcaX509ExtensionUtils() .createSubjectKeyIdentifier(tempCert.getPublicKey()); if (responderSubjectKey.equals(subjectKeyIdentifier)) { signingCert = tempCert; logger.log(Level.INFO, "Found a certificate \"{0}\" with the subject key matching the OCSP responder key", signingCert.getSubjectDN().getName()); break; } } catch (CertificateException e) { logger.log(Level.FINE, e.getMessage()); } } } } if (signingCert != null) { if (signingCert.equals(issuerCertificate)) { logger.log(Level.INFO, "OCSP response is signed by the target''s Issuing CA"); } else if (responderCertificate != null && signingCert.equals(responderCertificate)) { // https://www.ietf.org/rfc/rfc2560.txt // 2.6 OCSP Signature Authority Delegation // - The responder certificate is issued to the responder by CA logger.log(Level.INFO, "OCSP response is signed by an authorized responder certificate"); } else { // 4.2.2.2 Authorized Responders // 3. Includes a value of id-ad-ocspSigning in an ExtendedKeyUsage // extension and is issued by the CA that issued the certificate in // question." if (!signingCert.getIssuerX500Principal().equals(issuerCertificate.getSubjectX500Principal())) { logger.log(Level.INFO, "Signer certificate''s Issuer: {0}\nIssuer certificate''s Subject: {1}", new Object[] { signingCert.getIssuerX500Principal().getName(), issuerCertificate.getSubjectX500Principal().getName() }); throw new CertPathValidatorException( "Responder\'s certificate is not authorized to sign OCSP responses"); } try { List<String> purposes = signingCert.getExtendedKeyUsage(); if (purposes != null && !purposes.contains(KeyPurposeId.id_kp_OCSPSigning.getId())) { logger.log(Level.INFO, "OCSPSigning extended usage is not set"); throw new CertPathValidatorException( "Responder\'s certificate not valid for signing OCSP responses"); } } catch (CertificateParsingException e) { logger.log(Level.FINE, "Failed to get certificate''s extended key usage extension\n{0}", e.getMessage()); } if (date == null) { signingCert.checkValidity(); } else { signingCert.checkValidity(date); } try { Extension noOCSPCheck = new JcaX509CertificateHolder(signingCert) .getExtension(OCSPObjectIdentifiers.id_pkix_ocsp_nocheck); // TODO If the extension is present, the OCSP client can trust the // responder's certificate for the lifetime of the certificate. logger.log(Level.INFO, "OCSP no-check extension is {0} present", noOCSPCheck == null ? "not" : ""); } catch (CertificateEncodingException e) { logger.log(Level.FINE, "Certificate encoding exception: {0}", e.getMessage()); } try { signingCert.verify(issuerCertificate.getPublicKey()); logger.log(Level.INFO, "OCSP response is signed by an Authorized Responder"); } catch (GeneralSecurityException ex) { signingCert = null; } } } if (signingCert == null) { throw new CertPathValidatorException("Unable to verify OCSP Response\'s signature"); } else { if (!verifySignature(basicOcspResponse, signingCert)) { throw new CertPathValidatorException("Error verifying OCSP Response\'s signature"); } else { Extension responseNonce = basicOcspResponse.getExtension(OCSPObjectIdentifiers.id_pkix_ocsp_nonce); if (responseNonce != null && requestNonce != null && !Arrays.equals(requestNonce, responseNonce.getExtnValue().getOctets())) { throw new CertPathValidatorException("Nonces do not match."); } else { // See Sun's OCSP implementation. // https://www.ietf.org/rfc/rfc2560.txt, if nextUpdate is not set, // the responder is indicating that newer update is avilable all the time long current = date == null ? System.currentTimeMillis() : date.getTime(); Date stop = new Date(current + (long) TIME_SKEW); Date start = new Date(current - (long) TIME_SKEW); Iterator<SingleResp> iter = Arrays.asList(basicOcspResponse.getResponses()).iterator(); SingleResp singleRes = null; do { if (!iter.hasNext()) { return; } singleRes = iter.next(); } while (!stop.before(singleRes.getThisUpdate()) && !start.after(singleRes.getNextUpdate() != null ? singleRes.getNextUpdate() : singleRes.getThisUpdate())); throw new CertPathValidatorException( "Response is unreliable: its validity interval is out-of-date"); } } } }
From source file:org.poreid.verify.ocsp.OCSPClient.java
License:Open Source License
public CertStatus getCertificateStatus() throws OCSPValidationException { try {// ww w. j a va 2s.c om if (null == url) { throw new OCSPValidationException("Certificado no tem validao por 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( "Cdigo HTTP recebido != 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 na resposta ocsp no coincide com nonce do pedido ocsp"); } X509CertificateHolder certHolder = basicResponse.getCerts()[0]; if (!basicResponse .isSignatureValid(new JcaContentVerifierProviderBuilder().setProvider("BC").build(issuer))) { if (!certHolder.isValidOn(Date.from(Instant.now()))) { throw new OCSPValidationException("Certificado no vlido na data atual"); } // Certificado tem de ter uma Key Purpose ID for authorized responders if (!ExtendedKeyUsage.fromExtensions(certHolder.getExtensions()) .hasKeyPurposeId(KeyPurposeId.id_kp_OCSPSigning)) { throw new OCSPValidationException( "Certificado no contm extenso necessria (id_kp_OCSPSigning)"); } // Certificado tem de ser emitido pela mesma CA do certificado que estamos a verificar if (!certHolder.isSignatureValid( new JcaContentVerifierProviderBuilder().setProvider("BC").build(issuer))) { throw new OCSPValidationException("Certificado no assinado pelo mesmo issuer"); } // Validar assinatura na resposta ocsp if (!basicResponse.isSignatureValid( new JcaContentVerifierProviderBuilder().setProvider("BC").build(certHolder))) { throw new OCSPValidationException("No foi possivel validar resposta ocsp"); } } else { if (!certHolder.isValidOn(Date.from(Instant.now()))) { throw new OCSPValidationException("Certificado no vlido na data atual"); } } // Politica de Certificados do SCEE if (null == certHolder.getExtension(OCSPObjectIdentifiers.id_pkix_ocsp_nocheck).getExtnId()) { throw new OCSPValidationException( "Extenso id_pkix_ocsp_nocheck no encontrada no certificado (Politica de Certificados do SCEE)"); } 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( "Nmero de srie do certificado na resposta ocsp no coincide com nmero de srie do certificado"); } } catch (CertificateEncodingException | OperatorCreationException | OCSPException | IOException ex) { throw new OCSPValidationException("No foi possivel efetuar a validao atravs de OCSP (" + certificate.getSubjectX500Principal().getName() + ")", ex); } catch (CertException | CertificateException ex) { throw new OCSPValidationException("No foi possivel efetuar a validao atravs de OCSP (" + certificate.getSubjectX500Principal().getName() + ")", ex); } }
From source file:org.xipki.ocsp.client.impl.AbstractOCSPRequestor.java
License:Open Source License
@Override public OCSPResp ask(final X509Certificate issuerCert, final BigInteger[] serialNumbers, final URL responderUrl, final RequestOptions requestOptions, final RequestResponseDebug debug) throws OCSPResponseException, OCSPRequestorException { if (requestOptions == null) { throw new IllegalArgumentException("requestOptions could not be null"); }/*www . j a v a2 s. co m*/ byte[] nonce = null; if (requestOptions.isUseNonce()) { nonce = nextNonce(requestOptions.getNonceLen()); } OCSPReq ocspReq = buildRequest(issuerCert, serialNumbers, nonce, requestOptions); byte[] encodedReq; try { encodedReq = ocspReq.getEncoded(); } catch (IOException e) { throw new OCSPRequestorException("could not encode OCSP request: " + e.getMessage(), e); } RequestResponsePair msgPair = null; if (debug != null) { msgPair = new RequestResponsePair(); debug.add(msgPair); msgPair.setRequest(encodedReq); } byte[] encodedResp; try { encodedResp = send(encodedReq, responderUrl, requestOptions); } catch (IOException e) { throw new ResponderUnreachableException("IOException: " + e.getMessage(), e); } if (debug != null) { msgPair.setRequest(encodedResp); } OCSPResp ocspResp; try { ocspResp = new OCSPResp(encodedResp); } catch (IOException e) { throw new InvalidOCSPResponseException("IOException: " + e.getMessage(), e); } Object respObject; try { respObject = ocspResp.getResponseObject(); } catch (OCSPException e) { throw new InvalidOCSPResponseException("responseObject is invalid"); } if (ocspResp.getStatus() != 0) { return ocspResp; } if (respObject instanceof BasicOCSPResp == false) { return ocspResp; } BasicOCSPResp basicOCSPResp = (BasicOCSPResp) respObject; if (nonce != null) { Extension nonceExtn = basicOCSPResp.getExtension(OCSPObjectIdentifiers.id_pkix_ocsp_nonce); if (nonceExtn == null) { throw new OCSPNonceUnmatchedException(nonce, null); } byte[] receivedNonce = nonceExtn.getExtnValue().getOctets(); if (Arrays.equals(nonce, receivedNonce) == false) { throw new OCSPNonceUnmatchedException(nonce, receivedNonce); } } SingleResp[] singleResponses = basicOCSPResp.getResponses(); final int countSingleResponses = singleResponses == null ? 0 : singleResponses.length; if (countSingleResponses != serialNumbers.length) { StringBuilder sb = new StringBuilder(100); sb.append("response with ").append(countSingleResponses).append(" singleRessponse"); if (countSingleResponses > 1) { sb.append("s"); } sb.append(" is returned, expected is ").append(serialNumbers.length); throw new OCSPTargetUnmatchedException(sb.toString()); } CertificateID certID = ocspReq.getRequestList()[0].getCertID(); ASN1ObjectIdentifier issuerHashAlg = certID.getHashAlgOID(); byte[] issuerKeyHash = certID.getIssuerKeyHash(); byte[] issuerNameHash = certID.getIssuerNameHash(); if (serialNumbers.length == 1) { SingleResp m = singleResponses[0]; CertificateID cid = m.getCertID(); boolean issuerMatch = issuerHashAlg.equals(cid.getHashAlgOID()) && Arrays.equals(issuerKeyHash, cid.getIssuerKeyHash()) && Arrays.equals(issuerNameHash, cid.getIssuerNameHash()); if (issuerMatch == false) { throw new OCSPTargetUnmatchedException("the issuer is not requested"); } BigInteger serialNumber = cid.getSerialNumber(); if (serialNumbers[0].equals(serialNumber) == false) { throw new OCSPTargetUnmatchedException("the serialNumber is not requested"); } } else { List<BigInteger> tmpSerials1 = Arrays.asList(serialNumbers); List<BigInteger> tmpSerials2 = new ArrayList<>(tmpSerials1); for (int i = 0; i < singleResponses.length; i++) { SingleResp m = singleResponses[i]; CertificateID cid = m.getCertID(); boolean issuerMatch = issuerHashAlg.equals(cid.getHashAlgOID()) && Arrays.equals(issuerKeyHash, cid.getIssuerKeyHash()) && Arrays.equals(issuerNameHash, cid.getIssuerNameHash()); if (issuerMatch == false) { throw new OCSPTargetUnmatchedException( "the issuer specified in singleResponse[" + i + "] is not requested"); } BigInteger serialNumber = cid.getSerialNumber(); if (tmpSerials2.remove(serialNumber) == false) { if (tmpSerials1.contains(serialNumber)) { throw new OCSPTargetUnmatchedException( "serialNumber " + serialNumber + "is contained in at least two singleResponses"); } else { throw new OCSPTargetUnmatchedException( "the serialNumber specified in singleResponse[" + i + "] is not requested"); } } } } return ocspResp; }