Example usage for org.bouncycastle.cms CMSEnvelopedData getRecipientInfos

List of usage examples for org.bouncycastle.cms CMSEnvelopedData getRecipientInfos

Introduction

In this page you can find the example usage for org.bouncycastle.cms CMSEnvelopedData getRecipientInfos.

Prototype

public RecipientInformationStore getRecipientInfos() 

Source Link

Document

return a store of the intended recipients for this message

Usage

From source file:io.aos.crypto.spl09.KeyTransEnvelopedDataExample.java

License:Apache License

public static void main(String... args) throws Exception {
    KeyStore credentials = Utils.createCredentials();
    PrivateKey key = (PrivateKey) credentials.getKey(Utils.END_ENTITY_ALIAS, Utils.KEY_PASSWD);
    Certificate[] chain = credentials.getCertificateChain(Utils.END_ENTITY_ALIAS);
    X509Certificate cert = (X509Certificate) chain[0];

    // set up the generator
    CMSEnvelopedDataGenerator gen = new CMSEnvelopedDataGenerator();

    gen.addKeyTransRecipient(cert);//ww w .j a va  2  s.  c  om

    // create the enveloped-data object
    CMSProcessable data = new CMSProcessableByteArray("Hello World!".getBytes());

    CMSEnvelopedData enveloped = gen.generate(data, CMSEnvelopedDataGenerator.AES128_CBC, "BC");

    // recreate
    enveloped = new CMSEnvelopedData(enveloped.getEncoded());

    // look for our recipient identifier
    RecipientId recId = new KEKRecipientId(null);

    recId.setSerialNumber(cert.getSerialNumber());
    recId.setIssuer(cert.getIssuerX500Principal().getEncoded());

    RecipientInformationStore recipients = enveloped.getRecipientInfos();
    RecipientInformation recipient = recipients.get(recId);

    if (recipient != null) {
        // decrypt the data
        byte[] recData = recipient.getContent(key, "BC");

        // compare recovered data to the original data
        if (Arrays.equals((byte[]) data.getContent(), recData)) {
            System.out.println("data recovery succeeded");
        } else {
            System.out.println("data recovery failed");
        }
    } else {
        System.out.println("could not find a matching recipient");
    }
}

From source file:io.aos.crypto.spl09.KeyTransEnvelopedDataWithCertMatchExample.java

License:Apache License

public static void main(String... args) throws Exception {
    KeyStore credentials = Utils.createCredentials();
    PrivateKey key = (PrivateKey) credentials.getKey(Utils.END_ENTITY_ALIAS, Utils.KEY_PASSWD);
    Certificate[] chain = credentials.getCertificateChain(Utils.END_ENTITY_ALIAS);
    X509Certificate cert = (X509Certificate) chain[0];

    // set up the generator
    CMSEnvelopedDataGenerator gen = new CMSEnvelopedDataGenerator();

    gen.addKeyTransRecipient(cert);//from   w  w  w. j av  a2 s .  c om

    // create the enveloped-data object
    CMSProcessable data = new CMSProcessableByteArray("Hello World!".getBytes());

    CMSEnvelopedData enveloped = gen.generate(data, CMSEnvelopedDataGenerator.AES256_CBC, "BC");

    // recreate
    enveloped = new CMSEnvelopedData(enveloped.getEncoded());

    // set up to iterate through the recipients
    RecipientInformationStore recipients = enveloped.getRecipientInfos();
    CertStore certStore = CertStore.getInstance("Collection",
            new CollectionCertStoreParameters(Collections.singleton(cert)), "BC");
    Iterator it = recipients.getRecipients().iterator();
    RecipientInformation recipient = null;

    while (it.hasNext()) {
        recipient = (RecipientInformation) it.next();
        if (recipient instanceof KeyTransRecipientInformation) {
            // match the recipient ID
            Collection matches = certStore.getCertificates(recipient.getRID());

            if (!matches.isEmpty()) {
                // decrypt the data
                byte[] recData = recipient.getContent(key, "BC");

                // compare recovered data to the original data
                if (Arrays.equals((byte[]) data.getContent(), recData)) {
                    System.out.println("data recovery succeeded");
                    break;
                } else {
                    System.out.println("data recovery failed");
                    break;
                }
            }
        }
    }

    if (recipient == null) {
        System.out.println("could not find a matching recipient");
    }
}

From source file:org.apache.kerby.pkix.EnvelopedDataEngine.java

License:Apache License

/**
 * Uses a private key to decrypt data in a CMS EnvelopedData structure and
 * returns the recovered (decrypted) data bytes.
 *
 * @param envelopedDataBytes//from   ww w  .  ja  va 2  s  .  c o m
 * @param privateKey
 * @return The recovered (decrypted) data bytes.
 * @throws IOException
 * @throws CMSException
 */
@SuppressWarnings("unchecked")
public static byte[] getUnenvelopedData(byte[] envelopedDataBytes, PrivateKey privateKey)
        throws CMSException, IOException {
    CMSEnvelopedData envelopedData = new CMSEnvelopedData(envelopedDataBytes);

    // Set up to iterate through the recipients.
    RecipientInformationStore recipients = envelopedData.getRecipientInfos();
    Collection c = recipients.getRecipients();
    Iterator it = c.iterator();

    byte[] recData = new byte[0];
    while (it.hasNext()) {
        RecipientInformation recipient = (RecipientInformation) it.next();

        recData = recipient.getContent(new BcRSAKeyTransEnvelopedRecipient(
                PrivateKeyFactory.createKey(PrivateKeyInfo.getInstance(privateKey.getEncoded()))));
    }
    return recData;
}

From source file:org.apache.pdfbox.pdmodel.encryption.PublicKeySecurityHandler.java

License:Apache License

/**
 * Prepares everything to decrypt the document.
 *
 * If {@link #decryptDocument(PDDocument, DecryptionMaterial)} is used, this method is
 * called from there. Only if decryption of single objects is needed this should be called instead.
 *
 * @param encDictionary  encryption dictionary, can be retrieved via {@link PDDocument#getEncryptionDictionary()}
 * @param documentIDArray  document id which is returned via {@link COSDocument#getDocumentID()} (not used by this handler)
 * @param decryptionMaterial Information used to decrypt the document.
 *
 * @throws IOException If there is an error accessing data.
 * @throws CryptographyException If there is an error with decryption.
 *//*from   w  w w  .  j  a  va2s . co  m*/
public void prepareForDecryption(PDEncryptionDictionary encDictionary, COSArray documentIDArray,
        DecryptionMaterial decryptionMaterial) throws CryptographyException, IOException {

    if (encDictionary.getLength() != 0) {
        this.keyLength = encDictionary.getLength();
    }

    if (!(decryptionMaterial instanceof PublicKeyDecryptionMaterial)) {
        throw new CryptographyException("Provided decryption material is not compatible with the document");
    }

    PublicKeyDecryptionMaterial material = (PublicKeyDecryptionMaterial) decryptionMaterial;

    try {
        boolean foundRecipient = false;

        // the decrypted content of the enveloped data that match
        // the certificate in the decryption material provided
        byte[] envelopedData = null;

        // the bytes of each recipient in the recipients array
        byte[][] recipientFieldsBytes = new byte[encDictionary.getRecipientsLength()][];

        int recipientFieldsLength = 0;

        for (int i = 0; i < encDictionary.getRecipientsLength(); i++) {
            COSString recipientFieldString = encDictionary.getRecipientStringAt(i);
            byte[] recipientBytes = recipientFieldString.getBytes();
            CMSEnvelopedData data = new CMSEnvelopedData(recipientBytes);
            Iterator recipCertificatesIt = data.getRecipientInfos().getRecipients().iterator();
            while (recipCertificatesIt.hasNext()) {
                RecipientInformation ri = (RecipientInformation) recipCertificatesIt.next();
                // Impl: if a matching certificate was previously found it is an error,
                // here we just don't care about it
                if (ri.getRID().match(material.getCertificate()) && !foundRecipient) {
                    foundRecipient = true;
                    envelopedData = ri.getContent(material.getPrivateKey(), "BC");
                }
            }
            recipientFieldsBytes[i] = recipientBytes;
            recipientFieldsLength += recipientBytes.length;
        }
        if (!foundRecipient || envelopedData == null) {
            throw new CryptographyException("The certificate matches no recipient entry");
        }
        if (envelopedData.length != 24) {
            throw new CryptographyException("The enveloped data does not contain 24 bytes");
        }
        // now envelopedData contains:
        // - the 20 bytes seed
        // - the 4 bytes of permission for the current user

        byte[] accessBytes = new byte[4];
        System.arraycopy(envelopedData, 20, accessBytes, 0, 4);

        currentAccessPermission = new AccessPermission(accessBytes);
        currentAccessPermission.setReadOnly();

        // what we will put in the SHA1 = the seed + each byte contained in the recipients array
        byte[] sha1Input = new byte[recipientFieldsLength + 20];

        // put the seed in the sha1 input
        System.arraycopy(envelopedData, 0, sha1Input, 0, 20);

        // put each bytes of the recipients array in the sha1 input
        int sha1InputOffset = 20;
        for (int i = 0; i < recipientFieldsBytes.length; i++) {
            System.arraycopy(recipientFieldsBytes[i], 0, sha1Input, sha1InputOffset,
                    recipientFieldsBytes[i].length);
            sha1InputOffset += recipientFieldsBytes[i].length;
        }

        MessageDigest md = MessageDigest.getInstance("SHA-1");
        byte[] mdResult = md.digest(sha1Input);

        // we have the encryption key ...
        encryptionKey = new byte[this.keyLength / 8];
        System.arraycopy(mdResult, 0, encryptionKey, 0, this.keyLength / 8);
    } catch (CMSException e) {
        throw new CryptographyException(e);
    } catch (KeyStoreException e) {
        throw new CryptographyException(e);
    } catch (NoSuchProviderException e) {
        throw new CryptographyException(e);
    } catch (NoSuchAlgorithmException e) {
        throw new CryptographyException(e);
    }
}

From source file:org.cesecore.certificates.ca.X509CA.java

License:Open Source License

@Override
public KeyPair decryptKeys(CryptoToken cryptoToken, String alias, byte[] data)
        throws IOException, CMSException, CryptoTokenOfflineException, ClassNotFoundException {
    CMSEnvelopedData ed = new CMSEnvelopedData(data);
    RecipientInformationStore recipients = ed.getRecipientInfos();
    RecipientInformation recipient = (RecipientInformation) recipients.getRecipients().iterator().next();
    ObjectInputStream ois = null;
    JceKeyTransEnvelopedRecipient rec = new JceKeyTransEnvelopedRecipient(cryptoToken.getPrivateKey(alias));
    rec.setProvider(cryptoToken.getEncProviderName());
    rec.setContentProvider("BC");
    byte[] recdata = recipient.getContent(rec);
    ois = new ObjectInputStream(new ByteArrayInputStream(recdata));
    log.info("Decrypted keys using key alias '" + alias + "' from Crypto Token " + cryptoToken.getId());
    return (KeyPair) ois.readObject();
}

From source file:org.cesecore.certificates.ca.X509CA.java

License:Open Source License

@Override
public byte[] decryptData(CryptoToken cryptoToken, byte[] data, int cAKeyPurpose)
        throws CMSException, CryptoTokenOfflineException {
    CMSEnvelopedData ed = new CMSEnvelopedData(data);
    RecipientInformationStore recipients = ed.getRecipientInfos();
    RecipientInformation recipient = (RecipientInformation) recipients.getRecipients().iterator().next();
    final String keyAlias = getCAToken().getAliasFromPurpose(cAKeyPurpose);
    JceKeyTransEnvelopedRecipient rec = new JceKeyTransEnvelopedRecipient(cryptoToken.getPrivateKey(keyAlias));
    rec.setProvider(cryptoToken.getSignProviderName());
    rec.setContentProvider("BC");
    byte[] recdata = recipient.getContent(rec);
    log.info("Decrypted data using key alias '" + keyAlias + "' from Crypto Token " + cryptoToken.getId());
    return recdata;
}

From source file:org.ejbca.core.model.ca.caadmin.extendedcaservices.CmsCAService.java

License:Open Source License

@Override
public ExtendedCAServiceResponse extendedService(final CryptoToken cryptoToken,
        final ExtendedCAServiceRequest request) throws ExtendedCAServiceRequestException,
        IllegalExtendedCAServiceRequestException, ExtendedCAServiceNotActiveException {
    if (log.isTraceEnabled()) {
        log.trace(">extendedService");
    }//from  w w  w . j a  v  a2s  .  com
    if (!(request instanceof CmsCAServiceRequest)) {
        throw new IllegalExtendedCAServiceRequestException();
    }
    if (getStatus() != ExtendedCAServiceInfo.STATUS_ACTIVE) {
        final String msg = intres.getLocalizedMessage("caservice.notactive", "CMS");
        log.error(msg);
        throw new ExtendedCAServiceNotActiveException(msg);
    }
    ExtendedCAServiceResponse returnval = null;
    final X509Certificate signerCert = (X509Certificate) certificatechain.get(0);
    final CmsCAServiceRequest serviceReq = (CmsCAServiceRequest) request;
    // Create the signed data
    final CMSSignedDataGenerator gen1 = new CMSSignedDataGenerator();
    try {
        byte[] resp = serviceReq.getDoc();
        // Add our signer info and sign the message
        if ((serviceReq.getMode() & CmsCAServiceRequest.MODE_SIGN) != 0) {
            final List<X509Certificate> x509CertChain = new ArrayList<X509Certificate>();
            for (Certificate certificate : certificatechain) {
                x509CertChain.add((X509Certificate) certificate);
            }
            gen1.addCertificates(new CollectionStore(CertTools.convertToX509CertificateHolder(x509CertChain)));
            JcaDigestCalculatorProviderBuilder calculatorProviderBuilder = new JcaDigestCalculatorProviderBuilder()
                    .setProvider(BouncyCastleProvider.PROVIDER_NAME);
            JcaSignerInfoGeneratorBuilder builder = new JcaSignerInfoGeneratorBuilder(
                    calculatorProviderBuilder.build());
            ASN1ObjectIdentifier oid = AlgorithmTools
                    .getSignAlgOidFromDigestAndKey(CMSSignedGenerator.DIGEST_SHA1, privKey.getAlgorithm());
            String signatureAlgorithmName = AlgorithmTools.getAlgorithmNameFromOID(oid);
            JcaContentSignerBuilder signerBuilder = new JcaContentSignerBuilder(signatureAlgorithmName)
                    .setProvider(BouncyCastleProvider.PROVIDER_NAME);
            ContentSigner contentSigner = signerBuilder.build(privKey);
            gen1.addSignerInfoGenerator(builder.build(contentSigner, signerCert));
            final CMSTypedData msg = new CMSProcessableByteArray(resp);
            final CMSSignedData s = gen1.generate(msg, true);
            resp = s.getEncoded();
        }
        if ((serviceReq.getMode() & CmsCAServiceRequest.MODE_ENCRYPT) != 0) {
            CMSEnvelopedDataGenerator edGen = new CMSEnvelopedDataGenerator();
            edGen.addRecipientInfoGenerator(new JceKeyTransRecipientInfoGenerator(getCMSCertificate())
                    .setProvider(BouncyCastleProvider.PROVIDER_NAME));
            JceCMSContentEncryptorBuilder jceCMSContentEncryptorBuilder = new JceCMSContentEncryptorBuilder(
                    PKCSObjectIdentifiers.des_EDE3_CBC).setProvider(BouncyCastleProvider.PROVIDER_NAME);
            CMSEnvelopedData ed = edGen.generate(new CMSProcessableByteArray(resp),
                    jceCMSContentEncryptorBuilder.build());
            resp = ed.getEncoded();
        }
        if ((serviceReq.getMode() & CmsCAServiceRequest.MODE_DECRYPT) != 0) {
            final CMSEnvelopedData ed = new CMSEnvelopedData(resp);
            final RecipientInformationStore recipients = ed.getRecipientInfos();
            final X500Name issuer = X500Name
                    .getInstance(getCMSCertificate().getIssuerX500Principal().getEncoded());
            final KeyTransRecipientId id = new KeyTransRecipientId(issuer,
                    getCMSCertificate().getSerialNumber());
            final RecipientInformation recipient = recipients.get(id);
            if (recipient != null) {
                JceKeyTransEnvelopedRecipient rec = new JceKeyTransEnvelopedRecipient(this.privKey);
                // Provider for decrypting the symmetric key 
                rec.setContentProvider(BouncyCastleProvider.PROVIDER_NAME);
                rec.setProvider(cryptoToken.getSignProviderName());
                // We can use a different provider for decrypting the content, for example of we used a PKCS#11 provider above we could use the BC provider below
                resp = recipient.getContent(rec);
            }
        }
        returnval = new CmsCAServiceResponse(resp);
    } catch (CMSException e) {
        log.error("Error in CmsCAService", e);
        throw new ExtendedCAServiceRequestException(e);
    } catch (IOException e) {
        log.error("Error in CmsCAService", e);
        throw new ExtendedCAServiceRequestException(e);
    } catch (OperatorCreationException e) {
        log.error("Error in CmsCAService", e);
        throw new ExtendedCAServiceRequestException(e);
    } catch (CertificateEncodingException e) {
        log.error("Error in CmsCAService", e);
        throw new ExtendedCAServiceRequestException(e);
    }
    if (log.isTraceEnabled()) {
        log.trace("<extendedService");
    }
    return returnval;
}

From source file:org.ejbca.core.model.ca.caadmin.X509CA.java

License:Open Source License

public KeyPair decryptKeys(byte[] data) throws Exception {
    CMSEnvelopedData ed = new CMSEnvelopedData(data);

    RecipientInformationStore recipients = ed.getRecipientInfos();
    Iterator it = recipients.getRecipients().iterator();
    RecipientInformation recipient = (RecipientInformation) it.next();
    ObjectInputStream ois = null;
    byte[] recdata = recipient.getContent(getCAToken().getPrivateKey(SecConst.CAKEYPURPOSE_KEYENCRYPT),
            getCAToken().getJCEProvider());
    ois = new ObjectInputStream(new ByteArrayInputStream(recdata));

    return (KeyPair) ois.readObject();
}

From source file:org.ejbca.core.model.ca.caadmin.X509CA.java

License:Open Source License

public byte[] decryptData(byte[] data, int cAKeyPurpose) throws Exception {
    CMSEnvelopedData ed = new CMSEnvelopedData(data);
    RecipientInformationStore recipients = ed.getRecipientInfos();
    Iterator it = recipients.getRecipients().iterator();
    RecipientInformation recipient = (RecipientInformation) it.next();
    byte[] recdata = recipient.getContent(getCAToken().getPrivateKey(cAKeyPurpose), getCAToken().getProvider());

    return recdata;
}

From source file:org.ejbca.core.protocol.scep.ProtocolScepHttpTest.java

License:Open Source License

private void checkScepResponse(byte[] retMsg, String userDN, String _senderNonce, String _transId,
        boolean crlRep, String digestOid, boolean noca)
        throws CMSException, OperatorCreationException, NoSuchProviderException, CRLException,
        InvalidKeyException, NoSuchAlgorithmException, SignatureException, CertificateException {

    // Parse response message
    ///*w  w w  .  ja  v a2s. c om*/
    CMSSignedData s = new CMSSignedData(retMsg);
    // The signer, i.e. the CA, check it's the right CA
    SignerInformationStore signers = s.getSignerInfos();
    @SuppressWarnings("unchecked")
    Collection<SignerInformation> col = signers.getSigners();
    assertTrue(col.size() > 0);
    Iterator<SignerInformation> iter = col.iterator();
    SignerInformation signerInfo = 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(cacert.getIssuerDN().getName()),
            CertTools.stringToBCDNString(sinfo.getIssuer().toString()));
    // Verify the signature
    JcaDigestCalculatorProviderBuilder calculatorProviderBuilder = new JcaDigestCalculatorProviderBuilder()
            .setProvider(BouncyCastleProvider.PROVIDER_NAME);
    JcaSignerInfoVerifierBuilder jcaSignerInfoVerifierBuilder = new JcaSignerInfoVerifierBuilder(
            calculatorProviderBuilder.build()).setProvider(BouncyCastleProvider.PROVIDER_NAME);
    boolean ret = signerInfo.verify(jcaSignerInfoVerifierBuilder.build(cacert.getPublicKey()));
    assertTrue(ret);
    // Get authenticated attributes
    AttributeTable tab = signerInfo.getSignedAttributes();
    // --Fail info
    Attribute attr = tab.get(new ASN1ObjectIdentifier(ScepRequestMessage.id_failInfo));
    // No failInfo on this success message
    assertNull(attr);
    // --Message type
    attr = tab.get(new ASN1ObjectIdentifier(ScepRequestMessage.id_messageType));
    assertNotNull(attr);
    ASN1Set values = attr.getAttrValues();
    assertEquals(values.size(), 1);
    ASN1String str = DERPrintableString.getInstance((values.getObjectAt(0)));
    String messageType = str.getString();
    assertEquals("3", messageType);
    // --Success status
    attr = tab.get(new ASN1ObjectIdentifier(ScepRequestMessage.id_pkiStatus));
    assertNotNull(attr);
    values = attr.getAttrValues();
    assertEquals(values.size(), 1);
    str = DERPrintableString.getInstance((values.getObjectAt(0)));
    assertEquals(ResponseStatus.SUCCESS.getStringValue(), str.getString());
    // --SenderNonce
    attr = tab.get(new ASN1ObjectIdentifier(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 ASN1ObjectIdentifier(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 ASN1ObjectIdentifier(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 (messageType.equals("3")) {
        // First we extract the encrypted data from the CMS enveloped data
        // contained
        // within the CMS signed data
        final CMSProcessable sp = s.getSignedContent();
        final byte[] content = (byte[]) sp.getContent();
        final CMSEnvelopedData ed = new CMSEnvelopedData(content);
        final RecipientInformationStore recipients = ed.getRecipientInfos();
        Store certstore;

        @SuppressWarnings("unchecked")
        Collection<RecipientInformation> c = recipients.getRecipients();
        assertEquals(c.size(), 1);
        Iterator<RecipientInformation> riIterator = c.iterator();
        byte[] decBytes = null;
        RecipientInformation recipient = riIterator.next();
        JceKeyTransEnvelopedRecipient rec = new JceKeyTransEnvelopedRecipient(key1.getPrivate());
        rec.setContentProvider(BouncyCastleProvider.PROVIDER_NAME);
        decBytes = recipient.getContent(rec);
        // This is yet another CMS signed data
        CMSSignedData sd = new CMSSignedData(decBytes);
        // Get certificates from the signed data
        certstore = sd.getCertificates();

        if (crlRep) {
            // We got a reply with a requested CRL
            @SuppressWarnings("unchecked")
            final Collection<X509CRLHolder> crls = (Collection<X509CRLHolder>) sd.getCRLs().getMatches(null);
            assertEquals(crls.size(), 1);
            final Iterator<X509CRLHolder> it = crls.iterator();
            // CRL is first (and only)
            final X509CRL retCrl = new JcaX509CRLConverter().getCRL(it.next());
            log.info("Got CRL with DN: " + retCrl.getIssuerDN().getName());

            // check the returned CRL
            assertEquals(CertTools.getSubjectDN(cacert), CertTools.getIssuerDN(retCrl));
            retCrl.verify(cacert.getPublicKey());
        } else {
            // We got a reply with a requested certificate
            @SuppressWarnings("unchecked")
            final Collection<X509CertificateHolder> certs = (Collection<X509CertificateHolder>) certstore
                    .getMatches(null);
            // 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);
            }
            final Iterator<X509CertificateHolder> it = certs.iterator();
            // Issued certificate must be first
            boolean verified = false;
            boolean gotcacert = false;
            JcaX509CertificateConverter jcaX509CertificateConverter = new JcaX509CertificateConverter();
            while (it.hasNext()) {
                X509Certificate retcert = jcaX509CertificateConverter.getCertificate(it.next());
                log.info("Got cert with DN: " + retcert.getSubjectDN().getName());

                // check the returned certificate
                String subjectdn = CertTools.stringToBCDNString(retcert.getSubjectDN().getName());
                if (CertTools.stringToBCDNString(userDN).equals(subjectdn)) {
                    // issued certificate
                    assertEquals(CertTools.stringToBCDNString(userDN), subjectdn);
                    assertEquals(CertTools.getSubjectDN(cacert), CertTools.getIssuerDN(retcert));
                    retcert.verify(cacert.getPublicKey());
                    assertTrue(checkKeys(key1.getPrivate(), retcert.getPublicKey()));
                    verified = true;
                } else {
                    // ca certificate
                    assertEquals(CertTools.getSubjectDN(cacert), CertTools.getSubjectDN(retcert));
                    gotcacert = true;
                }
            }
            assertTrue(verified);
            if (noca) {
                assertFalse(gotcacert);
            } else {
                assertTrue(gotcacert);
            }
        }
    }

}