org.cryptable.pki.communication.PKICMPMessagesTest.java Source code

Java tutorial

Introduction

Here is the source code for org.cryptable.pki.communication.PKICMPMessagesTest.java

Source

/**
 * The MIT License (MIT)
 *
 * Copyright (c) <2013> <Cryptable>
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
 *
 */
package org.cryptable.pki.communication;

import org.bouncycastle.asn1.*;
import org.bouncycastle.asn1.cmp.*;
import org.bouncycastle.asn1.crmf.*;
import org.bouncycastle.asn1.x509.*;
import org.bouncycastle.asn1.x509.CRLReason;
import org.bouncycastle.asn1.x509.Extension;
import org.bouncycastle.asn1.x509.X509Extension;
import org.bouncycastle.cert.X509CertificateHolder;
import org.bouncycastle.cert.cmp.CMPException;
import org.bouncycastle.cert.cmp.GeneralPKIMessage;
import org.bouncycastle.cert.cmp.ProtectedPKIMessage;
import org.bouncycastle.cert.cmp.ProtectedPKIMessageBuilder;
import org.bouncycastle.cert.crmf.CRMFException;
import org.bouncycastle.cert.crmf.PKIArchiveControl;
import org.bouncycastle.cert.crmf.jcajce.JceCRMFEncryptorBuilder;
import org.bouncycastle.cert.jcajce.JcaX500NameUtil;
import org.bouncycastle.cert.jcajce.JcaX509CRLHolder;
import org.bouncycastle.cert.jcajce.JcaX509CertificateHolder;
import org.bouncycastle.cms.*;
import org.bouncycastle.cms.jcajce.JceKeyTransEnvelopedRecipient;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.bouncycastle.operator.*;
import org.bouncycastle.operator.jcajce.JcaContentSignerBuilder;
import org.bouncycastle.operator.jcajce.JcaContentVerifierProviderBuilder;
import org.bouncycastle.operator.jcajce.JceAsymmetricKeyWrapper;
import org.cryptable.pki.model.CertificationResult;
import org.cryptable.pki.model.RevocationInput;
import org.cryptable.pki.util.GeneratePKI;
import org.cryptable.pki.util.PKIKeyStore;
import org.cryptable.pki.util.PKIKeyStoreException;
import org.junit.After;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.math.BigInteger;
import java.security.*;
import java.security.cert.*;
import java.security.spec.InvalidKeySpecException;
import java.text.ParseException;
import java.util.*;

public class PKICMPMessagesTest {

    private GeneratePKI pki;
    private PKIKeyStore pkiKeyStoreRA;
    private PKIKeyStore pkiKeyStoreCA;

    @Before
    public void setUp() throws Exception {
        Security.addProvider(new BouncyCastleProvider());
        pki = new GeneratePKI();
        pki.createPKI();

        pkiKeyStoreRA = new PKIKeyStore(pki.getRACertPrivateKey(), pki.getRACert(), pki.getSubCACert(),
                pki.getCertificateChain());
        pkiKeyStoreCA = new PKIKeyStore(pki.getSubCACertPrivateKey(), pki.getSubCACert(), pki.getRACert(),
                pki.getCertificateChain());
    }

    @After
    public void tearDown() throws Exception {
    }

    @Test
    public void testKeyGeneration() throws NoSuchProviderException, NoSuchAlgorithmException {
        KeyPairGenerator kGen = KeyPairGenerator.getInstance("RSA", "BC");
        kGen.initialize(2048);
        KeyPair kp = kGen.generateKeyPair();
        System.out.print(kp.getPrivate().toString());
    }

    /**
     * Test the basic certification request message
     *
     * @throws OperatorCreationException
     * @throws CertificateEncodingException
     * @throws IOException
     * @throws CRMFException
     * @throws CMPException
     * @throws CMSException
     */
    @Test
    public void testCertification() throws OperatorCreationException, CertificateEncodingException, IOException,
            CRMFException, CMPException, CMSException, ParseException, PKICMPMessageException,
            NoSuchProviderException, NoSuchAlgorithmException, NoSuchFieldException, IllegalAccessException {
        String distinguishedName = pki.getTestUser1Cert().getSubjectX500Principal().getName();

        KeyPair keyPair = new KeyPair(pki.getTestUser1Cert().getPublicKey(), pki.getTestUser1CertPrivateKey());

        PKICMPMessages pkiMessages = new PKICMPMessages();
        pkiMessages.setPkiKeyStore(pkiKeyStoreRA);
        byte[] result = pkiMessages.createCertificateMessageWithLocalKey(distinguishedName, keyPair);

        ASN1InputStream asn1InputStream = new ASN1InputStream(result);
        ASN1Primitive asn1Primitive = asn1InputStream.readObject();
        PKIMessage pkiMessage = PKIMessage.getInstance(asn1Primitive);

        // Header verification
        Assert.assertEquals(pkiMessage.getHeader().getPvno().getValue(), BigInteger.valueOf(2));
        Assert.assertEquals(pkiKeyStoreRA.getRecipientCertificate().getSubjectDN().getName(),
                pkiMessage.getHeader().getRecipient().getName().toString());
        Assert.assertEquals(pkiKeyStoreRA.getSenderCertificate().getSubjectDN().getName(),
                pkiMessage.getHeader().getSender().getName().toString());
        Assert.assertNotNull(pkiMessage.getHeader().getSenderNonce());
        Assert.assertNotNull(pkiMessage.getHeader().getTransactionID());
        Assert.assertNotNull(pkiMessage.getHeader().getMessageTime().getDate());
        // check the body
        // Check the tests in Bouncycastle for decoding cert request
        Assert.assertEquals(PKIBody.TYPE_CERT_REQ, pkiMessage.getBody().getType());
        CertReqMsg[] certReqMsgs = CertReqMessages.getInstance(pkiMessage.getBody().getContent())
                .toCertReqMsgArray();
        Assert.assertEquals(BigInteger.ZERO.toString(), certReqMsgs[0].getCertReq().getCertReqId().toString());
        Assert.assertEquals(distinguishedName,
                certReqMsgs[0].getCertReq().getCertTemplate().getSubject().toString());
        Assert.assertArrayEquals(keyPair.getPublic().getEncoded(),
                certReqMsgs[0].getCertReq().getCertTemplate().getPublicKey().getEncoded());
        AttributeTypeAndValue[] attributeTypeAndValue = certReqMsgs[0].getCertReq().getControls()
                .toAttributeTypeAndValueArray();
        Assert.assertEquals(CRMFObjectIdentifiers.id_regCtrl_pkiArchiveOptions, attributeTypeAndValue[0].getType());
        // Check the signature
        GeneralPKIMessage generalPKIMessage = new GeneralPKIMessage(result);
        Assert.assertTrue(generalPKIMessage.hasProtection());
        ProtectedPKIMessage pkiMsg = new ProtectedPKIMessage(generalPKIMessage);
        ContentVerifierProvider verifierProvider = new JcaContentVerifierProviderBuilder()
                .setProvider(pkiKeyStoreRA.getProvider())
                .build(pkiKeyStoreRA.getSenderCertificate().getPublicKey());

        Assert.assertTrue(pkiMsg.verify(verifierProvider));
    }

    /**
     * Test the basic certification request message
     *
     * @throws OperatorCreationException
     * @throws CertificateEncodingException
     * @throws IOException
     * @throws CRMFException
     * @throws CMPException
     * @throws CMSException
     */
    @Test
    public void testInitialization() throws OperatorCreationException, CertificateEncodingException, IOException,
            CRMFException, CMPException, CMSException, ParseException, PKICMPMessageException,
            NoSuchProviderException, NoSuchAlgorithmException, NoSuchFieldException, IllegalAccessException {
        String distinguishedName = pki.getTestUser1Cert().getSubjectX500Principal().getName();

        KeyPair keyPair = new KeyPair(pki.getTestUser1Cert().getPublicKey(), pki.getTestUser1CertPrivateKey());

        PKICMPMessages pkiMessages = new PKICMPMessages();
        pkiMessages.setPkiKeyStore(pkiKeyStoreRA);
        byte[] result = pkiMessages.createInitializationMessage(distinguishedName, keyPair);

        ASN1InputStream asn1InputStream = new ASN1InputStream(result);
        ASN1Primitive asn1Primitive = asn1InputStream.readObject();
        PKIMessage pkiMessage = PKIMessage.getInstance(asn1Primitive);

        // check the body
        // Check the tests in Bouncycastle for decoding cert request
        Assert.assertEquals(PKIBody.TYPE_INIT_REQ, pkiMessage.getBody().getType());
    }

    /**
     * Check the extensions in the certification request
     *
     * @throws OperatorCreationException
     * @throws PKICMPMessageException
     * @throws CertificateEncodingException
     * @throws IOException
     * @throws CRMFException
     * @throws CMPException
     * @throws CMSException
     */
    @Test
    public void testCertificationWithExtensions()
            throws OperatorCreationException, PKICMPMessageException, CertificateEncodingException, IOException,
            CRMFException, CMPException, CMSException, NoSuchFieldException, IllegalAccessException {
        String distinguishedName = pki.getTestUser1Cert().getSubjectX500Principal().getName();

        KeyPair keyPair = new KeyPair(pki.getTestUser1Cert().getPublicKey(), pki.getTestUser1CertPrivateKey());

        List<Extension> extensionList = new ArrayList<Extension>();
        // KeyUsage
        extensionList.add(new Extension(X509Extension.keyUsage, true,
                new KeyUsage(KeyUsage.digitalSignature | KeyUsage.nonRepudiation).getEncoded()));
        // Extended keyUsage
        List<KeyPurposeId> keyPurposeIds = new ArrayList<KeyPurposeId>();
        keyPurposeIds.add(KeyPurposeId.getInstance(KeyPurposeId.id_kp_clientAuth));
        keyPurposeIds.add(KeyPurposeId.getInstance(KeyPurposeId.id_kp_emailProtection));
        extensionList.add(new Extension(X509Extension.extendedKeyUsage, false,
                new ExtendedKeyUsage(keyPurposeIds.toArray(new KeyPurposeId[keyPurposeIds.size()])).getEncoded()));
        // Subject alternative names
        List<GeneralName> generalNames = new ArrayList<GeneralName>();
        generalNames.add(new GeneralName(GeneralName.dNSName, "www1.cryptable.org"));
        generalNames.add(new GeneralName(GeneralName.dNSName, "www2.cryptable.org"));
        GeneralNames subjectAlternativeName = new GeneralNames(
                generalNames.toArray(new GeneralName[generalNames.size()]));
        extensionList.add(
                new Extension(X509Extension.subjectAlternativeName, false, subjectAlternativeName.getEncoded()));

        PKICMPMessages pkiMessages = new PKICMPMessages();
        pkiMessages.setPkiKeyStore(pkiKeyStoreRA);
        pkiMessages.setExtensions(extensionList.toArray(new Extension[extensionList.size()]));
        byte[] result = pkiMessages.createCertificateMessageWithLocalKey(distinguishedName, keyPair);

        ASN1InputStream asn1InputStream = new ASN1InputStream(result);
        ASN1Primitive asn1Primitive = asn1InputStream.readObject();
        PKIMessage pkiMessage = PKIMessage.getInstance(asn1Primitive);

        CertReqMsg[] certReqMsgs = CertReqMessages.getInstance(pkiMessage.getBody().getContent())
                .toCertReqMsgArray();
        // KeyUsage
        KeyUsage verifyKeyUsage = KeyUsage.getInstance(certReqMsgs[0].getCertReq().getCertTemplate().getExtensions()
                .getExtensionParsedValue(Extension.keyUsage));
        Assert.assertEquals(KeyUsage.digitalSignature | KeyUsage.nonRepudiation,
                verifyKeyUsage.getBytes()[0] & 0xFF);
        // Extended KeyUsage
        ExtendedKeyUsage verifyExtendedKeyUsage = ExtendedKeyUsage
                .fromExtensions(certReqMsgs[0].getCertReq().getCertTemplate().getExtensions());
        Assert.assertTrue(verifyExtendedKeyUsage.hasKeyPurposeId(KeyPurposeId.id_kp_clientAuth));
        Assert.assertTrue(verifyExtendedKeyUsage.hasKeyPurposeId(KeyPurposeId.id_kp_emailProtection));
        // Subject Alternative Name
        GeneralNames verifyGeneralNames = GeneralNames.fromExtensions(
                certReqMsgs[0].getCertReq().getCertTemplate().getExtensions(), Extension.subjectAlternativeName);
        Assert.assertTrue(generalNames.contains(verifyGeneralNames.getNames()[0]));
        Assert.assertTrue(generalNames.contains(verifyGeneralNames.getNames()[1]));
    }

    /**
     * Check the extensions in the certification request
     *
     * @throws OperatorCreationException
     * @throws PKICMPMessageException
     * @throws CertificateEncodingException
     * @throws IOException
     * @throws CRMFException
     * @throws CMPException
     * @throws CMSException
     */
    @Test
    public void testCertificationWithValidity()
            throws OperatorCreationException, PKICMPMessageException, CertificateEncodingException, IOException,
            CRMFException, CMPException, CMSException, NoSuchFieldException, IllegalAccessException {
        String distinguishedName = pki.getTestUser1Cert().getSubjectX500Principal().getName();

        KeyPair keyPair = new KeyPair(pki.getTestUser1Cert().getPublicKey(), pki.getTestUser1CertPrivateKey());

        Date notBefore = new Date(System.currentTimeMillis() - 1000L * 60 * 60 * 24 * 30);
        Date notAfter = new Date(System.currentTimeMillis() + 1000L * 60 * 60 * 24 * 30);

        PKICMPMessages pkiMessages = new PKICMPMessages();
        pkiMessages.setPkiKeyStore(pkiKeyStoreRA);
        pkiMessages.setValidity(notBefore, notAfter);
        byte[] result = pkiMessages.createCertificateMessageWithLocalKey(distinguishedName, keyPair);

        ASN1InputStream asn1InputStream = new ASN1InputStream(result);
        ASN1Primitive asn1Primitive = asn1InputStream.readObject();
        PKIMessage pkiMessage = PKIMessage.getInstance(asn1Primitive);

        CertReqMsg[] certReqMsgs = CertReqMessages.getInstance(pkiMessage.getBody().getContent())
                .toCertReqMsgArray();
        Assert.assertEquals(notBefore.toString(),
                certReqMsgs[0].getCertReq().getCertTemplate().getValidity().getNotBefore().getDate().toString());
        Assert.assertEquals(notAfter.toString(),
                certReqMsgs[0].getCertReq().getCertTemplate().getValidity().getNotAfter().getDate().toString());
    }

    /**
     * Check the private key archive control in the certification request
     *
     * @throws OperatorCreationException
     * @throws PKICMPMessageException
     * @throws CertificateEncodingException
     * @throws IOException
     * @throws CRMFException
     * @throws CMPException
     * @throws CMSException
     */
    @Test
    public void testCertificationWithPrivateKeyControl()
            throws OperatorCreationException, PKICMPMessageException, CertificateException, IOException,
            CRMFException, CMPException, CMSException, InvalidKeySpecException, NoSuchAlgorithmException,
            NoSuchProviderException, NoSuchFieldException, IllegalAccessException, CRLException {
        String distinguishedName = pki.getTestUser1Cert().getSubjectX500Principal().getName();

        KeyPair keyPair = new KeyPair(pki.getTestUser1Cert().getPublicKey(), pki.getTestUser1CertPrivateKey());

        PKICMPMessages pkiMessages = new PKICMPMessages();
        pkiMessages.setPkiKeyStore(pkiKeyStoreRA);
        byte[] result = pkiMessages.createCertificateMessageWithLocalKey(distinguishedName, keyPair);

        ASN1InputStream asn1InputStream = new ASN1InputStream(result);
        ASN1Primitive asn1Primitive = asn1InputStream.readObject();
        PKIMessage pkiMessage = PKIMessage.getInstance(asn1Primitive);

        CertReqMsg[] certReqMsgs = CertReqMessages.getInstance(pkiMessage.getBody().getContent())
                .toCertReqMsgArray();
        AttributeTypeAndValue[] attributeTypeAndValues = certReqMsgs[0].getCertReq().getControls()
                .toAttributeTypeAndValueArray();
        GeneratePKI genPKI = new GeneratePKI();
        genPKI.createPKI();

        boolean bFound = false;
        for (AttributeTypeAndValue attributeTypeAndValue : attributeTypeAndValues) {
            if (attributeTypeAndValue.getType().equals(CRMFObjectIdentifiers.id_regCtrl_pkiArchiveOptions)) {
                PKIArchiveControl pkiArchiveControl = new PKIArchiveControl(
                        PKIArchiveOptions.getInstance(attributeTypeAndValue.getValue()));

                // Decrypt data
                CMSEnvelopedDataParser cmsEnvelopedDataParser = new CMSEnvelopedDataParser(
                        pkiArchiveControl.getEnvelopedData().getEncoded());
                RecipientInformationStore recipients = cmsEnvelopedDataParser.getRecipientInfos();
                Collection c = recipients.getRecipients();
                Iterator it = c.iterator();

                if (it.hasNext()) {
                    RecipientInformation recipient = (RecipientInformation) it.next();
                    byte[] recdata = recipient
                            .getContent(new JceKeyTransEnvelopedRecipient(genPKI.getSubCACertPrivateKey())
                                    .setProvider(pkiKeyStoreRA.getProvider()));
                    ASN1InputStream tstAsn1InputStream = new ASN1InputStream(recdata);
                    ASN1Primitive tstAsn1Primitive = tstAsn1InputStream.readObject();
                    EncKeyWithID encKeyWithID = EncKeyWithID.getInstance(tstAsn1Primitive);
                    Assert.assertArrayEquals(keyPair.getPrivate().getEncoded(),
                            encKeyWithID.getPrivateKey().getEncoded());
                    Assert.assertTrue(encKeyWithID.hasIdentifier());
                    GeneralName identifier = GeneralName.getInstance(encKeyWithID.getIdentifier());
                    Assert.assertEquals(genPKI.getTestUser1Cert().getSubjectDN().getName(),
                            identifier.getName().toString());
                    bFound = true;
                }
            }
        }

        Assert.assertTrue(bFound);

    }

    /**
     * Test a certification request without sending the private key
     *
     * @throws OperatorCreationException
     * @throws PKICMPMessageException
     * @throws CertificateException
     * @throws IOException
     * @throws CRMFException
     * @throws CMPException
     * @throws CMSException
     * @throws InvalidKeySpecException
     * @throws NoSuchAlgorithmException
     * @throws NoSuchProviderException
     */
    @Test
    public void testCertificationWithWithoutPrivateKey() throws OperatorCreationException, PKICMPMessageException,
            CertificateException, IOException, CRMFException, CMPException, CMSException, InvalidKeySpecException,
            NoSuchAlgorithmException, NoSuchProviderException, NoSuchFieldException, IllegalAccessException {
        String distinguishedName = pki.getTestUser1Cert().getSubjectX500Principal().getName();

        KeyPair keyPair = new KeyPair(pki.getTestUser1Cert().getPublicKey(), null);

        PKICMPMessages pkiMessages = new PKICMPMessages();
        pkiMessages.setPkiKeyStore(pkiKeyStoreRA);
        byte[] result = pkiMessages.createCertificateMessageWithLocalKey(distinguishedName, keyPair);

        ASN1InputStream asn1InputStream = new ASN1InputStream(result);
        ASN1Primitive asn1Primitive = asn1InputStream.readObject();
        PKIMessage pkiMessage = PKIMessage.getInstance(asn1Primitive);

        boolean bFound = false;
        CertReqMsg[] certReqMsgs = CertReqMessages.getInstance(pkiMessage.getBody().getContent())
                .toCertReqMsgArray();
        Controls controls = certReqMsgs[0].getCertReq().getControls();

        Assert.assertNull(controls);
    }

    /**
     * Test the certificate message generation prepared for remote key generation
     *
     * @throws OperatorCreationException
     * @throws PKICMPMessageException
     * @throws CertificateEncodingException
     * @throws IOException
     * @throws CRMFException
     * @throws CMPException
     * @throws CMSException
     */
    @Test
    public void testCertificationWithRemoteKeyGeneration()
            throws OperatorCreationException, PKICMPMessageException, CertificateEncodingException, IOException,
            CRMFException, CMPException, CMSException, NoSuchFieldException, IllegalAccessException {
        String distinguishedName = pki.getTestUser1Cert().getSubjectX500Principal().getName();

        PKICMPMessages pkiMessages = new PKICMPMessages();
        pkiMessages.setPkiKeyStore(pkiKeyStoreRA);
        byte[] result = pkiMessages.createCertificateMessageWithRemoteKey(distinguishedName);

        ASN1InputStream asn1InputStream = new ASN1InputStream(result);
        ASN1Primitive asn1Primitive = asn1InputStream.readObject();
        PKIMessage pkiMessage = PKIMessage.getInstance(asn1Primitive);
        CertReqMsg[] certReqMsgs = CertReqMessages.getInstance(pkiMessage.getBody().getContent())
                .toCertReqMsgArray();

        Assert.assertNull(certReqMsgs[0].getCertReq().getCertTemplate().getPublicKey());
    }

    /**
     * Test certification message with a predefined transactionId
     * @throws OperatorCreationException
     * @throws PKICMPMessageException
     * @throws CertificateEncodingException
     * @throws IOException
     * @throws CRMFException
     * @throws CMPException
     * @throws CMSException
     */
    @Test
    public void testCertificationWithTransactionId()
            throws OperatorCreationException, PKICMPMessageException, CertificateEncodingException, IOException,
            CRMFException, CMPException, CMSException, NoSuchFieldException, IllegalAccessException {
        String distinguishedName = pki.getTestUser1Cert().getSubjectX500Principal().getName();
        byte[] transactionId = { 0x01, 0x02, 0x03, 0x04 };

        PKICMPMessages pkiMessages = new PKICMPMessages();
        pkiMessages.setPkiKeyStore(pkiKeyStoreRA);
        pkiMessages.setTransactionId(transactionId);
        byte[] result = pkiMessages.createCertificateMessageWithRemoteKey(distinguishedName);

        ASN1InputStream asn1InputStream = new ASN1InputStream(result);
        ASN1Primitive asn1Primitive = asn1InputStream.readObject();
        PKIMessage pkiMessage = PKIMessage.getInstance(asn1Primitive);

        Assert.assertArrayEquals(transactionId, pkiMessage.getHeader().getTransactionID().getOctets());
    }

    /**
     * Test the confirmation message from the certification authority
     *
     * @throws IOException
     * @throws CertificateEncodingException
     * @throws OperatorCreationException
     * @throws CMPException
     */
    @Test
    public void testCertificateConfirm() throws IOException, CertificateEncodingException,
            OperatorCreationException, CMPException, PKICMPMessageException {
        PKICMPMessages pkiMessages = new PKICMPMessages();
        pkiMessages.setPkiKeyStore(pkiKeyStoreRA);
        byte[] result = pkiMessages.createConfirmationMessage(pki.getTestUser1Cert(), BigInteger.ONE);

        ASN1InputStream asn1InputStream = new ASN1InputStream(result);
        ASN1Primitive asn1Primitive = asn1InputStream.readObject();
        PKIMessage pkiMessage = PKIMessage.getInstance(asn1Primitive);
        // Check the body
        CertConfirmContent certConfirmContent = CertConfirmContent.getInstance(pkiMessage.getBody().getContent());
        CertStatus[] certStatuses = certConfirmContent.toCertStatusArray();
        Assert.assertEquals(BigInteger.ONE, certStatuses[0].getCertReqId().getValue());
        Assert.assertNotNull(certStatuses[0].getCertHash().getOctets());
    }

    /**
     * Test the confirmation message from the certification authority
     *
     * @throws IOException
     * @throws CertificateEncodingException
     * @throws OperatorCreationException
     * @throws CMPException
     */
    @Test
    public void testKeyUpdateWithLocalKeyChangeKey()
            throws IOException, CertificateEncodingException, OperatorCreationException, CMPException,
            PKICMPMessageException, CRMFException, IllegalAccessException, CMSException, NoSuchFieldException {
        PKICMPMessages pkiMessages = new PKICMPMessages();
        pkiMessages.setPkiKeyStore(pkiKeyStoreRA);
        KeyPair keyPair = new KeyPair(pki.getTestUser2Cert().getPublicKey(), pki.getTestUser2CertPrivateKey());

        byte[] result = pkiMessages.createKeyUpdateMessageWithLocalKey(pki.getTestUser1Cert(), keyPair);

        ASN1InputStream asn1InputStream = new ASN1InputStream(result);
        ASN1Primitive asn1Primitive = asn1InputStream.readObject();
        PKIMessage pkiMessage = PKIMessage.getInstance(asn1Primitive);

        // Check the Body
        Assert.assertEquals(PKIBody.TYPE_KEY_UPDATE_REQ, pkiMessage.getBody().getType());
        CertReqMsg[] certReqMsgs = CertReqMessages.getInstance(pkiMessage.getBody().getContent())
                .toCertReqMsgArray();
        Assert.assertEquals(BigInteger.ZERO.toString(), certReqMsgs[0].getCertReq().getCertReqId().toString());
        Assert.assertEquals(pki.getTestUser1Cert().getSubjectDN().getName().toString(),
                certReqMsgs[0].getCertReq().getCertTemplate().getSubject().toString());
        Assert.assertEquals(pki.getTestUser1Cert().getSerialNumber(),
                certReqMsgs[0].getCertReq().getCertTemplate().getSerialNumber().getValue());
        Assert.assertEquals(pki.getTestUser1Cert().getIssuerDN().getName().toString(),
                certReqMsgs[0].getCertReq().getCertTemplate().getIssuer().toString());
        // KeyPair check
        Assert.assertArrayEquals(pki.getTestUser2Cert().getPublicKey().getEncoded(),
                certReqMsgs[0].getCertReq().getCertTemplate().getPublicKey().getEncoded());
        AttributeTypeAndValue[] attributeTypeAndValue = certReqMsgs[0].getCertReq().getControls()
                .toAttributeTypeAndValueArray();
        Assert.assertEquals(CRMFObjectIdentifiers.id_regCtrl_pkiArchiveOptions, attributeTypeAndValue[0].getType());
        // Validity
        Assert.assertEquals(pki.getTestUser1Cert().getNotBefore().toString(),
                certReqMsgs[0].getCertReq().getCertTemplate().getValidity().getNotBefore().getDate().toString());
        Assert.assertEquals(pki.getTestUser1Cert().getNotAfter().toString(),
                certReqMsgs[0].getCertReq().getCertTemplate().getValidity().getNotAfter().getDate().toString());
        // Extensions check
        Assert.assertNull(certReqMsgs[0].getCertReq().getCertTemplate().getExtensions());
    }

    /**
     * Test the confirmation message from the certification authority
     *
     * @throws IOException
     * @throws CertificateEncodingException
     * @throws OperatorCreationException
     * @throws CMPException
     */
    @Test
    public void testKeyUpdateWithLocalKeyChangeValidity()
            throws IOException, CertificateEncodingException, OperatorCreationException, CMPException,
            PKICMPMessageException, CRMFException, IllegalAccessException, CMSException, NoSuchFieldException {
        PKICMPMessages pkiMessages = new PKICMPMessages();
        pkiMessages.setPkiKeyStore(pkiKeyStoreRA);
        KeyPair keyPair = new KeyPair(pki.getTestUser2Cert().getPublicKey(), pki.getTestUser2CertPrivateKey());

        Date notBefore = new Date(System.currentTimeMillis() - 500L * 60 * 60 * 24 * 30);
        Date notAfter = new Date(System.currentTimeMillis() + 500L * 60 * 60 * 24 * 30);

        pkiMessages.setValidity(notBefore, notAfter);
        byte[] result = pkiMessages.createKeyUpdateMessageWithLocalKey(pki.getTestUser1Cert(), keyPair);

        ASN1InputStream asn1InputStream = new ASN1InputStream(result);
        ASN1Primitive asn1Primitive = asn1InputStream.readObject();
        PKIMessage pkiMessage = PKIMessage.getInstance(asn1Primitive);

        // Check the Body
        Assert.assertEquals(PKIBody.TYPE_KEY_UPDATE_REQ, pkiMessage.getBody().getType());
        CertReqMsg[] certReqMsgs = CertReqMessages.getInstance(pkiMessage.getBody().getContent())
                .toCertReqMsgArray();
        // Validity
        Assert.assertEquals(notBefore.toString(),
                certReqMsgs[0].getCertReq().getCertTemplate().getValidity().getNotBefore().getDate().toString());
        Assert.assertEquals(notAfter.toString(),
                certReqMsgs[0].getCertReq().getCertTemplate().getValidity().getNotAfter().getDate().toString());
    }

    /**
     * Test the confirmation message from the certification authority
     *
     * @throws IOException
     * @throws CertificateEncodingException
     * @throws OperatorCreationException
     * @throws CMPException
     */
    @Test
    public void testKeyUpdateWithLocalKeyWithExtensions()
            throws IOException, CertificateEncodingException, OperatorCreationException, CMPException,
            PKICMPMessageException, CRMFException, IllegalAccessException, CMSException, NoSuchFieldException {
        PKICMPMessages pkiMessages = new PKICMPMessages();
        pkiMessages.setPkiKeyStore(pkiKeyStoreRA);
        KeyPair keyPair = new KeyPair(pki.getTestUser2Cert().getPublicKey(), pki.getTestUser2CertPrivateKey());

        List<Extension> extensionList = new ArrayList<Extension>();
        // KeyUsage
        extensionList.add(new Extension(X509Extension.keyUsage, true,
                new KeyUsage(KeyUsage.digitalSignature | KeyUsage.nonRepudiation).getEncoded()));
        // Extended keyUsage
        List<KeyPurposeId> keyPurposeIds = new ArrayList<KeyPurposeId>();
        keyPurposeIds.add(KeyPurposeId.getInstance(KeyPurposeId.id_kp_clientAuth));
        keyPurposeIds.add(KeyPurposeId.getInstance(KeyPurposeId.id_kp_emailProtection));
        extensionList.add(new Extension(X509Extension.extendedKeyUsage, false,
                new ExtendedKeyUsage(keyPurposeIds.toArray(new KeyPurposeId[keyPurposeIds.size()])).getEncoded()));

        pkiMessages.setExtensions(extensionList.toArray(new Extension[extensionList.size()]));
        byte[] result = pkiMessages.createKeyUpdateMessageWithLocalKey(pki.getRACert(), keyPair);

        ASN1InputStream asn1InputStream = new ASN1InputStream(result);
        ASN1Primitive asn1Primitive = asn1InputStream.readObject();
        PKIMessage pkiMessage = PKIMessage.getInstance(asn1Primitive);

        // Check the Body
        CertReqMsg[] certReqMsgs = CertReqMessages.getInstance(pkiMessage.getBody().getContent())
                .toCertReqMsgArray();
        // Extensions check
        // KeyUsage
        KeyUsage verifyKeyUsage = KeyUsage.getInstance(certReqMsgs[0].getCertReq().getCertTemplate().getExtensions()
                .getExtensionParsedValue(Extension.keyUsage));
        Assert.assertEquals(KeyUsage.digitalSignature | KeyUsage.nonRepudiation,
                verifyKeyUsage.getBytes()[0] & 0xFF);
        // Extended KeyUsage
        ExtendedKeyUsage verifyExtendedKeyUsage = ExtendedKeyUsage
                .fromExtensions(certReqMsgs[0].getCertReq().getCertTemplate().getExtensions());
        Assert.assertTrue(verifyExtendedKeyUsage.hasKeyPurposeId(KeyPurposeId.id_kp_clientAuth));
        Assert.assertTrue(verifyExtendedKeyUsage.hasKeyPurposeId(KeyPurposeId.id_kp_emailProtection));
    }

    /**
     * Test the confirmation message from the certification authority
     *
     * @throws IOException
     * @throws CertificateEncodingException
     * @throws OperatorCreationException
     * @throws CMPException
     */
    @Test
    public void testKeyUpdateWithRemoteKey()
            throws IOException, CertificateEncodingException, OperatorCreationException, CMPException,
            PKICMPMessageException, CRMFException, IllegalAccessException, CMSException, NoSuchFieldException {
        PKICMPMessages pkiMessages = new PKICMPMessages();
        pkiMessages.setPkiKeyStore(pkiKeyStoreRA);

        byte[] result = pkiMessages.createKeyUpdateMessageWithRemoteKey(pki.getTestUser1Cert());

        ASN1InputStream asn1InputStream = new ASN1InputStream(result);
        ASN1Primitive asn1Primitive = asn1InputStream.readObject();
        PKIMessage pkiMessage = PKIMessage.getInstance(asn1Primitive);

        // Check the Body
        Assert.assertEquals(PKIBody.TYPE_KEY_UPDATE_REQ, pkiMessage.getBody().getType());
        CertReqMsg[] certReqMsgs = CertReqMessages.getInstance(pkiMessage.getBody().getContent())
                .toCertReqMsgArray();
        Assert.assertEquals(BigInteger.ZERO.toString(), certReqMsgs[0].getCertReq().getCertReqId().toString());
        Assert.assertEquals(pki.getTestUser1Cert().getSubjectDN().getName().toString(),
                certReqMsgs[0].getCertReq().getCertTemplate().getSubject().toString());
        Assert.assertEquals(pki.getTestUser1Cert().getSerialNumber(),
                certReqMsgs[0].getCertReq().getCertTemplate().getSerialNumber().getValue());
        Assert.assertEquals(pki.getTestUser1Cert().getIssuerDN().getName().toString(),
                certReqMsgs[0].getCertReq().getCertTemplate().getIssuer().toString());
        // KeyPair check: should be not there
        Assert.assertNull(certReqMsgs[0].getCertReq().getCertTemplate().getPublicKey());
        Assert.assertNull(certReqMsgs[0].getCertReq().getControls());
        // Validity
        Assert.assertEquals(pki.getTestUser1Cert().getNotBefore().toString(),
                certReqMsgs[0].getCertReq().getCertTemplate().getValidity().getNotBefore().getDate().toString());
        Assert.assertEquals(pki.getTestUser1Cert().getNotAfter().toString(),
                certReqMsgs[0].getCertReq().getCertTemplate().getValidity().getNotAfter().getDate().toString());
        // Extensions check
        Assert.assertNull(certReqMsgs[0].getCertReq().getCertTemplate().getExtensions());
    }

    /**
     * Test the confirmation message from the certification authority
     *
     * @throws IOException
     * @throws CertificateEncodingException
     * @throws OperatorCreationException
     * @throws CMPException
     */
    @Test
    public void testRevocationMessage()
            throws IOException, CertificateEncodingException, OperatorCreationException, CMPException,
            PKICMPMessageException, CRMFException, IllegalAccessException, CMSException, NoSuchFieldException {
        PKICMPMessages pkiMessages = new PKICMPMessages();
        pkiMessages.setPkiKeyStore(pkiKeyStoreRA);
        List<RevocationInput> revocationInputs = new ArrayList<RevocationInput>(2);
        revocationInputs.add(new RevocationInput(pki.getTestUser1Cert()));
        revocationInputs.add(new RevocationInput(pki.getTestUser2Cert()));

        byte[] result = pkiMessages
                .createRevocationMessage(revocationInputs.toArray(new RevocationInput[revocationInputs.size()]));

        ASN1InputStream asn1InputStream = new ASN1InputStream(result);
        ASN1Primitive asn1Primitive = asn1InputStream.readObject();
        PKIMessage pkiMessage = PKIMessage.getInstance(asn1Primitive);

        // Check the Body
        Assert.assertEquals(PKIBody.TYPE_REVOCATION_REQ, pkiMessage.getBody().getType());
        RevDetails[] revDetailses = RevReqContent.getInstance(pkiMessage.getBody().getContent())
                .toRevDetailsArray();
        Assert.assertEquals(pki.getTestUser1Cert().getIssuerDN().getName().toString(),
                revDetailses[0].getCertDetails().getIssuer().toString());
        Assert.assertEquals(pki.getTestUser1Cert().getSerialNumber(),
                revDetailses[0].getCertDetails().getSerialNumber().getValue());
        Assert.assertEquals(pki.getTestUser1Cert().getSubjectDN().getName().toString(),
                revDetailses[0].getCertDetails().getSubject().toString());
        Assert.assertArrayEquals(pki.getTestUser1Cert().getPublicKey().getEncoded(),
                revDetailses[0].getCertDetails().getPublicKey().getEncoded());
        Assert.assertNull(revDetailses[0].getCrlEntryDetails());
        Assert.assertEquals(pki.getTestUser2Cert().getIssuerDN().getName().toString(),
                revDetailses[1].getCertDetails().getIssuer().toString());
        Assert.assertEquals(pki.getTestUser2Cert().getSerialNumber(),
                revDetailses[1].getCertDetails().getSerialNumber().getValue());
        Assert.assertEquals(pki.getTestUser2Cert().getSubjectDN().getName().toString(),
                revDetailses[1].getCertDetails().getSubject().toString());
        Assert.assertArrayEquals(pki.getTestUser2Cert().getPublicKey().getEncoded(),
                revDetailses[1].getCertDetails().getPublicKey().getEncoded());
        Assert.assertNull(revDetailses[1].getCrlEntryDetails());
    }

    /**
     * Test the confirmation message from the certification authority
     *
     * @throws IOException
     * @throws CertificateEncodingException
     * @throws OperatorCreationException
     * @throws CMPException
     */
    @Test
    public void testRevocationMessageWithExtensions()
            throws IOException, CertificateEncodingException, OperatorCreationException, CMPException,
            PKICMPMessageException, CRMFException, IllegalAccessException, CMSException, NoSuchFieldException {
        PKICMPMessages pkiMessages = new PKICMPMessages();
        pkiMessages.setPkiKeyStore(pkiKeyStoreRA);
        List<RevocationInput> revocationInputs = new ArrayList<RevocationInput>(2);
        Date invalidityDate = new Date(System.currentTimeMillis() - 500L * 60 * 60 * 24 * 30);
        revocationInputs.add(new RevocationInput(pki.getTestUser1Cert(), RevocationInput.aACompromise));
        revocationInputs
                .add(new RevocationInput(pki.getTestUser2Cert(), RevocationInput.noReasonCode, invalidityDate));

        byte[] result = pkiMessages
                .createRevocationMessage(revocationInputs.toArray(new RevocationInput[revocationInputs.size()]));

        ASN1InputStream asn1InputStream = new ASN1InputStream(result);
        ASN1Primitive asn1Primitive = asn1InputStream.readObject();
        PKIMessage pkiMessage = PKIMessage.getInstance(asn1Primitive);

        // Check the Body
        Assert.assertEquals(PKIBody.TYPE_REVOCATION_REQ, pkiMessage.getBody().getType());
        RevDetails[] revDetailses = RevReqContent.getInstance(pkiMessage.getBody().getContent())
                .toRevDetailsArray();
        Assert.assertEquals(pki.getTestUser1Cert().getIssuerDN().getName().toString(),
                revDetailses[0].getCertDetails().getIssuer().toString());
        Assert.assertEquals(pki.getTestUser1Cert().getSerialNumber(),
                revDetailses[0].getCertDetails().getSerialNumber().getValue());
        Assert.assertEquals(pki.getTestUser1Cert().getSubjectDN().getName().toString(),
                revDetailses[0].getCertDetails().getSubject().toString());
        Assert.assertArrayEquals(pki.getTestUser1Cert().getPublicKey().getEncoded(),
                revDetailses[0].getCertDetails().getPublicKey().getEncoded());
        Assert.assertNotNull(revDetailses[0].getCrlEntryDetails());
        Assert.assertNull(revDetailses[0].getCrlEntryDetails().getExtensionParsedValue(Extension.invalidityDate));
        ReasonFlags reasonFlags = new ReasonFlags(ReasonFlags
                .getInstance(revDetailses[0].getCrlEntryDetails().getExtensionParsedValue(Extension.reasonCode)));
        Assert.assertEquals(RevocationInput.aACompromise, reasonFlags.intValue());
        Assert.assertEquals(pki.getTestUser2Cert().getIssuerDN().getName().toString(),
                revDetailses[1].getCertDetails().getIssuer().toString());
        Assert.assertEquals(pki.getTestUser2Cert().getSerialNumber(),
                revDetailses[1].getCertDetails().getSerialNumber().getValue());
        Assert.assertEquals(pki.getTestUser2Cert().getSubjectDN().getName().toString(),
                revDetailses[1].getCertDetails().getSubject().toString());
        Assert.assertArrayEquals(pki.getTestUser2Cert().getPublicKey().getEncoded(),
                revDetailses[1].getCertDetails().getPublicKey().getEncoded());
        Assert.assertNotNull(revDetailses[1].getCrlEntryDetails());
        Assert.assertNull(revDetailses[1].getCrlEntryDetails().getExtensionParsedValue(Extension.reasonCode));
        Time tmp = new Time(revDetailses[1].getCrlEntryDetails().getExtensionParsedValue(Extension.invalidityDate)
                .toASN1Primitive());
        Assert.assertEquals(invalidityDate.toString(), tmp.getDate().toString());
    }

    //The test response creation for testing the decoding of the responses
    private byte[] createProtectedPKIMessage(byte[] senderNonce, byte[] transactionId, PKIBody pkiBody)
            throws CMPException, OperatorCreationException, IOException, CertificateEncodingException,
            PKICMPMessageException {
        byte[] recipientNonce = new byte[64];

        pkiKeyStoreCA.getSecureRandom().nextBytes(recipientNonce);

        ContentSigner signer = new JcaContentSignerBuilder("SHA1WithRSAEncryption")
                .setProvider(pkiKeyStoreCA.getProvider()).build(pkiKeyStoreCA.getSenderPrivateKey());
        ProtectedPKIMessage message = new ProtectedPKIMessageBuilder(
                new GeneralName(JcaX500NameUtil.getSubject(pkiKeyStoreCA.getSenderCertificate())),
                new GeneralName(JcaX500NameUtil.getSubject(pkiKeyStoreCA.getRecipientCertificate())))
                        .setMessageTime(new Date()).setSenderNonce(recipientNonce).setRecipNonce(senderNonce)
                        .setTransactionID(transactionId)
                        .addCMPCertificate(
                                new X509CertificateHolder(pkiKeyStoreCA.getSenderCertificate().getEncoded()))
                        .setBody(pkiBody).build(signer);

        return message.toASN1Structure().getEncoded();
    }

    private byte[] createInitializationRespons1(byte[] senderNonce, byte[] transactionId) throws CMPException,
            CertificateEncodingException, OperatorCreationException, PKICMPMessageException, IOException {
        X509CertificateHolder x509CertificateHolder = new JcaX509CertificateHolder(pki.getTestUser3Cert());

        // Body
        CertResponse certResponse = new CertResponse(new ASN1Integer(0), new PKIStatusInfo(PKIStatus.granted),
                new CertifiedKeyPair(
                        new CertOrEncCert(new CMPCertificate(x509CertificateHolder.toASN1Structure()))),
                null);
        CertResponse[] certResponses = new CertResponse[1];
        certResponses[0] = certResponse;

        PKIBody pkiBody = new PKIBody(PKIBody.TYPE_INIT_REP,
                new CertRepMessage(pkiKeyStoreCA.getCMPCertificateChain(), certResponses));

        return createProtectedPKIMessage(senderNonce, transactionId, pkiBody);

    }

    private byte[] createInitializationRespons2(byte[] senderNonce, byte[] transactionId) throws CMPException,
            CertificateEncodingException, OperatorException, PKICMPMessageException, IOException, CRMFException {
        X509CertificateHolder x509CertificateHolder = new JcaX509CertificateHolder(pki.getTestUser3Cert());

        //encrypt Private Key
        KeyWrapper keyWrapper = new JceAsymmetricKeyWrapper(pkiKeyStoreCA.getRecipientCertificate().getPublicKey())
                .setProvider("BC");
        OutputEncryptor encryptor = new JceCRMFEncryptorBuilder(CMSAlgorithm.DES_EDE3_CBC).setProvider("BC")
                .build();
        ByteArrayOutputStream bOut = new ByteArrayOutputStream();

        OutputStream eOut = encryptor.getOutputStream(bOut);
        eOut.write(pki.getTestUser3CertPrivateKey().getEncoded());
        eOut.close();

        AlgorithmIdentifier intendedAlg = null;
        AlgorithmIdentifier symmAlg = encryptor.getAlgorithmIdentifier();
        DERBitString encSymmKey;
        keyWrapper.generateWrappedKey(encryptor.getKey());
        encSymmKey = new DERBitString(keyWrapper.generateWrappedKey(encryptor.getKey()));

        AlgorithmIdentifier keyAlg = keyWrapper.getAlgorithmIdentifier();
        ASN1OctetString valueHint = null;
        DERBitString encValue = new DERBitString(bOut.toByteArray());

        EncryptedValue encryptedPrivateKey = new EncryptedValue(intendedAlg, symmAlg, encSymmKey, keyAlg, valueHint,
                encValue);

        // Body
        CertResponse certResponse = new CertResponse(new ASN1Integer(0), new PKIStatusInfo(PKIStatus.granted),
                new CertifiedKeyPair(new CertOrEncCert(new CMPCertificate(x509CertificateHolder.toASN1Structure())),
                        encryptedPrivateKey, null),
                null);
        CertResponse[] certResponses = new CertResponse[1];
        certResponses[0] = certResponse;

        PKIBody pkiBody = new PKIBody(PKIBody.TYPE_INIT_REP,
                new CertRepMessage(pkiKeyStoreCA.getCMPCertificateChain(), certResponses));

        return createProtectedPKIMessage(senderNonce, transactionId, pkiBody);

    }

    private byte[] createRevocationRespons1(byte[] senderNonce, byte[] transactionId)
            throws CRLException, CMPException, CertificateEncodingException, OperatorCreationException,
            PKICMPMessageException, IOException {

        RevRepContentBuilder revRepContentBuilder = new RevRepContentBuilder();
        revRepContentBuilder.add(new PKIStatusInfo(PKIStatus.granted),
                new CertId(new GeneralName(JcaX500NameUtil.getIssuer(pki.getRevokedCert())),
                        pki.getRevokedCert().getSerialNumber()));
        revRepContentBuilder.addCrl(new JcaX509CRLHolder(pki.getX509CRL()).toASN1Structure());

        PKIBody pkiBody = new PKIBody(PKIBody.TYPE_REVOCATION_REP, revRepContentBuilder.build());

        return createProtectedPKIMessage(senderNonce, transactionId, pkiBody);

    }

    @Test
    public void testProcessMessage() throws NoSuchProviderException, NoSuchAlgorithmException, CertificateException,
            NoSuchFieldException, PKICMPMessageException, OperatorCreationException, IOException, CRMFException,
            CMPException, IllegalAccessException, CMSException, PKIKeyStoreException, ParseException {
        String distinguishedName = pki.getTestUser3Cert().getSubjectX500Principal().getName();

        KeyPair keyPair = new KeyPair(pki.getTestUser3Cert().getPublicKey(), pki.getTestUser3CertPrivateKey());

        PKICMPMessages pkiMessages = new PKICMPMessages();
        pkiMessages.setPkiKeyStore(pkiKeyStoreRA);
        byte[] request = pkiMessages.createInitializationMessage(distinguishedName, keyPair);

        byte[] response = createInitializationRespons1(pkiMessages.getSenderNonce(),
                pkiMessages.getTransactionId());

        PKICMPResponse pkicmpResponse = pkiMessages.processResponse(response);

        Assert.assertEquals(PKIBody.TYPE_INIT_REP, pkicmpResponse.getPkiBody().getType());
    }

    @Test(expected = PKICMPMessageException.class)
    public void testProcessMessageIllegalNonce()
            throws NoSuchProviderException, NoSuchAlgorithmException, CertificateException, NoSuchFieldException,
            PKICMPMessageException, OperatorCreationException, IOException, CRMFException, CMPException,
            IllegalAccessException, CMSException, PKIKeyStoreException, ParseException {
        String distinguishedName = pki.getTestUser3Cert().getSubjectX500Principal().getName();
        KeyPair keyPair = new KeyPair(pki.getTestUser3Cert().getPublicKey(), pki.getTestUser3CertPrivateKey());

        byte[] senderNonce = new byte[64];
        pkiKeyStoreRA.getSecureRandom().nextBytes(senderNonce);

        PKICMPMessages pkiMessages = new PKICMPMessages();
        pkiMessages.setPkiKeyStore(pkiKeyStoreRA);
        byte[] request = pkiMessages.createInitializationMessage(distinguishedName, keyPair);

        byte[] response = createInitializationRespons1(senderNonce, pkiMessages.getTransactionId());

        PKICMPResponse pkicmpResponse = pkiMessages.processResponse(response);

    }

    @Test(expected = PKICMPMessageException.class)
    public void testProcessMessageVerificationFailed()
            throws NoSuchProviderException, NoSuchAlgorithmException, CertificateException, NoSuchFieldException,
            PKICMPMessageException, OperatorCreationException, IOException, CRMFException, CMPException,
            IllegalAccessException, CMSException, PKIKeyStoreException, ParseException {
        String distinguishedName = pki.getTestUser3Cert().getSubjectX500Principal().getName();
        KeyPair keyPair = new KeyPair(pki.getTestUser3Cert().getPublicKey(), pki.getTestUser3CertPrivateKey());

        PKIKeyStore invalidKeyStore = new PKIKeyStore(pki.getTestUser1CertPrivateKey(), pki.getSubCACert(),
                pki.getRACert(), pki.getCertificateChain());
        PKIKeyStore tmpKeyStore = pkiKeyStoreCA;
        pkiKeyStoreCA = invalidKeyStore;

        PKICMPMessages pkiMessages = new PKICMPMessages();
        pkiMessages.setPkiKeyStore(pkiKeyStoreRA);
        byte[] request = pkiMessages.createInitializationMessage(distinguishedName, keyPair);

        byte[] response = createInitializationRespons1(pkiMessages.getSenderNonce(),
                pkiMessages.getTransactionId());
        pkiKeyStoreCA = tmpKeyStore;

        PKICMPResponse pkicmpResponse = pkiMessages.processResponse(response);

    }

    /**
     * Test the certification response decoding without a private key
     *
     * @throws NoSuchProviderException
     * @throws NoSuchAlgorithmException
     * @throws CertificateException
     * @throws NoSuchFieldException
     * @throws PKICMPMessageException
     * @throws OperatorCreationException
     * @throws IOException
     * @throws CRMFException
     * @throws CMPException
     * @throws IllegalAccessException
     * @throws CMSException
     * @throws PKIKeyStoreException
     * @throws ParseException
     * @throws InvalidKeySpecException
     */
    @Test
    public void testProcessInitializationMessageWithoutPrivateKey()
            throws NoSuchProviderException, NoSuchAlgorithmException, CertificateException, NoSuchFieldException,
            PKICMPMessageException, OperatorCreationException, IOException, CRMFException, CMPException,
            IllegalAccessException, CMSException, PKIKeyStoreException, ParseException, InvalidKeySpecException {
        String distinguishedName = pki.getTestUser3Cert().getSubjectX500Principal().getName();

        KeyPair keyPair = new KeyPair(pki.getTestUser3Cert().getPublicKey(), pki.getTestUser3CertPrivateKey());

        PKICMPMessages pkiMessages = new PKICMPMessages();
        pkiMessages.setPkiKeyStore(pkiKeyStoreRA);
        byte[] request = pkiMessages.createInitializationMessage(distinguishedName, keyPair);

        byte[] response = createInitializationRespons1(pkiMessages.getSenderNonce(),
                pkiMessages.getTransactionId());

        PKICMPResponse pkicmpResponse = pkiMessages.processResponse(response);

        CertificationResult certificationResult = pkiMessages.processCertification(pkicmpResponse.getPkiBody());

        Assert.assertEquals(PKIBody.TYPE_INIT_REP, pkicmpResponse.getPkiBody().getType());
        Assert.assertArrayEquals(pki.getTestUser3Cert().getEncoded(),
                certificationResult.getX509Certificate().getEncoded());
        Assert.assertNull(certificationResult.getPrivateKey());
        Assert.assertEquals(0, certificationResult.getCertificateId().intValue());
        Assert.assertArrayEquals(pki.getCertificateChain()[0].getEncoded(),
                certificationResult.getX509CertificateChain()[0].getEncoded());
        Assert.assertArrayEquals(pki.getCertificateChain()[1].getEncoded(),
                certificationResult.getX509CertificateChain()[1].getEncoded());
    }

    /**
     * Test the certification response decoding with a private key encryption and decryption
     *
     * @throws NoSuchProviderException
     * @throws NoSuchAlgorithmException
     * @throws CertificateException
     * @throws NoSuchFieldException
     * @throws PKICMPMessageException
     * @throws OperatorCreationException
     * @throws IOException
     * @throws CRMFException
     * @throws CMPException
     * @throws IllegalAccessException
     * @throws CMSException
     * @throws PKIKeyStoreException
     * @throws ParseException
     * @throws InvalidKeySpecException
     */
    @Test
    public void testProcessInitializationMessageWithPrivateKey()
            throws NoSuchProviderException, NoSuchAlgorithmException, CertificateException, NoSuchFieldException,
            PKICMPMessageException, OperatorException, IOException, CRMFException, CMPException,
            IllegalAccessException, CMSException, PKIKeyStoreException, ParseException, InvalidKeySpecException {
        String distinguishedName = pki.getTestUser3Cert().getSubjectX500Principal().getName();

        KeyPair keyPair = new KeyPair(pki.getTestUser3Cert().getPublicKey(), pki.getTestUser3CertPrivateKey());

        PKICMPMessages pkiMessages = new PKICMPMessages();
        pkiMessages.setPkiKeyStore(pkiKeyStoreRA);
        byte[] request = pkiMessages.createInitializationMessage(distinguishedName, keyPair);

        byte[] response = createInitializationRespons2(pkiMessages.getSenderNonce(),
                pkiMessages.getTransactionId());

        PKICMPResponse pkicmpResponse = pkiMessages.processResponse(response);

        CertificationResult certificationResult = pkiMessages.processCertification(pkicmpResponse.getPkiBody());

        Assert.assertEquals(PKIBody.TYPE_INIT_REP, pkicmpResponse.getPkiBody().getType());
        Assert.assertArrayEquals(pki.getTestUser3Cert().getEncoded(),
                certificationResult.getX509Certificate().getEncoded());
        Assert.assertArrayEquals(pki.getTestUser3CertPrivateKey().getEncoded(),
                certificationResult.getPrivateKey().getEncoded());
        Assert.assertEquals(0, certificationResult.getCertificateId().intValue());
        Assert.assertArrayEquals(pki.getCertificateChain()[0].getEncoded(),
                certificationResult.getX509CertificateChain()[0].getEncoded());
        Assert.assertArrayEquals(pki.getCertificateChain()[1].getEncoded(),
                certificationResult.getX509CertificateChain()[1].getEncoded());
    }

    /**
     * This test the revocation response message
     *
     * @throws IOException
     * @throws CertificateException
     * @throws CRMFException
     * @throws CMSException
     * @throws NoSuchFieldException
     * @throws CMPException
     * @throws IllegalAccessException
     * @throws OperatorCreationException
     * @throws PKICMPMessageException
     * @throws CRLException
     * @throws ParseException
     * @throws PKIKeyStoreException
     * @throws NoSuchProviderException
     * @throws NoSuchAlgorithmException
     * @throws InvalidKeyException
     * @throws SignatureException
     */
    @Test
    public void testProcessRevocationMessage() throws IOException, CertificateException, CRMFException,
            CMSException, NoSuchFieldException, CMPException, IllegalAccessException, OperatorCreationException,
            PKICMPMessageException, CRLException, ParseException, PKIKeyStoreException, NoSuchProviderException,
            NoSuchAlgorithmException, InvalidKeyException, SignatureException {
        PKICMPMessages pkiMessages = new PKICMPMessages();

        pkiMessages.setPkiKeyStore(pkiKeyStoreRA);

        List<RevocationInput> revocationInputs = new ArrayList<RevocationInput>(2);
        Date invalidityDate = new Date(System.currentTimeMillis() - 500L * 60 * 60 * 24 * 30);
        revocationInputs.add(new RevocationInput(pki.getTestUser3Cert(), RevocationInput.aACompromise));
        revocationInputs
                .add(new RevocationInput(pki.getTestUser4Cert(), RevocationInput.noReasonCode, invalidityDate));

        byte[] request = pkiMessages
                .createRevocationMessage(revocationInputs.toArray(new RevocationInput[revocationInputs.size()]));

        byte[] response = createRevocationRespons1(pkiMessages.getSenderNonce(), pkiMessages.getTransactionId());

        PKICMPResponse pkicmpResponse = pkiMessages.processResponse(response);

        X509CRL x509CRL = pkiMessages.processRevocation(pkicmpResponse.getPkiBody());

        x509CRL.verify(pkiKeyStoreRA.getRecipientCertificate().getPublicKey());
        Assert.assertEquals(pkiKeyStoreRA.getRecipientCertificate().getSubjectX500Principal().getName(),
                x509CRL.getIssuerX500Principal().getName());
        Assert.assertNotNull(x509CRL.getRevokedCertificate(BigInteger.valueOf(40)));
    }
}