org.ejbca.extra.ra.ProtocolScepHttpTest.java Source code

Java tutorial

Introduction

Here is the source code for org.ejbca.extra.ra.ProtocolScepHttpTest.java

Source

/*************************************************************************
 *                                                                       *
 *  EJBCA: The OpenSource Certificate Authority                          *
 *                                                                       *
 *  This software is free software; you can redistribute it and/or       *
 *  modify it under the terms of the GNU Lesser General Public           *
 *  License as published by the Free Software Foundation; either         *
 *  version 2.1 of the License, or any later version.                    *
 *                                                                       *
 *  See terms of license at gnu.org.                                     *
 *                                                                       *
 *************************************************************************/

package org.ejbca.extra.ra;

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.net.URLEncoder;
import java.security.InvalidAlgorithmParameterException;
import java.security.InvalidKeyException;
import java.security.KeyPair;
import java.security.NoSuchAlgorithmException;
import java.security.NoSuchProviderException;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.Signature;
import java.security.SignatureException;
import java.security.cert.CRLException;
import java.security.cert.CertStore;
import java.security.cert.CertStoreException;
import java.security.cert.CertificateEncodingException;
import java.security.cert.CertificateException;
import java.security.cert.X509CRL;
import java.security.cert.X509Certificate;
import java.util.Collection;
import java.util.Iterator;

import junit.framework.TestCase;
import junit.framework.TestSuite;

import org.apache.log4j.Logger;
import org.bouncycastle.asn1.ASN1OctetString;
import org.bouncycastle.asn1.ASN1Set;
import org.bouncycastle.asn1.DERObjectIdentifier;
import org.bouncycastle.asn1.DERPrintableString;
import org.bouncycastle.asn1.DERString;
import org.bouncycastle.asn1.cms.Attribute;
import org.bouncycastle.asn1.cms.AttributeTable;
import org.bouncycastle.cms.CMSEnvelopedData;
import org.bouncycastle.cms.CMSException;
import org.bouncycastle.cms.CMSProcessable;
import org.bouncycastle.cms.CMSSignedData;
import org.bouncycastle.cms.CMSSignedGenerator;
import org.bouncycastle.cms.RecipientInformation;
import org.bouncycastle.cms.RecipientInformationStore;
import org.bouncycastle.cms.SignerId;
import org.bouncycastle.cms.SignerInformation;
import org.bouncycastle.cms.SignerInformationStore;
import org.bouncycastle.util.encoders.Base64;
import org.ejbca.core.model.AlgorithmConstants;
import org.ejbca.core.protocol.ResponseStatus;
import org.ejbca.core.protocol.scep.ScepRequestMessage;
import org.ejbca.util.CertTools;
import org.ejbca.util.CryptoProviderTools;
import org.ejbca.util.keystore.KeyTools;

/**
 * Tests SCEP enrollment with an RA (SCEP polling RA mode).
 * This test assumes a CA hierarchy. One root CA AdminCA1 and one sub CA ScepCA.
 * 
 * @version $Id: ProtocolScepHttpTest.java 9435 2010-07-14 15:18:39Z mikekushner $
 */
public class ProtocolScepHttpTest extends TestCase {
    private static Logger log = Logger.getLogger(ProtocolScepHttpTest.class);

    private static final String httpReqPath = "http://127.0.0.1:8080";
    private static final String resourceScep = "/scepraserver/scep/pkiclient.exe";
    private static final String resourceScepNoCA = "/scepraserver/scep/noca/pkiclient.exe";
    private static final String radn = "CN=Scep RA,O=PrimeKey,C=SE";
    private static final String cadn = "CN=Scep CA,O=EJBCA Sample,C=SE";
    private static final String rootcadn = "CN=AdminCA1,O=EJBCA Sample,C=SE";

    private static X509Certificate rootcacert = null;
    private static X509Certificate cacert = null;
    private static X509Certificate racert = null;
    private static KeyPair keys = null;

    private String transId = null;
    private String senderNonce = null;

    public static void main(String args[]) {
        junit.textui.TestRunner.run(suite());
    }

    public static TestSuite suite() {
        return new TestSuite(ProtocolScepHttpTest.class);
    }

    public ProtocolScepHttpTest(String name) throws Exception {
        super(name);
        // Install BouncyCastle provider
        CryptoProviderTools.installBCProvider();
        if (keys == null) {
            keys = KeyTools.genKeys("512", AlgorithmConstants.KEYALGORITHM_RSA);
        }
    }

    public void setUp() throws Exception {
    }

    public void tearDown() throws Exception {
    }

    // GetCACert and GetCACertChain behaves the same if it is an RA that responds
    public void test02ScepGetCACert() throws Exception {
        log.debug(">test02ScepGetCACert()");
        scepGetCACertChain("GetCACert", "application/x-x509-ca-ra-cert");
        log.debug(">test02ScepGetCACert()");
    }

    public void test03ScepGetCACertChain() throws Exception {
        log.debug(">test03ScepGetCACertChain()");
        scepGetCACertChain("GetCACertChain", "application/x-x509-ca-ra-cert-chain");
        log.debug(">test03ScepGetCACertChain()");
    }

    private void scepGetCACertChain(String method, String mimetype) throws Exception {
        String reqUrl = httpReqPath + '/' + resourceScepNoCA + "?operation=" + method + "&message=test";
        URL url = new URL(reqUrl);
        HttpURLConnection con = (HttpURLConnection) url.openConnection();
        con.setRequestMethod("GET");
        con.getDoOutput();
        con.connect();
        assertEquals("Response code", 200, con.getResponseCode());
        assertEquals("Content-Type", mimetype, con.getContentType());
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        // This works for small requests, and SCEP requests are small enough
        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();
        assertNotNull("Response can not be null.", respBytes);
        assertTrue(respBytes.length > 0);

        CMSSignedData s = new CMSSignedData(respBytes);
        assertNotNull(s);
        SignerInformationStore signers = s.getSignerInfos();
        Collection col = signers.getSigners();
        assertTrue(col.size() == 0);
        CertStore certstore = s.getCertificatesAndCRLs("Collection", "BC");
        Collection certs = certstore.getCertificates(null);
        // Length two if the Scep RA server is signed directly by a Root CA
        // Length three if the Scep RA server is signed by a CA which is signed by a Root CA
        assertEquals(3, certs.size());
        Iterator it = certs.iterator();
        racert = (X509Certificate) it.next();
        cacert = (X509Certificate) it.next();
        rootcacert = (X509Certificate) it.next();
        log.info("Got CA cert with DN: " + cacert.getSubjectDN().getName());
        assertEquals(cadn, cacert.getSubjectDN().getName());
        log.info("Got Root CA cert with DN: " + rootcacert.getSubjectDN().getName());
        assertEquals(rootcadn, rootcacert.getSubjectDN().getName());
        log.info("Got RA cert with DN: " + racert.getSubjectDN().getName());
        assertEquals(radn, racert.getSubjectDN().getName());
    }

    public void test04ScepGetCACaps() throws Exception {
        log.debug(">test04ScepGetCACaps()");
        String reqUrl = httpReqPath + '/' + resourceScep + "?operation=GetCACaps&message=test";
        URL url = new URL(reqUrl);
        HttpURLConnection con = (HttpURLConnection) url.openConnection();
        con.setRequestMethod("GET");
        con.getDoOutput();
        con.connect();
        assertEquals("Response code", 200, con.getResponseCode());
        assertEquals("Content-Type", "text/plain", con.getContentType());
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        // This works for small requests, and SCEP requests are small enough
        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();
        assertNotNull("Response can not be null.", respBytes);
        assertTrue(respBytes.length > 0);
        assertEquals(new String(respBytes), "POSTPKIOperation\nSHA-1");
        log.debug(">test04ScepGetCACaps()");
    }

    // This test will send a request and expect back a pending response.
    // It will then start polling the RA waiting for a real reply.
    // When polling it will accept a pending or a success reply
    public void test05ScepRequestOKSHA1() throws Exception {
        log.debug(">test05ScepRequestOKSHA1()");
        // send SCEP req to RA server and get pending request, until the request is processed on the CA
        // Then we will get a certificate response back    
        ScepRequestGenerator gen = new ScepRequestGenerator();
        byte[] msgBytes = genScepRequest(gen, CMSSignedGenerator.DIGEST_SHA1);
        // Send message with GET
        byte[] retMsg = sendScep(false, msgBytes, false);
        assertNotNull(retMsg);
        checkScepResponse(retMsg, senderNonce, transId, false, CMSSignedGenerator.DIGEST_SHA1, false,
                ResponseStatus.PENDING);
        // Send GetCertInitial and wait for a certificate response, you will probably get PENDING reply several times
        int keeprunning = 0;
        boolean processed = false;
        while ((keeprunning < 5) && !processed) {
            log.info("Waiting 5 secs...");
            Thread.sleep(5000); // wait 5 seconds between polls
            msgBytes = genScepGetCertInitial(gen, CMSSignedGenerator.DIGEST_SHA1);
            // Send message with GET
            retMsg = sendScep(false, msgBytes, false);
            assertNotNull(retMsg);
            if (isScepResponseMessageOfType(retMsg, ResponseStatus.PENDING)) {
                log.info("Received a PENDING message");
                checkScepResponse(retMsg, senderNonce, transId, false, CMSSignedGenerator.DIGEST_SHA1, false,
                        ResponseStatus.PENDING);
            } else {
                log.info("Received a SUCCESS message");
                checkScepResponse(retMsg, senderNonce, transId, false, CMSSignedGenerator.DIGEST_SHA1, false,
                        ResponseStatus.SUCCESS);
                processed = true;
            }
            keeprunning++;
        }
        assertTrue(processed);
        log.debug("<test05ScepRequestOKSHA1()");
    }

    // This test will send a request and expect back a pending response.
    // It will then start polling the RA waiting for a real reply.
    // When polling it will accept a pending or a success reply
    public void test06ScepRequestOKSHA1PostNoCA() throws Exception {
        log.debug(">test06ScepRequestOKSHA1PostNoCA()");
        // send SCEP req to RA server and get pending request, until the request is processed on the CA
        // Then we will get a certificate response back    
        ScepRequestGenerator gen = new ScepRequestGenerator();
        byte[] msgBytes = genScepRequest(gen, CMSSignedGenerator.DIGEST_SHA1);
        // Send message with POST
        byte[] retMsg = sendScep(true, msgBytes, true);
        assertNotNull(retMsg);
        checkScepResponse(retMsg, senderNonce, transId, false, CMSSignedGenerator.DIGEST_SHA1, true,
                ResponseStatus.PENDING);
        // Send GetCertInitial and wait for a certificate response, you will probably get PENDING reply several times
        int keeprunning = 0;
        boolean processed = false;
        while ((keeprunning < 5) && !processed) {
            Thread.sleep(5000); // wait 5 seconds between polls
            msgBytes = genScepGetCertInitial(gen, CMSSignedGenerator.DIGEST_SHA1);
            // Send message with GET
            retMsg = sendScep(true, msgBytes, true);
            assertNotNull(retMsg);
            if (isScepResponseMessageOfType(retMsg, ResponseStatus.PENDING)) {
                checkScepResponse(retMsg, senderNonce, transId, false, CMSSignedGenerator.DIGEST_SHA1, true,
                        ResponseStatus.PENDING);
            } else {
                checkScepResponse(retMsg, senderNonce, transId, false, CMSSignedGenerator.DIGEST_SHA1, true,
                        ResponseStatus.SUCCESS);
                processed = true;
            }
            keeprunning++;
        }
        assertTrue(processed);
        log.debug("<test06ScepRequestOKSHA1PostNoCA()");
    }

    //
    //
    // Private helper methods
    //
    //

    private byte[] genScepRequest(ScepRequestGenerator gen, String digestoid)
            throws InvalidKeyException, NoSuchAlgorithmException, NoSuchProviderException, SignatureException,
            InvalidAlgorithmParameterException, CertStoreException, IOException, CMSException,
            CertificateEncodingException, IllegalStateException {
        gen.setKeys(keys);
        gen.setDigestOid(digestoid);
        byte[] msgBytes = null;
        String dn = "C=SE, O=PrimeKey, CN=sceptest";
        msgBytes = gen.generateCertReq(dn, "foo123", racert);
        assertNotNull(msgBytes);
        transId = gen.getTransactionId();
        assertNotNull(transId);
        byte[] idBytes = Base64.decode(transId.getBytes());
        assertEquals(16, idBytes.length);
        senderNonce = gen.getSenderNonce();
        byte[] nonceBytes = Base64.decode(senderNonce.getBytes());
        assertEquals(16, nonceBytes.length);
        return msgBytes;
    }

    private byte[] genScepGetCertInitial(ScepRequestGenerator gen, String digestoid)
            throws NoSuchAlgorithmException, NoSuchProviderException, InvalidAlgorithmParameterException,
            CertStoreException, IOException, CMSException, IllegalStateException {
        gen.setKeys(keys);
        gen.setDigestOid(digestoid);
        byte[] msgBytes = null;
        String dn = "C=SE, O=PrimeKey, CN=sceptest"; // must be same as when the request was generated
        msgBytes = gen.generateGetCertInitial(dn, racert);
        assertNotNull(msgBytes);
        transId = gen.getTransactionId();
        assertNotNull(transId);
        byte[] idBytes = Base64.decode(transId.getBytes());
        assertEquals(16, idBytes.length);
        senderNonce = gen.getSenderNonce();
        byte[] nonceBytes = Base64.decode(senderNonce.getBytes());
        assertEquals(16, nonceBytes.length);
        return msgBytes;
    }

    private boolean isScepResponseMessageOfType(byte[] retMsg, ResponseStatus extectedResponseStatus)
            throws CMSException, NoSuchAlgorithmException, NoSuchProviderException {
        //
        // Parse response message
        //
        CMSSignedData s = new CMSSignedData(retMsg);
        // The signer, i.e. the CA, check it's the right CA
        SignerInformationStore signers = s.getSignerInfos();
        Collection col = signers.getSigners();
        assertTrue(col.size() > 0);
        Iterator iter = col.iterator();
        SignerInformation signerInfo = (SignerInformation) iter.next();
        SignerId sinfo = signerInfo.getSID();
        // Check that the signer is the expected CA
        assertEquals(CertTools.stringToBCDNString(racert.getIssuerDN().getName()),
                CertTools.stringToBCDNString(sinfo.getIssuerAsString()));
        // Verify the signature
        boolean ret = signerInfo.verify(racert.getPublicKey(), "BC");
        assertTrue(ret);
        // Get authenticated attributes
        AttributeTable tab = signerInfo.getSignedAttributes();
        // --Fail info
        Attribute attr = tab.get(new DERObjectIdentifier(ScepRequestMessage.id_failInfo));
        // --Message type
        attr = tab.get(new DERObjectIdentifier(ScepRequestMessage.id_messageType));
        assertNotNull(attr);
        ASN1Set values = attr.getAttrValues();
        assertEquals(values.size(), 1);
        DERString str = DERPrintableString.getInstance((values.getObjectAt(0)));
        String messageType = str.getString();
        assertEquals("3", messageType);
        // --Success status
        attr = tab.get(new DERObjectIdentifier(ScepRequestMessage.id_pkiStatus));
        assertNotNull(attr);
        values = attr.getAttrValues();
        assertEquals(values.size(), 1);
        str = DERPrintableString.getInstance((values.getObjectAt(0)));
        String responsestatus = str.getString();
        if (extectedResponseStatus.getValue().equals(responsestatus)) {
            return true;
        }
        return false;
    }

    private void checkScepResponse(byte[] retMsg, String senderNonce, String transId, boolean crlRep,
            String digestOid, boolean noca, ResponseStatus expectedResponseStatus)
            throws CMSException, NoSuchProviderException, NoSuchAlgorithmException, CertStoreException,
            InvalidKeyException, CertificateException, SignatureException, CRLException, IOException {
        //
        // Parse response message
        //
        CMSSignedData s = new CMSSignedData(retMsg);
        // The signer, i.e. the CA, check it's the right CA
        SignerInformationStore signers = s.getSignerInfos();
        Collection col = signers.getSigners();
        assertTrue(col.size() > 0);
        Iterator iter = col.iterator();
        SignerInformation signerInfo = (SignerInformation) iter.next();
        // Check that the message is signed with the correct digest alg
        assertEquals(signerInfo.getDigestAlgOID(), digestOid);
        SignerId sinfo = signerInfo.getSID();
        // Check that the signer is the expected CA
        assertEquals(CertTools.stringToBCDNString(racert.getIssuerDN().getName()),
                CertTools.stringToBCDNString(sinfo.getIssuerAsString()));
        // Verify the signature
        boolean ret = signerInfo.verify(racert.getPublicKey(), "BC");
        assertTrue(ret);
        // Get authenticated attributes
        AttributeTable tab = signerInfo.getSignedAttributes();
        // --Fail info
        Attribute attr = tab.get(new DERObjectIdentifier(ScepRequestMessage.id_failInfo));
        // No failInfo on this success message
        if (expectedResponseStatus == ResponseStatus.SUCCESS) {
            assertNull(attr);
        }

        // --Message type
        attr = tab.get(new DERObjectIdentifier(ScepRequestMessage.id_messageType));
        assertNotNull(attr);
        ASN1Set values = attr.getAttrValues();
        assertEquals(values.size(), 1);
        DERString str = DERPrintableString.getInstance((values.getObjectAt(0)));
        String messageType = str.getString();
        assertEquals("3", messageType);
        // --Success status
        attr = tab.get(new DERObjectIdentifier(ScepRequestMessage.id_pkiStatus));
        assertNotNull(attr);
        values = attr.getAttrValues();
        assertEquals(values.size(), 1);
        str = DERPrintableString.getInstance((values.getObjectAt(0)));
        String responsestatus = str.getString();
        assertEquals(expectedResponseStatus.getValue(), responsestatus);
        // --SenderNonce
        attr = tab.get(new DERObjectIdentifier(ScepRequestMessage.id_senderNonce));
        assertNotNull(attr);
        values = attr.getAttrValues();
        assertEquals(values.size(), 1);
        ASN1OctetString octstr = ASN1OctetString.getInstance(values.getObjectAt(0));
        // SenderNonce is something the server came up with, but it should be 16 chars
        assertTrue(octstr.getOctets().length == 16);
        // --Recipient Nonce
        attr = tab.get(new DERObjectIdentifier(ScepRequestMessage.id_recipientNonce));
        assertNotNull(attr);
        values = attr.getAttrValues();
        assertEquals(values.size(), 1);
        octstr = ASN1OctetString.getInstance(values.getObjectAt(0));
        // recipient nonce should be the same as we sent away as sender nonce
        assertEquals(senderNonce, new String(Base64.encode(octstr.getOctets())));
        // --Transaction ID
        attr = tab.get(new DERObjectIdentifier(ScepRequestMessage.id_transId));
        assertNotNull(attr);
        values = attr.getAttrValues();
        assertEquals(values.size(), 1);
        str = DERPrintableString.getInstance((values.getObjectAt(0)));
        // transid should be the same as the one we sent
        assertEquals(transId, str.getString());

        //
        // Check different message types
        //        
        if (!responsestatus.equals(ResponseStatus.PENDING.getValue()) && messageType.equals("3")) {
            // First we extract the encrypted data from the CMS enveloped data contained
            // within the CMS signed data
            CMSProcessable sp = s.getSignedContent();
            byte[] content = (byte[]) sp.getContent();
            CMSEnvelopedData ed = new CMSEnvelopedData(content);
            RecipientInformationStore recipients = ed.getRecipientInfos();
            Collection c = recipients.getRecipients();
            assertEquals(c.size(), 1);
            Iterator it = c.iterator();
            byte[] decBytes = null;
            RecipientInformation recipient = (RecipientInformation) it.next();
            decBytes = recipient.getContent(keys.getPrivate(), "BC");
            // This is yet another CMS signed data
            CMSSignedData sd = new CMSSignedData(decBytes);
            // Get certificates from the signed data
            CertStore certstore = sd.getCertificatesAndCRLs("Collection", "BC");
            if (crlRep) {
                // We got a reply with a requested CRL
                Collection crls = certstore.getCRLs(null);
                assertEquals(crls.size(), 1);
                it = crls.iterator();
                X509CRL retCrl = null;
                // CRL is first (and only)
                retCrl = (X509CRL) it.next();
                log.info("Got CRL with DN: " + retCrl.getIssuerDN().getName());
                //                try {
                //                    FileOutputStream fos = new FileOutputStream("sceptest.der");
                //                    fos.write(retCrl.getEncoded());
                //                    fos.close();
                //                } catch (Exception e) {}
                // check the returned CRL
                assertEquals(cacert.getSubjectDN().getName(), retCrl.getIssuerDN().getName());
                retCrl.verify(cacert.getPublicKey());
            } else {
                // We got a reply with a requested certificate 
                Collection certs = certstore.getCertificates(null);
                log.info("Got certificate reply with certchain of length: " + certs.size());
                // EJBCA returns the issued cert and the CA cert (cisco vpn client requires that the ca cert is included)
                if (noca) {
                    assertEquals(certs.size(), 1);
                } else {
                    assertEquals(certs.size(), 2);
                }
                it = certs.iterator();
                // Issued certificate must be first
                boolean verified = false;
                boolean gotcacert = false;
                String mysubjectdn = CertTools.stringToBCDNString("C=SE,O=PrimeKey,CN=sceptest");
                X509Certificate usercert = null;
                while (it.hasNext()) {
                    X509Certificate retcert = (X509Certificate) it.next();
                    //                    try {
                    //                        FileOutputStream fos = new FileOutputStream("sceptest.der");
                    //                        fos.write(retcert.getEncoded());
                    //                        fos.close();
                    //                    } catch (Exception e) {}

                    // check the returned certificate
                    String subjectdn = CertTools.stringToBCDNString(retcert.getSubjectDN().getName());
                    if (mysubjectdn.equals(subjectdn)) {
                        System.out.println("Got user cert with DN: " + retcert.getSubjectDN().getName());
                        // issued certificate
                        assertEquals(CertTools.stringToBCDNString("C=SE,O=PrimeKey,CN=sceptest"), subjectdn);
                        //System.out.println(retcert);
                        //System.out.println(cacert);
                        retcert.verify(cacert.getPublicKey());
                        assertTrue(checkKeys(keys.getPrivate(), retcert.getPublicKey()));
                        verified = true;
                        String altName = CertTools.getSubjectAlternativeName(retcert);
                        assertEquals("iPAddress=10.0.0.1, dNSName=foo.bar.com", altName);
                        usercert = retcert;
                    } else {
                        log.info("Got CA cert with DN: " + retcert.getSubjectDN().getName());
                        // ca certificate
                        assertEquals(cacert.getSubjectDN().getName(), retcert.getSubjectDN().getName());
                        gotcacert = true;
                        usercert.verify(retcert.getPublicKey());
                    }
                }
                assertTrue(verified);
                if (noca) {
                    assertFalse(gotcacert);
                } else {
                    assertTrue(gotcacert);
                }
            }
        }

    }

    /**
     * checks that a public and private key matches by signing and verifying a message
     */
    private boolean checkKeys(PrivateKey priv, PublicKey pub)
            throws SignatureException, NoSuchAlgorithmException, InvalidKeyException {
        Signature signer = Signature.getInstance("SHA1WithRSA");
        signer.initSign(priv);
        signer.update("PrimeKey".getBytes());
        byte[] signature = signer.sign();

        Signature signer2 = Signature.getInstance("SHA1WithRSA");
        signer2.initVerify(pub);
        signer2.update("PrimeKey".getBytes());
        return signer2.verify(signature);
    }

    private byte[] sendScep(boolean post, byte[] scepPackage, boolean noca) throws IOException {
        // POST the OCSP request
        // we are going to do a POST
        String resource = resourceScep;
        if (noca) {
            resource = resourceScepNoCA;
        }
        String urlString = httpReqPath + '/' + resource + "?operation=PKIOperation";
        log.debug("UrlString =" + urlString);
        log.debug("scepPackage.length: " + scepPackage.length);
        HttpURLConnection con = null;
        if (post) {
            URL url = new URL(urlString);
            con = (HttpURLConnection) url.openConnection();
            con.setDoOutput(true);
            con.setRequestMethod("POST");
            con.connect();
            // POST it
            OutputStream os = con.getOutputStream();
            os.write(scepPackage);
            os.close();
        } else {
            String reqUrl = urlString + "&message="
                    + URLEncoder.encode(new String(Base64.encode(scepPackage)), "UTF-8");
            URL url = new URL(reqUrl);
            con = (HttpURLConnection) url.openConnection();
            con.setRequestMethod("GET");
            con.getDoOutput();
            con.connect();
        }
        log.debug("HTTP response message: " + con.getResponseMessage());
        assertEquals("Response code ", 200, con.getResponseCode());
        assertEquals("Content-Type", "application/x-pki-message", con.getContentType());
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        // This works for small requests, and SCEP requests are small enough
        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();
        assertNotNull("Response can not be null.", respBytes);
        assertTrue(respBytes.length > 0);
        return respBytes;
    }
}