Package org.ejbca.core.protocol.ocsp

Source Code of org.ejbca.core.protocol.ocsp.OcspJunitHelper

package org.ejbca.core.protocol.ocsp;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.security.NoSuchAlgorithmException;
import java.security.NoSuchProviderException;
import java.security.cert.X509Certificate;

import junit.framework.TestCase;

import org.apache.log4j.Logger;
import org.bouncycastle.asn1.ASN1InputStream;
import org.bouncycastle.asn1.ASN1OctetString;
import org.bouncycastle.asn1.ocsp.OCSPObjectIdentifiers;
import org.bouncycastle.ocsp.BasicOCSPResp;
import org.bouncycastle.ocsp.OCSPException;
import org.bouncycastle.ocsp.OCSPResp;
import org.bouncycastle.ocsp.SingleResp;
import org.ejbca.util.Base64;

public class OcspJunitHelper extends TestCase {
 
  private static Logger log = Logger.getLogger(OcspJunitHelper.class);

  private String httpReqPath = "";
  private String resourceOcsp = "";
 
  public OcspJunitHelper(String httpReqPath, String resourceOcsp) {
    this.httpReqPath = httpReqPath;
    this.resourceOcsp = resourceOcsp;
  }
 
  /**
   *
   * @param ocspPackage
   * @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
   */
    protected SingleResp[] sendOCSPPost(byte[] ocspPackage, String nonce, int respCode, int httpCode) throws IOException, OCSPException, NoSuchProviderException {
        // 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(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(new ByteArrayInputStream(inputStreamToBytes(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.", (BasicOCSPResp) response.getResponseObject());
            return null; // it messes up testing of invalid signatures... but is needed for the unsuccessful responses
        }
        BasicOCSPResp brep = (BasicOCSPResp) response.getResponseObject();
        X509Certificate[] chain = brep.getCerts("BC");
        boolean verify = brep.verify(chain[0].getPublicKey(), "BC");
        assertTrue("Response failed to verify.", verify);
        // Check nonce (if we sent one)
        if (nonce != null) {
          byte[] noncerep = brep.getExtensionValue(OCSPObjectIdentifiers.id_pkix_ocsp_nonce.getId());
          assertNotNull(noncerep);
          ASN1InputStream ain = new ASN1InputStream(noncerep);
          ASN1OctetString oct = ASN1OctetString.getInstance(ain.readObject());
          assertEquals(nonce, new String(oct.getOctets()));
        }
        SingleResp[] singleResps = brep.getResponses();
        return singleResps;
    }
   
  /**
   *
   * @param ocspPackage
   * @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 NoSuchAlgorithmException
   */
    protected SingleResp[] sendOCSPGet(byte[] ocspPackage, String nonce, int respCode, int httpCode) throws IOException, OCSPException, NoSuchProviderException, NoSuchAlgorithmException {
        // 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(httpReqPath + '/' + resourceOcsp + '/' + b64);
        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(new ByteArrayInputStream(inputStreamToBytes(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.", (BasicOCSPResp) response.getResponseObject());
            return null; // it messes up testing of invalid signatures... but is needed for the unsuccessful responses
        }
        BasicOCSPResp brep = (BasicOCSPResp) response.getResponseObject();
        X509Certificate[] chain = brep.getCerts("BC");
        boolean verify = brep.verify(chain[0].getPublicKey(), "BC");
        assertTrue("Response failed to verify.", verify);
        // Check nonce (if we sent one)
        if (nonce != null) {
          byte[] noncerep = brep.getExtensionValue(OCSPObjectIdentifiers.id_pkix_ocsp_nonce.getId());
          assertNotNull(noncerep);
          ASN1InputStream ain = new ASN1InputStream(noncerep);
          ASN1OctetString oct = ASN1OctetString.getInstance(ain.readObject());
          assertEquals(nonce, new String(oct.getOctets()));
        }
        SingleResp[] singleResps = brep.getResponses();
        return singleResps;
    }
   
    protected void reloadKeys() throws IOException, OCSPException, NoSuchProviderException {
        URL url = new URL(httpReqPath + '/' + resourceOcsp+"?reloadkeys=true");
        HttpURLConnection con = (HttpURLConnection)url.openConnection();
        assertEquals("Response code", 200, con.getResponseCode());
        con.disconnect();
    }

    /**
     * For small streams only.
     */
    static byte[] inputStreamToBytes(InputStream in) throws IOException {
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        int b = in.read();
        while (b != -1) {
          baos.write(b);
          b = in.read();
        }
        baos.flush();
        in.close();
        return  baos.toByteArray();
    }
}
TOP

Related Classes of org.ejbca.core.protocol.ocsp.OcspJunitHelper

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.