List of usage examples for org.bouncycastle.cert.ocsp BasicOCSPResp isSignatureValid
public boolean isSignatureValid(ContentVerifierProvider verifierProvider) throws OCSPException
From source file:org.jruby.ext.openssl.OCSPBasicResponse.java
License:Common Public License
@JRubyMethod(name = "verify", rest = true) public IRubyObject verify(final ThreadContext context, IRubyObject[] args) { Ruby runtime = context.runtime;/* ww w. j a v a 2s . co m*/ int flags = 0; IRubyObject certificates = args[0]; IRubyObject store = args[1]; boolean ret = false; if (Arity.checkArgumentCount(runtime, args, 2, 3) == 3) { flags = RubyFixnum.fix2int(args[2]); } JcaContentVerifierProviderBuilder jcacvpb = new JcaContentVerifierProviderBuilder(); jcacvpb.setProvider("BC"); BasicOCSPResp basicOCSPResp = getBasicOCSPResp(); java.security.cert.Certificate signer = findSignerCert(context, asn1BCBasicOCSPResp, convertRubyCerts(certificates), flags); if (signer == null) return RubyBoolean.newBoolean(runtime, false); if ((flags & RubyFixnum.fix2int((RubyFixnum) _OCSP(runtime).getConstant(OCSP_NOINTERN))) == 0 && (flags & RubyFixnum.fix2int((RubyFixnum) _OCSP(runtime).getConstant(OCSP_TRUSTOTHER))) != 0) { flags |= RubyFixnum.fix2int((RubyFixnum) _OCSP(runtime).getConstant(OCSP_NOVERIFY)); } if ((flags & RubyFixnum.fix2int((RubyFixnum) _OCSP(runtime).getConstant(OCSP_NOSIGS))) == 0) { PublicKey sPKey = signer.getPublicKey(); if (sPKey == null) return RubyBoolean.newBoolean(runtime, false); try { ContentVerifierProvider cvp = jcacvpb.build(sPKey); ret = basicOCSPResp.isSignatureValid(cvp); } catch (Exception e) { throw newOCSPError(runtime, e); } } if ((flags & RubyFixnum.fix2int((RubyFixnum) _OCSP(runtime).getConstant(OCSP_NOVERIFY))) == 0) { List<X509Cert> untrustedCerts = null; if ((flags & RubyFixnum.fix2int((RubyFixnum) _OCSP(runtime).getConstant(OCSP_NOCHAIN))) != 0) { } else if (basicOCSPResp.getCerts() != null && (certificates != null && !((RubyArray) certificates).isEmpty())) { untrustedCerts = getCertsFromResp(); Iterator<java.security.cert.Certificate> certIt = ((RubyArray) certificates).iterator(); while (certIt.hasNext()) { try { untrustedCerts.add(X509Cert.wrap(context, certIt.next().getEncoded())); } catch (CertificateEncodingException e) { throw newOCSPError(runtime, e); } } } else { untrustedCerts = getCertsFromResp(); } RubyArray rUntrustedCerts = RubyArray.newEmptyArray(runtime); if (untrustedCerts != null) { X509Cert[] rubyCerts = new X509Cert[untrustedCerts.size()]; rUntrustedCerts = RubyArray.newArray(runtime, untrustedCerts.toArray(rubyCerts)); } X509StoreContext ctx; try { ctx = X509StoreContext.newStoreContext(context, (X509Store) store, X509Cert.wrap(runtime, signer), rUntrustedCerts); } catch (CertificateEncodingException e) { throw newOCSPError(runtime, e); } ctx.set_purpose(context, _X509(runtime).getConstant("PURPOSE_OCSP_HELPER")); ret = ctx.verify(context).isTrue(); IRubyObject chain = ctx.chain(context); if ((flags & RubyFixnum.fix2int((RubyFixnum) _OCSP(runtime).getConstant(OCSP_NOCHECKS))) > 0) { ret = true; } try { if (checkIssuer(getBasicOCSPResp(), chain)) return RubyBoolean.newBoolean(runtime, true); } catch (IOException e) { throw newOCSPError(runtime, e); } if ((flags & RubyFixnum.fix2int((RubyFixnum) _OCSP(runtime).getConstant(OCSP_NOCHAIN))) != 0) { return RubyBoolean.newBoolean(runtime, ret); } else { X509Cert rootCA = (X509Cert) ((RubyArray) chain).last(); PublicKey rootKey = rootCA.getAuxCert().getPublicKey(); try { // check if self-signed and valid (trusts itself) rootCA.getAuxCert().verify(rootKey); ret = true; } catch (Exception e) { ret = false; } } } return RubyBoolean.newBoolean(runtime, ret); }
From source file:org.keycloak.common.util.OCSPUtils.java
License:Apache License
private static boolean verifySignature(BasicOCSPResp basicOcspResponse, X509Certificate cert) { try {/*from w ww .ja va 2 s .com*/ ContentVerifierProvider contentVerifier = new JcaContentVerifierProviderBuilder().setProvider("BC") .build(cert.getPublicKey()); return basicOcspResponse.isSignatureValid(contentVerifier); } catch (OperatorCreationException e) { logger.log(Level.FINE, "Unable to construct OCSP content signature verifier\n{0}", e.getMessage()); } catch (OCSPException e) { logger.log(Level.FINE, "Unable to validate OCSP response signature\n{0}", e.getMessage()); } return false; }
From source file:org.poreid.verify.ocsp.OCSPClient.java
License:Open Source License
public CertStatus getCertificateStatus() throws OCSPValidationException { try {//from ww w . j a va 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
/** * 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 w w w .j a v a 2 s . c om*/ * @param x509Cert - certificate originally passed to validator for validation * @param ocspresp - ocsp response received from ocsp responder * @throws OCSPException * @throws NoSuchProviderException * @throws IOException * @throws CertStoreException * @throws NoSuchAlgorithmException * @throws SignServerException * @throws CertificateParsingException * @throws CryptoTokenOfflineException * @throws IllegalRequestException */ protected void parseAndVerifyOCSPResponse(X509Certificate x509Cert, OCSPResp ocspresp, X509Certificate cACert) throws NoSuchProviderException, OCSPException, NoSuchAlgorithmException, CertStoreException, IOException, SignServerException, CertificateParsingException, IllegalRequestException, CryptoTokenOfflineException, OperatorCreationException, CertificateEncodingException { 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) { //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 validateUsingCRL (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 if (ocspRespSignerCertificate.equals(cACert)) { LOG.debug("Not performing revocation check on issuer certificate"); } else { // TODO: Could try to use CRL if available throw new SignServerException("Revokation check of OCSP certificate not yet supported"); } //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.module.xades.validator.AbstractCustomCertPathChecker.java
License:Open Source License
/** * //from w w w. j a v a2 s. c om * 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 w ww . j a v a 2 s .c om*/ * @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 w w w . ja v a2 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 */ 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.OCSPPathChecker.java
License:Open Source License
/** * Method that traverses all configured AuthorizedOCSPResponderCert properties for the issuer of certficate passed originally to the validators validate() method * and tries to find the one that signed the ocsp response * @param basicOCSPResponse - response that is tried to be verified * @return - Authorized ocsp responder's certificate, or null if none found that verifies ocsp response received * @throws NoSuchProviderException// w ww . ja va 2s. c o m * @throws OCSPException */ protected X509Certificate getAuthorizedOCSPRespondersCertificateFromProperties(BasicOCSPResp basicOCSPResponse) throws NoSuchProviderException, OCSPException, OperatorCreationException { log.debug("Searching for Authorized OCSP Responder certificate from PROPERTIES"); if (this.authorizedOCSPResponderCerts == null || this.authorizedOCSPResponderCerts.isEmpty()) { return null; } for (X509Certificate ocspCert : this.authorizedOCSPResponderCerts) { if (basicOCSPResponse.isSignatureValid( new JcaContentVerifierProviderBuilder().setProvider("BC").build(ocspCert.getPublicKey()))) { log.debug("Found Authorized OCSP Responder's certificate, signing ocsp response. found cert : " + CertTools.getSubjectDN(ocspCert)); return ocspCert; } } log.debug("Authorized OCSP Responder is not found"); return null; }
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"); }/*w w w. j ava 2 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 {/*from w w w . j a v a2 s .com*/ 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); }