Example usage for org.bouncycastle.cert.ocsp BasicOCSPResp isSignatureValid

List of usage examples for org.bouncycastle.cert.ocsp BasicOCSPResp isSignatureValid

Introduction

In this page you can find the example usage for org.bouncycastle.cert.ocsp BasicOCSPResp isSignatureValid.

Prototype

public boolean isSignatureValid(ContentVerifierProvider verifierProvider) throws OCSPException 

Source Link

Document

verify the signature against the tbsResponseData object we contain.

Usage

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);
}