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.cesecore.util.PKIXCertRevocationStatusChecker.java

License:Open Source License

/**
 * Sends an OCSP request, gets a response and verifies the response as much as possible before returning it to the caller.
 * // w  w w  .j a  v  a 2  s  .  c  om
 * @return The OCSP response, or null of no correct response could be obtained.
 */
private SingleResp getOCSPResponse(final String ocspurl, final OCSPReq ocspRequest, final Certificate cert,
        final byte[] nonce, int expectedOcspRespCode, int expectedHttpRespCode) {
    if (log.isDebugEnabled()) {
        log.debug("Sending OCSP request to " + ocspurl + " regarding certificate with SubjectDN: "
                + CertTools.getSubjectDN(cert) + " - IssuerDN: " + CertTools.getIssuerDN(cert));
    }

    //----------------------- Open connection and send the request --------------//
    OCSPResp response = null;
    HttpURLConnection con = null;
    try {
        final URL url = new URL(ocspurl);
        con = (HttpURLConnection) url.openConnection();
        // we are going to do a POST
        con.setDoOutput(true);
        con.setRequestMethod("POST");

        // POST it
        con.setRequestProperty("Content-Type", "application/ocsp-request");
        OutputStream os = con.getOutputStream();
        os.write(ocspRequest.getEncoded());
        os.close();

        final int httpRespCode = ((HttpURLConnection) con).getResponseCode();
        if (httpRespCode != expectedHttpRespCode) {
            log.info("HTTP response from OCSP request was " + httpRespCode + ". Expected "
                    + expectedHttpRespCode);
            handleContentOfErrorStream(con.getErrorStream());
            return null; // if it is an http error code we don't need to test any more
        }

        InputStream is = con.getInputStream();
        response = new OCSPResp(IOUtils.toByteArray(is));
        is.close();

    } catch (IOException e) {
        log.info("Unable to get an OCSP response. " + e.getLocalizedMessage());
        if (con != null) {
            handleContentOfErrorStream(con.getErrorStream());
        }
        return null;
    }

    // ------------ Verify the response signature --------------//
    BasicOCSPResp brep = null;
    try {
        brep = (BasicOCSPResp) response.getResponseObject();

        if ((expectedOcspRespCode != OCSPRespBuilder.SUCCESSFUL) && (brep != null)) {
            log.warn("According to RFC 2560, responseBytes are not set on error, but we got some.");
            return null; // it messes up testing of invalid signatures... but is needed for the unsuccessful responses
        }

        if (brep == null) {
            log.warn("Cannot extract OCSP response object. OCSP response status: " + response.getStatus());
            return null;
        }

        X509CertificateHolder[] chain = brep.getCerts();
        boolean verify = brep.isSignatureValid(new JcaContentVerifierProviderBuilder()
                .setProvider(BouncyCastleProvider.PROVIDER_NAME).build(chain[0]));
        if (!verify) {
            log.warn("OCSP response signature was not valid");
            return null;
        }
    } catch (OCSPException | OperatorCreationException | CertificateException e) {
        if (log.isDebugEnabled()) {
            log.debug("Failed to obtain or verify OCSP response. " + e.getLocalizedMessage());
        }
        return null;
    }

    // ------------- Verify the nonce ---------------//
    byte[] noncerep;
    try {
        noncerep = brep.getExtension(OCSPObjectIdentifiers.id_pkix_ocsp_nonce).getExtnValue().getEncoded();
    } catch (IOException e) {
        if (log.isDebugEnabled()) {
            log.debug("Failed to read extension from OCSP response. " + e.getLocalizedMessage());
        }
        return null;
    }
    if (noncerep == null) {
        log.warn("Sent an OCSP request containing a nonce, but the OCSP response does not contain a nonce");
        return null;
    }

    try {
        ASN1InputStream ain = new ASN1InputStream(noncerep);
        ASN1OctetString oct = ASN1OctetString.getInstance(ain.readObject());
        ain.close();
        if (!Arrays.equals(nonce, oct.getOctets())) {
            log.warn("The nonce in the OCSP request and the OCSP response do not match");
            return null;
        }
    } catch (IOException e) {
        if (log.isDebugEnabled()) {
            log.debug("Failed to read extension from OCSP response. " + e.getLocalizedMessage());
        }
        return null;
    }

    // ------------ Extract the single response and verify that it concerns a cert with the right serialnumber ----//
    SingleResp[] singleResps = brep.getResponses();
    if ((singleResps == null) || (singleResps.length == 0)) {
        if (log.isDebugEnabled()) {
            log.debug("The OCSP response object contained no responses.");
        }
        return null;
    }

    SingleResp singleResponse = singleResps[0];
    CertificateID certId = singleResponse.getCertID();
    if (!certId.getSerialNumber().equals(CertTools.getSerialNumber(cert))) {
        if (log.isDebugEnabled()) {
            log.debug(
                    "Certificate serialnumber in response does not match certificate serialnumber in request.");
        }
        return null;
    }

    // ------------ Return the single response ---------------//
    return singleResponse;
}

From source file:org.ejbca.core.protocol.ocsp.OcspJunitHelper.java

License:Open Source License

/**
 *
 * @param ocspPackage/* w w w .j  ava2 s. co m*/
 * @param nonce
 * @param respCode expected response code, OK = 0, if not 0, response checking will not continue after response code is checked.
 * @param httpCode, normally 200 for OK or OCSP error. Can be 400 is more than 1 million bytes is sent for example
 * @return a SingleResp or null if respCode != 0
 * @throws IOException
 * @throws OCSPException
 * @throws NoSuchProviderException
 * @throws CertificateException on parsing errors.
 * @throws OperatorCreationException 
 */
protected SingleResp[] sendOCSPPost(byte[] ocspPackage, String nonce, int respCode, int httpCode)
        throws IOException, OCSPException, NoSuchProviderException, OperatorCreationException,
        CertificateException {
    // POST the OCSP request
    URL url = new URL(this.sBaseURL + this.urlEnding);
    HttpURLConnection con = (HttpURLConnection) url.openConnection();
    // we are going to do a POST
    con.setDoOutput(true);
    con.setRequestMethod("POST");

    // POST it
    con.setRequestProperty("Content-Type", "application/ocsp-request");
    OutputStream os = con.getOutputStream();
    os.write(ocspPackage);
    os.close();
    assertEquals("Response code", httpCode, con.getResponseCode());
    if (con.getResponseCode() != 200) {
        return null; // if it is an http error code we don't need to test any more
    }
    // Some appserver (Weblogic) responds with "application/ocsp-response; charset=UTF-8"
    assertNotNull("No Content-Type in reply.", con.getContentType());
    assertTrue(con.getContentType().startsWith("application/ocsp-response"));
    OCSPResp response = new OCSPResp(IOUtils.toByteArray(con.getInputStream()));
    assertEquals("Response status not the expected.", respCode, response.getStatus());
    if (respCode != 0) {
        assertNull("According to RFC 2560, responseBytes are not set on error.", response.getResponseObject());
        return null; // it messes up testing of invalid signatures... but is needed for the unsuccessful responses
    }
    BasicOCSPResp brep = (BasicOCSPResp) response.getResponseObject();
    X509CertificateHolder[] chain = brep.getCerts();
    assertNotNull(
            "No certificate chain returned in response (chain == null), is ocsp.includesignercert=false in ocsp.properties?. It should be set to default value for test to run.",
            chain);
    boolean verify = brep.isSignatureValid(new JcaContentVerifierProviderBuilder().build(chain[0]));
    assertTrue("Response failed to verify.", verify);
    // Check nonce (if we sent one)
    if (nonce != null) {
        byte[] noncerep = brep.getExtension(OCSPObjectIdentifiers.id_pkix_ocsp_nonce).getExtnValue()
                .getEncoded();
        assertNotNull(noncerep);
        ASN1InputStream ain = new ASN1InputStream(noncerep);
        ASN1OctetString oct = ASN1OctetString.getInstance(ain.readObject());
        ain.close();
        assertEquals(nonce, new String(oct.getOctets()));
    }
    SingleResp[] singleResps = brep.getResponses();
    return singleResps;
}

From source file:org.ejbca.core.protocol.ocsp.OcspJunitHelper.java

License:Open Source License

/**
 *
 * @param ocspPackage/*from w  ww .j  a  va  2  s.c  om*/
 * @param nonce
 * @param respCode expected response code, OK = 0, if not 0, response checking will not continue after response code is checked.
 * @param httpCode, normally 200 for OK or OCSP error. Can be 400 is more than 1 million bytes is sent for example
 * @return a BasicOCSPResp or null if not found
 * @throws IOException
 * @throws OCSPException
 * @throws NoSuchProviderException
 * @throws NoSuchAlgorithmException
 * @throws CertificateException on parsing errors.
 * @throws OperatorCreationException 
 */
protected BasicOCSPResp sendOCSPGet(byte[] ocspPackage, String nonce, int respCode, int httpCode,
        boolean shouldIncludeSignCert, X509Certificate signCert) throws IOException, OCSPException,
        NoSuchProviderException, NoSuchAlgorithmException, OperatorCreationException, CertificateException {
    // GET the OCSP request
    String b64 = new String(Base64.encode(ocspPackage, false));
    //String urls = URLEncoder.encode(b64, "UTF-8");   // JBoss/Tomcat will not accept escaped '/'-characters by default
    URL url = new URL(this.sBaseURL + '/' + b64 + this.urlEnding);
    HttpURLConnection con = (HttpURLConnection) url.openConnection();
    if (con.getResponseCode() != httpCode) {
        log.info("URL when request gave unexpected result: " + url.toString() + " Message was: "
                + con.getResponseMessage());
    }
    assertEquals("Response code did not match. ", httpCode, con.getResponseCode());
    if (con.getResponseCode() != 200) {
        return null; // if it is an http error code we don't need to test any more
    }
    // Some appserver (Weblogic) responds with "application/ocsp-response; charset=UTF-8"
    assertNotNull(con.getContentType());
    assertTrue(con.getContentType().startsWith("application/ocsp-response"));
    OCSPResp response = new OCSPResp(IOUtils.toByteArray(con.getInputStream()));
    assertNotNull("Response should not be null.", response);
    assertEquals("Response status not the expected.", respCode, response.getStatus());
    if (respCode != 0) {
        assertNull("According to RFC 2560, responseBytes are not set on error.", response.getResponseObject());
        return null; // it messes up testing of invalid signatures... but is needed for the unsuccessful responses
    }
    BasicOCSPResp brep = (BasicOCSPResp) response.getResponseObject();

    final X509CertificateHolder signCertHolder;
    if (!shouldIncludeSignCert) {
        assertEquals("The signing certificate should not be included in the OCSP response ", 0,
                brep.getCerts().length);
        signCertHolder = new JcaX509CertificateHolder(signCert);
    } else {
        X509CertificateHolder[] chain = brep.getCerts();
        signCertHolder = chain[0];
    }
    boolean verify = brep.isSignatureValid(new JcaContentVerifierProviderBuilder().build(signCertHolder));

    assertTrue("Response failed to verify.", verify);
    // Check nonce (if we sent one)
    if (nonce != null) {
        byte[] noncerep = brep.getExtension(OCSPObjectIdentifiers.id_pkix_ocsp_nonce).getExtnValue()
                .getEncoded();
        assertNotNull(noncerep);
        ASN1InputStream ain = new ASN1InputStream(noncerep);
        ASN1OctetString oct = ASN1OctetString.getInstance(ain.readObject());
        ain.close();
        assertEquals(nonce, new String(oct.getOctets()));
    }
    return brep;
}

From source file:org.ejbca.core.protocol.ocsp.OCSPUnidClient.java

License:Open Source License

private OCSPUnidResponse sendOCSPRequest(byte[] ocspPackage, X509Certificate knownTrustAnchor, boolean useGet)
        throws IOException, OCSPException, OperatorCreationException, CertificateException,
        UnrecoverableKeyException, KeyManagementException, NoSuchAlgorithmException, KeyStoreException {
    final HttpURLConnection con;
    if (useGet) {
        String b64 = new String(Base64.encode(ocspPackage, false));
        URL url = new URL(httpReqPath + '/' + b64);
        con = (HttpURLConnection) url.openConnection();
    } else {//ww  w .  j  a v a  2 s  . c  om
        // POST the OCSP request
        URL url = new URL(httpReqPath);
        con = (HttpURLConnection) getUrlConnection(url);
        // we are going to do a POST
        con.setDoOutput(true);
        con.setRequestMethod("POST");
        // POST it
        con.setRequestProperty("Content-Type", "application/ocsp-request");
        OutputStream os = null;
        try {
            os = con.getOutputStream();
            os.write(ocspPackage);
        } finally {
            if (os != null) {
                os.close();
            }
        }
    }
    final OCSPUnidResponse ret = new OCSPUnidResponse();
    ret.setHttpReturnCode(con.getResponseCode());
    if (ret.getHttpReturnCode() != 200) {
        if (ret.getHttpReturnCode() == 401) {
            ret.setErrorCode(OCSPUnidResponse.ERROR_UNAUTHORIZED);
        } else {
            ret.setErrorCode(OCSPUnidResponse.ERROR_UNKNOWN);
        }
        return ret;
    }
    final OCSPResp response;
    {
        final InputStream in = con.getInputStream();
        if (in != null) {
            try {
                response = new OCSPResp(IOUtils.toByteArray(in));
            } finally {
                in.close();
            }
        } else {
            response = null;
        }
    }
    if (response == null) {
        ret.setErrorCode(OCSPUnidResponse.ERROR_NO_RESPONSE);
        return ret;
    }
    ret.setResp(response);
    final BasicOCSPResp brep = (BasicOCSPResp) response.getResponseObject();
    if (brep == null) {
        ret.setErrorCode(OCSPUnidResponse.ERROR_NO_RESPONSE);
        return ret;
    }
    // Compare nonces to see if the server sent the same nonce as we sent
    final byte[] noncerep = brep.getExtension(OCSPObjectIdentifiers.id_pkix_ocsp_nonce).getExtnValue()
            .getEncoded();
    if (noncerep != null) {
        ASN1InputStream ain = new ASN1InputStream(noncerep);
        ASN1OctetString oct = ASN1OctetString.getInstance(ain.readObject());
        ain.close();
        boolean eq = ArrayUtils.isEquals(this.nonce, oct.getOctets());
        if (!eq) {
            ret.setErrorCode(OCSPUnidResponse.ERROR_INVALID_NONCE);
            return ret;
        }
    }

    final RespID id = brep.getResponderId();
    final DERTaggedObject to = (DERTaggedObject) id.toASN1Object().toASN1Primitive();
    final RespID respId;
    final X509CertificateHolder[] chain = brep.getCerts();
    JcaX509CertificateConverter converter = new JcaX509CertificateConverter();
    X509Certificate signerCertificate = converter.getCertificate(chain[0]);
    final PublicKey signerPub = signerCertificate.getPublicKey();
    if (to.getTagNo() == 1) {
        // This is Name
        respId = new JcaRespID(signerCertificate.getSubjectX500Principal());
    } else {
        // This is KeyHash
        respId = new JcaRespID(signerPub, SHA1DigestCalculator.buildSha1Instance());
    }
    if (!id.equals(respId)) {
        // Response responderId does not match signer certificate responderId!
        ret.setErrorCode(OCSPUnidResponse.ERROR_INVALID_SIGNERID);
    }
    if (!brep.isSignatureValid(new JcaContentVerifierProviderBuilder().build(signerPub))) {
        ret.setErrorCode(OCSPUnidResponse.ERROR_INVALID_SIGNATURE);
        return ret;
    }

    /* 
     * Okay, at this point we have three different variables and six different possible valid use cases. These
     * variables are:
     *          1. If the OCSP reply is from a CA (integrated) or an OCSP responder (standalone) 
     *          2. If it was from a CA, then if that CA is self signed or a subCA
     *          3. If the server (in the integrated case) or keybinding (standalone case) was set to include the certificate chain
     */

    //If we have a chain, verify it
    if (chain.length > 1) {
        // end at one shortof chain.length, because the root certificate is (usually) not included in the OCSP response
        // TODO: improve this when we can pass in the root cert from parameter to properly validate the whole chain
        for (int i = 0; i + 1 < chain.length; i++) {
            final X509Certificate cert1 = converter.getCertificate(chain[i]);
            final X509Certificate cert2 = converter.getCertificate(chain[Math.min(i + 1, chain.length - 1)]);
            try {
                cert1.verify(cert2.getPublicKey());
            } catch (GeneralSecurityException e) {
                m_log.info("Verifying problem with", e);
                m_log.info("Certificate to be verified: " + cert1);
                m_log.info("Verifying certificate: " + cert2);
                ret.setErrorCode(OCSPUnidResponse.ERROR_INVALID_SIGNERCERT);
                return ret;
            }
        }
    }

    if (CertTools.isCA(signerCertificate)) {
        //Verify that the signer certificate was the same as the trust anchor
        if (!signerCertificate.getSerialNumber().equals(knownTrustAnchor.getSerialNumber())) {
            m_log.info("Signing certificate for integrated OCSP was not the provided trust anchor.");
            ret.setErrorCode(OCSPUnidResponse.ERROR_INVALID_SIGNERCERT);
            return ret;
        }
    } else if (CertTools.isOCSPCert(signerCertificate)) {
        //If an OCSP certificate was used to sign
        try {
            signerCertificate.verify(knownTrustAnchor.getPublicKey());
        } catch (GeneralSecurityException e) {
            m_log.info("Signing certificate was not signed by known trust anchor.");
            ret.setErrorCode(OCSPUnidResponse.ERROR_INVALID_SIGNERCERT);
            return ret;
        }
    } else {
        m_log.info("Signing certificate was not an OCSP certificate.");
        ret.setErrorCode(OCSPUnidResponse.ERROR_INVALID_SIGNERCERT);
        return ret;
    }

    String fnr = getFnr(brep);
    if (fnr != null) {
        ret.setFnr(fnr);
    }
    return ret;
}

From source file:org.ejbca.core.protocol.ocsp.ProtocolLookupServerHttpTest.java

License:Open Source License

private BasicOCSPResp sendOCSPPost(byte[] ocspPackage, boolean trust)
        throws IOException, OCSPException, GeneralSecurityException, OperatorCreationException {
    // POST the OCSP request
    URL url = new URL(httpReqPath + '/' + resourceOcsp);
    HttpURLConnection con = (HttpURLConnection) getUrlConnection(url, trust);
    // we are going to do a POST
    con.setDoOutput(true);//from w ww  .j a v  a 2  s .  c om
    con.setRequestMethod("POST");

    // POST it
    con.setRequestProperty("Content-Type", "application/ocsp-request");
    OutputStream os = con.getOutputStream();
    os.write(ocspPackage);
    os.close();
    assertEquals("Response code", 200, con.getResponseCode());
    assertEquals("Content-Type", "application/ocsp-response", con.getContentType());
    ByteArrayOutputStream baos = new ByteArrayOutputStream();
    // This works for small requests, and OCSP requests are small
    InputStream in = con.getInputStream();
    int b = in.read();
    while (b != -1) {
        baos.write(b);
        b = in.read();
    }
    baos.flush();
    in.close();
    byte[] respBytes = baos.toByteArray();
    OCSPResp response = new OCSPResp(respBytes);
    assertEquals("Response status not zero.", response.getStatus(), 0);
    BasicOCSPResp brep = (BasicOCSPResp) response.getResponseObject();
    X509CertificateHolder[] chain = brep.getCerts();
    boolean verify = brep.isSignatureValid(new JcaContentVerifierProviderBuilder().build(chain[0]));
    assertTrue("Response failed to verify.", verify);
    return brep;
}

From source file:org.ejbca.core.protocol.ocsp.ProtocolOcspHttpPerfTest.java

License:Open Source License

private SingleResp sendOCSPPost(byte[] ocspPackage, String nonce) throws IOException, OCSPException,
        NoSuchProviderException, OperatorCreationException, CertificateException {
    // POST the OCSP request
    URL url = new URL(httpReqPath + '/' + resourceOcsp);
    HttpURLConnection con = (HttpURLConnection) url.openConnection();
    // we are going to do a POST
    con.setDoOutput(true);//from  ww w  .  j a  v a  2 s .  co  m
    con.setRequestMethod("POST");

    // POST it
    con.setRequestProperty("Content-Type", "application/ocsp-request");
    OutputStream os = con.getOutputStream();
    os.write(ocspPackage);
    os.close();
    assertEquals("Response code", 200, con.getResponseCode());
    assertEquals("Content-Type", "application/ocsp-response", con.getContentType());
    ByteArrayOutputStream baos = new ByteArrayOutputStream();
    // This works for small requests, and OCSP requests are small
    InputStream in = con.getInputStream();
    int b = in.read();
    while (b != -1) {
        baos.write(b);
        b = in.read();
    }
    baos.flush();
    in.close();
    byte[] respBytes = baos.toByteArray();
    OCSPResp response = new OCSPResp(respBytes);
    assertEquals("Response status not zero.", response.getStatus(), 0);
    BasicOCSPResp brep = (BasicOCSPResp) response.getResponseObject();
    X509CertificateHolder[] chain = brep.getCerts();
    boolean verify = brep.isSignatureValid(new JcaContentVerifierProviderBuilder().build(chain[0]));
    assertTrue("Response failed to verify.", verify);
    // Check nonce (if we sent one)
    if (nonce != null) {
        byte[] noncerep = brep.getExtension(OCSPObjectIdentifiers.id_pkix_ocsp_nonce).getExtnValue()
                .getEncoded();
        assertNotNull(noncerep);
        ASN1InputStream ain = new ASN1InputStream(noncerep);
        ASN1OctetString oct = ASN1OctetString.getInstance(ain.readObject());
        ain.close();
        assertEquals(nonce, new String(oct.getOctets()));
    }
    SingleResp[] singleResps = brep.getResponses();
    assertEquals("No of SingResps should be 1.", singleResps.length, 1);
    SingleResp singleResp = singleResps[0];
    return singleResp;
}

From source file:org.ejbca.core.protocol.ocsp.ProtocolOcspHttpStandaloneTest.java

License:Open Source License

private void testVerifyHttpGetHeaders(X509Certificate caCertificate, BigInteger serialNumber) throws Exception {
    // An OCSP request, ocspTestCert is already created in earlier tests
    OCSPReqBuilder gen = new OCSPReqBuilder();
    gen.addRequest(new JcaCertificateID(SHA1DigestCalculator.buildSha1Instance(), caCertificate, serialNumber));
    OCSPReq req = gen.build();/* w w  w .  j  av  a 2s .  com*/
    String reqString = new String(Base64.encode(req.getEncoded(), false));
    URL url = new URL(httpReqPath + '/' + resourceOcsp + '/' + URLEncoder.encode(reqString, "UTF-8"));
    log.debug("OCSP Request: " + url.toExternalForm());
    HttpURLConnection con = (HttpURLConnection) url.openConnection();
    assertEquals(
            "Response code did not match. (Make sure you allow encoded slashes in your appserver.. add -Dorg.apache.tomcat.util.buf.UDecoder.ALLOW_ENCODED_SLASH=true in Tomcat)",
            200, con.getResponseCode());
    // Some appserver (Weblogic) responds with
    // "application/ocsp-response; charset=UTF-8"
    assertNotNull(con.getContentType());
    assertTrue(con.getContentType().startsWith("application/ocsp-response"));
    OCSPResp response = new OCSPResp(IOUtils.toByteArray(con.getInputStream()));
    assertEquals("Response status not the expected.", OCSPRespBuilder.SUCCESSFUL, response.getStatus());
    BasicOCSPResp brep = (BasicOCSPResp) response.getResponseObject();
    // Just output the headers to stdout so we can visually inspect them if
    // something goes wrong
    Set<String> keys = con.getHeaderFields().keySet();
    for (String field : keys) {
        List<String> values = con.getHeaderFields().get(field);
        for (String value : values) {
            log.info(field + ": " + value);
        }
    }
    String eTag = con.getHeaderField("ETag");
    assertNotNull(
            "RFC 5019 6.2: No 'ETag' HTTP header present as it SHOULD. (Make sure ocsp.untilNextUpdate and ocsp.maxAge are configured for this test)",
            eTag);
    assertTrue("ETag is messed up.",
            ("\"" + new String(
                    Hex.encode(MessageDigest.getInstance("SHA-1", "BC").digest(response.getEncoded()))) + "\"")
                            .equals(eTag));
    long date = con.getHeaderFieldDate("Date", -1);
    assertTrue("RFC 5019 6.2: No 'Date' HTTP header present as it SHOULD.", date != -1);
    long lastModified = con.getHeaderFieldDate("Last-Modified", -1);
    assertTrue("RFC 5019 6.2: No 'Last-Modified' HTTP header present as it SHOULD.", lastModified != -1);
    // assertTrue("Last-Modified is after response was sent",
    // lastModified<=date); This will not hold on JBoss AS due to the
    // caching of the Date-header
    long expires = con.getExpiration();
    assertTrue("Expires is before response was sent", expires >= date);
    assertTrue("RFC 5019 6.2: No 'Expires' HTTP header present as it SHOULD.", expires != 0);
    String cacheControl = con.getHeaderField("Cache-Control");
    assertNotNull("RFC 5019 6.2: No 'Cache-Control' HTTP header present as it SHOULD.", cacheControl);
    assertTrue("RFC 5019 6.2: No 'public' HTTP header Cache-Control present as it SHOULD.",
            cacheControl.contains("public"));
    assertTrue("RFC 5019 6.2: No 'no-transform' HTTP header Cache-Control present as it SHOULD.",
            cacheControl.contains("no-transform"));
    assertTrue("RFC 5019 6.2: No 'must-revalidate' HTTP header Cache-Control present as it SHOULD.",
            cacheControl.contains("must-revalidate"));
    Matcher matcher = Pattern.compile(".*max-age\\s*=\\s*(\\d+).*").matcher(cacheControl);
    assertTrue("RFC 5019 6.2: No 'max-age' HTTP header Cache-Control present as it SHOULD.", matcher.matches());
    int maxAge = Integer.parseInt(matcher.group(1));
    log.debug("maxAge=" + maxAge + " (expires-lastModified)/1000=" + ((expires - lastModified) / 1000));
    assertTrue(
            "thisUpdate and nextUpdate should not be the same (Make sure ocsp.untilNextUpdate and ocsp.maxAge are configured for this test)",
            expires != lastModified);
    assertTrue("RFC 5019 6.2: [maxAge] SHOULD be 'later than thisUpdate but earlier than nextUpdate'.",
            maxAge < (expires - lastModified) / 1000);
    // assertTrue("Response cannot be produced after it was sent.",
    // brep.getProducedAt().getTime() <= date); This might not hold on JBoss
    // AS due to the caching of the Date-header
    X509CertificateHolder[] chain = brep.getCerts();
    boolean verify = brep.isSignatureValid(new JcaContentVerifierProviderBuilder().build(chain[0]));
    assertTrue("Response failed to verify.", verify);
    assertNull("No nonce should be present.", brep.getExtension(OCSPObjectIdentifiers.id_pkix_ocsp_nonce));
    SingleResp[] singleResps = brep.getResponses();
    assertNotNull("SingleResps should not be null.", singleResps);
    assertTrue("Expected a single SingleResp in the repsonse.", singleResps.length == 1);
    assertEquals("Serno in response does not match serno in request.",
            singleResps[0].getCertID().getSerialNumber(), serialNumber);
    assertEquals("Status is not null (null is 'good')", singleResps[0].getCertStatus(), null);
    assertTrue(
            "RFC 5019 6.2: Last-Modified SHOULD 'be the same as the thisUpdate timestamp in the request itself'",
            singleResps[0].getThisUpdate().getTime() == lastModified);
    assertTrue("RFC 5019 6.2: Expires SHOULD 'be the same as the nextUpdate timestamp in the request itself'",
            singleResps[0].getNextUpdate().getTime() == expires);
    assertTrue("Response cannot be produced before it was last modified..",
            brep.getProducedAt().getTime() >= singleResps[0].getThisUpdate().getTime());
}

From source file:org.ejbca.core.protocol.ocsp.ProtocolOcspHttpStandaloneTest.java

License:Open Source License

private void testNextUpdateThisUpdate(X509Certificate caCertificate, BigInteger serialNumber) throws Exception {
    // And an OCSP request
    OCSPReqBuilder gen = new OCSPReqBuilder();
    gen.addRequest(new JcaCertificateID(SHA1DigestCalculator.buildSha1Instance(), caCertificate, serialNumber));
    OCSPReq req = gen.build();// w w  w  .  j a  v a 2s  .  c  o  m
    // POST the request and receive a singleResponse
    URL url = new URL(httpReqPath + '/' + resourceOcsp);
    HttpURLConnection con = (HttpURLConnection) url.openConnection();
    con.setDoOutput(true);
    con.setRequestMethod("POST");
    con.setRequestProperty("Content-Type", "application/ocsp-request");
    OutputStream os = con.getOutputStream();
    os.write(req.getEncoded());
    os.close();
    assertEquals("Response code", 200, con.getResponseCode());
    // Some appserver (Weblogic) responds with
    // "application/ocsp-response; charset=UTF-8"
    assertNotNull(con.getContentType());
    assertTrue(con.getContentType().startsWith("application/ocsp-response"));
    OCSPResp response = new OCSPResp(IOUtils.toByteArray(con.getInputStream()));
    assertEquals("Response status not the expected.", 0, response.getStatus());
    BasicOCSPResp brep = (BasicOCSPResp) response.getResponseObject();
    X509CertificateHolder[] chain = brep.getCerts();
    boolean verify = brep.isSignatureValid(new JcaContentVerifierProviderBuilder().build(chain[0]));
    assertTrue("Response failed to verify.", verify);
    SingleResp[] singleResps = brep.getResponses();
    assertEquals("No of SingResps should be 1.", 1, singleResps.length);
    CertificateID certId = singleResps[0].getCertID();
    assertEquals("Serno in response does not match serno in request.", certId.getSerialNumber(), serialNumber);
    assertNull("Status is not null.", singleResps[0].getCertStatus());
    Date thisUpdate = singleResps[0].getThisUpdate();
    Date nextUpdate = singleResps[0].getNextUpdate();
    Date producedAt = brep.getProducedAt();
    assertNotNull("thisUpdate was not set.", thisUpdate);
    assertNotNull("nextUpdate was not set. (This test requires ocsp.untilNextUpdate to be configured.)",
            nextUpdate);
    assertNotNull("producedAt was not set.", producedAt);
    assertTrue("nextUpdate cannot be before thisUpdate.", !nextUpdate.before(thisUpdate));
    assertTrue("producedAt cannot be before thisUpdate.", !producedAt.before(thisUpdate));
}

From source file:org.ejbca.core.protocol.ocsp.ProtocolOcspHttpTest.java

License:Open Source License

/**
 * Verify that Internal OCSP responses are signed by CA signing key.
 *//*from w w w.  ja v  a2  s . c  om*/
@Test
public void test17OCSPResponseSignature() throws Exception {

    // Get user and ocspTestCert that we know...
    loadUserCert(caid);
    this.helper.reloadKeys();
    // And an OCSP request
    OCSPReqBuilder gen = new OCSPReqBuilder();
    gen.addRequest(new JcaCertificateID(SHA1DigestCalculator.buildSha1Instance(), cacert,
            ocspTestCert.getSerialNumber()));
    Extension[] extensions = new Extension[1];
    extensions[0] = new Extension(OCSPObjectIdentifiers.id_pkix_ocsp_nonce, false,
            new DEROctetString("123456789".getBytes()));
    gen.setRequestExtensions(new Extensions(extensions));
    OCSPReq req = gen.build();

    // POST the OCSP request
    URL url = new URL(httpReqPath + '/' + resourceOcsp);
    HttpURLConnection con = (HttpURLConnection) url.openConnection();
    // we are going to do a POST
    con.setDoOutput(true);
    con.setRequestMethod("POST");

    // POST it
    con.setRequestProperty("Content-Type", "application/ocsp-request");
    OutputStream os = con.getOutputStream();
    os.write(req.getEncoded());
    os.close();
    assertTrue("HTTP error", con.getResponseCode() == 200);

    // Some appserver (Weblogic) responds with
    // "application/ocsp-response; charset=UTF-8"
    assertNotNull("No Content-Type in reply.", con.getContentType());
    assertTrue(con.getContentType().startsWith("application/ocsp-response"));
    OCSPResp response = new OCSPResp(IOUtils.toByteArray(con.getInputStream()));
    assertTrue("Response status not the expected.", response.getStatus() != 200);

    BasicOCSPResp brep = (BasicOCSPResp) response.getResponseObject();
    boolean verify = brep
            .isSignatureValid(new JcaContentVerifierProviderBuilder().build(cacert.getPublicKey()));
    assertTrue("Signature verification", verify);
}

From source file:org.jivesoftware.openfire.net.OCSPChecker.java

License:Open Source License

@Override
public void check(Certificate cert, Collection<String> unresolvedCritExts) throws CertPathValidatorException {
    Log.debug("OCSPChecker: check called");
    InputStream in = null;//from  ww w .  j  ava2s.c  o  m
    OutputStream out = null;
    try {
        // Examine OCSP properties
        X509Certificate responderCert = null;
        boolean haveResponderCert = true; //defaults to issuers cert
        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 = (X509Certificate) (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);
            }
        }
    }
}