Search in sources :

Example 11 with SingleResp

use of org.bouncycastle.cert.ocsp.SingleResp in project xipki by xipki.

the class OcspQa method checkOcsp.

public ValidationResult checkOcsp(OCSPResp response, IssuerHash issuerHash, List<BigInteger> serialNumbers, Map<BigInteger, byte[]> encodedCerts, OcspError expectedOcspError, Map<BigInteger, OcspCertStatus> expectedOcspStatuses, Map<BigInteger, Date> expectedRevTimes, OcspResponseOption responseOption, boolean noSigVerify) {
    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);
    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
    if (noSigVerify) {
        issue = new ValidationIssue("OCSP.SIG", (hasSignature ? "signature presence (Ignore)" : "signature presence"));
    } else {
        issue = new ValidationIssue("OCSP.SIG", "signature presence");
    }
    resultIssues.add(issue);
    if (!hasSignature) {
        issue.setFailureMessage("response is not signed");
    }
    if (hasSignature & !noSigVerify) {
        // 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 = HashAlgo.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);
        Date expectedRevTime = null;
        if (expectedRevTimes != null) {
            expectedRevTime = expectedRevTimes.get(serialNumber);
        }
        byte[] encodedCert = null;
        if (encodedCerts != null) {
            encodedCert = encodedCerts.get(serialNumber);
        }
        List<ValidationIssue> issues = checkSingleCert(i, singleResp, issuerHash, expectedStatus, encodedCert, expectedRevTime, extendedRevoke, responseOption.getNextUpdateOccurrence(), responseOption.getCerthashOccurrence(), responseOption.getCerthashAlgId());
        resultIssues.addAll(issues);
    }
    return new ValidationResult(resultIssues);
}
Also used : ResponderID(org.bouncycastle.asn1.ocsp.ResponderID) NoSuchAlgorithmException(java.security.NoSuchAlgorithmException) X500Name(org.bouncycastle.asn1.x500.X500Name) ValidationResult(org.xipki.common.qa.ValidationResult) AlgorithmIdentifier(org.bouncycastle.asn1.x509.AlgorithmIdentifier) OCSPException(org.bouncycastle.cert.ocsp.OCSPException) SingleResp(org.bouncycastle.cert.ocsp.SingleResp) ContentVerifierProvider(org.bouncycastle.operator.ContentVerifierProvider) PublicKey(java.security.PublicKey) ValidationIssue(org.xipki.common.qa.ValidationIssue) LinkedList(java.util.LinkedList) X509Certificate(java.security.cert.X509Certificate) OCSPException(org.bouncycastle.cert.ocsp.OCSPException) NoSuchAlgorithmException(java.security.NoSuchAlgorithmException) Date(java.util.Date) Extension(org.bouncycastle.asn1.x509.Extension) BasicOCSPResp(org.bouncycastle.cert.ocsp.BasicOCSPResp) X509CertificateHolder(org.bouncycastle.cert.X509CertificateHolder) BigInteger(java.math.BigInteger)

Example 12 with SingleResp

use of org.bouncycastle.cert.ocsp.SingleResp in project pdfbox by apache.

the class OcspHelper method verifyOcspResponse.

/**
 * Verifies the status and the response itself (including nonce), but not the signature.
 *
 * @param ocspResponse to be verified
 * @throws OCSPException
 * @throws RevokedCertificateException
 */
private void verifyOcspResponse(OCSPResp ocspResponse) throws OCSPException, RevokedCertificateException {
    verifyRespStatus(ocspResponse);
    BasicOCSPResp basicResponse = (BasicOCSPResp) ocspResponse.getResponseObject();
    if (basicResponse != null) {
        checkOcspSignature(basicResponse.getCerts()[0], basicResponse);
        checkNonce(basicResponse);
        SingleResp[] responses = basicResponse.getResponses();
        if (responses.length == 1) {
            SingleResp resp = responses[0];
            Object status = resp.getCertStatus();
            if (status instanceof RevokedStatus) {
                throw new RevokedCertificateException("OCSP: Certificate is revoked.");
            } else if (status != CertificateStatus.GOOD) {
                throw new OCSPException("OCSP: Status of Cert is unknown");
            }
        } else {
            throw new OCSPException("OCSP: Recieved " + responses.length + " responses instead of 1!");
        }
    }
}
Also used : RevokedStatus(org.bouncycastle.cert.ocsp.RevokedStatus) OCSPException(org.bouncycastle.cert.ocsp.OCSPException) BasicOCSPResp(org.bouncycastle.cert.ocsp.BasicOCSPResp) SingleResp(org.bouncycastle.cert.ocsp.SingleResp)

Example 13 with SingleResp

use of org.bouncycastle.cert.ocsp.SingleResp in project netty by netty.

the class OcspServerExample method main.

public static void main(String[] args) throws Exception {
    // We assume there's a private key.
    PrivateKey privateKey = null;
    // Step 1: Load the certificate chain for netty.io. We'll need the certificate
    // and the issuer's certificate and we don't need any of the intermediate certs.
    // The array is assumed to be a certain order to keep things simple.
    X509Certificate[] keyCertChain = parseCertificates(OcspServerExample.class, "netty_io_chain.pem");
    X509Certificate certificate = keyCertChain[0];
    X509Certificate issuer = keyCertChain[keyCertChain.length - 1];
    // Step 2: We need the URL of the CA's OCSP responder server. It's somewhere encoded
    // into the certificate! Notice that it's an HTTP URL.
    URI uri = OcspUtils.ocspUri(certificate);
    System.out.println("OCSP Responder URI: " + uri);
    if (uri == null) {
        throw new IllegalStateException("The CA/certificate doesn't have an OCSP responder");
    }
    // Step 3: Construct the OCSP request
    OCSPReq request = new OcspRequestBuilder().certificate(certificate).issuer(issuer).build();
    // Step 4: Do the request to the CA's OCSP responder
    OCSPResp response = OcspUtils.request(uri, request, 5L, TimeUnit.SECONDS);
    if (response.getStatus() != OCSPResponseStatus.SUCCESSFUL) {
        throw new IllegalStateException("response-status=" + response.getStatus());
    }
    // Step 5: Is my certificate any good or has the CA revoked it?
    BasicOCSPResp basicResponse = (BasicOCSPResp) response.getResponseObject();
    SingleResp first = basicResponse.getResponses()[0];
    CertificateStatus status = first.getCertStatus();
    System.out.println("Status: " + (status == CertificateStatus.GOOD ? "Good" : status));
    System.out.println("This Update: " + first.getThisUpdate());
    System.out.println("Next Update: " + first.getNextUpdate());
    if (status != null) {
        throw new IllegalStateException("certificate-status=" + status);
    }
    BigInteger certSerial = certificate.getSerialNumber();
    BigInteger ocspSerial = first.getCertID().getSerialNumber();
    if (!certSerial.equals(ocspSerial)) {
        throw new IllegalStateException("Bad Serials=" + certSerial + " vs. " + ocspSerial);
    }
    if (!OpenSsl.isAvailable()) {
        throw new IllegalStateException("OpenSSL is not available!");
    }
    if (!OpenSsl.isOcspSupported()) {
        throw new IllegalStateException("OCSP is not supported!");
    }
    if (privateKey == null) {
        throw new IllegalStateException("Because we don't have a PrivateKey we can't continue past this point.");
    }
    ReferenceCountedOpenSslContext context = (ReferenceCountedOpenSslContext) SslContextBuilder.forServer(privateKey, keyCertChain).sslProvider(SslProvider.OPENSSL).enableOcsp(true).build();
    try {
        ServerBootstrap bootstrap = new ServerBootstrap().childHandler(newServerHandler(context, response));
    // so on and so forth...
    } finally {
        context.release();
    }
}
Also used : PrivateKey(java.security.PrivateKey) CertificateStatus(org.bouncycastle.cert.ocsp.CertificateStatus) URI(java.net.URI) X509Certificate(java.security.cert.X509Certificate) ServerBootstrap(io.netty.bootstrap.ServerBootstrap) OCSPResp(org.bouncycastle.cert.ocsp.OCSPResp) BasicOCSPResp(org.bouncycastle.cert.ocsp.BasicOCSPResp) ReferenceCountedOpenSslContext(io.netty.handler.ssl.ReferenceCountedOpenSslContext) OCSPReq(org.bouncycastle.cert.ocsp.OCSPReq) BasicOCSPResp(org.bouncycastle.cert.ocsp.BasicOCSPResp) BigInteger(java.math.BigInteger) SingleResp(org.bouncycastle.cert.ocsp.SingleResp)

Example 14 with SingleResp

use of org.bouncycastle.cert.ocsp.SingleResp in project jruby-openssl by jruby.

the class OCSPBasicResponse method checkIssuer.

private boolean checkIssuer(BasicOCSPResp basicOCSPResp, IRubyObject chain) throws IOException {
    boolean ret = false;
    if (((RubyArray) chain).size() <= 0)
        return false;
    List<SingleResp> singleResponses = Arrays.asList(basicOCSPResp.getResponses());
    CertificateID certId = checkCertIds(singleResponses);
    X509Cert signer = (X509Cert) ((RubyArray) chain).first();
    if (((RubyArray) chain).size() > 1) {
        X509Cert signerCA = (X509Cert) ((RubyArray) chain).entry(1);
        if (matchIssuerId(signerCA, certId, singleResponses)) {
            return checkDelegated(signerCA);
        }
    } else {
        ret = matchIssuerId(signer, certId, singleResponses);
    }
    return ret;
}
Also used : CertificateID(org.bouncycastle.cert.ocsp.CertificateID) SingleResp(org.bouncycastle.cert.ocsp.SingleResp)

Example 15 with SingleResp

use of org.bouncycastle.cert.ocsp.SingleResp in project jruby-openssl by jruby.

the class OCSPBasicResponse method matchIssuerId.

private boolean matchIssuerId(X509Cert signerCA, CertificateID certId, List<SingleResp> singleResponses) throws IOException {
    Ruby runtime = getRuntime();
    if (certId == null) {
        // gotta check em all
        for (SingleResp resp : singleResponses) {
            CertificateID tempId = resp.getCertID();
            if (!matchIssuerId(signerCA, tempId, null))
                return false;
        }
        return true;
    } else {
        // we have a matching cid
        ASN1ObjectIdentifier alg = certId.getHashAlgOID();
        String sym = ASN1.oid2Sym(runtime, alg);
        MessageDigest md = Digest.getDigest(runtime, sym);
        byte[] issuerNameDigest = md.digest(signerCA.getIssuer().getX500Name().getEncoded());
        byte[] issuerKeyDigest = md.digest(signerCA.getAuxCert().getPublicKey().getEncoded());
        if (!issuerNameDigest.equals(certId.getIssuerNameHash()))
            return false;
        if (!issuerKeyDigest.equals(certId.getIssuerKeyHash()))
            return false;
        return true;
    }
}
Also used : CertificateID(org.bouncycastle.cert.ocsp.CertificateID) RubyString(org.jruby.RubyString) MessageDigest(java.security.MessageDigest) Ruby(org.jruby.Ruby) SingleResp(org.bouncycastle.cert.ocsp.SingleResp) ASN1ObjectIdentifier(org.bouncycastle.asn1.ASN1ObjectIdentifier)

Aggregations

SingleResp (org.bouncycastle.cert.ocsp.SingleResp)17 BasicOCSPResp (org.bouncycastle.cert.ocsp.BasicOCSPResp)14 CertificateID (org.bouncycastle.cert.ocsp.CertificateID)12 X509Certificate (java.security.cert.X509Certificate)9 OCSPException (org.bouncycastle.cert.ocsp.OCSPException)9 IOException (java.io.IOException)8 X509CertificateHolder (org.bouncycastle.cert.X509CertificateHolder)8 OCSPResp (org.bouncycastle.cert.ocsp.OCSPResp)8 BigInteger (java.math.BigInteger)7 OCSPReq (org.bouncycastle.cert.ocsp.OCSPReq)7 RevokedStatus (org.bouncycastle.cert.ocsp.RevokedStatus)7 JcaDigestCalculatorProviderBuilder (org.bouncycastle.operator.jcajce.JcaDigestCalculatorProviderBuilder)7 Extension (org.bouncycastle.asn1.x509.Extension)6 Date (java.util.Date)5 OperatorCreationException (org.bouncycastle.operator.OperatorCreationException)5 CertificateEncodingException (java.security.cert.CertificateEncodingException)4 ArrayList (java.util.ArrayList)4 DigestCalculator (org.bouncycastle.operator.DigestCalculator)4 DigestCalculatorProvider (org.bouncycastle.operator.DigestCalculatorProvider)4 InputStream (java.io.InputStream)3