Search in sources :

Example 1 with JcaContentVerifierProviderBuilder

use of org.bouncycastle.operator.jcajce.JcaContentVerifierProviderBuilder in project Openfire by igniterealtime.

the class OCSPChecker method check.

@Override
public void check(Certificate cert, Collection<String> unresolvedCritExts) throws CertPathValidatorException {
    Log.debug("OCSPChecker: check called");
    InputStream in = null;
    OutputStream out = null;
    try {
        // Examine OCSP properties
        X509Certificate responderCert = null;
        //defaults to issuers cert
        boolean haveResponderCert = true;
        X500Principal responderSubjectName = null;
        boolean haveIssuerCert = false;
        // If we set the subject name, we need to find the certificate
        if (ocspServerSubject != null) {
            haveResponderCert = false;
            responderSubjectName = new X500Principal(ocspServerSubject);
        }
        X509Certificate issuerCert = null;
        X509Certificate currCert = (X509Certificate) cert;
        // Set the issuer certificate if we were passed a chain
        if (certIndex != 0) {
            issuerCert = certs[certIndex];
            haveIssuerCert = true;
            if (haveResponderCert) {
                responderCert = certs[certIndex];
            }
        }
        if (!haveIssuerCert || !haveResponderCert) {
            if (!haveResponderCert) {
                Log.debug("OCSPChecker: Looking for responder's certificate");
            }
            if (!haveIssuerCert) {
                Log.debug("OCSPChecker: Looking for issuer's certificate");
            }
            // Extract the anchor certs
            Iterator anchors = pkixParams.getTrustAnchors().iterator();
            if (!anchors.hasNext()) {
                throw new CertPathValidatorException("Must specify at least one trust anchor");
            }
            X500Principal certIssuerName = currCert.getIssuerX500Principal();
            while (anchors.hasNext() && (!haveIssuerCert || !haveResponderCert)) {
                TrustAnchor anchor = (TrustAnchor) anchors.next();
                X509Certificate anchorCert = anchor.getTrustedCert();
                X500Principal anchorSubjectName = anchorCert.getSubjectX500Principal();
                // Check if this anchor cert is the issuer cert
                if (!haveIssuerCert && certIssuerName.equals(anchorSubjectName)) {
                    issuerCert = anchorCert;
                    haveIssuerCert = true;
                    //If we have not set the responderCert at this point, set it to the issuer
                    if (haveResponderCert && responderCert == null) {
                        responderCert = anchorCert;
                        Log.debug("OCSPChecker: Responder's certificate = issuer certificate");
                    }
                }
                // Check if this anchor cert is the responder cert
                if (!haveResponderCert) {
                    if (responderSubjectName != null && responderSubjectName.equals(anchorSubjectName)) {
                        responderCert = anchorCert;
                        haveResponderCert = true;
                    }
                }
            }
            if (issuerCert == null) {
                //No trust anchor was found matching the issuer
                throw new CertPathValidatorException("No trusted certificate for " + currCert.getIssuerDN());
            }
            // Check cert stores if responder cert has not yet been found
            if (!haveResponderCert) {
                Log.debug("OCSPChecker: Searching cert stores for responder's certificate");
                if (responderSubjectName != null) {
                    X509CertSelector filter = new X509CertSelector();
                    filter.setSubject(responderSubjectName.getName());
                    List<CertStore> certStores = pkixParams.getCertStores();
                    for (CertStore certStore : certStores) {
                        Iterator i = certStore.getCertificates(filter).iterator();
                        if (i.hasNext()) {
                            responderCert = (X509Certificate) i.next();
                            haveResponderCert = true;
                            break;
                        }
                    }
                }
            }
        }
        // Could not find the responder cert
        if (!haveResponderCert) {
            throw new CertPathValidatorException("Cannot find the responder's certificate.");
        }
        // Construct an OCSP Request
        OCSPReqBuilder gen = new OCSPReqBuilder();
        CertificateID certID = new CertificateID(new JcaDigestCalculatorProviderBuilder().setProvider("BC").build().get(CertificateID.HASH_SHA1), new X509CertificateHolder(issuerCert.getEncoded()), currCert.getSerialNumber());
        gen.addRequest(certID);
        OCSPReq ocspRequest = gen.build();
        URL url;
        if (ocspServerUrl != null) {
            try {
                url = new URL(ocspServerUrl);
            } catch (MalformedURLException e) {
                throw new CertPathValidatorException(e);
            }
        } else {
            throw new CertPathValidatorException("Must set OCSP Server URL");
        }
        HttpURLConnection con = (HttpURLConnection) url.openConnection();
        Log.debug("OCSPChecker: connecting to OCSP service at: " + url);
        con.setDoOutput(true);
        con.setDoInput(true);
        con.setRequestMethod("POST");
        con.setRequestProperty("Content-type", "application/ocsp-request");
        con.setRequestProperty("Accept", "application/ocsp-response");
        byte[] bytes = ocspRequest.getEncoded();
        con.setRequestProperty("Content-length", String.valueOf(bytes.length));
        out = con.getOutputStream();
        out.write(bytes);
        out.flush();
        // Check the response
        if (con.getResponseCode() != HttpURLConnection.HTTP_OK) {
            Log.debug("OCSPChecker: Received HTTP error: " + con.getResponseCode() + " - " + con.getResponseMessage());
        }
        in = con.getInputStream();
        OCSPResp ocspResponse = new OCSPResp(in);
        BigInteger serialNumber = currCert.getSerialNumber();
        BasicOCSPResp brep = (BasicOCSPResp) ocspResponse.getResponseObject();
        try {
            if (!brep.isSignatureValid(new JcaContentVerifierProviderBuilder().setProvider("BC").build(responderCert.getPublicKey()))) {
                throw new CertPathValidatorException("OCSP response is not verified");
            }
        } catch (Exception e) {
            throw new CertPathValidatorException("OCSP response could not be verified (" + e.getMessage() + ")", null, cp, certIndex);
        }
        SingleResp[] singleResp = brep.getResponses();
        boolean foundResponse = false;
        for (SingleResp resp : singleResp) {
            CertificateID respCertID = resp.getCertID();
            if (respCertID.equals(certID)) {
                Object status = resp.getCertStatus();
                if (status == CertificateStatus.GOOD) {
                    Log.debug("OCSPChecker: Status of certificate (with serial number " + serialNumber.toString() + ") is: good");
                    foundResponse = true;
                    break;
                } else if (status instanceof org.bouncycastle.cert.ocsp.RevokedStatus) {
                    Log.debug("OCSPChecker: Status of certificate (with serial number " + serialNumber.toString() + ") is: revoked");
                    throw new CertPathValidatorException("Certificate has been revoked", null, cp, certIndex);
                } else if (status instanceof org.bouncycastle.cert.ocsp.UnknownStatus) {
                    Log.debug("OCSPChecker: Status of certificate (with serial number " + serialNumber.toString() + ") is: unknown");
                    throw new CertPathValidatorException("Certificate's revocation status is unknown", null, cp, certIndex);
                } else {
                    Log.debug("Status of certificate (with serial number " + serialNumber.toString() + ") is: not recognized");
                    throw new CertPathValidatorException("Unknown OCSP response for certificate", null, cp, certIndex);
                }
            }
        }
        // Check that response applies to the cert that was supplied
        if (!foundResponse) {
            throw new CertPathValidatorException("No certificates in the OCSP response match the " + "certificate supplied in the OCSP request.");
        }
    } catch (CertPathValidatorException cpve) {
        throw cpve;
    } catch (Exception e) {
        throw new CertPathValidatorException(e);
    } finally {
        if (in != null) {
            try {
                in.close();
            } catch (IOException ioe) {
                throw new CertPathValidatorException(ioe);
            }
        }
        if (out != null) {
            try {
                out.close();
            } catch (IOException ioe) {
                throw new CertPathValidatorException(ioe);
            }
        }
    }
}
Also used : MalformedURLException(java.net.MalformedURLException) OutputStream(java.io.OutputStream) X509CertSelector(java.security.cert.X509CertSelector) URL(java.net.URL) OCSPResp(org.bouncycastle.cert.ocsp.OCSPResp) BasicOCSPResp(org.bouncycastle.cert.ocsp.BasicOCSPResp) HttpURLConnection(java.net.HttpURLConnection) Iterator(java.util.Iterator) OCSPReqBuilder(org.bouncycastle.cert.ocsp.OCSPReqBuilder) SingleResp(org.bouncycastle.cert.ocsp.SingleResp) InputStream(java.io.InputStream) CertificateID(org.bouncycastle.cert.ocsp.CertificateID) TrustAnchor(java.security.cert.TrustAnchor) IOException(java.io.IOException) X509Certificate(java.security.cert.X509Certificate) CertPathValidatorException(java.security.cert.CertPathValidatorException) MalformedURLException(java.net.MalformedURLException) IOException(java.io.IOException) NoSuchProviderException(java.security.NoSuchProviderException) CertPathValidatorException(java.security.cert.CertPathValidatorException) JcaContentVerifierProviderBuilder(org.bouncycastle.operator.jcajce.JcaContentVerifierProviderBuilder) OCSPReq(org.bouncycastle.cert.ocsp.OCSPReq) X509CertificateHolder(org.bouncycastle.cert.X509CertificateHolder) BasicOCSPResp(org.bouncycastle.cert.ocsp.BasicOCSPResp) X500Principal(javax.security.auth.x500.X500Principal) BigInteger(java.math.BigInteger) JcaDigestCalculatorProviderBuilder(org.bouncycastle.operator.jcajce.JcaDigestCalculatorProviderBuilder) CertStore(java.security.cert.CertStore)

Example 2 with JcaContentVerifierProviderBuilder

use of org.bouncycastle.operator.jcajce.JcaContentVerifierProviderBuilder in project Openfire by igniterealtime.

the class CertificateManager method createX509V3Certificate.

/**
     * Creates an X509 version3 certificate.
     *
     * @param kp           KeyPair that keeps the public and private keys for the new certificate.
     * @param days       time to live
     * @param issuerBuilder     IssuerDN builder
     * @param subjectBuilder    SubjectDN builder
     * @param domain       Domain of the server.
     * @param signAlgoritm Signature algorithm. This can be either a name or an OID.
     * @return X509 V3 Certificate
     * @throws GeneralSecurityException
     * @throws IOException
     */
public static synchronized X509Certificate createX509V3Certificate(KeyPair kp, int days, X500NameBuilder issuerBuilder, X500NameBuilder subjectBuilder, String domain, String signAlgoritm) throws GeneralSecurityException, IOException {
    PublicKey pubKey = kp.getPublic();
    PrivateKey privKey = kp.getPrivate();
    byte[] serno = new byte[8];
    SecureRandom random = SecureRandom.getInstance("SHA1PRNG");
    random.setSeed((new Date().getTime()));
    random.nextBytes(serno);
    BigInteger serial = (new java.math.BigInteger(serno)).abs();
    X500Name issuerDN = issuerBuilder.build();
    X500Name subjectDN = subjectBuilder.build();
    // builder
    JcaX509v3CertificateBuilder certBuilder = new //
    JcaX509v3CertificateBuilder(//
    issuerDN, //
    serial, //
    new Date(), //
    new Date(System.currentTimeMillis() + days * (1000L * 60 * 60 * 24)), //
    subjectDN, //
    pubKey);
    // add subjectAlternativeName extension
    boolean critical = subjectDN.getRDNs().length == 0;
    ASN1Sequence othernameSequence = new DERSequence(new ASN1Encodable[] { new ASN1ObjectIdentifier("1.3.6.1.5.5.7.8.5"), new DERUTF8String(domain) });
    GeneralName othernameGN = new GeneralName(GeneralName.otherName, othernameSequence);
    GeneralNames subjectAltNames = new GeneralNames(new GeneralName[] { othernameGN });
    certBuilder.addExtension(Extension.subjectAlternativeName, critical, subjectAltNames);
    // add keyIdentifiers extensions
    JcaX509ExtensionUtils utils = new JcaX509ExtensionUtils();
    certBuilder.addExtension(Extension.subjectKeyIdentifier, false, utils.createSubjectKeyIdentifier(pubKey));
    certBuilder.addExtension(Extension.authorityKeyIdentifier, false, utils.createAuthorityKeyIdentifier(pubKey));
    try {
        // build the certificate
        ContentSigner signer = new JcaContentSignerBuilder(signAlgoritm).build(privKey);
        X509CertificateHolder cert = certBuilder.build(signer);
        // verify the validity
        if (!cert.isValidOn(new Date())) {
            throw new GeneralSecurityException("Certificate validity not valid");
        }
        // verify the signature (self-signed)
        ContentVerifierProvider verifierProvider = new JcaContentVerifierProviderBuilder().build(pubKey);
        if (!cert.isSignatureValid(verifierProvider)) {
            throw new GeneralSecurityException("Certificate signature not valid");
        }
        return new JcaX509CertificateConverter().getCertificate(cert);
    } catch (OperatorCreationException | CertException e) {
        throw new GeneralSecurityException(e);
    }
}
Also used : JcaX509ExtensionUtils(org.bouncycastle.cert.jcajce.JcaX509ExtensionUtils) PrivateKey(java.security.PrivateKey) JcaContentSignerBuilder(org.bouncycastle.operator.jcajce.JcaContentSignerBuilder) X500Name(org.bouncycastle.asn1.x500.X500Name) JcaX509CertificateConverter(org.bouncycastle.cert.jcajce.JcaX509CertificateConverter) JcaX509v3CertificateBuilder(org.bouncycastle.cert.jcajce.JcaX509v3CertificateBuilder) OperatorCreationException(org.bouncycastle.operator.OperatorCreationException) ContentVerifierProvider(org.bouncycastle.operator.ContentVerifierProvider) PublicKey(java.security.PublicKey) GeneralSecurityException(java.security.GeneralSecurityException) ContentSigner(org.bouncycastle.operator.ContentSigner) SecureRandom(java.security.SecureRandom) CertException(org.bouncycastle.cert.CertException) Date(java.util.Date) JcaContentVerifierProviderBuilder(org.bouncycastle.operator.jcajce.JcaContentVerifierProviderBuilder) GeneralNames(org.bouncycastle.asn1.x509.GeneralNames) X509CertificateHolder(org.bouncycastle.cert.X509CertificateHolder) BigInteger(java.math.BigInteger) GeneralName(org.bouncycastle.asn1.x509.GeneralName)

Aggregations

BigInteger (java.math.BigInteger)2 X509CertificateHolder (org.bouncycastle.cert.X509CertificateHolder)2 JcaContentVerifierProviderBuilder (org.bouncycastle.operator.jcajce.JcaContentVerifierProviderBuilder)2 IOException (java.io.IOException)1 InputStream (java.io.InputStream)1 OutputStream (java.io.OutputStream)1 HttpURLConnection (java.net.HttpURLConnection)1 MalformedURLException (java.net.MalformedURLException)1 URL (java.net.URL)1 GeneralSecurityException (java.security.GeneralSecurityException)1 NoSuchProviderException (java.security.NoSuchProviderException)1 PrivateKey (java.security.PrivateKey)1 PublicKey (java.security.PublicKey)1 SecureRandom (java.security.SecureRandom)1 CertPathValidatorException (java.security.cert.CertPathValidatorException)1 CertStore (java.security.cert.CertStore)1 TrustAnchor (java.security.cert.TrustAnchor)1 X509CertSelector (java.security.cert.X509CertSelector)1 X509Certificate (java.security.cert.X509Certificate)1 Date (java.util.Date)1