List of usage examples for org.bouncycastle.cert.ocsp BasicOCSPResp getCerts
public X509CertificateHolder[] getCerts()
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 {//from w ww . ja v a 2 s. c om 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 {/*from ww w.ja v a 2 s . c o m*/ 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.signserver.module.xades.validator.AbstractCustomCertPathChecker.java
License:Open Source License
/** * //w ww. j a va 2 s. c o m * Method that retrieves the Authorized OCSP Responders certificate from basic ocsp response structure * the Authorized OCSP responders certificate is identified by OCSPSigner extension * Only certificate having this extension and that can verify response's signature is returned * * NOTE : RFC 2560 does not state it should be an end entity certificate ! * * @param basic ocsp response * @return Authorized OCSP Responders certificate if found, null if not found * @throws OCSPException * @throws NoSuchProviderException * @throws NoSuchAlgorithmException * @throws CertStoreException */ private X509Certificate getAuthorizedOCSPRespondersCertificateFromOCSPResponse(BasicOCSPResp basicOCSPResponse) throws NoSuchAlgorithmException, NoSuchProviderException, OCSPException, CertStoreException, CertificateEncodingException, OperatorCreationException { X509Certificate result = null; X509CertificateHolder[] certs = basicOCSPResponse.getCerts(); Store ocspRespCertStore = new JcaCertStore(Arrays.asList(certs)); //search for certificate having OCSPSigner extension X509ExtendedKeyUsageExistsCertSelector certSel = new X509ExtendedKeyUsageExistsCertSelector( KeyPurposeId.id_kp_OCSPSigning.getId()); for (X509CertificateHolder cert : (Collection<X509CertificateHolder>) ocspRespCertStore .getMatches(certSel)) { try { //it might be the case that certchain contains more than one certificate with OCSPSigner extension //check if certificate verifies the signature on the response if (cert != null && basicOCSPResponse .isSignatureValid(new JcaContentVerifierProviderBuilder().setProvider("BC").build(cert))) { result = new JcaX509CertificateConverter().getCertificate(cert); break; } } catch (CertificateException ignored) { } } return result; }
From source file:org.signserver.validationservice.server.OCSPPathChecker.java
License:Open Source License
/** * Parses received response bytes to form basic ocsp response object and verifies ocsp response * If returns , ocsp response is successfully verified, otherwise throws exception detailing problem * /*from www . j a v a 2 s . co m*/ * @param x509Cert - certificate originally passed to validator for validation * @param derocspresponse - der formatted ocsp response received from ocsp responder * @throws OCSPException * @throws NoSuchProviderException * @throws IOException * @throws CertStoreException * @throws NoSuchAlgorithmException * @throws NoSuchAlgorithmException * @throws SignServerException * @throws CertificateParsingException * @throws CryptoTokenOfflineException * @throws IllegalRequestException */ protected void parseAndVerifyOCSPResponse(X509Certificate x509Cert, byte[] derocspresponse) throws NoSuchProviderException, OCSPException, NoSuchAlgorithmException, CertStoreException, IOException, SignServerException, CertificateParsingException, IllegalRequestException, CryptoTokenOfflineException, OperatorCreationException, CertificateEncodingException { //parse received ocsp response OCSPResp ocspresp = new OCSPResp(derocspresponse); if (ocspresp.getStatus() != OCSPRespStatus.SUCCESSFUL) { throw new SignServerException( "Unexpected ocsp response status. Response Status Received : " + ocspresp.getStatus()); } // we currently support only basic ocsp response BasicOCSPResp basicOCSPResponse = (BasicOCSPResp) ocspresp.getResponseObject(); if (basicOCSPResponse == null) { throw new SignServerException( "Could not construct BasicOCSPResp object from response. Only BasicOCSPResponse as defined in RFC 2560 is supported."); } //OCSP response might be signed by CA issuing the certificate or //the Authorized OCSP responder certificate containing the id-kp-OCSPSigning extended key usage extension X509Certificate ocspRespSignerCertificate = null; //first check if CA issuing certificate signed the response //since it is expected to be the most common case if (basicOCSPResponse.isSignatureValid( new JcaContentVerifierProviderBuilder().setProvider("BC").build(cACert.getPublicKey()))) { ocspRespSignerCertificate = cACert; } //if CA did not sign the ocsp response, look for authorized ocsp responses from properties or from certificate chain received with response if (ocspRespSignerCertificate == null) { log.debug("OCSP Response is not signed by issuing CA. Looking for authorized responders"); if (basicOCSPResponse.getCerts() == null) { log.debug( "OCSP Response does not contain certificate chain, trying to verify response using one of configured authorized ocsp responders"); //certificate chain is not present in response received //try to verify using one of the configured AuthorizedOCSPResponderCerts ocspRespSignerCertificate = getAuthorizedOCSPRespondersCertificateFromProperties(basicOCSPResponse); if (ocspRespSignerCertificate == null) { throw new SignServerException( "OCSP Response does not contain certificate chain, and response is not signed by any of the configured Authorized OCSP Responders or CA issuing certificate."); } } else { //look for existence of Authorized OCSP responder inside the cert chain in ocsp response ocspRespSignerCertificate = getAuthorizedOCSPRespondersCertificateFromOCSPResponse( basicOCSPResponse); //could not find the certificate signing the OCSP response in the ocsp response if (ocspRespSignerCertificate == null) { throw new SignServerException( "Certificate signing the ocsp response is not found in ocsp response's certificate chain received and is not signed by CA issuing certificate"); } } } log.debug("OCSP response signed by : " + CertTools.getSubjectDN(ocspRespSignerCertificate)); // validating ocsp signers certificate // Check if responders certificate has id-pkix-ocsp-nocheck extension, in which case we do not validate (perform revocation check on ) ocsp certs for lifetime of certificate // using CRL RFC 2560 sect 4.2.2.2.1 // TODO : RFC States the extension value should be NULL, so maybe bare existence of the extension is not sufficient ?? if (ocspRespSignerCertificate .getExtensionValue(OCSPObjectIdentifiers.id_pkix_ocsp_nocheck.getId()) != null) { //check if lifetime of certificate is ok try { ocspRespSignerCertificate.checkValidity(); } catch (CertificateExpiredException e) { throw new SignServerException( "Certificate signing the ocsp response has expired. OCSP Responder Certificate Subject DN : " + CertTools.getSubjectDN(ocspRespSignerCertificate)); } catch (CertificateNotYetValidException e) { throw new SignServerException( "Certificate signing the ocsp response is not yet valid. OCSP Responder Certificate Subject DN : " + CertTools.getSubjectDN(ocspRespSignerCertificate)); } } else { // check if CDP exists in ocsp signers certificate // TODO : ?? add property for issuer whether to accept the OCSP response if the CDPs are not available (or use preconfigured CRLs) on signing certificate CRL RFC 2560 sect 4.2.2.2.1 if (CertTools.getCrlDistributionPoint(ocspRespSignerCertificate) == null) { throw new SignServerException( "CRL Distribution Point extension missing in ocsp signer's certificate."); } //verify certificate using CRL Validator //TODO : refactor Validators to follow factory pattern (discuss) CRLValidator crlValidator = new CRLValidator(); Validation valresult = crlValidator.validate(ocspRespSignerCertificate, this.props); if (valresult.getStatus() != Validation.Status.VALID) { throw new SignServerException( "Validation of ocsp signer's certificate failed. Status message received : " + valresult.getStatusMessage()); } } //get the response we requested for for (SingleResp singleResponse : basicOCSPResponse.getResponses()) { if (singleResponse.getCertID().getSerialNumber().equals(x509Cert.getSerialNumber())) { //found our response //check if response is OK, and if not throw OCSPStatusNotGoodException if (singleResponse.getCertStatus() != null) { throw new OCSPStatusNotGoodException( "Responce for queried certificate is not good. Certificate status returned : " + singleResponse.getCertStatus(), singleResponse.getCertStatus()); } //check the dates ThisUpdate and NextUpdate RFC 2560 sect : 4.2.2.1 if (singleResponse.getNextUpdate() != null && (new Date()).compareTo(singleResponse.getNextUpdate()) >= 0) { throw new SignServerException( "Unreliable response received. Response reported a nextupdate as : " + singleResponse.getNextUpdate().toString() + " which is earlier than current date."); } if (singleResponse.getThisUpdate() != null && (new Date()).compareTo(singleResponse.getThisUpdate()) <= 0) { throw new SignServerException( "Unreliable response received. Response reported a thisupdate as : " + singleResponse.getThisUpdate().toString() + " which is earlier than current date."); } break; } } }
From source file:org.signserver.validationservice.server.OCSPPathChecker.java
License:Open Source License
/** * /*from ww w .j a va2 s .co m*/ * Method that retrieves the Authorized OCSP Responders certificate from basic ocsp response structure * the Authorized OCSP responders certificate is identified by OCSPSigner extension * Only certificate having this extension and that can verify response's signature is returned * * NOTE : RFC 2560 does not state it should be an end entity certificate ! * * @param basic ocsp response * @return Authorized OCSP Responders certificate if found, null if not found * @throws OCSPException * @throws NoSuchProviderException * @throws NoSuchAlgorithmException * @throws CertStoreException */ protected X509Certificate getAuthorizedOCSPRespondersCertificateFromOCSPResponse( BasicOCSPResp basicOCSPResponse) throws NoSuchAlgorithmException, NoSuchProviderException, OCSPException, CertStoreException, CertificateEncodingException, OperatorCreationException { X509Certificate retCert = null; X509Certificate tempCert; X509CertificateHolder[] certs = basicOCSPResponse.getCerts(); Store ocspRespCertStore = new JcaCertStore(Arrays.asList(certs)); //search for certificate having OCSPSigner extension X509ExtendedKeyUsageExistsCertSelector certSel = new X509ExtendedKeyUsageExistsCertSelector( "1.3.6.1.5.5.7.3.9"); Iterator<?> certsIter = ocspRespCertStore.getMatches(certSel).iterator(); while (certsIter.hasNext()) { try { // direct cast to org.signserver.validationservice.common.X509Certificate fails tempCert = (java.security.cert.X509Certificate) certsIter.next(); } catch (Exception e) { //eat up exception continue; } //it might be the case that certchain contains more than one certificate with OCSPSigner extension //check if certificate verifies the signature on the response if (tempCert != null && basicOCSPResponse.isSignatureValid( new JcaContentVerifierProviderBuilder().setProvider("BC").build(tempCert.getPublicKey()))) { retCert = tempCert; break; } } return retCert; }
From source file:org.signserver.validationservice.server.ValidationUtils.java
License:Open Source License
/** * Sends a request to the OCSP responder and returns the results. * * Note: Based on code from the EJBCA ValidationTool. * * @param url of the OCSP responder/* w w w . j a va 2s .com*/ * @param request to send * @return An OCSPResponse object filled with information about the response * @throws IOException in case of networking related errors * @throws OCSPException in case of error parsing the response */ public static OCSPResponse queryOCSPResponder(URL url, OCSPReq request) throws IOException, OCSPException { final OCSPResponse result = new OCSPResponse(); final HttpURLConnection con; final URLConnection urlCon = url.openConnection(); if (!(urlCon instanceof HttpURLConnection)) { throw new IOException("Unsupported protocol in URL: " + url); } con = (HttpURLConnection) urlCon; // POST the OCSP request con.setDoOutput(true); con.setRequestMethod("POST"); // POST it con.setRequestProperty("Content-Type", "application/ocsp-request"); OutputStream os = null; try { os = con.getOutputStream(); os.write(request.getEncoded()); } finally { if (os != null) { os.close(); } } result.setHttpReturnCode(con.getResponseCode()); if (result.getHttpReturnCode() != 200) { if (result.getHttpReturnCode() == 401) { result.setError(OCSPResponse.Error.httpUnauthorized); } else { result.setError(OCSPResponse.Error.unknown); } return result; } OCSPResp response = null; InputStream in = null; try { in = con.getInputStream(); if (in != null) { ByteArrayOutputStream bout = new ByteArrayOutputStream(); int b; while ((b = in.read()) != -1) { bout.write(b); } response = new OCSPResp(bout.toByteArray()); } } finally { if (in != null) { try { in.close(); } catch (IOException ignored) { } // NOPMD } } if (response == null) { result.setError(OCSPResponse.Error.noResponse); return result; } result.setResp(response); if (response.getStatus() != OCSPResponseStatus.SUCCESSFUL) { result.setError(OCSPResponse.Error.fromBCOCSPResponseStatus(response.getStatus())); return result; } final BasicOCSPResp brep = (BasicOCSPResp) response.getResponseObject(); result.setResponseObject(brep); if (brep == null) { result.setError(OCSPResponse.Error.noResponse); return result; } final RespID id = brep.getResponderId(); final DERTaggedObject to = (DERTaggedObject) id.toASN1Object().toASN1Object(); final RespID respId; final X509CertificateHolder[] chain = brep.getCerts(); JcaX509CertificateConverter converter = new JcaX509CertificateConverter(); X509Certificate signerCertificate; try { signerCertificate = converter.getCertificate(chain[0]); } catch (CertificateException ex) { throw new IOException("Could not convert certificate: " + ex.getMessage()); } result.setSignerCertificate(signerCertificate); if (to.getTagNo() == 1) { // This is Name respId = new JcaRespID(signerCertificate.getSubjectX500Principal()); } else { // This is KeyHash final PublicKey signerPub = signerCertificate.getPublicKey(); try { respId = new JcaRespID(signerPub, new JcaDigestCalculatorProviderBuilder().build().get(RespID.HASH_SHA1)); } catch (OperatorCreationException ex) { throw new IOException("Could not create respId: " + ex.getMessage()); } } if (!id.equals(respId)) { // Response responderId does not match signer certificate responderId! result.setError(OCSPResponse.Error.invalidSignerId); } result.setIssuerDN(signerCertificate.getIssuerX500Principal()); if (result.getError() == null) { result.setError(OCSPResponse.Error.responseSuccess); } return result; }
From source file:org.xipki.ocsp.client.shell.OCSPStatusCommand.java
License:Open Source License
@Override protected Object processResponse(final OCSPResp response, final X509Certificate respIssuer, final X509Certificate issuer, final List<BigInteger> serialNumbers, final Map<BigInteger, byte[]> encodedCerts) throws Exception { BasicOCSPResp basicResp = OCSPUtils.extractBasicOCSPResp(response); boolean extendedRevoke = basicResp.getExtension(OCSPRequestor.id_pkix_ocsp_extendedRevoke) != null; SingleResp[] singleResponses = basicResp.getResponses(); int n = singleResponses == null ? 0 : singleResponses.length; if (n == 0) { throw new CmdFailure("received no status from server"); }//from w w w . j a va2 s. c o m if (n != serialNumbers.size()) { throw new CmdFailure("received status with " + n + " single responses from server, but " + serialNumbers.size() + " were requested"); } Date[] thisUpdates = new Date[n]; for (int i = 0; i < n; i++) { thisUpdates[i] = singleResponses[i].getThisUpdate(); } // check the signature if available if (null == basicResp.getSignature()) { out("response is not signed"); } else { X509CertificateHolder[] responderCerts = basicResp.getCerts(); if (responderCerts == null || responderCerts.length < 1) { throw new CmdFailure("no responder certificate is contained in the response"); } X509CertificateHolder respSigner = responderCerts[0]; boolean validOn = true; for (Date thisUpdate : thisUpdates) { validOn = respSigner.isValidOn(thisUpdate); if (validOn == false) { throw new CmdFailure("responder certificate is not valid on " + thisUpdate); } } if (validOn) { PublicKey responderPubKey = KeyUtil.generatePublicKey(respSigner.getSubjectPublicKeyInfo()); ContentVerifierProvider cvp = KeyUtil.getContentVerifierProvider(responderPubKey); boolean sigValid = basicResp.isSignatureValid(cvp); if (sigValid == false) { throw new CmdFailure("response is equipped with invalid signature"); } // verify the OCSPResponse signer if (respIssuer != null) { boolean certValid = true; X509Certificate jceRespSigner = new X509CertificateObject(respSigner.toASN1Structure()); if (X509Util.issues(respIssuer, jceRespSigner)) { try { jceRespSigner.verify(respIssuer.getPublicKey()); } catch (SignatureException e) { certValid = false; } } if (certValid == false) { throw new CmdFailure( "response is equipped with valid signature but the OCSP signer is not trusted"); } } else { out("response is equipped with valid signature"); } } if (verbose.booleanValue()) { out("responder is " + X509Util.getRFC4519Name(responderCerts[0].getSubject())); } } for (int i = 0; i < n; i++) { if (n > 1) { out("---------------------------- " + i + " ----------------------------"); } SingleResp singleResp = singleResponses[i]; BigInteger serialNumber = singleResp.getCertID().getSerialNumber(); CertificateStatus singleCertStatus = singleResp.getCertStatus(); String status; if (singleCertStatus == null) { status = "good"; } else if (singleCertStatus instanceof RevokedStatus) { RevokedStatus revStatus = (RevokedStatus) singleCertStatus; Date revTime = revStatus.getRevocationTime(); Date invTime = null; Extension ext = singleResp.getExtension(Extension.invalidityDate); if (ext != null) { invTime = ASN1GeneralizedTime.getInstance(ext.getParsedValue()).getDate(); } if (revStatus.hasRevocationReason()) { int reason = revStatus.getRevocationReason(); if (extendedRevoke && reason == CRLReason.CERTIFICATE_HOLD.getCode() && revTime.getTime() == 0) { status = "unknown (RFC6960)"; } else { StringBuilder sb = new StringBuilder("revoked, reason = "); sb.append(CRLReason.forReasonCode(reason).getDescription()); sb.append(", revocationTime = "); sb.append(revTime); if (invTime != null) { sb.append(", invalidityTime = "); sb.append(invTime); } status = sb.toString(); } } else { status = "revoked, no reason, revocationTime = " + revTime; } } else if (singleCertStatus instanceof UnknownStatus) { status = "unknown (RFC2560)"; } else { status = "ERROR"; } StringBuilder msg = new StringBuilder(); msg.append("serialNumber: ").append(serialNumber); msg.append("\nCertificate status: ").append(status); if (verbose.booleanValue()) { msg.append("\nthisUpdate: " + singleResp.getThisUpdate()); msg.append("\nnextUpdate: " + singleResp.getNextUpdate()); Extension extension = singleResp.getExtension(ISISMTTObjectIdentifiers.id_isismtt_at_certHash); if (extension != null) { msg.append("\nCertHash is provided:\n"); ASN1Encodable extensionValue = extension.getParsedValue(); CertHash certHash = CertHash.getInstance(extensionValue); ASN1ObjectIdentifier hashAlgOid = certHash.getHashAlgorithm().getAlgorithm(); byte[] hashValue = certHash.getCertificateHash(); msg.append("\tHash algo : ").append(hashAlgOid.getId()).append("\n"); msg.append("\tHash value: ").append(Hex.toHexString(hashValue)).append("\n"); if (encodedCerts != null) { byte[] encodedCert = encodedCerts.get(serialNumber); MessageDigest md = MessageDigest.getInstance(hashAlgOid.getId()); byte[] expectedHashValue = md.digest(encodedCert); if (Arrays.equals(expectedHashValue, hashValue)) { msg.append("\tThis matches the requested certificate"); } else { msg.append("\tThis differs from the requested certificate"); } } } extension = singleResp.getExtension(OCSPObjectIdentifiers.id_pkix_ocsp_archive_cutoff); if (extension != null) { ASN1Encodable extensionValue = extension.getParsedValue(); ASN1GeneralizedTime time = ASN1GeneralizedTime.getInstance(extensionValue); msg.append("\nArchive-CutOff: "); msg.append(time.getTimeString()); } AlgorithmIdentifier sigAlg = basicResp.getSignatureAlgorithmID(); if (sigAlg == null) { msg.append(("\nresponse is not signed")); } else { String sigAlgName = AlgorithmUtil.getSignatureAlgoName(sigAlg); if (sigAlgName == null) { sigAlgName = "unknown"; } msg.append("\nresponse is signed with ").append(sigAlgName); } // extensions msg.append("\nExtensions: "); List<?> extensionOIDs = basicResp.getExtensionOIDs(); if (extensionOIDs == null || extensionOIDs.size() == 0) { msg.append("-"); } else { int size = extensionOIDs.size(); for (int j = 0; j < size; j++) { ASN1ObjectIdentifier extensionOID = (ASN1ObjectIdentifier) extensionOIDs.get(j); String name = extensionOidNameMap.get(extensionOID); msg.append(name == null ? extensionOID.getId() : name); if (j != size - 1) { msg.append(", "); } } } } out(msg.toString()); } out(""); return null; }
From source file:org.xipki.ocsp.qa.impl.OcspQAImpl.java
License:Open Source License
@Override public ValidationResult checkOCSP(final OCSPResp response, final X509Certificate issuer, final List<BigInteger> serialNumbers, final Map<BigInteger, byte[]> encodedCerts, final OcspError expectedOcspError, final Map<BigInteger, OcspCertStatus> expectedOcspStatuses, final OcspResponseOption responseOption) { List<ValidationIssue> resultIssues = new LinkedList<ValidationIssue>(); int status = response.getStatus(); // Response status {/* w w w.j a v a2s . co m*/ ValidationIssue issue = new ValidationIssue("OCSP.STATUS", "response.status"); resultIssues.add(issue); if (expectedOcspError != null) { if (status != expectedOcspError.getStatus()) { issue.setFailureMessage( "is '" + status + "', but expected '" + expectedOcspError.getStatus() + "'"); } } else { if (status != 0) { issue.setFailureMessage("is '" + status + "', but expected '0'"); } } } if (status != 0) { return new ValidationResult(resultIssues); } ValidationIssue encodingIssue = new ValidationIssue("OCSP.ENCODING", "response encoding"); resultIssues.add(encodingIssue); BasicOCSPResp basicResp; { try { basicResp = (BasicOCSPResp) response.getResponseObject(); } catch (OCSPException e) { encodingIssue.setFailureMessage(e.getMessage()); return new ValidationResult(resultIssues); } } SingleResp[] singleResponses = basicResp.getResponses(); { ValidationIssue issue = new ValidationIssue("OCSP.RESPONSES.NUM", "number of single responses"); resultIssues.add(issue); int n = singleResponses == null ? 0 : singleResponses.length; if (n == 0) { issue.setFailureMessage("received no status from server"); } else if (n != serialNumbers.size()) { issue.setFailureMessage("is '" + n + "', but expected '" + serialNumbers.size() + "'"); } if (issue.isFailed()) { return new ValidationResult(resultIssues); } } { boolean hasSignature = basicResp.getSignature() != null; { // check the signature if available ValidationIssue issue = new ValidationIssue("OCSP.SIG", "signature presence"); resultIssues.add(issue); if (hasSignature == false) { issue.setFailureMessage("response is not signed"); } } if (hasSignature) { { // signature algorithm ValidationIssue issue = new ValidationIssue("OCSP.SIG.ALG", "signature algorithm"); resultIssues.add(issue); String expectedSigalgo = responseOption.getSignatureAlgName(); if (expectedSigalgo != null) { AlgorithmIdentifier sigAlg = basicResp.getSignatureAlgorithmID(); try { String sigAlgName = AlgorithmUtil.getSignatureAlgoName(sigAlg); if (AlgorithmUtil.equalsAlgoName(sigAlgName, expectedSigalgo) == false) { issue.setFailureMessage( "is '" + sigAlgName + "', but expected '" + expectedSigalgo + "'"); } } catch (NoSuchAlgorithmException e) { issue.setFailureMessage("could not extract the signature algorithm"); } } } // signer certificate ValidationIssue sigSignerCertIssue = new ValidationIssue("OCSP.SIGNERCERT", "signer certificate"); resultIssues.add(sigSignerCertIssue); // signature validation ValidationIssue sigValIssue = new ValidationIssue("OCSP.SIG.VALIDATION", "signature validation"); resultIssues.add(sigValIssue); X509CertificateHolder[] responderCerts = basicResp.getCerts(); if (responderCerts == null || responderCerts.length < 1) { sigSignerCertIssue.setFailureMessage("No responder certificate is contained in the response"); sigValIssue.setFailureMessage("could not find certificate to validate signature"); } else { X509CertificateHolder respSigner = responderCerts[0]; ValidationIssue issue = new ValidationIssue("OCSP.SIGNERCERT.TRUST", "signer certificate validation"); resultIssues.add(issue); for (int i = 0; i < singleResponses.length; i++) { SingleResp singleResp = singleResponses[i]; if (respSigner.isValidOn(singleResp.getThisUpdate()) == false) { issue.setFailureMessage("responder certificate is not valid on the thisUpdate[ " + i + "]" + singleResp.getThisUpdate()); } } if (issue.isFailed() == false) { X509Certificate respIssuer = responseOption.getRespIssuer(); if (respIssuer != null) { X509Certificate jceRespSigner; try { jceRespSigner = new X509CertificateObject(respSigner.toASN1Structure()); if (X509Util.issues(respIssuer, jceRespSigner)) { jceRespSigner.verify(respIssuer.getPublicKey()); } else { issue.setFailureMessage("responder signer is not trusted"); } } catch (Exception e) { issue.setFailureMessage("responder signer is not trusted"); } } } try { PublicKey responderPubKey = KeyUtil.generatePublicKey(respSigner.getSubjectPublicKeyInfo()); ContentVerifierProvider cvp = KeyUtil.getContentVerifierProvider(responderPubKey); boolean sigValid = basicResp.isSignatureValid(cvp); if (sigValid == false) { sigValIssue.setFailureMessage("signature is invalid"); } } catch (Exception e) { sigValIssue.setFailureMessage("error while validating signature"); } } } } { // nonce Extension nonceExtn = basicResp.getExtension(OCSPObjectIdentifiers.id_pkix_ocsp_nonce); resultIssues.add(checkOccurrence("OCSP.NONCE", nonceExtn, responseOption.getNonceOccurrence())); } boolean extendedRevoke = basicResp.getExtension(id_pkix_ocsp_extendedRevoke) != null; for (int i = 0; i < singleResponses.length; i++) { SingleResp singleResp = singleResponses[i]; BigInteger serialNumber = singleResp.getCertID().getSerialNumber(); OcspCertStatus expectedStatus = expectedOcspStatuses.get(serialNumber); byte[] encodedCert = null; if (encodedCerts != null) { encodedCert = encodedCerts.get(serialNumber); } List<ValidationIssue> issues = checkSingleCert(i, singleResp, expectedStatus, encodedCert, extendedRevoke, responseOption.getNextUpdateOccurrence(), responseOption.getCerthashOccurrence(), responseOption.getCerthashAlgId()); resultIssues.addAll(issues); } return new ValidationResult(resultIssues); }
From source file:org.xipki.pki.ocsp.client.shell.OcspStatusCmd.java
License:Open Source License
@Override protected Object processResponse(final OCSPResp response, final X509Certificate respIssuer, final IssuerHash issuerHash, final List<BigInteger> serialNumbers, final Map<BigInteger, byte[]> encodedCerts) throws Exception { ParamUtil.requireNonNull("response", response); ParamUtil.requireNonNull("issuerHash", issuerHash); ParamUtil.requireNonNull("serialNumbers", serialNumbers); BasicOCSPResp basicResp = OcspUtils.extractBasicOcspResp(response); boolean extendedRevoke = basicResp.getExtension(ObjectIdentifiers.id_pkix_ocsp_extendedRevoke) != null; SingleResp[] singleResponses = basicResp.getResponses(); if (singleResponses == null || singleResponses.length == 0) { throw new CmdFailure("received no status from server"); }/* ww w .ja v a 2 s. c o m*/ final int n = singleResponses.length; if (n != serialNumbers.size()) { throw new CmdFailure("received status with " + n + " single responses from server, but " + serialNumbers.size() + " were requested"); } Date[] thisUpdates = new Date[n]; for (int i = 0; i < n; i++) { thisUpdates[i] = singleResponses[i].getThisUpdate(); } // check the signature if available if (null == basicResp.getSignature()) { println("response is not signed"); } else { X509CertificateHolder[] responderCerts = basicResp.getCerts(); if (responderCerts == null || responderCerts.length < 1) { throw new CmdFailure("no responder certificate is contained in the response"); } ResponderID respId = basicResp.getResponderId().toASN1Primitive(); X500Name respIdByName = respId.getName(); byte[] respIdByKey = respId.getKeyHash(); X509CertificateHolder respSigner = null; for (X509CertificateHolder cert : responderCerts) { if (respIdByName != null) { if (cert.getSubject().equals(respIdByName)) { respSigner = cert; } } else { byte[] spkiSha1 = HashAlgoType.SHA1 .hash(cert.getSubjectPublicKeyInfo().getPublicKeyData().getBytes()); if (Arrays.equals(respIdByKey, spkiSha1)) { respSigner = cert; } } if (respSigner != null) { break; } } if (respSigner == null) { throw new CmdFailure("no responder certificate match the ResponderId"); } boolean validOn = true; for (Date thisUpdate : thisUpdates) { validOn = respSigner.isValidOn(thisUpdate); if (!validOn) { throw new CmdFailure("responder certificate is not valid on " + thisUpdate); } } if (validOn) { PublicKey responderPubKey = KeyUtil.generatePublicKey(respSigner.getSubjectPublicKeyInfo()); ContentVerifierProvider cvp = securityFactory.getContentVerifierProvider(responderPubKey); boolean sigValid = basicResp.isSignatureValid(cvp); if (!sigValid) { throw new CmdFailure("response is equipped with invalid signature"); } // verify the OCSPResponse signer if (respIssuer != null) { boolean certValid = true; X509Certificate jceRespSigner = X509Util.toX509Cert(respSigner.toASN1Structure()); if (X509Util.issues(respIssuer, jceRespSigner)) { try { jceRespSigner.verify(respIssuer.getPublicKey()); } catch (SignatureException ex) { certValid = false; } } if (!certValid) { throw new CmdFailure("response is equipped with valid signature but the" + " OCSP signer is not trusted"); } } else { println("response is equipped with valid signature"); } // end if(respIssuer) } // end if(validOn) if (verbose.booleanValue()) { println("responder is " + X509Util.getRfc4519Name(responderCerts[0].getSubject())); } } // end if for (int i = 0; i < n; i++) { if (n > 1) { println("---------------------------- " + i + "----------------------------"); } SingleResp singleResp = singleResponses[i]; CertificateStatus singleCertStatus = singleResp.getCertStatus(); String status; if (singleCertStatus == null) { status = "good"; } else if (singleCertStatus instanceof RevokedStatus) { RevokedStatus revStatus = (RevokedStatus) singleCertStatus; Date revTime = revStatus.getRevocationTime(); Date invTime = null; Extension ext = singleResp.getExtension(Extension.invalidityDate); if (ext != null) { invTime = ASN1GeneralizedTime.getInstance(ext.getParsedValue()).getDate(); } if (revStatus.hasRevocationReason()) { int reason = revStatus.getRevocationReason(); if (extendedRevoke && reason == CrlReason.CERTIFICATE_HOLD.getCode() && revTime.getTime() == 0) { status = "unknown (RFC6960)"; } else { StringBuilder sb = new StringBuilder("revoked, reason = "); sb.append(CrlReason.forReasonCode(reason).getDescription()); sb.append(", revocationTime = ").append(revTime); if (invTime != null) { sb.append(", invalidityTime = ").append(invTime); } status = sb.toString(); } } else { status = "revoked, no reason, revocationTime = " + revTime; } } else if (singleCertStatus instanceof UnknownStatus) { status = "unknown (RFC2560)"; } else { status = "ERROR"; } StringBuilder msg = new StringBuilder(); CertificateID certId = singleResp.getCertID(); HashAlgoType hashAlgo = HashAlgoType.getNonNullHashAlgoType(certId.getHashAlgOID()); boolean issuerMatch = issuerHash.match(hashAlgo, certId.getIssuerNameHash(), certId.getIssuerKeyHash()); BigInteger serialNumber = certId.getSerialNumber(); msg.append("issuer matched: ").append(issuerMatch); msg.append("\nserialNumber: ").append(LogUtil.formatCsn(serialNumber)); msg.append("\nCertificate status: ").append(status); if (verbose.booleanValue()) { msg.append("\nthisUpdate: ").append(singleResp.getThisUpdate()); msg.append("\nnextUpdate: ").append(singleResp.getNextUpdate()); Extension extension = singleResp.getExtension(ISISMTTObjectIdentifiers.id_isismtt_at_certHash); if (extension != null) { msg.append("\nCertHash is provided:\n"); ASN1Encodable extensionValue = extension.getParsedValue(); CertHash certHash = CertHash.getInstance(extensionValue); ASN1ObjectIdentifier hashAlgOid = certHash.getHashAlgorithm().getAlgorithm(); byte[] hashValue = certHash.getCertificateHash(); msg.append("\tHash algo : ").append(hashAlgOid.getId()).append("\n"); msg.append("\tHash value: ").append(Hex.toHexString(hashValue)).append("\n"); if (encodedCerts != null) { byte[] encodedCert = encodedCerts.get(serialNumber); MessageDigest md = MessageDigest.getInstance(hashAlgOid.getId()); byte[] expectedHashValue = md.digest(encodedCert); if (Arrays.equals(expectedHashValue, hashValue)) { msg.append("\tThis matches the requested certificate"); } else { msg.append("\tThis differs from the requested certificate"); } } } // end if (extension != null) extension = singleResp.getExtension(OCSPObjectIdentifiers.id_pkix_ocsp_archive_cutoff); if (extension != null) { ASN1Encodable extensionValue = extension.getParsedValue(); ASN1GeneralizedTime time = ASN1GeneralizedTime.getInstance(extensionValue); msg.append("\nArchive-CutOff: "); msg.append(time.getTimeString()); } AlgorithmIdentifier sigAlg = basicResp.getSignatureAlgorithmID(); if (sigAlg == null) { msg.append(("\nresponse is not signed")); } else { String sigAlgName = AlgorithmUtil.getSignatureAlgoName(sigAlg); if (sigAlgName == null) { sigAlgName = "unknown"; } msg.append("\nresponse is signed with ").append(sigAlgName); } // extensions msg.append("\nExtensions: "); List<?> extensionOids = basicResp.getExtensionOIDs(); if (extensionOids == null || extensionOids.size() == 0) { msg.append("-"); } else { int size = extensionOids.size(); for (int j = 0; j < size; j++) { ASN1ObjectIdentifier extensionOid = (ASN1ObjectIdentifier) extensionOids.get(j); String name = EXTENSION_OIDNAME_MAP.get(extensionOid); if (name == null) { msg.append(extensionOid.getId()); } else { msg.append(name); } if (j != size - 1) { msg.append(", "); } } } } // end if (verbose.booleanValue()) println(msg.toString()); } // end for println(""); return null; }
From source file:org.xipki.pki.ocsp.qa.OcspQa.java
License:Open Source License
public ValidationResult checkOcsp(final OCSPResp response, final IssuerHash issuerHash, final List<BigInteger> serialNumbers, final Map<BigInteger, byte[]> encodedCerts, final OcspError expectedOcspError, final Map<BigInteger, OcspCertStatus> expectedOcspStatuses, final OcspResponseOption responseOption) { ParamUtil.requireNonNull("response", response); ParamUtil.requireNonEmpty("serialNumbers", serialNumbers); ParamUtil.requireNonEmpty("expectedOcspStatuses", expectedOcspStatuses); ParamUtil.requireNonNull("responseOption", responseOption); List<ValidationIssue> resultIssues = new LinkedList<ValidationIssue>(); int status = response.getStatus(); // Response status ValidationIssue issue = new ValidationIssue("OCSP.STATUS", "response.status"); resultIssues.add(issue);//ww w . j a v a 2 s . co m if (expectedOcspError != null) { if (status != expectedOcspError.getStatus()) { issue.setFailureMessage( "is '" + status + "', but expected '" + expectedOcspError.getStatus() + "'"); } } else { if (status != 0) { issue.setFailureMessage("is '" + status + "', but expected '0'"); } } if (status != 0) { return new ValidationResult(resultIssues); } ValidationIssue encodingIssue = new ValidationIssue("OCSP.ENCODING", "response encoding"); resultIssues.add(encodingIssue); BasicOCSPResp basicResp; try { basicResp = (BasicOCSPResp) response.getResponseObject(); } catch (OCSPException ex) { encodingIssue.setFailureMessage(ex.getMessage()); return new ValidationResult(resultIssues); } SingleResp[] singleResponses = basicResp.getResponses(); issue = new ValidationIssue("OCSP.RESPONSES.NUM", "number of single responses"); resultIssues.add(issue); if (singleResponses == null || singleResponses.length == 0) { issue.setFailureMessage("received no status from server"); return new ValidationResult(resultIssues); } final int n = singleResponses.length; if (n != serialNumbers.size()) { issue.setFailureMessage("is '" + n + "', but expected '" + serialNumbers.size() + "'"); return new ValidationResult(resultIssues); } boolean hasSignature = basicResp.getSignature() != null; // check the signature if available issue = new ValidationIssue("OCSP.SIG", "signature presence"); resultIssues.add(issue); if (!hasSignature) { issue.setFailureMessage("response is not signed"); } if (hasSignature) { // signature algorithm issue = new ValidationIssue("OCSP.SIG.ALG", "signature algorithm"); resultIssues.add(issue); String expectedSigalgo = responseOption.getSignatureAlgName(); if (expectedSigalgo != null) { AlgorithmIdentifier sigAlg = basicResp.getSignatureAlgorithmID(); try { String sigAlgName = AlgorithmUtil.getSignatureAlgoName(sigAlg); if (!AlgorithmUtil.equalsAlgoName(sigAlgName, expectedSigalgo)) { issue.setFailureMessage("is '" + sigAlgName + "', but expected '" + expectedSigalgo + "'"); } } catch (NoSuchAlgorithmException ex) { issue.setFailureMessage("could not extract the signature algorithm"); } } // end if (expectedSigalgo != null) // signer certificate ValidationIssue sigSignerCertIssue = new ValidationIssue("OCSP.SIGNERCERT", "signer certificate"); resultIssues.add(sigSignerCertIssue); // signature validation ValidationIssue sigValIssue = new ValidationIssue("OCSP.SIG.VALIDATION", "signature validation"); resultIssues.add(sigValIssue); X509CertificateHolder respSigner = null; X509CertificateHolder[] responderCerts = basicResp.getCerts(); if (responderCerts == null || responderCerts.length < 1) { sigSignerCertIssue.setFailureMessage("no responder certificate is contained in the response"); sigValIssue.setFailureMessage("could not find certificate to validate signature"); } else { ResponderID respId = basicResp.getResponderId().toASN1Primitive(); X500Name respIdByName = respId.getName(); byte[] respIdByKey = respId.getKeyHash(); for (X509CertificateHolder cert : responderCerts) { if (respIdByName != null) { if (cert.getSubject().equals(respIdByName)) { respSigner = cert; } } else { byte[] spkiSha1 = HashAlgoType.SHA1 .hash(cert.getSubjectPublicKeyInfo().getPublicKeyData().getBytes()); if (Arrays.equals(respIdByKey, spkiSha1)) { respSigner = cert; } } if (respSigner != null) { break; } } if (respSigner == null) { sigSignerCertIssue.setFailureMessage("no responder certificate match the ResponderId"); sigValIssue.setFailureMessage( "could not find certificate matching the" + " ResponderId to validate signature"); } } if (respSigner != null) { issue = new ValidationIssue("OCSP.SIGNERCERT.TRUST", "signer certificate validation"); resultIssues.add(issue); for (int i = 0; i < singleResponses.length; i++) { SingleResp singleResp = singleResponses[i]; if (!respSigner.isValidOn(singleResp.getThisUpdate())) { issue.setFailureMessage( String.format("responder certificate is not valid on the thisUpdate[%d]: %s", i, singleResp.getThisUpdate())); } } // end for X509Certificate respIssuer = responseOption.getRespIssuer(); if (!issue.isFailed() && respIssuer != null) { X509Certificate jceRespSigner; try { jceRespSigner = X509Util.toX509Cert(respSigner.toASN1Structure()); if (X509Util.issues(respIssuer, jceRespSigner)) { jceRespSigner.verify(respIssuer.getPublicKey()); } else { issue.setFailureMessage("responder signer is not trusted"); } } catch (Exception ex) { issue.setFailureMessage("responder signer is not trusted"); } } try { PublicKey responderPubKey = KeyUtil.generatePublicKey(respSigner.getSubjectPublicKeyInfo()); ContentVerifierProvider cvp = securityFactory.getContentVerifierProvider(responderPubKey); boolean sigValid = basicResp.isSignatureValid(cvp); if (!sigValid) { sigValIssue.setFailureMessage("signature is invalid"); } } catch (Exception ex) { sigValIssue.setFailureMessage("could not validate signature"); } } // end if } // end if (hasSignature) // nonce Extension nonceExtn = basicResp.getExtension(OCSPObjectIdentifiers.id_pkix_ocsp_nonce); resultIssues.add(checkOccurrence("OCSP.NONCE", nonceExtn, responseOption.getNonceOccurrence())); boolean extendedRevoke = basicResp.getExtension(ObjectIdentifiers.id_pkix_ocsp_extendedRevoke) != null; for (int i = 0; i < singleResponses.length; i++) { SingleResp singleResp = singleResponses[i]; BigInteger serialNumber = singleResp.getCertID().getSerialNumber(); OcspCertStatus expectedStatus = expectedOcspStatuses.get(serialNumber); byte[] encodedCert = null; if (encodedCerts != null) { encodedCert = encodedCerts.get(serialNumber); } List<ValidationIssue> issues = checkSingleCert(i, singleResp, issuerHash, expectedStatus, encodedCert, extendedRevoke, responseOption.getNextUpdateOccurrence(), responseOption.getCerthashOccurrence(), responseOption.getCerthashAlgId()); resultIssues.addAll(issues); } // end for return new ValidationResult(resultIssues); }