Search in sources :

Example 16 with DigestCalculator

use of org.bouncycastle.operator.DigestCalculator in project keycloak by keycloak.

the class OcspHandler method handleRequest.

@Override
public void handleRequest(final HttpServerExchange exchange) throws Exception {
    if (exchange.isInIoThread()) {
        exchange.dispatch(this);
        return;
    }
    final byte[] buffy = new byte[16384];
    try (InputStream requestStream = exchange.getInputStream()) {
        requestStream.read(buffy);
    }
    final OCSPReq request = new OCSPReq(buffy);
    final Req[] requested = request.getRequestList();
    final Extension nonce = request.getExtension(OCSPObjectIdentifiers.id_pkix_ocsp_nonce);
    final DigestCalculator sha1Calculator = new JcaDigestCalculatorProviderBuilder().build().get(AlgorithmIdentifier.getInstance(RespID.HASH_SHA1));
    final BasicOCSPRespBuilder responseBuilder = new BasicOCSPRespBuilder(subjectPublicKeyInfo, sha1Calculator);
    if (nonce != null) {
        responseBuilder.setResponseExtensions(new Extensions(nonce));
    }
    for (final Req req : requested) {
        final CertificateID certId = req.getCertID();
        final BigInteger certificateSerialNumber = certId.getSerialNumber();
        responseBuilder.addResponse(certId, REVOKED_CERTIFICATES_STATUS.get(certificateSerialNumber));
    }
    final ContentSigner contentSigner = new BcRSAContentSignerBuilder(new AlgorithmIdentifier(PKCSObjectIdentifiers.sha256WithRSAEncryption), new AlgorithmIdentifier(NISTObjectIdentifiers.id_sha256)).build(privateKey);
    final OCSPResp response = new OCSPRespBuilder().build(OCSPResp.SUCCESSFUL, responseBuilder.build(contentSigner, chain, new Date()));
    final byte[] responseBytes = response.getEncoded();
    final HeaderMap responseHeaders = exchange.getResponseHeaders();
    responseHeaders.put(Headers.CONTENT_TYPE, "application/ocsp-response");
    final Sender responseSender = exchange.getResponseSender();
    responseSender.send(ByteBuffer.wrap(responseBytes));
    exchange.endExchange();
}
Also used : BasicOCSPRespBuilder(org.bouncycastle.cert.ocsp.BasicOCSPRespBuilder) OCSPRespBuilder(org.bouncycastle.cert.ocsp.OCSPRespBuilder) InputStream(java.io.InputStream) CertificateID(org.bouncycastle.cert.ocsp.CertificateID) DigestCalculator(org.bouncycastle.operator.DigestCalculator) ContentSigner(org.bouncycastle.operator.ContentSigner) Extensions(org.bouncycastle.asn1.x509.Extensions) Date(java.util.Date) AlgorithmIdentifier(org.bouncycastle.asn1.x509.AlgorithmIdentifier) OCSPResp(org.bouncycastle.cert.ocsp.OCSPResp) Extension(org.bouncycastle.asn1.x509.Extension) Sender(io.undertow.io.Sender) BcRSAContentSignerBuilder(org.bouncycastle.operator.bc.BcRSAContentSignerBuilder) BasicOCSPRespBuilder(org.bouncycastle.cert.ocsp.BasicOCSPRespBuilder) HeaderMap(io.undertow.util.HeaderMap) OCSPReq(org.bouncycastle.cert.ocsp.OCSPReq) BigInteger(java.math.BigInteger) JcaDigestCalculatorProviderBuilder(org.bouncycastle.operator.jcajce.JcaDigestCalculatorProviderBuilder) Req(org.bouncycastle.cert.ocsp.Req) OCSPReq(org.bouncycastle.cert.ocsp.OCSPReq)

Example 17 with DigestCalculator

use of org.bouncycastle.operator.DigestCalculator in project keycloak by keycloak.

the class OCSPUtils method check.

/**
 * Requests certificate revocation status using OCSP.
 * @param cert the certificate to be checked
 * @param issuerCertificate the issuer certificate
 * @param responderURIs the OCSP responder URIs
 * @param responderCert the OCSP responder certificate
 * @param date if null, the current time is used.
 * @return a revocation status
 * @throws CertPathValidatorException
 */
private static OCSPRevocationStatus check(KeycloakSession session, X509Certificate cert, X509Certificate issuerCertificate, List<URI> responderURIs, X509Certificate responderCert, Date date) throws CertPathValidatorException {
    if (responderURIs == null || responderURIs.size() == 0)
        throw new IllegalArgumentException("Need at least one responder");
    try {
        DigestCalculator digCalc = new BcDigestCalculatorProvider().get(new AlgorithmIdentifier(OIWObjectIdentifiers.idSHA1));
        JcaCertificateID certificateID = new JcaCertificateID(digCalc, issuerCertificate, cert.getSerialNumber());
        // Create a nounce extension to protect against replay attacks
        SecureRandom random = SecureRandom.getInstance("SHA1PRNG");
        BigInteger nounce = BigInteger.valueOf(Math.abs(random.nextInt()));
        DEROctetString derString = new DEROctetString(nounce.toByteArray());
        Extension nounceExtension = new Extension(OCSPObjectIdentifiers.id_pkix_ocsp_nonce, false, derString);
        Extensions extensions = new Extensions(nounceExtension);
        OCSPReq ocspReq = new OCSPReqBuilder().addRequest(certificateID, extensions).build();
        URI responderURI = responderURIs.get(0);
        logger.log(Level.INFO, "OCSP Responder {0}", responderURI);
        try {
            OCSPResp resp = getResponse(session, ocspReq, responderURI);
            logger.log(Level.FINE, "Received a response from OCSP responder {0}, the response status is {1}", new Object[] { responderURI, resp.getStatus() });
            switch(resp.getStatus()) {
                case OCSPResp.SUCCESSFUL:
                    if (resp.getResponseObject() instanceof BasicOCSPResp) {
                        return processBasicOCSPResponse(issuerCertificate, responderCert, date, certificateID, nounce, (BasicOCSPResp) resp.getResponseObject());
                    } else {
                        throw new CertPathValidatorException("OCSP responder returned an invalid or unknown OCSP response.");
                    }
                case OCSPResp.INTERNAL_ERROR:
                case OCSPResp.TRY_LATER:
                    throw new CertPathValidatorException("Internal error/try later. OCSP response error: " + resp.getStatus(), (Throwable) null, (CertPath) null, -1, CertPathValidatorException.BasicReason.UNDETERMINED_REVOCATION_STATUS);
                case OCSPResp.SIG_REQUIRED:
                    throw new CertPathValidatorException("Invalid or missing signature. OCSP response error: " + resp.getStatus(), (Throwable) null, (CertPath) null, -1, CertPathValidatorException.BasicReason.INVALID_SIGNATURE);
                case OCSPResp.UNAUTHORIZED:
                    throw new CertPathValidatorException("Unauthorized request. OCSP response error: " + resp.getStatus(), (Throwable) null, (CertPath) null, -1, CertPathValidatorException.BasicReason.UNSPECIFIED);
                case OCSPResp.MALFORMED_REQUEST:
                default:
                    throw new CertPathValidatorException("OCSP request is malformed. OCSP response error: " + resp.getStatus(), (Throwable) null, (CertPath) null, -1, CertPathValidatorException.BasicReason.UNSPECIFIED);
            }
        } catch (IOException e) {
            logger.log(Level.FINE, "OCSP Responder \"{0}\" failed to return a valid OCSP response\n{1}", new Object[] { responderURI, e.getMessage() });
            throw new CertPathValidatorException("OCSP check failed", e);
        }
    } catch (CertificateNotYetValidException | CertificateExpiredException | OperatorCreationException | OCSPException | CertificateEncodingException | NoSuchAlgorithmException | NoSuchProviderException e) {
        logger.log(Level.FINE, e.getMessage());
        throw new CertPathValidatorException(e.getMessage(), e);
    }
}
Also used : DigestCalculator(org.bouncycastle.operator.DigestCalculator) NoSuchAlgorithmException(java.security.NoSuchAlgorithmException) Extensions(org.bouncycastle.asn1.x509.Extensions) URI(java.net.URI) DEROctetString(org.bouncycastle.asn1.DEROctetString) AlgorithmIdentifier(org.bouncycastle.asn1.x509.AlgorithmIdentifier) OperatorCreationException(org.bouncycastle.operator.OperatorCreationException) BcDigestCalculatorProvider(org.bouncycastle.operator.bc.BcDigestCalculatorProvider) JcaCertificateID(org.bouncycastle.cert.ocsp.jcajce.JcaCertificateID) SecureRandom(java.security.SecureRandom) IOException(java.io.IOException) Extension(org.bouncycastle.asn1.x509.Extension) BigInteger(java.math.BigInteger) NoSuchProviderException(java.security.NoSuchProviderException)

Aggregations

DigestCalculator (org.bouncycastle.operator.DigestCalculator)17 OperatorCreationException (org.bouncycastle.operator.OperatorCreationException)8 IOException (java.io.IOException)7 BigInteger (java.math.BigInteger)7 Date (java.util.Date)7 AlgorithmIdentifier (org.bouncycastle.asn1.x509.AlgorithmIdentifier)7 CertificateID (org.bouncycastle.cert.ocsp.CertificateID)7 JcaDigestCalculatorProviderBuilder (org.bouncycastle.operator.jcajce.JcaDigestCalculatorProviderBuilder)7 X509CertificateHolder (org.bouncycastle.cert.X509CertificateHolder)6 SecureRandom (java.security.SecureRandom)5 Extension (org.bouncycastle.asn1.x509.Extension)5 Extensions (org.bouncycastle.asn1.x509.Extensions)5 X509Certificate (java.security.cert.X509Certificate)4 DEROctetString (org.bouncycastle.asn1.DEROctetString)4 SubjectPublicKeyInfo (org.bouncycastle.asn1.x509.SubjectPublicKeyInfo)4 BasicOCSPResp (org.bouncycastle.cert.ocsp.BasicOCSPResp)4 OCSPReq (org.bouncycastle.cert.ocsp.OCSPReq)4 OCSPResp (org.bouncycastle.cert.ocsp.OCSPResp)4 ContentSigner (org.bouncycastle.operator.ContentSigner)4 JcaContentSignerBuilder (org.bouncycastle.operator.jcajce.JcaContentSignerBuilder)4