Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.com/quite/humla-spongycastle.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'pkix/src/test/java/org/spongycastle/cert')
-rw-r--r--pkix/src/test/java/org/spongycastle/cert/cmp/test/AllTests.java317
-rw-r--r--pkix/src/test/java/org/spongycastle/cert/crmf/test/AllTests.java384
-rw-r--r--pkix/src/test/java/org/spongycastle/cert/ocsp/test/AllTests.java44
-rw-r--r--pkix/src/test/java/org/spongycastle/cert/ocsp/test/OCSPTest.java972
-rw-r--r--pkix/src/test/java/org/spongycastle/cert/ocsp/test/OCSPTestUtil.java177
-rw-r--r--pkix/src/test/java/org/spongycastle/cert/path/test/CertPathTest.java369
-rw-r--r--pkix/src/test/java/org/spongycastle/cert/path/test/CertPathValidationTest.java403
-rw-r--r--pkix/src/test/java/org/spongycastle/cert/test/AllTests.java57
-rw-r--r--pkix/src/test/java/org/spongycastle/cert/test/AttrCertSelectorTest.java243
-rw-r--r--pkix/src/test/java/org/spongycastle/cert/test/AttrCertTest.java667
-rw-r--r--pkix/src/test/java/org/spongycastle/cert/test/BcAttrCertSelectorTest.java212
-rw-r--r--pkix/src/test/java/org/spongycastle/cert/test/BcAttrCertTest.java636
-rw-r--r--pkix/src/test/java/org/spongycastle/cert/test/BcCertTest.java1434
-rw-r--r--pkix/src/test/java/org/spongycastle/cert/test/BcPKCS10Test.java230
-rw-r--r--pkix/src/test/java/org/spongycastle/cert/test/CertTest.java2995
-rw-r--r--pkix/src/test/java/org/spongycastle/cert/test/ConverterTest.java66
-rw-r--r--pkix/src/test/java/org/spongycastle/cert/test/PEMData.java114
-rw-r--r--pkix/src/test/java/org/spongycastle/cert/test/PKCS10Test.java616
-rw-r--r--pkix/src/test/java/org/spongycastle/cert/test/SHA1DigestCalculator.java44
-rw-r--r--pkix/src/test/java/org/spongycastle/cert/test/X509ExtensionUtilsTest.java55
20 files changed, 10035 insertions, 0 deletions
diff --git a/pkix/src/test/java/org/spongycastle/cert/cmp/test/AllTests.java b/pkix/src/test/java/org/spongycastle/cert/cmp/test/AllTests.java
new file mode 100644
index 00000000..ca633903
--- /dev/null
+++ b/pkix/src/test/java/org/spongycastle/cert/cmp/test/AllTests.java
@@ -0,0 +1,317 @@
+package org.spongycastle.cert.cmp.test;
+
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.math.BigInteger;
+import java.security.GeneralSecurityException;
+import java.security.KeyPair;
+import java.security.KeyPairGenerator;
+import java.security.PrivateKey;
+import java.security.PublicKey;
+import java.security.Security;
+import java.security.cert.X509Certificate;
+import java.util.Date;
+
+import junit.framework.Test;
+import junit.framework.TestCase;
+import junit.framework.TestSuite;
+import org.spongycastle.asn1.ASN1Primitive;
+import org.spongycastle.asn1.DERSequence;
+import org.spongycastle.asn1.cmp.CertConfirmContent;
+import org.spongycastle.asn1.cmp.CertRepMessage;
+import org.spongycastle.asn1.cmp.PKIBody;
+import org.spongycastle.asn1.cmp.PKIMessage;
+import org.spongycastle.asn1.crmf.CertReqMessages;
+import org.spongycastle.asn1.crmf.CertReqMsg;
+import org.spongycastle.asn1.crmf.ProofOfPossession;
+import org.spongycastle.asn1.crmf.SubsequentMessage;
+import org.spongycastle.asn1.x500.X500Name;
+import org.spongycastle.asn1.x509.GeneralName;
+import org.spongycastle.cert.CertException;
+import org.spongycastle.cert.X509CertificateHolder;
+import org.spongycastle.cert.X509v3CertificateBuilder;
+import org.spongycastle.cert.cmp.CertificateConfirmationContent;
+import org.spongycastle.cert.cmp.CertificateConfirmationContentBuilder;
+import org.spongycastle.cert.cmp.CertificateStatus;
+import org.spongycastle.cert.cmp.GeneralPKIMessage;
+import org.spongycastle.cert.cmp.ProtectedPKIMessage;
+import org.spongycastle.cert.cmp.ProtectedPKIMessageBuilder;
+import org.spongycastle.cert.crmf.CertificateRequestMessage;
+import org.spongycastle.cert.crmf.CertificateRequestMessageBuilder;
+import org.spongycastle.cert.crmf.PKMACBuilder;
+import org.spongycastle.cert.crmf.jcajce.JcaCertificateRequestMessageBuilder;
+import org.spongycastle.cert.crmf.jcajce.JcePKMACValuesCalculator;
+import org.spongycastle.cert.jcajce.JcaX509CertificateConverter;
+import org.spongycastle.cert.jcajce.JcaX509v3CertificateBuilder;
+import org.spongycastle.jce.provider.BouncyCastleProvider;
+import org.spongycastle.operator.ContentSigner;
+import org.spongycastle.operator.ContentVerifierProvider;
+import org.spongycastle.operator.OperatorCreationException;
+import org.spongycastle.operator.jcajce.JcaContentSignerBuilder;
+import org.spongycastle.operator.jcajce.JcaContentVerifierProviderBuilder;
+import org.spongycastle.operator.jcajce.JcaDigestCalculatorProviderBuilder;
+import org.spongycastle.util.io.Streams;
+
+public class AllTests
+ extends TestCase
+{
+ private static final byte[] TEST_DATA = "Hello world!".getBytes();
+ private static final String BC = BouncyCastleProvider.PROVIDER_NAME;
+ private static final String TEST_DATA_HOME = "bc.test.data.home";
+
+ /*
+ *
+ * INFRASTRUCTURE
+ *
+ */
+
+ public AllTests(String name)
+ {
+ super(name);
+ }
+
+ public static void main(String args[])
+ {
+ junit.textui.TestRunner.run(AllTests.class);
+ }
+
+ public static Test suite()
+ {
+ return new TestSuite(AllTests.class);
+ }
+
+ public void setUp()
+ {
+ Security.addProvider(new BouncyCastleProvider());
+ }
+
+ public void tearDown()
+ {
+
+ }
+
+ public void testProtectedMessage()
+ throws Exception
+ {
+ KeyPairGenerator kGen = KeyPairGenerator.getInstance("RSA", BC);
+
+ kGen.initialize(512);
+
+ KeyPair kp = kGen.generateKeyPair();
+ X509CertificateHolder cert = makeV3Certificate(kp, "CN=Test", kp, "CN=Test");
+
+ GeneralName sender = new GeneralName(new X500Name("CN=Sender"));
+ GeneralName recipient = new GeneralName(new X500Name("CN=Recip"));
+
+ ContentSigner signer = new JcaContentSignerBuilder("MD5WithRSAEncryption").setProvider(BC).build(kp.getPrivate());
+ ProtectedPKIMessage message = new ProtectedPKIMessageBuilder(sender, recipient)
+ .setBody(new PKIBody(PKIBody.TYPE_INIT_REP, CertRepMessage.getInstance(new DERSequence(new DERSequence()))))
+ .addCMPCertificate(cert)
+ .build(signer);
+
+ X509Certificate jcaCert = new JcaX509CertificateConverter().setProvider(BC).getCertificate(message.getCertificates()[0]);
+ ContentVerifierProvider verifierProvider = new JcaContentVerifierProviderBuilder().setProvider(BC).build(jcaCert.getPublicKey());
+
+ assertTrue(message.verify(verifierProvider));
+
+ assertEquals(sender, message.getHeader().getSender());
+ assertEquals(recipient, message.getHeader().getRecipient());
+ }
+
+ public void testMacProtectedMessage()
+ throws Exception
+ {
+ KeyPairGenerator kGen = KeyPairGenerator.getInstance("RSA", BC);
+
+ kGen.initialize(512);
+
+ KeyPair kp = kGen.generateKeyPair();
+ X509CertificateHolder cert = makeV3Certificate(kp, "CN=Test", kp, "CN=Test");
+
+ GeneralName sender = new GeneralName(new X500Name("CN=Sender"));
+ GeneralName recipient = new GeneralName(new X500Name("CN=Recip"));
+
+ ProtectedPKIMessage message = new ProtectedPKIMessageBuilder(sender, recipient)
+ .setBody(new PKIBody(PKIBody.TYPE_INIT_REP, CertRepMessage.getInstance(new DERSequence(new DERSequence()))))
+ .addCMPCertificate(cert)
+ .build(new PKMACBuilder(new JcePKMACValuesCalculator().setProvider(BC)).build("secret".toCharArray()));
+
+ PKMACBuilder pkMacBuilder = new PKMACBuilder(new JcePKMACValuesCalculator().setProvider(BC));
+
+ assertTrue(message.verify(pkMacBuilder, "secret".toCharArray()));
+
+ assertEquals(sender, message.getHeader().getSender());
+ assertEquals(recipient, message.getHeader().getRecipient());
+ }
+
+ public void testConfirmationMessage()
+ throws Exception
+ {
+ KeyPairGenerator kGen = KeyPairGenerator.getInstance("RSA", BC);
+
+ kGen.initialize(512);
+
+ KeyPair kp = kGen.generateKeyPair();
+ X509CertificateHolder cert = makeV3Certificate(kp, "CN=Test", kp, "CN=Test");
+
+ GeneralName sender = new GeneralName(new X500Name("CN=Sender"));
+ GeneralName recipient = new GeneralName(new X500Name("CN=Recip"));
+
+ CertificateConfirmationContent content = new CertificateConfirmationContentBuilder()
+ .addAcceptedCertificate(cert, BigInteger.valueOf(1))
+ .build(new JcaDigestCalculatorProviderBuilder().build());
+
+ ContentSigner signer = new JcaContentSignerBuilder("MD5WithRSAEncryption").setProvider(BC).build(kp.getPrivate());
+ ProtectedPKIMessage message = new ProtectedPKIMessageBuilder(sender, recipient)
+ .setBody(new PKIBody(PKIBody.TYPE_CERT_CONFIRM, content.toASN1Structure()))
+ .addCMPCertificate(cert)
+ .build(signer);
+
+ X509Certificate jcaCert = new JcaX509CertificateConverter().setProvider(BC).getCertificate(message.getCertificates()[0]);
+ ContentVerifierProvider verifierProvider = new JcaContentVerifierProviderBuilder().setProvider(BC).build(jcaCert.getPublicKey());
+
+ assertTrue(message.verify(verifierProvider));
+
+ assertEquals(sender, message.getHeader().getSender());
+ assertEquals(recipient, message.getHeader().getRecipient());
+
+ content = new CertificateConfirmationContent(CertConfirmContent.getInstance(message.getBody().getContent()));
+
+ CertificateStatus[] statusList = content.getStatusMessages();
+
+ assertEquals(1, statusList.length);
+ assertTrue(statusList[0].isVerified(cert, new JcaDigestCalculatorProviderBuilder().setProvider(BC).build()));
+ }
+
+ public void testSampleCr()
+ throws Exception
+ {
+ PKIMessage msg = loadMessage("sample_cr.der");
+ ProtectedPKIMessage procMsg = new ProtectedPKIMessage(new GeneralPKIMessage(msg));
+
+ assertTrue(procMsg.verify(new PKMACBuilder(new JcePKMACValuesCalculator().setProvider(BC)), "TopSecret1234".toCharArray()));
+ }
+
+ public void testSubsequentMessage()
+ throws Exception
+ {
+ KeyPairGenerator kGen = KeyPairGenerator.getInstance("RSA", BC);
+
+ kGen.initialize(512);
+
+ KeyPair kp = kGen.generateKeyPair();
+ X509CertificateHolder cert = makeV3Certificate(kp, "CN=Test", kp, "CN=Test");
+
+ ContentSigner signer = new JcaContentSignerBuilder("SHA256withRSA").setProvider(BC).build(
+ kp.getPrivate());
+
+ GeneralName user = new GeneralName(new X500Name("CN=Test"));
+
+ CertificateRequestMessageBuilder builder = new JcaCertificateRequestMessageBuilder(
+ BigInteger.valueOf(1)).setPublicKey(kp.getPublic()).setProofOfPossessionSubsequentMessage(
+ SubsequentMessage.encrCert);
+
+ ProtectedPKIMessage certRequestMsg = new ProtectedPKIMessageBuilder(user,
+ user).setTransactionID(new byte[] { 1, 2, 3, 4, 5 }).setBody(
+ new PKIBody(PKIBody.TYPE_KEY_UPDATE_REQ, new CertReqMessages(builder.build().toASN1Structure()))).addCMPCertificate(
+ cert).build(signer);
+
+ ProtectedPKIMessage msg = new ProtectedPKIMessage(new GeneralPKIMessage(certRequestMsg.toASN1Structure().getEncoded()));
+
+ CertReqMessages reqMsgs = CertReqMessages.getInstance(msg.getBody().getContent());
+
+ CertReqMsg reqMsg = reqMsgs.toCertReqMsgArray()[0];
+
+ assertEquals(ProofOfPossession.TYPE_KEY_ENCIPHERMENT, reqMsg.getPopo().getType());
+ }
+
+ public void testNotBeforeNotAfter()
+ throws Exception
+ {
+ KeyPairGenerator kGen = KeyPairGenerator.getInstance("RSA", BC);
+
+ kGen.initialize(512);
+
+ KeyPair kp = kGen.generateKeyPair();
+
+ doNotBeforeNotAfterTest(kp, new Date(0L), new Date(60000L));
+ doNotBeforeNotAfterTest(kp, null, new Date(60000L));
+ doNotBeforeNotAfterTest(kp, new Date(0L), null);
+ }
+
+ private void doNotBeforeNotAfterTest(KeyPair kp, Date notBefore, Date notAfter)
+ throws Exception
+ {
+ CertificateRequestMessageBuilder builder = new JcaCertificateRequestMessageBuilder(
+ BigInteger.valueOf(1)).setPublicKey(kp.getPublic()).setProofOfPossessionSubsequentMessage(
+ SubsequentMessage.encrCert);
+
+ builder.setValidity(notBefore, notAfter);
+
+ CertificateRequestMessage message = builder.build();
+
+ if (notBefore != null)
+ {
+ assertEquals(notBefore.getTime(), message.getCertTemplate().getValidity().getNotBefore().getDate().getTime());
+ }
+ else
+ {
+ assertNull(message.getCertTemplate().getValidity().getNotBefore());
+ }
+
+ if (notAfter != null)
+ {
+ assertEquals(notAfter.getTime(), message.getCertTemplate().getValidity().getNotAfter().getDate().getTime());
+ }
+ else
+ {
+ assertNull(message.getCertTemplate().getValidity().getNotAfter());
+ }
+ }
+
+ private static X509CertificateHolder makeV3Certificate(KeyPair subKP, String _subDN, KeyPair issKP, String _issDN)
+ throws GeneralSecurityException, IOException, OperatorCreationException, CertException
+ {
+
+ PublicKey subPub = subKP.getPublic();
+ PrivateKey issPriv = issKP.getPrivate();
+ PublicKey issPub = issKP.getPublic();
+
+ X509v3CertificateBuilder v1CertGen = new JcaX509v3CertificateBuilder(
+ new X500Name(_issDN),
+ BigInteger.valueOf(System.currentTimeMillis()),
+ new Date(System.currentTimeMillis()),
+ new Date(System.currentTimeMillis() + (1000L * 60 * 60 * 24 * 100)),
+ new X500Name(_subDN),
+ subPub);
+
+ ContentSigner signer = new JcaContentSignerBuilder("SHA1WithRSA").setProvider(BC).build(issPriv);
+
+ X509CertificateHolder certHolder = v1CertGen.build(signer);
+
+ ContentVerifierProvider verifier = new JcaContentVerifierProviderBuilder().setProvider(BC).build(issPub);
+
+ assertTrue(certHolder.isSignatureValid(verifier));
+
+ return certHolder;
+ }
+
+ private static PKIMessage loadMessage(String name)
+ {
+ String dataHome = System.getProperty(TEST_DATA_HOME);
+
+ if (dataHome == null)
+ {
+ throw new IllegalStateException(TEST_DATA_HOME + " property not set");
+ }
+
+ try
+ {
+ return PKIMessage.getInstance(ASN1Primitive.fromByteArray(Streams.readAll(new FileInputStream(dataHome + "/cmp/" + name))));
+ }
+ catch (IOException e)
+ {
+ throw new RuntimeException(e.toString());
+ }
+ }
+} \ No newline at end of file
diff --git a/pkix/src/test/java/org/spongycastle/cert/crmf/test/AllTests.java b/pkix/src/test/java/org/spongycastle/cert/crmf/test/AllTests.java
new file mode 100644
index 00000000..b5634684
--- /dev/null
+++ b/pkix/src/test/java/org/spongycastle/cert/crmf/test/AllTests.java
@@ -0,0 +1,384 @@
+package org.spongycastle.cert.crmf.test;
+
+import java.io.IOException;
+import java.math.BigInteger;
+import java.security.GeneralSecurityException;
+import java.security.KeyPair;
+import java.security.KeyPairGenerator;
+import java.security.PrivateKey;
+import java.security.PublicKey;
+import java.security.SecureRandom;
+import java.security.Security;
+import java.security.cert.X509Certificate;
+import java.security.interfaces.RSAPublicKey;
+import java.util.Date;
+
+import javax.security.auth.x500.X500Principal;
+
+import junit.framework.Test;
+import junit.framework.TestCase;
+import junit.framework.TestSuite;
+import org.spongycastle.asn1.ASN1ObjectIdentifier;
+import org.spongycastle.asn1.crmf.CRMFObjectIdentifiers;
+import org.spongycastle.asn1.crmf.EncKeyWithID;
+import org.spongycastle.asn1.crmf.EncryptedValue;
+import org.spongycastle.asn1.x500.X500Name;
+import org.spongycastle.asn1.x509.GeneralName;
+import org.spongycastle.cert.X509CertificateHolder;
+import org.spongycastle.cert.X509v1CertificateBuilder;
+import org.spongycastle.cert.crmf.EncryptedValueBuilder;
+import org.spongycastle.cert.crmf.EncryptedValuePadder;
+import org.spongycastle.cert.crmf.EncryptedValueParser;
+import org.spongycastle.cert.crmf.PKIArchiveControl;
+import org.spongycastle.cert.crmf.PKMACBuilder;
+import org.spongycastle.cert.crmf.ValueDecryptorGenerator;
+import org.spongycastle.cert.crmf.bc.BcFixedLengthMGF1Padder;
+import org.spongycastle.cert.crmf.jcajce.JcaCertificateRequestMessage;
+import org.spongycastle.cert.crmf.jcajce.JcaCertificateRequestMessageBuilder;
+import org.spongycastle.cert.crmf.jcajce.JcaEncryptedValueBuilder;
+import org.spongycastle.cert.crmf.jcajce.JcaPKIArchiveControlBuilder;
+import org.spongycastle.cert.crmf.jcajce.JceAsymmetricValueDecryptorGenerator;
+import org.spongycastle.cert.crmf.jcajce.JceCRMFEncryptorBuilder;
+import org.spongycastle.cert.crmf.jcajce.JcePKMACValuesCalculator;
+import org.spongycastle.cert.jcajce.JcaX509CertificateConverter;
+import org.spongycastle.cert.jcajce.JcaX509v1CertificateBuilder;
+import org.spongycastle.cms.CMSAlgorithm;
+import org.spongycastle.cms.CMSEnvelopedDataGenerator;
+import org.spongycastle.cms.RecipientId;
+import org.spongycastle.cms.RecipientInformation;
+import org.spongycastle.cms.RecipientInformationStore;
+import org.spongycastle.cms.jcajce.JceCMSContentEncryptorBuilder;
+import org.spongycastle.cms.jcajce.JceKeyTransEnvelopedRecipient;
+import org.spongycastle.cms.jcajce.JceKeyTransRecipientId;
+import org.spongycastle.cms.jcajce.JceKeyTransRecipientInfoGenerator;
+import org.spongycastle.jce.provider.BouncyCastleProvider;
+import org.spongycastle.operator.OperatorCreationException;
+import org.spongycastle.operator.jcajce.JcaContentSignerBuilder;
+import org.spongycastle.operator.jcajce.JcaContentVerifierProviderBuilder;
+import org.spongycastle.operator.jcajce.JceAsymmetricKeyWrapper;
+import org.spongycastle.util.Arrays;
+
+public class AllTests
+ extends TestCase
+{
+ private static final byte[] TEST_DATA = "Hello world!".getBytes();
+ private static final String BC = BouncyCastleProvider.PROVIDER_NAME;
+ private static final String PASSPHRASE = "hello world";
+
+ /*
+ *
+ * INFRASTRUCTURE
+ *
+ */
+
+ public AllTests(String name)
+ {
+ super(name);
+ }
+
+ public static void main(String args[])
+ {
+ junit.textui.TestRunner.run(AllTests.class);
+ }
+
+ public static Test suite()
+ {
+ return new TestSuite(AllTests.class);
+ }
+
+ public void setUp()
+ {
+ Security.addProvider(new BouncyCastleProvider());
+ }
+
+ public void tearDown()
+ {
+
+ }
+
+ public void testBasicMessageWithArchiveControl()
+ throws Exception
+ {
+ KeyPairGenerator kGen = KeyPairGenerator.getInstance("RSA", BC);
+
+ kGen.initialize(512);
+
+ KeyPair kp = kGen.generateKeyPair();
+ X509Certificate cert = makeV1Certificate(kp, "CN=Test", kp, "CN=Test");
+
+ JcaCertificateRequestMessageBuilder certReqBuild = new JcaCertificateRequestMessageBuilder(BigInteger.ONE);
+
+ certReqBuild.setSubject(new X500Principal("CN=Test"))
+ .setPublicKey(kp.getPublic());
+
+ certReqBuild.addControl(new JcaPKIArchiveControlBuilder(kp.getPrivate(), new X500Principal("CN=Test"))
+ .addRecipientGenerator(new JceKeyTransRecipientInfoGenerator(cert).setProvider(BC))
+ .build(new JceCMSContentEncryptorBuilder(new ASN1ObjectIdentifier(CMSEnvelopedDataGenerator.AES128_CBC)).setProvider(BC).build()));
+
+ JcaCertificateRequestMessage certReqMsg = new JcaCertificateRequestMessage(certReqBuild.build());
+
+ assertEquals(new X500Principal("CN=Test"), certReqMsg.getSubjectX500Principal());
+ assertEquals(kp.getPublic(), certReqMsg.getPublicKey());
+
+ PKIArchiveControl archiveControl = (PKIArchiveControl)certReqMsg.getControl(CRMFObjectIdentifiers.id_regCtrl_pkiArchiveOptions);
+
+ assertEquals(PKIArchiveControl.encryptedPrivKey, archiveControl.getArchiveType());
+
+ assertTrue(archiveControl.isEnvelopedData());
+
+ RecipientInformationStore recips = archiveControl.getEnvelopedData().getRecipientInfos();
+
+ RecipientId recipientId = new JceKeyTransRecipientId(cert);
+
+ RecipientInformation recipientInformation = recips.get(recipientId);
+
+ assertNotNull(recipientInformation);
+
+ EncKeyWithID encKeyWithID = EncKeyWithID.getInstance(recipientInformation.getContent(new JceKeyTransEnvelopedRecipient(kp.getPrivate()).setProvider(BC)));
+
+ assertTrue(encKeyWithID.hasIdentifier());
+ assertFalse(encKeyWithID.isIdentifierUTF8String());
+
+ assertEquals(new GeneralName(X500Name.getInstance(new X500Principal("CN=Test").getEncoded())), encKeyWithID.getIdentifier());
+ assertTrue(Arrays.areEqual(kp.getPrivate().getEncoded(), encKeyWithID.getPrivateKey().getEncoded()));
+ }
+
+ public void testProofOfPossessionWithoutSender()
+ throws Exception
+ {
+ KeyPairGenerator kGen = KeyPairGenerator.getInstance("RSA", BC);
+
+ kGen.initialize(512);
+
+ KeyPair kp = kGen.generateKeyPair();
+ X509Certificate cert = makeV1Certificate(kp, "CN=Test", kp, "CN=Test");
+
+ JcaCertificateRequestMessageBuilder certReqBuild = new JcaCertificateRequestMessageBuilder(BigInteger.ONE);
+
+ certReqBuild.setPublicKey(kp.getPublic())
+ .setAuthInfoPKMAC(new PKMACBuilder(new JcePKMACValuesCalculator()), "fred".toCharArray())
+ .setProofOfPossessionSigningKeySigner(new JcaContentSignerBuilder("SHA1withRSA").setProvider(BC).build(kp.getPrivate()));
+
+ certReqBuild.addControl(new JcaPKIArchiveControlBuilder(kp.getPrivate(), new X500Principal("CN=test"))
+ .addRecipientGenerator(new JceKeyTransRecipientInfoGenerator(cert).setProvider(BC))
+ .build(new JceCMSContentEncryptorBuilder(new ASN1ObjectIdentifier(CMSEnvelopedDataGenerator.AES128_CBC)).setProvider(BC).build()));
+
+ JcaCertificateRequestMessage certReqMsg = new JcaCertificateRequestMessage(certReqBuild.build().getEncoded());
+
+ // check that internal check on popo signing is working okay
+ try
+ {
+ certReqMsg.isValidSigningKeyPOP(new JcaContentVerifierProviderBuilder().setProvider(BC).build(kp.getPublic()));
+ fail("IllegalStateException not thrown");
+ }
+ catch (IllegalStateException e)
+ {
+ // ignore
+ }
+
+ assertTrue(certReqMsg.isValidSigningKeyPOP(new JcaContentVerifierProviderBuilder().setProvider(BC).build(kp.getPublic()), new PKMACBuilder(new JcePKMACValuesCalculator().setProvider(BC)), "fred".toCharArray()));
+
+ assertEquals(kp.getPublic(), certReqMsg.getPublicKey());
+ }
+
+ public void testProofOfPossessionWithSender()
+ throws Exception
+ {
+ KeyPairGenerator kGen = KeyPairGenerator.getInstance("RSA", BC);
+
+ kGen.initialize(512);
+
+ KeyPair kp = kGen.generateKeyPair();
+ X509Certificate cert = makeV1Certificate(kp, "CN=Test", kp, "CN=Test");
+
+ JcaCertificateRequestMessageBuilder certReqBuild = new JcaCertificateRequestMessageBuilder(BigInteger.ONE);
+
+ certReqBuild.setPublicKey(kp.getPublic())
+ .setAuthInfoSender(new X500Principal("CN=Test"))
+ .setProofOfPossessionSigningKeySigner(new JcaContentSignerBuilder("SHA1withRSA").setProvider(BC).build(kp.getPrivate()));
+
+ certReqBuild.addControl(new JcaPKIArchiveControlBuilder(kp.getPrivate(), new X500Principal("CN=test"))
+ .addRecipientGenerator(new JceKeyTransRecipientInfoGenerator(cert).setProvider(BC))
+ .build(new JceCMSContentEncryptorBuilder(new ASN1ObjectIdentifier(CMSEnvelopedDataGenerator.AES128_CBC)).setProvider(BC).build()));
+
+ JcaCertificateRequestMessage certReqMsg = new JcaCertificateRequestMessage(certReqBuild.build().getEncoded());
+
+ // check that internal check on popo signing is working okay
+ try
+ {
+ certReqMsg.isValidSigningKeyPOP(new JcaContentVerifierProviderBuilder().setProvider(BC).build(kp.getPublic()), new PKMACBuilder(new JcePKMACValuesCalculator().setProvider(BC)), "fred".toCharArray());
+
+ fail("IllegalStateException not thrown");
+ }
+ catch (IllegalStateException e)
+ {
+ // ignore
+ }
+
+
+ assertTrue(certReqMsg.isValidSigningKeyPOP(new JcaContentVerifierProviderBuilder().setProvider(BC).build(kp.getPublic())));
+
+ assertEquals(kp.getPublic(), certReqMsg.getPublicKey());
+ }
+
+ public void testProofOfPossessionWithTemplate()
+ throws Exception
+ {
+ KeyPairGenerator kGen = KeyPairGenerator.getInstance("RSA", BC);
+
+ kGen.initialize(512);
+
+ KeyPair kp = kGen.generateKeyPair();
+ X509Certificate cert = makeV1Certificate(kp, "CN=Test", kp, "CN=Test");
+
+ JcaCertificateRequestMessageBuilder certReqBuild = new JcaCertificateRequestMessageBuilder(BigInteger.ONE);
+
+ certReqBuild.setPublicKey(kp.getPublic())
+ .setSubject(new X500Principal("CN=Test"))
+ .setAuthInfoSender(new X500Principal("CN=Test"))
+ .setProofOfPossessionSigningKeySigner(new JcaContentSignerBuilder("SHA1withRSA").setProvider(BC).build(kp.getPrivate()));
+
+ certReqBuild.addControl(new JcaPKIArchiveControlBuilder(kp.getPrivate(), new X500Principal("CN=test"))
+ .addRecipientGenerator(new JceKeyTransRecipientInfoGenerator(cert).setProvider(BC))
+ .build(new JceCMSContentEncryptorBuilder(new ASN1ObjectIdentifier(CMSEnvelopedDataGenerator.AES128_CBC)).setProvider(BC).build()));
+
+ JcaCertificateRequestMessage certReqMsg = new JcaCertificateRequestMessage(certReqBuild.build().getEncoded());
+
+ assertTrue(certReqMsg.isValidSigningKeyPOP(new JcaContentVerifierProviderBuilder().setProvider(BC).build(kp.getPublic())));
+
+ assertEquals(kp.getPublic(), certReqMsg.getPublicKey());
+ }
+
+ public void testEncryptedValue()
+ throws Exception
+ {
+ KeyPairGenerator kGen = KeyPairGenerator.getInstance("RSA", BC);
+
+ kGen.initialize(512);
+
+ KeyPair kp = kGen.generateKeyPair();
+ X509Certificate cert = makeV1Certificate(kp, "CN=Test", kp, "CN=Test");
+
+ JcaEncryptedValueBuilder build = new JcaEncryptedValueBuilder(new JceAsymmetricKeyWrapper(cert.getPublicKey()).setProvider(BC), new JceCRMFEncryptorBuilder(CMSAlgorithm.AES128_CBC).setProvider(BC).build());
+ EncryptedValue value = build.build(cert);
+ ValueDecryptorGenerator decGen = new JceAsymmetricValueDecryptorGenerator(kp.getPrivate()).setProvider(BC);
+
+ // try direct
+ encryptedValueParserTest(value, decGen, cert);
+
+ // try indirect
+ encryptedValueParserTest(EncryptedValue.getInstance(value.getEncoded()), decGen, cert);
+ }
+
+ private void encryptedValueParserTest(EncryptedValue value, ValueDecryptorGenerator decGen, X509Certificate cert)
+ throws Exception
+ {
+ EncryptedValueParser parser = new EncryptedValueParser(value);
+
+ X509CertificateHolder holder = parser.readCertificateHolder(decGen);
+
+ assertTrue(Arrays.areEqual(cert.getEncoded(), holder.getEncoded()));
+ }
+
+ public void testEncryptedValuePassphrase()
+ throws Exception
+ {
+ char[] passphrase = PASSPHRASE.toCharArray();
+ KeyPairGenerator kGen = KeyPairGenerator.getInstance("RSA", BC);
+
+ kGen.initialize(512);
+
+ KeyPair kp = kGen.generateKeyPair();
+ X509Certificate cert = makeV1Certificate(kp, "CN=Test", kp, "CN=Test");
+
+ EncryptedValueBuilder build = new EncryptedValueBuilder(new JceAsymmetricKeyWrapper(cert.getPublicKey()).setProvider(BC), new JceCRMFEncryptorBuilder(CMSAlgorithm.AES128_CBC).setProvider(BC).build());
+ EncryptedValue value = build.build(passphrase);
+ ValueDecryptorGenerator decGen = new JceAsymmetricValueDecryptorGenerator(kp.getPrivate()).setProvider(BC);
+
+ // try direct
+ encryptedValuePassphraseParserTest(value, null, decGen, cert);
+
+ // try indirect
+ encryptedValuePassphraseParserTest(EncryptedValue.getInstance(value.getEncoded()), null, decGen, cert);
+ }
+
+ public void testEncryptedValuePassphraseWithPadding()
+ throws Exception
+ {
+ char[] passphrase = PASSPHRASE.toCharArray();
+ KeyPairGenerator kGen = KeyPairGenerator.getInstance("RSA", BC);
+
+ kGen.initialize(512);
+
+ KeyPair kp = kGen.generateKeyPair();
+ X509Certificate cert = makeV1Certificate(kp, "CN=Test", kp, "CN=Test");
+
+ BcFixedLengthMGF1Padder mgf1Padder = new BcFixedLengthMGF1Padder(200, new SecureRandom());
+ EncryptedValueBuilder build = new EncryptedValueBuilder(new JceAsymmetricKeyWrapper(cert.getPublicKey()).setProvider(BC), new JceCRMFEncryptorBuilder(CMSAlgorithm.AES128_CBC).setProvider(BC).build(), mgf1Padder);
+ EncryptedValue value = build.build(passphrase);
+ ValueDecryptorGenerator decGen = new JceAsymmetricValueDecryptorGenerator(kp.getPrivate()).setProvider(BC);
+
+ // try direct
+ encryptedValuePassphraseParserTest(value, mgf1Padder, decGen, cert);
+
+ // try indirect
+ encryptedValuePassphraseParserTest(EncryptedValue.getInstance(value.getEncoded()), mgf1Padder, decGen, cert);
+ }
+
+ private void encryptedValuePassphraseParserTest(EncryptedValue value, EncryptedValuePadder padder, ValueDecryptorGenerator decGen, X509Certificate cert)
+ throws Exception
+ {
+ EncryptedValueParser parser = new EncryptedValueParser(value, padder);
+
+ assertTrue(Arrays.areEqual(PASSPHRASE.toCharArray(), parser.readPassphrase(decGen)));
+ }
+
+ private static X509Certificate makeV1Certificate(KeyPair subKP, String _subDN, KeyPair issKP, String _issDN)
+ throws GeneralSecurityException, IOException, OperatorCreationException
+ {
+
+ PublicKey subPub = subKP.getPublic();
+ PrivateKey issPriv = issKP.getPrivate();
+ PublicKey issPub = issKP.getPublic();
+
+ X509v1CertificateBuilder v1CertGen = new JcaX509v1CertificateBuilder(
+ new X500Name(_issDN),
+ BigInteger.valueOf(System.currentTimeMillis()),
+ new Date(System.currentTimeMillis()),
+ new Date(System.currentTimeMillis() + (1000L * 60 * 60 * 24 * 100)),
+ new X500Name(_subDN),
+ subPub);
+
+ JcaContentSignerBuilder signerBuilder = null;
+
+ if (issPub instanceof RSAPublicKey)
+ {
+ signerBuilder = new JcaContentSignerBuilder("SHA1WithRSA");
+ }
+ else if (issPub.getAlgorithm().equals("DSA"))
+ {
+ signerBuilder = new JcaContentSignerBuilder("SHA1withDSA");
+ }
+ else if (issPub.getAlgorithm().equals("ECDSA"))
+ {
+ signerBuilder = new JcaContentSignerBuilder("SHA1withECDSA");
+ }
+ else if (issPub.getAlgorithm().equals("ECGOST3410"))
+ {
+ signerBuilder = new JcaContentSignerBuilder("GOST3411withECGOST3410");
+ }
+ else
+ {
+ signerBuilder = new JcaContentSignerBuilder("GOST3411WithGOST3410");
+ }
+
+ signerBuilder.setProvider(BC);
+
+ X509Certificate _cert = new JcaX509CertificateConverter().setProvider(BC).getCertificate(v1CertGen.build(signerBuilder.build(issPriv)));
+
+ _cert.checkValidity(new Date());
+ _cert.verify(issPub);
+
+ return _cert;
+ }
+} \ No newline at end of file
diff --git a/pkix/src/test/java/org/spongycastle/cert/ocsp/test/AllTests.java b/pkix/src/test/java/org/spongycastle/cert/ocsp/test/AllTests.java
new file mode 100644
index 00000000..cd739e62
--- /dev/null
+++ b/pkix/src/test/java/org/spongycastle/cert/ocsp/test/AllTests.java
@@ -0,0 +1,44 @@
+package org.spongycastle.cert.ocsp.test;
+
+import java.security.Security;
+
+import junit.framework.Test;
+import junit.framework.TestCase;
+import junit.framework.TestSuite;
+import org.spongycastle.jce.provider.BouncyCastleProvider;
+import org.spongycastle.util.test.SimpleTestResult;
+
+public class AllTests
+ extends TestCase
+{
+ public void testOCSP()
+ {
+ Security.addProvider(new BouncyCastleProvider());
+
+ org.spongycastle.util.test.Test[] tests = new org.spongycastle.util.test.Test[] { new OCSPTest() };
+
+ for (int i = 0; i != tests.length; i++)
+ {
+ SimpleTestResult result = (SimpleTestResult)tests[i].perform();
+
+ if (!result.isSuccessful())
+ {
+ fail(result.toString());
+ }
+ }
+ }
+
+ public static void main (String[] args)
+ {
+ junit.textui.TestRunner.run(suite());
+ }
+
+ public static Test suite()
+ {
+ TestSuite suite = new TestSuite("OCSP Tests");
+
+ suite.addTestSuite(AllTests.class);
+
+ return suite;
+ }
+}
diff --git a/pkix/src/test/java/org/spongycastle/cert/ocsp/test/OCSPTest.java b/pkix/src/test/java/org/spongycastle/cert/ocsp/test/OCSPTest.java
new file mode 100644
index 00000000..aa2bdeca
--- /dev/null
+++ b/pkix/src/test/java/org/spongycastle/cert/ocsp/test/OCSPTest.java
@@ -0,0 +1,972 @@
+package org.spongycastle.cert.ocsp.test;
+
+import java.io.IOException;
+import java.math.BigInteger;
+import java.security.KeyPair;
+import java.security.Security;
+import java.util.Date;
+import java.util.Random;
+import java.util.Set;
+import java.util.Vector;
+
+import org.spongycastle.asn1.ASN1Encodable;
+import org.spongycastle.asn1.ASN1Exception;
+import org.spongycastle.asn1.ASN1OctetString;
+import org.spongycastle.asn1.DEROctetString;
+import org.spongycastle.asn1.ocsp.OCSPObjectIdentifiers;
+import org.spongycastle.asn1.x509.Extension;
+import org.spongycastle.asn1.x509.ExtensionsGenerator;
+import org.spongycastle.asn1.x509.GeneralName;
+import org.spongycastle.asn1.x509.X509Name;
+import org.spongycastle.cert.CertIOException;
+import org.spongycastle.cert.X509CertificateHolder;
+import org.spongycastle.cert.jcajce.JcaX509CertificateHolder;
+import org.spongycastle.cert.ocsp.BasicOCSPResp;
+import org.spongycastle.cert.ocsp.BasicOCSPRespBuilder;
+import org.spongycastle.cert.ocsp.CertificateID;
+import org.spongycastle.cert.ocsp.CertificateStatus;
+import org.spongycastle.cert.ocsp.OCSPReq;
+import org.spongycastle.cert.ocsp.OCSPReqBuilder;
+import org.spongycastle.cert.ocsp.OCSPResp;
+import org.spongycastle.cert.ocsp.OCSPRespBuilder;
+import org.spongycastle.cert.ocsp.Req;
+import org.spongycastle.cert.ocsp.RespID;
+import org.spongycastle.cert.ocsp.SingleResp;
+import org.spongycastle.cert.ocsp.jcajce.JcaBasicOCSPRespBuilder;
+import org.spongycastle.jce.X509Principal;
+import org.spongycastle.jce.provider.BouncyCastleProvider;
+import org.spongycastle.operator.DigestCalculatorProvider;
+import org.spongycastle.operator.jcajce.JcaContentSignerBuilder;
+import org.spongycastle.operator.jcajce.JcaContentVerifierProviderBuilder;
+import org.spongycastle.operator.jcajce.JcaDigestCalculatorProviderBuilder;
+import org.spongycastle.util.encoders.Base64;
+import org.spongycastle.util.test.SimpleTest;
+
+public class OCSPTest
+ extends SimpleTest
+{
+ byte[] testResp1 = Base64.decode(
+ "MIIFnAoBAKCCBZUwggWRBgkrBgEFBQcwAQEEggWCMIIFfjCCARehgZ8wgZwx"
+ + "CzAJBgNVBAYTAklOMRcwFQYDVQQIEw5BbmRocmEgcHJhZGVzaDESMBAGA1UE"
+ + "BxMJSHlkZXJhYmFkMQwwCgYDVQQKEwNUQ1MxDDAKBgNVBAsTA0FUQzEeMBwG"
+ + "A1UEAxMVVENTLUNBIE9DU1AgUmVzcG9uZGVyMSQwIgYJKoZIhvcNAQkBFhVv"
+ + "Y3NwQHRjcy1jYS50Y3MuY28uaW4YDzIwMDMwNDAyMTIzNDU4WjBiMGAwOjAJ"
+ + "BgUrDgMCGgUABBRs07IuoCWNmcEl1oHwIak1BPnX8QQUtGyl/iL9WJ1VxjxF"
+ + "j0hAwJ/s1AcCAQKhERgPMjAwMjA4MjkwNzA5MjZaGA8yMDAzMDQwMjEyMzQ1"
+ + "OFowDQYJKoZIhvcNAQEFBQADgYEAfbN0TCRFKdhsmvOdUoiJ+qvygGBzDxD/"
+ + "VWhXYA+16AphHLIWNABR3CgHB3zWtdy2j7DJmQ/R7qKj7dUhWLSqclAiPgFt"
+ + "QQ1YvSJAYfEIdyHkxv4NP0LSogxrumANcDyC9yt/W9yHjD2ICPBIqCsZLuLk"
+ + "OHYi5DlwWe9Zm9VFwCGgggPMMIIDyDCCA8QwggKsoAMCAQICAQYwDQYJKoZI"
+ + "hvcNAQEFBQAwgZQxFDASBgNVBAMTC1RDUy1DQSBPQ1NQMSYwJAYJKoZIhvcN"
+ + "AQkBFhd0Y3MtY2FAdGNzLWNhLnRjcy5jby5pbjEMMAoGA1UEChMDVENTMQww"
+ + "CgYDVQQLEwNBVEMxEjAQBgNVBAcTCUh5ZGVyYWJhZDEXMBUGA1UECBMOQW5k"
+ + "aHJhIHByYWRlc2gxCzAJBgNVBAYTAklOMB4XDTAyMDgyOTA3MTE0M1oXDTAz"
+ + "MDgyOTA3MTE0M1owgZwxCzAJBgNVBAYTAklOMRcwFQYDVQQIEw5BbmRocmEg"
+ + "cHJhZGVzaDESMBAGA1UEBxMJSHlkZXJhYmFkMQwwCgYDVQQKEwNUQ1MxDDAK"
+ + "BgNVBAsTA0FUQzEeMBwGA1UEAxMVVENTLUNBIE9DU1AgUmVzcG9uZGVyMSQw"
+ + "IgYJKoZIhvcNAQkBFhVvY3NwQHRjcy1jYS50Y3MuY28uaW4wgZ8wDQYJKoZI"
+ + "hvcNAQEBBQADgY0AMIGJAoGBAM+XWW4caMRv46D7L6Bv8iwtKgmQu0SAybmF"
+ + "RJiz12qXzdvTLt8C75OdgmUomxp0+gW/4XlTPUqOMQWv463aZRv9Ust4f8MH"
+ + "EJh4ekP/NS9+d8vEO3P40ntQkmSMcFmtA9E1koUtQ3MSJlcs441JjbgUaVnm"
+ + "jDmmniQnZY4bU3tVAgMBAAGjgZowgZcwDAYDVR0TAQH/BAIwADALBgNVHQ8E"
+ + "BAMCB4AwEwYDVR0lBAwwCgYIKwYBBQUHAwkwNgYIKwYBBQUHAQEEKjAoMCYG"
+ + "CCsGAQUFBzABhhpodHRwOi8vMTcyLjE5LjQwLjExMDo3NzAwLzAtBgNVHR8E"
+ + "JjAkMCKgIKAehhxodHRwOi8vMTcyLjE5LjQwLjExMC9jcmwuY3JsMA0GCSqG"
+ + "SIb3DQEBBQUAA4IBAQB6FovM3B4VDDZ15o12gnADZsIk9fTAczLlcrmXLNN4"
+ + "PgmqgnwF0Ymj3bD5SavDOXxbA65AZJ7rBNAguLUo+xVkgxmoBH7R2sBxjTCc"
+ + "r07NEadxM3HQkt0aX5XYEl8eRoifwqYAI9h0ziZfTNes8elNfb3DoPPjqq6V"
+ + "mMg0f0iMS4W8LjNPorjRB+kIosa1deAGPhq0eJ8yr0/s2QR2/WFD5P4aXc8I"
+ + "KWleklnIImS3zqiPrq6tl2Bm8DZj7vXlTOwmraSQxUwzCKwYob1yGvNOUQTq"
+ + "pG6jxn7jgDawHU1+WjWQe4Q34/pWeGLysxTraMa+Ug9kPe+jy/qRX2xwvKBZ");
+
+ byte[] testResp2 = Base64.decode(
+ "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"
+ + "A5oyOoNv0w+8bbtMNEc1");
+
+ /**
+ * extra version number encoding.
+ */
+ private static byte[] irregReq = Base64.decode(
+ "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");
+
+ private static byte[] invalidResp = Base64.decode(
+ "MIIGggoAoIIGfDCCBngGCSsGAQUFBzABAQSCBmkwggZlMIHeoTQwMjELMAkG"
+ + "A1UEBhMCVVMxDTALBgNVBAoMBGlXYXkxFDASBgNVBAMMC2lXYXkgT3BlbkNB"
+ + "GA8yMDEyMDEyMzIxMjkxMVowbjBsMEQwCQYFKw4DAhoFAAQUPA5ymcOyHyZJ"
+ + "d7DAidsEh79Uh6QEFMHnDLGSc/VElMBzr5f0+LQnpN2YAgsA5xIzv2Ln0dAa"
+ + "94IAGA8yMDEyMDEyMzIxMjkxMVqgERgPMjAxMjAxMjMyMTM0MTFaoSUwIzAh"
+ + "BgkrBgEFBQcwAQIEFCHEdgCz5w64KgppPIetaRzxewinMA0GCSqGSIb3DQEB"
+ + "CwUAA4IBAQBsW8cXR4eOLgclY/uRodjso/5xkHIAiJy+DpgqELRrnzKe87HO"
+ + "Km7DCicz1nwsPJskK14xtIw1rfQ8nzgztriComAUVc/pxJ9wQWGZI3d2dNbW"
+ + "AmecKb/mG0QrJrt3U5D0+CFTUq5u7NOs1jZRe+df9TDLBr0vIA6a0I6K9M9F"
+ + "ZOPWU/j5KVjoi0/kv4wnxRzQ2zc4Z3b5gm9T0MXMH5bST3z4yhOs/NRezNTA"
+ + "fBQvimS60d4fybH0pXcVYUH81y5fm9rCpuwQ6rMt2vi0ZKrfyVom4OIAr/gh"
+ + "Doj8Yh/LdtI1RvFkAL3pvzs06cfg3qM38b9Uh9w93w4/Hguw14eroIIEbDCC"
+ + "BGgwggRkMIIDTKADAgECAgEBMA0GCSqGSIb3DQEBCwUAMDIxCzAJBgNVBAYT"
+ + "AlVTMQ0wCwYDVQQKDARpV2F5MRQwEgYDVQQDDAtpV2F5IE9wZW5DQTAeFw0x"
+ + "MjAxMjAxNTIyMjFaFw0zMjAxMTUxNTIyMjFaMDIxCzAJBgNVBAYTAlVTMQ0w"
+ + "CwYDVQQKDARpV2F5MRQwEgYDVQQDDAtpV2F5IE9wZW5DQTCCASIwDQYJKoZI"
+ + "hvcNAQEBBQADggEPADCCAQoCggEBALOnLWYPvGNLxodQQ16tqCKflpEQF2OA"
+ + "0inZbIeUVxOgph5Qf562XV1Mtbv5Agv+z4/LSLbwuo28NTkhSlEEwf1k9vL9"
+ + "/wFvpPZ4ecpqXOS6LJ6khmMh53IwK/QpG8CeF9UxTZskjQzD9XgnNGYd2BIj"
+ + "qVbzU5qWhsPYPRrsAaE2jS6My5+xfiw46/Xj26VZQ/PR/rVURsc40fpCE30y"
+ + "TyORQeeZfjb/LxXH3e/3wjya04MBACv+uX89n5YXG7OH6zTriMAOn/aiXPfE"
+ + "E8g834RKvVS7ruELWG/IcZDC+Eoy2qtgG7y1rFlXd3H/6rny+Xd+BZrt0WP/"
+ + "hfezklVw3asCAwEAAaOCAYMwggF/MA8GA1UdEwEB/wQFMAMBAf8wCwYDVR0P"
+ + "BAQDAgEGMB0GA1UdDgQWBBTB5wyxknP1RJTAc6+X9Pi0J6TdmDAfBgNVHSME"
+ + "GDAWgBTB5wyxknP1RJTAc6+X9Pi0J6TdmDAjBgNVHREEHDAagRhzdXBwb3J0"
+ + "QGl3YXlzb2Z0d2FyZS5jb20wIwYDVR0SBBwwGoEYc3VwcG9ydEBpd2F5c29m"
+ + "dHdhcmUuY29tMIGYBggrBgEFBQcBAQSBizCBiDA5BggrBgEFBQcwAoYtaHR0"
+ + "cDovL2l3NTRjZW50LXZtMi9wa2kvcHViL2NhY2VydC9jYWNlcnQuY3J0MCUG"
+ + "CCsGAQUFBzABhhlodHRwOi8vaXc1NGNlbnQtdm0yOjI1NjAvMCQGCCsGAQUF"
+ + "BzAMhhhodHRwOi8vaXc1NGNlbnQtdm0yOjgzMC8wOgYDVR0fBDMwMTAvoC2g"
+ + "K4YpaHR0cDovL2l3NTRjZW50LXZtMi9wa2kvcHViL2NybC9jYWNybC5jcmww"
+ + "DQYJKoZIhvcNAQELBQADggEBAE9wBjQ1c+HAO2gIzT+J5Gqgrcu/m7t4hnHN"
+ + "m5eyIfwXD1T6wOhovFmzPTaO9BSNsi4G5R7yZxOHeLN4PIY2kwFIbSkg7mwe"
+ + "5aGp2RPIuK/MtzMZT6pq8uMGhzyHGsqtdkz7p26/G0anU2u59eimcvISdwNE"
+ + "QXOIp/KNUC+Vx+Pmfw8PuFYDNacZ6YXp5qKoEjyUoBhNicmVINTNfDu0CQhu"
+ + "pDr2UmDMDT2cdmTSRC0rcTe3BNzWqtsXNmIBFL1oB7B0PZbmFm8Bgvk1azxa"
+ + "ClrcOKZWKOWa14XJy/DJk6nlOiq5W2AglUt8JVOpa5oVdiNRIT2WoGnpqVV9"
+ + "tUeoWog=");
+
+ private static final String BC = "SC";
+
+ public String getName()
+ {
+ return "OCSP";
+ }
+
+ private void testECDSA()
+ throws Exception
+ {
+ String signDN = "O=Bouncy Castle, C=AU";
+ KeyPair signKP = OCSPTestUtil.makeECKeyPair();
+ X509CertificateHolder testCert = new JcaX509CertificateHolder(OCSPTestUtil.makeECDSACertificate(signKP, signDN, signKP, signDN));
+ DigestCalculatorProvider digCalcProv = new JcaDigestCalculatorProviderBuilder().setProvider(BC).build();
+
+ String origDN = "CN=Eric H. Echidna, E=eric@bouncycastle.org, O=Bouncy Castle, C=AU";
+ GeneralName origName = new GeneralName(new X509Name(origDN));
+
+ //
+ // general id value for our test issuer cert and a serial number.
+ //
+ CertificateID id = new CertificateID(digCalcProv.get(CertificateID.HASH_SHA1), testCert, BigInteger.valueOf(1));
+
+ //
+ // basic request generation
+ //
+ OCSPReqBuilder gen = new OCSPReqBuilder();
+ gen.addRequest(id);
+
+ OCSPReq req = gen.build();
+
+ if (req.isSigned())
+ {
+ fail("signed but shouldn't be");
+ }
+
+ X509CertificateHolder[] certs = req.getCerts();
+
+ if (certs.length != 0)
+ {
+ fail("0 certs expected, but not found");
+ }
+
+ Req[] requests = req.getRequestList();
+
+ if (!requests[0].getCertID().equals(id))
+ {
+ fail("Failed isFor test");
+ }
+
+ //
+ // request generation with signing
+ //
+ X509CertificateHolder[] chain = new X509CertificateHolder[1];
+
+ gen = new OCSPReqBuilder();
+
+ gen.setRequestorName(new GeneralName(GeneralName.directoryName, new X509Principal("CN=fred")));
+
+ gen.addRequest(
+ new CertificateID(digCalcProv.get(CertificateID.HASH_SHA1), testCert, BigInteger.valueOf(1)));
+
+ chain[0] = testCert;
+
+ req = gen.build(new JcaContentSignerBuilder("SHA1withECDSA").setProvider(BC).build( signKP.getPrivate()), chain);
+
+ if (!req.isSigned())
+ {
+ fail("not signed but should be");
+ }
+
+ if (!req.isSignatureValid(new JcaContentVerifierProviderBuilder().setProvider(BC).build(signKP.getPublic())))
+ {
+ fail("signature failed to verify");
+ }
+
+ requests = req.getRequestList();
+
+ if (!requests[0].getCertID().equals(id))
+ {
+ fail("Failed isFor test");
+ }
+
+ certs = req.getCerts();
+
+ if (certs == null)
+ {
+ fail("null certs found");
+ }
+
+ if (certs.length != 1 || !certs[0].equals(testCert))
+ {
+ fail("incorrect certs found in request");
+ }
+
+ //
+ // encoding test
+ //
+ byte[] reqEnc = req.getEncoded();
+
+ OCSPReq newReq = new OCSPReq(reqEnc);
+
+ if (!newReq.isSignatureValid(new JcaContentVerifierProviderBuilder().setProvider(BC).build(signKP.getPublic())))
+ {
+ fail("newReq signature failed to verify");
+ }
+
+ //
+ // request generation with signing and nonce
+ //
+ chain = new X509CertificateHolder[1];
+
+ gen = new OCSPReqBuilder();
+
+ Vector oids = new Vector();
+ Vector values = new Vector();
+ byte[] sampleNonce = new byte[16];
+ Random rand = new Random();
+
+ rand.nextBytes(sampleNonce);
+
+ gen.setRequestorName(new GeneralName(GeneralName.directoryName, new X509Principal("CN=fred")));
+
+ ExtensionsGenerator extGen = new ExtensionsGenerator();
+
+ extGen.addExtension(OCSPObjectIdentifiers.id_pkix_ocsp_nonce, false, new DEROctetString(sampleNonce));
+
+ gen.setRequestExtensions(extGen.generate());
+
+ gen.addRequest(
+ new CertificateID(digCalcProv.get(CertificateID.HASH_SHA1), testCert, BigInteger.valueOf(1)));
+
+ chain[0] = testCert;
+
+ req = gen.build(new JcaContentSignerBuilder("SHA1withECDSA").setProvider(BC).build(signKP.getPrivate()), chain);
+
+ if (!req.isSigned())
+ {
+ fail("not signed but should be");
+ }
+
+ if (!req.isSignatureValid(new JcaContentVerifierProviderBuilder().setProvider(BC).build(signKP.getPublic())))
+ {
+ fail("signature failed to verify");
+ }
+
+ //
+ // extension check.
+ //
+ Set extOids = req.getCriticalExtensionOIDs();
+
+ if (extOids.size() != 0)
+ {
+ fail("wrong number of critical extensions in OCSP request.");
+ }
+
+ extOids = req.getNonCriticalExtensionOIDs();
+
+ if (extOids.size() != 1)
+ {
+ fail("wrong number of non-critical extensions in OCSP request.");
+ }
+
+ Extension extValue = req.getExtension(OCSPObjectIdentifiers.id_pkix_ocsp_nonce);
+
+ ASN1Encodable extObj = extValue.getParsedValue();
+
+ if (!(extObj instanceof ASN1OctetString))
+ {
+ fail("wrong extension type found.");
+ }
+
+ if (!areEqual(((ASN1OctetString)extObj).getOctets(), sampleNonce))
+ {
+ fail("wrong extension value found.");
+ }
+
+ //
+ // request list check
+ //
+ requests = req.getRequestList();
+
+ if (!requests[0].getCertID().equals(id))
+ {
+ fail("Failed isFor test");
+ }
+
+ //
+ // response generation
+ //
+ BasicOCSPRespBuilder respGen = new JcaBasicOCSPRespBuilder(signKP.getPublic(), digCalcProv.get(RespID.HASH_SHA1));
+
+ respGen.addResponse(id, CertificateStatus.GOOD);
+
+ BasicOCSPResp resp = respGen.build(new JcaContentSignerBuilder("SHA1withECDSA").setProvider(BC).build(signKP.getPrivate()), chain, new Date());
+ }
+
+ private void testRSA()
+ throws Exception
+ {
+ String signDN = "O=Bouncy Castle, C=AU";
+ KeyPair signKP = OCSPTestUtil.makeKeyPair();
+ X509CertificateHolder testCert = new JcaX509CertificateHolder(OCSPTestUtil.makeCertificate(signKP, signDN, signKP, signDN));
+ DigestCalculatorProvider digCalcProv = new JcaDigestCalculatorProviderBuilder().setProvider(BC).build();
+
+ String origDN = "CN=Eric H. Echidna, E=eric@bouncycastle.org, O=Bouncy Castle, C=AU";
+ GeneralName origName = new GeneralName(new X509Name(origDN));
+
+ //
+ // general id value for our test issuer cert and a serial number.
+ //
+ CertificateID id = new CertificateID(digCalcProv.get(CertificateID.HASH_SHA1), testCert, BigInteger.valueOf(1));
+
+ //
+ // basic request generation
+ //
+ OCSPReqBuilder gen = new OCSPReqBuilder();
+
+ gen.addRequest(
+ new CertificateID(digCalcProv.get(CertificateID.HASH_SHA1), testCert, BigInteger.valueOf(1)));
+
+ OCSPReq req = gen.build();
+
+ if (req.isSigned())
+ {
+ fail("signed but shouldn't be");
+ }
+
+ X509CertificateHolder[] certs = req.getCerts();
+
+ if (certs.length != 0)
+ {
+ fail("0 certs expected, but not found");
+ }
+
+ Req[] requests = req.getRequestList();
+
+ if (!requests[0].getCertID().equals(id))
+ {
+ fail("Failed isFor test");
+ }
+
+ //
+ // request generation with signing
+ //
+ X509CertificateHolder[] chain = new X509CertificateHolder[1];
+
+ gen = new OCSPReqBuilder();
+
+ gen.setRequestorName(new GeneralName(GeneralName.directoryName, new X509Principal("CN=fred")));
+
+ gen.addRequest(
+ new CertificateID(digCalcProv.get(CertificateID.HASH_SHA1), testCert, BigInteger.valueOf(1)));
+
+ chain[0] = testCert;
+
+ req = gen.build(new JcaContentSignerBuilder("SHA1withRSA").setProvider(BC).build(signKP.getPrivate()), chain);
+
+ if (!req.isSigned())
+ {
+ fail("not signed but should be");
+ }
+
+ if (!req.isSignatureValid(new JcaContentVerifierProviderBuilder().setProvider(BC).build(signKP.getPublic())))
+ {
+ fail("signature failed to verify");
+ }
+
+ requests = req.getRequestList();
+
+ if (!requests[0].getCertID().equals(id))
+ {
+ fail("Failed isFor test");
+ }
+
+ certs = req.getCerts();
+
+ if (certs == null)
+ {
+ fail("null certs found");
+ }
+
+ if (certs.length != 1 || !certs[0].equals(testCert))
+ {
+ fail("incorrect certs found in request");
+ }
+
+ //
+ // encoding test
+ //
+ byte[] reqEnc = req.getEncoded();
+
+ OCSPReq newReq = new OCSPReq(reqEnc);
+
+ if (!newReq.isSignatureValid(new JcaContentVerifierProviderBuilder().setProvider(BC).build(signKP.getPublic())))
+ {
+ fail("newReq signature failed to verify");
+ }
+
+ //
+ // request generation with signing and nonce
+ //
+ chain = new X509CertificateHolder[1];
+
+ gen = new OCSPReqBuilder();
+
+ byte[] sampleNonce = new byte[16];
+ Random rand = new Random();
+
+ rand.nextBytes(sampleNonce);
+
+ gen.setRequestorName(new GeneralName(GeneralName.directoryName, new X509Principal("CN=fred")));
+
+ ExtensionsGenerator extGen = new ExtensionsGenerator();
+
+ extGen.addExtension(OCSPObjectIdentifiers.id_pkix_ocsp_nonce, false, new DEROctetString(sampleNonce));
+
+ gen.setRequestExtensions(extGen.generate());
+
+ gen.addRequest(
+ new CertificateID(digCalcProv.get(CertificateID.HASH_SHA1), testCert, BigInteger.valueOf(1)));
+
+ chain[0] = testCert;
+
+ req = gen.build(new JcaContentSignerBuilder("SHA1withRSA").setProvider(BC).build(signKP.getPrivate()), chain);
+
+ if (!req.isSigned())
+ {
+ fail("not signed but should be");
+ }
+
+ if (!req.isSignatureValid(new JcaContentVerifierProviderBuilder().setProvider(BC).build(signKP.getPublic())))
+ {
+ fail("signature failed to verify");
+ }
+
+ //
+ // extension check.
+ //
+ Set extOids = req.getCriticalExtensionOIDs();
+
+ if (extOids.size() != 0)
+ {
+ fail("wrong number of critical extensions in OCSP request.");
+ }
+
+ extOids = req.getNonCriticalExtensionOIDs();
+
+ if (extOids.size() != 1)
+ {
+ fail("wrong number of non-critical extensions in OCSP request.");
+ }
+
+ Extension ext = req.getExtension(OCSPObjectIdentifiers.id_pkix_ocsp_nonce);
+
+ ASN1Encodable extObj = ext.getParsedValue();
+
+ if (!(extObj instanceof ASN1OctetString))
+ {
+ fail("wrong extension type found.");
+ }
+
+ if (!areEqual(((ASN1OctetString)extObj).getOctets(), sampleNonce))
+ {
+ fail("wrong extension value found.");
+ }
+
+ //
+ // request list check
+ //
+ requests = req.getRequestList();
+
+ if (!requests[0].getCertID().equals(id))
+ {
+ fail("Failed isFor test");
+ }
+
+ //
+ // response generation
+ //
+ BasicOCSPRespBuilder respGen = new JcaBasicOCSPRespBuilder(signKP.getPublic(), digCalcProv.get(RespID.HASH_SHA1));
+
+ respGen.addResponse(id, CertificateStatus.GOOD);
+
+ BasicOCSPResp resp = respGen.build(new JcaContentSignerBuilder("SHA1withRSA").setProvider(BC).build(signKP.getPrivate()), chain, new Date());
+ OCSPRespBuilder rGen = new OCSPRespBuilder();
+
+ byte[] enc = rGen.build(OCSPRespBuilder.SUCCESSFUL, resp).getEncoded();
+ }
+
+ private void testIrregularVersionReq()
+ throws Exception
+ {
+ OCSPReq ocspRequest = new OCSPReq(irregReq);
+ X509CertificateHolder cert = ocspRequest.getCerts()[0];
+ if (!ocspRequest.isSignatureValid(new JcaContentVerifierProviderBuilder().setProvider(BC).build(cert)))
+ {
+ fail("extra version encoding test failed");
+ }
+ }
+
+ public void testInvalidResp()
+ throws Exception
+ {
+ try
+ {
+ OCSPResp response = new OCSPResp(invalidResp);
+ }
+ catch (CertIOException e)
+ {
+ if (e.getCause() instanceof ASN1Exception)
+ {
+ Throwable c = ((ASN1Exception)e.getCause()).getCause();
+
+ if (!c.getMessage().equals("ENUMERATED has zero length"))
+ {
+ fail("parsing failed, but for wrong reason: " + c.getMessage());
+ }
+ }
+ else
+ {
+ fail("parsing failed, but for wrong reason: " + e.getMessage());
+ }
+ }
+
+
+ }
+
+ public void performTest()
+ throws Exception
+ {
+ String signDN = "O=Bouncy Castle, C=AU";
+ KeyPair signKP = OCSPTestUtil.makeKeyPair();
+ X509CertificateHolder testCert = new JcaX509CertificateHolder(OCSPTestUtil.makeCertificate(signKP, signDN, signKP, signDN));
+
+ String origDN = "CN=Eric H. Echidna, E=eric@bouncycastle.org, O=Bouncy Castle, C=AU";
+ GeneralName origName = new GeneralName(new X509Name(origDN));
+ DigestCalculatorProvider digCalcProv = new JcaDigestCalculatorProviderBuilder().setProvider(BC).build();
+
+ //
+ // general id value for our test issuer cert and a serial number.
+ //
+ CertificateID id = new CertificateID(digCalcProv.get(CertificateID.HASH_SHA1), testCert, BigInteger.valueOf(1));
+
+ //
+ // basic request generation
+ //
+ OCSPReqBuilder gen = new OCSPReqBuilder();
+
+ gen.addRequest(
+ new CertificateID(digCalcProv.get(CertificateID.HASH_SHA1), testCert, BigInteger.valueOf(1)));
+
+ OCSPReq req = gen.build();
+
+ if (req.isSigned())
+ {
+ fail("signed but shouldn't be");
+ }
+
+ X509CertificateHolder[] certs = req.getCerts();
+
+ if (certs.length != 0)
+ {
+ fail("0 certs expected, but not found");
+ }
+
+ Req[] requests = req.getRequestList();
+
+ if (!requests[0].getCertID().equals(id))
+ {
+ fail("Failed isFor test");
+ }
+
+ //
+ // request generation with signing
+ //
+ X509CertificateHolder[] chain = new X509CertificateHolder[1];
+
+ gen = new OCSPReqBuilder();
+
+ gen.setRequestorName(new GeneralName(GeneralName.directoryName, new X509Principal("CN=fred")));
+
+ gen.addRequest(
+ new CertificateID(digCalcProv.get(CertificateID.HASH_SHA1), testCert, BigInteger.valueOf(1)));
+
+ chain[0] = testCert;
+
+ req = gen.build(new JcaContentSignerBuilder("SHA1withRSA").setProvider(BC).build(signKP.getPrivate()), chain);
+
+ if (!req.isSigned())
+ {
+ fail("not signed but should be");
+ }
+
+ if (!req.isSignatureValid(new JcaContentVerifierProviderBuilder().setProvider(BC).build(signKP.getPublic())))
+ {
+ fail("signature failed to verify");
+ }
+
+ requests = req.getRequestList();
+
+ if (!requests[0].getCertID().equals(id))
+ {
+ fail("Failed isFor test");
+ }
+
+ certs = req.getCerts();
+
+ if (certs == null)
+ {
+ fail("null certs found");
+ }
+
+ if (certs.length != 1 || !certs[0].equals(testCert))
+ {
+ fail("incorrect certs found in request");
+ }
+
+ //
+ // encoding test
+ //
+ byte[] reqEnc = req.getEncoded();
+
+ OCSPReq newReq = new OCSPReq(reqEnc);
+
+ if (!newReq.isSignatureValid(new JcaContentVerifierProviderBuilder().setProvider(BC).build(signKP.getPublic())))
+ {
+ fail("newReq signature failed to verify");
+ }
+
+ //
+ // request generation with signing and nonce
+ //
+ chain = new X509CertificateHolder[1];
+
+ gen = new OCSPReqBuilder();
+
+ Vector oids = new Vector();
+ Vector values = new Vector();
+ byte[] sampleNonce = new byte[16];
+ Random rand = new Random();
+
+ rand.nextBytes(sampleNonce);
+
+ gen.setRequestorName(new GeneralName(GeneralName.directoryName, new X509Principal("CN=fred")));
+
+ ExtensionsGenerator extGen = new ExtensionsGenerator();
+
+ extGen.addExtension(OCSPObjectIdentifiers.id_pkix_ocsp_nonce, false, new DEROctetString(sampleNonce));
+
+ gen.setRequestExtensions(extGen.generate());
+
+ gen.addRequest(
+ new CertificateID(digCalcProv.get(CertificateID.HASH_SHA1), testCert, BigInteger.valueOf(1)));
+
+ chain[0] = testCert;
+
+ req = gen.build(new JcaContentSignerBuilder("SHA1withRSA").setProvider(BC).build(signKP.getPrivate()), chain);
+
+ if (!req.isSigned())
+ {
+ fail("not signed but should be");
+ }
+
+ if (!req.isSignatureValid(new JcaContentVerifierProviderBuilder().setProvider(BC).build(signKP.getPublic())))
+ {
+ fail("signature failed to verify");
+ }
+
+ //
+ // extension check.
+ //
+ Set extOids = req.getCriticalExtensionOIDs();
+
+ if (extOids.size() != 0)
+ {
+ fail("wrong number of critical extensions in OCSP request.");
+ }
+
+ extOids = req.getNonCriticalExtensionOIDs();
+
+ if (extOids.size() != 1)
+ {
+ fail("wrong number of non-critical extensions in OCSP request.");
+ }
+
+ Extension ext = req.getExtension(OCSPObjectIdentifiers.id_pkix_ocsp_nonce);
+
+ ASN1Encodable extObj = ext.getParsedValue();
+
+ if (!(extObj instanceof ASN1OctetString))
+ {
+ fail("wrong extension type found.");
+ }
+
+ if (!areEqual(((ASN1OctetString)extObj).getOctets(), sampleNonce))
+ {
+ fail("wrong extension value found.");
+ }
+
+ //
+ // request list check
+ //
+ requests = req.getRequestList();
+
+ if (!requests[0].getCertID().equals(id))
+ {
+ fail("Failed isFor test");
+ }
+
+ //
+ // response parsing - test 1
+ //
+ OCSPResp response = new OCSPResp(testResp1);
+
+ if (response.getStatus() != 0)
+ {
+ fail("response status not zero.");
+ }
+
+ BasicOCSPResp brep = (BasicOCSPResp)response.getResponseObject();
+ chain = brep.getCerts();
+
+ if (!brep.isSignatureValid(new JcaContentVerifierProviderBuilder().setProvider(BC).build(chain[0])))
+ {
+ fail("response 1 failed to verify.");
+ }
+
+ //
+ // test 2
+ //
+ SingleResp[] singleResp = brep.getResponses();
+
+ response = new OCSPResp(testResp2);
+
+ if (response.getStatus() != 0)
+ {
+ fail("response status not zero.");
+ }
+
+ brep = (BasicOCSPResp)response.getResponseObject();
+ chain = brep.getCerts();
+
+ if (!brep.isSignatureValid(new JcaContentVerifierProviderBuilder().setProvider(BC).build(chain[0])))
+ {
+ fail("response 2 failed to verify.");
+ }
+
+ singleResp = brep.getResponses();
+
+ //
+ // simple response generation
+ //
+ OCSPRespBuilder respGen = new OCSPRespBuilder();
+ OCSPResp resp = respGen.build(OCSPRespBuilder.SUCCESSFUL, response.getResponseObject());
+
+ if (!resp.getResponseObject().equals(response.getResponseObject()))
+ {
+ fail("response fails to match");
+ }
+
+ testECDSA();
+ testRSA();
+ testIrregularVersionReq();
+ testInvalidResp();
+
+ //
+ // Empty data test
+ //
+ try
+ {
+ response = new OCSPResp(new byte[0]);
+ fail("no exception thrown");
+ }
+ catch (IOException e)
+ {
+ if (!e.getMessage().equals("malformed response: no response data found"))
+ {
+ fail("wrong exception");
+ }
+ }
+
+ try
+ {
+ req = new OCSPReq(new byte[0]);
+ fail("no exception thrown");
+ }
+ catch (IOException e)
+ {
+ if (!e.getMessage().equals("malformed request: no request data found"))
+ {
+ fail("wrong exception");
+ }
+ }
+ }
+
+ public static void main(
+ String[] args)
+ {
+ Security.addProvider(new BouncyCastleProvider());
+
+ runTest(new OCSPTest());
+ }
+}
diff --git a/pkix/src/test/java/org/spongycastle/cert/ocsp/test/OCSPTestUtil.java b/pkix/src/test/java/org/spongycastle/cert/ocsp/test/OCSPTestUtil.java
new file mode 100644
index 00000000..2dcde313
--- /dev/null
+++ b/pkix/src/test/java/org/spongycastle/cert/ocsp/test/OCSPTestUtil.java
@@ -0,0 +1,177 @@
+package org.spongycastle.cert.ocsp.test;
+
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.math.BigInteger;
+import java.security.KeyPair;
+import java.security.KeyPairGenerator;
+import java.security.PrivateKey;
+import java.security.PublicKey;
+import java.security.SecureRandom;
+import java.security.cert.X509Certificate;
+import java.util.Date;
+
+import javax.crypto.KeyGenerator;
+
+import org.spongycastle.asn1.ASN1InputStream;
+import org.spongycastle.asn1.ASN1Sequence;
+import org.spongycastle.asn1.x509.AuthorityKeyIdentifier;
+import org.spongycastle.asn1.x509.BasicConstraints;
+import org.spongycastle.asn1.x509.SubjectKeyIdentifier;
+import org.spongycastle.asn1.x509.SubjectPublicKeyInfo;
+import org.spongycastle.asn1.x509.X509Extensions;
+import org.spongycastle.asn1.x509.X509Name;
+import org.spongycastle.cert.bc.BcX509ExtensionUtils;
+import org.spongycastle.x509.X509V3CertificateGenerator;
+
+public class OCSPTestUtil
+{
+
+ public static SecureRandom rand;
+ public static KeyPairGenerator kpg, eckpg;
+ public static KeyGenerator desede128kg;
+ public static KeyGenerator desede192kg;
+ public static KeyGenerator rc240kg;
+ public static KeyGenerator rc264kg;
+ public static KeyGenerator rc2128kg;
+ public static BigInteger serialNumber;
+
+ public static final boolean DEBUG = true;
+
+ static
+ {
+ try
+ {
+ rand = new SecureRandom();
+
+ kpg = KeyPairGenerator.getInstance("RSA", "SC");
+ kpg.initialize(1024, rand);
+
+ serialNumber = new BigInteger("1");
+
+ eckpg = KeyPairGenerator.getInstance("ECDSA", "SC");
+ eckpg.initialize(192, rand);
+ }
+ catch(Exception ex)
+ {
+ throw new RuntimeException(ex.toString());
+ }
+ }
+
+ public static KeyPair makeKeyPair()
+ {
+ return kpg.generateKeyPair();
+ }
+
+ public static KeyPair makeECKeyPair()
+ {
+ return eckpg.generateKeyPair();
+ }
+
+ public static X509Certificate makeCertificate(KeyPair _subKP,
+ String _subDN, KeyPair _issKP, String _issDN)
+ throws Exception
+ {
+
+ return makeCertificate(_subKP, _subDN, _issKP, _issDN, false);
+ }
+
+ public static X509Certificate makeECDSACertificate(KeyPair _subKP,
+ String _subDN, KeyPair _issKP, String _issDN)
+ throws Exception
+ {
+
+ return makeECDSACertificate(_subKP, _subDN, _issKP, _issDN, false);
+ }
+
+ public static X509Certificate makeCACertificate(KeyPair _subKP,
+ String _subDN, KeyPair _issKP, String _issDN)
+ throws Exception
+ {
+
+ return makeCertificate(_subKP, _subDN, _issKP, _issDN, true);
+ }
+
+ public static X509Certificate makeCertificate(KeyPair _subKP,
+ String _subDN, KeyPair _issKP, String _issDN, boolean _ca)
+ throws Exception
+ {
+ return makeCertificate(_subKP,_subDN, _issKP, _issDN, "MD5withRSA", _ca);
+ }
+
+ public static X509Certificate makeECDSACertificate(KeyPair _subKP,
+ String _subDN, KeyPair _issKP, String _issDN, boolean _ca)
+ throws Exception
+ {
+ return makeCertificate(_subKP,_subDN, _issKP, _issDN, "SHA1WithECDSA", _ca);
+ }
+
+ public static X509Certificate makeCertificate(KeyPair _subKP,
+ String _subDN, KeyPair _issKP, String _issDN, String algorithm, boolean _ca)
+ throws Exception
+ {
+
+ PublicKey _subPub = _subKP.getPublic();
+ PrivateKey _issPriv = _issKP.getPrivate();
+ PublicKey _issPub = _issKP.getPublic();
+
+ X509V3CertificateGenerator _v3CertGen = new X509V3CertificateGenerator();
+
+ _v3CertGen.reset();
+ _v3CertGen.setSerialNumber(allocateSerialNumber());
+ _v3CertGen.setIssuerDN(new X509Name(_issDN));
+ _v3CertGen.setNotBefore(new Date(System.currentTimeMillis()));
+ _v3CertGen.setNotAfter(new Date(System.currentTimeMillis()
+ + (1000L * 60 * 60 * 24 * 100)));
+ _v3CertGen.setSubjectDN(new X509Name(_subDN));
+ _v3CertGen.setPublicKey(_subPub);
+ _v3CertGen.setSignatureAlgorithm(algorithm);
+
+ _v3CertGen.addExtension(X509Extensions.SubjectKeyIdentifier, false,
+ createSubjectKeyId(_subPub));
+
+ _v3CertGen.addExtension(X509Extensions.AuthorityKeyIdentifier, false,
+ createAuthorityKeyId(_issPub));
+
+ _v3CertGen.addExtension(X509Extensions.BasicConstraints, false,
+ new BasicConstraints(_ca));
+
+ X509Certificate _cert = _v3CertGen.generate(_issPriv);
+
+ _cert.checkValidity(new Date());
+ _cert.verify(_issPub);
+
+ return _cert;
+ }
+
+ /*
+ *
+ * INTERNAL METHODS
+ *
+ */
+
+ private static AuthorityKeyIdentifier createAuthorityKeyId(PublicKey _pubKey)
+ throws IOException
+ {
+
+ ByteArrayInputStream _bais = new ByteArrayInputStream(_pubKey
+ .getEncoded());
+ SubjectPublicKeyInfo _info = new SubjectPublicKeyInfo(
+ (ASN1Sequence)new ASN1InputStream(_bais).readObject());
+
+ return new AuthorityKeyIdentifier(_info);
+ }
+
+ private static SubjectKeyIdentifier createSubjectKeyId(PublicKey _pubKey)
+ throws IOException
+ {
+ return new BcX509ExtensionUtils().createSubjectKeyIdentifier(SubjectPublicKeyInfo.getInstance(_pubKey.getEncoded()));
+ }
+
+ private static BigInteger allocateSerialNumber()
+ {
+ BigInteger _tmp = serialNumber;
+ serialNumber = serialNumber.add(BigInteger.valueOf(1));
+ return _tmp;
+ }
+}
diff --git a/pkix/src/test/java/org/spongycastle/cert/path/test/CertPathTest.java b/pkix/src/test/java/org/spongycastle/cert/path/test/CertPathTest.java
new file mode 100644
index 00000000..d166d935
--- /dev/null
+++ b/pkix/src/test/java/org/spongycastle/cert/path/test/CertPathTest.java
@@ -0,0 +1,369 @@
+package org.spongycastle.cert.path.test;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.ObjectOutputStream;
+import java.security.InvalidKeyException;
+import java.security.NoSuchAlgorithmException;
+import java.security.NoSuchProviderException;
+import java.security.PublicKey;
+import java.security.Security;
+import java.security.SignatureException;
+import java.security.cert.CertPath;
+import java.security.cert.CertPathBuilder;
+import java.security.cert.CertPathBuilderException;
+import java.security.cert.CertPathBuilderResult;
+import java.security.cert.CertStore;
+import java.security.cert.Certificate;
+import java.security.cert.CertificateEncodingException;
+import java.security.cert.CertificateException;
+import java.security.cert.CertificateFactory;
+import java.security.cert.CollectionCertStoreParameters;
+import java.security.cert.PKIXBuilderParameters;
+import java.security.cert.TrustAnchor;
+import java.security.cert.X509CertSelector;
+import java.security.cert.X509Certificate;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Set;
+import java.util.Vector;
+
+import org.spongycastle.jce.provider.BouncyCastleProvider;
+import org.spongycastle.util.encoders.Base64;
+import org.spongycastle.util.test.SimpleTest;
+
+public class CertPathTest
+ extends SimpleTest
+{
+ public static byte[] rootCertBin = Base64.decode(
+ "MIIBqzCCARQCAQEwDQYJKoZIhvcNAQEFBQAwHjEcMBoGA1UEAxMTVGVzdCBDQSBDZXJ0aWZpY2F0ZTAeFw0wODA5MDQwNDQ1MDhaFw0wODA5MTEwNDQ1MDhaMB4xHDAaBgNVBAMTE1Rlc3QgQ0EgQ2VydGlmaWNhdGUwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAMRLUjhPe4YUdLo6EcjKcWUOG7CydFTH53Pr1lWjOkbmszYDpkhCTT9LOsI+disk18nkBxSl8DAHTqV+VxtuTPt64iyi10YxyDeep+DwZG/f8cVQv97U3hA9cLurZ2CofkMLGr6JpSGCMZ9FcstcTdHB4lbErIJ54YqfF4pNOs4/AgMBAAEwDQYJKoZIhvcNAQEFBQADgYEAgyrTEFY7ALpeY59jL6xFOLpuPqoBOWrUWv6O+zy5BCU0qiX71r3BpigtxRj+DYcfLIM9FNERDoHu3TthD3nwYWUBtFX8N0QUJIdJabxqAMhLjSC744koiFpCYse5Ye3ZvEdFwDzgAQsJTp5eFGgTZPkPzcdhkFJ2p9+OWs+cb24=");
+
+
+ static byte[] interCertBin = Base64.decode(
+ "MIICSzCCAbSgAwIBAgIBATANBgkqhkiG9w0BAQUFADAeMRwwGgYDVQQDExNUZXN0IENBIENlcnRpZmljYXRlMB4XDTA4MDkwNDA0NDUwOFoXDTA4MDkxMTA0NDUwOFowKDEmMCQGA1UEAxMdVGVzdCBJbnRlcm1lZGlhdGUgQ2VydGlmaWNhdGUwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAISS9OOZ2wxzdWny9aVvk4Joq+dwSJ+oqvHUxX3PflZyuiLiCBUOUE4q59dGKdtNX5fIfwyK3cpV0e73Y/0fwfM3m9rOWFrCKOhfeswNTes0w/2PqPVVDDsF/nj7NApuqXwioeQlgTL251RDF4sVoxXqAU7lRkcqwZt3mwqS4KTJAgMBAAGjgY4wgYswRgYDVR0jBD8wPYAUhv8BOT27EB9JaCccJD4YASPP5XWhIqQgMB4xHDAaBgNVBAMTE1Rlc3QgQ0EgQ2VydGlmaWNhdGWCAQEwHQYDVR0OBBYEFL/IwAGOkHzaQyPZegy79CwM5oTFMBIGA1UdEwEB/wQIMAYBAf8CAQAwDgYDVR0PAQH/BAQDAgGGMA0GCSqGSIb3DQEBBQUAA4GBAE4TRgUz4sUvZyVdZxqV+XyNRnqXAeLOOqFGYv2D96tQrS+zjd0elVlT6lFrtchZdOmmX7R6/H/tjMWMcTBICZyRYrvK8cCAmDOI+EIdq5p6lj2Oq6Pbw/wruojAqNrpaR6IkwNpWtdOSSupv4IJL+YU9q2YFTh4R1j3tOkPoFGr");
+
+ static byte[] finalCertBin = Base64.decode(
+ "MIICRjCCAa+gAwIBAgIBATANBgkqhkiG9w0BAQUFADAoMSYwJAYDVQQDEx1UZXN0IEludGVybWVkaWF0ZSBDZXJ0aWZpY2F0ZTAeFw0wODA5MDQwNDQ1MDhaFw0wODA5MTEwNDQ1MDhaMB8xHTAbBgNVBAMTFFRlc3QgRW5kIENlcnRpZmljYXRlMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQChpUeo0tPYywWKiLlbWKNJBcCpSaLSlaZ+4+yer1AxI5yJIVHP6SAlBghlbD5Qne5ImnN/15cz1xwYAiul6vGKJkVPlFEe2Mr+g/J/WJPQQPsjbZ1G+vxbAwXEDA4KaQrnpjRZFq+CdKHwOjuPLYS/MYQNgdIvDVEQcTbPQ8GaiQIDAQABo4GIMIGFMEYGA1UdIwQ/MD2AFL/IwAGOkHzaQyPZegy79CwM5oTFoSKkIDAeMRwwGgYDVQQDExNUZXN0IENBIENlcnRpZmljYXRlggEBMB0GA1UdDgQWBBSVkw+VpqBf3zsLc/9GdkK9TzHPwDAMBgNVHRMBAf8EAjAAMA4GA1UdDwEB/wQEAwIFoDANBgkqhkiG9w0BAQUFAAOBgQBLv/0bVDjzTs/y1vN3FUiZNknEbzupIZduTuXJjqv/vBX+LDPjUfu/+iOCXOSKoRn6nlOWhwB1z6taG2usQkFG8InMkRcPREi2uVgFdhJ/1C3dAWhsdlubjdL926bftXvxnx/koDzyrePW5U96RlOQM2qLvbaky2Giz6hrc3Wl+w==");
+ public static byte[] rootCrlBin = Base64.decode(
+ "MIIBYjCBzAIBATANBgkqhkiG9w0BAQsFADAeMRwwGgYDVQQDExNUZXN0IENBIENlcnRpZmljYXRlFw0wODA5MDQwNDQ1MDhaFw0wODA5MDQwNzMxNDhaMCIwIAIBAhcNMDgwOTA0MDQ0NTA4WjAMMAoGA1UdFQQDCgEJoFYwVDBGBgNVHSMEPzA9gBSG/wE5PbsQH0loJxwkPhgBI8/ldaEipCAwHjEcMBoGA1UEAxMTVGVzdCBDQSBDZXJ0aWZpY2F0ZYIBATAKBgNVHRQEAwIBATANBgkqhkiG9w0BAQsFAAOBgQCAbaFCo0BNG4AktVf6jjBLeawP1u0ELYkOCEGvYZE0mBpQ+OvFg7subZ6r3lRIj030nUli28sPFtu5ZQMBNcpE4nS1ziF44RfT3Lp5UgHx9x17Krz781iEyV+7zU8YxYMY9wULD+DCuK294kGKIssVNbmTYXZatBNoXQN5CLIocA==");
+ static byte[] interCrlBin = Base64.decode(
+ "MIIBbDCB1gIBATANBgkqhkiG9w0BAQsFADAoMSYwJAYDVQQDEx1UZXN0IEludGVybWVkaWF0ZSBDZXJ0aWZpY2F0ZRcNMDgwOTA0MDQ0NTA4WhcNMDgwOTA0MDczMTQ4WjAiMCACAQIXDTA4MDkwNDA0NDUwOFowDDAKBgNVHRUEAwoBCaBWMFQwRgYDVR0jBD8wPYAUv8jAAY6QfNpDI9l6DLv0LAzmhMWhIqQgMB4xHDAaBgNVBAMTE1Rlc3QgQ0EgQ2VydGlmaWNhdGWCAQEwCgYDVR0UBAMCAQEwDQYJKoZIhvcNAQELBQADgYEAEVCr5TKs5yguGgLH+dBzmSPoeSIWJFLsgWwJEit/iUDJH3dgYmaczOcGxIDtbYYHLWIHM+P2YRyQz3MEkCXEgm/cx4y7leAmux5l+xQWgmxFPz+197vaphPeCZo+B7V1CWtm518gcq4mrs9ovfgNqgyFj7KGjcBpWdJE32KMt50=");
+
+ /*
+ * certpath with a circular reference
+ */
+ static byte[] certA = Base64.decode(
+ "MIIC6jCCAlOgAwIBAgIBBTANBgkqhkiG9w0BAQUFADCBjTEPMA0GA1UEAxMGSW50"
+ + "ZXIzMQswCQYDVQQGEwJDSDEPMA0GA1UEBxMGWnVyaWNoMQswCQYDVQQIEwJaSDEX"
+ + "MBUGA1UEChMOUHJpdmFzcGhlcmUgQUcxEDAOBgNVBAsTB1Rlc3RpbmcxJDAiBgkq"
+ + "hkiG9w0BCQEWFWFybWluQHByaXZhc3BoZXJlLmNvbTAeFw0wNzA0MDIwODQ2NTda"
+ + "Fw0xNzAzMzAwODQ0MDBaMIGlMScwJQYDVQQDHh4AQQByAG0AaQBuACAASADkAGIA"
+ + "ZQByAGwAaQBuAGcxCzAJBgNVBAYTAkNIMQ8wDQYDVQQHEwZadXJpY2gxCzAJBgNV"
+ + "BAgTAlpIMRcwFQYDVQQKEw5Qcml2YXNwaGVyZSBBRzEQMA4GA1UECxMHVGVzdGlu"
+ + "ZzEkMCIGCSqGSIb3DQEJARYVYXJtaW5AcHJpdmFzcGhlcmUuY29tMIGfMA0GCSqG"
+ + "SIb3DQEBAQUAA4GNADCBiQKBgQCfHfyVs5dbxG35H/Thd29qR4NZU88taCu/OWA1"
+ + "GdACI02lXWYpmLWiDgnU0ULP+GG8OnVp1IES9fz2zcrXKQ19xZzsen/To3h5sNte"
+ + "cJpS00XMM24q/jDwy5NvkBP9YIfFKQ1E/0hFHXcqwlw+b/y/v6YGsZCU2h6QDzc4"
+ + "5m0+BwIDAQABo0AwPjAMBgNVHRMBAf8EAjAAMA4GA1UdDwEB/wQEAwIE8DAeBglg"
+ + "hkgBhvhCAQ0EERYPeGNhIGNlcnRpZmljYXRlMA0GCSqGSIb3DQEBBQUAA4GBAJEu"
+ + "KiSfIwsY7SfobMLrv2v/BtLhGLi4RnmjiwzBhuv5rn4rRfBpq1ppmqQMJ2pmA67v"
+ + "UWCY+mNwuyjHyivpCCyJGsZ9d5H09g2vqxzkDBMz7X9VNMZYFH8j/R3/Cfvqks31"
+ + "z0OFslJkeKLa1I0P/dfVHsRKNkLRT3Ws5LKksErQ");
+
+ static byte[] certB = Base64.decode(
+ "MIICtTCCAh6gAwIBAgIBBDANBgkqhkiG9w0BAQQFADCBjTEPMA0GA1UEAxMGSW50"
+ + "ZXIyMQswCQYDVQQGEwJDSDEPMA0GA1UEBxMGWnVyaWNoMQswCQYDVQQIEwJaSDEX"
+ + "MBUGA1UEChMOUHJpdmFzcGhlcmUgQUcxEDAOBgNVBAsTB1Rlc3RpbmcxJDAiBgkq"
+ + "hkiG9w0BCQEWFWFybWluQHByaXZhc3BoZXJlLmNvbTAeFw0wNzA0MDIwODQ2Mzha"
+ + "Fw0xNzAzMzAwODQ0MDBaMIGNMQ8wDQYDVQQDEwZJbnRlcjMxCzAJBgNVBAYTAkNI"
+ + "MQ8wDQYDVQQHEwZadXJpY2gxCzAJBgNVBAgTAlpIMRcwFQYDVQQKEw5Qcml2YXNw"
+ + "aGVyZSBBRzEQMA4GA1UECxMHVGVzdGluZzEkMCIGCSqGSIb3DQEJARYVYXJtaW5A"
+ + "cHJpdmFzcGhlcmUuY29tMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCxCXIB"
+ + "QRnmVvl2h7Q+0SsRxDLnyM1dJG9jMa+UCCmHy0k/ZHs5VirSbjEJSjkQ9BGeh9SC"
+ + "7JwbMpXO7UE+gcVc2RnWUY+MA+fWIeTV4KtkYA8WPu8wVGCXbN8wwh/StOocszxb"
+ + "g+iLvGeh8CYSRqg6QN3S/02etH3o8H4e7Z0PZwIDAQABoyMwITAPBgNVHRMBAf8E"
+ + "BTADAQH/MA4GA1UdDwEB/wQEAwIB9jANBgkqhkiG9w0BAQQFAAOBgQCtWdirSsmt"
+ + "+CBBCNn6ZnbU3QqQfiiQIomjenNEHESJgaS/+PvPE5i3xWFXsunTHLW321/Km16I"
+ + "7+ZvT8Su1cqHg79NAT8QB0yke1saKSy2C0Pic4HwrNqVBWFNSxMU0hQzpx/ZXDbZ"
+ + "DqIXAp5EfyRYBy2ul+jm6Rot6aFgzuopKg==");
+
+ static byte[] certC = Base64.decode(
+ "MIICtTCCAh6gAwIBAgIBAjANBgkqhkiG9w0BAQQFADCBjTEPMA0GA1UEAxMGSW50"
+ + "ZXIxMQswCQYDVQQGEwJDSDEPMA0GA1UEBxMGWnVyaWNoMQswCQYDVQQIEwJaSDEX"
+ + "MBUGA1UEChMOUHJpdmFzcGhlcmUgQUcxEDAOBgNVBAsTB1Rlc3RpbmcxJDAiBgkq"
+ + "hkiG9w0BCQEWFWFybWluQHByaXZhc3BoZXJlLmNvbTAeFw0wNzA0MDIwODQ0Mzla"
+ + "Fw0xNzAzMzAwODQ0MDBaMIGNMQ8wDQYDVQQDEwZJbnRlcjIxCzAJBgNVBAYTAkNI"
+ + "MQ8wDQYDVQQHEwZadXJpY2gxCzAJBgNVBAgTAlpIMRcwFQYDVQQKEw5Qcml2YXNw"
+ + "aGVyZSBBRzEQMA4GA1UECxMHVGVzdGluZzEkMCIGCSqGSIb3DQEJARYVYXJtaW5A"
+ + "cHJpdmFzcGhlcmUuY29tMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQD0rLr6"
+ + "f2/ONeJzTb0q9M/NNX+MnAFMSqiQGVBkT76u5nOH4KLkpHXkzI82JI7GuQMzoT3a"
+ + "+RP1hO6FneO92ms2soC6xiOFb4EC69Dfhh87Nww5O35JxVF0bzmbmIAWd6P/7zGh"
+ + "nd2S4tKkaZcubps+C0j9Fgi0hipVicAOUVVoDQIDAQABoyMwITAPBgNVHRMBAf8E"
+ + "BTADAQH/MA4GA1UdDwEB/wQEAwIB9jANBgkqhkiG9w0BAQQFAAOBgQCLPvc1IMA4"
+ + "YP+PmnEldyUoRWRnvPWjBGeu0WheBP7fdcnGBf93Nmc5j68ZN+eTZ5VMuZ99YdvH"
+ + "CXGNX6oodONLU//LlFKdLl5xjLAS5X9p1RbOEGytnalqeiEpjk4+C/7rIBG1kllO"
+ + "dItmI6LlEMV09Hkpg6ZRAUmRkb8KrM4X7A==");
+
+ static byte[] certD = Base64.decode(
+ "MIICtTCCAh6gAwIBAgIBBjANBgkqhkiG9w0BAQQFADCBjTEPMA0GA1UEAxMGSW50"
+ + "ZXIzMQswCQYDVQQGEwJDSDEPMA0GA1UEBxMGWnVyaWNoMQswCQYDVQQIEwJaSDEX"
+ + "MBUGA1UEChMOUHJpdmFzcGhlcmUgQUcxEDAOBgNVBAsTB1Rlc3RpbmcxJDAiBgkq"
+ + "hkiG9w0BCQEWFWFybWluQHByaXZhc3BoZXJlLmNvbTAeFw0wNzA0MDIwODQ5NTNa"
+ + "Fw0xNzAzMzAwODQ0MDBaMIGNMQ8wDQYDVQQDEwZJbnRlcjExCzAJBgNVBAYTAkNI"
+ + "MQ8wDQYDVQQHEwZadXJpY2gxCzAJBgNVBAgTAlpIMRcwFQYDVQQKEw5Qcml2YXNw"
+ + "aGVyZSBBRzEQMA4GA1UECxMHVGVzdGluZzEkMCIGCSqGSIb3DQEJARYVYXJtaW5A"
+ + "cHJpdmFzcGhlcmUuY29tMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCae3TP"
+ + "jIVKeASqvNabaiUHAMGUgFxB7L0yUsIj39azLcLtUj4S7XkDf7SMGtYV0JY1XNaQ"
+ + "sHJAsnJivDZc50oiYvqDYfgFZx5+AsN5l5X5rjRzs/OX+Jo+k1OgsIyu6+mf9Kfb"
+ + "5IdWOVB2EcOg4f9tPjLM8CIj9Pp7RbKLyqUUgwIDAQABoyMwITAPBgNVHRMBAf8E"
+ + "BTADAQH/MA4GA1UdDwEB/wQEAwIB9jANBgkqhkiG9w0BAQQFAAOBgQCgr9kUdWUT"
+ + "Lt9UcztSzR3pnHRsyvS0E/z850OKQKS5/VxLEalpFvhj+3EcZ7Y6mFxaaS2B7vXg"
+ + "2YWyqV1PRb6iF7/u9EXkpSTKGrJahwANirCa3V/HTUuPdCE2GITlnWI8h3eVA+xQ"
+ + "D4LF0PXHOkXbwmhXRSb10lW1bSGkUxE9jg==");
+
+ private void testExceptions()
+ throws Exception
+ {
+ byte[] enc = { (byte)0, (byte)2, (byte)3, (byte)4, (byte)5 };
+ MyCertPath mc = new MyCertPath(enc);
+ ByteArrayOutputStream os = new ByteArrayOutputStream();
+ ByteArrayInputStream is;
+ byte[] arr;
+
+ ObjectOutputStream oOut = new ObjectOutputStream(os);
+ oOut.writeObject(mc);
+ oOut.flush();
+ oOut.close();
+
+ try
+ {
+ CertificateFactory cFac = CertificateFactory.getInstance("X.509",
+ "SC");
+ arr = os.toByteArray();
+ is = new ByteArrayInputStream(arr);
+ cFac.generateCertPath(is);
+ }
+ catch (CertificateException e)
+ {
+ // ignore okay
+ }
+
+ CertificateFactory cf = CertificateFactory.getInstance("X.509");
+ List certCol = new ArrayList();
+
+ certCol.add(cf.generateCertificate(new ByteArrayInputStream(certA)));
+ certCol.add(cf.generateCertificate(new ByteArrayInputStream(certB)));
+ certCol.add(cf.generateCertificate(new ByteArrayInputStream(certC)));
+ certCol.add(cf.generateCertificate(new ByteArrayInputStream(certD)));
+
+ CertPathBuilder pathBuilder = CertPathBuilder.getInstance("PKIX", "SC");
+ X509CertSelector select = new X509CertSelector();
+ select.setSubject(((X509Certificate)certCol.get(0)).getSubjectX500Principal().getEncoded());
+
+ Set trustanchors = new HashSet();
+ trustanchors.add(new TrustAnchor((X509Certificate)cf.generateCertificate(new ByteArrayInputStream(rootCertBin)), null));
+
+ CertStore certStore = CertStore.getInstance("Collection", new CollectionCertStoreParameters(certCol));
+
+ PKIXBuilderParameters params = new PKIXBuilderParameters(trustanchors, select);
+ params.addCertStore(certStore);
+
+ try
+ {
+ CertPathBuilderResult result = pathBuilder.build(params);
+ CertPath path = result.getCertPath();
+ fail("found cert path in circular set");
+ }
+ catch (CertPathBuilderException e)
+ {
+ // expected
+ }
+ }
+
+ public void performTest()
+ throws Exception
+ {
+ CertificateFactory cf = CertificateFactory.getInstance("X.509", "SC");
+
+ X509Certificate rootCert = (X509Certificate)cf.generateCertificate(new ByteArrayInputStream(rootCertBin));
+ X509Certificate interCert = (X509Certificate)cf.generateCertificate(new ByteArrayInputStream(interCertBin));
+ X509Certificate finalCert = (X509Certificate)cf.generateCertificate(new ByteArrayInputStream(finalCertBin));
+
+ //Testing CertPath generation from List
+ List list = new ArrayList();
+ list.add(interCert);
+ CertPath certPath1 = cf.generateCertPath(list);
+
+ //Testing CertPath encoding as PkiPath
+ byte[] encoded = certPath1.getEncoded("PkiPath");
+
+ //Testing CertPath generation from InputStream
+ ByteArrayInputStream inStream = new ByteArrayInputStream(encoded);
+ CertPath certPath2 = cf.generateCertPath(inStream, "PkiPath");
+
+ //Comparing both CertPathes
+ if (!certPath2.equals(certPath1))
+ {
+ fail("CertPath differ after encoding and decoding.");
+ }
+
+ encoded = certPath1.getEncoded("PKCS7");
+
+ //Testing CertPath generation from InputStream
+ inStream = new ByteArrayInputStream(encoded);
+ certPath2 = cf.generateCertPath(inStream, "PKCS7");
+
+ //Comparing both CertPathes
+ if (!certPath2.equals(certPath1))
+ {
+ fail("CertPath differ after encoding and decoding.");
+ }
+
+ encoded = certPath1.getEncoded("PEM");
+
+ //Testing CertPath generation from InputStream
+ inStream = new ByteArrayInputStream(encoded);
+ certPath2 = cf.generateCertPath(inStream, "PEM");
+
+ //Comparing both CertPathes
+ if (!certPath2.equals(certPath1))
+ {
+ fail("CertPath differ after encoding and decoding.");
+ }
+
+ //
+ // empty list test
+ //
+ list = new ArrayList();
+
+ CertPath certPath = CertificateFactory.getInstance("X.509","SC").generateCertPath(list);
+ if (certPath.getCertificates().size() != 0)
+ {
+ fail("list wrong size.");
+ }
+
+ //
+ // exception tests
+ //
+ testExceptions();
+ }
+
+ public String getName()
+ {
+ return "CertPath";
+ }
+
+ public static void main(
+ String[] args)
+ {
+ Security.addProvider(new BouncyCastleProvider());
+
+ runTest(new CertPathTest());
+ }
+
+ private static class MyCertificate extends Certificate
+ {
+ private final byte[] encoding;
+
+ public MyCertificate(String type, byte[] encoding)
+ {
+ super(type);
+ // don't copy to allow null parameter in test
+ this.encoding = encoding;
+ }
+
+ public byte[] getEncoded() throws CertificateEncodingException
+ {
+ // do copy to force NPE in test
+ return (byte[])encoding.clone();
+ }
+
+ public void verify(PublicKey key) throws CertificateException,
+ NoSuchAlgorithmException, InvalidKeyException,
+ NoSuchProviderException, SignatureException
+ {
+ }
+
+ public void verify(PublicKey key, String sigProvider)
+ throws CertificateException, NoSuchAlgorithmException,
+ InvalidKeyException, NoSuchProviderException,
+ SignatureException
+ {
+ }
+
+ public String toString()
+ {
+ return "[My test Certificate, type: " + getType() + "]";
+ }
+
+ public PublicKey getPublicKey()
+ {
+ return new PublicKey()
+ {
+ public String getAlgorithm()
+ {
+ return "TEST";
+ }
+
+ public byte[] getEncoded()
+ {
+ return new byte[] { (byte)1, (byte)2, (byte)3 };
+ }
+
+ public String getFormat()
+ {
+ return "TEST_FORMAT";
+ }
+ };
+ }
+ }
+
+ private static class MyCertPath extends CertPath
+ {
+ private final Vector certificates;
+
+ private final Vector encodingNames;
+
+ private final byte[] encoding;
+
+ public MyCertPath(byte[] encoding)
+ {
+ super("MyEncoding");
+ this.encoding = encoding;
+ certificates = new Vector();
+ certificates.add(new MyCertificate("MyEncoding", encoding));
+ encodingNames = new Vector();
+ encodingNames.add("MyEncoding");
+ }
+
+ public List getCertificates()
+ {
+ return Collections.unmodifiableList(certificates);
+ }
+
+ public byte[] getEncoded() throws CertificateEncodingException
+ {
+ return (byte[])encoding.clone();
+ }
+
+ public byte[] getEncoded(String encoding)
+ throws CertificateEncodingException
+ {
+ if (getType().equals(encoding))
+ {
+ return (byte[])this.encoding.clone();
+ }
+ throw new CertificateEncodingException("Encoding not supported: "
+ + encoding);
+ }
+
+ public Iterator getEncodings()
+ {
+ return Collections.unmodifiableCollection(encodingNames).iterator();
+ }
+ }
+}
+
diff --git a/pkix/src/test/java/org/spongycastle/cert/path/test/CertPathValidationTest.java b/pkix/src/test/java/org/spongycastle/cert/path/test/CertPathValidationTest.java
new file mode 100644
index 00000000..b168342c
--- /dev/null
+++ b/pkix/src/test/java/org/spongycastle/cert/path/test/CertPathValidationTest.java
@@ -0,0 +1,403 @@
+package org.spongycastle.cert.path.test;
+
+import java.security.Security;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.spongycastle.asn1.x509.Extension;
+import org.spongycastle.cert.X509CRLHolder;
+import org.spongycastle.cert.X509CertificateHolder;
+import org.spongycastle.cert.X509ContentVerifierProviderBuilder;
+import org.spongycastle.cert.jcajce.JcaX509ContentVerifierProviderBuilder;
+import org.spongycastle.cert.path.CertPath;
+import org.spongycastle.cert.path.CertPathValidation;
+import org.spongycastle.cert.path.CertPathValidationResult;
+import org.spongycastle.cert.path.validations.BasicConstraintsValidation;
+import org.spongycastle.cert.path.validations.CRLValidation;
+import org.spongycastle.cert.path.validations.KeyUsageValidation;
+import org.spongycastle.cert.path.validations.ParentCertIssuedValidation;
+import org.spongycastle.jce.provider.BouncyCastleProvider;
+import org.spongycastle.util.CollectionStore;
+import org.spongycastle.util.Store;
+import org.spongycastle.util.encoders.Base64;
+import org.spongycastle.util.test.SimpleTest;
+
+public class CertPathValidationTest
+ extends SimpleTest
+{
+ private byte[] AC_PR = Base64.decode(
+ "LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tDQpNSUlFU1RDQ0F6R2dBd0lC"
+ + "QWdJQkJUQU5CZ2txaGtpRzl3MEJBUVVGQURDQnRERUxNQWtHQTFVRUJoTUNR"
+ + "bEl4DQpFekFSQmdOVkJBb1RDa2xEVUMxQ2NtRnphV3d4UFRBN0JnTlZCQXNU"
+ + "TkVsdWMzUnBkSFYwYnlCT1lXTnBiMjVoDQpiQ0JrWlNCVVpXTnViMnh2WjJs"
+ + "aElHUmhJRWx1Wm05eWJXRmpZVzhnTFNCSlZFa3hFVEFQQmdOVkJBY1RDRUp5"
+ + "DQpZWE5wYkdsaE1Rc3dDUVlEVlFRSUV3SkVSakV4TUM4R0ExVUVBeE1vUVhW"
+ + "MGIzSnBaR0ZrWlNCRFpYSjBhV1pwDQpZMkZrYjNKaElGSmhhWG9nUW5KaGMy"
+ + "bHNaV2x5WVRBZUZ3MHdNakEwTURReE9UTTVNREJhRncwd05UQTBNRFF5DQpN"
+ + "elU1TURCYU1HRXhDekFKQmdOVkJBWVRBa0pTTVJNd0VRWURWUVFLRXdwSlEx"
+ + "QXRRbkpoYzJsc01UMHdPd1lEDQpWUVFERXpSQmRYUnZjbWxrWVdSbElFTmxj"
+ + "blJwWm1sallXUnZjbUVnWkdFZ1VISmxjMmxrWlc1amFXRWdaR0VnDQpVbVZ3"
+ + "ZFdKc2FXTmhNSUlCSWpBTkJna3Foa2lHOXcwQkFRRUZBQU9DQVE4QU1JSUJD"
+ + "Z0tDQVFFQXMwc0t5NGsrDQp6b016aldyMTQxeTVYQ045UGJMZERFQXN2cjZ4"
+ + "Z0NCN1l5bEhIQ1NBYmpGR3dOQ0R5NlVxN1h0VjZ6UHdIMXpGDQpFWENlS3Jm"
+ + "UUl5YXBXSEZ4V1VKajBMblFrY1RZM1FOR1huK0JuVk9EVTZDV3M1c3NoZktH"
+ + "RXZyVlQ1Z214V1NmDQp4OFlsdDgzY1dwUE1QZzg3VDlCaHVIbHQzazh2M2Ev"
+ + "NmRPbmF2dytOYTAyZExBaDBlNzZqcCtQUS9LK0pHZlBuDQphQjVVWURrZkd0"
+ + "em5uTTNBV01tY3VJK0o0ek5OMDZaa3ZnbDFsdEo2UU1qcnZEUFlSak9ndDlT"
+ + "cklpY1NmbEo4DQptVDdHWGRRaXJnQUNXc3g1QURBSklRK253TU1vNHlyTUtx"
+ + "SlFhNFFDMHhhT0QvdkdVcG9SaDQzT0FTZFp3c3YvDQpPWFlybmVJeVAwVCs4"
+ + "UUlEQVFBQm80RzNNSUcwTUQwR0ExVWRId1EyTURRd01xQXdvQzZHTEdoMGRI"
+ + "QTZMeTloDQpZM0poYVhvdWFXTndZbkpoYzJsc0xtZHZkaTVpY2k5TVExSmhZ"
+ + "M0poYVhvdVkzSnNNQklHQTFVZElBUUxNQWt3DQpCd1lGWUV3QkFRRXdIUVlE"
+ + "VlIwT0JCWUVGREpUVFlKNE9TWVB5T09KZkVMZXhDaHppK2hiTUI4R0ExVWRJ"
+ + "d1FZDQpNQmFBRklyNjhWZUVFUk0xa0VMNlYwbFVhUTJreFBBM01BNEdBMVVk"
+ + "RHdFQi93UUVBd0lCQmpBUEJnTlZIUk1CDQpBZjhFQlRBREFRSC9NQTBHQ1Nx"
+ + "R1NJYjNEUUVCQlFVQUE0SUJBUUJRUFNoZ1lidnFjaWV2SDVVb3ZMeXhkbkYr"
+ + "DQpFcjlOeXF1SWNkMnZ3Y0N1SnpKMkQ3WDBUcWhHQ0JmUEpVVkdBVWorS0NP"
+ + "SDFCVkgva1l1OUhsVHB1MGtKWFBwDQpBQlZkb2hJUERqRHhkbjhXcFFSL0Yr"
+ + "ejFDaWtVcldIMDR4eTd1N1p6UUpLSlBuR0loY1FpOElyRm1PYkllMEc3DQpY"
+ + "WTZPTjdPRUZxY21KTFFHWWdtRzFXMklXcytQd1JwWTdENGhLVEFoVjFSNkVv"
+ + "amE1L3BPcmVDL09kZXlQWmVxDQo1SUZTOUZZZk02U0Npd2hrK3l2Q1FHbVo0"
+ + "YzE5SjM0ZjVFYkRrK1NQR2tEK25EQ0E3L3VMUWNUMlJURE14SzBaDQpuZlo2"
+ + "Nm1Sc0ZjcXRGaWdScjVFcmtKZDdoUVV6eHNOV0VrNzJEVUFIcVgvNlNjeWtt"
+ + "SkR2V0plSUpqZlcNCi0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0NCg==");
+
+ private byte[] AC_RAIZ_ICPBRASIL = Base64.decode(
+ "LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tDQpNSUlFdURDQ0E2Q2dBd0lC"
+ + "QWdJQkJEQU5CZ2txaGtpRzl3MEJBUVVGQURDQnRERUxNQWtHQTFVRUJoTUNR"
+ + "bEl4DQpFekFSQmdOVkJBb1RDa2xEVUMxQ2NtRnphV3d4UFRBN0JnTlZCQXNU"
+ + "TkVsdWMzUnBkSFYwYnlCT1lXTnBiMjVoDQpiQ0JrWlNCVVpXTnViMnh2WjJs"
+ + "aElHUmhJRWx1Wm05eWJXRmpZVzhnTFNCSlZFa3hFVEFQQmdOVkJBY1RDRUp5"
+ + "DQpZWE5wYkdsaE1Rc3dDUVlEVlFRSUV3SkVSakV4TUM4R0ExVUVBeE1vUVhW"
+ + "MGIzSnBaR0ZrWlNCRFpYSjBhV1pwDQpZMkZrYjNKaElGSmhhWG9nUW5KaGMy"
+ + "bHNaV2x5WVRBZUZ3MHdNVEV4TXpBeE1qVTRNREJhRncweE1URXhNekF5DQpN"
+ + "elU1TURCYU1JRzBNUXN3Q1FZRFZRUUdFd0pDVWpFVE1CRUdBMVVFQ2hNS1NV"
+ + "TlFMVUp5WVhOcGJERTlNRHNHDQpBMVVFQ3hNMFNXNXpkR2wwZFhSdklFNWhZ"
+ + "Mmx2Ym1Gc0lHUmxJRlJsWTI1dmJHOW5hV0VnWkdFZ1NXNW1iM0p0DQpZV05o"
+ + "YnlBdElFbFVTVEVSTUE4R0ExVUVCeE1JUW5KaGMybHNhV0V4Q3pBSkJnTlZC"
+ + "QWdUQWtSR01URXdMd1lEDQpWUVFERXloQmRYUnZjbWxrWVdSbElFTmxjblJw"
+ + "Wm1sallXUnZjbUVnVW1GcGVpQkNjbUZ6YVd4bGFYSmhNSUlCDQpJakFOQmdr"
+ + "cWhraUc5dzBCQVFFRkFBT0NBUThBTUlJQkNnS0NBUUVBd1BNdWR3WC9odm0r"
+ + "VWgyYi9sUUFjSFZBDQppc2FtYUxrV2Rrd1A5L1MvdE9LSWdSckw2T3krWklH"
+ + "bE9VZGQ2dVl0azlNYS8zcFVwZ2NmTkFqMHZZbTVnc3lqDQpRbzllbXNjK3g2"
+ + "bTRWV3drOWlxTVpTQ0s1RVFrQXEvVXQ0bjdLdUxFMStnZGZ0d2RJZ3hmVXNQ"
+ + "dDRDeU5yWTUwDQpRVjU3S00yVVQ4eDVycm16RWpyN1RJQ0dwU1VBbDJnVnFl"
+ + "NnhhaWkrYm1ZUjFRcm1XYUJTQUc1OUxya3Jqcll0DQpiUmhGYm9VRGUxREsr"
+ + "NlQ4czVMNms4Yzhva3BiSHBhOXZlTXp0RFZDOXNQSjYwTVdYaDZhblZLbzFV"
+ + "Y0xjYlVSDQp5RWVOdlpuZVZSS0FBVTZvdXdkakR2d2xzYUt5ZEZLd2VkMFRv"
+ + "UTQ3Ym1VS2djbSt3VjNlVFJrMzZVT25Ud0lEDQpBUUFCbzRIU01JSFBNRTRH"
+ + "QTFVZElBUkhNRVV3UXdZRllFd0JBUUF3T2pBNEJnZ3JCZ0VGQlFjQ0FSWXNh"
+ + "SFIwDQpjRG92TDJGamNtRnBlaTVwWTNCaWNtRnphV3d1WjI5MkxtSnlMMFJR"
+ + "UTJGamNtRnBlaTV3WkdZd1BRWURWUjBmDQpCRFl3TkRBeW9EQ2dMb1lzYUhS"
+ + "MGNEb3ZMMkZqY21GcGVpNXBZM0JpY21GemFXd3VaMjkyTG1KeUwweERVbUZq"
+ + "DQpjbUZwZWk1amNtd3dIUVlEVlIwT0JCWUVGSXI2OFZlRUVSTTFrRUw2VjBs"
+ + "VWFRMmt4UEEzTUE4R0ExVWRFd0VCDQovd1FGTUFNQkFmOHdEZ1lEVlIwUEFR"
+ + "SC9CQVFEQWdFR01BMEdDU3FHU0liM0RRRUJCUVVBQTRJQkFRQVpBNWMxDQpV"
+ + "L2hnSWg2T2NnTEFmaUpnRldwdm1EWldxbFYzMC9iSEZwajhpQm9iSlNtNXVE"
+ + "cHQ3VGlyWWgxVXhlM2ZRYUdsDQpZakplKzl6ZCtpelBSYkJxWFBWUUEzNEVY"
+ + "Y3drNHFwV3VmMWhIcmlXZmRyeDhBY3FTcXI2Q3VRRndTcjc1Rm9zDQpTemx3"
+ + "REFEYTcwbVQ3d1pqQW1RaG5aeDJ4SjZ3ZldsVDlWUWZTLy9KWWVJYzdGdWUy"
+ + "Sk5MZDAwVU9TTU1haUsvDQp0NzllbktOSEVBMmZ1cEgzdkVpZ2Y1RWg0YlZB"
+ + "TjVWb2hyVG02TVk1M3g3WFFaWnIxTUU3YTU1bEZFblNlVDB1DQptbE9BalIy"
+ + "bUFidlNNNVg1b1NaTnJtZXRkenlUajJmbENNOENDN01MYWIwa2tkbmdSSWxV"
+ + "QkdIRjEvUzVubVBiDQpLKzlBNDZzZDMzb3FLOG44DQotLS0tLUVORCBDRVJU"
+ + "SUZJQ0FURS0tLS0tDQo=");
+
+ private byte[] schefer = Base64.decode(
+ "MIIEnDCCBAWgAwIBAgICIPAwDQYJKoZIhvcNAQEEBQAwgcAxCzAJBgNVBAYT"
+ + "AkRFMQ8wDQYDVQQIEwZIRVNTRU4xGDAWBgNVBAcTDzY1MDA4IFdpZXNiYWRl"
+ + "bjEaMBgGA1UEChMRU0NIVUZBIEhPTERJTkcgQUcxGjAYBgNVBAsTEVNDSFVG"
+ + "QSBIT0xESU5HIEFHMSIwIAYDVQQDExlJbnRlcm5ldCBCZW51dHplciBTZXJ2"
+ + "aWNlMSowKAYJKoZIhvcNAQkBFht6ZXJ0aWZpa2F0QHNjaHVmYS1vbmxpbmUu"
+ + "ZGUwHhcNMDQwMzMwMTEwODAzWhcNMDUwMzMwMTEwODAzWjCBnTELMAkGA1UE"
+ + "BhMCREUxCjAIBgNVBAcTASAxIzAhBgNVBAoTGlNIUyBJbmZvcm1hdGlvbnNz"
+ + "eXN0ZW1lIEFHMRwwGgYDVQQLExM2MDAvMDU5NDktNjAwLzA1OTQ5MRgwFgYD"
+ + "VQQDEw9TY2hldHRlciBTdGVmYW4xJTAjBgkqhkiG9w0BCQEWFlN0ZWZhbi5T"
+ + "Y2hldHRlckBzaHMuZGUwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAJD0"
+ + "95Bi76fkAMjJNTGPDiLPHmZXNsmakngDeS0juzKMeJA+TjXFouhYh6QyE4Bl"
+ + "Nf18fT4mInlgLefwf4t6meIWbiseeTo7VQdM+YrbXERMx2uHsRcgZMsiMYHM"
+ + "kVfYMK3SMJ4nhCmZxrBkoTRed4gXzVA1AA8YjjTqMyyjvt4TAgMBAAGjggHE"
+ + "MIIBwDAJBgNVHRMEAjAAMBEGCWCGSAGG+EIBAQQEAwIEsDALBgNVHQ8EBAMC"
+ + "BNAwOQYJYIZIAYb4QgENBCwWKlplcnRpZmlrYXQgbnVyIGZ1ZXIgU0NIVUZB"
+ + "LU9ubGluZSBndWVsdGlnLjAdBgNVHQ4EFgQUXReirhBfg0Yhf6MsBWoo/nPa"
+ + "hGwwge0GA1UdIwSB5TCB4oAUf2UyCaBV9JUeG9lS1Yo6OFBUdEKhgcakgcMw"
+ + "gcAxCzAJBgNVBAYTAkRFMQ8wDQYDVQQIEwZIRVNTRU4xGDAWBgNVBAcTDzY1"
+ + "MDA4IFdpZXNiYWRlbjEaMBgGA1UEChMRU0NIVUZBIEhPTERJTkcgQUcxGjAY"
+ + "BgNVBAsTEVNDSFVGQSBIT0xESU5HIEFHMSIwIAYDVQQDExlJbnRlcm5ldCBC"
+ + "ZW51dHplciBTZXJ2aWNlMSowKAYJKoZIhvcNAQkBFht6ZXJ0aWZpa2F0QHNj"
+ + "aHVmYS1vbmxpbmUuZGWCAQAwIQYDVR0RBBowGIEWU3RlZmFuLlNjaGV0dGVy"
+ + "QHNocy5kZTAmBgNVHRIEHzAdgRt6ZXJ0aWZpa2F0QHNjaHVmYS1vbmxpbmUu"
+ + "ZGUwDQYJKoZIhvcNAQEEBQADgYEAWzZtN9XQ9uyrFXqSy3hViYwV751+XZr0"
+ + "YH5IFhIS+9ixNAu8orP3bxqTaMhpwoU7T/oSsyGGSkb3fhzclgUADbA2lrOI"
+ + "GkeB/m+FArTwRbwpqhCNTwZywOp0eDosgPjCX1t53BB/m/2EYkRiYdDGsot0"
+ + "kQPOVGSjQSQ4+/D+TM8=");
+
+ // circular dependency certificates
+ private static final byte[] circCA = Base64.decode(
+ "MIIDTzCCAjegAwIBAgIDARAAMA0GCSqGSIb3DQEBBQUAMDkxCzAJBgNVBAYT"
+ + "AkZSMRAwDgYDVQQKEwdHSVAtQ1BTMRgwFgYDVQQLEw9HSVAtQ1BTIEFOT05Z"
+ + "TUUwHhcNMDQxMDExMDAwMDAxWhcNMTQxMjMxMjM1OTU5WjA5MQswCQYDVQQG"
+ + "EwJGUjEQMA4GA1UEChMHR0lQLUNQUzEYMBYGA1UECxMPR0lQLUNQUyBBTk9O"
+ + "WU1FMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA3WyWDwcM58aU"
+ + "hPX4ueI1mwETt3WdQtMfIdRiCXeBrjCkYCc7nIgCmGbnfTzXSplHRgKColWh"
+ + "q/Z+1rHYayje1gjAEU2+4/r1P2pnBmPgquDuguktCIbDtCcGZu0ylyKeHh37"
+ + "aeIKzkcmRSLRzvGf/eO3RdFksrvaPaSjqCVfGRXVDKK2uftE8rIFJE+bCqow"
+ + "6+WiaAaDDiJaSJPuu5hC1NA5jw0/BFodlCuAvl1GJ8A+TICkYWcSpKS9bkSC"
+ + "0i8xdGbSSk94shA1PdDvRdFMfFys8g4aupBXV8yqqEAUkBYmOtZSJckc3W4y"
+ + "2Gx53y7vY07Xh63mcgtJs2T82WJICwIDAQABo2AwXjAdBgNVHQ4EFgQU8c/P"
+ + "NNJaL0srd9SwHwgtvwPB/3cwDgYDVR0PAQH/BAQDAgIEMBkGA1UdIAQSMBAw"
+ + "DgYMKoF6AUcDBwgAAAABMBIGA1UdEwEB/wQIMAYBAf8CAQEwDQYJKoZIhvcN"
+ + "AQEFBQADggEBAHRjYDPJKlfUzID0YzajZpgR/i2ngJrJqYeaWCmwzBgNUPad"
+ + "uBKSGHmPVg21sfULMSnirnR+e90i/D0EVzLwQzcbjPDD/85rp9QDCeMxqqPe"
+ + "9ZCHGs2BpE/HOQMP0QfQ3/Kpk7SvOH/ZcpIf6+uE6lLBQYAGs5cxvtTGOzZk"
+ + "jCVFG+TrAnF4V5sNkn3maCWiYLmyqcnxtKEFSONy2bYqqudx/dBBlRrDbRfZ"
+ + "9XsCBdiXAHY1hFHldbfDs8rslmkXJi3fJC028HZYB6oiBX/JE7BbMk7bRnUf"
+ + "HSpP7Sjxeso2SY7Yit+hQDVAlqTDGmh6kLt/hQMpsOMry4vgBL6XHKw=");
+
+ private static final byte[] circCRLCA = Base64.decode(
+ "MIIDXDCCAkSgAwIBAgIDASAAMA0GCSqGSIb3DQEBBQUAMDkxCzAJBgNVBAYT"
+ + "AkZSMRAwDgYDVQQKEwdHSVAtQ1BTMRgwFgYDVQQLEw9HSVAtQ1BTIEFOT05Z"
+ + "TUUwHhcNMDQxMDExMDAwMDAxWhcNMTQxMjMxMjM1OTU5WjA5MQswCQYDVQQG"
+ + "EwJGUjEQMA4GA1UEChMHR0lQLUNQUzEYMBYGA1UECxMPR0lQLUNQUyBBTk9O"
+ + "WU1FMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAwfEcFK0g7Kfo"
+ + "o5f2IBF7VEd/AG+RVGSds0Yg+u2kNYu4k04HR/+tOdBQtJvyr4W5jrQKsC5X"
+ + "skeFWMyWaFKzAjZDWB52HWp/kiMivGcxnYDuYf5piukSC+d2+vL8YaAphDzV"
+ + "HPnxEKqoM/J66uUussDTqfcL3JC/Bc7kBwn4srrsZOsamMWTQQtEqVQxNN7A"
+ + "ROSRsdiTt3hMOKditc9/NBNmjZWxgc7Twr/SaZ8CfN5wf2wuOl23knWL0QsJ"
+ + "0lSMBSBTzTcfAke4/jIT7d4nVMp3t7dsna8rt56pFK4wpRFGuCt+1P5gi51x"
+ + "xVSdI+JoNXv6zGO4o8YVaRpC5rQeGQIDAQABo20wazAfBgNVHSMEGDAWgBTx"
+ + "z8800lovSyt31LAfCC2/A8H/dzAdBgNVHQ4EFgQUGa3SbBrJx/wa2MQwhWPl"
+ + "dwLw1+IwDgYDVR0PAQH/BAQDAgECMBkGA1UdIAQSMBAwDgYMKoF6AUcDBwgA"
+ + "AAABMA0GCSqGSIb3DQEBBQUAA4IBAQAPDpYe2WPYnXTLsXSIUREBNMLmg+/7"
+ + "4Yhq9uOm5Hb5LVkDuHoEHGfmpXXEvucx5Ehu69hw+F4YSrd9wPjOiG8G6GXi"
+ + "RcrK8nE8XDvvV+E1HpJ7NKN4fSAoSb+0gliiq3aF15bvXP8nfespdd/x1xWQ"
+ + "mpYCx/mJeuqONQv2/D/7hfRKYoDBaAkWGodenPFPVs6FxwnEuH2R+KWCUdA9"
+ + "L04v8JBeL3kZiALkU7+DCCm7A0imUAgeeArbAbfIPu6eDygm+XndZ9qi7o4O"
+ + "AntPxrqbeXFIbDrQ4GV1kpxnW+XpSGDd96SWKe715gxkkDBppR5IKYJwRb6O"
+ + "1TRQIf2F+muQ");
+
+ private static final byte[] circCRL = Base64.decode(
+ "MIIB1DCBvQIBATANBgkqhkiG9w0BAQUFADA5MQswCQYDVQQGEwJGUjEQMA4G"
+ + "A1UEChMHR0lQLUNQUzEYMBYGA1UECxMPR0lQLUNQUyBBTk9OWU1FFw0xMDAx"
+ + "MDcwMzAwMTVaFw0xMDAxMTMwMzAwMTVaMACgTjBMMB8GA1UdIwQYMBaAFBmt"
+ + "0mwaycf8GtjEMIVj5XcC8NfiMAsGA1UdFAQEAgILgzAcBgNVHRIEFTATgRFh"
+ + "Yy1naXBAZ2lwLWNwcy5mcjANBgkqhkiG9w0BAQUFAAOCAQEAtF1DdFl1MQvf"
+ + "vNkbrCPuppNYcHen4+za/ZDepKuwHsH/OpKuaDJc4LndRgd5IwzfpCHkQGzt"
+ + "shK50bakN8oaYJgthKIOIJzR+fn6NMjftfR2a27Hdk2o3eQXRHQ360qMbpSy"
+ + "qPb3WfuBhxO2/DlLChJP+OxZIHtT/rNYgE0tlIv7swYi81Gq+DafzaZ9+A5t"
+ + "I0L2Gp/NUDsp5dF6PllAGiXQzl27qkcu+r50w+u0gul3nobXgbwPcMSYuWUz"
+ + "1lhA+uDn/EUWV4RSiJciCGSS10WCkFh1/YPo++mV15KDB0m+8chscrSu/bAl"
+ + "B19LxL/pCX3qr5iLE9ss3olVImyFZg==");
+
+// private void checkCircProcessing()
+// throws Exception
+// {
+// CertificateFactory cf = CertificateFactory.getInstance("X.509", "SC");
+//
+// X509Certificate caCert = (X509Certificate)cf.generateCertificate(new ByteArrayInputStream(circCA));
+// X509Certificate crlCaCert = (X509Certificate)cf.generateCertificate(new ByteArrayInputStream(circCRLCA));
+// X509CRL crl = (X509CRL)cf.generateCRL(new ByteArrayInputStream(circCRL));
+//
+// List list = new ArrayList();
+//
+// list.add(caCert);
+// list.add(crlCaCert);
+// list.add(crl);
+//
+// CertStoreParameters ccsp = new CollectionCertStoreParameters(list);
+// CertStore store = CertStore.getInstance("Collection", ccsp);
+//
+// Calendar validDate = Calendar.getInstance();
+// validDate.set(2010,0,8,2,21,10);
+//
+// //validating path
+// List certchain = new ArrayList();
+//
+// certchain.add(crlCaCert);
+// CertPath cp = CertificateFactory.getInstance("X.509","SC").generateCertPath(certchain);
+//
+// Set trust = new HashSet();
+// trust.add(new TrustAnchor(caCert, null));
+//
+// CertPathValidator cpv = CertPathValidator.getInstance("PKIX","SC");
+// //PKIXParameters param = new PKIXParameters(trust);
+//
+// PKIXBuilderParameters param = new PKIXBuilderParameters(trust, null);
+// X509CertSelector certSelector = new X509CertSelector();
+// certSelector.setCertificate(crlCaCert);
+// param.setTargetCertConstraints(certSelector);
+// param.addCertStore(store);
+// param.setRevocationEnabled(true);
+// param.setDate(validDate.getTime());
+//
+// PKIXCertPathValidatorResult result = (PKIXCertPathValidatorResult)cpv.validate(cp, param);
+// }
+
+ public void performTest()
+ throws Exception
+ {
+ // initialise CertStore
+ X509CertificateHolder rootCert = new X509CertificateHolder(CertPathTest.rootCertBin);
+ X509CertificateHolder interCert = new X509CertificateHolder(CertPathTest.interCertBin);
+ X509CertificateHolder finalCert = new X509CertificateHolder(CertPathTest.finalCertBin);
+ X509CRLHolder rootCrl = new X509CRLHolder(CertPathTest.rootCrlBin);
+ X509CRLHolder interCrl = new X509CRLHolder(CertPathTest.interCrlBin);
+
+ CertPath path = new CertPath(new X509CertificateHolder[] { finalCert, interCert });
+ X509ContentVerifierProviderBuilder verifier = new JcaX509ContentVerifierProviderBuilder().setProvider(BouncyCastleProvider.PROVIDER_NAME);
+
+ CertPathValidationResult result = path.validate(new CertPathValidation[]{new ParentCertIssuedValidation(verifier), new BasicConstraintsValidation(), new KeyUsageValidation()});
+
+ if (!result.isValid())
+ {
+ fail("basic validation (1) not working");
+ }
+
+ List crlList = new ArrayList();
+
+ crlList.add(rootCrl);
+ crlList.add(interCrl);
+
+ Store crls = new CollectionStore(crlList);
+
+ result = path.validate(new CertPathValidation[]{new ParentCertIssuedValidation(verifier), new BasicConstraintsValidation(), new KeyUsageValidation(), new CRLValidation(rootCert.getSubject(), crls)});
+
+ if (!result.isValid())
+ {
+ fail("basic validation (2) not working");
+ }
+
+ result = path.validate(new CertPathValidation[]{new ParentCertIssuedValidation(verifier), new KeyUsageValidation(), new CRLValidation(rootCert.getSubject(), crls)});
+
+ if (result.isValid() || result.getUnhandledCriticalExtensionOIDs().size() != 1
+ || !result.getUnhandledCriticalExtensionOIDs().contains(Extension.basicConstraints))
+ {
+ fail("basic validation (3) not working");
+ }
+
+ result = path.validate(new CertPathValidation[]{new ParentCertIssuedValidation(verifier), new CRLValidation(rootCert.getSubject(), crls)});
+
+ if (result.isValid() || result.getUnhandledCriticalExtensionOIDs().size() != 2
+ || !result.getUnhandledCriticalExtensionOIDs().contains(Extension.basicConstraints)
+ || !result.getUnhandledCriticalExtensionOIDs().contains(Extension.keyUsage))
+ {
+ fail("basic validation (4) not working");
+ }
+
+ path = new CertPath(new X509CertificateHolder[] { interCert, finalCert });
+
+ result = path.validate(new CertPathValidation[]{new ParentCertIssuedValidation(verifier)});
+
+ if (result.isValid())
+ {
+ fail("incorrect path validated!!");
+ }
+
+
+
+// List list = new ArrayList();
+// list.add(rootCert);
+// list.add(interCert);
+// list.add(finalCert);
+// list.add(rootCrl);
+// list.add(interCrl);
+// CollectionCertStoreParameters ccsp = new CollectionCertStoreParameters(list);
+// CertStore store = CertStore.getInstance("Collection", ccsp, "SC");
+// Calendar validDate = Calendar.getInstance();
+// validDate.set(2008,8,4,14,49,10);
+// //validating path
+// List certchain = new ArrayList();
+// certchain.add(finalCert);
+// certchain.add(interCert);
+// CertPath cp = CertificateFactory.getInstance("X.509","SC").generateCertPath(certchain);
+// Set trust = new HashSet();
+// trust.add(new TrustAnchor(rootCert, null));
+//
+// CertPathValidator cpv = CertPathValidator.getInstance("PKIX","SC");
+// PKIXParameters param = new PKIXParameters(trust);
+// param.addCertStore(store);
+// param.setDate(validDate.getTime());
+// MyChecker checker = new MyChecker();
+// param.addCertPathChecker(checker);
+//
+// PKIXCertPathValidatorResult result =
+// (PKIXCertPathValidatorResult) cpv.validate(cp, param);
+// PolicyNode policyTree = result.getPolicyTree();
+// PublicKey subjectPublicKey = result.getPublicKey();
+//
+// if (checker.getCount() != 2)
+// {
+// fail("checker not evaluated for each certificate");
+// }
+//
+// if (!subjectPublicKey.equals(finalCert.getPublicKey()))
+// {
+// fail("wrong public key returned");
+// }
+//
+// //
+// // invalid path containing a valid one test
+// //
+// try
+// {
+// // initialise CertStore
+// rootCert = (X509Certificate)cf.generateCertificate(new ByteArrayInputStream(AC_RAIZ_ICPBRASIL));
+// interCert = (X509Certificate)cf.generateCertificate(new ByteArrayInputStream(AC_PR));
+// finalCert = (X509Certificate)cf.generateCertificate(new ByteArrayInputStream(schefer));
+//
+// list = new ArrayList();
+// list.add(rootCert);
+// list.add(interCert);
+// list.add(finalCert);
+//
+// ccsp = new CollectionCertStoreParameters(list);
+// store = CertStore.getInstance("Collection", ccsp);
+// validDate = Calendar.getInstance();
+// validDate.set(2004,2,21,2,21,10);
+//
+// //validating path
+// certchain = new ArrayList();
+// certchain.add(finalCert);
+// certchain.add(interCert);
+// cp = CertificateFactory.getInstance("X.509","SC").generateCertPath(certchain);
+// trust = new HashSet();
+// trust.add(new TrustAnchor(rootCert, null));
+//
+// cpv = CertPathValidator.getInstance("PKIX","SC");
+// param = new PKIXParameters(trust);
+// param.addCertStore(store);
+// param.setRevocationEnabled(false);
+// param.setDate(validDate.getTime());
+//
+// result =(PKIXCertPathValidatorResult) cpv.validate(cp, param);
+// policyTree = result.getPolicyTree();
+// subjectPublicKey = result.getPublicKey();
+//
+// fail("Invalid path validated");
+// }
+// catch (Exception e)
+// {
+// if (!(e instanceof CertPathValidatorException
+// && e.getMessage().startsWith("Could not validate certificate signature.")))
+// {
+// fail("unexpected exception", e);
+// }
+// }
+//
+// checkCircProcessing();
+ }
+
+ public String getName()
+ {
+ return "CertPathValidator";
+ }
+
+ public static void main(
+ String[] args)
+ {
+ Security.addProvider(new BouncyCastleProvider());
+
+ runTest(new CertPathValidationTest());
+ }
+}
+
diff --git a/pkix/src/test/java/org/spongycastle/cert/test/AllTests.java b/pkix/src/test/java/org/spongycastle/cert/test/AllTests.java
new file mode 100644
index 00000000..162abafb
--- /dev/null
+++ b/pkix/src/test/java/org/spongycastle/cert/test/AllTests.java
@@ -0,0 +1,57 @@
+package org.spongycastle.cert.test;
+
+import java.security.Security;
+
+import junit.framework.Test;
+import junit.framework.TestCase;
+import junit.framework.TestSuite;
+import org.spongycastle.jce.provider.BouncyCastleProvider;
+import org.spongycastle.util.test.SimpleTestResult;
+
+public class AllTests
+ extends TestCase
+{
+ public void testSimpleTests()
+ {
+ org.spongycastle.util.test.Test[] tests = new org.spongycastle.util.test.Test[] { new CertTest(), new PKCS10Test(), new AttrCertSelectorTest(), new AttrCertTest(), new X509ExtensionUtilsTest() };
+
+ for (int i = 0; i != tests.length; i++)
+ {
+ SimpleTestResult result = (SimpleTestResult)tests[i].perform();
+
+ if (!result.isSuccessful())
+ {
+ if (result.getException() != null)
+ {
+ result.getException().printStackTrace();
+ }
+ fail(result.toString());
+ }
+ }
+ }
+
+ public static void main (String[] args)
+ {
+ junit.textui.TestRunner.run(suite());
+ }
+
+ public static Test suite()
+ {
+ TestSuite suite = new TestSuite("Cert Tests");
+
+ if (Security.getProvider("SC") == null)
+ {
+ Security.addProvider(new BouncyCastleProvider());
+ }
+
+ suite.addTestSuite(AllTests.class);
+ suite.addTestSuite(BcAttrCertSelectorTest.class);
+ suite.addTestSuite(BcAttrCertSelectorTest.class);
+ suite.addTestSuite(BcAttrCertTest.class);
+ suite.addTestSuite(BcCertTest.class);
+ suite.addTestSuite(BcPKCS10Test.class);
+ suite.addTest(ConverterTest.suite());
+
+ return suite;
+ }
+} \ No newline at end of file
diff --git a/pkix/src/test/java/org/spongycastle/cert/test/AttrCertSelectorTest.java b/pkix/src/test/java/org/spongycastle/cert/test/AttrCertSelectorTest.java
new file mode 100644
index 00000000..99412f08
--- /dev/null
+++ b/pkix/src/test/java/org/spongycastle/cert/test/AttrCertSelectorTest.java
@@ -0,0 +1,243 @@
+package org.spongycastle.cert.test;
+
+import java.io.ByteArrayInputStream;
+import java.math.BigInteger;
+import java.security.KeyFactory;
+import java.security.PrivateKey;
+import java.security.Security;
+import java.security.cert.CertificateFactory;
+import java.security.cert.X509Certificate;
+import java.security.spec.RSAPrivateCrtKeySpec;
+import java.util.Date;
+
+import org.spongycastle.asn1.ASN1EncodableVector;
+import org.spongycastle.asn1.ASN1ObjectIdentifier;
+import org.spongycastle.asn1.DERSequence;
+import org.spongycastle.asn1.x500.X500Name;
+import org.spongycastle.asn1.x509.GeneralName;
+import org.spongycastle.asn1.x509.Target;
+import org.spongycastle.asn1.x509.TargetInformation;
+import org.spongycastle.asn1.x509.X509Extension;
+import org.spongycastle.cert.AttributeCertificateHolder;
+import org.spongycastle.cert.AttributeCertificateIssuer;
+import org.spongycastle.cert.X509AttributeCertificateHolder;
+import org.spongycastle.cert.X509CertificateHolder;
+import org.spongycastle.cert.X509v2AttributeCertificateBuilder;
+import org.spongycastle.cert.jcajce.JcaX509CertificateHolder;
+import org.spongycastle.cert.selector.X509AttributeCertificateHolderSelectorBuilder;
+import org.spongycastle.jce.provider.BouncyCastleProvider;
+import org.spongycastle.operator.ContentSigner;
+import org.spongycastle.operator.jcajce.JcaContentSignerBuilder;
+import org.spongycastle.util.encoders.Base64;
+import org.spongycastle.util.test.SimpleTest;
+import org.spongycastle.util.test.Test;
+import org.spongycastle.util.test.TestResult;
+
+public class AttrCertSelectorTest
+ extends SimpleTest
+{
+ private static final String BC = BouncyCastleProvider.PROVIDER_NAME;
+
+ static final RSAPrivateCrtKeySpec RSA_PRIVATE_KEY_SPEC = new RSAPrivateCrtKeySpec(
+ new BigInteger(
+ "b4a7e46170574f16a97082b22be58b6a2a629798419be12872a4bdba626cfae9900f76abfb12139dce5de56564fab2b6543165a040c606887420e33d91ed7ed7",
+ 16),
+ new BigInteger("11", 16),
+ new BigInteger(
+ "9f66f6b05410cd503b2709e88115d55daced94d1a34d4e32bf824d0dde6028ae79c5f07b580f5dce240d7111f7ddb130a7945cd7d957d1920994da389f490c89",
+ 16), new BigInteger(
+ "c0a0758cdf14256f78d4708c86becdead1b50ad4ad6c5c703e2168fbf37884cb",
+ 16), new BigInteger(
+ "f01734d7960ea60070f1b06f2bb81bfac48ff192ae18451d5e56c734a5aab8a5",
+ 16), new BigInteger(
+ "b54bb9edff22051d9ee60f9351a48591b6500a319429c069a3e335a1d6171391",
+ 16), new BigInteger(
+ "d3d83daf2a0cecd3367ae6f8ae1aeb82e9ac2f816c6fc483533d8297dd7884cd",
+ 16), new BigInteger(
+ "b8f52fc6f38593dabb661d3f50f8897f8106eee68b1bce78a95b132b4e5b5d19",
+ 16));
+
+ static final byte[] holderCert = Base64
+ .decode("MIIGjTCCBXWgAwIBAgICAPswDQYJKoZIhvcNAQEEBQAwaTEdMBsGCSqGSIb3DQEJ"
+ + "ARYOaXJtaGVscEB2dC5lZHUxLjAsBgNVBAMTJVZpcmdpbmlhIFRlY2ggQ2VydGlm"
+ + "aWNhdGlvbiBBdXRob3JpdHkxCzAJBgNVBAoTAnZ0MQswCQYDVQQGEwJVUzAeFw0w"
+ + "MzAxMzExMzUyMTRaFw0wNDAxMzExMzUyMTRaMIGDMRswGQYJKoZIhvcNAQkBFgxz"
+ + "c2hhaEB2dC5lZHUxGzAZBgNVBAMTElN1bWl0IFNoYWggKHNzaGFoKTEbMBkGA1UE"
+ + "CxMSVmlyZ2luaWEgVGVjaCBVc2VyMRAwDgYDVQQLEwdDbGFzcyAxMQswCQYDVQQK"
+ + "EwJ2dDELMAkGA1UEBhMCVVMwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAPDc"
+ + "scgSKmsEp0VegFkuitD5j5PUkDuzLjlfaYONt2SN8WeqU4j2qtlCnsipa128cyKS"
+ + "JzYe9duUdNxquh5BPIkMkHBw4jHoQA33tk0J/sydWdN74/AHPpPieK5GHwhU7GTG"
+ + "rCCS1PJRxjXqse79ExAlul+gjQwHeldAC+d4A6oZAgMBAAGjggOmMIIDojAMBgNV"
+ + "HRMBAf8EAjAAMBEGCWCGSAGG+EIBAQQEAwIFoDAOBgNVHQ8BAf8EBAMCA/gwHQYD"
+ + "VR0lBBYwFAYIKwYBBQUHAwIGCCsGAQUFBwMEMB0GA1UdDgQWBBRUIoWAzlXbzBYE"
+ + "yVTjQFWyMMKo1jCBkwYDVR0jBIGLMIGIgBTgc3Fm+TGqKDhen+oKfbl+xVbj2KFt"
+ + "pGswaTEdMBsGCSqGSIb3DQEJARYOaXJtaGVscEB2dC5lZHUxLjAsBgNVBAMTJVZp"
+ + "cmdpbmlhIFRlY2ggQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkxCzAJBgNVBAoTAnZ0"
+ + "MQswCQYDVQQGEwJVU4IBADCBiwYJYIZIAYb4QgENBH4WfFZpcmdpbmlhIFRlY2gg"
+ + "Q2VydGlmaWNhdGlvbiBBdXRob3JpdHkgZGlnaXRhbCBjZXJ0aWZpY2F0ZXMgYXJl"
+ + "IHN1YmplY3QgdG8gcG9saWNpZXMgbG9jYXRlZCBhdCBodHRwOi8vd3d3LnBraS52"
+ + "dC5lZHUvY2EvY3BzLy4wFwYDVR0RBBAwDoEMc3NoYWhAdnQuZWR1MBkGA1UdEgQS"
+ + "MBCBDmlybWhlbHBAdnQuZWR1MEMGCCsGAQUFBwEBBDcwNTAzBggrBgEFBQcwAoYn"
+ + "aHR0cDovL2JveDE3Ny5jYy52dC5lZHUvY2EvaXNzdWVycy5odG1sMEQGA1UdHwQ9"
+ + "MDswOaA3oDWGM2h0dHA6Ly9ib3gxNzcuY2MudnQuZWR1L2h0ZG9jcy1wdWJsaWMv"
+ + "Y3JsL2NhY3JsLmNybDBUBgNVHSAETTBLMA0GCysGAQQBtGgFAQEBMDoGCysGAQQB"
+ + "tGgFAQEBMCswKQYIKwYBBQUHAgEWHWh0dHA6Ly93d3cucGtpLnZ0LmVkdS9jYS9j"
+ + "cHMvMD8GCWCGSAGG+EIBBAQyFjBodHRwOi8vYm94MTc3LmNjLnZ0LmVkdS9jZ2kt"
+ + "cHVibGljL2NoZWNrX3Jldl9jYT8wPAYJYIZIAYb4QgEDBC8WLWh0dHA6Ly9ib3gx"
+ + "NzcuY2MudnQuZWR1L2NnaS1wdWJsaWMvY2hlY2tfcmV2PzBLBglghkgBhvhCAQcE"
+ + "PhY8aHR0cHM6Ly9ib3gxNzcuY2MudnQuZWR1L35PcGVuQ0E4LjAxMDYzMC9jZ2kt"
+ + "cHVibGljL3JlbmV3YWw/MCwGCWCGSAGG+EIBCAQfFh1odHRwOi8vd3d3LnBraS52"
+ + "dC5lZHUvY2EvY3BzLzANBgkqhkiG9w0BAQQFAAOCAQEAHJ2ls9yjpZVcu5DqiE67"
+ + "r7BfkdMnm7IOj2v8cd4EAlPp6OPBmjwDMwvKRBb/P733kLBqFNWXWKTpT008R0KB"
+ + "8kehbx4h0UPz9vp31zhGv169+5iReQUUQSIwTGNWGLzrT8kPdvxiSAvdAJxcbRBm"
+ + "KzDic5I8PoGe48kSCkPpT1oNmnivmcu5j1SMvlx0IS2BkFMksr0OHiAW1elSnE/N"
+ + "RuX2k73b3FucwVxB3NRo3vgoHPCTnh9r4qItAHdxFlF+pPtbw2oHESKRfMRfOIHz"
+ + "CLQWSIa6Tvg4NIV3RRJ0sbCObesyg08lymalQMdkXwtRn5eGE00SHWwEUjSXP2gR"
+ + "3g==");
+
+ public String getName()
+ {
+ return "AttrCertSelector";
+ }
+
+ private X509AttributeCertificateHolder createAttrCert() throws Exception
+ {
+ CertificateFactory fact = CertificateFactory.getInstance("X.509", "SC");
+ X509Certificate iCert = (X509Certificate) fact
+ .generateCertificate(new ByteArrayInputStream(holderCert));
+ X509CertificateHolder iCertHolder = new JcaX509CertificateHolder(iCert);
+ //
+ // a sample key pair.
+ //
+ // RSAPublicKeySpec pubKeySpec = new RSAPublicKeySpec(
+ // new BigInteger(
+ // "b4a7e46170574f16a97082b22be58b6a2a629798419be12872a4bdba626cfae9900f76abfb12139dce5de56564fab2b6543165a040c606887420e33d91ed7ed7",
+ // 16), new BigInteger("11", 16));
+
+ //
+ // set up the keys
+ //
+ PrivateKey privKey;
+
+ KeyFactory kFact = KeyFactory.getInstance("RSA", "SC");
+
+ privKey = kFact.generatePrivate(RSA_PRIVATE_KEY_SPEC);
+
+ X509v2AttributeCertificateBuilder gen = new X509v2AttributeCertificateBuilder(
+ new AttributeCertificateHolder(iCertHolder.getSubject()),
+ new AttributeCertificateIssuer(new X500Name("cn=test")),
+ BigInteger.valueOf(1),
+ new Date(System.currentTimeMillis() - 50000),
+ new Date(System.currentTimeMillis() + 50000));
+
+ // the actual attributes
+ GeneralName roleName = new GeneralName(GeneralName.rfc822Name,
+ "DAU123456789@test.com");
+ ASN1EncodableVector roleSyntax = new ASN1EncodableVector();
+ roleSyntax.add(roleName);
+
+ // roleSyntax OID: 2.5.24.72
+ gen.addAttribute(new ASN1ObjectIdentifier("2.5.24.72"), new DERSequence(roleSyntax));
+
+
+ ContentSigner sigGen = new JcaContentSignerBuilder("SHA1WithRSAEncryption").setProvider(BC).build(privKey);
+
+ Target targetName = new Target(Target.targetName, new GeneralName(GeneralName.dNSName,
+ "www.test.com"));
+
+ Target targetGroup = new Target(Target.targetGroup, new GeneralName(
+ GeneralName.directoryName, "o=Test, ou=Test"));
+ Target[] targets = new Target[2];
+ targets[0] = targetName;
+ targets[1] = targetGroup;
+ TargetInformation targetInformation = new TargetInformation(targets);
+
+ gen.addExtension(X509Extension.targetInformation, true, targetInformation);
+
+ return gen.build(sigGen);
+ }
+
+ public void testSelector() throws Exception
+ {
+ X509AttributeCertificateHolder aCert = createAttrCert();
+ X509AttributeCertificateHolderSelectorBuilder sel = new X509AttributeCertificateHolderSelectorBuilder();
+ sel.setAttributeCert(aCert);
+ boolean match = sel.build().match(aCert);
+ if (!match)
+ {
+ fail("Selector does not match attribute certificate.");
+ }
+ sel.setAttributeCert(null);
+ match = sel.build().match(aCert);
+ if (!match)
+ {
+ fail("Selector does not match attribute certificate.");
+ }
+ sel.setHolder(aCert.getHolder());
+ match = sel.build().match(aCert);
+ if (!match)
+ {
+ fail("Selector does not match attribute certificate holder.");
+ }
+ sel.setHolder(null);
+ sel.setIssuer(aCert.getIssuer());
+ match = sel.build().match(aCert);
+ if (!match)
+ {
+ fail("Selector does not match attribute certificate issuer.");
+ }
+ sel.setIssuer(null);
+
+ CertificateFactory fact = CertificateFactory.getInstance("X.509", "SC");
+ X509CertificateHolder iCert = new JcaX509CertificateHolder((X509Certificate) fact
+ .generateCertificate(new ByteArrayInputStream(holderCert)));
+ match = aCert.getHolder().match(iCert);
+ if (!match)
+ {
+ fail("Issuer holder does not match signing certificate of attribute certificate.");
+ }
+
+ sel.setSerialNumber(aCert.getSerialNumber());
+ match = sel.build().match(aCert);
+ if (!match)
+ {
+ fail("Selector does not match attribute certificate serial number.");
+ }
+
+ sel.setAttributeCertificateValid(new Date());
+ match = sel.build().match(aCert);
+ if (!match)
+ {
+ fail("Selector does not match attribute certificate time.");
+ }
+
+ sel.addTargetName(new GeneralName(2, "www.test.com"));
+ match = sel.build().match(aCert);
+ if (!match)
+ {
+ fail("Selector does not match attribute certificate target name.");
+ }
+ sel.setTargetNames(null);
+ sel.addTargetGroup(new GeneralName(4, "o=Test, ou=Test"));
+ match = sel.build().match(aCert);
+ if (!match)
+ {
+ fail("Selector does not match attribute certificate target group.");
+ }
+ sel.setTargetGroups(null);
+ }
+
+ public void performTest() throws Exception
+ {
+ Security.addProvider(new BouncyCastleProvider());
+ testSelector();
+ }
+
+ public static void main(String[] args)
+ {
+ Test test = new AttrCertSelectorTest();
+ TestResult result = test.perform();
+ System.out.println(result);
+ }
+}
+
diff --git a/pkix/src/test/java/org/spongycastle/cert/test/AttrCertTest.java b/pkix/src/test/java/org/spongycastle/cert/test/AttrCertTest.java
new file mode 100644
index 00000000..ea350426
--- /dev/null
+++ b/pkix/src/test/java/org/spongycastle/cert/test/AttrCertTest.java
@@ -0,0 +1,667 @@
+package org.spongycastle.cert.test;
+
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.math.BigInteger;
+import java.security.KeyFactory;
+import java.security.PrivateKey;
+import java.security.PublicKey;
+import java.security.Security;
+import java.security.cert.CertificateFactory;
+import java.security.cert.X509Certificate;
+import java.security.spec.RSAPrivateCrtKeySpec;
+import java.security.spec.RSAPublicKeySpec;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Date;
+import java.util.List;
+import java.util.Set;
+
+import javax.security.auth.x500.X500Principal;
+
+import org.spongycastle.asn1.ASN1Encodable;
+import org.spongycastle.asn1.ASN1EncodableVector;
+import org.spongycastle.asn1.ASN1ObjectIdentifier;
+import org.spongycastle.asn1.ASN1String;
+import org.spongycastle.asn1.DEROctetString;
+import org.spongycastle.asn1.DERSequence;
+import org.spongycastle.asn1.x500.X500Name;
+import org.spongycastle.asn1.x509.Attribute;
+import org.spongycastle.asn1.x509.Extension;
+import org.spongycastle.asn1.x509.GeneralName;
+import org.spongycastle.asn1.x509.GeneralNames;
+import org.spongycastle.cert.AttributeCertificateHolder;
+import org.spongycastle.cert.AttributeCertificateIssuer;
+import org.spongycastle.cert.X509AttributeCertificateHolder;
+import org.spongycastle.cert.X509v2AttributeCertificateBuilder;
+import org.spongycastle.cert.jcajce.JcaCertStore;
+import org.spongycastle.cert.jcajce.JcaX509CertificateHolder;
+import org.spongycastle.jce.provider.BouncyCastleProvider;
+import org.spongycastle.operator.ContentSigner;
+import org.spongycastle.operator.jcajce.JcaContentSignerBuilder;
+import org.spongycastle.operator.jcajce.JcaContentVerifierProviderBuilder;
+import org.spongycastle.util.Store;
+import org.spongycastle.util.encoders.Base64;
+import org.spongycastle.util.test.SimpleTest;
+
+public class AttrCertTest
+ extends SimpleTest
+{
+ private static final String BC = BouncyCastleProvider.PROVIDER_NAME;
+
+ private static final RSAPrivateCrtKeySpec RSA_PRIVATE_KEY_SPEC = new RSAPrivateCrtKeySpec(
+ new BigInteger("b4a7e46170574f16a97082b22be58b6a2a629798419be12872a4bdba626cfae9900f76abfb12139dce5de56564fab2b6543165a040c606887420e33d91ed7ed7", 16),
+ new BigInteger("11", 16),
+ new BigInteger("9f66f6b05410cd503b2709e88115d55daced94d1a34d4e32bf824d0dde6028ae79c5f07b580f5dce240d7111f7ddb130a7945cd7d957d1920994da389f490c89", 16),
+ new BigInteger("c0a0758cdf14256f78d4708c86becdead1b50ad4ad6c5c703e2168fbf37884cb", 16),
+ new BigInteger("f01734d7960ea60070f1b06f2bb81bfac48ff192ae18451d5e56c734a5aab8a5", 16),
+ new BigInteger("b54bb9edff22051d9ee60f9351a48591b6500a319429c069a3e335a1d6171391", 16),
+ new BigInteger("d3d83daf2a0cecd3367ae6f8ae1aeb82e9ac2f816c6fc483533d8297dd7884cd", 16),
+ new BigInteger("b8f52fc6f38593dabb661d3f50f8897f8106eee68b1bce78a95b132b4e5b5d19", 16));
+
+ public static byte[] attrCert = Base64.decode(
+ "MIIHQDCCBqkCAQEwgZChgY2kgYowgYcxHDAaBgkqhkiG9w0BCQEWDW1sb3JjaEB2"
+ + "dC5lZHUxHjAcBgNVBAMTFU1hcmt1cyBMb3JjaCAobWxvcmNoKTEbMBkGA1UECxMS"
+ + "VmlyZ2luaWEgVGVjaCBVc2VyMRAwDgYDVQQLEwdDbGFzcyAyMQswCQYDVQQKEwJ2"
+ + "dDELMAkGA1UEBhMCVVMwgYmkgYYwgYMxGzAZBgkqhkiG9w0BCQEWDHNzaGFoQHZ0"
+ + "LmVkdTEbMBkGA1UEAxMSU3VtaXQgU2hhaCAoc3NoYWgpMRswGQYDVQQLExJWaXJn"
+ + "aW5pYSBUZWNoIFVzZXIxEDAOBgNVBAsTB0NsYXNzIDExCzAJBgNVBAoTAnZ0MQsw"
+ + "CQYDVQQGEwJVUzANBgkqhkiG9w0BAQQFAAIBBTAiGA8yMDAzMDcxODE2MDgwMloY"
+ + "DzIwMDMwNzI1MTYwODAyWjCCBU0wggVJBgorBgEEAbRoCAEBMYIFORaCBTU8UnVs"
+ + "ZSBSdWxlSWQ9IkZpbGUtUHJpdmlsZWdlLVJ1bGUiIEVmZmVjdD0iUGVybWl0Ij4K"
+ + "IDxUYXJnZXQ+CiAgPFN1YmplY3RzPgogICA8U3ViamVjdD4KICAgIDxTdWJqZWN0"
+ + "TWF0Y2ggTWF0Y2hJZD0idXJuOm9hc2lzOm5hbWVzOnRjOnhhY21sOjEuMDpmdW5j"
+ + "dGlvbjpzdHJpbmctZXF1YWwiPgogICAgIDxBdHRyaWJ1dGVWYWx1ZSBEYXRhVHlw"
+ + "ZT0iaHR0cDovL3d3dy53My5vcmcvMjAwMS9YTUxTY2hlbWEjc3RyaW5nIj4KICAg"
+ + "ICAgIENOPU1hcmt1cyBMb3JjaDwvQXR0cmlidXRlVmFsdWU+CiAgICAgPFN1Ympl"
+ + "Y3RBdHRyaWJ1dGVEZXNpZ25hdG9yIEF0dHJpYnV0ZUlkPSJ1cm46b2FzaXM6bmFt"
+ + "ZXM6dGM6eGFjbWw6MS4wOnN1YmplY3Q6c3ViamVjdC1pZCIgRGF0YVR5cGU9Imh0"
+ + "dHA6Ly93d3cudzMub3JnLzIwMDEvWE1MU2NoZW1hI3N0cmluZyIgLz4gCiAgICA8"
+ + "L1N1YmplY3RNYXRjaD4KICAgPC9TdWJqZWN0PgogIDwvU3ViamVjdHM+CiAgPFJl"
+ + "c291cmNlcz4KICAgPFJlc291cmNlPgogICAgPFJlc291cmNlTWF0Y2ggTWF0Y2hJ"
+ + "ZD0idXJuOm9hc2lzOm5hbWVzOnRjOnhhY21sOjEuMDpmdW5jdGlvbjpzdHJpbmct"
+ + "ZXF1YWwiPgogICAgIDxBdHRyaWJ1dGVWYWx1ZSBEYXRhVHlwZT0iaHR0cDovL3d3"
+ + "dy53My5vcmcvMjAwMS9YTUxTY2hlbWEjYW55VVJJIj4KICAgICAgaHR0cDovL3p1"
+ + "bmkuY3MudnQuZWR1PC9BdHRyaWJ1dGVWYWx1ZT4KICAgICA8UmVzb3VyY2VBdHRy"
+ + "aWJ1dGVEZXNpZ25hdG9yIEF0dHJpYnV0ZUlkPSJ1cm46b2FzaXM6bmFtZXM6dGM6"
+ + "eGFjbWw6MS4wOnJlc291cmNlOnJlc291cmNlLWlkIiBEYXRhVHlwZT0iaHR0cDov"
+ + "L3d3dy53My5vcmcvMjAwMS9YTUxTY2hlbWEjYW55VVJJIiAvPiAKICAgIDwvUmVz"
+ + "b3VyY2VNYXRjaD4KICAgPC9SZXNvdXJjZT4KICA8L1Jlc291cmNlcz4KICA8QWN0"
+ + "aW9ucz4KICAgPEFjdGlvbj4KICAgIDxBY3Rpb25NYXRjaCBNYXRjaElkPSJ1cm46"
+ + "b2FzaXM6bmFtZXM6dGM6eGFjbWw6MS4wOmZ1bmN0aW9uOnN0cmluZy1lcXVhbCI+"
+ + "CiAgICAgPEF0dHJpYnV0ZVZhbHVlIERhdGFUeXBlPSJodHRwOi8vd3d3LnczLm9y"
+ + "Zy8yMDAxL1hNTFNjaGVtYSNzdHJpbmciPgpEZWxlZ2F0ZSBBY2Nlc3MgICAgIDwv"
+ + "QXR0cmlidXRlVmFsdWU+CgkgIDxBY3Rpb25BdHRyaWJ1dGVEZXNpZ25hdG9yIEF0"
+ + "dHJpYnV0ZUlkPSJ1cm46b2FzaXM6bmFtZXM6dGM6eGFjbWw6MS4wOmFjdGlvbjph"
+ + "Y3Rpb24taWQiIERhdGFUeXBlPSJodHRwOi8vd3d3LnczLm9yZy8yMDAxL1hNTFNj"
+ + "aGVtYSNzdHJpbmciIC8+IAogICAgPC9BY3Rpb25NYXRjaD4KICAgPC9BY3Rpb24+"
+ + "CiAgPC9BY3Rpb25zPgogPC9UYXJnZXQ+CjwvUnVsZT4KMA0GCSqGSIb3DQEBBAUA"
+ + "A4GBAGiJSM48XsY90HlYxGmGVSmNR6ZW2As+bot3KAfiCIkUIOAqhcphBS23egTr"
+ + "6asYwy151HshbPNYz+Cgeqs45KkVzh7bL/0e1r8sDVIaaGIkjHK3CqBABnfSayr3"
+ + "Rd1yBoDdEv8Qb+3eEPH6ab9021AsLEnJ6LWTmybbOpMNZ3tv");
+
+ byte[] signCert = Base64.decode(
+ "MIIGjTCCBXWgAwIBAgICAPswDQYJKoZIhvcNAQEEBQAwaTEdMBsGCSqGSIb3DQEJ"
+ + "ARYOaXJtaGVscEB2dC5lZHUxLjAsBgNVBAMTJVZpcmdpbmlhIFRlY2ggQ2VydGlm"
+ + "aWNhdGlvbiBBdXRob3JpdHkxCzAJBgNVBAoTAnZ0MQswCQYDVQQGEwJVUzAeFw0w"
+ + "MzAxMzExMzUyMTRaFw0wNDAxMzExMzUyMTRaMIGDMRswGQYJKoZIhvcNAQkBFgxz"
+ + "c2hhaEB2dC5lZHUxGzAZBgNVBAMTElN1bWl0IFNoYWggKHNzaGFoKTEbMBkGA1UE"
+ + "CxMSVmlyZ2luaWEgVGVjaCBVc2VyMRAwDgYDVQQLEwdDbGFzcyAxMQswCQYDVQQK"
+ + "EwJ2dDELMAkGA1UEBhMCVVMwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAPDc"
+ + "scgSKmsEp0VegFkuitD5j5PUkDuzLjlfaYONt2SN8WeqU4j2qtlCnsipa128cyKS"
+ + "JzYe9duUdNxquh5BPIkMkHBw4jHoQA33tk0J/sydWdN74/AHPpPieK5GHwhU7GTG"
+ + "rCCS1PJRxjXqse79ExAlul+gjQwHeldAC+d4A6oZAgMBAAGjggOmMIIDojAMBgNV"
+ + "HRMBAf8EAjAAMBEGCWCGSAGG+EIBAQQEAwIFoDAOBgNVHQ8BAf8EBAMCA/gwHQYD"
+ + "VR0lBBYwFAYIKwYBBQUHAwIGCCsGAQUFBwMEMB0GA1UdDgQWBBRUIoWAzlXbzBYE"
+ + "yVTjQFWyMMKo1jCBkwYDVR0jBIGLMIGIgBTgc3Fm+TGqKDhen+oKfbl+xVbj2KFt"
+ + "pGswaTEdMBsGCSqGSIb3DQEJARYOaXJtaGVscEB2dC5lZHUxLjAsBgNVBAMTJVZp"
+ + "cmdpbmlhIFRlY2ggQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkxCzAJBgNVBAoTAnZ0"
+ + "MQswCQYDVQQGEwJVU4IBADCBiwYJYIZIAYb4QgENBH4WfFZpcmdpbmlhIFRlY2gg"
+ + "Q2VydGlmaWNhdGlvbiBBdXRob3JpdHkgZGlnaXRhbCBjZXJ0aWZpY2F0ZXMgYXJl"
+ + "IHN1YmplY3QgdG8gcG9saWNpZXMgbG9jYXRlZCBhdCBodHRwOi8vd3d3LnBraS52"
+ + "dC5lZHUvY2EvY3BzLy4wFwYDVR0RBBAwDoEMc3NoYWhAdnQuZWR1MBkGA1UdEgQS"
+ + "MBCBDmlybWhlbHBAdnQuZWR1MEMGCCsGAQUFBwEBBDcwNTAzBggrBgEFBQcwAoYn"
+ + "aHR0cDovL2JveDE3Ny5jYy52dC5lZHUvY2EvaXNzdWVycy5odG1sMEQGA1UdHwQ9"
+ + "MDswOaA3oDWGM2h0dHA6Ly9ib3gxNzcuY2MudnQuZWR1L2h0ZG9jcy1wdWJsaWMv"
+ + "Y3JsL2NhY3JsLmNybDBUBgNVHSAETTBLMA0GCysGAQQBtGgFAQEBMDoGCysGAQQB"
+ + "tGgFAQEBMCswKQYIKwYBBQUHAgEWHWh0dHA6Ly93d3cucGtpLnZ0LmVkdS9jYS9j"
+ + "cHMvMD8GCWCGSAGG+EIBBAQyFjBodHRwOi8vYm94MTc3LmNjLnZ0LmVkdS9jZ2kt"
+ + "cHVibGljL2NoZWNrX3Jldl9jYT8wPAYJYIZIAYb4QgEDBC8WLWh0dHA6Ly9ib3gx"
+ + "NzcuY2MudnQuZWR1L2NnaS1wdWJsaWMvY2hlY2tfcmV2PzBLBglghkgBhvhCAQcE"
+ + "PhY8aHR0cHM6Ly9ib3gxNzcuY2MudnQuZWR1L35PcGVuQ0E4LjAxMDYzMC9jZ2kt"
+ + "cHVibGljL3JlbmV3YWw/MCwGCWCGSAGG+EIBCAQfFh1odHRwOi8vd3d3LnBraS52"
+ + "dC5lZHUvY2EvY3BzLzANBgkqhkiG9w0BAQQFAAOCAQEAHJ2ls9yjpZVcu5DqiE67"
+ + "r7BfkdMnm7IOj2v8cd4EAlPp6OPBmjwDMwvKRBb/P733kLBqFNWXWKTpT008R0KB"
+ + "8kehbx4h0UPz9vp31zhGv169+5iReQUUQSIwTGNWGLzrT8kPdvxiSAvdAJxcbRBm"
+ + "KzDic5I8PoGe48kSCkPpT1oNmnivmcu5j1SMvlx0IS2BkFMksr0OHiAW1elSnE/N"
+ + "RuX2k73b3FucwVxB3NRo3vgoHPCTnh9r4qItAHdxFlF+pPtbw2oHESKRfMRfOIHz"
+ + "CLQWSIa6Tvg4NIV3RRJ0sbCObesyg08lymalQMdkXwtRn5eGE00SHWwEUjSXP2gR"
+ + "3g==");
+
+ static byte[] certWithBaseCertificateID = Base64.decode(
+ "MIIBqzCCARQCAQEwSKBGMD6kPDA6MQswCQYDVQQGEwJJVDEOMAwGA1UEChMFVU5JVE4xDDAKBgNV"
+ + "BAsTA0RJVDENMAsGA1UEAxMEcm9vdAIEAVMVjqB6MHikdjB0MQswCQYDVQQGEwJBVTEoMCYGA1UE"
+ + "ChMfVGhlIExlZ2lvbiBvZiB0aGUgQm91bmN5IENhc3RsZTEjMCEGA1UECxMaQm91bmN5IFByaW1h"
+ + "cnkgQ2VydGlmaWNhdGUxFjAUBgNVBAMTDUJvdW5jeSBDYXN0bGUwDQYJKoZIhvcNAQEFBQACBQKW"
+ + "RhnHMCIYDzIwMDUxMjEyMTIwMDQyWhgPMjAwNTEyMTkxMjAxMzJaMA8wDQYDVRhIMQaBBGVWSVAw"
+ + "DQYJKoZIhvcNAQEFBQADgYEAUAVin9StDaA+InxtXq/av6rUQLI9p1X6louBcj4kYJnxRvTrHpsr"
+ + "N3+i9Uq/uk5lRdAqmPFvcmSbuE3TRAsjrXON5uFiBBKZ1AouLqcr8nHbwcdwjJ9TyUNO9I4hfpSH"
+ + "UHHXMtBKgp4MOkhhX8xTGyWg3hp23d3GaUeg/IYlXBI=");
+
+ byte[] holderCertWithBaseCertificateID = Base64.decode(
+ "MIIBwDCCASmgAwIBAgIEAVMVjjANBgkqhkiG9w0BAQUFADA6MQswCQYDVQQGEwJJVDEOMAwGA1UE"
+ + "ChMFVU5JVE4xDDAKBgNVBAsTA0RJVDENMAsGA1UEAxMEcm9vdDAeFw0wNTExMTExMjAxMzJaFw0w"
+ + "NjA2MTYxMjAxMzJaMD4xCzAJBgNVBAYTAklUMQ4wDAYDVQQKEwVVTklUTjEMMAoGA1UECxMDRElU"
+ + "MREwDwYDVQQDEwhMdWNhQm9yejBaMA0GCSqGSIb3DQEBAQUAA0kAMEYCQQC0p+RhcFdPFqlwgrIr"
+ + "5YtqKmKXmEGb4ShypL26Ymz66ZAPdqv7EhOdzl3lZWT6srZUMWWgQMYGiHQg4z2R7X7XAgERoxUw"
+ + "EzARBglghkgBhvhCAQEEBAMCBDAwDQYJKoZIhvcNAQEFBQADgYEAsX50VPQQCWmHvPq9y9DeCpmS"
+ + "4szcpFAhpZyn6gYRwY9CRZVtmZKH8713XhkGDWcIEMcG0u3oTz3tdKgPU5uyIPrDEWr6w8ClUj4x"
+ + "5aVz5c2223+dVY7KES//JSB2bE/KCIchN3kAioQ4K8O3e0OL6oDVjsqKGw5bfahgKuSIk/Q=");
+
+
+ public String getName()
+ {
+ return "AttrCertTest";
+ }
+
+ private void testCertWithBaseCertificateID()
+ throws Exception
+ {
+ X509AttributeCertificateHolder attrCert = new X509AttributeCertificateHolder(certWithBaseCertificateID);
+ CertificateFactory fact = CertificateFactory.getInstance("X.509", "SC");
+ X509Certificate cert = (X509Certificate)fact.generateCertificate(new ByteArrayInputStream(holderCertWithBaseCertificateID));
+
+ AttributeCertificateHolder holder = attrCert.getHolder();
+
+ if (holder.getEntityNames() != null)
+ {
+ fail("entity names set when none expected");
+ }
+
+ if (!holder.getSerialNumber().equals(cert.getSerialNumber()))
+ {
+ fail("holder serial number doesn't match");
+ }
+
+ if (!holder.getIssuer()[0].equals(X500Name.getInstance(cert.getIssuerX500Principal().getEncoded())))
+ {
+ fail("holder issuer doesn't match");
+ }
+
+ if (!holder.match(new JcaX509CertificateHolder(cert)))
+ {
+ fail("holder not matching holder certificate");
+ }
+
+ if (!holder.equals(holder.clone()))
+ {
+ fail("holder clone test failed");
+ }
+
+ if (!attrCert.getIssuer().equals(attrCert.getIssuer().clone()))
+ {
+ fail("issuer clone test failed");
+ }
+
+ //equalityAndHashCodeTest(attrCert, certWithBaseCertificateID);
+ }
+
+ private void equalityAndHashCodeTest(X509AttributeCertificateHolder attrCert, byte[] encoding)
+ throws IOException
+ {
+ if (!attrCert.equals(attrCert))
+ {
+ fail("same certificate not equal");
+ }
+
+ if (!attrCert.getHolder().equals(attrCert.getHolder()))
+ {
+ fail("same holder not equal");
+ }
+
+ if (!attrCert.getIssuer().equals(attrCert.getIssuer()))
+ {
+ fail("same issuer not equal");
+ }
+
+ if (attrCert.getHolder().equals(attrCert.getIssuer()))
+ {
+ fail("wrong holder equal");
+ }
+
+ if (attrCert.getIssuer().equals(attrCert.getHolder()))
+ {
+ fail("wrong issuer equal");
+ }
+
+ X509AttributeCertificateHolder attrCert2 = new X509AttributeCertificateHolder(encoding);
+
+ if (attrCert2.getHolder().hashCode() != attrCert.getHolder().hashCode())
+ {
+ fail("holder hashCode test failed");
+ }
+
+ if (!attrCert2.getHolder().equals(attrCert.getHolder()))
+ {
+ fail("holder equals test failed");
+ }
+
+ if (attrCert2.getIssuer().hashCode() != attrCert.getIssuer().hashCode())
+ {
+ fail("issuer hashCode test failed");
+ }
+
+ if (!attrCert2.getIssuer().equals(attrCert.getIssuer()))
+ {
+ fail("issuer equals test failed");
+ }
+ }
+
+ private void testGenerateWithCert()
+ throws Exception
+ {
+ CertificateFactory fact = CertificateFactory.getInstance("X.509","SC");
+ X509Certificate iCert = (X509Certificate)fact.generateCertificate(new ByteArrayInputStream(signCert));
+
+ //
+ // a sample key pair.
+ //
+ RSAPublicKeySpec pubKeySpec = new RSAPublicKeySpec(
+ new BigInteger("b4a7e46170574f16a97082b22be58b6a2a629798419be12872a4bdba626cfae9900f76abfb12139dce5de56564fab2b6543165a040c606887420e33d91ed7ed7", 16),
+ new BigInteger("11", 16));
+
+ //
+ // set up the keys
+ //
+ PrivateKey privKey;
+ PublicKey pubKey;
+
+ KeyFactory kFact = KeyFactory.getInstance("RSA", "SC");
+
+ privKey = kFact.generatePrivate(RSA_PRIVATE_KEY_SPEC);
+ pubKey = kFact.generatePublic(pubKeySpec);
+
+ X509v2AttributeCertificateBuilder gen = new X509v2AttributeCertificateBuilder(
+ new AttributeCertificateHolder(new JcaX509CertificateHolder(iCert)),
+ new AttributeCertificateIssuer(new X500Name("cn=test")),
+ BigInteger.ONE,
+ new Date(System.currentTimeMillis() - 50000),
+ new Date(System.currentTimeMillis() + 50000));
+
+ // the actual attributes
+ GeneralName roleName = new GeneralName(GeneralName.rfc822Name, "DAU123456789");
+ ASN1EncodableVector roleSyntax = new ASN1EncodableVector();
+ roleSyntax.add(roleName);
+
+ // roleSyntax OID: 2.5.24.72;
+
+ gen.addAttribute(new ASN1ObjectIdentifier("2.5.24.72"), new DERSequence(roleSyntax));
+
+ ContentSigner sigGen = new JcaContentSignerBuilder("SHA1WithRSAEncryption").setProvider(BC).build(privKey);
+
+ X509AttributeCertificateHolder aCert = gen.build(sigGen);
+
+ if (!aCert.isValidOn(new Date()))
+ {
+ fail("certificate invalid");
+ }
+
+ if (!aCert.isSignatureValid(new JcaContentVerifierProviderBuilder().setProvider(BC).build(pubKey)))
+ {
+ fail("certificate signature not valid");
+ }
+
+ AttributeCertificateHolder holder = aCert.getHolder();
+
+ if (holder.getEntityNames() != null)
+ {
+ fail("entity names set when none expected");
+ }
+
+ if (!holder.getSerialNumber().equals(iCert.getSerialNumber()))
+ {
+ fail("holder serial number doesn't match");
+ }
+
+ if (!holder.getIssuer()[0].equals(X500Name.getInstance(iCert.getIssuerX500Principal().getEncoded())))
+ {
+ fail("holder issuer doesn't match");
+ }
+
+ if (!holder.match(new JcaX509CertificateHolder(iCert)))
+ {
+ fail("generated holder not matching holder certificate");
+ }
+
+ Attribute[] attrs = aCert.getAttributes(new ASN1ObjectIdentifier("2.5.24.72"));
+
+ if (attrs == null)
+ {
+ fail("attributes related to 2.5.24.72 not found");
+ }
+
+ Attribute attr = attrs[0];
+
+ if (!attr.getAttrType().getId().equals("2.5.24.72"))
+ {
+ fail("attribute oid mismatch");
+ }
+
+ ASN1Encodable[] values = attr.getAttrValues().toArray();
+
+ GeneralName role = GeneralNames.getInstance(values[0]).getNames()[0];
+
+ if (role.getTagNo() != GeneralName.rfc822Name)
+ {
+ fail("wrong general name type found in role");
+ }
+
+ if (!((ASN1String)role.getName()).getString().equals("DAU123456789"))
+ {
+ fail("wrong general name value found in role");
+ }
+
+ X509Certificate sCert = (X509Certificate)fact.generateCertificate(new ByteArrayInputStream(holderCertWithBaseCertificateID));
+
+ if (holder.match(new JcaX509CertificateHolder(sCert)))
+ {
+ fail("generated holder matching wrong certificate");
+ }
+
+ equalityAndHashCodeTest(aCert, aCert.getEncoded());
+ }
+
+ private void testGenerateWithPrincipal()
+ throws Exception
+ {
+ CertificateFactory fact = CertificateFactory.getInstance("X.509","SC");
+ X509Certificate iCert = (X509Certificate)fact.generateCertificate(new ByteArrayInputStream(signCert));
+
+ //
+ // a sample key pair.
+ //
+ RSAPublicKeySpec pubKeySpec = new RSAPublicKeySpec(
+ new BigInteger("b4a7e46170574f16a97082b22be58b6a2a629798419be12872a4bdba626cfae9900f76abfb12139dce5de56564fab2b6543165a040c606887420e33d91ed7ed7", 16),
+ new BigInteger("11", 16));
+
+ //
+ // set up the keys
+ //
+ PrivateKey privKey;
+ PublicKey pubKey;
+
+ KeyFactory kFact = KeyFactory.getInstance("RSA", "SC");
+
+ privKey = kFact.generatePrivate(RSA_PRIVATE_KEY_SPEC);
+ pubKey = kFact.generatePublic(pubKeySpec);
+
+ X509v2AttributeCertificateBuilder gen = new X509v2AttributeCertificateBuilder(
+ new AttributeCertificateHolder(new JcaX509CertificateHolder(iCert).getSubject()),
+ new AttributeCertificateIssuer(new X500Name("cn=test")),
+ BigInteger.ONE,
+ new Date(System.currentTimeMillis() - 50000),
+ new Date(System.currentTimeMillis() + 50000));
+
+ // the actual attributes
+ GeneralName roleName = new GeneralName(GeneralName.rfc822Name, "DAU123456789");
+ ASN1EncodableVector roleSyntax = new ASN1EncodableVector();
+ roleSyntax.add(roleName);
+
+ // roleSyntax OID: 2.5.24.72
+
+ gen.addAttribute(new ASN1ObjectIdentifier("2.5.24.72"), new DERSequence(roleSyntax));
+
+ ContentSigner sigGen = new JcaContentSignerBuilder("SHA1WithRSAEncryption").setProvider(BC).build(privKey);
+
+ X509AttributeCertificateHolder aCert = gen.build(sigGen);
+
+ if (!aCert.isValidOn(new Date()))
+ {
+ fail("certificate invalid");
+ }
+
+ if (!aCert.isSignatureValid(new JcaContentVerifierProviderBuilder().setProvider(BC).build(pubKey)))
+ {
+ fail("certificate signature not valid");
+ }
+
+ AttributeCertificateHolder holder = aCert.getHolder();
+
+ if (holder.getEntityNames() == null)
+ {
+ fail("entity names not set when expected");
+ }
+
+ if (holder.getSerialNumber() != null)
+ {
+ fail("holder serial number found when none expected");
+ }
+
+ if (holder.getIssuer() != null)
+ {
+ fail("holder issuer found when none expected");
+ }
+
+ if (!holder.match(new JcaX509CertificateHolder(iCert)))
+ {
+ fail("generated holder not matching holder certificate");
+ }
+
+ X509Certificate sCert = (X509Certificate)fact.generateCertificate(new ByteArrayInputStream(holderCertWithBaseCertificateID));
+
+ if (holder.match(sCert))
+ {
+ fail("principal generated holder matching wrong certificate");
+ }
+
+ equalityAndHashCodeTest(aCert, aCert.getEncoded());
+ }
+
+ public void performTest()
+ throws Exception
+ {
+ X509AttributeCertificateHolder aCert = new X509AttributeCertificateHolder(attrCert);
+ CertificateFactory fact = CertificateFactory.getInstance("X.509","SC");
+ X509Certificate sCert = (X509Certificate)fact.generateCertificate(new ByteArrayInputStream(signCert));
+
+ if (!aCert.isSignatureValid(new JcaContentVerifierProviderBuilder().setProvider(BC).build(sCert)))
+ {
+ fail("certificate signature not valid");
+ }
+
+ //
+ // search test
+ //
+
+ List list = new ArrayList();
+
+ list.add(sCert);
+
+ Store store = new JcaCertStore(list);
+
+ Collection certs = store.getMatches(aCert.getIssuer());
+ if (certs.size() != 1 || !certs.contains(new JcaX509CertificateHolder(sCert)))
+ {
+ fail("sCert not found by issuer");
+ }
+
+ Attribute[] attrs = aCert.getAttributes(new ASN1ObjectIdentifier("1.3.6.1.4.1.6760.8.1.1"));
+ if (attrs == null || attrs.length != 1)
+ {
+ fail("attribute not found");
+ }
+
+ //
+ // reencode test
+ //
+ aCert = new X509AttributeCertificateHolder(aCert.getEncoded());
+
+ if (!aCert.isSignatureValid(new JcaContentVerifierProviderBuilder().setProvider(BC).build(sCert)))
+ {
+ fail("certificate signature not valid");
+ }
+
+ X509AttributeCertificateHolder saCert = new X509AttributeCertificateHolder(aCert.getEncoded());
+
+ if (!aCert.getNotAfter().equals(saCert.getNotAfter()))
+ {
+ fail("failed date comparison");
+ }
+
+ // base generator test
+
+ //
+ // a sample key pair.
+ //
+ RSAPublicKeySpec pubKeySpec = new RSAPublicKeySpec(
+ new BigInteger("b4a7e46170574f16a97082b22be58b6a2a629798419be12872a4bdba626cfae9900f76abfb12139dce5de56564fab2b6543165a040c606887420e33d91ed7ed7", 16),
+ new BigInteger("11", 16));
+
+ RSAPrivateCrtKeySpec privKeySpec = RSA_PRIVATE_KEY_SPEC;
+
+ //
+ // set up the keys
+ //
+ PrivateKey privKey;
+ PublicKey pubKey;
+
+ KeyFactory kFact = KeyFactory.getInstance("RSA", "SC");
+
+ privKey = kFact.generatePrivate(privKeySpec);
+ pubKey = kFact.generatePublic(pubKeySpec);
+
+ X509v2AttributeCertificateBuilder gen = new X509v2AttributeCertificateBuilder(
+ aCert.getHolder(),
+ aCert.getIssuer(),
+ aCert.getSerialNumber(),
+ new Date(System.currentTimeMillis() - 50000),
+ new Date(System.currentTimeMillis() + 50000));
+
+ gen.addAttribute(attrs[0].getAttrType(), attrs[0].getAttributeValues());
+
+ ContentSigner sigGen = new JcaContentSignerBuilder("SHA1WithRSAEncryption").setProvider(BC).build(privKey);
+
+ aCert = gen.build(sigGen);
+
+ if (!aCert.isValidOn(new Date()))
+ {
+ fail("certificate not valid");
+ }
+
+ if (!aCert.isSignatureValid(new JcaContentVerifierProviderBuilder().setProvider(BC).build(pubKey)))
+ {
+ fail("signature not valid");
+ }
+
+ // as the issuer is the same this should still work (even though it is not
+ // technically correct
+
+ certs = store.getMatches(aCert.getIssuer());
+ if (certs.size() != 1 || !certs.contains(new JcaX509CertificateHolder(sCert)))
+ {
+ fail("sCert not found by issuer");
+ }
+
+ attrs = aCert.getAttributes(new ASN1ObjectIdentifier("1.3.6.1.4.1.6760.8.1.1"));
+ if (attrs == null || attrs.length != 1)
+ {
+ fail("attribute not found");
+ }
+
+ //
+ // reencode test
+ //
+ aCert = new X509AttributeCertificateHolder(aCert.getEncoded());
+
+ if (!aCert.isSignatureValid(new JcaContentVerifierProviderBuilder().setProvider(BC).build(pubKey)))
+ {
+ fail("signature not valid");
+ }
+
+ AttributeCertificateIssuer issuer = aCert.getIssuer();
+
+ X500Name[] principals = issuer.getNames();
+
+ //
+ // test holder
+ //
+ AttributeCertificateHolder holder = aCert.getHolder();
+
+ if (holder.getEntityNames() == null)
+ {
+ fail("entity names not set");
+ }
+
+ if (holder.getSerialNumber() != null)
+ {
+ fail("holder serial number set when none expected");
+ }
+
+ if (holder.getIssuer() != null)
+ {
+ fail("holder issuer set when none expected");
+ }
+
+ principals = holder.getEntityNames();
+
+ X500Principal principal0 = new X500Principal(principals[0].getEncoded());
+ if (!principal0.toString().equals("C=US, O=vt, OU=Class 2, OU=Virginia Tech User, CN=Markus Lorch (mlorch), EMAILADDRESS=mlorch@vt.edu"))
+ {
+ fail("principal[0] for entity names don't match");
+ }
+
+ //
+ // extension test
+ //
+
+ if (aCert.hasExtensions())
+ {
+ fail("hasExtensions true with no extensions");
+ }
+
+ gen.addExtension(new ASN1ObjectIdentifier("1.1"), true, new DEROctetString(new byte[10]));
+
+ gen.addExtension(new ASN1ObjectIdentifier("2.2"), false, new DEROctetString(new byte[20]));
+
+ aCert = gen.build(new JcaContentSignerBuilder("SHA1withRSA").setProvider(BC).build(privKey));
+
+ Set exts = aCert.getCriticalExtensionOIDs();
+
+ if (exts.size() != 1 || !exts.contains(new ASN1ObjectIdentifier("1.1")))
+ { System.err.println(exts);
+ fail("critical extension test failed");
+ }
+
+ exts = aCert.getNonCriticalExtensionOIDs();
+
+ if (exts.size() != 1 || !exts.contains(new ASN1ObjectIdentifier("2.2")))
+ {
+ fail("non-critical extension test failed");
+ }
+
+ if (aCert.getCriticalExtensionOIDs().isEmpty())
+ {
+ fail("critical extensions not found");
+ }
+
+ Extension ext = aCert.getExtension(new ASN1ObjectIdentifier("1.1"));
+ ASN1Encodable extValue = ext.getParsedValue();
+
+ if (!extValue.equals(new DEROctetString(new byte[10])))
+ {
+ fail("wrong extension value found for 1.1");
+ }
+
+ testCertWithBaseCertificateID();
+ testGenerateWithCert();
+ testGenerateWithPrincipal();
+ }
+
+ public static void main(
+ String[] args)
+ {
+ Security.addProvider(new BouncyCastleProvider());
+
+ runTest(new AttrCertTest());
+ }
+}
diff --git a/pkix/src/test/java/org/spongycastle/cert/test/BcAttrCertSelectorTest.java b/pkix/src/test/java/org/spongycastle/cert/test/BcAttrCertSelectorTest.java
new file mode 100644
index 00000000..bf5557fd
--- /dev/null
+++ b/pkix/src/test/java/org/spongycastle/cert/test/BcAttrCertSelectorTest.java
@@ -0,0 +1,212 @@
+package org.spongycastle.cert.test;
+
+import java.math.BigInteger;
+import java.util.Date;
+
+import junit.framework.TestCase;
+import org.spongycastle.asn1.ASN1EncodableVector;
+import org.spongycastle.asn1.ASN1ObjectIdentifier;
+import org.spongycastle.asn1.DERSequence;
+import org.spongycastle.asn1.x500.X500Name;
+import org.spongycastle.asn1.x509.AlgorithmIdentifier;
+import org.spongycastle.asn1.x509.Extension;
+import org.spongycastle.asn1.x509.GeneralName;
+import org.spongycastle.asn1.x509.Target;
+import org.spongycastle.asn1.x509.TargetInformation;
+import org.spongycastle.cert.AttributeCertificateHolder;
+import org.spongycastle.cert.AttributeCertificateIssuer;
+import org.spongycastle.cert.X509AttributeCertificateHolder;
+import org.spongycastle.cert.X509CertificateHolder;
+import org.spongycastle.cert.X509v2AttributeCertificateBuilder;
+import org.spongycastle.cert.selector.X509AttributeCertificateHolderSelectorBuilder;
+import org.spongycastle.crypto.params.RSAPrivateCrtKeyParameters;
+import org.spongycastle.operator.ContentSigner;
+import org.spongycastle.operator.DefaultDigestAlgorithmIdentifierFinder;
+import org.spongycastle.operator.DefaultSignatureAlgorithmIdentifierFinder;
+import org.spongycastle.operator.bc.BcRSAContentSignerBuilder;
+import org.spongycastle.util.encoders.Base64;
+
+public class BcAttrCertSelectorTest
+ extends TestCase
+{
+ DefaultSignatureAlgorithmIdentifierFinder sigAlgFinder = new DefaultSignatureAlgorithmIdentifierFinder();
+ DefaultDigestAlgorithmIdentifierFinder digAlgFinder = new DefaultDigestAlgorithmIdentifierFinder();
+
+ static final RSAPrivateCrtKeyParameters RSA_PRIVATE_KEY_SPEC = new RSAPrivateCrtKeyParameters(
+ new BigInteger(
+ "b4a7e46170574f16a97082b22be58b6a2a629798419be12872a4bdba626cfae9900f76abfb12139dce5de56564fab2b6543165a040c606887420e33d91ed7ed7",
+ 16),
+ new BigInteger("11", 16),
+ new BigInteger(
+ "9f66f6b05410cd503b2709e88115d55daced94d1a34d4e32bf824d0dde6028ae79c5f07b580f5dce240d7111f7ddb130a7945cd7d957d1920994da389f490c89",
+ 16), new BigInteger(
+ "c0a0758cdf14256f78d4708c86becdead1b50ad4ad6c5c703e2168fbf37884cb",
+ 16), new BigInteger(
+ "f01734d7960ea60070f1b06f2bb81bfac48ff192ae18451d5e56c734a5aab8a5",
+ 16), new BigInteger(
+ "b54bb9edff22051d9ee60f9351a48591b6500a319429c069a3e335a1d6171391",
+ 16), new BigInteger(
+ "d3d83daf2a0cecd3367ae6f8ae1aeb82e9ac2f816c6fc483533d8297dd7884cd",
+ 16), new BigInteger(
+ "b8f52fc6f38593dabb661d3f50f8897f8106eee68b1bce78a95b132b4e5b5d19",
+ 16));
+
+ static final byte[] holderCert = Base64
+ .decode("MIIGjTCCBXWgAwIBAgICAPswDQYJKoZIhvcNAQEEBQAwaTEdMBsGCSqGSIb3DQEJ"
+ + "ARYOaXJtaGVscEB2dC5lZHUxLjAsBgNVBAMTJVZpcmdpbmlhIFRlY2ggQ2VydGlm"
+ + "aWNhdGlvbiBBdXRob3JpdHkxCzAJBgNVBAoTAnZ0MQswCQYDVQQGEwJVUzAeFw0w"
+ + "MzAxMzExMzUyMTRaFw0wNDAxMzExMzUyMTRaMIGDMRswGQYJKoZIhvcNAQkBFgxz"
+ + "c2hhaEB2dC5lZHUxGzAZBgNVBAMTElN1bWl0IFNoYWggKHNzaGFoKTEbMBkGA1UE"
+ + "CxMSVmlyZ2luaWEgVGVjaCBVc2VyMRAwDgYDVQQLEwdDbGFzcyAxMQswCQYDVQQK"
+ + "EwJ2dDELMAkGA1UEBhMCVVMwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAPDc"
+ + "scgSKmsEp0VegFkuitD5j5PUkDuzLjlfaYONt2SN8WeqU4j2qtlCnsipa128cyKS"
+ + "JzYe9duUdNxquh5BPIkMkHBw4jHoQA33tk0J/sydWdN74/AHPpPieK5GHwhU7GTG"
+ + "rCCS1PJRxjXqse79ExAlul+gjQwHeldAC+d4A6oZAgMBAAGjggOmMIIDojAMBgNV"
+ + "HRMBAf8EAjAAMBEGCWCGSAGG+EIBAQQEAwIFoDAOBgNVHQ8BAf8EBAMCA/gwHQYD"
+ + "VR0lBBYwFAYIKwYBBQUHAwIGCCsGAQUFBwMEMB0GA1UdDgQWBBRUIoWAzlXbzBYE"
+ + "yVTjQFWyMMKo1jCBkwYDVR0jBIGLMIGIgBTgc3Fm+TGqKDhen+oKfbl+xVbj2KFt"
+ + "pGswaTEdMBsGCSqGSIb3DQEJARYOaXJtaGVscEB2dC5lZHUxLjAsBgNVBAMTJVZp"
+ + "cmdpbmlhIFRlY2ggQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkxCzAJBgNVBAoTAnZ0"
+ + "MQswCQYDVQQGEwJVU4IBADCBiwYJYIZIAYb4QgENBH4WfFZpcmdpbmlhIFRlY2gg"
+ + "Q2VydGlmaWNhdGlvbiBBdXRob3JpdHkgZGlnaXRhbCBjZXJ0aWZpY2F0ZXMgYXJl"
+ + "IHN1YmplY3QgdG8gcG9saWNpZXMgbG9jYXRlZCBhdCBodHRwOi8vd3d3LnBraS52"
+ + "dC5lZHUvY2EvY3BzLy4wFwYDVR0RBBAwDoEMc3NoYWhAdnQuZWR1MBkGA1UdEgQS"
+ + "MBCBDmlybWhlbHBAdnQuZWR1MEMGCCsGAQUFBwEBBDcwNTAzBggrBgEFBQcwAoYn"
+ + "aHR0cDovL2JveDE3Ny5jYy52dC5lZHUvY2EvaXNzdWVycy5odG1sMEQGA1UdHwQ9"
+ + "MDswOaA3oDWGM2h0dHA6Ly9ib3gxNzcuY2MudnQuZWR1L2h0ZG9jcy1wdWJsaWMv"
+ + "Y3JsL2NhY3JsLmNybDBUBgNVHSAETTBLMA0GCysGAQQBtGgFAQEBMDoGCysGAQQB"
+ + "tGgFAQEBMCswKQYIKwYBBQUHAgEWHWh0dHA6Ly93d3cucGtpLnZ0LmVkdS9jYS9j"
+ + "cHMvMD8GCWCGSAGG+EIBBAQyFjBodHRwOi8vYm94MTc3LmNjLnZ0LmVkdS9jZ2kt"
+ + "cHVibGljL2NoZWNrX3Jldl9jYT8wPAYJYIZIAYb4QgEDBC8WLWh0dHA6Ly9ib3gx"
+ + "NzcuY2MudnQuZWR1L2NnaS1wdWJsaWMvY2hlY2tfcmV2PzBLBglghkgBhvhCAQcE"
+ + "PhY8aHR0cHM6Ly9ib3gxNzcuY2MudnQuZWR1L35PcGVuQ0E4LjAxMDYzMC9jZ2kt"
+ + "cHVibGljL3JlbmV3YWw/MCwGCWCGSAGG+EIBCAQfFh1odHRwOi8vd3d3LnBraS52"
+ + "dC5lZHUvY2EvY3BzLzANBgkqhkiG9w0BAQQFAAOCAQEAHJ2ls9yjpZVcu5DqiE67"
+ + "r7BfkdMnm7IOj2v8cd4EAlPp6OPBmjwDMwvKRBb/P733kLBqFNWXWKTpT008R0KB"
+ + "8kehbx4h0UPz9vp31zhGv169+5iReQUUQSIwTGNWGLzrT8kPdvxiSAvdAJxcbRBm"
+ + "KzDic5I8PoGe48kSCkPpT1oNmnivmcu5j1SMvlx0IS2BkFMksr0OHiAW1elSnE/N"
+ + "RuX2k73b3FucwVxB3NRo3vgoHPCTnh9r4qItAHdxFlF+pPtbw2oHESKRfMRfOIHz"
+ + "CLQWSIa6Tvg4NIV3RRJ0sbCObesyg08lymalQMdkXwtRn5eGE00SHWwEUjSXP2gR"
+ + "3g==");
+
+ public String getName()
+ {
+ return "AttrCertSelector";
+ }
+
+ private X509AttributeCertificateHolder createAttrCert() throws Exception
+ {
+ X509CertificateHolder iCertHolder = new X509CertificateHolder(holderCert);
+ //
+ // a sample key pair.
+ //
+ // RSAPublicKeySpec pubKeySpec = new RSAPublicKeySpec(
+ // new BigInteger(
+ // "b4a7e46170574f16a97082b22be58b6a2a629798419be12872a4bdba626cfae9900f76abfb12139dce5de56564fab2b6543165a040c606887420e33d91ed7ed7",
+ // 16), new BigInteger("11", 16));
+
+ X509v2AttributeCertificateBuilder gen = new X509v2AttributeCertificateBuilder(
+ new AttributeCertificateHolder(iCertHolder.getSubject()),
+ new AttributeCertificateIssuer(new X500Name("cn=test")),
+ BigInteger.ONE,
+ new Date(System.currentTimeMillis() - 50000),
+ new Date(System.currentTimeMillis() + 50000));
+
+ // the actual attributes
+ GeneralName roleName = new GeneralName(GeneralName.rfc822Name,
+ "DAU123456789@test.com");
+ ASN1EncodableVector roleSyntax = new ASN1EncodableVector();
+ roleSyntax.add(roleName);
+
+ // roleSyntax OID: 2.5.24.72
+ gen.addAttribute(new ASN1ObjectIdentifier("2.5.24.72"), new DERSequence(roleSyntax));
+
+
+ AlgorithmIdentifier sigAlg = sigAlgFinder.find("SHA1withRSA");
+ AlgorithmIdentifier digAlg = digAlgFinder.find(sigAlg);
+
+ ContentSigner sigGen = new BcRSAContentSignerBuilder(sigAlg, digAlg).build(RSA_PRIVATE_KEY_SPEC);
+ Target targetName = new Target(Target.targetName, new GeneralName(GeneralName.dNSName,
+ "www.test.com"));
+
+ Target targetGroup = new Target(Target.targetGroup, new GeneralName(
+ GeneralName.directoryName, "o=Test, ou=Test"));
+ Target[] targets = new Target[2];
+ targets[0] = targetName;
+ targets[1] = targetGroup;
+ TargetInformation targetInformation = new TargetInformation(targets);
+
+ gen.addExtension(Extension.targetInformation, true, targetInformation);
+
+ return gen.build(sigGen);
+ }
+
+ public void testSelector() throws Exception
+ {
+ X509AttributeCertificateHolder aCert = createAttrCert();
+ X509AttributeCertificateHolderSelectorBuilder sel = new X509AttributeCertificateHolderSelectorBuilder();
+ sel.setAttributeCert(aCert);
+ boolean match = sel.build().match(aCert);
+ if (!match)
+ {
+ fail("Selector does not match attribute certificate.");
+ }
+ sel.setAttributeCert(null);
+ match = sel.build().match(aCert);
+ if (!match)
+ {
+ fail("Selector does not match attribute certificate.");
+ }
+ sel.setHolder(aCert.getHolder());
+ match = sel.build().match(aCert);
+ if (!match)
+ {
+ fail("Selector does not match attribute certificate holder.");
+ }
+ sel.setHolder(null);
+ sel.setIssuer(aCert.getIssuer());
+ match = sel.build().match(aCert);
+ if (!match)
+ {
+ fail("Selector does not match attribute certificate issuer.");
+ }
+ sel.setIssuer(null);
+
+ X509CertificateHolder iCert = new X509CertificateHolder(holderCert);
+ match = aCert.getHolder().match(iCert);
+ if (!match)
+ {
+ fail("Issuer holder does not match signing certificate of attribute certificate.");
+ }
+
+ sel.setSerialNumber(aCert.getSerialNumber());
+ match = sel.build().match(aCert);
+ if (!match)
+ {
+ fail("Selector does not match attribute certificate serial number.");
+ }
+
+ sel.setAttributeCertificateValid(new Date());
+ match = sel.build().match(aCert);
+ if (!match)
+ {
+ fail("Selector does not match attribute certificate time.");
+ }
+
+ sel.addTargetName(new GeneralName(2, "www.test.com"));
+ match = sel.build().match(aCert);
+ if (!match)
+ {
+ fail("Selector does not match attribute certificate target name.");
+ }
+ sel.setTargetNames(null);
+ sel.addTargetGroup(new GeneralName(4, "o=Test, ou=Test"));
+ match = sel.build().match(aCert);
+ if (!match)
+ {
+ fail("Selector does not match attribute certificate target group.");
+ }
+ sel.setTargetGroups(null);
+ }
+}
+
diff --git a/pkix/src/test/java/org/spongycastle/cert/test/BcAttrCertTest.java b/pkix/src/test/java/org/spongycastle/cert/test/BcAttrCertTest.java
new file mode 100644
index 00000000..6603e4d5
--- /dev/null
+++ b/pkix/src/test/java/org/spongycastle/cert/test/BcAttrCertTest.java
@@ -0,0 +1,636 @@
+package org.spongycastle.cert.test;
+
+
+import java.io.IOException;
+import java.math.BigInteger;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Date;
+import java.util.List;
+import java.util.Set;
+
+import junit.framework.TestCase;
+import org.spongycastle.asn1.ASN1Encodable;
+import org.spongycastle.asn1.ASN1EncodableVector;
+import org.spongycastle.asn1.ASN1ObjectIdentifier;
+import org.spongycastle.asn1.ASN1String;
+import org.spongycastle.asn1.DEROctetString;
+import org.spongycastle.asn1.DERSequence;
+import org.spongycastle.asn1.x500.X500Name;
+import org.spongycastle.asn1.x500.style.RFC4519Style;
+import org.spongycastle.asn1.x509.AlgorithmIdentifier;
+import org.spongycastle.asn1.x509.Attribute;
+import org.spongycastle.asn1.x509.Extension;
+import org.spongycastle.asn1.x509.GeneralName;
+import org.spongycastle.asn1.x509.GeneralNames;
+import org.spongycastle.cert.AttributeCertificateHolder;
+import org.spongycastle.cert.AttributeCertificateIssuer;
+import org.spongycastle.cert.X509AttributeCertificateHolder;
+import org.spongycastle.cert.X509CertificateHolder;
+import org.spongycastle.cert.X509v2AttributeCertificateBuilder;
+import org.spongycastle.crypto.params.AsymmetricKeyParameter;
+import org.spongycastle.crypto.params.RSAKeyParameters;
+import org.spongycastle.crypto.params.RSAPrivateCrtKeyParameters;
+import org.spongycastle.operator.ContentSigner;
+import org.spongycastle.operator.DefaultDigestAlgorithmIdentifierFinder;
+import org.spongycastle.operator.DefaultSignatureAlgorithmIdentifierFinder;
+import org.spongycastle.operator.bc.BcRSAContentSignerBuilder;
+import org.spongycastle.operator.bc.BcRSAContentVerifierProviderBuilder;
+import org.spongycastle.util.CollectionStore;
+import org.spongycastle.util.Store;
+import org.spongycastle.util.encoders.Base64;
+
+public class BcAttrCertTest
+ extends TestCase
+{
+ DefaultSignatureAlgorithmIdentifierFinder sigAlgFinder = new DefaultSignatureAlgorithmIdentifierFinder();
+ DefaultDigestAlgorithmIdentifierFinder digAlgFinder = new DefaultDigestAlgorithmIdentifierFinder();
+
+ private static final AsymmetricKeyParameter RSA_PRIVATE_KEY_SPEC = new RSAPrivateCrtKeyParameters(
+ new BigInteger("b4a7e46170574f16a97082b22be58b6a2a629798419be12872a4bdba626cfae9900f76abfb12139dce5de56564fab2b6543165a040c606887420e33d91ed7ed7", 16),
+ new BigInteger("11", 16),
+ new BigInteger("9f66f6b05410cd503b2709e88115d55daced94d1a34d4e32bf824d0dde6028ae79c5f07b580f5dce240d7111f7ddb130a7945cd7d957d1920994da389f490c89", 16),
+ new BigInteger("c0a0758cdf14256f78d4708c86becdead1b50ad4ad6c5c703e2168fbf37884cb", 16),
+ new BigInteger("f01734d7960ea60070f1b06f2bb81bfac48ff192ae18451d5e56c734a5aab8a5", 16),
+ new BigInteger("b54bb9edff22051d9ee60f9351a48591b6500a319429c069a3e335a1d6171391", 16),
+ new BigInteger("d3d83daf2a0cecd3367ae6f8ae1aeb82e9ac2f816c6fc483533d8297dd7884cd", 16),
+ new BigInteger("b8f52fc6f38593dabb661d3f50f8897f8106eee68b1bce78a95b132b4e5b5d19", 16));
+
+ public static byte[] attrCert = Base64.decode(
+ "MIIHQDCCBqkCAQEwgZChgY2kgYowgYcxHDAaBgkqhkiG9w0BCQEWDW1sb3JjaEB2"
+ + "dC5lZHUxHjAcBgNVBAMTFU1hcmt1cyBMb3JjaCAobWxvcmNoKTEbMBkGA1UECxMS"
+ + "VmlyZ2luaWEgVGVjaCBVc2VyMRAwDgYDVQQLEwdDbGFzcyAyMQswCQYDVQQKEwJ2"
+ + "dDELMAkGA1UEBhMCVVMwgYmkgYYwgYMxGzAZBgkqhkiG9w0BCQEWDHNzaGFoQHZ0"
+ + "LmVkdTEbMBkGA1UEAxMSU3VtaXQgU2hhaCAoc3NoYWgpMRswGQYDVQQLExJWaXJn"
+ + "aW5pYSBUZWNoIFVzZXIxEDAOBgNVBAsTB0NsYXNzIDExCzAJBgNVBAoTAnZ0MQsw"
+ + "CQYDVQQGEwJVUzANBgkqhkiG9w0BAQQFAAIBBTAiGA8yMDAzMDcxODE2MDgwMloY"
+ + "DzIwMDMwNzI1MTYwODAyWjCCBU0wggVJBgorBgEEAbRoCAEBMYIFORaCBTU8UnVs"
+ + "ZSBSdWxlSWQ9IkZpbGUtUHJpdmlsZWdlLVJ1bGUiIEVmZmVjdD0iUGVybWl0Ij4K"
+ + "IDxUYXJnZXQ+CiAgPFN1YmplY3RzPgogICA8U3ViamVjdD4KICAgIDxTdWJqZWN0"
+ + "TWF0Y2ggTWF0Y2hJZD0idXJuOm9hc2lzOm5hbWVzOnRjOnhhY21sOjEuMDpmdW5j"
+ + "dGlvbjpzdHJpbmctZXF1YWwiPgogICAgIDxBdHRyaWJ1dGVWYWx1ZSBEYXRhVHlw"
+ + "ZT0iaHR0cDovL3d3dy53My5vcmcvMjAwMS9YTUxTY2hlbWEjc3RyaW5nIj4KICAg"
+ + "ICAgIENOPU1hcmt1cyBMb3JjaDwvQXR0cmlidXRlVmFsdWU+CiAgICAgPFN1Ympl"
+ + "Y3RBdHRyaWJ1dGVEZXNpZ25hdG9yIEF0dHJpYnV0ZUlkPSJ1cm46b2FzaXM6bmFt"
+ + "ZXM6dGM6eGFjbWw6MS4wOnN1YmplY3Q6c3ViamVjdC1pZCIgRGF0YVR5cGU9Imh0"
+ + "dHA6Ly93d3cudzMub3JnLzIwMDEvWE1MU2NoZW1hI3N0cmluZyIgLz4gCiAgICA8"
+ + "L1N1YmplY3RNYXRjaD4KICAgPC9TdWJqZWN0PgogIDwvU3ViamVjdHM+CiAgPFJl"
+ + "c291cmNlcz4KICAgPFJlc291cmNlPgogICAgPFJlc291cmNlTWF0Y2ggTWF0Y2hJ"
+ + "ZD0idXJuOm9hc2lzOm5hbWVzOnRjOnhhY21sOjEuMDpmdW5jdGlvbjpzdHJpbmct"
+ + "ZXF1YWwiPgogICAgIDxBdHRyaWJ1dGVWYWx1ZSBEYXRhVHlwZT0iaHR0cDovL3d3"
+ + "dy53My5vcmcvMjAwMS9YTUxTY2hlbWEjYW55VVJJIj4KICAgICAgaHR0cDovL3p1"
+ + "bmkuY3MudnQuZWR1PC9BdHRyaWJ1dGVWYWx1ZT4KICAgICA8UmVzb3VyY2VBdHRy"
+ + "aWJ1dGVEZXNpZ25hdG9yIEF0dHJpYnV0ZUlkPSJ1cm46b2FzaXM6bmFtZXM6dGM6"
+ + "eGFjbWw6MS4wOnJlc291cmNlOnJlc291cmNlLWlkIiBEYXRhVHlwZT0iaHR0cDov"
+ + "L3d3dy53My5vcmcvMjAwMS9YTUxTY2hlbWEjYW55VVJJIiAvPiAKICAgIDwvUmVz"
+ + "b3VyY2VNYXRjaD4KICAgPC9SZXNvdXJjZT4KICA8L1Jlc291cmNlcz4KICA8QWN0"
+ + "aW9ucz4KICAgPEFjdGlvbj4KICAgIDxBY3Rpb25NYXRjaCBNYXRjaElkPSJ1cm46"
+ + "b2FzaXM6bmFtZXM6dGM6eGFjbWw6MS4wOmZ1bmN0aW9uOnN0cmluZy1lcXVhbCI+"
+ + "CiAgICAgPEF0dHJpYnV0ZVZhbHVlIERhdGFUeXBlPSJodHRwOi8vd3d3LnczLm9y"
+ + "Zy8yMDAxL1hNTFNjaGVtYSNzdHJpbmciPgpEZWxlZ2F0ZSBBY2Nlc3MgICAgIDwv"
+ + "QXR0cmlidXRlVmFsdWU+CgkgIDxBY3Rpb25BdHRyaWJ1dGVEZXNpZ25hdG9yIEF0"
+ + "dHJpYnV0ZUlkPSJ1cm46b2FzaXM6bmFtZXM6dGM6eGFjbWw6MS4wOmFjdGlvbjph"
+ + "Y3Rpb24taWQiIERhdGFUeXBlPSJodHRwOi8vd3d3LnczLm9yZy8yMDAxL1hNTFNj"
+ + "aGVtYSNzdHJpbmciIC8+IAogICAgPC9BY3Rpb25NYXRjaD4KICAgPC9BY3Rpb24+"
+ + "CiAgPC9BY3Rpb25zPgogPC9UYXJnZXQ+CjwvUnVsZT4KMA0GCSqGSIb3DQEBBAUA"
+ + "A4GBAGiJSM48XsY90HlYxGmGVSmNR6ZW2As+bot3KAfiCIkUIOAqhcphBS23egTr"
+ + "6asYwy151HshbPNYz+Cgeqs45KkVzh7bL/0e1r8sDVIaaGIkjHK3CqBABnfSayr3"
+ + "Rd1yBoDdEv8Qb+3eEPH6ab9021AsLEnJ6LWTmybbOpMNZ3tv");
+
+ byte[] signCert = Base64.decode(
+ "MIIGjTCCBXWgAwIBAgICAPswDQYJKoZIhvcNAQEEBQAwaTEdMBsGCSqGSIb3DQEJ"
+ + "ARYOaXJtaGVscEB2dC5lZHUxLjAsBgNVBAMTJVZpcmdpbmlhIFRlY2ggQ2VydGlm"
+ + "aWNhdGlvbiBBdXRob3JpdHkxCzAJBgNVBAoTAnZ0MQswCQYDVQQGEwJVUzAeFw0w"
+ + "MzAxMzExMzUyMTRaFw0wNDAxMzExMzUyMTRaMIGDMRswGQYJKoZIhvcNAQkBFgxz"
+ + "c2hhaEB2dC5lZHUxGzAZBgNVBAMTElN1bWl0IFNoYWggKHNzaGFoKTEbMBkGA1UE"
+ + "CxMSVmlyZ2luaWEgVGVjaCBVc2VyMRAwDgYDVQQLEwdDbGFzcyAxMQswCQYDVQQK"
+ + "EwJ2dDELMAkGA1UEBhMCVVMwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAPDc"
+ + "scgSKmsEp0VegFkuitD5j5PUkDuzLjlfaYONt2SN8WeqU4j2qtlCnsipa128cyKS"
+ + "JzYe9duUdNxquh5BPIkMkHBw4jHoQA33tk0J/sydWdN74/AHPpPieK5GHwhU7GTG"
+ + "rCCS1PJRxjXqse79ExAlul+gjQwHeldAC+d4A6oZAgMBAAGjggOmMIIDojAMBgNV"
+ + "HRMBAf8EAjAAMBEGCWCGSAGG+EIBAQQEAwIFoDAOBgNVHQ8BAf8EBAMCA/gwHQYD"
+ + "VR0lBBYwFAYIKwYBBQUHAwIGCCsGAQUFBwMEMB0GA1UdDgQWBBRUIoWAzlXbzBYE"
+ + "yVTjQFWyMMKo1jCBkwYDVR0jBIGLMIGIgBTgc3Fm+TGqKDhen+oKfbl+xVbj2KFt"
+ + "pGswaTEdMBsGCSqGSIb3DQEJARYOaXJtaGVscEB2dC5lZHUxLjAsBgNVBAMTJVZp"
+ + "cmdpbmlhIFRlY2ggQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkxCzAJBgNVBAoTAnZ0"
+ + "MQswCQYDVQQGEwJVU4IBADCBiwYJYIZIAYb4QgENBH4WfFZpcmdpbmlhIFRlY2gg"
+ + "Q2VydGlmaWNhdGlvbiBBdXRob3JpdHkgZGlnaXRhbCBjZXJ0aWZpY2F0ZXMgYXJl"
+ + "IHN1YmplY3QgdG8gcG9saWNpZXMgbG9jYXRlZCBhdCBodHRwOi8vd3d3LnBraS52"
+ + "dC5lZHUvY2EvY3BzLy4wFwYDVR0RBBAwDoEMc3NoYWhAdnQuZWR1MBkGA1UdEgQS"
+ + "MBCBDmlybWhlbHBAdnQuZWR1MEMGCCsGAQUFBwEBBDcwNTAzBggrBgEFBQcwAoYn"
+ + "aHR0cDovL2JveDE3Ny5jYy52dC5lZHUvY2EvaXNzdWVycy5odG1sMEQGA1UdHwQ9"
+ + "MDswOaA3oDWGM2h0dHA6Ly9ib3gxNzcuY2MudnQuZWR1L2h0ZG9jcy1wdWJsaWMv"
+ + "Y3JsL2NhY3JsLmNybDBUBgNVHSAETTBLMA0GCysGAQQBtGgFAQEBMDoGCysGAQQB"
+ + "tGgFAQEBMCswKQYIKwYBBQUHAgEWHWh0dHA6Ly93d3cucGtpLnZ0LmVkdS9jYS9j"
+ + "cHMvMD8GCWCGSAGG+EIBBAQyFjBodHRwOi8vYm94MTc3LmNjLnZ0LmVkdS9jZ2kt"
+ + "cHVibGljL2NoZWNrX3Jldl9jYT8wPAYJYIZIAYb4QgEDBC8WLWh0dHA6Ly9ib3gx"
+ + "NzcuY2MudnQuZWR1L2NnaS1wdWJsaWMvY2hlY2tfcmV2PzBLBglghkgBhvhCAQcE"
+ + "PhY8aHR0cHM6Ly9ib3gxNzcuY2MudnQuZWR1L35PcGVuQ0E4LjAxMDYzMC9jZ2kt"
+ + "cHVibGljL3JlbmV3YWw/MCwGCWCGSAGG+EIBCAQfFh1odHRwOi8vd3d3LnBraS52"
+ + "dC5lZHUvY2EvY3BzLzANBgkqhkiG9w0BAQQFAAOCAQEAHJ2ls9yjpZVcu5DqiE67"
+ + "r7BfkdMnm7IOj2v8cd4EAlPp6OPBmjwDMwvKRBb/P733kLBqFNWXWKTpT008R0KB"
+ + "8kehbx4h0UPz9vp31zhGv169+5iReQUUQSIwTGNWGLzrT8kPdvxiSAvdAJxcbRBm"
+ + "KzDic5I8PoGe48kSCkPpT1oNmnivmcu5j1SMvlx0IS2BkFMksr0OHiAW1elSnE/N"
+ + "RuX2k73b3FucwVxB3NRo3vgoHPCTnh9r4qItAHdxFlF+pPtbw2oHESKRfMRfOIHz"
+ + "CLQWSIa6Tvg4NIV3RRJ0sbCObesyg08lymalQMdkXwtRn5eGE00SHWwEUjSXP2gR"
+ + "3g==");
+
+ static byte[] certWithBaseCertificateID = Base64.decode(
+ "MIIBqzCCARQCAQEwSKBGMD6kPDA6MQswCQYDVQQGEwJJVDEOMAwGA1UEChMFVU5JVE4xDDAKBgNV"
+ + "BAsTA0RJVDENMAsGA1UEAxMEcm9vdAIEAVMVjqB6MHikdjB0MQswCQYDVQQGEwJBVTEoMCYGA1UE"
+ + "ChMfVGhlIExlZ2lvbiBvZiB0aGUgQm91bmN5IENhc3RsZTEjMCEGA1UECxMaQm91bmN5IFByaW1h"
+ + "cnkgQ2VydGlmaWNhdGUxFjAUBgNVBAMTDUJvdW5jeSBDYXN0bGUwDQYJKoZIhvcNAQEFBQACBQKW"
+ + "RhnHMCIYDzIwMDUxMjEyMTIwMDQyWhgPMjAwNTEyMTkxMjAxMzJaMA8wDQYDVRhIMQaBBGVWSVAw"
+ + "DQYJKoZIhvcNAQEFBQADgYEAUAVin9StDaA+InxtXq/av6rUQLI9p1X6louBcj4kYJnxRvTrHpsr"
+ + "N3+i9Uq/uk5lRdAqmPFvcmSbuE3TRAsjrXON5uFiBBKZ1AouLqcr8nHbwcdwjJ9TyUNO9I4hfpSH"
+ + "UHHXMtBKgp4MOkhhX8xTGyWg3hp23d3GaUeg/IYlXBI=");
+
+ byte[] holderCertWithBaseCertificateID = Base64.decode(
+ "MIIBwDCCASmgAwIBAgIEAVMVjjANBgkqhkiG9w0BAQUFADA6MQswCQYDVQQGEwJJVDEOMAwGA1UE"
+ + "ChMFVU5JVE4xDDAKBgNVBAsTA0RJVDENMAsGA1UEAxMEcm9vdDAeFw0wNTExMTExMjAxMzJaFw0w"
+ + "NjA2MTYxMjAxMzJaMD4xCzAJBgNVBAYTAklUMQ4wDAYDVQQKEwVVTklUTjEMMAoGA1UECxMDRElU"
+ + "MREwDwYDVQQDEwhMdWNhQm9yejBaMA0GCSqGSIb3DQEBAQUAA0kAMEYCQQC0p+RhcFdPFqlwgrIr"
+ + "5YtqKmKXmEGb4ShypL26Ymz66ZAPdqv7EhOdzl3lZWT6srZUMWWgQMYGiHQg4z2R7X7XAgERoxUw"
+ + "EzARBglghkgBhvhCAQEEBAMCBDAwDQYJKoZIhvcNAQEFBQADgYEAsX50VPQQCWmHvPq9y9DeCpmS"
+ + "4szcpFAhpZyn6gYRwY9CRZVtmZKH8713XhkGDWcIEMcG0u3oTz3tdKgPU5uyIPrDEWr6w8ClUj4x"
+ + "5aVz5c2223+dVY7KES//JSB2bE/KCIchN3kAioQ4K8O3e0OL6oDVjsqKGw5bfahgKuSIk/Q=");
+
+
+ public String getName()
+ {
+ return "AttrCertTest";
+ }
+
+ public void testCertWithBaseCertificateID()
+ throws Exception
+ {
+ X509AttributeCertificateHolder attrCert = new X509AttributeCertificateHolder(certWithBaseCertificateID);
+ X509CertificateHolder cert = new X509CertificateHolder(holderCertWithBaseCertificateID);
+
+ AttributeCertificateHolder holder = attrCert.getHolder();
+
+ if (holder.getEntityNames() != null)
+ {
+ fail("entity names set when none expected");
+ }
+
+ if (!holder.getSerialNumber().equals(cert.getSerialNumber()))
+ {
+ fail("holder serial number doesn't match");
+ }
+
+ if (!holder.getIssuer()[0].equals(cert.getIssuer()))
+ {
+ fail("holder issuer doesn't match");
+ }
+
+ if (!holder.match(cert))
+ {
+ fail("holder not matching holder certificate");
+ }
+
+ if (!holder.equals(holder.clone()))
+ {
+ fail("holder clone test failed");
+ }
+
+ if (!attrCert.getIssuer().equals(attrCert.getIssuer().clone()))
+ {
+ fail("issuer clone test failed");
+ }
+
+ //equalityAndHashCodeTest(attrCert, certWithBaseCertificateID);
+ }
+
+ private void equalityAndHashCodeTest(X509AttributeCertificateHolder attrCert, byte[] encoding)
+ throws IOException
+ {
+ if (!attrCert.equals(attrCert))
+ {
+ fail("same certificate not equal");
+ }
+
+ if (!attrCert.getHolder().equals(attrCert.getHolder()))
+ {
+ fail("same holder not equal");
+ }
+
+ if (!attrCert.getIssuer().equals(attrCert.getIssuer()))
+ {
+ fail("same issuer not equal");
+ }
+
+ if (attrCert.getHolder().equals(attrCert.getIssuer()))
+ {
+ fail("wrong holder equal");
+ }
+
+ if (attrCert.getIssuer().equals(attrCert.getHolder()))
+ {
+ fail("wrong issuer equal");
+ }
+
+ X509AttributeCertificateHolder attrCert2 = new X509AttributeCertificateHolder(encoding);
+
+ if (attrCert2.getHolder().hashCode() != attrCert.getHolder().hashCode())
+ {
+ fail("holder hashCode test failed");
+ }
+
+ if (!attrCert2.getHolder().equals(attrCert.getHolder()))
+ {
+ fail("holder equals test failed");
+ }
+
+ if (attrCert2.getIssuer().hashCode() != attrCert.getIssuer().hashCode())
+ {
+ fail("issuer hashCode test failed");
+ }
+
+ if (!attrCert2.getIssuer().equals(attrCert.getIssuer()))
+ {
+ fail("issuer equals test failed");
+ }
+ }
+
+ public void testGenerateWithCert()
+ throws Exception
+ {
+ X509CertificateHolder iCert = new X509CertificateHolder(signCert);
+
+ //
+ // a sample key pair.
+ //
+ AsymmetricKeyParameter pubKey = new RSAKeyParameters(
+ false,
+ new BigInteger("b4a7e46170574f16a97082b22be58b6a2a629798419be12872a4bdba626cfae9900f76abfb12139dce5de56564fab2b6543165a040c606887420e33d91ed7ed7", 16),
+ new BigInteger("11", 16));
+
+ //
+ // set up the keys
+ //
+ AsymmetricKeyParameter privKey = RSA_PRIVATE_KEY_SPEC;
+
+ X509v2AttributeCertificateBuilder gen = new X509v2AttributeCertificateBuilder(
+ new AttributeCertificateHolder(iCert),
+ new AttributeCertificateIssuer(new X500Name("cn=test")),
+ BigInteger.ONE,
+ new Date(System.currentTimeMillis() - 50000),
+ new Date(System.currentTimeMillis() + 50000));
+
+ // the actual attributes
+ GeneralName roleName = new GeneralName(GeneralName.rfc822Name, "DAU123456789");
+ ASN1EncodableVector roleSyntax = new ASN1EncodableVector();
+ roleSyntax.add(roleName);
+
+ // roleSyntax OID: 2.5.24.72;
+
+ gen.addAttribute(new ASN1ObjectIdentifier("2.5.24.72"), new DERSequence(roleSyntax));
+
+ AlgorithmIdentifier sigAlg = sigAlgFinder.find("SHA1withRSA");
+ AlgorithmIdentifier digAlg = digAlgFinder.find(sigAlg);
+
+ ContentSigner sigGen = new BcRSAContentSignerBuilder(sigAlg, digAlg).build(privKey);
+
+ X509AttributeCertificateHolder aCert = gen.build(sigGen);
+
+ if (!aCert.isValidOn(new Date()))
+ {
+ fail("certificate invalid");
+ }
+
+ if (!aCert.isSignatureValid(new BcRSAContentVerifierProviderBuilder(digAlgFinder).build(pubKey)))
+ {
+ fail("certificate signature not valid");
+ }
+
+ AttributeCertificateHolder holder = aCert.getHolder();
+
+ if (holder.getEntityNames() != null)
+ {
+ fail("entity names set when none expected");
+ }
+
+ if (!holder.getSerialNumber().equals(iCert.getSerialNumber()))
+ {
+ fail("holder serial number doesn't match");
+ }
+
+ if (!holder.getIssuer()[0].equals(iCert.getIssuer()))
+ {
+ fail("holder issuer doesn't match");
+ }
+
+ if (!holder.match(iCert))
+ {
+ fail("generated holder not matching holder certificate");
+ }
+
+ Attribute[] attrs = aCert.getAttributes(new ASN1ObjectIdentifier("2.5.24.72"));
+
+ if (attrs == null)
+ {
+ fail("attributes related to 2.5.24.72 not found");
+ }
+
+ Attribute attr = attrs[0];
+
+ if (!attr.getAttrType().getId().equals("2.5.24.72"))
+ {
+ fail("attribute oid mismatch");
+ }
+
+ ASN1Encodable[] values = attr.getAttrValues().toArray();
+
+ GeneralName role = GeneralNames.getInstance(values[0]).getNames()[0];
+
+ if (role.getTagNo() != GeneralName.rfc822Name)
+ {
+ fail("wrong general name type found in role");
+ }
+
+ if (!((ASN1String)role.getName()).getString().equals("DAU123456789"))
+ {
+ fail("wrong general name value found in role");
+ }
+
+ X509CertificateHolder sCert = new X509CertificateHolder(holderCertWithBaseCertificateID);
+
+ if (holder.match(sCert))
+ {
+ fail("generated holder matching wrong certificate");
+ }
+
+ equalityAndHashCodeTest(aCert, aCert.getEncoded());
+ }
+
+ public void testGenerateWithPrincipal()
+ throws Exception
+ {
+ X509CertificateHolder iCert = new X509CertificateHolder(signCert);
+
+ //
+ // a sample key pair.
+ //
+ RSAKeyParameters pubKey = new RSAKeyParameters(
+ false,
+ new BigInteger("b4a7e46170574f16a97082b22be58b6a2a629798419be12872a4bdba626cfae9900f76abfb12139dce5de56564fab2b6543165a040c606887420e33d91ed7ed7", 16),
+ new BigInteger("11", 16));
+
+ //
+ // set up the keys
+ //
+ AsymmetricKeyParameter privKey = RSA_PRIVATE_KEY_SPEC;
+
+ X509v2AttributeCertificateBuilder gen = new X509v2AttributeCertificateBuilder(
+ new AttributeCertificateHolder(iCert.getSubject()),
+ new AttributeCertificateIssuer(new X500Name("cn=test")),
+ BigInteger.ONE,
+ new Date(System.currentTimeMillis() - 50000),
+ new Date(System.currentTimeMillis() + 50000));
+
+ // the actual attributes
+ GeneralName roleName = new GeneralName(GeneralName.rfc822Name, "DAU123456789");
+ ASN1EncodableVector roleSyntax = new ASN1EncodableVector();
+ roleSyntax.add(roleName);
+
+ // roleSyntax OID: 2.5.24.72
+
+ gen.addAttribute(new ASN1ObjectIdentifier("2.5.24.72"), new DERSequence(roleSyntax));
+
+ AlgorithmIdentifier sigAlg = sigAlgFinder.find("SHA1withRSA");
+ AlgorithmIdentifier digAlg = digAlgFinder.find(sigAlg);
+
+ ContentSigner sigGen = new BcRSAContentSignerBuilder(sigAlg, digAlg).build(privKey);
+ X509AttributeCertificateHolder aCert = gen.build(sigGen);
+
+ if (!aCert.isValidOn(new Date()))
+ {
+ fail("certificate invalid");
+ }
+
+ if (!aCert.isSignatureValid(new BcRSAContentVerifierProviderBuilder(digAlgFinder).build(pubKey)))
+ {
+ fail("certificate signature not valid");
+ }
+
+ AttributeCertificateHolder holder = aCert.getHolder();
+
+ if (holder.getEntityNames() == null)
+ {
+ fail("entity names not set when expected");
+ }
+
+ if (holder.getSerialNumber() != null)
+ {
+ fail("holder serial number found when none expected");
+ }
+
+ if (holder.getIssuer() != null)
+ {
+ fail("holder issuer found when none expected");
+ }
+
+ if (!holder.match(iCert))
+ {
+ fail("generated holder not matching holder certificate");
+ }
+
+ X509CertificateHolder sCert = new X509CertificateHolder(holderCertWithBaseCertificateID);
+
+ if (holder.match(sCert))
+ {
+ fail("principal generated holder matching wrong certificate");
+ }
+
+ equalityAndHashCodeTest(aCert, aCert.getEncoded());
+ }
+
+ public void testFully()
+ throws Exception
+ {
+ X509AttributeCertificateHolder aCert = new X509AttributeCertificateHolder(attrCert);
+ X509CertificateHolder sCert = new X509CertificateHolder(signCert);
+
+ if (!aCert.isSignatureValid(new BcRSAContentVerifierProviderBuilder(digAlgFinder).build(sCert)))
+ {
+ fail("certificate signature not valid");
+ }
+
+ //
+ // search test
+ //
+
+ List list = new ArrayList();
+
+ list.add(sCert);
+
+ Store store = new CollectionStore(list);
+
+ Collection certs = store.getMatches(aCert.getIssuer());
+ if (certs.size() != 1 || !certs.contains(sCert))
+ {
+ fail("sCert not found by issuer");
+ }
+
+ Attribute[] attrs = aCert.getAttributes(new ASN1ObjectIdentifier("1.3.6.1.4.1.6760.8.1.1"));
+ if (attrs == null || attrs.length != 1)
+ {
+ fail("attribute not found");
+ }
+
+ //
+ // reencode test
+ //
+ aCert = new X509AttributeCertificateHolder(aCert.getEncoded());
+
+ if (!aCert.isSignatureValid(new BcRSAContentVerifierProviderBuilder(digAlgFinder).build(sCert)))
+ {
+ fail("certificate signature not valid");
+ }
+
+ X509AttributeCertificateHolder saCert = new X509AttributeCertificateHolder(aCert.getEncoded());
+
+ if (!aCert.getNotAfter().equals(saCert.getNotAfter()))
+ {
+ fail("failed date comparison");
+ }
+
+ // base generator test
+
+ //
+ // a sample key pair.
+ //
+ AsymmetricKeyParameter pubKey = new RSAKeyParameters(
+ false,
+ new BigInteger("b4a7e46170574f16a97082b22be58b6a2a629798419be12872a4bdba626cfae9900f76abfb12139dce5de56564fab2b6543165a040c606887420e33d91ed7ed7", 16),
+ new BigInteger("11", 16));
+
+ AsymmetricKeyParameter privKey = RSA_PRIVATE_KEY_SPEC;
+
+ X509v2AttributeCertificateBuilder gen = new X509v2AttributeCertificateBuilder(
+ aCert.getHolder(),
+ aCert.getIssuer(),
+ aCert.getSerialNumber(),
+ new Date(System.currentTimeMillis() - 50000),
+ new Date(System.currentTimeMillis() + 50000));
+
+ gen.addAttribute(attrs[0].getAttrType(), attrs[0].getAttributeValues());
+
+ AlgorithmIdentifier sigAlg = sigAlgFinder.find("SHA1withRSA");
+ AlgorithmIdentifier digAlg = digAlgFinder.find(sigAlg);
+
+ ContentSigner sigGen = new BcRSAContentSignerBuilder(sigAlg, digAlg).build(privKey);
+ aCert = gen.build(sigGen);
+
+ if (!aCert.isValidOn(new Date()))
+ {
+ fail("certificate not valid");
+ }
+
+ if (!aCert.isSignatureValid(new BcRSAContentVerifierProviderBuilder(digAlgFinder).build(pubKey)))
+ {
+ fail("signature not valid");
+ }
+
+ // as the issuer is the same this should still work (even though it is not
+ // technically correct
+
+ certs = store.getMatches(aCert.getIssuer());
+ if (certs.size() != 1 || !certs.contains(sCert))
+ {
+ fail("sCert not found by issuer");
+ }
+
+ attrs = aCert.getAttributes(new ASN1ObjectIdentifier("1.3.6.1.4.1.6760.8.1.1"));
+ if (attrs == null || attrs.length != 1)
+ {
+ fail("attribute not found");
+ }
+
+ //
+ // reencode test
+ //
+ aCert = new X509AttributeCertificateHolder(aCert.getEncoded());
+
+ if (!aCert.isSignatureValid(new BcRSAContentVerifierProviderBuilder(digAlgFinder).build(pubKey)))
+ {
+ fail("signature not valid");
+ }
+
+ AttributeCertificateIssuer issuer = aCert.getIssuer();
+
+ X500Name[] principals = issuer.getNames();
+
+ //
+ // test holder
+ //
+ AttributeCertificateHolder holder = aCert.getHolder();
+
+ if (holder.getEntityNames() == null)
+ {
+ fail("entity names not set");
+ }
+
+ if (holder.getSerialNumber() != null)
+ {
+ fail("holder serial number set when none expected");
+ }
+
+ if (holder.getIssuer() != null)
+ {
+ fail("holder issuer set when none expected");
+ }
+
+ principals = holder.getEntityNames();
+
+ X500Name principal0 = new X500Name(RFC4519Style.INSTANCE, principals[0]);
+ if (!principal0.toString().equals("c=US,o=vt,ou=Class 2,ou=Virginia Tech User,cn=Markus Lorch (mlorch),1.2.840.113549.1.9.1=mlorch@vt.edu"))
+ {
+ System.err.println(principal0.toString());
+ fail("principal[0] for entity names don't match");
+ }
+
+ //
+ // extension test
+ //
+
+ if (aCert.hasExtensions())
+ {
+ fail("hasExtensions true with no extensions");
+ }
+
+ gen.addExtension(new ASN1ObjectIdentifier("1.1"), true, new DEROctetString(new byte[10]));
+
+ gen.addExtension(new ASN1ObjectIdentifier("2.2"), false, new DEROctetString(new byte[20]));
+
+ aCert = gen.build(sigGen);
+
+ Set exts = aCert.getCriticalExtensionOIDs();
+
+ if (exts.size() != 1 || !exts.contains(new ASN1ObjectIdentifier("1.1")))
+ {
+ fail("critical extension test failed");
+ }
+
+ exts = aCert.getNonCriticalExtensionOIDs();
+
+ if (exts.size() != 1 || !exts.contains(new ASN1ObjectIdentifier("2.2")))
+ {
+ fail("non-critical extension test failed");
+ }
+
+ if (aCert.getCriticalExtensionOIDs().isEmpty())
+ {
+ fail("critical extensions not found");
+ }
+
+ Extension ext = aCert.getExtension(new ASN1ObjectIdentifier("1.1"));
+ ASN1Encodable extValue = ext.getParsedValue();
+
+ if (!extValue.equals(new DEROctetString(new byte[10])))
+ {
+ fail("wrong extension value found for 1.1");
+ }
+ }
+}
diff --git a/pkix/src/test/java/org/spongycastle/cert/test/BcCertTest.java b/pkix/src/test/java/org/spongycastle/cert/test/BcCertTest.java
new file mode 100644
index 00000000..41c98e8e
--- /dev/null
+++ b/pkix/src/test/java/org/spongycastle/cert/test/BcCertTest.java
@@ -0,0 +1,1434 @@
+package org.spongycastle.cert.test;
+
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.UnsupportedEncodingException;
+import java.math.BigInteger;
+import java.security.SecureRandom;
+import java.security.cert.CRL;
+import java.security.cert.CertificateException;
+import java.security.cert.CertificateFactory;
+import java.security.cert.X509CRL;
+import java.security.cert.X509Certificate;
+import java.util.Collection;
+import java.util.Date;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Set;
+
+import junit.framework.TestCase;
+import org.spongycastle.asn1.ASN1EncodableVector;
+import org.spongycastle.asn1.ASN1Enumerated;
+import org.spongycastle.asn1.ASN1Object;
+import org.spongycastle.asn1.ASN1ObjectIdentifier;
+import org.spongycastle.asn1.DERBitString;
+import org.spongycastle.asn1.DERSequence;
+import org.spongycastle.asn1.pkcs.PKCSObjectIdentifiers;
+import org.spongycastle.asn1.x500.X500Name;
+import org.spongycastle.asn1.x500.X500NameBuilder;
+import org.spongycastle.asn1.x500.style.RFC4519Style;
+import org.spongycastle.asn1.x509.AlgorithmIdentifier;
+import org.spongycastle.asn1.x509.AuthorityKeyIdentifier;
+import org.spongycastle.asn1.x509.CRLReason;
+import org.spongycastle.asn1.x509.Certificate;
+import org.spongycastle.asn1.x509.Extension;
+import org.spongycastle.asn1.x509.Extensions;
+import org.spongycastle.asn1.x509.ExtensionsGenerator;
+import org.spongycastle.asn1.x509.GeneralName;
+import org.spongycastle.asn1.x509.GeneralNames;
+import org.spongycastle.asn1.x509.KeyPurposeId;
+import org.spongycastle.asn1.x509.KeyUsage;
+import org.spongycastle.asn1.x509.SubjectPublicKeyInfo;
+import org.spongycastle.cert.CertException;
+import org.spongycastle.cert.X509CRLEntryHolder;
+import org.spongycastle.cert.X509CRLHolder;
+import org.spongycastle.cert.X509CertificateHolder;
+import org.spongycastle.cert.X509v1CertificateBuilder;
+import org.spongycastle.cert.X509v2CRLBuilder;
+import org.spongycastle.cert.X509v3CertificateBuilder;
+import org.spongycastle.cert.bc.BcX509ExtensionUtils;
+import org.spongycastle.cert.bc.BcX509v1CertificateBuilder;
+import org.spongycastle.cert.bc.BcX509v3CertificateBuilder;
+import org.spongycastle.cert.jcajce.JcaX509CertificateConverter;
+import org.spongycastle.crypto.AsymmetricCipherKeyPair;
+import org.spongycastle.crypto.AsymmetricCipherKeyPairGenerator;
+import org.spongycastle.crypto.generators.DSAKeyPairGenerator;
+import org.spongycastle.crypto.generators.DSAParametersGenerator;
+import org.spongycastle.crypto.generators.RSAKeyPairGenerator;
+import org.spongycastle.crypto.params.AsymmetricKeyParameter;
+import org.spongycastle.crypto.params.DSAKeyGenerationParameters;
+import org.spongycastle.crypto.params.DSAParameters;
+import org.spongycastle.crypto.params.RSAKeyGenerationParameters;
+import org.spongycastle.crypto.params.RSAKeyParameters;
+import org.spongycastle.crypto.params.RSAPrivateCrtKeyParameters;
+import org.spongycastle.crypto.util.SubjectPublicKeyInfoFactory;
+import org.spongycastle.operator.ContentSigner;
+import org.spongycastle.operator.ContentVerifierProvider;
+import org.spongycastle.operator.DefaultDigestAlgorithmIdentifierFinder;
+import org.spongycastle.operator.DefaultSignatureAlgorithmIdentifierFinder;
+import org.spongycastle.operator.OperatorCreationException;
+import org.spongycastle.operator.bc.BcDSAContentSignerBuilder;
+import org.spongycastle.operator.bc.BcDSAContentVerifierProviderBuilder;
+import org.spongycastle.operator.bc.BcRSAContentSignerBuilder;
+import org.spongycastle.operator.bc.BcRSAContentVerifierProviderBuilder;
+import org.spongycastle.util.encoders.Base64;
+
+public class BcCertTest
+ extends TestCase
+{
+ DefaultSignatureAlgorithmIdentifierFinder sigAlgFinder = new DefaultSignatureAlgorithmIdentifierFinder();
+ DefaultDigestAlgorithmIdentifierFinder digAlgFinder = new DefaultDigestAlgorithmIdentifierFinder();
+
+ //
+ // server.crt
+ //
+ byte[] cert1 = Base64.decode(
+ "MIIDXjCCAsegAwIBAgIBBzANBgkqhkiG9w0BAQQFADCBtzELMAkGA1UEBhMCQVUx"
+ + "ETAPBgNVBAgTCFZpY3RvcmlhMRgwFgYDVQQHEw9Tb3V0aCBNZWxib3VybmUxGjAY"
+ + "BgNVBAoTEUNvbm5lY3QgNCBQdHkgTHRkMR4wHAYDVQQLExVDZXJ0aWZpY2F0ZSBB"
+ + "dXRob3JpdHkxFTATBgNVBAMTDENvbm5lY3QgNCBDQTEoMCYGCSqGSIb3DQEJARYZ"
+ + "d2VibWFzdGVyQGNvbm5lY3Q0LmNvbS5hdTAeFw0wMDA2MDIwNzU2MjFaFw0wMTA2"
+ + "MDIwNzU2MjFaMIG4MQswCQYDVQQGEwJBVTERMA8GA1UECBMIVmljdG9yaWExGDAW"
+ + "BgNVBAcTD1NvdXRoIE1lbGJvdXJuZTEaMBgGA1UEChMRQ29ubmVjdCA0IFB0eSBM"
+ + "dGQxFzAVBgNVBAsTDldlYnNlcnZlciBUZWFtMR0wGwYDVQQDExR3d3cyLmNvbm5l"
+ + "Y3Q0LmNvbS5hdTEoMCYGCSqGSIb3DQEJARYZd2VibWFzdGVyQGNvbm5lY3Q0LmNv"
+ + "bS5hdTCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEArvDxclKAhyv7Q/Wmr2re"
+ + "Gw4XL9Cnh9e+6VgWy2AWNy/MVeXdlxzd7QAuc1eOWQkGQEiLPy5XQtTY+sBUJ3AO"
+ + "Rvd2fEVJIcjf29ey7bYua9J/vz5MG2KYo9/WCHIwqD9mmG9g0xLcfwq/s8ZJBswE"
+ + "7sb85VU+h94PTvsWOsWuKaECAwEAAaN3MHUwJAYDVR0RBB0wG4EZd2VibWFzdGVy"
+ + "QGNvbm5lY3Q0LmNvbS5hdTA6BglghkgBhvhCAQ0ELRYrbW9kX3NzbCBnZW5lcmF0"
+ + "ZWQgY3VzdG9tIHNlcnZlciBjZXJ0aWZpY2F0ZTARBglghkgBhvhCAQEEBAMCBkAw"
+ + "DQYJKoZIhvcNAQEEBQADgYEAotccfKpwSsIxM1Hae8DR7M/Rw8dg/RqOWx45HNVL"
+ + "iBS4/3N/TO195yeQKbfmzbAA2jbPVvIvGgTxPgO1MP4ZgvgRhasaa0qCJCkWvpM4"
+ + "yQf33vOiYQbpv4rTwzU8AmRlBG45WdjyNIigGV+oRc61aKCTnLq7zB8N3z1TF/bF"
+ + "5/8=");
+
+ //
+ // ca.crt
+ //
+ byte[] cert2 = Base64.decode(
+ "MIIDbDCCAtWgAwIBAgIBADANBgkqhkiG9w0BAQQFADCBtzELMAkGA1UEBhMCQVUx"
+ + "ETAPBgNVBAgTCFZpY3RvcmlhMRgwFgYDVQQHEw9Tb3V0aCBNZWxib3VybmUxGjAY"
+ + "BgNVBAoTEUNvbm5lY3QgNCBQdHkgTHRkMR4wHAYDVQQLExVDZXJ0aWZpY2F0ZSBB"
+ + "dXRob3JpdHkxFTATBgNVBAMTDENvbm5lY3QgNCBDQTEoMCYGCSqGSIb3DQEJARYZ"
+ + "d2VibWFzdGVyQGNvbm5lY3Q0LmNvbS5hdTAeFw0wMDA2MDIwNzU1MzNaFw0wMTA2"
+ + "MDIwNzU1MzNaMIG3MQswCQYDVQQGEwJBVTERMA8GA1UECBMIVmljdG9yaWExGDAW"
+ + "BgNVBAcTD1NvdXRoIE1lbGJvdXJuZTEaMBgGA1UEChMRQ29ubmVjdCA0IFB0eSBM"
+ + "dGQxHjAcBgNVBAsTFUNlcnRpZmljYXRlIEF1dGhvcml0eTEVMBMGA1UEAxMMQ29u"
+ + "bmVjdCA0IENBMSgwJgYJKoZIhvcNAQkBFhl3ZWJtYXN0ZXJAY29ubmVjdDQuY29t"
+ + "LmF1MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDgs5ptNG6Qv1ZpCDuUNGmv"
+ + "rhjqMDPd3ri8JzZNRiiFlBA4e6/ReaO1U8ASewDeQMH6i9R6degFdQRLngbuJP0s"
+ + "xcEE+SksEWNvygfzLwV9J/q+TQDyJYK52utb++lS0b48A1KPLwEsyL6kOAgelbur"
+ + "ukwxowprKUIV7Knf1ajetQIDAQABo4GFMIGCMCQGA1UdEQQdMBuBGXdlYm1hc3Rl"
+ + "ckBjb25uZWN0NC5jb20uYXUwDwYDVR0TBAgwBgEB/wIBADA2BglghkgBhvhCAQ0E"
+ + "KRYnbW9kX3NzbCBnZW5lcmF0ZWQgY3VzdG9tIENBIGNlcnRpZmljYXRlMBEGCWCG"
+ + "SAGG+EIBAQQEAwICBDANBgkqhkiG9w0BAQQFAAOBgQCsGvfdghH8pPhlwm1r3pQk"
+ + "msnLAVIBb01EhbXm2861iXZfWqGQjrGAaA0ZpXNk9oo110yxoqEoSJSzniZa7Xtz"
+ + "soTwNUpE0SLHvWf/SlKdFWlzXA+vOZbzEv4UmjeelekTm7lc01EEa5QRVzOxHFtQ"
+ + "DhkaJ8VqOMajkQFma2r9iA==");
+
+ //
+ // testx509.pem
+ //
+ byte[] cert3 = Base64.decode(
+ "MIIBWzCCAQYCARgwDQYJKoZIhvcNAQEEBQAwODELMAkGA1UEBhMCQVUxDDAKBgNV"
+ + "BAgTA1FMRDEbMBkGA1UEAxMSU1NMZWF5L3JzYSB0ZXN0IENBMB4XDTk1MDYxOTIz"
+ + "MzMxMloXDTk1MDcxNzIzMzMxMlowOjELMAkGA1UEBhMCQVUxDDAKBgNVBAgTA1FM"
+ + "RDEdMBsGA1UEAxMUU1NMZWF5L3JzYSB0ZXN0IGNlcnQwXDANBgkqhkiG9w0BAQEF"
+ + "AANLADBIAkEAqtt6qS5GTxVxGZYWa0/4u+IwHf7p2LNZbcPBp9/OfIcYAXBQn8hO"
+ + "/Re1uwLKXdCjIoaGs4DLdG88rkzfyK5dPQIDAQABMAwGCCqGSIb3DQIFBQADQQAE"
+ + "Wc7EcF8po2/ZO6kNCwK/ICH6DobgLekA5lSLr5EvuioZniZp5lFzAw4+YzPQ7XKJ"
+ + "zl9HYIMxATFyqSiD9jsx");
+
+ //
+ // v3-cert1.pem
+ //
+ byte[] cert4 = Base64.decode(
+ "MIICjTCCAfigAwIBAgIEMaYgRzALBgkqhkiG9w0BAQQwRTELMAkGA1UEBhMCVVMx"
+ + "NjA0BgNVBAoTLU5hdGlvbmFsIEFlcm9uYXV0aWNzIGFuZCBTcGFjZSBBZG1pbmlz"
+ + "dHJhdGlvbjAmFxE5NjA1MjgxMzQ5MDUrMDgwMBcROTgwNTI4MTM0OTA1KzA4MDAw"
+ + "ZzELMAkGA1UEBhMCVVMxNjA0BgNVBAoTLU5hdGlvbmFsIEFlcm9uYXV0aWNzIGFu"
+ + "ZCBTcGFjZSBBZG1pbmlzdHJhdGlvbjEgMAkGA1UEBRMCMTYwEwYDVQQDEwxTdGV2"
+ + "ZSBTY2hvY2gwWDALBgkqhkiG9w0BAQEDSQAwRgJBALrAwyYdgxmzNP/ts0Uyf6Bp"
+ + "miJYktU/w4NG67ULaN4B5CnEz7k57s9o3YY3LecETgQ5iQHmkwlYDTL2fTgVfw0C"
+ + "AQOjgaswgagwZAYDVR0ZAQH/BFowWDBWMFQxCzAJBgNVBAYTAlVTMTYwNAYDVQQK"
+ + "Ey1OYXRpb25hbCBBZXJvbmF1dGljcyBhbmQgU3BhY2UgQWRtaW5pc3RyYXRpb24x"
+ + "DTALBgNVBAMTBENSTDEwFwYDVR0BAQH/BA0wC4AJODMyOTcwODEwMBgGA1UdAgQR"
+ + "MA8ECTgzMjk3MDgyM4ACBSAwDQYDVR0KBAYwBAMCBkAwCwYJKoZIhvcNAQEEA4GB"
+ + "AH2y1VCEw/A4zaXzSYZJTTUi3uawbbFiS2yxHvgf28+8Js0OHXk1H1w2d6qOHH21"
+ + "X82tZXd/0JtG0g1T9usFFBDvYK8O0ebgz/P5ELJnBL2+atObEuJy1ZZ0pBDWINR3"
+ + "WkDNLCGiTkCKp0F5EWIrVDwh54NNevkCQRZita+z4IBO");
+
+ //
+ // v3-cert2.pem
+ //
+ byte[] cert5 = Base64.decode(
+ "MIICiTCCAfKgAwIBAgIEMeZfHzANBgkqhkiG9w0BAQQFADB9MQswCQYDVQQGEwJD"
+ + "YTEPMA0GA1UEBxMGTmVwZWFuMR4wHAYDVQQLExVObyBMaWFiaWxpdHkgQWNjZXB0"
+ + "ZWQxHzAdBgNVBAoTFkZvciBEZW1vIFB1cnBvc2VzIE9ubHkxHDAaBgNVBAMTE0Vu"
+ + "dHJ1c3QgRGVtbyBXZWIgQ0EwHhcNOTYwNzEyMTQyMDE1WhcNOTYxMDEyMTQyMDE1"
+ + "WjB0MSQwIgYJKoZIhvcNAQkBExVjb29rZUBpc3NsLmF0bC5ocC5jb20xCzAJBgNV"
+ + "BAYTAlVTMScwJQYDVQQLEx5IZXdsZXR0IFBhY2thcmQgQ29tcGFueSAoSVNTTCkx"
+ + "FjAUBgNVBAMTDVBhdWwgQS4gQ29va2UwXDANBgkqhkiG9w0BAQEFAANLADBIAkEA"
+ + "6ceSq9a9AU6g+zBwaL/yVmW1/9EE8s5you1mgjHnj0wAILuoB3L6rm6jmFRy7QZT"
+ + "G43IhVZdDua4e+5/n1ZslwIDAQABo2MwYTARBglghkgBhvhCAQEEBAMCB4AwTAYJ"
+ + "YIZIAYb4QgENBD8WPVRoaXMgY2VydGlmaWNhdGUgaXMgb25seSBpbnRlbmRlZCBm"
+ + "b3IgZGVtb25zdHJhdGlvbiBwdXJwb3Nlcy4wDQYJKoZIhvcNAQEEBQADgYEAi8qc"
+ + "F3zfFqy1sV8NhjwLVwOKuSfhR/Z8mbIEUeSTlnH3QbYt3HWZQ+vXI8mvtZoBc2Fz"
+ + "lexKeIkAZXCesqGbs6z6nCt16P6tmdfbZF3I3AWzLquPcOXjPf4HgstkyvVBn0Ap"
+ + "jAFN418KF/Cx4qyHB4cjdvLrRjjQLnb2+ibo7QU=");
+
+ //
+ // pem encoded pkcs7
+ //
+ byte[] cert6 = Base64.decode(
+ "MIAGCSqGSIb3DQEHAqCAMIACAQExCzAJBgUrDgMCGgUAMIAGCSqGSIb3DQEHAQAAoIIJbzCCAj0w"
+ + "ggGmAhEAzbp/VvDf5LxU/iKss3KqVTANBgkqhkiG9w0BAQIFADBfMQswCQYDVQQGEwJVUzEXMBUG"
+ + "A1UEChMOVmVyaVNpZ24sIEluYy4xNzA1BgNVBAsTLkNsYXNzIDEgUHVibGljIFByaW1hcnkgQ2Vy"
+ + "dGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNOTYwMTI5MDAwMDAwWhcNMjgwODAxMjM1OTU5WjBfMQsw"
+ + "CQYDVQQGEwJVUzEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xNzA1BgNVBAsTLkNsYXNzIDEgUHVi"
+ + "bGljIFByaW1hcnkgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwgZ8wDQYJKoZIhvcNAQEBBQADgY0A"
+ + "MIGJAoGBAOUZv22jVmEtmUhx9mfeuY3rt56GgAqRDvo4Ja9GiILlc6igmyRdDR/MZW4MsNBWhBiH"
+ + "mgabEKFz37RYOWtuwfYV1aioP6oSBo0xrH+wNNePNGeICc0UEeJORVZpH3gCgNrcR5EpuzbJY1zF"
+ + "4Ncth3uhtzKwezC6Ki8xqu6jZ9rbAgMBAAEwDQYJKoZIhvcNAQECBQADgYEATD+4i8Zo3+5DMw5d"
+ + "6abLB4RNejP/khv0Nq3YlSI2aBFsfELM85wuxAc/FLAPT/+Qknb54rxK6Y/NoIAK98Up8YIiXbix"
+ + "3YEjo3slFUYweRb46gVLlH8dwhzI47f0EEA8E8NfH1PoSOSGtHuhNbB7Jbq4046rPzidADQAmPPR"
+ + "cZQwggMuMIICl6ADAgECAhEA0nYujRQMPX2yqCVdr+4NdTANBgkqhkiG9w0BAQIFADBfMQswCQYD"
+ + "VQQGEwJVUzEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xNzA1BgNVBAsTLkNsYXNzIDEgUHVibGlj"
+ + "IFByaW1hcnkgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNOTgwNTEyMDAwMDAwWhcNMDgwNTEy"
+ + "MjM1OTU5WjCBzDEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xHzAdBgNVBAsTFlZlcmlTaWduIFRy"
+ + "dXN0IE5ldHdvcmsxRjBEBgNVBAsTPXd3dy52ZXJpc2lnbi5jb20vcmVwb3NpdG9yeS9SUEEgSW5j"
+ + "b3JwLiBCeSBSZWYuLExJQUIuTFREKGMpOTgxSDBGBgNVBAMTP1ZlcmlTaWduIENsYXNzIDEgQ0Eg"
+ + "SW5kaXZpZHVhbCBTdWJzY3JpYmVyLVBlcnNvbmEgTm90IFZhbGlkYXRlZDCBnzANBgkqhkiG9w0B"
+ + "AQEFAAOBjQAwgYkCgYEAu1pEigQWu1X9A3qKLZRPFXg2uA1Ksm+cVL+86HcqnbnwaLuV2TFBcHqB"
+ + "S7lIE1YtxwjhhEKrwKKSq0RcqkLwgg4C6S/7wju7vsknCl22sDZCM7VuVIhPh0q/Gdr5FegPh7Yc"
+ + "48zGmo5/aiSS4/zgZbqnsX7vyds3ashKyAkG5JkCAwEAAaN8MHowEQYJYIZIAYb4QgEBBAQDAgEG"
+ + "MEcGA1UdIARAMD4wPAYLYIZIAYb4RQEHAQEwLTArBggrBgEFBQcCARYfd3d3LnZlcmlzaWduLmNv"
+ + "bS9yZXBvc2l0b3J5L1JQQTAPBgNVHRMECDAGAQH/AgEAMAsGA1UdDwQEAwIBBjANBgkqhkiG9w0B"
+ + "AQIFAAOBgQCIuDc73dqUNwCtqp/hgQFxHpJqbS/28Z3TymQ43BuYDAeGW4UVag+5SYWklfEXfWe0"
+ + "fy0s3ZpCnsM+tI6q5QsG3vJWKvozx74Z11NMw73I4xe1pElCY+zCphcPXVgaSTyQXFWjZSAA/Rgg"
+ + "5V+CprGoksVYasGNAzzrw80FopCubjCCA/gwggNhoAMCAQICEBbbn/1G1zppD6KsP01bwywwDQYJ"
+ + "KoZIhvcNAQEEBQAwgcwxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMR8wHQYDVQQLExZWZXJpU2ln"
+ + "biBUcnVzdCBOZXR3b3JrMUYwRAYDVQQLEz13d3cudmVyaXNpZ24uY29tL3JlcG9zaXRvcnkvUlBB"
+ + "IEluY29ycC4gQnkgUmVmLixMSUFCLkxURChjKTk4MUgwRgYDVQQDEz9WZXJpU2lnbiBDbGFzcyAx"
+ + "IENBIEluZGl2aWR1YWwgU3Vic2NyaWJlci1QZXJzb25hIE5vdCBWYWxpZGF0ZWQwHhcNMDAxMDAy"
+ + "MDAwMDAwWhcNMDAxMjAxMjM1OTU5WjCCAQcxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMR8wHQYD"
+ + "VQQLExZWZXJpU2lnbiBUcnVzdCBOZXR3b3JrMUYwRAYDVQQLEz13d3cudmVyaXNpZ24uY29tL3Jl"
+ + "cG9zaXRvcnkvUlBBIEluY29ycC4gYnkgUmVmLixMSUFCLkxURChjKTk4MR4wHAYDVQQLExVQZXJz"
+ + "b25hIE5vdCBWYWxpZGF0ZWQxJzAlBgNVBAsTHkRpZ2l0YWwgSUQgQ2xhc3MgMSAtIE1pY3Jvc29m"
+ + "dDETMBEGA1UEAxQKRGF2aWQgUnlhbjElMCMGCSqGSIb3DQEJARYWZGF2aWRAbGl2ZW1lZGlhLmNv"
+ + "bS5hdTCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAqxBsdeNmSvFqhMNwhQgNzM8mdjX9eSXb"
+ + "DawpHtQHjmh0AKJSa3IwUY0VIsyZHuXWktO/CgaMBVPt6OVf/n0R2sQigMP6Y+PhEiS0vCJBL9aK"
+ + "0+pOo2qXrjVBmq+XuCyPTnc+BOSrU26tJsX0P9BYorwySiEGxGanBNATdVL4NdUCAwEAAaOBnDCB"
+ + "mTAJBgNVHRMEAjAAMEQGA1UdIAQ9MDswOQYLYIZIAYb4RQEHAQgwKjAoBggrBgEFBQcCARYcaHR0"
+ + "cHM6Ly93d3cudmVyaXNpZ24uY29tL3JwYTARBglghkgBhvhCAQEEBAMCB4AwMwYDVR0fBCwwKjAo"
+ + "oCagJIYiaHR0cDovL2NybC52ZXJpc2lnbi5jb20vY2xhc3MxLmNybDANBgkqhkiG9w0BAQQFAAOB"
+ + "gQBC8yIIdVGpFTf8/YiL14cMzcmL0nIRm4kGR3U59z7UtcXlfNXXJ8MyaeI/BnXwG/gD5OKYqW6R"
+ + "yca9vZOxf1uoTBl82gInk865ED3Tej6msCqFzZffnSUQvOIeqLxxDlqYRQ6PmW2nAnZeyjcnbI5Y"
+ + "syQSM2fmo7n6qJFP+GbFezGCAkUwggJBAgEBMIHhMIHMMRcwFQYDVQQKEw5WZXJpU2lnbiwgSW5j"
+ + "LjEfMB0GA1UECxMWVmVyaVNpZ24gVHJ1c3QgTmV0d29yazFGMEQGA1UECxM9d3d3LnZlcmlzaWdu"
+ + "LmNvbS9yZXBvc2l0b3J5L1JQQSBJbmNvcnAuIEJ5IFJlZi4sTElBQi5MVEQoYyk5ODFIMEYGA1UE"
+ + "AxM/VmVyaVNpZ24gQ2xhc3MgMSBDQSBJbmRpdmlkdWFsIFN1YnNjcmliZXItUGVyc29uYSBOb3Qg"
+ + "VmFsaWRhdGVkAhAW25/9Rtc6aQ+irD9NW8MsMAkGBSsOAwIaBQCggbowGAYJKoZIhvcNAQkDMQsG"
+ + "CSqGSIb3DQEHATAcBgkqhkiG9w0BCQUxDxcNMDAxMDAyMTczNTE4WjAjBgkqhkiG9w0BCQQxFgQU"
+ + "gZjSaBEY2oxGvlQUIMnxSXhivK8wWwYJKoZIhvcNAQkPMU4wTDAKBggqhkiG9w0DBzAOBggqhkiG"
+ + "9w0DAgICAIAwDQYIKoZIhvcNAwICAUAwBwYFKw4DAgcwDQYIKoZIhvcNAwICASgwBwYFKw4DAh0w"
+ + "DQYJKoZIhvcNAQEBBQAEgYAzk+PU91/ZFfoiuKOECjxEh9fDYE2jfDCheBIgh5gdcCo+sS1WQs8O"
+ + "HreQ9Nop/JdJv1DQMBK6weNBBDoP0EEkRm1XCC144XhXZC82jBZohYmi2WvDbbC//YN58kRMYMyy"
+ + "srrfn4Z9I+6kTriGXkrpGk9Q0LSGjmG2BIsqiF0dvwAAAAAAAA==");
+
+ //
+ // dsaWithSHA1 cert
+ //
+ byte[] cert7 = Base64.decode(
+ "MIIEXAYJKoZIhvcNAQcCoIIETTCCBEkCAQExCzAJBgUrDgMCGgUAMAsGCSqG"
+ + "SIb3DQEHAaCCAsMwggK/MIIB4AIBADCBpwYFKw4DAhswgZ0CQQEkJRHP+mN7"
+ + "d8miwTMN55CUSmo3TO8WGCxgY61TX5k+7NU4XPf1TULjw3GobwaJX13kquPh"
+ + "fVXk+gVy46n4Iw3hAhUBSe/QF4BUj+pJOF9ROBM4u+FEWA8CQQD4mSJbrABj"
+ + "TUWrlnAte8pS22Tq4/FPO7jHSqjijUHfXKTrHL1OEqV3SVWcFy5j/cqBgX/z"
+ + "m8Q12PFp/PjOhh+nMA4xDDAKBgNVBAMTA0lEMzAeFw05NzEwMDEwMDAwMDBa"
+ + "Fw0zODAxMDEwMDAwMDBaMA4xDDAKBgNVBAMTA0lEMzCB8DCBpwYFKw4DAhsw"
+ + "gZ0CQQEkJRHP+mN7d8miwTMN55CUSmo3TO8WGCxgY61TX5k+7NU4XPf1TULj"
+ + "w3GobwaJX13kquPhfVXk+gVy46n4Iw3hAhUBSe/QF4BUj+pJOF9ROBM4u+FE"
+ + "WA8CQQD4mSJbrABjTUWrlnAte8pS22Tq4/FPO7jHSqjijUHfXKTrHL1OEqV3"
+ + "SVWcFy5j/cqBgX/zm8Q12PFp/PjOhh+nA0QAAkEAkYkXLYMtGVGWj9OnzjPn"
+ + "sB9sefSRPrVegZJCZbpW+Iv0/1RP1u04pHG9vtRpIQLjzUiWvLMU9EKQTThc"
+ + "eNMmWDCBpwYFKw4DAhswgZ0CQQEkJRHP+mN7d8miwTMN55CUSmo3TO8WGCxg"
+ + "Y61TX5k+7NU4XPf1TULjw3GobwaJX13kquPhfVXk+gVy46n4Iw3hAhUBSe/Q"
+ + "F4BUj+pJOF9ROBM4u+FEWA8CQQD4mSJbrABjTUWrlnAte8pS22Tq4/FPO7jH"
+ + "SqjijUHfXKTrHL1OEqV3SVWcFy5j/cqBgX/zm8Q12PFp/PjOhh+nAy8AMCwC"
+ + "FBY3dBSdeprGcqpr6wr3xbG+6WW+AhRMm/facKJNxkT3iKgJbp7R8Xd3QTGC"
+ + "AWEwggFdAgEBMBMwDjEMMAoGA1UEAxMDSUQzAgEAMAkGBSsOAwIaBQCgXTAY"
+ + "BgkqhkiG9w0BCQMxCwYJKoZIhvcNAQcBMBwGCSqGSIb3DQEJBTEPFw0wMjA1"
+ + "MjQyMzEzMDdaMCMGCSqGSIb3DQEJBDEWBBS4WMsoJhf7CVbZYCFcjoTRzPkJ"
+ + "xjCBpwYFKw4DAhswgZ0CQQEkJRHP+mN7d8miwTMN55CUSmo3TO8WGCxgY61T"
+ + "X5k+7NU4XPf1TULjw3GobwaJX13kquPhfVXk+gVy46n4Iw3hAhUBSe/QF4BU"
+ + "j+pJOF9ROBM4u+FEWA8CQQD4mSJbrABjTUWrlnAte8pS22Tq4/FPO7jHSqji"
+ + "jUHfXKTrHL1OEqV3SVWcFy5j/cqBgX/zm8Q12PFp/PjOhh+nBC8wLQIVALID"
+ + "dt+MHwawrDrwsO1Z6sXBaaJsAhRaKssrpevmLkbygKPV07XiAKBG02Zvb2Jh"
+ + "cg==");
+
+ //
+ // testcrl.pem
+ //
+ byte[] crl1 = Base64.decode(
+ "MIICjTCCAfowDQYJKoZIhvcNAQECBQAwXzELMAkGA1UEBhMCVVMxIDAeBgNVBAoT"
+ + "F1JTQSBEYXRhIFNlY3VyaXR5LCBJbmMuMS4wLAYDVQQLEyVTZWN1cmUgU2VydmVy"
+ + "IENlcnRpZmljYXRpb24gQXV0aG9yaXR5Fw05NTA1MDIwMjEyMjZaFw05NTA2MDEw"
+ + "MDAxNDlaMIIBaDAWAgUCQQAABBcNOTUwMjAxMTcyNDI2WjAWAgUCQQAACRcNOTUw"
+ + "MjEwMDIxNjM5WjAWAgUCQQAADxcNOTUwMjI0MDAxMjQ5WjAWAgUCQQAADBcNOTUw"
+ + "MjI1MDA0NjQ0WjAWAgUCQQAAGxcNOTUwMzEzMTg0MDQ5WjAWAgUCQQAAFhcNOTUw"
+ + "MzE1MTkxNjU0WjAWAgUCQQAAGhcNOTUwMzE1MTk0MDQxWjAWAgUCQQAAHxcNOTUw"
+ + "MzI0MTk0NDMzWjAWAgUCcgAABRcNOTUwMzI5MjAwNzExWjAWAgUCcgAAERcNOTUw"
+ + "MzMwMDIzNDI2WjAWAgUCQQAAIBcNOTUwNDA3MDExMzIxWjAWAgUCcgAAHhcNOTUw"
+ + "NDA4MDAwMjU5WjAWAgUCcgAAQRcNOTUwNDI4MTcxNzI0WjAWAgUCcgAAOBcNOTUw"
+ + "NDI4MTcyNzIxWjAWAgUCcgAATBcNOTUwNTAyMDIxMjI2WjANBgkqhkiG9w0BAQIF"
+ + "AAN+AHqOEJXSDejYy0UwxxrH/9+N2z5xu/if0J6qQmK92W0hW158wpJg+ovV3+wQ"
+ + "wvIEPRL2rocL0tKfAsVq1IawSJzSNgxG0lrcla3MrJBnZ4GaZDu4FutZh72MR3Gt"
+ + "JaAL3iTJHJD55kK2D/VoyY1djlsPuNh6AEgdVwFAyp0v");
+
+ //
+ // ecdsa cert with extra octet string.
+ //
+ byte[] oldEcdsa = Base64.decode(
+ "MIICljCCAkCgAwIBAgIBATALBgcqhkjOPQQBBQAwgY8xCzAJBgNVBAYTAkFVMSgwJ"
+ + "gYDVQQKEx9UaGUgTGVnaW9uIG9mIHRoZSBCb3VuY3kgQ2FzdGxlMRIwEAYDVQQHEw"
+ + "lNZWxib3VybmUxETAPBgNVBAgTCFZpY3RvcmlhMS8wLQYJKoZIhvcNAQkBFiBmZWV"
+ + "kYmFjay1jcnlwdG9AYm91bmN5Y2FzdGxlLm9yZzAeFw0wMTEyMDcwMTAwMDRaFw0w"
+ + "MTEyMDcwMTAxNDRaMIGPMQswCQYDVQQGEwJBVTEoMCYGA1UEChMfVGhlIExlZ2lvb"
+ + "iBvZiB0aGUgQm91bmN5IENhc3RsZTESMBAGA1UEBxMJTWVsYm91cm5lMREwDwYDVQ"
+ + "QIEwhWaWN0b3JpYTEvMC0GCSqGSIb3DQEJARYgZmVlZGJhY2stY3J5cHRvQGJvdW5"
+ + "jeWNhc3RsZS5vcmcwgeQwgb0GByqGSM49AgEwgbECAQEwKQYHKoZIzj0BAQIef///"
+ + "////////////f///////gAAAAAAAf///////MEAEHn///////////////3///////"
+ + "4AAAAAAAH///////AQeawFsO9zxiUHQ1lSSFHXKcanbL7J9HTd5YYXClCwKBB8CD/"
+ + "qWPNyogWzMM7hkK+35BcPTWFc9Pyf7vTs8uaqvAh5///////////////9///+eXpq"
+ + "fXZBx+9FSJoiQnQsDIgAEHwJbbcU7xholSP+w9nFHLebJUhqdLSU05lq/y9X+DHAw"
+ + "CwYHKoZIzj0EAQUAA0MAMEACHnz6t4UNoVROp74ma4XNDjjGcjaqiIWPZLK8Bdw3G"
+ + "QIeLZ4j3a6ividZl344UH+UPUE7xJxlYGuy7ejTsqRR");
+
+ byte[] keyUsage = Base64.decode(
+ "MIIE7TCCBFagAwIBAgIEOAOR7jANBgkqhkiG9w0BAQQFADCByTELMAkGA1UE"
+ + "BhMCVVMxFDASBgNVBAoTC0VudHJ1c3QubmV0MUgwRgYDVQQLFD93d3cuZW50"
+ + "cnVzdC5uZXQvQ2xpZW50X0NBX0luZm8vQ1BTIGluY29ycC4gYnkgcmVmLiBs"
+ + "aW1pdHMgbGlhYi4xJTAjBgNVBAsTHChjKSAxOTk5IEVudHJ1c3QubmV0IExp"
+ + "bWl0ZWQxMzAxBgNVBAMTKkVudHJ1c3QubmV0IENsaWVudCBDZXJ0aWZpY2F0"
+ + "aW9uIEF1dGhvcml0eTAeFw05OTEwMTIxOTI0MzBaFw0xOTEwMTIxOTU0MzBa"
+ + "MIHJMQswCQYDVQQGEwJVUzEUMBIGA1UEChMLRW50cnVzdC5uZXQxSDBGBgNV"
+ + "BAsUP3d3dy5lbnRydXN0Lm5ldC9DbGllbnRfQ0FfSW5mby9DUFMgaW5jb3Jw"
+ + "LiBieSByZWYuIGxpbWl0cyBsaWFiLjElMCMGA1UECxMcKGMpIDE5OTkgRW50"
+ + "cnVzdC5uZXQgTGltaXRlZDEzMDEGA1UEAxMqRW50cnVzdC5uZXQgQ2xpZW50"
+ + "IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MIGdMA0GCSqGSIb3DQEBAQUAA4GL"
+ + "ADCBhwKBgQDIOpleMRffrCdvkHvkGf9FozTC28GoT/Bo6oT9n3V5z8GKUZSv"
+ + "x1cDR2SerYIbWtp/N3hHuzeYEpbOxhN979IMMFGpOZ5V+Pux5zDeg7K6PvHV"
+ + "iTs7hbqqdCz+PzFur5GVbgbUB01LLFZHGARS2g4Qk79jkJvh34zmAqTmT173"
+ + "iwIBA6OCAeAwggHcMBEGCWCGSAGG+EIBAQQEAwIABzCCASIGA1UdHwSCARkw"
+ + "ggEVMIHkoIHhoIHepIHbMIHYMQswCQYDVQQGEwJVUzEUMBIGA1UEChMLRW50"
+ + "cnVzdC5uZXQxSDBGBgNVBAsUP3d3dy5lbnRydXN0Lm5ldC9DbGllbnRfQ0Ff"
+ + "SW5mby9DUFMgaW5jb3JwLiBieSByZWYuIGxpbWl0cyBsaWFiLjElMCMGA1UE"
+ + "CxMcKGMpIDE5OTkgRW50cnVzdC5uZXQgTGltaXRlZDEzMDEGA1UEAxMqRW50"
+ + "cnVzdC5uZXQgQ2xpZW50IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MQ0wCwYD"
+ + "VQQDEwRDUkwxMCygKqAohiZodHRwOi8vd3d3LmVudHJ1c3QubmV0L0NSTC9D"
+ + "bGllbnQxLmNybDArBgNVHRAEJDAigA8xOTk5MTAxMjE5MjQzMFqBDzIwMTkx"
+ + "MDEyMTkyNDMwWjALBgNVHQ8EBAMCAQYwHwYDVR0jBBgwFoAUxPucKXuXzUyW"
+ + "/O5bs8qZdIuV6kwwHQYDVR0OBBYEFMT7nCl7l81MlvzuW7PKmXSLlepMMAwG"
+ + "A1UdEwQFMAMBAf8wGQYJKoZIhvZ9B0EABAwwChsEVjQuMAMCBJAwDQYJKoZI"
+ + "hvcNAQEEBQADgYEAP66K8ddmAwWePvrqHEa7pFuPeJoSSJn59DXeDDYHAmsQ"
+ + "OokUgZwxpnyyQbJq5wcBoUv5nyU7lsqZwz6hURzzwy5E97BnRqqS5TvaHBkU"
+ + "ODDV4qIxJS7x7EU47fgGWANzYrAQMY9Av2TgXD7FTx/aEkP/TOYGJqibGapE"
+ + "PHayXOw=");
+
+ byte[] nameCert = Base64.decode(
+ "MIIEFjCCA3+gAwIBAgIEdS8BozANBgkqhkiG9w0BAQUFADBKMQswCQYDVQQGEwJE"+
+ "RTERMA8GA1UEChQIREFURVYgZUcxKDAMBgcCggYBCgcUEwExMBgGA1UEAxQRQ0Eg"+
+ "REFURVYgRDAzIDE6UE4wIhgPMjAwMTA1MTAxMDIyNDhaGA8yMDA0MDUwOTEwMjI0"+
+ "OFowgYQxCzAJBgNVBAYTAkRFMQ8wDQYDVQQIFAZCYXllcm4xEjAQBgNVBAcUCU7I"+
+ "dXJuYmVyZzERMA8GA1UEChQIREFURVYgZUcxHTAbBgNVBAUTFDAwMDAwMDAwMDA4"+
+ "OTU3NDM2MDAxMR4wHAYDVQQDFBVEaWV0bWFyIFNlbmdlbmxlaXRuZXIwgaEwDQYJ"+
+ "KoZIhvcNAQEBBQADgY8AMIGLAoGBAJLI/LJLKaHoMk8fBECW/od8u5erZi6jI8Ug"+
+ "C0a/LZyQUO/R20vWJs6GrClQtXB+AtfiBSnyZOSYzOdfDI8yEKPEv8qSuUPpOHps"+
+ "uNCFdLZF1vavVYGEEWs2+y+uuPmg8q1oPRyRmUZ+x9HrDvCXJraaDfTEd9olmB/Z"+
+ "AuC/PqpjAgUAwAAAAaOCAcYwggHCMAwGA1UdEwEB/wQCMAAwDwYDVR0PAQH/BAUD"+
+ "AwdAADAxBgNVHSAEKjAoMCYGBSskCAEBMB0wGwYIKwYBBQUHAgEWD3d3dy56cy5k"+
+ "YXRldi5kZTApBgNVHREEIjAggR5kaWV0bWFyLnNlbmdlbmxlaXRuZXJAZGF0ZXYu"+
+ "ZGUwgYQGA1UdIwR9MHuhc6RxMG8xCzAJBgNVBAYTAkRFMT0wOwYDVQQKFDRSZWd1"+
+ "bGllcnVuZ3NiZWjIb3JkZSBmyHVyIFRlbGVrb21tdW5pa2F0aW9uIHVuZCBQb3N0"+
+ "MSEwDAYHAoIGAQoHFBMBMTARBgNVBAMUCjVSLUNBIDE6UE6CBACm8LkwDgYHAoIG"+
+ "AQoMAAQDAQEAMEcGA1UdHwRAMD4wPKAUoBKGEHd3dy5jcmwuZGF0ZXYuZGWiJKQi"+
+ "MCAxCzAJBgNVBAYTAkRFMREwDwYDVQQKFAhEQVRFViBlRzAWBgUrJAgDBAQNMAsT"+
+ "A0VVUgIBBQIBATAdBgNVHQ4EFgQUfv6xFP0xk7027folhy+ziZvBJiwwLAYIKwYB"+
+ "BQUHAQEEIDAeMBwGCCsGAQUFBzABhhB3d3cuZGlyLmRhdGV2LmRlMA0GCSqGSIb3"+
+ "DQEBBQUAA4GBAEOVX6uQxbgtKzdgbTi6YLffMftFr2mmNwch7qzpM5gxcynzgVkg"+
+ "pnQcDNlm5AIbS6pO8jTCLfCd5TZ5biQksBErqmesIl3QD+VqtB+RNghxectZ3VEs"+
+ "nCUtcE7tJ8O14qwCb3TxS9dvIUFiVi4DjbxX46TdcTbTaK8/qr6AIf+l");
+
+ byte[] probSelfSignedCert = Base64.decode(
+ "MIICxTCCAi6gAwIBAgIQAQAAAAAAAAAAAAAAAAAAATANBgkqhkiG9w0BAQUFADBF"
+ + "MScwJQYDVQQKEx4gRElSRUNUSU9OIEdFTkVSQUxFIERFUyBJTVBPVFMxGjAYBgNV"
+ + "BAMTESBBQyBNSU5FRkkgQiBURVNUMB4XDTA0MDUwNzEyMDAwMFoXDTE0MDUwNzEy"
+ + "MDAwMFowRTEnMCUGA1UEChMeIERJUkVDVElPTiBHRU5FUkFMRSBERVMgSU1QT1RT"
+ + "MRowGAYDVQQDExEgQUMgTUlORUZJIEIgVEVTVDCBnzANBgkqhkiG9w0BAQEFAAOB"
+ + "jQAwgYkCgYEAveoCUOAukZdcFCs2qJk76vSqEX0ZFzHqQ6faBPZWjwkgUNwZ6m6m"
+ + "qWvvyq1cuxhoDvpfC6NXILETawYc6MNwwxsOtVVIjuXlcF17NMejljJafbPximEt"
+ + "DQ4LcQeSp4K7FyFlIAMLyt3BQ77emGzU5fjFTvHSUNb3jblx0sV28c0CAwEAAaOB"
+ + "tTCBsjAfBgNVHSMEGDAWgBSEJ4bLbvEQY8cYMAFKPFD1/fFXlzAdBgNVHQ4EFgQU"
+ + "hCeGy27xEGPHGDABSjxQ9f3xV5cwDgYDVR0PAQH/BAQDAgEGMBEGCWCGSAGG+EIB"
+ + "AQQEAwIBBjA8BgNVHR8ENTAzMDGgL6AthitodHRwOi8vYWRvbmlzLnBrNy5jZXJ0"
+ + "cGx1cy5uZXQvZGdpLXRlc3QuY3JsMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcN"
+ + "AQEFBQADgYEAmToHJWjd3+4zknfsP09H6uMbolHNGG0zTS2lrLKpzcmkQfjhQpT9"
+ + "LUTBvfs1jdjo9fGmQLvOG+Sm51Rbjglb8bcikVI5gLbclOlvqLkm77otjl4U4Z2/"
+ + "Y0vP14Aov3Sn3k+17EfReYUZI4liuB95ncobC4e8ZM++LjQcIM0s+Vs=");
+
+
+ byte[] gost34102001base = Base64.decode(
+ "MIIB1DCCAYECEEjpVKXP6Wn1yVz3VeeDQa8wCgYGKoUDAgIDBQAwbTEfMB0G"
+ + "A1UEAwwWR29zdFIzNDEwLTIwMDEgZXhhbXBsZTESMBAGA1UECgwJQ3J5cHRv"
+ + "UHJvMQswCQYDVQQGEwJSVTEpMCcGCSqGSIb3DQEJARYaR29zdFIzNDEwLTIw"
+ + "MDFAZXhhbXBsZS5jb20wHhcNMDUwMjAzMTUxNjQ2WhcNMTUwMjAzMTUxNjQ2"
+ + "WjBtMR8wHQYDVQQDDBZHb3N0UjM0MTAtMjAwMSBleGFtcGxlMRIwEAYDVQQK"
+ + "DAlDcnlwdG9Qcm8xCzAJBgNVBAYTAlJVMSkwJwYJKoZIhvcNAQkBFhpHb3N0"
+ + "UjM0MTAtMjAwMUBleGFtcGxlLmNvbTBjMBwGBiqFAwICEzASBgcqhQMCAiQA"
+ + "BgcqhQMCAh4BA0MABECElWh1YAIaQHUIzROMMYks/eUFA3pDXPRtKw/nTzJ+"
+ + "V4/rzBa5lYgD0Jp8ha4P5I3qprt+VsfLsN8PZrzK6hpgMAoGBiqFAwICAwUA"
+ + "A0EAHw5dw/aw/OiNvHyOE65kvyo4Hp0sfz3csM6UUkp10VO247ofNJK3tsLb"
+ + "HOLjUaqzefrlGb11WpHYrvWFg+FcLA==");
+
+ private final byte[] emptyDNCert = Base64.decode(
+ "MIICfTCCAeagAwIBAgIBajANBgkqhkiG9w0BAQQFADB8MQswCQYDVQQGEwJVUzEMMAoGA1UEChMD"
+ + "Q0RXMQkwBwYDVQQLEwAxCTAHBgNVBAcTADEJMAcGA1UECBMAMRowGAYDVQQDExFUZW1wbGFyIFRl"
+ + "c3QgMTAyNDEiMCAGCSqGSIb3DQEJARYTdGVtcGxhcnRlc3RAY2R3LmNvbTAeFw0wNjA1MjIwNTAw"
+ + "MDBaFw0xMDA1MjIwNTAwMDBaMHwxCzAJBgNVBAYTAlVTMQwwCgYDVQQKEwNDRFcxCTAHBgNVBAsT"
+ + "ADEJMAcGA1UEBxMAMQkwBwYDVQQIEwAxGjAYBgNVBAMTEVRlbXBsYXIgVGVzdCAxMDI0MSIwIAYJ"
+ + "KoZIhvcNAQkBFhN0ZW1wbGFydGVzdEBjZHcuY29tMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKB"
+ + "gQDH3aJpJBfM+A3d84j5YcU6zEQaQ76u5xO9NSBmHjZykKS2kCcUqPpvVOPDA5WgV22dtKPh+lYV"
+ + "iUp7wyCVwAKibq8HIbihHceFqMKzjwC639rMoDJ7bi/yzQWz1Zg+075a4FGPlUKn7Yfu89wKkjdW"
+ + "wDpRPXc/agqBnrx5pJTXzQIDAQABow8wDTALBgNVHQ8EBAMCALEwDQYJKoZIhvcNAQEEBQADgYEA"
+ + "RRsRsjse3i2/KClFVd6YLZ+7K1BE0WxFyY2bbytkwQJSxvv3vLSuweFUbhNxutb68wl/yW4GLy4b"
+ + "1QdyswNxrNDXTuu5ILKhRDDuWeocz83aG2KGtr3JlFyr3biWGEyn5WUOE6tbONoQDJ0oPYgI6CAc"
+ + "EHdUp0lioOCt6UOw7Cs=");
+
+ private AsymmetricKeyParameter dudPublicKey = new AsymmetricKeyParameter(true)
+ {
+ public String getAlgorithm()
+ {
+ return null;
+ }
+
+ public String getFormat()
+ {
+ return null;
+ }
+
+ public byte[] getEncoded()
+ {
+ return null;
+ }
+
+ };
+
+ public String getName()
+ {
+ return "CertTest";
+ }
+
+ public void checkCertificate(
+ int id,
+ byte[] bytes)
+ {
+ try
+ {
+ X509CertificateHolder certHldr = new X509CertificateHolder(bytes);
+
+ SubjectPublicKeyInfo k = certHldr.getSubjectPublicKeyInfo();
+ // System.out.println(cert);
+ }
+ catch (Exception e)
+ {
+ fail(e.toString());
+ }
+ }
+ /*
+ public void checkNameCertificate(
+ int id,
+ byte[] bytes)
+ {
+ ByteArrayInputStream bIn;
+ String dump = "";
+
+ try
+ {
+ bIn = new ByteArrayInputStream(bytes);
+
+ CertificateFactory fact = CertificateFactory.getInstance("X.509", "LKBX-BC");
+
+ X509Certificate cert = (X509Certificate)fact.generateCertificate(bIn);
+
+ AsymmetricKeyParameter k = cert.getAsymmetricKeyParameter();
+ if (!cert.getIssuerDN().toString().equals("C=DE,O=DATEV eG,0.2.262.1.10.7.20=1+CN=CA DATEV D03 1:PN"))
+ {
+ fail(id + " failed - name test.");
+ }
+ // System.out.println(cert);
+ }
+ catch (Exception e)
+ {
+ fail(dump + System.getProperty("line.separator") + getName() + ": "+ id + " failed - exception " + e.toString(), e);
+ }
+
+ }
+ */
+ public void checkKeyUsage(
+ int id,
+ byte[] bytes)
+ throws IOException
+ {
+
+ X509CertificateHolder certHld = new X509CertificateHolder(bytes);
+
+ if ((DERBitString.getInstance(certHld.getExtension(Extension.keyUsage).getParsedValue()).getBytes()[0] & 0x01) != 0)
+ {
+ fail("error generating cert - key usage wrong.");
+ }
+
+
+ }
+
+
+ public void checkSelfSignedCertificate(
+ int id,
+ byte[] bytes)
+ throws OperatorCreationException, IOException, CertException
+ {
+
+ X509CertificateHolder certHolder = new X509CertificateHolder(bytes);
+
+ assertTrue(certHolder.isSignatureValid(new BcRSAContentVerifierProviderBuilder(digAlgFinder).build(certHolder)));
+
+
+ }
+
+ /**
+ * we generate a self signed certificate for the sake of testing - RSA
+ */
+ public void checkCreation1()
+ throws Exception
+ {
+ //
+ // a sample key pair.
+ //
+ AsymmetricKeyParameter pubKey = new RSAKeyParameters(
+ false,
+ new BigInteger("b4a7e46170574f16a97082b22be58b6a2a629798419be12872a4bdba626cfae9900f76abfb12139dce5de56564fab2b6543165a040c606887420e33d91ed7ed7", 16),
+ new BigInteger("11", 16));
+
+ AsymmetricKeyParameter privKey = new RSAPrivateCrtKeyParameters(
+ new BigInteger("b4a7e46170574f16a97082b22be58b6a2a629798419be12872a4bdba626cfae9900f76abfb12139dce5de56564fab2b6543165a040c606887420e33d91ed7ed7", 16),
+ new BigInteger("11", 16),
+ new BigInteger("9f66f6b05410cd503b2709e88115d55daced94d1a34d4e32bf824d0dde6028ae79c5f07b580f5dce240d7111f7ddb130a7945cd7d957d1920994da389f490c89", 16),
+ new BigInteger("c0a0758cdf14256f78d4708c86becdead1b50ad4ad6c5c703e2168fbf37884cb", 16),
+ new BigInteger("f01734d7960ea60070f1b06f2bb81bfac48ff192ae18451d5e56c734a5aab8a5", 16),
+ new BigInteger("b54bb9edff22051d9ee60f9351a48591b6500a319429c069a3e335a1d6171391", 16),
+ new BigInteger("d3d83daf2a0cecd3367ae6f8ae1aeb82e9ac2f816c6fc483533d8297dd7884cd", 16),
+ new BigInteger("b8f52fc6f38593dabb661d3f50f8897f8106eee68b1bce78a95b132b4e5b5d19", 16));
+
+ //
+ // distinguished name table.
+ //
+ X500NameBuilder builder = new X500NameBuilder(RFC4519Style.INSTANCE);
+
+ builder.addRDN(RFC4519Style.c, "AU");
+ builder.addRDN(RFC4519Style.o, "The Legion of the Bouncy Castle");
+ builder.addRDN(RFC4519Style.l, "Melbourne");
+ builder.addRDN(RFC4519Style.st, "Victoria");
+ builder.addRDN(PKCSObjectIdentifiers.pkcs_9_at_emailAddress, "feedback-crypto@bouncycastle.org");
+
+ //
+ // extensions
+ //
+
+ //
+ // create the certificate - version 3 - without extensions
+ //
+ AlgorithmIdentifier sigAlg = sigAlgFinder.find("SHA256WithRSAEncryption");
+ ContentSigner sigGen = new BcRSAContentSignerBuilder(sigAlg, digAlgFinder.find(sigAlg)).build(privKey);
+ X509v3CertificateBuilder certGen = new BcX509v3CertificateBuilder(builder.build(), BigInteger.valueOf(1), new Date(System.currentTimeMillis() - 50000), new Date(System.currentTimeMillis() + 50000),builder.build(), pubKey);
+
+ X509CertificateHolder certH = certGen.build(sigGen);
+
+ assertTrue(certH.isValidOn(new Date()));
+
+ ContentVerifierProvider contentVerifierProvider = new BcRSAContentVerifierProviderBuilder(new DefaultDigestAlgorithmIdentifierFinder()).build(pubKey);
+
+ assertTrue(certH.isSignatureValid(contentVerifierProvider));
+
+ X509Certificate cert = new JcaX509CertificateConverter().getCertificate(certH);
+ Set dummySet = cert.getNonCriticalExtensionOIDs();
+ if (dummySet != null)
+ {
+ fail("non-critical oid set should be null");
+ }
+ dummySet = cert.getCriticalExtensionOIDs();
+ if (dummySet != null)
+ {
+ fail("critical oid set should be null");
+ }
+
+ //
+ // create the certificate - version 3 - with extensions
+ //
+ sigGen = new BcRSAContentSignerBuilder(sigAlgFinder.find("MD5WithRSA"), digAlgFinder.find(sigAlgFinder.find("MD5withRSA"))).build(privKey);
+ certGen = new BcX509v3CertificateBuilder(builder.build(), BigInteger.valueOf(1)
+ , new Date(System.currentTimeMillis() - 50000)
+ , new Date(System.currentTimeMillis() + 50000)
+ , builder.build()
+ , pubKey)
+ .addExtension(new ASN1ObjectIdentifier("2.5.29.15"), true,
+ new KeyUsage(KeyUsage.encipherOnly))
+ .addExtension(new ASN1ObjectIdentifier("2.5.29.37"), true,
+ new DERSequence(KeyPurposeId.anyExtendedKeyUsage))
+ .addExtension(new ASN1ObjectIdentifier("2.5.29.17"), true,
+ new GeneralNames(new GeneralName(GeneralName.rfc822Name, "test@test.test")));
+
+ X509CertificateHolder certHolder = certGen.build(sigGen);
+
+ assertTrue(certHolder.isValidOn(new Date()));
+
+ contentVerifierProvider = new BcRSAContentVerifierProviderBuilder(digAlgFinder).build(pubKey);
+ if (!certHolder.isSignatureValid(contentVerifierProvider))
+ {
+ fail("signature test failed");
+ }
+
+ ByteArrayInputStream bIn = new ByteArrayInputStream(certHolder.getEncoded());
+ CertificateFactory certFact = CertificateFactory.getInstance("X.509");
+
+ cert = (X509Certificate)certFact.generateCertificate(bIn);
+
+ if (!cert.getKeyUsage()[7])
+ {
+ fail("error generating cert - key usage wrong.");
+ }
+
+ List l = cert.getExtendedKeyUsage();
+ if (!l.get(0).equals(KeyPurposeId.anyExtendedKeyUsage.getId()))
+ {
+ fail("failed extended key usage test");
+ }
+
+ Collection c = cert.getSubjectAlternativeNames();
+ Iterator it = c.iterator();
+ while (it.hasNext())
+ {
+ List gn = (List)it.next();
+ if (!gn.get(1).equals("test@test.test"))
+ {
+ fail("failed subject alternative names test");
+ }
+ }
+
+ // System.out.println(cert);
+
+ //
+ // create the certificate - version 1
+ //
+ sigGen = new BcRSAContentSignerBuilder(sigAlgFinder.find("MD5WithRSA"), digAlgFinder.find(sigAlgFinder.find("MD5withRSA"))).build(privKey);
+ X509v1CertificateBuilder certGen1 = new BcX509v1CertificateBuilder(builder.build(), BigInteger.valueOf(1), new Date(System.currentTimeMillis() - 50000),new Date(System.currentTimeMillis() + 50000),builder.build(),pubKey);
+
+ cert = new JcaX509CertificateConverter().getCertificate(certGen1.build(sigGen));
+
+ assertTrue(certHolder.isValidOn(new Date()));
+
+ contentVerifierProvider = new BcRSAContentVerifierProviderBuilder(new DefaultDigestAlgorithmIdentifierFinder()).build(pubKey);
+
+ assertTrue(certHolder.isSignatureValid(contentVerifierProvider));
+
+ bIn = new ByteArrayInputStream(cert.getEncoded());
+ certFact = CertificateFactory.getInstance("X.509");
+
+ cert = (X509Certificate)certFact.generateCertificate(bIn);
+
+ // System.out.println(cert);
+ if (!cert.getIssuerDN().equals(cert.getSubjectDN()))
+ {
+ fail("name comparison fails");
+ }
+
+//
+ // a lightweight key pair.
+ //
+ RSAKeyParameters lwPubKey = new RSAKeyParameters(
+ false,
+ new BigInteger("b4a7e46170574f16a97082b22be58b6a2a629798419be12872a4bdba626cfae9900f76abfb12139dce5de56564fab2b6543165a040c606887420e33d91ed7ed7", 16),
+ new BigInteger("11", 16));
+
+ RSAPrivateCrtKeyParameters lwPrivKey = new RSAPrivateCrtKeyParameters(
+ new BigInteger("b4a7e46170574f16a97082b22be58b6a2a629798419be12872a4bdba626cfae9900f76abfb12139dce5de56564fab2b6543165a040c606887420e33d91ed7ed7", 16),
+ new BigInteger("11", 16),
+ new BigInteger("9f66f6b05410cd503b2709e88115d55daced94d1a34d4e32bf824d0dde6028ae79c5f07b580f5dce240d7111f7ddb130a7945cd7d957d1920994da389f490c89", 16),
+ new BigInteger("c0a0758cdf14256f78d4708c86becdead1b50ad4ad6c5c703e2168fbf37884cb", 16),
+ new BigInteger("f01734d7960ea60070f1b06f2bb81bfac48ff192ae18451d5e56c734a5aab8a5", 16),
+ new BigInteger("b54bb9edff22051d9ee60f9351a48591b6500a319429c069a3e335a1d6171391", 16),
+ new BigInteger("d3d83daf2a0cecd3367ae6f8ae1aeb82e9ac2f816c6fc483533d8297dd7884cd", 16),
+ new BigInteger("b8f52fc6f38593dabb661d3f50f8897f8106eee68b1bce78a95b132b4e5b5d19", 16));
+
+ //
+ // distinguished name table.
+ //
+ builder = new X500NameBuilder(RFC4519Style.INSTANCE);
+
+ builder.addRDN(RFC4519Style.c, "AU");
+ builder.addRDN(RFC4519Style.o, "The Legion of the Bouncy Castle");
+ builder.addRDN(RFC4519Style.l, "Melbourne");
+ builder.addRDN(RFC4519Style.st, "Victoria");
+ builder.addRDN(PKCSObjectIdentifiers.pkcs_9_at_emailAddress, "feedback-crypto@bouncycastle.org");
+
+ //
+ // extensions
+ //
+
+ //
+ // create the certificate - version 3 - without extensions
+ //
+ AlgorithmIdentifier sigAlgId = new DefaultSignatureAlgorithmIdentifierFinder().find("SHA256WithRSAEncryption");
+ AlgorithmIdentifier digAlgId = new DefaultDigestAlgorithmIdentifierFinder().find(sigAlgId);
+
+ sigGen = new BcRSAContentSignerBuilder(sigAlgId, digAlgId).build(lwPrivKey);
+ SubjectPublicKeyInfo pubInfo = SubjectPublicKeyInfoFactory.createSubjectPublicKeyInfo(lwPubKey);
+ certGen = new X509v3CertificateBuilder(builder.build(), BigInteger.valueOf(1), new Date(System.currentTimeMillis() - 50000), new Date(System.currentTimeMillis() + 50000), builder.build(), pubInfo);
+
+ certHolder = certGen.build(sigGen);
+
+ assertTrue(certHolder.isValidOn(new Date()));
+
+ contentVerifierProvider = new BcRSAContentVerifierProviderBuilder(new DefaultDigestAlgorithmIdentifierFinder()).build(lwPubKey);
+
+ assertTrue(certHolder.isSignatureValid(contentVerifierProvider));
+
+ if (!certHolder.isSignatureValid(contentVerifierProvider))
+ {
+ fail("lw sig verification failed");
+ }
+ }
+
+ /**
+ * we generate a self signed certificate for the sake of testing - DSA
+ */
+ public void checkCreation2()
+ throws Exception
+ {
+ //
+ // set up the keys
+ //
+ AsymmetricKeyParameter privKey;
+ AsymmetricKeyParameter pubKey;
+
+ AsymmetricCipherKeyPairGenerator kpg = new DSAKeyPairGenerator();
+ BigInteger r = new BigInteger("68076202252361894315274692543577577550894681403");
+ BigInteger s = new BigInteger("1089214853334067536215539335472893651470583479365");
+ DSAParametersGenerator pGen = new DSAParametersGenerator();
+
+ pGen.init(512, 80, new SecureRandom());
+
+ DSAParameters params = pGen.generateParameters();
+ DSAKeyGenerationParameters genParam = new DSAKeyGenerationParameters(new SecureRandom(), params);
+
+ kpg.init(genParam);
+
+ AsymmetricCipherKeyPair pair = kpg.generateKeyPair();
+
+ privKey = (AsymmetricKeyParameter)pair.getPrivate();
+ pubKey = (AsymmetricKeyParameter)pair.getPublic();
+
+ //
+ // distinguished name table.
+ //
+ X500NameBuilder builder = createStdBuilder();
+
+ //
+ // extensions
+ //
+
+ //
+ // create the certificate - version 3
+ //
+ AlgorithmIdentifier sigAlgId = sigAlgFinder.find("SHA1withDSA");
+ AlgorithmIdentifier digAlgId = digAlgFinder.find(sigAlgId);
+
+ ContentSigner sigGen = new BcDSAContentSignerBuilder(sigAlgId, digAlgId).build(privKey);
+ X509v3CertificateBuilder certGen = new BcX509v3CertificateBuilder(builder.build(),BigInteger.valueOf(1),new Date(System.currentTimeMillis() - 50000),new Date(System.currentTimeMillis() + 50000),builder.build(),pubKey);
+
+
+ X509CertificateHolder cert = certGen.build(sigGen);
+
+ assertTrue(cert.isValidOn(new Date()));
+
+ assertTrue(cert.isSignatureValid(new BcDSAContentVerifierProviderBuilder(digAlgFinder).build(pubKey)));
+
+
+ //
+ // create the certificate - version 1
+ //
+ sigAlgId = sigAlgFinder.find("SHA1withDSA");
+ digAlgId = digAlgFinder.find(sigAlgId);
+
+ sigGen = new BcDSAContentSignerBuilder(sigAlgId, digAlgId).build(privKey);
+ X509v1CertificateBuilder certGen1 = new BcX509v1CertificateBuilder(builder.build(),BigInteger.valueOf(1),new Date(System.currentTimeMillis() - 50000),new Date(System.currentTimeMillis() + 50000),builder.build(),pubKey);
+
+ cert = certGen1.build(sigGen);
+
+ assertTrue(cert.isValidOn(new Date()));
+
+ assertTrue(cert.isSignatureValid(new BcDSAContentVerifierProviderBuilder(digAlgFinder).build(pubKey)));
+
+ ByteArrayInputStream bIn = new ByteArrayInputStream(cert.getEncoded());
+ CertificateFactory fact = CertificateFactory.getInstance("X.509");
+
+ X509Certificate x509cert = (X509Certificate)fact.generateCertificate(bIn);
+
+ //System.out.println(cert);
+ }
+
+ private X500NameBuilder createStdBuilder()
+ {
+ X500NameBuilder builder = new X500NameBuilder(RFC4519Style.INSTANCE);
+
+ builder.addRDN(RFC4519Style.c, "AU");
+ builder.addRDN(RFC4519Style.o, "The Legion of the Bouncy Castle");
+ builder.addRDN(RFC4519Style.l, "Melbourne");
+ builder.addRDN(RFC4519Style.st, "Victoria");
+ builder.addRDN(PKCSObjectIdentifiers.pkcs_9_at_emailAddress, "feedback-crypto@bouncycastle.org");
+
+ return builder;
+ }
+
+ private void checkCRL(
+ int id,
+ byte[] bytes)
+ {
+ String dump = "";
+
+ try
+ {
+ X509CRLHolder crlHolder = new X509CRLHolder(bytes);
+
+ }
+ catch (Exception e)
+ {
+ fail(dump + System.getProperty("line.separator") + getName() + ": "+ id + " failed - exception " + e.toString());
+ }
+
+ }
+
+ public void checkCRLCreation1()
+ throws Exception
+ {
+ AsymmetricCipherKeyPairGenerator kpg = new RSAKeyPairGenerator();
+ RSAKeyGenerationParameters genParam = new RSAKeyGenerationParameters(
+ BigInteger.valueOf(0x1001), new SecureRandom(), 1024, 25);
+
+ kpg.init(genParam);
+
+ AsymmetricCipherKeyPair pair = kpg.generateKeyPair();
+ Date now = new Date();
+
+ X509v2CRLBuilder crlGen = new X509v2CRLBuilder(new X500Name("CN=Test CA"), now);
+
+ BcX509ExtensionUtils extFact = new BcX509ExtensionUtils(new SHA1DigestCalculator());
+
+ crlGen.setNextUpdate(new Date(now.getTime() + 100000));
+
+ crlGen.addCRLEntry(BigInteger.ONE, now, CRLReason.privilegeWithdrawn);
+
+ crlGen.addExtension(Extension.authorityKeyIdentifier, false, extFact.createAuthorityKeyIdentifier(pair.getPublic()));
+
+ AlgorithmIdentifier sigAlg = sigAlgFinder.find("SHA256withRSAEncryption");
+ AlgorithmIdentifier digAlg = digAlgFinder.find(sigAlg);
+
+ X509CRLHolder crl = crlGen.build(new BcRSAContentSignerBuilder(sigAlg, digAlg).build(pair.getPrivate()));
+
+ if (!crl.getIssuer().equals(new X500Name("CN=Test CA")))
+ {
+ fail("failed CRL issuer test");
+ }
+
+ Extension authExt = crl.getExtension(Extension.authorityKeyIdentifier);
+
+ if (authExt == null)
+ {
+ fail("failed to find CRL extension");
+ }
+
+ AuthorityKeyIdentifier authId = AuthorityKeyIdentifier.getInstance(authExt.getParsedValue());
+
+ X509CRLEntryHolder entry = crl.getRevokedCertificate(BigInteger.ONE);
+
+ if (entry == null)
+ {
+ fail("failed to find CRL entry");
+ }
+
+ if (!entry.getSerialNumber().equals(BigInteger.ONE))
+ {
+ fail("CRL cert serial number does not match");
+ }
+
+ if (!entry.hasExtensions())
+ {
+ fail("CRL entry extension not found");
+ }
+
+ Extension ext = entry.getExtension(Extension.reasonCode);
+
+ if (ext != null)
+ {
+ ASN1Enumerated reasonCode = ASN1Enumerated.getInstance(ext.getParsedValue());
+
+ if (reasonCode.getValue().intValue() != CRLReason.privilegeWithdrawn)
+ {
+ fail("CRL entry reasonCode wrong");
+ }
+ }
+ else
+ {
+ fail("CRL entry reasonCode not found");
+ }
+ }
+
+ public void checkCRLCreation2()
+ throws Exception
+ {
+ AsymmetricCipherKeyPairGenerator kpg = new RSAKeyPairGenerator();
+ RSAKeyGenerationParameters genParam = new RSAKeyGenerationParameters(
+ BigInteger.valueOf(0x1001), new SecureRandom(), 1024, 25);
+
+ kpg.init(genParam);
+
+ AsymmetricCipherKeyPair pair = kpg.generateKeyPair();
+ Date now = new Date();
+
+ X509v2CRLBuilder crlGen = new X509v2CRLBuilder(new X500Name("CN=Test CA"), now);
+
+ crlGen.setNextUpdate(new Date(now.getTime() + 100000));
+
+ ExtensionsGenerator extGen = new ExtensionsGenerator();
+
+ CRLReason crlReason = CRLReason.lookup(CRLReason.privilegeWithdrawn);
+
+ extGen.addExtension(Extension.reasonCode, false, crlReason);
+
+ BcX509ExtensionUtils extFact = new BcX509ExtensionUtils(new SHA1DigestCalculator());
+
+ crlGen.addCRLEntry(BigInteger.ONE, now, extGen.generate());
+
+ crlGen.addExtension(Extension.authorityKeyIdentifier, false, extFact.createAuthorityKeyIdentifier((AsymmetricKeyParameter)pair.getPublic()));
+
+ AlgorithmIdentifier sigAlg = sigAlgFinder.find("SHA256withRSAEncryption");
+ AlgorithmIdentifier digAlg = digAlgFinder.find(sigAlg);
+
+ X509CRLHolder crlHolder = crlGen.build(new BcRSAContentSignerBuilder(sigAlg, digAlg).build((AsymmetricKeyParameter)pair.getPrivate()));
+
+ if (!crlHolder.getIssuer().equals(new X500Name("CN=Test CA")))
+ {
+ fail("failed CRL issuer test");
+ }
+
+ Extension authExt = crlHolder.getExtension(Extension.authorityKeyIdentifier);
+
+ if (authExt == null)
+ {
+ fail("failed to find CRL extension");
+ }
+
+ AuthorityKeyIdentifier authId = AuthorityKeyIdentifier.getInstance(authExt.getParsedValue());
+
+ X509CRLEntryHolder entry = crlHolder.getRevokedCertificate(BigInteger.ONE);
+
+ if (entry == null)
+ {
+ fail("failed to find CRL entry");
+ }
+
+ if (!entry.getSerialNumber().equals(BigInteger.ONE))
+ {
+ fail("CRL cert serial number does not match");
+ }
+
+ if (!entry.hasExtensions())
+ {
+ fail("CRL entry extension not found");
+ }
+
+ Extension ext = entry.getExtension(Extension.reasonCode);
+
+ if (ext != null)
+ {
+ ASN1Enumerated reasonCode = ASN1Enumerated.getInstance(ext.getParsedValue());
+
+ if (reasonCode.getValue().intValue() != CRLReason.privilegeWithdrawn)
+ {
+ fail("CRL entry reasonCode wrong");
+ }
+ }
+ else
+ {
+ fail("CRL entry reasonCode not found");
+ }
+ }
+
+ public void checkCRLCreation3()
+ throws Exception
+ {
+ AsymmetricCipherKeyPairGenerator kpg = new RSAKeyPairGenerator();
+ RSAKeyGenerationParameters genParam = new RSAKeyGenerationParameters(
+ BigInteger.valueOf(0x1001), new SecureRandom(), 1024, 25);
+
+ kpg.init(genParam);
+
+ AsymmetricCipherKeyPair pair = kpg.generateKeyPair();
+ Date now = new Date();
+ X509v2CRLBuilder crlGen = new X509v2CRLBuilder(new X500Name("CN=Test CA"), now);
+
+ crlGen.setNextUpdate(new Date(now.getTime() + 100000));
+
+ ExtensionsGenerator extGen = new ExtensionsGenerator();
+
+ CRLReason crlReason = CRLReason.lookup(CRLReason.privilegeWithdrawn);
+
+ extGen.addExtension(Extension.reasonCode, false, crlReason);
+
+ BcX509ExtensionUtils extFact = new BcX509ExtensionUtils(new SHA1DigestCalculator());
+
+ Extensions entryExtensions = extGen.generate();
+
+ crlGen.addCRLEntry(BigInteger.ONE, now, entryExtensions);
+
+ crlGen.addExtension(Extension.authorityKeyIdentifier, false, extFact.createAuthorityKeyIdentifier((AsymmetricKeyParameter)pair.getPublic()));
+
+ AlgorithmIdentifier sigAlg = sigAlgFinder.find("SHA256withRSAEncryption");
+ AlgorithmIdentifier digAlg = digAlgFinder.find(sigAlg);
+
+ X509CRLHolder crlHolder = crlGen.build(new BcRSAContentSignerBuilder(sigAlg, digAlg).build((AsymmetricKeyParameter)pair.getPrivate()));
+
+ if (!crlHolder.getIssuer().equals(new X500Name("CN=Test CA")))
+ {
+ fail("failed CRL issuer test");
+ }
+
+ Extension authExt = crlHolder.getExtension(Extension.authorityKeyIdentifier);
+
+ if (authExt == null)
+ {
+ fail("failed to find CRL extension");
+ }
+
+ AuthorityKeyIdentifier authId = AuthorityKeyIdentifier.getInstance(authExt.getParsedValue());
+
+ X509CRLEntryHolder entry = crlHolder.getRevokedCertificate(BigInteger.ONE);
+
+ if (entry == null)
+ {
+ fail("failed to find CRL entry");
+ }
+
+ if (!entry.getSerialNumber().equals(BigInteger.ONE))
+ {
+ fail("CRL cert serial number does not match");
+ }
+
+ if (!entry.hasExtensions())
+ {
+ fail("CRL entry extension not found");
+ }
+
+ Extension ext = entry.getExtension(Extension.reasonCode);
+
+ if (ext != null)
+ {
+ ASN1Enumerated reasonCode = ASN1Enumerated.getInstance(ext.getParsedValue());
+
+ if (reasonCode.getValue().intValue() != CRLReason.privilegeWithdrawn)
+ {
+ fail("CRL entry reasonCode wrong");
+ }
+ }
+ else
+ {
+ fail("CRL entry reasonCode not found");
+ }
+
+ //
+ // check loading of existing CRL
+ //
+ now = new Date();
+ crlGen = new X509v2CRLBuilder(new X500Name("CN=Test CA"), now);
+
+ crlGen.setNextUpdate(new Date(now.getTime() + 100000));
+
+ crlGen.addCRL(crlHolder);
+
+ crlGen.addCRLEntry(BigInteger.valueOf(2), now, entryExtensions);
+
+ crlGen.addExtension(Extension.authorityKeyIdentifier, false, extFact.createAuthorityKeyIdentifier(pair.getPublic()));
+
+ crlHolder = crlGen.build(new BcRSAContentSignerBuilder(sigAlg, digAlg).build(pair.getPrivate()));
+
+ int count = 0;
+ boolean oneFound = false;
+ boolean twoFound = false;
+
+ Iterator it = crlHolder.getRevokedCertificates().iterator();
+ while (it.hasNext())
+ {
+ X509CRLEntryHolder crlEnt = (X509CRLEntryHolder)it.next();
+
+ if (crlEnt.getSerialNumber().intValue() == 1)
+ {
+ oneFound = true;
+ Extension extn = crlEnt.getExtension(Extension.reasonCode);
+
+ if (extn != null)
+ {
+ ASN1Enumerated reasonCode = ASN1Enumerated.getInstance(extn.getParsedValue());
+
+ if (reasonCode.getValue().intValue() != CRLReason.privilegeWithdrawn)
+ {
+ fail("CRL entry reasonCode wrong on recheck");
+ }
+ }
+ else
+ {
+ fail("CRL entry reasonCode not found on recheck");
+ }
+ }
+ else if (crlEnt.getSerialNumber().intValue() == 2)
+ {
+ twoFound = true;
+ }
+
+ count++;
+ }
+
+ if (count != 2)
+ {
+ fail("wrong number of CRLs found, got: " + count);
+ }
+
+ if (!oneFound || !twoFound)
+ {
+ fail("wrong CRLs found in copied list");
+ }
+
+ //
+ // check factory read back
+ //
+ CertificateFactory cFact = CertificateFactory.getInstance("X.509");
+
+ X509CRL readCrl = (X509CRL)cFact.generateCRL(new ByteArrayInputStream(crlHolder.getEncoded()));
+
+ if (readCrl == null)
+ {
+ fail("crl not returned!");
+ }
+
+ Collection col = cFact.generateCRLs(new ByteArrayInputStream(crlHolder.getEncoded()));
+
+ if (col.size() != 1)
+ {
+ fail("wrong number of CRLs found in collection");
+ }
+ }
+
+ public void checkCreation5()
+ throws Exception
+ {
+ //
+ // a sample key pair.
+ //
+ AsymmetricKeyParameter pubKey = new RSAKeyParameters(
+ false,
+ new BigInteger("b4a7e46170574f16a97082b22be58b6a2a629798419be12872a4bdba626cfae9900f76abfb12139dce5de56564fab2b6543165a040c606887420e33d91ed7ed7", 16),
+ new BigInteger("11", 16));
+
+ AsymmetricKeyParameter privKey = new RSAPrivateCrtKeyParameters(
+ new BigInteger("b4a7e46170574f16a97082b22be58b6a2a629798419be12872a4bdba626cfae9900f76abfb12139dce5de56564fab2b6543165a040c606887420e33d91ed7ed7", 16),
+ new BigInteger("11", 16),
+ new BigInteger("9f66f6b05410cd503b2709e88115d55daced94d1a34d4e32bf824d0dde6028ae79c5f07b580f5dce240d7111f7ddb130a7945cd7d957d1920994da389f490c89", 16),
+ new BigInteger("c0a0758cdf14256f78d4708c86becdead1b50ad4ad6c5c703e2168fbf37884cb", 16),
+ new BigInteger("f01734d7960ea60070f1b06f2bb81bfac48ff192ae18451d5e56c734a5aab8a5", 16),
+ new BigInteger("b54bb9edff22051d9ee60f9351a48591b6500a319429c069a3e335a1d6171391", 16),
+ new BigInteger("d3d83daf2a0cecd3367ae6f8ae1aeb82e9ac2f816c6fc483533d8297dd7884cd", 16),
+ new BigInteger("b8f52fc6f38593dabb661d3f50f8897f8106eee68b1bce78a95b132b4e5b5d19", 16));
+
+ //
+ // set up the keys
+ //
+ SecureRandom rand = new SecureRandom();
+
+ //
+ // distinguished name table.
+ //
+ X500NameBuilder builder = createStdBuilder();
+
+ //
+ // create base certificate - version 3
+ //
+ AlgorithmIdentifier sigAlg = sigAlgFinder.find("MD5WithRSA");
+ AlgorithmIdentifier digAlg = digAlgFinder.find(sigAlg);
+
+ ContentSigner sigGen = new BcRSAContentSignerBuilder(sigAlg, digAlg).build(privKey);
+ ASN1ObjectIdentifier extOid = new ASN1ObjectIdentifier("2.5.29.37");
+ X509v3CertificateBuilder certGen = new BcX509v3CertificateBuilder(builder.build(),BigInteger.valueOf(1),new Date(System.currentTimeMillis() - 50000),new Date(System.currentTimeMillis() + 50000),builder.build(),pubKey)
+ .addExtension(new ASN1ObjectIdentifier("2.5.29.15"), true,
+ new KeyUsage(KeyUsage.encipherOnly))
+ .addExtension(extOid, true,
+ new DERSequence(KeyPurposeId.anyExtendedKeyUsage))
+ .addExtension(new ASN1ObjectIdentifier("2.5.29.17"), true,
+ new GeneralNames(new GeneralName(GeneralName.rfc822Name, "test@test.test")));
+
+ X509CertificateHolder baseCert = certGen.build(sigGen);
+
+ //
+ // copy certificate
+ //
+
+ certGen = new BcX509v3CertificateBuilder(builder.build(),BigInteger.valueOf(1),new Date(System.currentTimeMillis() - 50000),new Date(System.currentTimeMillis() + 50000),builder.build(),pubKey)
+ .copyAndAddExtension(new ASN1ObjectIdentifier("2.5.29.15"), true, baseCert)
+ .copyAndAddExtension(extOid, false, baseCert);
+
+ X509CertificateHolder cert = certGen.build(sigGen);
+
+ assertTrue(cert.isValidOn(new Date()));
+
+ assertTrue(cert.isSignatureValid(new BcRSAContentVerifierProviderBuilder(digAlgFinder).build(pubKey)));
+
+ if (!baseCert.getExtension(new ASN1ObjectIdentifier("2.5.29.15")).equals(cert.getExtension(new ASN1ObjectIdentifier("2.5.29.15"))))
+ {
+ fail("2.5.29.15 differs");
+ }
+
+ assertTrue(baseCert.getExtension(extOid).getExtnId().equals(cert.getExtension(extOid).getExtnId()));
+ assertFalse(baseCert.getExtension(extOid).isCritical() == cert.getExtension(extOid).isCritical());
+ if (!baseCert.getExtension(extOid).getParsedValue().equals(cert.getExtension(extOid).getParsedValue()))
+ {
+ fail("2.5.29.37 differs");
+ }
+
+ //
+ // exception test
+ //
+
+ try
+ {
+ certGen.copyAndAddExtension(new ASN1ObjectIdentifier("2.5.99.99"), true, baseCert);
+
+ fail("exception not thrown on dud extension copy");
+ }
+ catch (NullPointerException e)
+ {
+ // expected
+ }
+
+// try
+// {
+// certGen.setPublicKey(dudPublicKey);
+//
+// certGen.generate(privKey, BC);
+//
+// fail("key without encoding not detected in v3");
+// }
+// catch (IllegalArgumentException e)
+// {
+// // expected
+// }
+
+ }
+
+ public void testForgedSignature()
+ throws Exception
+ {
+ String cert = "MIIBsDCCAVoCAQYwDQYJKoZIhvcNAQEFBQAwYzELMAkGA1UEBhMCQVUxEzARBgNV"
+ + "BAgTClF1ZWVuc2xhbmQxGjAYBgNVBAoTEUNyeXB0U29mdCBQdHkgTHRkMSMwIQYD"
+ + "VQQDExpTZXJ2ZXIgdGVzdCBjZXJ0ICg1MTIgYml0KTAeFw0wNjA5MTEyMzU4NTVa"
+ + "Fw0wNjEwMTEyMzU4NTVaMGMxCzAJBgNVBAYTAkFVMRMwEQYDVQQIEwpRdWVlbnNs"
+ + "YW5kMRowGAYDVQQKExFDcnlwdFNvZnQgUHR5IEx0ZDEjMCEGA1UEAxMaU2VydmVy"
+ + "IHRlc3QgY2VydCAoNTEyIGJpdCkwXDANBgkqhkiG9w0BAQEFAANLADBIAkEAn7PD"
+ + "hCeV/xIxUg8V70YRxK2A5jZbD92A12GN4PxyRQk0/lVmRUNMaJdq/qigpd9feP/u"
+ + "12S4PwTLb/8q/v657QIDAQABMA0GCSqGSIb3DQEBBQUAA0EAbynCRIlUQgaqyNgU"
+ + "DF6P14yRKUtX8akOP2TwStaSiVf/akYqfLFm3UGka5XbPj4rifrZ0/sOoZEEBvHQ"
+ + "e20sRA==";
+
+ X509CertificateHolder hldr = new X509CertificateHolder(Base64.decode(cert));
+
+ assertFalse(hldr.isSignatureValid(new BcRSAContentVerifierProviderBuilder(digAlgFinder).build(hldr)));
+ }
+
+ private void pemTest()
+ throws Exception
+ {
+ CertificateFactory cf = CertificateFactory.getInstance("X.509", "SC");
+
+ X509Certificate cert = readPEMCert(cf, PEMData.CERTIFICATE_1);
+ if (cert == null)
+ {
+ fail("PEM cert not read");
+ }
+ cert = readPEMCert(cf, "-----BEGIN CERTIFICATE-----" + PEMData.CERTIFICATE_2);
+ if (cert == null)
+ {
+ fail("PEM cert with extraneous header not read");
+ }
+ CRL crl = cf.generateCRL(new ByteArrayInputStream(PEMData.CRL_1.getBytes("US-ASCII")));
+ if (crl == null)
+ {
+ fail("PEM crl not read");
+ }
+ Collection col = cf.generateCertificates(new ByteArrayInputStream(PEMData.CERTIFICATE_2.getBytes("US-ASCII")));
+ if (col.size() != 1 || !col.contains(cert))
+ {
+ fail("PEM cert collection not right");
+ }
+ col = cf.generateCRLs(new ByteArrayInputStream(PEMData.CRL_2.getBytes("US-ASCII")));
+ if (col.size() != 1 || !col.contains(crl))
+ {
+ fail("PEM crl collection not right");
+ }
+ }
+
+ private static X509Certificate readPEMCert(CertificateFactory cf, String pemData)
+ throws CertificateException, UnsupportedEncodingException
+ {
+ return (X509Certificate)cf.generateCertificate(new ByteArrayInputStream(pemData.getBytes("US-ASCII")));
+ }
+
+ private void createPSSCert(String algorithm)
+ throws Exception
+ {
+ AsymmetricCipherKeyPair pair = generateLongFixedKeys();
+
+ AsymmetricKeyParameter privKey = (AsymmetricKeyParameter)pair.getPrivate();
+ AsymmetricKeyParameter pubKey = (AsymmetricKeyParameter)pair.getPublic();
+
+ //
+ // distinguished name table.
+ //
+
+ X500NameBuilder builder = createStdBuilder();
+
+ //
+ // create base certificate - version 3
+ //
+ BcX509ExtensionUtils extFact = new BcX509ExtensionUtils(new SHA1DigestCalculator());
+
+ AlgorithmIdentifier sigAlgId = sigAlgFinder.find(algorithm);
+ AlgorithmIdentifier digAlgId = digAlgFinder.find(sigAlgId);
+
+ ContentSigner sigGen = new BcRSAContentSignerBuilder(sigAlgId, digAlgId).build(privKey);
+ BcX509v3CertificateBuilder certGen = new BcX509v3CertificateBuilder(builder.build(),BigInteger.valueOf(1),
+ new Date(System.currentTimeMillis() - 50000),new Date(System.currentTimeMillis() + 50000),builder.build(),pubKey);
+
+ certGen.addExtension(new ASN1ObjectIdentifier("2.5.29.15"), true,
+ new KeyUsage(KeyUsage.encipherOnly));
+ certGen.addExtension(new ASN1ObjectIdentifier("2.5.29.37"), true,
+ new DERSequence(KeyPurposeId.anyExtendedKeyUsage));
+ certGen.addExtension(new ASN1ObjectIdentifier("2.5.29.17"), true,
+ new GeneralNames(new GeneralName(GeneralName.rfc822Name, "test@test.test")));
+
+ certGen.addExtension(Extension.authorityKeyIdentifier, true, extFact.createAuthorityKeyIdentifier(pubKey));
+
+ X509CertificateHolder baseCert = certGen.build(sigGen);
+
+ assertTrue(baseCert.isSignatureValid(new BcRSAContentVerifierProviderBuilder(digAlgFinder).build(pubKey)));
+ }
+
+ private AsymmetricCipherKeyPair generateLongFixedKeys()
+ {
+ RSAKeyParameters pubKeySpec = new RSAKeyParameters(
+ false,
+ new BigInteger("a56e4a0e701017589a5187dc7ea841d156f2ec0e36ad52a44dfeb1e61f7ad991d8c51056ffedb162b4c0f283a12a88a394dff526ab7291cbb307ceabfce0b1dfd5cd9508096d5b2b8b6df5d671ef6377c0921cb23c270a70e2598e6ff89d19f105acc2d3f0cb35f29280e1386b6f64c4ef22e1e1f20d0ce8cffb2249bd9a2137",16),
+ new BigInteger("010001",16));
+
+ RSAKeyParameters privKeySpec = new RSAPrivateCrtKeyParameters(
+ new BigInteger("a56e4a0e701017589a5187dc7ea841d156f2ec0e36ad52a44dfeb1e61f7ad991d8c51056ffedb162b4c0f283a12a88a394dff526ab7291cbb307ceabfce0b1dfd5cd9508096d5b2b8b6df5d671ef6377c0921cb23c270a70e2598e6ff89d19f105acc2d3f0cb35f29280e1386b6f64c4ef22e1e1f20d0ce8cffb2249bd9a2137",16),
+ new BigInteger("010001",16),
+ new BigInteger("33a5042a90b27d4f5451ca9bbbd0b44771a101af884340aef9885f2a4bbe92e894a724ac3c568c8f97853ad07c0266c8c6a3ca0929f1e8f11231884429fc4d9ae55fee896a10ce707c3ed7e734e44727a39574501a532683109c2abacaba283c31b4bd2f53c3ee37e352cee34f9e503bd80c0622ad79c6dcee883547c6a3b325",16),
+ new BigInteger("e7e8942720a877517273a356053ea2a1bc0c94aa72d55c6e86296b2dfc967948c0a72cbccca7eacb35706e09a1df55a1535bd9b3cc34160b3b6dcd3eda8e6443",16),
+ new BigInteger("b69dca1cf7d4d7ec81e75b90fcca874abcde123fd2700180aa90479b6e48de8d67ed24f9f19d85ba275874f542cd20dc723e6963364a1f9425452b269a6799fd",16),
+ new BigInteger("28fa13938655be1f8a159cbaca5a72ea190c30089e19cd274a556f36c4f6e19f554b34c077790427bbdd8dd3ede2448328f385d81b30e8e43b2fffa027861979",16),
+ new BigInteger("1a8b38f398fa712049898d7fb79ee0a77668791299cdfa09efc0e507acb21ed74301ef5bfd48be455eaeb6e1678255827580a8e4e8e14151d1510a82a3f2e729",16),
+ new BigInteger("27156aba4126d24a81f3a528cbfb27f56886f840a9f6e86e17a44b94fe9319584b8e22fdde1e5a2e3bd8aa5ba8d8584194eb2190acf832b847f13a3d24a79f4d",16));
+
+ return new AsymmetricCipherKeyPair(pubKeySpec, privKeySpec);
+ }
+
+ public void testNullDerNullCert()
+ throws Exception
+ {
+ AsymmetricCipherKeyPair pair = generateLongFixedKeys();
+ AsymmetricKeyParameter pubKey = (AsymmetricKeyParameter)pair.getPublic();
+ AsymmetricKeyParameter privKey = (AsymmetricKeyParameter)pair.getPrivate();
+
+ DefaultSignatureAlgorithmIdentifierFinder sigAlgFinder = new DefaultSignatureAlgorithmIdentifierFinder();
+ DefaultDigestAlgorithmIdentifierFinder digAlgFinder = new DefaultDigestAlgorithmIdentifierFinder();
+
+ AlgorithmIdentifier sigAlgId = sigAlgFinder.find("MD5withRSA");
+ AlgorithmIdentifier digAlgId = digAlgFinder.find(sigAlgId);
+
+ ContentSigner sigGen = new BcRSAContentSignerBuilder(sigAlgId, digAlgId).build(privKey);
+ BcX509v3CertificateBuilder certGen = new BcX509v3CertificateBuilder(new X500Name("CN=Test"),BigInteger.valueOf(1),new Date(System.currentTimeMillis() - 50000),new Date(System.currentTimeMillis() + 50000),new X500Name("CN=Test"),pubKey);
+ X509CertificateHolder cert = certGen.build(sigGen);
+
+ Certificate struct = Certificate.getInstance(cert.getEncoded());
+
+ ASN1Object tbsCertificate = struct.getTBSCertificate();
+ AlgorithmIdentifier sig = struct.getSignatureAlgorithm();
+
+ ASN1EncodableVector v = new ASN1EncodableVector();
+
+ v.add(tbsCertificate);
+ v.add(new AlgorithmIdentifier(sig.getAlgorithm()));
+ v.add(struct.getSignature());
+
+ // verify
+ ByteArrayInputStream bIn;
+ String dump = "";
+
+ bIn = new ByteArrayInputStream(new DERSequence(v).getEncoded());
+
+ cert = new X509CertificateHolder(new DERSequence(v).getEncoded());
+
+ assertTrue(cert.isSignatureValid(new BcRSAContentVerifierProviderBuilder(digAlgFinder).build(pubKey)));
+ }
+
+ public void testCertificates()
+ throws Exception
+ {
+ checkCertificate(1, cert1);
+ checkCertificate(2, cert2);
+ checkCertificate(3, cert3);
+ checkCertificate(4, cert4);
+ checkCertificate(5, cert5);
+ //checkCertificate(7, cert7);
+
+ checkKeyUsage(8, keyUsage);
+
+ checkSelfSignedCertificate(11, probSelfSignedCert);
+
+ checkCRL(1, crl1);
+
+ checkCreation1();
+ checkCreation2();
+ checkCreation5();
+
+ createPSSCert("SHA1withRSAandMGF1");
+ createPSSCert("SHA224withRSAandMGF1");
+ createPSSCert("SHA256withRSAandMGF1");
+ createPSSCert("SHA384withRSAandMGF1");
+
+ checkCRLCreation1();
+ checkCRLCreation2();
+ checkCRLCreation3();
+
+ pemTest();
+
+ checkCertificate(18, emptyDNCert);
+ }
+}
diff --git a/pkix/src/test/java/org/spongycastle/cert/test/BcPKCS10Test.java b/pkix/src/test/java/org/spongycastle/cert/test/BcPKCS10Test.java
new file mode 100644
index 00000000..0d019764
--- /dev/null
+++ b/pkix/src/test/java/org/spongycastle/cert/test/BcPKCS10Test.java
@@ -0,0 +1,230 @@
+package org.spongycastle.cert.test;
+
+import java.math.BigInteger;
+import java.security.SecureRandom;
+
+import junit.framework.TestCase;
+import org.spongycastle.asn1.pkcs.Attribute;
+import org.spongycastle.asn1.pkcs.PKCSObjectIdentifiers;
+import org.spongycastle.asn1.x500.X500Name;
+import org.spongycastle.asn1.x500.X500NameBuilder;
+import org.spongycastle.asn1.x500.style.RFC4519Style;
+import org.spongycastle.asn1.x509.AlgorithmIdentifier;
+import org.spongycastle.asn1.x509.BasicConstraints;
+import org.spongycastle.asn1.x509.Extension;
+import org.spongycastle.asn1.x509.ExtensionsGenerator;
+import org.spongycastle.asn1.x509.KeyUsage;
+import org.spongycastle.asn1.x509.SubjectKeyIdentifier;
+import org.spongycastle.cert.bc.BcX509ExtensionUtils;
+import org.spongycastle.crypto.AsymmetricCipherKeyPair;
+import org.spongycastle.crypto.AsymmetricCipherKeyPairGenerator;
+import org.spongycastle.crypto.generators.RSAKeyPairGenerator;
+import org.spongycastle.crypto.params.AsymmetricKeyParameter;
+import org.spongycastle.crypto.params.RSAKeyGenerationParameters;
+import org.spongycastle.crypto.params.RSAKeyParameters;
+import org.spongycastle.crypto.params.RSAPrivateCrtKeyParameters;
+import org.spongycastle.operator.DefaultDigestAlgorithmIdentifierFinder;
+import org.spongycastle.operator.DefaultSignatureAlgorithmIdentifierFinder;
+import org.spongycastle.operator.bc.BcContentSignerBuilder;
+import org.spongycastle.operator.bc.BcRSAContentSignerBuilder;
+import org.spongycastle.operator.bc.BcRSAContentVerifierProviderBuilder;
+import org.spongycastle.pkcs.PKCS10CertificationRequest;
+import org.spongycastle.pkcs.PKCS10CertificationRequestBuilder;
+import org.spongycastle.pkcs.bc.BcPKCS10CertificationRequest;
+import org.spongycastle.pkcs.bc.BcPKCS10CertificationRequestBuilder;
+import org.spongycastle.util.Arrays;
+
+public class BcPKCS10Test
+ extends TestCase
+{
+ public String getName()
+ {
+ return "PKCS10CertRequest";
+ }
+
+ private void generationTest(int keySize, String keyName, String sigName)
+ throws Exception
+ {
+ AsymmetricCipherKeyPairGenerator kpg = new RSAKeyPairGenerator();
+ RSAKeyGenerationParameters genParam = new RSAKeyGenerationParameters(
+ BigInteger.valueOf(0x1001), new SecureRandom(), keySize, 25);
+
+ kpg.init(genParam);
+
+ AsymmetricCipherKeyPair kp = kpg.generateKeyPair();
+
+
+ X500NameBuilder x500NameBld = new X500NameBuilder(RFC4519Style.INSTANCE);
+
+ x500NameBld.addRDN(RFC4519Style.c, "AU");
+ x500NameBld.addRDN(RFC4519Style.o, "The Legion of the Bouncy Castle");
+ x500NameBld.addRDN(RFC4519Style.l, "Melbourne");
+ x500NameBld.addRDN(RFC4519Style.st, "Victoria");
+ x500NameBld.addRDN(PKCSObjectIdentifiers.pkcs_9_at_emailAddress, "feedback-crypto@bouncycastle.org");
+
+ X500Name subject = x500NameBld.build();
+
+ PKCS10CertificationRequestBuilder requestBuilder = new BcPKCS10CertificationRequestBuilder(subject, kp.getPublic());
+
+ DefaultSignatureAlgorithmIdentifierFinder sigAlgFinder = new DefaultSignatureAlgorithmIdentifierFinder();
+ DefaultDigestAlgorithmIdentifierFinder digAlgFinder = new DefaultDigestAlgorithmIdentifierFinder();
+
+ AlgorithmIdentifier sigAlgId = sigAlgFinder.find("SHA1withRSA");
+
+ AlgorithmIdentifier digAlgId = digAlgFinder.find(sigAlgId);
+
+ BcContentSignerBuilder contentSignerBuilder = new BcRSAContentSignerBuilder(sigAlgId, digAlgId);
+
+ PKCS10CertificationRequest req1 = requestBuilder.build(contentSignerBuilder.build(kp.getPrivate()));
+
+ BcPKCS10CertificationRequest req2 = new BcPKCS10CertificationRequest(req1.getEncoded());
+
+ if (!req2.isSignatureValid(new BcRSAContentVerifierProviderBuilder(digAlgFinder).build(kp.getPublic())))
+ {
+ fail(sigName + ": Failed verify check.");
+ }
+
+ if (!Arrays.areEqual(req2.getSubjectPublicKeyInfo().getEncoded(), req1.getSubjectPublicKeyInfo().getEncoded()))
+ {
+ fail(keyName + ": Failed public key check.");
+ }
+ }
+
+ private void createPSSTest(String algorithm)
+ throws Exception
+ {
+ AsymmetricKeyParameter pubKey = new RSAKeyParameters(
+ false,
+ new BigInteger("a56e4a0e701017589a5187dc7ea841d156f2ec0e36ad52a44dfeb1e61f7ad991d8c51056ffedb162b4c0f283a12a88a394dff526ab7291cbb307ceabfce0b1dfd5cd9508096d5b2b8b6df5d671ef6377c0921cb23c270a70e2598e6ff89d19f105acc2d3f0cb35f29280e1386b6f64c4ef22e1e1f20d0ce8cffb2249bd9a2137",16),
+ new BigInteger("010001",16));
+
+ AsymmetricKeyParameter privKey = new RSAPrivateCrtKeyParameters(
+ new BigInteger("a56e4a0e701017589a5187dc7ea841d156f2ec0e36ad52a44dfeb1e61f7ad991d8c51056ffedb162b4c0f283a12a88a394dff526ab7291cbb307ceabfce0b1dfd5cd9508096d5b2b8b6df5d671ef6377c0921cb23c270a70e2598e6ff89d19f105acc2d3f0cb35f29280e1386b6f64c4ef22e1e1f20d0ce8cffb2249bd9a2137",16),
+ new BigInteger("010001",16),
+ new BigInteger("33a5042a90b27d4f5451ca9bbbd0b44771a101af884340aef9885f2a4bbe92e894a724ac3c568c8f97853ad07c0266c8c6a3ca0929f1e8f11231884429fc4d9ae55fee896a10ce707c3ed7e734e44727a39574501a532683109c2abacaba283c31b4bd2f53c3ee37e352cee34f9e503bd80c0622ad79c6dcee883547c6a3b325",16),
+ new BigInteger("e7e8942720a877517273a356053ea2a1bc0c94aa72d55c6e86296b2dfc967948c0a72cbccca7eacb35706e09a1df55a1535bd9b3cc34160b3b6dcd3eda8e6443",16),
+ new BigInteger("b69dca1cf7d4d7ec81e75b90fcca874abcde123fd2700180aa90479b6e48de8d67ed24f9f19d85ba275874f542cd20dc723e6963364a1f9425452b269a6799fd",16),
+ new BigInteger("28fa13938655be1f8a159cbaca5a72ea190c30089e19cd274a556f36c4f6e19f554b34c077790427bbdd8dd3ede2448328f385d81b30e8e43b2fffa027861979",16),
+ new BigInteger("1a8b38f398fa712049898d7fb79ee0a77668791299cdfa09efc0e507acb21ed74301ef5bfd48be455eaeb6e1678255827580a8e4e8e14151d1510a82a3f2e729",16),
+ new BigInteger("27156aba4126d24a81f3a528cbfb27f56886f840a9f6e86e17a44b94fe9319584b8e22fdde1e5a2e3bd8aa5ba8d8584194eb2190acf832b847f13a3d24a79f4d",16));
+
+ DefaultSignatureAlgorithmIdentifierFinder sigAlgFinder = new DefaultSignatureAlgorithmIdentifierFinder();
+ DefaultDigestAlgorithmIdentifierFinder digAlgFinder = new DefaultDigestAlgorithmIdentifierFinder();
+
+ AlgorithmIdentifier sigAlgId = sigAlgFinder.find(algorithm);
+ AlgorithmIdentifier digAlgId = digAlgFinder.find(sigAlgId);
+ BcContentSignerBuilder contentSignerBuilder = new BcRSAContentSignerBuilder(sigAlgId, digAlgId);
+
+ PKCS10CertificationRequest req = new BcPKCS10CertificationRequestBuilder(new X500Name("CN=XXX"), pubKey).build(contentSignerBuilder.build(privKey));
+ if (!req.isSignatureValid(new BcRSAContentVerifierProviderBuilder(digAlgFinder).build(pubKey)))
+ {
+ fail("Failed verify check PSS.");
+ }
+
+ BcPKCS10CertificationRequest bcReq = new BcPKCS10CertificationRequest(req.getEncoded());
+ if (!bcReq.isSignatureValid(new BcRSAContentVerifierProviderBuilder(digAlgFinder).build(bcReq.getPublicKey())))
+ {
+ fail("Failed verify check PSS encoded.");
+ }
+
+ if (!bcReq.getSignatureAlgorithm().getAlgorithm().equals(PKCSObjectIdentifiers.id_RSASSA_PSS))
+ {
+ fail("PSS oid incorrect.");
+ }
+
+ if (bcReq.getSignatureAlgorithm().getParameters() == null)
+ {
+ fail("PSS parameters incorrect.");
+ }
+ }
+
+ // previous code found to cause a NullPointerException
+ private void nullPointerTest()
+ throws Exception
+ {
+ AsymmetricCipherKeyPairGenerator kpg = new RSAKeyPairGenerator();
+ RSAKeyGenerationParameters genParam = new RSAKeyGenerationParameters(
+ BigInteger.valueOf(0x1001), new SecureRandom(), 1024, 25);
+
+ kpg.init(genParam);
+
+ AsymmetricCipherKeyPair kp = kpg.generateKeyPair();
+ ExtensionsGenerator extGen = new ExtensionsGenerator();
+
+ extGen.addExtension(Extension.basicConstraints, true, new BasicConstraints(true));
+ extGen.addExtension(Extension.keyUsage, true, new KeyUsage(KeyUsage.keyCertSign | KeyUsage.cRLSign));
+
+ BcX509ExtensionUtils extUtils = new BcX509ExtensionUtils(new SHA1DigestCalculator());
+
+ SubjectKeyIdentifier subjectKeyIdentifier = extUtils.createSubjectKeyIdentifier(kp.getPublic());
+
+ extGen.addExtension(Extension.subjectKeyIdentifier, false, subjectKeyIdentifier);
+
+ DefaultSignatureAlgorithmIdentifierFinder sigAlgFinder = new DefaultSignatureAlgorithmIdentifierFinder();
+ DefaultDigestAlgorithmIdentifierFinder digAlgFinder = new DefaultDigestAlgorithmIdentifierFinder();
+
+ AlgorithmIdentifier sigAlgId = sigAlgFinder.find("SHA1withRSA");
+
+ AlgorithmIdentifier digAlgId = digAlgFinder.find(sigAlgId);
+
+ BcContentSignerBuilder contentSignerBuilder = new BcRSAContentSignerBuilder(sigAlgId, digAlgId);
+
+ PKCS10CertificationRequest p1 = new BcPKCS10CertificationRequestBuilder(
+ new X500Name("cn=csr"), kp.getPublic())
+ .addAttribute(PKCSObjectIdentifiers.pkcs_9_at_extensionRequest, extGen.generate())
+ .build(contentSignerBuilder.build(kp.getPrivate()));
+ PKCS10CertificationRequest p2 = new BcPKCS10CertificationRequestBuilder(
+ new X500Name("cn=csr"), kp.getPublic())
+ .addAttribute(PKCSObjectIdentifiers.pkcs_9_at_extensionRequest, extGen.generate())
+ .build(contentSignerBuilder.build(kp.getPrivate()));
+
+ if (!p1.equals(p2))
+ {
+ fail("cert request comparison failed");
+ }
+
+ Attribute[] attr1 = p1.getAttributes();
+ Attribute[] attr2 = p1.getAttributes();
+
+ checkAttrs(1, attr1, attr2);
+
+ attr1 = p1.getAttributes(PKCSObjectIdentifiers.pkcs_9_at_extensionRequest);
+ attr2 = p1.getAttributes(PKCSObjectIdentifiers.pkcs_9_at_extensionRequest);
+
+ checkAttrs(1, attr1, attr2);
+ }
+
+ private void checkAttrs(int expectedLength, Attribute[] attr1, Attribute[] attr2)
+ {
+ if (expectedLength != attr1.length)
+ {
+ fail("expected length mismatch");
+ }
+
+ if (attr1.length != attr2.length)
+ {
+ fail("atrribute length mismatch");
+ }
+
+ for (int i = 0; i != attr1.length; i++)
+ {
+ if (!attr1[i].equals(attr2[i]))
+ {
+ fail("atrribute mismatch");
+ }
+ }
+ }
+
+ public void testPKCS10()
+ throws Exception
+ {
+ generationTest(512, "RSA", "SHA1withRSA");
+
+ createPSSTest("SHA1withRSAandMGF1");
+ createPSSTest("SHA224withRSAandMGF1");
+ createPSSTest("SHA256withRSAandMGF1");
+ createPSSTest("SHA384withRSAandMGF1");
+
+ nullPointerTest();
+ }
+}
diff --git a/pkix/src/test/java/org/spongycastle/cert/test/CertTest.java b/pkix/src/test/java/org/spongycastle/cert/test/CertTest.java
new file mode 100644
index 00000000..14e01304
--- /dev/null
+++ b/pkix/src/test/java/org/spongycastle/cert/test/CertTest.java
@@ -0,0 +1,2995 @@
+package org.spongycastle.cert.test;
+
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.UnsupportedEncodingException;
+import java.math.BigInteger;
+import java.security.KeyFactory;
+import java.security.KeyPair;
+import java.security.KeyPairGenerator;
+import java.security.KeyStore;
+import java.security.NoSuchAlgorithmException;
+import java.security.NoSuchProviderException;
+import java.security.PrivateKey;
+import java.security.PublicKey;
+import java.security.SecureRandom;
+import java.security.Security;
+import java.security.Signature;
+import java.security.cert.CRL;
+import java.security.cert.Certificate;
+import java.security.cert.CertificateException;
+import java.security.cert.CertificateFactory;
+import java.security.cert.X509CRL;
+import java.security.cert.X509CRLEntry;
+import java.security.cert.X509Certificate;
+import java.security.spec.InvalidKeySpecException;
+import java.security.spec.RSAPrivateCrtKeySpec;
+import java.security.spec.RSAPublicKeySpec;
+import java.util.Collection;
+import java.util.Date;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Set;
+import java.util.Vector;
+
+import javax.security.auth.x500.X500Principal;
+
+import org.spongycastle.asn1.ASN1Encodable;
+import org.spongycastle.asn1.ASN1EncodableVector;
+import org.spongycastle.asn1.ASN1Enumerated;
+import org.spongycastle.asn1.ASN1ObjectIdentifier;
+import org.spongycastle.asn1.ASN1Primitive;
+import org.spongycastle.asn1.DERNull;
+import org.spongycastle.asn1.DEROctetString;
+import org.spongycastle.asn1.DERSequence;
+import org.spongycastle.asn1.pkcs.PKCSObjectIdentifiers;
+import org.spongycastle.asn1.pkcs.RSAPublicKey;
+import org.spongycastle.asn1.x500.X500Name;
+import org.spongycastle.asn1.x500.X500NameBuilder;
+import org.spongycastle.asn1.x500.style.BCStyle;
+import org.spongycastle.asn1.x509.AlgorithmIdentifier;
+import org.spongycastle.asn1.x509.AuthorityKeyIdentifier;
+import org.spongycastle.asn1.x509.CRLReason;
+import org.spongycastle.asn1.x509.Extension;
+import org.spongycastle.asn1.x509.ExtensionsGenerator;
+import org.spongycastle.asn1.x509.GeneralName;
+import org.spongycastle.asn1.x509.GeneralNames;
+import org.spongycastle.asn1.x509.IssuingDistributionPoint;
+import org.spongycastle.asn1.x509.KeyPurposeId;
+import org.spongycastle.asn1.x509.SubjectPublicKeyInfo;
+import org.spongycastle.asn1.x509.X509CertificateStructure;
+import org.spongycastle.asn1.x509.X509Extension;
+import org.spongycastle.asn1.x509.X509Extensions;
+import org.spongycastle.asn1.x9.X9ObjectIdentifiers;
+import org.spongycastle.cert.X509CRLEntryHolder;
+import org.spongycastle.cert.X509CRLHolder;
+import org.spongycastle.cert.X509CertificateHolder;
+import org.spongycastle.cert.X509v1CertificateBuilder;
+import org.spongycastle.cert.X509v2CRLBuilder;
+import org.spongycastle.cert.X509v3CertificateBuilder;
+import org.spongycastle.cert.jcajce.JcaX509CRLConverter;
+import org.spongycastle.cert.jcajce.JcaX509CRLHolder;
+import org.spongycastle.cert.jcajce.JcaX509CertificateConverter;
+import org.spongycastle.cert.jcajce.JcaX509CertificateHolder;
+import org.spongycastle.cert.jcajce.JcaX509v1CertificateBuilder;
+import org.spongycastle.cert.jcajce.JcaX509v2CRLBuilder;
+import org.spongycastle.cert.jcajce.JcaX509v3CertificateBuilder;
+import org.spongycastle.crypto.params.RSAKeyParameters;
+import org.spongycastle.crypto.params.RSAPrivateCrtKeyParameters;
+import org.spongycastle.jce.X509KeyUsage;
+import org.spongycastle.jce.X509Principal;
+import org.spongycastle.jce.interfaces.ECPointEncoder;
+import org.spongycastle.jce.provider.BouncyCastleProvider;
+import org.spongycastle.jce.spec.ECParameterSpec;
+import org.spongycastle.jce.spec.ECPrivateKeySpec;
+import org.spongycastle.jce.spec.ECPublicKeySpec;
+import org.spongycastle.jce.spec.GOST3410ParameterSpec;
+import org.spongycastle.math.ec.ECCurve;
+import org.spongycastle.operator.ContentSigner;
+import org.spongycastle.operator.ContentVerifierProvider;
+import org.spongycastle.operator.DefaultDigestAlgorithmIdentifierFinder;
+import org.spongycastle.operator.DefaultSignatureAlgorithmIdentifierFinder;
+import org.spongycastle.operator.bc.BcRSAContentSignerBuilder;
+import org.spongycastle.operator.bc.BcRSAContentVerifierProviderBuilder;
+import org.spongycastle.operator.jcajce.JcaContentSignerBuilder;
+import org.spongycastle.operator.jcajce.JcaContentVerifierProviderBuilder;
+import org.spongycastle.util.encoders.Base64;
+import org.spongycastle.util.encoders.Hex;
+import org.spongycastle.util.test.SimpleTest;
+import org.spongycastle.x509.extension.AuthorityKeyIdentifierStructure;
+import org.spongycastle.x509.extension.X509ExtensionUtil;
+
+public class CertTest
+ extends SimpleTest
+{
+ private static final String BC = org.spongycastle.jce.provider.BouncyCastleProvider.PROVIDER_NAME;
+
+ // test CA
+ byte[] testCAp12 = Base64.decode(
+ "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"
+ + "HLhcYQcQ1R+RucctAgIEAAAA");
+
+ //
+ // server.crt
+ //
+ byte[] cert1 = Base64.decode(
+ "MIIDXjCCAsegAwIBAgIBBzANBgkqhkiG9w0BAQQFADCBtzELMAkGA1UEBhMCQVUx"
+ + "ETAPBgNVBAgTCFZpY3RvcmlhMRgwFgYDVQQHEw9Tb3V0aCBNZWxib3VybmUxGjAY"
+ + "BgNVBAoTEUNvbm5lY3QgNCBQdHkgTHRkMR4wHAYDVQQLExVDZXJ0aWZpY2F0ZSBB"
+ + "dXRob3JpdHkxFTATBgNVBAMTDENvbm5lY3QgNCBDQTEoMCYGCSqGSIb3DQEJARYZ"
+ + "d2VibWFzdGVyQGNvbm5lY3Q0LmNvbS5hdTAeFw0wMDA2MDIwNzU2MjFaFw0wMTA2"
+ + "MDIwNzU2MjFaMIG4MQswCQYDVQQGEwJBVTERMA8GA1UECBMIVmljdG9yaWExGDAW"
+ + "BgNVBAcTD1NvdXRoIE1lbGJvdXJuZTEaMBgGA1UEChMRQ29ubmVjdCA0IFB0eSBM"
+ + "dGQxFzAVBgNVBAsTDldlYnNlcnZlciBUZWFtMR0wGwYDVQQDExR3d3cyLmNvbm5l"
+ + "Y3Q0LmNvbS5hdTEoMCYGCSqGSIb3DQEJARYZd2VibWFzdGVyQGNvbm5lY3Q0LmNv"
+ + "bS5hdTCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEArvDxclKAhyv7Q/Wmr2re"
+ + "Gw4XL9Cnh9e+6VgWy2AWNy/MVeXdlxzd7QAuc1eOWQkGQEiLPy5XQtTY+sBUJ3AO"
+ + "Rvd2fEVJIcjf29ey7bYua9J/vz5MG2KYo9/WCHIwqD9mmG9g0xLcfwq/s8ZJBswE"
+ + "7sb85VU+h94PTvsWOsWuKaECAwEAAaN3MHUwJAYDVR0RBB0wG4EZd2VibWFzdGVy"
+ + "QGNvbm5lY3Q0LmNvbS5hdTA6BglghkgBhvhCAQ0ELRYrbW9kX3NzbCBnZW5lcmF0"
+ + "ZWQgY3VzdG9tIHNlcnZlciBjZXJ0aWZpY2F0ZTARBglghkgBhvhCAQEEBAMCBkAw"
+ + "DQYJKoZIhvcNAQEEBQADgYEAotccfKpwSsIxM1Hae8DR7M/Rw8dg/RqOWx45HNVL"
+ + "iBS4/3N/TO195yeQKbfmzbAA2jbPVvIvGgTxPgO1MP4ZgvgRhasaa0qCJCkWvpM4"
+ + "yQf33vOiYQbpv4rTwzU8AmRlBG45WdjyNIigGV+oRc61aKCTnLq7zB8N3z1TF/bF"
+ + "5/8=");
+
+ //
+ // ca.crt
+ //
+ byte[] cert2 = Base64.decode(
+ "MIIDbDCCAtWgAwIBAgIBADANBgkqhkiG9w0BAQQFADCBtzELMAkGA1UEBhMCQVUx"
+ + "ETAPBgNVBAgTCFZpY3RvcmlhMRgwFgYDVQQHEw9Tb3V0aCBNZWxib3VybmUxGjAY"
+ + "BgNVBAoTEUNvbm5lY3QgNCBQdHkgTHRkMR4wHAYDVQQLExVDZXJ0aWZpY2F0ZSBB"
+ + "dXRob3JpdHkxFTATBgNVBAMTDENvbm5lY3QgNCBDQTEoMCYGCSqGSIb3DQEJARYZ"
+ + "d2VibWFzdGVyQGNvbm5lY3Q0LmNvbS5hdTAeFw0wMDA2MDIwNzU1MzNaFw0wMTA2"
+ + "MDIwNzU1MzNaMIG3MQswCQYDVQQGEwJBVTERMA8GA1UECBMIVmljdG9yaWExGDAW"
+ + "BgNVBAcTD1NvdXRoIE1lbGJvdXJuZTEaMBgGA1UEChMRQ29ubmVjdCA0IFB0eSBM"
+ + "dGQxHjAcBgNVBAsTFUNlcnRpZmljYXRlIEF1dGhvcml0eTEVMBMGA1UEAxMMQ29u"
+ + "bmVjdCA0IENBMSgwJgYJKoZIhvcNAQkBFhl3ZWJtYXN0ZXJAY29ubmVjdDQuY29t"
+ + "LmF1MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDgs5ptNG6Qv1ZpCDuUNGmv"
+ + "rhjqMDPd3ri8JzZNRiiFlBA4e6/ReaO1U8ASewDeQMH6i9R6degFdQRLngbuJP0s"
+ + "xcEE+SksEWNvygfzLwV9J/q+TQDyJYK52utb++lS0b48A1KPLwEsyL6kOAgelbur"
+ + "ukwxowprKUIV7Knf1ajetQIDAQABo4GFMIGCMCQGA1UdEQQdMBuBGXdlYm1hc3Rl"
+ + "ckBjb25uZWN0NC5jb20uYXUwDwYDVR0TBAgwBgEB/wIBADA2BglghkgBhvhCAQ0E"
+ + "KRYnbW9kX3NzbCBnZW5lcmF0ZWQgY3VzdG9tIENBIGNlcnRpZmljYXRlMBEGCWCG"
+ + "SAGG+EIBAQQEAwICBDANBgkqhkiG9w0BAQQFAAOBgQCsGvfdghH8pPhlwm1r3pQk"
+ + "msnLAVIBb01EhbXm2861iXZfWqGQjrGAaA0ZpXNk9oo110yxoqEoSJSzniZa7Xtz"
+ + "soTwNUpE0SLHvWf/SlKdFWlzXA+vOZbzEv4UmjeelekTm7lc01EEa5QRVzOxHFtQ"
+ + "DhkaJ8VqOMajkQFma2r9iA==");
+
+ //
+ // testx509.pem
+ //
+ byte[] cert3 = Base64.decode(
+ "MIIBWzCCAQYCARgwDQYJKoZIhvcNAQEEBQAwODELMAkGA1UEBhMCQVUxDDAKBgNV"
+ + "BAgTA1FMRDEbMBkGA1UEAxMSU1NMZWF5L3JzYSB0ZXN0IENBMB4XDTk1MDYxOTIz"
+ + "MzMxMloXDTk1MDcxNzIzMzMxMlowOjELMAkGA1UEBhMCQVUxDDAKBgNVBAgTA1FM"
+ + "RDEdMBsGA1UEAxMUU1NMZWF5L3JzYSB0ZXN0IGNlcnQwXDANBgkqhkiG9w0BAQEF"
+ + "AANLADBIAkEAqtt6qS5GTxVxGZYWa0/4u+IwHf7p2LNZbcPBp9/OfIcYAXBQn8hO"
+ + "/Re1uwLKXdCjIoaGs4DLdG88rkzfyK5dPQIDAQABMAwGCCqGSIb3DQIFBQADQQAE"
+ + "Wc7EcF8po2/ZO6kNCwK/ICH6DobgLekA5lSLr5EvuioZniZp5lFzAw4+YzPQ7XKJ"
+ + "zl9HYIMxATFyqSiD9jsx");
+
+ //
+ // v3-cert1.pem
+ //
+ byte[] cert4 = Base64.decode(
+ "MIICjTCCAfigAwIBAgIEMaYgRzALBgkqhkiG9w0BAQQwRTELMAkGA1UEBhMCVVMx"
+ + "NjA0BgNVBAoTLU5hdGlvbmFsIEFlcm9uYXV0aWNzIGFuZCBTcGFjZSBBZG1pbmlz"
+ + "dHJhdGlvbjAmFxE5NjA1MjgxMzQ5MDUrMDgwMBcROTgwNTI4MTM0OTA1KzA4MDAw"
+ + "ZzELMAkGA1UEBhMCVVMxNjA0BgNVBAoTLU5hdGlvbmFsIEFlcm9uYXV0aWNzIGFu"
+ + "ZCBTcGFjZSBBZG1pbmlzdHJhdGlvbjEgMAkGA1UEBRMCMTYwEwYDVQQDEwxTdGV2"
+ + "ZSBTY2hvY2gwWDALBgkqhkiG9w0BAQEDSQAwRgJBALrAwyYdgxmzNP/ts0Uyf6Bp"
+ + "miJYktU/w4NG67ULaN4B5CnEz7k57s9o3YY3LecETgQ5iQHmkwlYDTL2fTgVfw0C"
+ + "AQOjgaswgagwZAYDVR0ZAQH/BFowWDBWMFQxCzAJBgNVBAYTAlVTMTYwNAYDVQQK"
+ + "Ey1OYXRpb25hbCBBZXJvbmF1dGljcyBhbmQgU3BhY2UgQWRtaW5pc3RyYXRpb24x"
+ + "DTALBgNVBAMTBENSTDEwFwYDVR0BAQH/BA0wC4AJODMyOTcwODEwMBgGA1UdAgQR"
+ + "MA8ECTgzMjk3MDgyM4ACBSAwDQYDVR0KBAYwBAMCBkAwCwYJKoZIhvcNAQEEA4GB"
+ + "AH2y1VCEw/A4zaXzSYZJTTUi3uawbbFiS2yxHvgf28+8Js0OHXk1H1w2d6qOHH21"
+ + "X82tZXd/0JtG0g1T9usFFBDvYK8O0ebgz/P5ELJnBL2+atObEuJy1ZZ0pBDWINR3"
+ + "WkDNLCGiTkCKp0F5EWIrVDwh54NNevkCQRZita+z4IBO");
+
+ //
+ // v3-cert2.pem
+ //
+ byte[] cert5 = Base64.decode(
+ "MIICiTCCAfKgAwIBAgIEMeZfHzANBgkqhkiG9w0BAQQFADB9MQswCQYDVQQGEwJD"
+ + "YTEPMA0GA1UEBxMGTmVwZWFuMR4wHAYDVQQLExVObyBMaWFiaWxpdHkgQWNjZXB0"
+ + "ZWQxHzAdBgNVBAoTFkZvciBEZW1vIFB1cnBvc2VzIE9ubHkxHDAaBgNVBAMTE0Vu"
+ + "dHJ1c3QgRGVtbyBXZWIgQ0EwHhcNOTYwNzEyMTQyMDE1WhcNOTYxMDEyMTQyMDE1"
+ + "WjB0MSQwIgYJKoZIhvcNAQkBExVjb29rZUBpc3NsLmF0bC5ocC5jb20xCzAJBgNV"
+ + "BAYTAlVTMScwJQYDVQQLEx5IZXdsZXR0IFBhY2thcmQgQ29tcGFueSAoSVNTTCkx"
+ + "FjAUBgNVBAMTDVBhdWwgQS4gQ29va2UwXDANBgkqhkiG9w0BAQEFAANLADBIAkEA"
+ + "6ceSq9a9AU6g+zBwaL/yVmW1/9EE8s5you1mgjHnj0wAILuoB3L6rm6jmFRy7QZT"
+ + "G43IhVZdDua4e+5/n1ZslwIDAQABo2MwYTARBglghkgBhvhCAQEEBAMCB4AwTAYJ"
+ + "YIZIAYb4QgENBD8WPVRoaXMgY2VydGlmaWNhdGUgaXMgb25seSBpbnRlbmRlZCBm"
+ + "b3IgZGVtb25zdHJhdGlvbiBwdXJwb3Nlcy4wDQYJKoZIhvcNAQEEBQADgYEAi8qc"
+ + "F3zfFqy1sV8NhjwLVwOKuSfhR/Z8mbIEUeSTlnH3QbYt3HWZQ+vXI8mvtZoBc2Fz"
+ + "lexKeIkAZXCesqGbs6z6nCt16P6tmdfbZF3I3AWzLquPcOXjPf4HgstkyvVBn0Ap"
+ + "jAFN418KF/Cx4qyHB4cjdvLrRjjQLnb2+ibo7QU=");
+
+ //
+ // pem encoded pkcs7
+ //
+ byte[] cert6 = Base64.decode(
+ "MIAGCSqGSIb3DQEHAqCAMIACAQExCzAJBgUrDgMCGgUAMIAGCSqGSIb3DQEHAQAAoIIJbzCCAj0w"
+ + "ggGmAhEAzbp/VvDf5LxU/iKss3KqVTANBgkqhkiG9w0BAQIFADBfMQswCQYDVQQGEwJVUzEXMBUG"
+ + "A1UEChMOVmVyaVNpZ24sIEluYy4xNzA1BgNVBAsTLkNsYXNzIDEgUHVibGljIFByaW1hcnkgQ2Vy"
+ + "dGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNOTYwMTI5MDAwMDAwWhcNMjgwODAxMjM1OTU5WjBfMQsw"
+ + "CQYDVQQGEwJVUzEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xNzA1BgNVBAsTLkNsYXNzIDEgUHVi"
+ + "bGljIFByaW1hcnkgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwgZ8wDQYJKoZIhvcNAQEBBQADgY0A"
+ + "MIGJAoGBAOUZv22jVmEtmUhx9mfeuY3rt56GgAqRDvo4Ja9GiILlc6igmyRdDR/MZW4MsNBWhBiH"
+ + "mgabEKFz37RYOWtuwfYV1aioP6oSBo0xrH+wNNePNGeICc0UEeJORVZpH3gCgNrcR5EpuzbJY1zF"
+ + "4Ncth3uhtzKwezC6Ki8xqu6jZ9rbAgMBAAEwDQYJKoZIhvcNAQECBQADgYEATD+4i8Zo3+5DMw5d"
+ + "6abLB4RNejP/khv0Nq3YlSI2aBFsfELM85wuxAc/FLAPT/+Qknb54rxK6Y/NoIAK98Up8YIiXbix"
+ + "3YEjo3slFUYweRb46gVLlH8dwhzI47f0EEA8E8NfH1PoSOSGtHuhNbB7Jbq4046rPzidADQAmPPR"
+ + "cZQwggMuMIICl6ADAgECAhEA0nYujRQMPX2yqCVdr+4NdTANBgkqhkiG9w0BAQIFADBfMQswCQYD"
+ + "VQQGEwJVUzEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xNzA1BgNVBAsTLkNsYXNzIDEgUHVibGlj"
+ + "IFByaW1hcnkgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNOTgwNTEyMDAwMDAwWhcNMDgwNTEy"
+ + "MjM1OTU5WjCBzDEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xHzAdBgNVBAsTFlZlcmlTaWduIFRy"
+ + "dXN0IE5ldHdvcmsxRjBEBgNVBAsTPXd3dy52ZXJpc2lnbi5jb20vcmVwb3NpdG9yeS9SUEEgSW5j"
+ + "b3JwLiBCeSBSZWYuLExJQUIuTFREKGMpOTgxSDBGBgNVBAMTP1ZlcmlTaWduIENsYXNzIDEgQ0Eg"
+ + "SW5kaXZpZHVhbCBTdWJzY3JpYmVyLVBlcnNvbmEgTm90IFZhbGlkYXRlZDCBnzANBgkqhkiG9w0B"
+ + "AQEFAAOBjQAwgYkCgYEAu1pEigQWu1X9A3qKLZRPFXg2uA1Ksm+cVL+86HcqnbnwaLuV2TFBcHqB"
+ + "S7lIE1YtxwjhhEKrwKKSq0RcqkLwgg4C6S/7wju7vsknCl22sDZCM7VuVIhPh0q/Gdr5FegPh7Yc"
+ + "48zGmo5/aiSS4/zgZbqnsX7vyds3ashKyAkG5JkCAwEAAaN8MHowEQYJYIZIAYb4QgEBBAQDAgEG"
+ + "MEcGA1UdIARAMD4wPAYLYIZIAYb4RQEHAQEwLTArBggrBgEFBQcCARYfd3d3LnZlcmlzaWduLmNv"
+ + "bS9yZXBvc2l0b3J5L1JQQTAPBgNVHRMECDAGAQH/AgEAMAsGA1UdDwQEAwIBBjANBgkqhkiG9w0B"
+ + "AQIFAAOBgQCIuDc73dqUNwCtqp/hgQFxHpJqbS/28Z3TymQ43BuYDAeGW4UVag+5SYWklfEXfWe0"
+ + "fy0s3ZpCnsM+tI6q5QsG3vJWKvozx74Z11NMw73I4xe1pElCY+zCphcPXVgaSTyQXFWjZSAA/Rgg"
+ + "5V+CprGoksVYasGNAzzrw80FopCubjCCA/gwggNhoAMCAQICEBbbn/1G1zppD6KsP01bwywwDQYJ"
+ + "KoZIhvcNAQEEBQAwgcwxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMR8wHQYDVQQLExZWZXJpU2ln"
+ + "biBUcnVzdCBOZXR3b3JrMUYwRAYDVQQLEz13d3cudmVyaXNpZ24uY29tL3JlcG9zaXRvcnkvUlBB"
+ + "IEluY29ycC4gQnkgUmVmLixMSUFCLkxURChjKTk4MUgwRgYDVQQDEz9WZXJpU2lnbiBDbGFzcyAx"
+ + "IENBIEluZGl2aWR1YWwgU3Vic2NyaWJlci1QZXJzb25hIE5vdCBWYWxpZGF0ZWQwHhcNMDAxMDAy"
+ + "MDAwMDAwWhcNMDAxMjAxMjM1OTU5WjCCAQcxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMR8wHQYD"
+ + "VQQLExZWZXJpU2lnbiBUcnVzdCBOZXR3b3JrMUYwRAYDVQQLEz13d3cudmVyaXNpZ24uY29tL3Jl"
+ + "cG9zaXRvcnkvUlBBIEluY29ycC4gYnkgUmVmLixMSUFCLkxURChjKTk4MR4wHAYDVQQLExVQZXJz"
+ + "b25hIE5vdCBWYWxpZGF0ZWQxJzAlBgNVBAsTHkRpZ2l0YWwgSUQgQ2xhc3MgMSAtIE1pY3Jvc29m"
+ + "dDETMBEGA1UEAxQKRGF2aWQgUnlhbjElMCMGCSqGSIb3DQEJARYWZGF2aWRAbGl2ZW1lZGlhLmNv"
+ + "bS5hdTCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAqxBsdeNmSvFqhMNwhQgNzM8mdjX9eSXb"
+ + "DawpHtQHjmh0AKJSa3IwUY0VIsyZHuXWktO/CgaMBVPt6OVf/n0R2sQigMP6Y+PhEiS0vCJBL9aK"
+ + "0+pOo2qXrjVBmq+XuCyPTnc+BOSrU26tJsX0P9BYorwySiEGxGanBNATdVL4NdUCAwEAAaOBnDCB"
+ + "mTAJBgNVHRMEAjAAMEQGA1UdIAQ9MDswOQYLYIZIAYb4RQEHAQgwKjAoBggrBgEFBQcCARYcaHR0"
+ + "cHM6Ly93d3cudmVyaXNpZ24uY29tL3JwYTARBglghkgBhvhCAQEEBAMCB4AwMwYDVR0fBCwwKjAo"
+ + "oCagJIYiaHR0cDovL2NybC52ZXJpc2lnbi5jb20vY2xhc3MxLmNybDANBgkqhkiG9w0BAQQFAAOB"
+ + "gQBC8yIIdVGpFTf8/YiL14cMzcmL0nIRm4kGR3U59z7UtcXlfNXXJ8MyaeI/BnXwG/gD5OKYqW6R"
+ + "yca9vZOxf1uoTBl82gInk865ED3Tej6msCqFzZffnSUQvOIeqLxxDlqYRQ6PmW2nAnZeyjcnbI5Y"
+ + "syQSM2fmo7n6qJFP+GbFezGCAkUwggJBAgEBMIHhMIHMMRcwFQYDVQQKEw5WZXJpU2lnbiwgSW5j"
+ + "LjEfMB0GA1UECxMWVmVyaVNpZ24gVHJ1c3QgTmV0d29yazFGMEQGA1UECxM9d3d3LnZlcmlzaWdu"
+ + "LmNvbS9yZXBvc2l0b3J5L1JQQSBJbmNvcnAuIEJ5IFJlZi4sTElBQi5MVEQoYyk5ODFIMEYGA1UE"
+ + "AxM/VmVyaVNpZ24gQ2xhc3MgMSBDQSBJbmRpdmlkdWFsIFN1YnNjcmliZXItUGVyc29uYSBOb3Qg"
+ + "VmFsaWRhdGVkAhAW25/9Rtc6aQ+irD9NW8MsMAkGBSsOAwIaBQCggbowGAYJKoZIhvcNAQkDMQsG"
+ + "CSqGSIb3DQEHATAcBgkqhkiG9w0BCQUxDxcNMDAxMDAyMTczNTE4WjAjBgkqhkiG9w0BCQQxFgQU"
+ + "gZjSaBEY2oxGvlQUIMnxSXhivK8wWwYJKoZIhvcNAQkPMU4wTDAKBggqhkiG9w0DBzAOBggqhkiG"
+ + "9w0DAgICAIAwDQYIKoZIhvcNAwICAUAwBwYFKw4DAgcwDQYIKoZIhvcNAwICASgwBwYFKw4DAh0w"
+ + "DQYJKoZIhvcNAQEBBQAEgYAzk+PU91/ZFfoiuKOECjxEh9fDYE2jfDCheBIgh5gdcCo+sS1WQs8O"
+ + "HreQ9Nop/JdJv1DQMBK6weNBBDoP0EEkRm1XCC144XhXZC82jBZohYmi2WvDbbC//YN58kRMYMyy"
+ + "srrfn4Z9I+6kTriGXkrpGk9Q0LSGjmG2BIsqiF0dvwAAAAAAAA==");
+
+ //
+ // dsaWithSHA1 cert
+ //
+ byte[] cert7 = Base64.decode(
+ "MIIEXAYJKoZIhvcNAQcCoIIETTCCBEkCAQExCzAJBgUrDgMCGgUAMAsGCSqG"
+ + "SIb3DQEHAaCCAsMwggK/MIIB4AIBADCBpwYFKw4DAhswgZ0CQQEkJRHP+mN7"
+ + "d8miwTMN55CUSmo3TO8WGCxgY61TX5k+7NU4XPf1TULjw3GobwaJX13kquPh"
+ + "fVXk+gVy46n4Iw3hAhUBSe/QF4BUj+pJOF9ROBM4u+FEWA8CQQD4mSJbrABj"
+ + "TUWrlnAte8pS22Tq4/FPO7jHSqjijUHfXKTrHL1OEqV3SVWcFy5j/cqBgX/z"
+ + "m8Q12PFp/PjOhh+nMA4xDDAKBgNVBAMTA0lEMzAeFw05NzEwMDEwMDAwMDBa"
+ + "Fw0zODAxMDEwMDAwMDBaMA4xDDAKBgNVBAMTA0lEMzCB8DCBpwYFKw4DAhsw"
+ + "gZ0CQQEkJRHP+mN7d8miwTMN55CUSmo3TO8WGCxgY61TX5k+7NU4XPf1TULj"
+ + "w3GobwaJX13kquPhfVXk+gVy46n4Iw3hAhUBSe/QF4BUj+pJOF9ROBM4u+FE"
+ + "WA8CQQD4mSJbrABjTUWrlnAte8pS22Tq4/FPO7jHSqjijUHfXKTrHL1OEqV3"
+ + "SVWcFy5j/cqBgX/zm8Q12PFp/PjOhh+nA0QAAkEAkYkXLYMtGVGWj9OnzjPn"
+ + "sB9sefSRPrVegZJCZbpW+Iv0/1RP1u04pHG9vtRpIQLjzUiWvLMU9EKQTThc"
+ + "eNMmWDCBpwYFKw4DAhswgZ0CQQEkJRHP+mN7d8miwTMN55CUSmo3TO8WGCxg"
+ + "Y61TX5k+7NU4XPf1TULjw3GobwaJX13kquPhfVXk+gVy46n4Iw3hAhUBSe/Q"
+ + "F4BUj+pJOF9ROBM4u+FEWA8CQQD4mSJbrABjTUWrlnAte8pS22Tq4/FPO7jH"
+ + "SqjijUHfXKTrHL1OEqV3SVWcFy5j/cqBgX/zm8Q12PFp/PjOhh+nAy8AMCwC"
+ + "FBY3dBSdeprGcqpr6wr3xbG+6WW+AhRMm/facKJNxkT3iKgJbp7R8Xd3QTGC"
+ + "AWEwggFdAgEBMBMwDjEMMAoGA1UEAxMDSUQzAgEAMAkGBSsOAwIaBQCgXTAY"
+ + "BgkqhkiG9w0BCQMxCwYJKoZIhvcNAQcBMBwGCSqGSIb3DQEJBTEPFw0wMjA1"
+ + "MjQyMzEzMDdaMCMGCSqGSIb3DQEJBDEWBBS4WMsoJhf7CVbZYCFcjoTRzPkJ"
+ + "xjCBpwYFKw4DAhswgZ0CQQEkJRHP+mN7d8miwTMN55CUSmo3TO8WGCxgY61T"
+ + "X5k+7NU4XPf1TULjw3GobwaJX13kquPhfVXk+gVy46n4Iw3hAhUBSe/QF4BU"
+ + "j+pJOF9ROBM4u+FEWA8CQQD4mSJbrABjTUWrlnAte8pS22Tq4/FPO7jHSqji"
+ + "jUHfXKTrHL1OEqV3SVWcFy5j/cqBgX/zm8Q12PFp/PjOhh+nBC8wLQIVALID"
+ + "dt+MHwawrDrwsO1Z6sXBaaJsAhRaKssrpevmLkbygKPV07XiAKBG02Zvb2Jh"
+ + "cg==");
+
+ //
+ // testcrl.pem
+ //
+ byte[] crl1 = Base64.decode(
+ "MIICjTCCAfowDQYJKoZIhvcNAQECBQAwXzELMAkGA1UEBhMCVVMxIDAeBgNVBAoT"
+ + "F1JTQSBEYXRhIFNlY3VyaXR5LCBJbmMuMS4wLAYDVQQLEyVTZWN1cmUgU2VydmVy"
+ + "IENlcnRpZmljYXRpb24gQXV0aG9yaXR5Fw05NTA1MDIwMjEyMjZaFw05NTA2MDEw"
+ + "MDAxNDlaMIIBaDAWAgUCQQAABBcNOTUwMjAxMTcyNDI2WjAWAgUCQQAACRcNOTUw"
+ + "MjEwMDIxNjM5WjAWAgUCQQAADxcNOTUwMjI0MDAxMjQ5WjAWAgUCQQAADBcNOTUw"
+ + "MjI1MDA0NjQ0WjAWAgUCQQAAGxcNOTUwMzEzMTg0MDQ5WjAWAgUCQQAAFhcNOTUw"
+ + "MzE1MTkxNjU0WjAWAgUCQQAAGhcNOTUwMzE1MTk0MDQxWjAWAgUCQQAAHxcNOTUw"
+ + "MzI0MTk0NDMzWjAWAgUCcgAABRcNOTUwMzI5MjAwNzExWjAWAgUCcgAAERcNOTUw"
+ + "MzMwMDIzNDI2WjAWAgUCQQAAIBcNOTUwNDA3MDExMzIxWjAWAgUCcgAAHhcNOTUw"
+ + "NDA4MDAwMjU5WjAWAgUCcgAAQRcNOTUwNDI4MTcxNzI0WjAWAgUCcgAAOBcNOTUw"
+ + "NDI4MTcyNzIxWjAWAgUCcgAATBcNOTUwNTAyMDIxMjI2WjANBgkqhkiG9w0BAQIF"
+ + "AAN+AHqOEJXSDejYy0UwxxrH/9+N2z5xu/if0J6qQmK92W0hW158wpJg+ovV3+wQ"
+ + "wvIEPRL2rocL0tKfAsVq1IawSJzSNgxG0lrcla3MrJBnZ4GaZDu4FutZh72MR3Gt"
+ + "JaAL3iTJHJD55kK2D/VoyY1djlsPuNh6AEgdVwFAyp0v");
+
+ //
+ // ecdsa cert with extra octet string.
+ //
+ byte[] oldEcdsa = Base64.decode(
+ "MIICljCCAkCgAwIBAgIBATALBgcqhkjOPQQBBQAwgY8xCzAJBgNVBAYTAkFVMSgwJ"
+ + "gYDVQQKEx9UaGUgTGVnaW9uIG9mIHRoZSBCb3VuY3kgQ2FzdGxlMRIwEAYDVQQHEw"
+ + "lNZWxib3VybmUxETAPBgNVBAgTCFZpY3RvcmlhMS8wLQYJKoZIhvcNAQkBFiBmZWV"
+ + "kYmFjay1jcnlwdG9AYm91bmN5Y2FzdGxlLm9yZzAeFw0wMTEyMDcwMTAwMDRaFw0w"
+ + "MTEyMDcwMTAxNDRaMIGPMQswCQYDVQQGEwJBVTEoMCYGA1UEChMfVGhlIExlZ2lvb"
+ + "iBvZiB0aGUgQm91bmN5IENhc3RsZTESMBAGA1UEBxMJTWVsYm91cm5lMREwDwYDVQ"
+ + "QIEwhWaWN0b3JpYTEvMC0GCSqGSIb3DQEJARYgZmVlZGJhY2stY3J5cHRvQGJvdW5"
+ + "jeWNhc3RsZS5vcmcwgeQwgb0GByqGSM49AgEwgbECAQEwKQYHKoZIzj0BAQIef///"
+ + "////////////f///////gAAAAAAAf///////MEAEHn///////////////3///////"
+ + "4AAAAAAAH///////AQeawFsO9zxiUHQ1lSSFHXKcanbL7J9HTd5YYXClCwKBB8CD/"
+ + "qWPNyogWzMM7hkK+35BcPTWFc9Pyf7vTs8uaqvAh5///////////////9///+eXpq"
+ + "fXZBx+9FSJoiQnQsDIgAEHwJbbcU7xholSP+w9nFHLebJUhqdLSU05lq/y9X+DHAw"
+ + "CwYHKoZIzj0EAQUAA0MAMEACHnz6t4UNoVROp74ma4XNDjjGcjaqiIWPZLK8Bdw3G"
+ + "QIeLZ4j3a6ividZl344UH+UPUE7xJxlYGuy7ejTsqRR");
+
+ byte[] uncompressedPtEC = Base64.decode(
+ "MIIDKzCCAsGgAwIBAgICA+kwCwYHKoZIzj0EAQUAMGYxCzAJBgNVBAYTAkpQ"
+ + "MRUwEwYDVQQKEwxuaXRlY2guYWMuanAxDjAMBgNVBAsTBWFpbGFiMQ8wDQYD"
+ + "VQQDEwZ0ZXN0Y2ExHzAdBgkqhkiG9w0BCQEWEHRlc3RjYUBsb2NhbGhvc3Qw"
+ + "HhcNMDExMDEzMTE1MzE3WhcNMjAxMjEyMTE1MzE3WjBmMQswCQYDVQQGEwJK"
+ + "UDEVMBMGA1UEChMMbml0ZWNoLmFjLmpwMQ4wDAYDVQQLEwVhaWxhYjEPMA0G"
+ + "A1UEAxMGdGVzdGNhMR8wHQYJKoZIhvcNAQkBFhB0ZXN0Y2FAbG9jYWxob3N0"
+ + "MIIBczCCARsGByqGSM49AgEwggEOAgEBMDMGByqGSM49AQECKEdYWnajFmnZ"
+ + "tzrukK2XWdle2v+GsD9l1ZiR6g7ozQDbhFH/bBiMDQcwVAQoJ5EQKrI54/CT"
+ + "xOQ2pMsd/fsXD+EX8YREd8bKHWiLz8lIVdD5cBNeVwQoMKSc6HfI7vKZp8Q2"
+ + "zWgIFOarx1GQoWJbMcSt188xsl30ncJuJT2OoARRBAqJ4fD+q6hbqgNSjTQ7"
+ + "htle1KO3eiaZgcJ8rrnyN8P+5A8+5K+H9aQ/NbBR4Gs7yto5PXIUZEUgodHA"
+ + "TZMSAcSq5ZYt4KbnSYaLY0TtH9CqAigEwZ+hglbT21B7ZTzYX2xj0x+qooJD"
+ + "hVTLtIPaYJK2HrMPxTw6/zfrAgEPA1IABAnvfFcFDgD/JicwBGn6vR3N8MIn"
+ + "mptZf/mnJ1y649uCF60zOgdwIyI7pVSxBFsJ7ohqXEHW0x7LrGVkdSEiipiH"
+ + "LYslqh3xrqbAgPbl93GUo0IwQDAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB"
+ + "/wQEAwIBxjAdBgNVHQ4EFgQUAEo62Xm9H6DcsE0zUDTza4BRG90wCwYHKoZI"
+ + "zj0EAQUAA1cAMFQCKAQsCHHSNOqfJXLgt3bg5+k49hIBGVr/bfG0B9JU3rNt"
+ + "Ycl9Y2zfRPUCKAK2ccOQXByAWfsasDu8zKHxkZv7LVDTFjAIffz3HaCQeVhD"
+ + "z+fauEg=");
+
+ byte[] keyUsage = Base64.decode(
+ "MIIE7TCCBFagAwIBAgIEOAOR7jANBgkqhkiG9w0BAQQFADCByTELMAkGA1UE"
+ + "BhMCVVMxFDASBgNVBAoTC0VudHJ1c3QubmV0MUgwRgYDVQQLFD93d3cuZW50"
+ + "cnVzdC5uZXQvQ2xpZW50X0NBX0luZm8vQ1BTIGluY29ycC4gYnkgcmVmLiBs"
+ + "aW1pdHMgbGlhYi4xJTAjBgNVBAsTHChjKSAxOTk5IEVudHJ1c3QubmV0IExp"
+ + "bWl0ZWQxMzAxBgNVBAMTKkVudHJ1c3QubmV0IENsaWVudCBDZXJ0aWZpY2F0"
+ + "aW9uIEF1dGhvcml0eTAeFw05OTEwMTIxOTI0MzBaFw0xOTEwMTIxOTU0MzBa"
+ + "MIHJMQswCQYDVQQGEwJVUzEUMBIGA1UEChMLRW50cnVzdC5uZXQxSDBGBgNV"
+ + "BAsUP3d3dy5lbnRydXN0Lm5ldC9DbGllbnRfQ0FfSW5mby9DUFMgaW5jb3Jw"
+ + "LiBieSByZWYuIGxpbWl0cyBsaWFiLjElMCMGA1UECxMcKGMpIDE5OTkgRW50"
+ + "cnVzdC5uZXQgTGltaXRlZDEzMDEGA1UEAxMqRW50cnVzdC5uZXQgQ2xpZW50"
+ + "IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MIGdMA0GCSqGSIb3DQEBAQUAA4GL"
+ + "ADCBhwKBgQDIOpleMRffrCdvkHvkGf9FozTC28GoT/Bo6oT9n3V5z8GKUZSv"
+ + "x1cDR2SerYIbWtp/N3hHuzeYEpbOxhN979IMMFGpOZ5V+Pux5zDeg7K6PvHV"
+ + "iTs7hbqqdCz+PzFur5GVbgbUB01LLFZHGARS2g4Qk79jkJvh34zmAqTmT173"
+ + "iwIBA6OCAeAwggHcMBEGCWCGSAGG+EIBAQQEAwIABzCCASIGA1UdHwSCARkw"
+ + "ggEVMIHkoIHhoIHepIHbMIHYMQswCQYDVQQGEwJVUzEUMBIGA1UEChMLRW50"
+ + "cnVzdC5uZXQxSDBGBgNVBAsUP3d3dy5lbnRydXN0Lm5ldC9DbGllbnRfQ0Ff"
+ + "SW5mby9DUFMgaW5jb3JwLiBieSByZWYuIGxpbWl0cyBsaWFiLjElMCMGA1UE"
+ + "CxMcKGMpIDE5OTkgRW50cnVzdC5uZXQgTGltaXRlZDEzMDEGA1UEAxMqRW50"
+ + "cnVzdC5uZXQgQ2xpZW50IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MQ0wCwYD"
+ + "VQQDEwRDUkwxMCygKqAohiZodHRwOi8vd3d3LmVudHJ1c3QubmV0L0NSTC9D"
+ + "bGllbnQxLmNybDArBgNVHRAEJDAigA8xOTk5MTAxMjE5MjQzMFqBDzIwMTkx"
+ + "MDEyMTkyNDMwWjALBgNVHQ8EBAMCAQYwHwYDVR0jBBgwFoAUxPucKXuXzUyW"
+ + "/O5bs8qZdIuV6kwwHQYDVR0OBBYEFMT7nCl7l81MlvzuW7PKmXSLlepMMAwG"
+ + "A1UdEwQFMAMBAf8wGQYJKoZIhvZ9B0EABAwwChsEVjQuMAMCBJAwDQYJKoZI"
+ + "hvcNAQEEBQADgYEAP66K8ddmAwWePvrqHEa7pFuPeJoSSJn59DXeDDYHAmsQ"
+ + "OokUgZwxpnyyQbJq5wcBoUv5nyU7lsqZwz6hURzzwy5E97BnRqqS5TvaHBkU"
+ + "ODDV4qIxJS7x7EU47fgGWANzYrAQMY9Av2TgXD7FTx/aEkP/TOYGJqibGapE"
+ + "PHayXOw=");
+
+ byte[] nameCert = Base64.decode(
+ "MIIEFjCCA3+gAwIBAgIEdS8BozANBgkqhkiG9w0BAQUFADBKMQswCQYDVQQGEwJE"+
+ "RTERMA8GA1UEChQIREFURVYgZUcxKDAMBgcCggYBCgcUEwExMBgGA1UEAxQRQ0Eg"+
+ "REFURVYgRDAzIDE6UE4wIhgPMjAwMTA1MTAxMDIyNDhaGA8yMDA0MDUwOTEwMjI0"+
+ "OFowgYQxCzAJBgNVBAYTAkRFMQ8wDQYDVQQIFAZCYXllcm4xEjAQBgNVBAcUCU7I"+
+ "dXJuYmVyZzERMA8GA1UEChQIREFURVYgZUcxHTAbBgNVBAUTFDAwMDAwMDAwMDA4"+
+ "OTU3NDM2MDAxMR4wHAYDVQQDFBVEaWV0bWFyIFNlbmdlbmxlaXRuZXIwgaEwDQYJ"+
+ "KoZIhvcNAQEBBQADgY8AMIGLAoGBAJLI/LJLKaHoMk8fBECW/od8u5erZi6jI8Ug"+
+ "C0a/LZyQUO/R20vWJs6GrClQtXB+AtfiBSnyZOSYzOdfDI8yEKPEv8qSuUPpOHps"+
+ "uNCFdLZF1vavVYGEEWs2+y+uuPmg8q1oPRyRmUZ+x9HrDvCXJraaDfTEd9olmB/Z"+
+ "AuC/PqpjAgUAwAAAAaOCAcYwggHCMAwGA1UdEwEB/wQCMAAwDwYDVR0PAQH/BAUD"+
+ "AwdAADAxBgNVHSAEKjAoMCYGBSskCAEBMB0wGwYIKwYBBQUHAgEWD3d3dy56cy5k"+
+ "YXRldi5kZTApBgNVHREEIjAggR5kaWV0bWFyLnNlbmdlbmxlaXRuZXJAZGF0ZXYu"+
+ "ZGUwgYQGA1UdIwR9MHuhc6RxMG8xCzAJBgNVBAYTAkRFMT0wOwYDVQQKFDRSZWd1"+
+ "bGllcnVuZ3NiZWjIb3JkZSBmyHVyIFRlbGVrb21tdW5pa2F0aW9uIHVuZCBQb3N0"+
+ "MSEwDAYHAoIGAQoHFBMBMTARBgNVBAMUCjVSLUNBIDE6UE6CBACm8LkwDgYHAoIG"+
+ "AQoMAAQDAQEAMEcGA1UdHwRAMD4wPKAUoBKGEHd3dy5jcmwuZGF0ZXYuZGWiJKQi"+
+ "MCAxCzAJBgNVBAYTAkRFMREwDwYDVQQKFAhEQVRFViBlRzAWBgUrJAgDBAQNMAsT"+
+ "A0VVUgIBBQIBATAdBgNVHQ4EFgQUfv6xFP0xk7027folhy+ziZvBJiwwLAYIKwYB"+
+ "BQUHAQEEIDAeMBwGCCsGAQUFBzABhhB3d3cuZGlyLmRhdGV2LmRlMA0GCSqGSIb3"+
+ "DQEBBQUAA4GBAEOVX6uQxbgtKzdgbTi6YLffMftFr2mmNwch7qzpM5gxcynzgVkg"+
+ "pnQcDNlm5AIbS6pO8jTCLfCd5TZ5biQksBErqmesIl3QD+VqtB+RNghxectZ3VEs"+
+ "nCUtcE7tJ8O14qwCb3TxS9dvIUFiVi4DjbxX46TdcTbTaK8/qr6AIf+l");
+
+ byte[] probSelfSignedCert = Base64.decode(
+ "MIICxTCCAi6gAwIBAgIQAQAAAAAAAAAAAAAAAAAAATANBgkqhkiG9w0BAQUFADBF"
+ + "MScwJQYDVQQKEx4gRElSRUNUSU9OIEdFTkVSQUxFIERFUyBJTVBPVFMxGjAYBgNV"
+ + "BAMTESBBQyBNSU5FRkkgQiBURVNUMB4XDTA0MDUwNzEyMDAwMFoXDTE0MDUwNzEy"
+ + "MDAwMFowRTEnMCUGA1UEChMeIERJUkVDVElPTiBHRU5FUkFMRSBERVMgSU1QT1RT"
+ + "MRowGAYDVQQDExEgQUMgTUlORUZJIEIgVEVTVDCBnzANBgkqhkiG9w0BAQEFAAOB"
+ + "jQAwgYkCgYEAveoCUOAukZdcFCs2qJk76vSqEX0ZFzHqQ6faBPZWjwkgUNwZ6m6m"
+ + "qWvvyq1cuxhoDvpfC6NXILETawYc6MNwwxsOtVVIjuXlcF17NMejljJafbPximEt"
+ + "DQ4LcQeSp4K7FyFlIAMLyt3BQ77emGzU5fjFTvHSUNb3jblx0sV28c0CAwEAAaOB"
+ + "tTCBsjAfBgNVHSMEGDAWgBSEJ4bLbvEQY8cYMAFKPFD1/fFXlzAdBgNVHQ4EFgQU"
+ + "hCeGy27xEGPHGDABSjxQ9f3xV5cwDgYDVR0PAQH/BAQDAgEGMBEGCWCGSAGG+EIB"
+ + "AQQEAwIBBjA8BgNVHR8ENTAzMDGgL6AthitodHRwOi8vYWRvbmlzLnBrNy5jZXJ0"
+ + "cGx1cy5uZXQvZGdpLXRlc3QuY3JsMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcN"
+ + "AQEFBQADgYEAmToHJWjd3+4zknfsP09H6uMbolHNGG0zTS2lrLKpzcmkQfjhQpT9"
+ + "LUTBvfs1jdjo9fGmQLvOG+Sm51Rbjglb8bcikVI5gLbclOlvqLkm77otjl4U4Z2/"
+ + "Y0vP14Aov3Sn3k+17EfReYUZI4liuB95ncobC4e8ZM++LjQcIM0s+Vs=");
+
+
+ byte[] gost34102001base = Base64.decode(
+ "MIIB1DCCAYECEEjpVKXP6Wn1yVz3VeeDQa8wCgYGKoUDAgIDBQAwbTEfMB0G"
+ + "A1UEAwwWR29zdFIzNDEwLTIwMDEgZXhhbXBsZTESMBAGA1UECgwJQ3J5cHRv"
+ + "UHJvMQswCQYDVQQGEwJSVTEpMCcGCSqGSIb3DQEJARYaR29zdFIzNDEwLTIw"
+ + "MDFAZXhhbXBsZS5jb20wHhcNMDUwMjAzMTUxNjQ2WhcNMTUwMjAzMTUxNjQ2"
+ + "WjBtMR8wHQYDVQQDDBZHb3N0UjM0MTAtMjAwMSBleGFtcGxlMRIwEAYDVQQK"
+ + "DAlDcnlwdG9Qcm8xCzAJBgNVBAYTAlJVMSkwJwYJKoZIhvcNAQkBFhpHb3N0"
+ + "UjM0MTAtMjAwMUBleGFtcGxlLmNvbTBjMBwGBiqFAwICEzASBgcqhQMCAiQA"
+ + "BgcqhQMCAh4BA0MABECElWh1YAIaQHUIzROMMYks/eUFA3pDXPRtKw/nTzJ+"
+ + "V4/rzBa5lYgD0Jp8ha4P5I3qprt+VsfLsN8PZrzK6hpgMAoGBiqFAwICAwUA"
+ + "A0EAHw5dw/aw/OiNvHyOE65kvyo4Hp0sfz3csM6UUkp10VO247ofNJK3tsLb"
+ + "HOLjUaqzefrlGb11WpHYrvWFg+FcLA==");
+
+ byte[] gost341094base = Base64.decode(
+ "MIICDzCCAbwCEBcxKsIb0ghYvAQeUjfQdFAwCgYGKoUDAgIEBQAwaTEdMBsG"
+ + "A1UEAwwUR29zdFIzNDEwLTk0IGV4YW1wbGUxEjAQBgNVBAoMCUNyeXB0b1By"
+ + "bzELMAkGA1UEBhMCUlUxJzAlBgkqhkiG9w0BCQEWGEdvc3RSMzQxMC05NEBl"
+ + "eGFtcGxlLmNvbTAeFw0wNTAyMDMxNTE2NTFaFw0xNTAyMDMxNTE2NTFaMGkx"
+ + "HTAbBgNVBAMMFEdvc3RSMzQxMC05NCBleGFtcGxlMRIwEAYDVQQKDAlDcnlw"
+ + "dG9Qcm8xCzAJBgNVBAYTAlJVMScwJQYJKoZIhvcNAQkBFhhHb3N0UjM0MTAt"
+ + "OTRAZXhhbXBsZS5jb20wgaUwHAYGKoUDAgIUMBIGByqFAwICIAIGByqFAwIC"
+ + "HgEDgYQABIGAu4Rm4XmeWzTYLIB/E6gZZnFX/oxUJSFHbzALJ3dGmMb7R1W+"
+ + "t7Lzk2w5tUI3JoTiDRCKJA4fDEJNKzsRK6i/ZjkyXJSLwaj+G2MS9gklh8x1"
+ + "G/TliYoJgmjTXHemD7aQEBON4z58nJHWrA0ILD54wbXCtrcaqCqLRYGTMjJ2"
+ + "+nswCgYGKoUDAgIEBQADQQBxKNhOmjgz/i5CEgLOyKyz9pFGkDcaymsWYQWV"
+ + "v7CZ0pTM8IzMzkUBW3GHsUjCFpanFZDfg2zuN+3kT+694n9B");
+
+ byte[] gost341094A = Base64.decode(
+ "MIICSDCCAfWgAwIBAgIBATAKBgYqhQMCAgQFADCBgTEXMBUGA1UEAxMOZGVmYXVsdDM0MTAtOTQx"
+ + "DTALBgNVBAoTBERpZ3QxDzANBgNVBAsTBkNyeXB0bzEOMAwGA1UEBxMFWS1vbGExDDAKBgNVBAgT"
+ + "A01FTDELMAkGA1UEBhMCcnUxGzAZBgkqhkiG9w0BCQEWDHRlc3RAdGVzdC5ydTAeFw0wNTAzMjkx"
+ + "MzExNTdaFw0wNjAzMjkxMzExNTdaMIGBMRcwFQYDVQQDEw5kZWZhdWx0MzQxMC05NDENMAsGA1UE"
+ + "ChMERGlndDEPMA0GA1UECxMGQ3J5cHRvMQ4wDAYDVQQHEwVZLW9sYTEMMAoGA1UECBMDTUVMMQsw"
+ + "CQYDVQQGEwJydTEbMBkGCSqGSIb3DQEJARYMdGVzdEB0ZXN0LnJ1MIGlMBwGBiqFAwICFDASBgcq"
+ + "hQMCAiACBgcqhQMCAh4BA4GEAASBgIQACDLEuxSdRDGgdZxHmy30g/DUYkRxO9Mi/uSHX5NjvZ31"
+ + "b7JMEMFqBtyhql1HC5xZfUwZ0aT3UnEFDfFjLP+Bf54gA+LPkQXw4SNNGOj+klnqgKlPvoqMGlwa"
+ + "+hLPKbS561WpvB2XSTgbV+pqqXR3j6j30STmybelEV3RdS2Now8wDTALBgNVHQ8EBAMCB4AwCgYG"
+ + "KoUDAgIEBQADQQBCFy7xWRXtNVXflKvDs0pBdBuPzjCMeZAXVxK8vUxsxxKu76d9CsvhgIFknFRi"
+ + "wWTPiZenvNoJ4R1uzeX+vREm");
+
+ byte[] gost341094B = Base64.decode(
+ "MIICSDCCAfWgAwIBAgIBATAKBgYqhQMCAgQFADCBgTEXMBUGA1UEAxMOcGFyYW0xLTM0MTAtOTQx"
+ + "DTALBgNVBAoTBERpZ3QxDzANBgNVBAsTBkNyeXB0bzEOMAwGA1UEBxMFWS1PbGExDDAKBgNVBAgT"
+ + "A01lbDELMAkGA1UEBhMCcnUxGzAZBgkqhkiG9w0BCQEWDHRlc3RAdGVzdC5ydTAeFw0wNTAzMjkx"
+ + "MzEzNTZaFw0wNjAzMjkxMzEzNTZaMIGBMRcwFQYDVQQDEw5wYXJhbTEtMzQxMC05NDENMAsGA1UE"
+ + "ChMERGlndDEPMA0GA1UECxMGQ3J5cHRvMQ4wDAYDVQQHEwVZLU9sYTEMMAoGA1UECBMDTWVsMQsw"
+ + "CQYDVQQGEwJydTEbMBkGCSqGSIb3DQEJARYMdGVzdEB0ZXN0LnJ1MIGlMBwGBiqFAwICFDASBgcq"
+ + "hQMCAiADBgcqhQMCAh4BA4GEAASBgEa+AAcZmijWs1M9x5Pn9efE8D9ztG1NMoIt0/hNZNqln3+j"
+ + "lMZjyqPt+kTLIjtmvz9BRDmIDk6FZz+4LhG2OTL7yGpWfrMxMRr56nxomTN9aLWRqbyWmn3brz9Y"
+ + "AUD3ifnwjjIuW7UM84JNlDTOdxx0XRUfLQIPMCXe9cO02Xskow8wDTALBgNVHQ8EBAMCB4AwCgYG"
+ + "KoUDAgIEBQADQQBzFcnuYc/639OTW+L5Ecjw9KxGr+dwex7lsS9S1BUgKa3m1d5c+cqI0B2XUFi5"
+ + "4iaHHJG0dCyjtQYLJr0OZjRw");
+
+ byte[] gost34102001A = Base64.decode(
+ "MIICCzCCAbigAwIBAgIBATAKBgYqhQMCAgMFADCBhDEaMBgGA1UEAxMRZGVmYXVsdC0zNDEwLTIw"
+ + "MDExDTALBgNVBAoTBERpZ3QxDzANBgNVBAsTBkNyeXB0bzEOMAwGA1UEBxMFWS1PbGExDDAKBgNV"
+ + "BAgTA01lbDELMAkGA1UEBhMCcnUxGzAZBgkqhkiG9w0BCQEWDHRlc3RAdGVzdC5ydTAeFw0wNTAz"
+ + "MjkxMzE4MzFaFw0wNjAzMjkxMzE4MzFaMIGEMRowGAYDVQQDExFkZWZhdWx0LTM0MTAtMjAwMTEN"
+ + "MAsGA1UEChMERGlndDEPMA0GA1UECxMGQ3J5cHRvMQ4wDAYDVQQHEwVZLU9sYTEMMAoGA1UECBMD"
+ + "TWVsMQswCQYDVQQGEwJydTEbMBkGCSqGSIb3DQEJARYMdGVzdEB0ZXN0LnJ1MGMwHAYGKoUDAgIT"
+ + "MBIGByqFAwICIwEGByqFAwICHgEDQwAEQG/4c+ZWb10IpeHfmR+vKcbpmSOClJioYmCVgnojw0Xn"
+ + "ned0KTg7TJreRUc+VX7vca4hLQaZ1o/TxVtfEApK/O6jDzANMAsGA1UdDwQEAwIHgDAKBgYqhQMC"
+ + "AgMFAANBAN8y2b6HuIdkD3aWujpfQbS1VIA/7hro4vLgDhjgVmev/PLzFB8oTh3gKhExpDo82IEs"
+ + "ZftGNsbbyp1NFg7zda0=");
+
+ byte[] gostCA1 = Base64.decode(
+ "MIIDNDCCAuGgAwIBAgIQZLcKDcWcQopF+jp4p9jylDAKBgYqhQMCAgQFADBm"
+ + "MQswCQYDVQQGEwJSVTEPMA0GA1UEBxMGTW9zY293MRcwFQYDVQQKEw5PT08g"
+ + "Q3J5cHRvLVBybzEUMBIGA1UECxMLRGV2ZWxvcG1lbnQxFzAVBgNVBAMTDkNQ"
+ + "IENTUCBUZXN0IENBMB4XDTAyMDYwOTE1NTIyM1oXDTA5MDYwOTE1NTkyOVow"
+ + "ZjELMAkGA1UEBhMCUlUxDzANBgNVBAcTBk1vc2NvdzEXMBUGA1UEChMOT09P"
+ + "IENyeXB0by1Qcm8xFDASBgNVBAsTC0RldmVsb3BtZW50MRcwFQYDVQQDEw5D"
+ + "UCBDU1AgVGVzdCBDQTCBpTAcBgYqhQMCAhQwEgYHKoUDAgIgAgYHKoUDAgIe"
+ + "AQOBhAAEgYAYglywKuz1nMc9UiBYOaulKy53jXnrqxZKbCCBSVaJ+aCKbsQm"
+ + "glhRFrw6Mwu8Cdeabo/ojmea7UDMZd0U2xhZFRti5EQ7OP6YpqD0alllo7za"
+ + "4dZNXdX+/ag6fOORSLFdMpVx5ganU0wHMPk67j+audnCPUj/plbeyccgcdcd"
+ + "WaOCASIwggEeMAsGA1UdDwQEAwIBxjAPBgNVHRMBAf8EBTADAQH/MB0GA1Ud"
+ + "DgQWBBTe840gTo4zt2twHilw3PD9wJaX0TCBygYDVR0fBIHCMIG/MDygOqA4"
+ + "hjYtaHR0cDovL2ZpZXdhbGwvQ2VydEVucm9sbC9DUCUyMENTUCUyMFRlc3Ql"
+ + "MjBDQSgzKS5jcmwwRKBCoECGPmh0dHA6Ly93d3cuY3J5cHRvcHJvLnJ1L0Nl"
+ + "cnRFbnJvbGwvQ1AlMjBDU1AlMjBUZXN0JTIwQ0EoMykuY3JsMDmgN6A1hjMt"
+ + "ZmlsZTovL1xcZmlld2FsbFxDZXJ0RW5yb2xsXENQIENTUCBUZXN0IENBKDMp"
+ + "LmNybC8wEgYJKwYBBAGCNxUBBAUCAwMAAzAKBgYqhQMCAgQFAANBAIJi7ni7"
+ + "9rwMR5rRGTFftt2k70GbqyUEfkZYOzrgdOoKiB4IIsIstyBX0/ne6GsL9Xan"
+ + "G2IN96RB7KrowEHeW+k=");
+
+ byte[] gostCA2 = Base64.decode(
+ "MIIC2DCCAoWgAwIBAgIQe9ZCugm42pRKNcHD8466zTAKBgYqhQMCAgMFADB+"
+ + "MRowGAYJKoZIhvcNAQkBFgtzYmFAZGlndC5ydTELMAkGA1UEBhMCUlUxDDAK"
+ + "BgNVBAgTA01FTDEUMBIGA1UEBxMLWW9zaGthci1PbGExDTALBgNVBAoTBERp"
+ + "Z3QxDzANBgNVBAsTBkNyeXB0bzEPMA0GA1UEAxMGc2JhLUNBMB4XDTA0MDgw"
+ + "MzEzMzE1OVoXDTE0MDgwMzEzNDAxMVowfjEaMBgGCSqGSIb3DQEJARYLc2Jh"
+ + "QGRpZ3QucnUxCzAJBgNVBAYTAlJVMQwwCgYDVQQIEwNNRUwxFDASBgNVBAcT"
+ + "C1lvc2hrYXItT2xhMQ0wCwYDVQQKEwREaWd0MQ8wDQYDVQQLEwZDcnlwdG8x"
+ + "DzANBgNVBAMTBnNiYS1DQTBjMBwGBiqFAwICEzASBgcqhQMCAiMBBgcqhQMC"
+ + "Ah4BA0MABEDMSy10CuOH+i8QKG2UWA4XmCt6+BFrNTZQtS6bOalyDY8Lz+G7"
+ + "HybyipE3PqdTB4OIKAAPsEEeZOCZd2UXGQm5o4HaMIHXMBMGCSsGAQQBgjcU"
+ + "AgQGHgQAQwBBMAsGA1UdDwQEAwIBhjAPBgNVHRMBAf8EBTADAQH/MB0GA1Ud"
+ + "DgQWBBRJJl3LcNMxkZI818STfoi3ng1xoDBxBgNVHR8EajBoMDGgL6Athito"
+ + "dHRwOi8vc2JhLmRpZ3QubG9jYWwvQ2VydEVucm9sbC9zYmEtQ0EuY3JsMDOg"
+ + "MaAvhi1maWxlOi8vXFxzYmEuZGlndC5sb2NhbFxDZXJ0RW5yb2xsXHNiYS1D"
+ + "QS5jcmwwEAYJKwYBBAGCNxUBBAMCAQAwCgYGKoUDAgIDBQADQQA+BRJHbc/p"
+ + "q8EYl6iJqXCuR+ozRmH7hPAP3c4KqYSC38TClCgBloLapx/3/WdatctFJW/L"
+ + "mcTovpq088927shE");
+
+ byte[] inDirectCrl = Base64.decode(
+ "MIIdXjCCHMcCAQEwDQYJKoZIhvcNAQEFBQAwdDELMAkGA1UEBhMCREUxHDAaBgNV"
+ +"BAoUE0RldXRzY2hlIFRlbGVrb20gQUcxFzAVBgNVBAsUDlQtVGVsZVNlYyBUZXN0"
+ +"MS4wDAYHAoIGAQoHFBMBMTAeBgNVBAMUF1QtVGVsZVNlYyBUZXN0IERJUiA4OlBO"
+ +"Fw0wNjA4MDQwODQ1MTRaFw0wNjA4MDQxNDQ1MTRaMIIbfzB+AgQvrj/pFw0wMzA3"
+ +"MjIwNTQxMjhaMGcwZQYDVR0dAQH/BFswWaRXMFUxCzAJBgNVBAYTAkRFMRwwGgYD"
+ +"VQQKFBNEZXV0c2NoZSBUZWxla29tIEFHMSgwDAYHAoIGAQoHFBMBMTAYBgNVBAMU"
+ +"EVNpZ0cgVGVzdCBDQSA0OlBOMH4CBC+uP+oXDTAzMDcyMjA1NDEyOFowZzBlBgNV"
+ +"HR0BAf8EWzBZpFcwVTELMAkGA1UEBhMCREUxHDAaBgNVBAoUE0RldXRzY2hlIFRl"
+ +"bGVrb20gQUcxKDAMBgcCggYBCgcUEwExMBgGA1UEAxQRU2lnRyBUZXN0IENBIDQ6"
+ +"UE4wfgIEL64/5xcNMDQwNDA1MTMxODE3WjBnMGUGA1UdHQEB/wRbMFmkVzBVMQsw"
+ +"CQYDVQQGEwJERTEcMBoGA1UEChQTRGV1dHNjaGUgVGVsZWtvbSBBRzEoMAwGBwKC"
+ +"BgEKBxQTATEwGAYDVQQDFBFTaWdHIFRlc3QgQ0EgNDpQTjB+AgQvrj/oFw0wNDA0"
+ +"MDUxMzE4MTdaMGcwZQYDVR0dAQH/BFswWaRXMFUxCzAJBgNVBAYTAkRFMRwwGgYD"
+ +"VQQKFBNEZXV0c2NoZSBUZWxla29tIEFHMSgwDAYHAoIGAQoHFBMBMTAYBgNVBAMU"
+ +"EVNpZ0cgVGVzdCBDQSA0OlBOMH4CBC+uP+UXDTAzMDExMzExMTgxMVowZzBlBgNV"
+ +"HR0BAf8EWzBZpFcwVTELMAkGA1UEBhMCREUxHDAaBgNVBAoUE0RldXRzY2hlIFRl"
+ +"bGVrb20gQUcxKDAMBgcCggYBCgcUEwExMBgGA1UEAxQRU2lnRyBUZXN0IENBIDQ6"
+ +"UE4wfgIEL64/5hcNMDMwMTEzMTExODExWjBnMGUGA1UdHQEB/wRbMFmkVzBVMQsw"
+ +"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");
+
+ byte[] directCRL = Base64.decode(
+ "MIIGXTCCBckCAQEwCgYGKyQDAwECBQAwdDELMAkGA1UEBhMCREUxHDAaBgNVBAoU"
+ +"E0RldXRzY2hlIFRlbGVrb20gQUcxFzAVBgNVBAsUDlQtVGVsZVNlYyBUZXN0MS4w"
+ +"DAYHAoIGAQoHFBMBMTAeBgNVBAMUF1QtVGVsZVNlYyBUZXN0IERJUiA4OlBOFw0w"
+ +"NjA4MDQwODQ1MTRaFw0wNjA4MDQxNDQ1MTRaMIIElTAVAgQvrj/pFw0wMzA3MjIw"
+ +"NTQxMjhaMBUCBC+uP+oXDTAzMDcyMjA1NDEyOFowFQIEL64/5xcNMDQwNDA1MTMx"
+ +"ODE3WjAVAgQvrj/oFw0wNDA0MDUxMzE4MTdaMBUCBC+uP+UXDTAzMDExMzExMTgx"
+ +"MVowFQIEL64/5hcNMDMwMTEzMTExODExWjAVAgQvrj/jFw0wMzAxMTMxMTI2NTZa"
+ +"MBUCBC+uP+QXDTAzMDExMzExMjY1NlowFQIEL64/4hcNMDQwNzEzMDc1ODM4WjAV"
+ +"AgQvrj/eFw0wMzAyMTcwNjMzMjVaMBUCBC+uP98XDTAzMDIxNzA2MzMyNVowFQIE"
+ +"L64/0xcNMDMwMjE3MDYzMzI1WjAVAgQvrj/dFw0wMzAxMTMxMTI4MTRaMBUCBC+u"
+ +"P9cXDTAzMDExMzExMjcwN1owFQIEL64/2BcNMDMwMTEzMTEyNzA3WjAVAgQvrj/V"
+ +"Fw0wMzA0MzAxMjI3NTNaMBUCBC+uP9YXDTAzMDQzMDEyMjc1M1owFQIEL64/xhcN"
+ +"MDMwMjEyMTM0NTQwWjAVAgQvrj/FFw0wMzAyMTIxMzQ1NDBaMBUCBC+uP8IXDTAz"
+ +"MDIxMjEzMDkxNlowFQIEL64/wRcNMDMwMjEyMTMwODQwWjAVAgQvrj++Fw0wMzAy"
+ +"MTcwNjM3MjVaMBUCBC+uP70XDTAzMDIxNzA2MzcyNVowFQIEL64/sBcNMDMwMjEy"
+ +"MTMwODU5WjAVAgQvrj+vFw0wMzAyMTcwNjM3MjVaMBUCBC+uP5MXDTAzMDQxMDA1"
+ +"MjYyOFowFQIEL64/khcNMDMwNDEwMDUyNjI4WjAVAgQvrj8/Fw0wMzAyMjYxMTA0"
+ +"NDRaMBUCBC+uPz4XDTAzMDIyNjExMDQ0NFowFQIEL64+zRcNMDMwNTIwMDUyNzM2"
+ +"WjAVAgQvrj7MFw0wMzA1MjAwNTI3MzZaMBUCBC+uPjwXDTAzMDYxNzEwMzQxNlow"
+ +"FQIEL64+OxcNMDMwNjE3MTAzNDE2WjAVAgQvrj46Fw0wMzA2MTcxMDM0MTZaMBUC"
+ +"BC+uPjkXDTAzMDYxNzEzMDEwMFowFQIEL64+OBcNMDMwNjE3MTMwMTAwWjAVAgQv"
+ +"rj43Fw0wMzA2MTcxMzAxMDBaMBUCBC+uPjYXDTAzMDYxNzEzMDEwMFowFQIEL64+"
+ +"MxcNMDMwNjE3MTAzNzQ5WjAVAgQvrj4xFw0wMzA2MTcxMDQyNThaMBUCBC+uPjAX"
+ +"DTAzMDYxNzEwNDI1OFowFQIEL649qRcNMDMxMDIyMTEzMjI0WjAVAgQvrjyyFw0w"
+ +"NTAzMTEwNjQ0MjRaMBUCBC+uPKsXDTA0MDQwMjA3NTQ1M1owFQIEL6466BcNMDUw"
+ +"MTI3MTIwMzI0WjAVAgQvrjq+Fw0wNTAyMTYwNzU3MTZaMBUCBC+uOqcXDTA1MDMx"
+ +"MDA1NTkzNVowFQIEL646PBcNMDUwNTExMTA0OTQ2WjAVAgQvrG3VFw0wNTExMTEx"
+ +"MDAzMjFaMBUCBC+uLmgXDTA2MDEyMzEwMjU1NVowFQIEL64mxxcNMDYwODAxMDk0"
+ +"ODQ0WqCBijCBhzALBgNVHRQEBAICEQwwHwYDVR0jBBgwFoAUA1vI26YMj3njkfCU"
+ +"IXbo244kLjkwVwYDVR0SBFAwToZMbGRhcDovL3Brc2xkYXAudHR0Yy5kZS9vdT1U"
+ +"LVRlbGVTZWMgVGVzdCBESVIgODpQTixvPURldXRzY2hlIFRlbGVrb20gQUcsYz1k"
+ +"ZTAKBgYrJAMDAQIFAAOBgQArj4eMlbAwuA2aS5O4UUUHQMKKdK/dtZi60+LJMiMY"
+ +"ojrMIf4+ZCkgm1Ca0Cd5T15MJxVHhh167Ehn/Hd48pdnAP6Dfz/6LeqkIHGWMHR+"
+ +"z6TXpwWB+P4BdUec1ztz04LypsznrHcLRa91ixg9TZCb1MrOG+InNhleRs1ImXk8"
+ +"MQ==");
+
+ private final byte[] pkcs7CrlProblem = Base64.decode(
+ "MIIwSAYJKoZIhvcNAQcCoIIwOTCCMDUCAQExCzAJBgUrDgMCGgUAMAsGCSqG"
+ + "SIb3DQEHAaCCEsAwggP4MIIC4KADAgECAgF1MA0GCSqGSIb3DQEBBQUAMEUx"
+ + "CzAJBgNVBAYTAlVTMRYwFAYDVQQKEw1HZW9UcnVzdCBJbmMuMR4wHAYDVQQD"
+ + "ExVHZW9UcnVzdCBDQSBmb3IgQWRvYmUwHhcNMDQxMjAyMjEyNTM5WhcNMDYx"
+ + "MjMwMjEyNTM5WjBMMQswCQYDVQQGEwJVUzEVMBMGA1UEChMMR2VvVHJ1c3Qg"
+ + "SW5jMSYwJAYDVQQDEx1HZW9UcnVzdCBBZG9iZSBPQ1NQIFJlc3BvbmRlcjCB"
+ + "nzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEA4gnNYhtw7U6QeVXZODnGhHMj"
+ + "+OgZ0DB393rEk6a2q9kq129IA2e03yKBTfJfQR9aWKc2Qj90dsSqPjvTDHFG"
+ + "Qsagm2FQuhnA3fb1UWhPzeEIdm6bxDsnQ8nWqKqxnWZzELZbdp3I9bBLizIq"
+ + "obZovzt60LNMghn/unvvuhpeVSsCAwEAAaOCAW4wggFqMA4GA1UdDwEB/wQE"
+ + "AwIE8DCB5QYDVR0gAQH/BIHaMIHXMIHUBgkqhkiG9y8BAgEwgcYwgZAGCCsG"
+ + "AQUFBwICMIGDGoGAVGhpcyBjZXJ0aWZpY2F0ZSBoYXMgYmVlbiBpc3N1ZWQg"
+ + "aW4gYWNjb3JkYW5jZSB3aXRoIHRoZSBBY3JvYmF0IENyZWRlbnRpYWxzIENQ"
+ + "UyBsb2NhdGVkIGF0IGh0dHA6Ly93d3cuZ2VvdHJ1c3QuY29tL3Jlc291cmNl"
+ + "cy9jcHMwMQYIKwYBBQUHAgEWJWh0dHA6Ly93d3cuZ2VvdHJ1c3QuY29tL3Jl"
+ + "c291cmNlcy9jcHMwEwYDVR0lBAwwCgYIKwYBBQUHAwkwOgYDVR0fBDMwMTAv"
+ + "oC2gK4YpaHR0cDovL2NybC5nZW90cnVzdC5jb20vY3Jscy9hZG9iZWNhMS5j"
+ + "cmwwHwYDVR0jBBgwFoAUq4BZw2WDbR19E70Zw+wajw1HaqMwDQYJKoZIhvcN"
+ + "AQEFBQADggEBAENJf1BD7PX5ivuaawt90q1OGzXpIQL/ClzEeFVmOIxqPc1E"
+ + "TFRq92YuxG5b6+R+k+tGkmCwPLcY8ipg6ZcbJ/AirQhohzjlFuT6YAXsTfEj"
+ + "CqEZfWM2sS7crK2EYxCMmKE3xDfPclYtrAoz7qZvxfQj0TuxHSstHZv39wu2"
+ + "ZiG1BWiEcyDQyTgqTOXBoZmfJtshuAcXmTpgkrYSrS37zNlPTGh+pMYQ0yWD"
+ + "c8OQRJR4OY5ZXfdna01mjtJTOmj6/6XPoLPYTq2gQrc2BCeNJ4bEhLb7sFVB"
+ + "PbwPrpzTE/HRbQHDrzj0YimDxeOUV/UXctgvYwHNtEkcBLsOm/uytMYwggSh"
+ + "MIIDiaADAgECAgQ+HL0oMA0GCSqGSIb3DQEBBQUAMGkxCzAJBgNVBAYTAlVT"
+ + "MSMwIQYDVQQKExpBZG9iZSBTeXN0ZW1zIEluY29ycG9yYXRlZDEdMBsGA1UE"
+ + "CxMUQWRvYmUgVHJ1c3QgU2VydmljZXMxFjAUBgNVBAMTDUFkb2JlIFJvb3Qg"
+ + "Q0EwHhcNMDMwMTA4MjMzNzIzWhcNMjMwMTA5MDAwNzIzWjBpMQswCQYDVQQG"
+ + "EwJVUzEjMCEGA1UEChMaQWRvYmUgU3lzdGVtcyBJbmNvcnBvcmF0ZWQxHTAb"
+ + "BgNVBAsTFEFkb2JlIFRydXN0IFNlcnZpY2VzMRYwFAYDVQQDEw1BZG9iZSBS"
+ + "b290IENBMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAzE9UhPen"
+ + "ouczU38/nBKIayyZR2d+Dx65rRSI+cMQ2B3w8NWfaQovWTWwzGypTJwVoJ/O"
+ + "IL+gz1Ti4CBmRT85hjh+nMSOByLGJPYBErA131XqaZCw24U3HuJOB7JCoWoT"
+ + "aaBm6oCREVkqmwh5WiBELcm9cziLPC/gQxtdswvwrzUaKf7vppLdgUydPVmO"
+ + "rTE8QH6bkTYG/OJcjdGNJtVcRc+vZT+xqtJilvSoOOq6YEL09BxKNRXO+E4i"
+ + "Vg+VGMX4lp+f+7C3eCXpgGu91grwxnSUnfMPUNuad85LcIMjjaDKeCBEXDxU"
+ + "ZPHqojAZn+pMBk0GeEtekt8i0slns3rSAQIDAQABo4IBTzCCAUswEQYJYIZI"
+ + "AYb4QgEBBAQDAgAHMIGOBgNVHR8EgYYwgYMwgYCgfqB8pHoweDELMAkGA1UE"
+ + "BhMCVVMxIzAhBgNVBAoTGkFkb2JlIFN5c3RlbXMgSW5jb3Jwb3JhdGVkMR0w"
+ + "GwYDVQQLExRBZG9iZSBUcnVzdCBTZXJ2aWNlczEWMBQGA1UEAxMNQWRvYmUg"
+ + "Um9vdCBDQTENMAsGA1UEAxMEQ1JMMTArBgNVHRAEJDAigA8yMDAzMDEwODIz"
+ + "MzcyM1qBDzIwMjMwMTA5MDAwNzIzWjALBgNVHQ8EBAMCAQYwHwYDVR0jBBgw"
+ + "FoAUgrc4SpOqmxDvgLvZVOLxD/uAnN4wHQYDVR0OBBYEFIK3OEqTqpsQ74C7"
+ + "2VTi8Q/7gJzeMAwGA1UdEwQFMAMBAf8wHQYJKoZIhvZ9B0EABBAwDhsIVjYu"
+ + "MDo0LjADAgSQMA0GCSqGSIb3DQEBBQUAA4IBAQAy2p9DdcH6b8lv26sdNjc+"
+ + "vGEZNrcCPB0jWZhsnu5NhedUyCAfp9S74r8Ad30ka3AvXME6dkm10+AjhCpx"
+ + "aiLzwScpmBX2NZDkBEzDjbyfYRzn/SSM0URDjBa6m02l1DUvvBHOvfdRN42f"
+ + "kOQU8Rg/vulZEjX5M5LznuDVa5pxm5lLyHHD4bFhCcTl+pHwQjo3fTT5cujN"
+ + "qmIcIenV9IIQ43sFti1oVgt+fpIsb01yggztVnSynbmrLSsdEF/bJ3Vwj/0d"
+ + "1+ICoHnlHOX/r2RAUS2em0fbQqV8H8KmSLDXvpJpTaT2KVfFeBEY3IdRyhOy"
+ + "Yp1PKzK9MaXB+lKrBYjIMIIEyzCCA7OgAwIBAgIEPhy9tTANBgkqhkiG9w0B"
+ + "AQUFADBpMQswCQYDVQQGEwJVUzEjMCEGA1UEChMaQWRvYmUgU3lzdGVtcyBJ"
+ + "bmNvcnBvcmF0ZWQxHTAbBgNVBAsTFEFkb2JlIFRydXN0IFNlcnZpY2VzMRYw"
+ + "FAYDVQQDEw1BZG9iZSBSb290IENBMB4XDTA0MDExNzAwMDMzOVoXDTE1MDEx"
+ + "NTA4MDAwMFowRTELMAkGA1UEBhMCVVMxFjAUBgNVBAoTDUdlb1RydXN0IElu"
+ + "Yy4xHjAcBgNVBAMTFUdlb1RydXN0IENBIGZvciBBZG9iZTCCASIwDQYJKoZI"
+ + "hvcNAQEBBQADggEPADCCAQoCggEBAKfld+BkeFrnOYW8r9L1WygTDlTdSfrO"
+ + "YvWS/Z6Ye5/l+HrBbOHqQCXBcSeCpz7kB2WdKMh1FOE4e9JlmICsHerBLdWk"
+ + "emU+/PDb69zh8E0cLoDfxukF6oVPXj6WSThdSG7H9aXFzRr6S3XGCuvgl+Qw"
+ + "DTLiLYW+ONF6DXwt3TQQtKReJjOJZk46ZZ0BvMStKyBaeB6DKZsmiIo89qso"
+ + "13VDZINH2w1KvXg0ygDizoNtbvgAPFymwnsINS1klfQlcvn0x0RJm9bYQXK3"
+ + "5GNZAgL3M7Lqrld0jMfIUaWvuHCLyivytRuzq1dJ7E8rmidjDEk/G+27pf13"
+ + "fNZ7vR7M+IkCAwEAAaOCAZ0wggGZMBIGA1UdEwEB/wQIMAYBAf8CAQEwUAYD"
+ + "VR0gBEkwRzBFBgkqhkiG9y8BAgEwODA2BggrBgEFBQcCARYqaHR0cHM6Ly93"
+ + "d3cuYWRvYmUuY29tL21pc2MvcGtpL2Nkc19jcC5odG1sMBQGA1UdJQQNMAsG"
+ + "CSqGSIb3LwEBBTCBsgYDVR0fBIGqMIGnMCKgIKAehhxodHRwOi8vY3JsLmFk"
+ + "b2JlLmNvbS9jZHMuY3JsMIGAoH6gfKR6MHgxCzAJBgNVBAYTAlVTMSMwIQYD"
+ + "VQQKExpBZG9iZSBTeXN0ZW1zIEluY29ycG9yYXRlZDEdMBsGA1UECxMUQWRv"
+ + "YmUgVHJ1c3QgU2VydmljZXMxFjAUBgNVBAMTDUFkb2JlIFJvb3QgQ0ExDTAL"
+ + "BgNVBAMTBENSTDEwCwYDVR0PBAQDAgEGMB8GA1UdIwQYMBaAFIK3OEqTqpsQ"
+ + "74C72VTi8Q/7gJzeMB0GA1UdDgQWBBSrgFnDZYNtHX0TvRnD7BqPDUdqozAZ"
+ + "BgkqhkiG9n0HQQAEDDAKGwRWNi4wAwIEkDANBgkqhkiG9w0BAQUFAAOCAQEA"
+ + "PzlZLqIAjrFeEWEs0uC29YyJhkXOE9mf3YSaFGsITF+Gl1j0pajTjyH4R35Q"
+ + "r3floW2q3HfNzTeZ90Jnr1DhVERD6zEMgJpCtJqVuk0sixuXJHghS/KicKf4"
+ + "YXJJPx9epuIRF1siBRnznnF90svmOJMXApc0jGnYn3nQfk4kaShSnDaYaeYR"
+ + "DJKcsiWhl6S5zfwS7Gg8hDeyckhMQKKWnlG1CQrwlSFisKCduoodwRtWgft8"
+ + "kx13iyKK3sbalm6vnVc+5nufS4vI+TwMXoV63NqYaSroafBWk0nL53zGXPEy"
+ + "+A69QhzEViJKn2Wgqt5gt++jMMNImbRObIqgfgF1VjCCBUwwggQ0oAMCAQIC"
+ + "AgGDMA0GCSqGSIb3DQEBBQUAMEUxCzAJBgNVBAYTAlVTMRYwFAYDVQQKEw1H"
+ + "ZW9UcnVzdCBJbmMuMR4wHAYDVQQDExVHZW9UcnVzdCBDQSBmb3IgQWRvYmUw"
+ + "HhcNMDYwMzI0MTU0MjI5WhcNMDkwNDA2MTQ0MjI5WjBzMQswCQYDVQQGEwJV"
+ + "UzELMAkGA1UECBMCTUExETAPBgNVBAoTCEdlb1RydXN0MR0wGwYDVQQDExRN"
+ + "YXJrZXRpbmcgRGVwYXJ0bWVudDElMCMGCSqGSIb3DQEJARYWbWFya2V0aW5n"
+ + "QGdlb3RydXN0LmNvbTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEB"
+ + "ANmvajTO4XJvAU2nVcLmXeCnAQX7RZt+7+ML3InmqQ3LCGo1weop09zV069/"
+ + "1x/Nmieol7laEzeXxd2ghjGzwfXafqQEqHn6+vBCvqdNPoSi63fSWhnuDVWp"
+ + "KVDOYgxOonrXl+Cc43lu4zRSq+Pi5phhrjDWcH74a3/rdljUt4c4GFezFXfa"
+ + "w2oTzWkxj2cTSn0Szhpr17+p66UNt8uknlhmu4q44Speqql2HwmCEnpLYJrK"
+ + "W3fOq5D4qdsvsLR2EABLhrBezamLI3iGV8cRHOUTsbTMhWhv/lKfHAyf4XjA"
+ + "z9orzvPN5jthhIfICOFq/nStTgakyL4Ln+nFAB/SMPkCAwEAAaOCAhYwggIS"
+ + "MA4GA1UdDwEB/wQEAwIF4DCB5QYDVR0gAQH/BIHaMIHXMIHUBgkqhkiG9y8B"
+ + "AgEwgcYwgZAGCCsGAQUFBwICMIGDGoGAVGhpcyBjZXJ0aWZpY2F0ZSBoYXMg"
+ + "YmVlbiBpc3N1ZWQgaW4gYWNjb3JkYW5jZSB3aXRoIHRoZSBBY3JvYmF0IENy"
+ + "ZWRlbnRpYWxzIENQUyBsb2NhdGVkIGF0IGh0dHA6Ly93d3cuZ2VvdHJ1c3Qu"
+ + "Y29tL3Jlc291cmNlcy9jcHMwMQYIKwYBBQUHAgEWJWh0dHA6Ly93d3cuZ2Vv"
+ + "dHJ1c3QuY29tL3Jlc291cmNlcy9jcHMwOgYDVR0fBDMwMTAvoC2gK4YpaHR0"
+ + "cDovL2NybC5nZW90cnVzdC5jb20vY3Jscy9hZG9iZWNhMS5jcmwwHwYDVR0j"
+ + "BBgwFoAUq4BZw2WDbR19E70Zw+wajw1HaqMwRAYIKwYBBQUHAQEEODA2MDQG"
+ + "CCsGAQUFBzABhihodHRwOi8vYWRvYmUtb2NzcC5nZW90cnVzdC5jb20vcmVz"
+ + "cG9uZGVyMBQGA1UdJQQNMAsGCSqGSIb3LwEBBTA8BgoqhkiG9y8BAQkBBC4w"
+ + "LAIBAYYnaHR0cDovL2Fkb2JlLXRpbWVzdGFtcC5nZW90cnVzdC5jb20vdHNh"
+ + "MBMGCiqGSIb3LwEBCQIEBTADAgEBMAwGA1UdEwQFMAMCAQAwDQYJKoZIhvcN"
+ + "AQEFBQADggEBAAOhy6QxOo+i3h877fvDvTa0plGD2bIqK7wMdNqbMDoSWied"
+ + "FIcgcBOIm2wLxOjZBAVj/3lDq59q2rnVeNnfXM0/N0MHI9TumHRjU7WNk9e4"
+ + "+JfJ4M+c3anrWOG3NE5cICDVgles+UHjXetHWql/LlP04+K2ZOLb6LE2xGnI"
+ + "YyLW9REzCYNAVF+/WkYdmyceHtaBZdbyVAJq0NAJPsfgY1pWcBo31Mr1fpX9"
+ + "WrXNTYDCqMyxMImJTmN3iI68tkXlNrhweQoArKFqBysiBkXzG/sGKYY6tWKU"
+ + "pzjLc3vIp/LrXC5zilROes8BSvwu1w9qQrJNcGwo7O4uijoNtyYil1Exgh1Q"
+ + "MIIdTAIBATBLMEUxCzAJBgNVBAYTAlVTMRYwFAYDVQQKEw1HZW9UcnVzdCBJ"
+ + "bmMuMR4wHAYDVQQDExVHZW9UcnVzdCBDQSBmb3IgQWRvYmUCAgGDMAkGBSsO"
+ + "AwIaBQCgggxMMBgGCSqGSIb3DQEJAzELBgkqhkiG9w0BBwEwIwYJKoZIhvcN"
+ + "AQkEMRYEFP4R6qIdpQJzWyzrqO8X1ZfJOgChMIIMCQYJKoZIhvcvAQEIMYIL"
+ + "+jCCC/agggZ5MIIGdTCCA6gwggKQMA0GCSqGSIb3DQEBBQUAMEUxCzAJBgNV"
+ + "BAYTAlVTMRYwFAYDVQQKEw1HZW9UcnVzdCBJbmMuMR4wHAYDVQQDExVHZW9U"
+ + "cnVzdCBDQSBmb3IgQWRvYmUXDTA2MDQwNDE3NDAxMFoXDTA2MDQwNTE3NDAx"
+ + "MFowggIYMBMCAgC5Fw0wNTEwMTEyMDM2MzJaMBICAVsXDTA0MTEwNDE1MDk0"
+ + "MVowEwICALgXDTA1MTIxMjIyMzgzOFowEgIBWhcNMDQxMTA0MTUwOTMzWjAT"
+ + "AgIA5hcNMDUwODI3MDQwOTM4WjATAgIAtxcNMDYwMTE2MTc1NTEzWjATAgIA"
+ + "hhcNMDUxMjEyMjIzODU1WjATAgIAtRcNMDUwNzA2MTgzODQwWjATAgIA4BcN"
+ + "MDYwMzIwMDc0ODM0WjATAgIAgRcNMDUwODAyMjIzMTE1WjATAgIA3xcNMDUx"
+ + "MjEyMjIzNjUwWjASAgFKFw0wNDExMDQxNTA5MTZaMBICAUQXDTA0MTEwNDE1"
+ + "MDg1M1owEgIBQxcNMDQxMDAzMDEwMDQwWjASAgFsFw0wNDEyMDYxOTQ0MzFa"
+ + "MBMCAgEoFw0wNjAzMDkxMjA3MTJaMBMCAgEkFw0wNjAxMTYxNzU1MzRaMBIC"
+ + "AWcXDTA1MDMxODE3NTYxNFowEwICAVEXDTA2MDEzMTExMjcxMVowEgIBZBcN"
+ + "MDQxMTExMjI0ODQxWjATAgIA8RcNMDUwOTE2MTg0ODAxWjATAgIBThcNMDYw"
+ + "MjIxMjAxMDM2WjATAgIAwRcNMDUxMjEyMjIzODE2WjASAgFiFw0wNTAxMTAx"
+ + "NjE5MzRaMBICAWAXDTA1MDExMDE5MDAwNFowEwICAL4XDTA1MDUxNzE0NTYx"
+ + "MFowDQYJKoZIhvcNAQEFBQADggEBAEKhRMS3wVho1U3EvEQJZC8+JlUngmZQ"
+ + "A78KQbHPWNZWFlNvPuf/b0s7Lu16GfNHXh1QAW6Y5Hi1YtYZ3YOPyMd4Xugt"
+ + "gCdumbB6xtKsDyN5RvTht6ByXj+CYlYqsL7RX0izJZ6mJn4fjMkqzPKNOjb8"
+ + "kSn5T6rn93BjlATtCE8tPVOM8dnqGccRE0OV59+nDBXc90UMt5LdEbwaUOap"
+ + "snVB0oLcNm8d/HnlVH6RY5LnDjrT4vwfe/FApZtTecEWsllVUXDjSpwfcfD/"
+ + "476/lpGySB2otALqzImlA9R8Ok3hJ8dnF6hhQ5Oe6OJMnGYgdhkKbxsKkdib"
+ + "tTVl3qmH5QAwggLFMIIBrQIBATANBgkqhkiG9w0BAQUFADBpMQswCQYDVQQG"
+ + "EwJVUzEjMCEGA1UEChMaQWRvYmUgU3lzdGVtcyBJbmNvcnBvcmF0ZWQxHTAb"
+ + "BgNVBAsTFEFkb2JlIFRydXN0IFNlcnZpY2VzMRYwFAYDVQQDEw1BZG9iZSBS"
+ + "b290IENBFw0wNjAxMjcxODMzMzFaFw0wNzAxMjcwMDAwMDBaMIHeMCMCBD4c"
+ + "vUAXDTAzMDEyMTIzNDY1NlowDDAKBgNVHRUEAwoBBDAjAgQ+HL1BFw0wMzAx"
+ + "MjEyMzQ3MjJaMAwwCgYDVR0VBAMKAQQwIwIEPhy9YhcNMDMwMTIxMjM0NzQy"
+ + "WjAMMAoGA1UdFQQDCgEEMCMCBD4cvWEXDTA0MDExNzAxMDg0OFowDDAKBgNV"
+ + "HRUEAwoBBDAjAgQ+HL2qFw0wNDAxMTcwMTA5MDVaMAwwCgYDVR0VBAMKAQQw"
+ + "IwIEPhy9qBcNMDQwMTE3MDEzOTI5WjAMMAoGA1UdFQQDCgEEoC8wLTAKBgNV"
+ + "HRQEAwIBDzAfBgNVHSMEGDAWgBSCtzhKk6qbEO+Au9lU4vEP+4Cc3jANBgkq"
+ + "hkiG9w0BAQUFAAOCAQEAwtXF9042wG39icUlsotn5tpE3oCusLb/hBpEONhx"
+ + "OdfEQOq0w5hf/vqaxkcf71etA+KpbEUeSVaHMHRPhx/CmPrO9odE139dJdbt"
+ + "9iqbrC9iZokFK3h/es5kg73xujLKd7C/u5ngJ4mwBtvhMLjFjF2vJhPKHL4C"
+ + "IgMwdaUAhrcNzy16v+mw/VGJy3Fvc6oCESW1K9tvFW58qZSNXrMlsuidgunM"
+ + "hPKG+z0SXVyCqL7pnqKiaGddcgujYGOSY4S938oVcfZeZQEODtSYGlzldojX"
+ + "C1U1hCK5+tHAH0Ox/WqRBIol5VCZQwJftf44oG8oviYq52aaqSejXwmfT6zb"
+ + "76GCBXUwggVxMIIFbQoBAKCCBWYwggViBgkrBgEFBQcwAQEEggVTMIIFTzCB"
+ + "taIWBBS+8EpykfXdl4h3z7m/NZfdkAQQERgPMjAwNjA0MDQyMDIwMTVaMGUw"
+ + "YzA7MAkGBSsOAwIaBQAEFEb4BuZYkbjBjOjT6VeA/00fBvQaBBT3fTSQniOp"
+ + "BbHBSkz4xridlX0bsAICAYOAABgPMjAwNjA0MDQyMDIwMTVaoBEYDzIwMDYw"
+ + "NDA1MDgyMDE1WqEjMCEwHwYJKwYBBQUHMAECBBIEEFqooq/R2WltD7TposkT"
+ + "BhMwDQYJKoZIhvcNAQEFBQADgYEAMig6lty4b0JDsT/oanfQG5x6jVKPACpp"
+ + "1UA9SJ0apJJa7LeIdDFmu5C2S/CYiKZm4A4P9cAu0YzgLHxE4r6Op+HfVlAG"
+ + "6bzUe1P/hi1KCJ8r8wxOZAktQFPSzs85RAZwkHMfB0lP2e/h666Oye+Zf8VH"
+ + "RaE+/xZ7aswE89HXoumgggQAMIID/DCCA/gwggLgoAMCAQICAXUwDQYJKoZI"
+ + "hvcNAQEFBQAwRTELMAkGA1UEBhMCVVMxFjAUBgNVBAoTDUdlb1RydXN0IElu"
+ + "Yy4xHjAcBgNVBAMTFUdlb1RydXN0IENBIGZvciBBZG9iZTAeFw0wNDEyMDIy"
+ + "MTI1MzlaFw0wNjEyMzAyMTI1MzlaMEwxCzAJBgNVBAYTAlVTMRUwEwYDVQQK"
+ + "EwxHZW9UcnVzdCBJbmMxJjAkBgNVBAMTHUdlb1RydXN0IEFkb2JlIE9DU1Ag"
+ + "UmVzcG9uZGVyMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDiCc1iG3Dt"
+ + "TpB5Vdk4OcaEcyP46BnQMHf3esSTprar2SrXb0gDZ7TfIoFN8l9BH1pYpzZC"
+ + "P3R2xKo+O9MMcUZCxqCbYVC6GcDd9vVRaE/N4Qh2bpvEOydDydaoqrGdZnMQ"
+ + "tlt2ncj1sEuLMiqhtmi/O3rQs0yCGf+6e++6Gl5VKwIDAQABo4IBbjCCAWow"
+ + "DgYDVR0PAQH/BAQDAgTwMIHlBgNVHSABAf8EgdowgdcwgdQGCSqGSIb3LwEC"
+ + "ATCBxjCBkAYIKwYBBQUHAgIwgYMagYBUaGlzIGNlcnRpZmljYXRlIGhhcyBi"
+ + "ZWVuIGlzc3VlZCBpbiBhY2NvcmRhbmNlIHdpdGggdGhlIEFjcm9iYXQgQ3Jl"
+ + "ZGVudGlhbHMgQ1BTIGxvY2F0ZWQgYXQgaHR0cDovL3d3dy5nZW90cnVzdC5j"
+ + "b20vcmVzb3VyY2VzL2NwczAxBggrBgEFBQcCARYlaHR0cDovL3d3dy5nZW90"
+ + "cnVzdC5jb20vcmVzb3VyY2VzL2NwczATBgNVHSUEDDAKBggrBgEFBQcDCTA6"
+ + "BgNVHR8EMzAxMC+gLaArhilodHRwOi8vY3JsLmdlb3RydXN0LmNvbS9jcmxz"
+ + "L2Fkb2JlY2ExLmNybDAfBgNVHSMEGDAWgBSrgFnDZYNtHX0TvRnD7BqPDUdq"
+ + "ozANBgkqhkiG9w0BAQUFAAOCAQEAQ0l/UEPs9fmK+5prC33SrU4bNekhAv8K"
+ + "XMR4VWY4jGo9zURMVGr3Zi7Eblvr5H6T60aSYLA8txjyKmDplxsn8CKtCGiH"
+ + "OOUW5PpgBexN8SMKoRl9YzaxLtysrYRjEIyYoTfEN89yVi2sCjPupm/F9CPR"
+ + "O7EdKy0dm/f3C7ZmIbUFaIRzINDJOCpM5cGhmZ8m2yG4BxeZOmCSthKtLfvM"
+ + "2U9MaH6kxhDTJYNzw5BElHg5jlld92drTWaO0lM6aPr/pc+gs9hOraBCtzYE"
+ + "J40nhsSEtvuwVUE9vA+unNMT8dFtAcOvOPRiKYPF45RX9Rdy2C9jAc20SRwE"
+ + "uw6b+7K0xjANBgkqhkiG9w0BAQEFAASCAQC7a4yICFGCEMPlJbydK5qLG3rV"
+ + "sip7Ojjz9TB4nLhC2DgsIHds8jjdq2zguInluH2nLaBCVS+qxDVlTjgbI2cB"
+ + "TaWS8nglC7nNjzkKAsa8vThA8FZUVXTW0pb74jNJJU2AA27bb4g+4WgunCrj"
+ + "fpYp+QjDyMmdrJVqRmt5eQN+dpVxMS9oq+NrhOSEhyIb4/rejgNg9wnVK1ms"
+ + "l5PxQ4x7kpm7+Ua41//owkJVWykRo4T1jo4eHEz1DolPykAaKie2VKH/sMqR"
+ + "Spjh4E5biKJLOV9fKivZWKAXByXfwUbbMsJvz4v/2yVHFy9xP+tqB5ZbRoDK"
+ + "k8PzUyCprozn+/22oYIPijCCD4YGCyqGSIb3DQEJEAIOMYIPdTCCD3EGCSqG"
+ + "SIb3DQEHAqCCD2Iwgg9eAgEDMQswCQYFKw4DAhoFADCB+gYLKoZIhvcNAQkQ"
+ + "AQSggeoEgecwgeQCAQEGAikCMCEwCQYFKw4DAhoFAAQUoT97qeCv3FXYaEcS"
+ + "gY8patCaCA8CAiMHGA8yMDA2MDQwNDIwMjA1N1owAwIBPAEB/wIIO0yRre3L"
+ + "8/6ggZCkgY0wgYoxCzAJBgNVBAYTAlVTMRYwFAYDVQQIEw1NYXNzYWNodXNl"
+ + "dHRzMRAwDgYDVQQHEwdOZWVkaGFtMRUwEwYDVQQKEwxHZW9UcnVzdCBJbmMx"
+ + "EzARBgNVBAsTClByb2R1Y3Rpb24xJTAjBgNVBAMTHGFkb2JlLXRpbWVzdGFt"
+ + "cC5nZW90cnVzdC5jb22gggzJMIIDUTCCAjmgAwIBAgICAI8wDQYJKoZIhvcN"
+ + "AQEFBQAwRTELMAkGA1UEBhMCVVMxFjAUBgNVBAoTDUdlb1RydXN0IEluYy4x"
+ + "HjAcBgNVBAMTFUdlb1RydXN0IENBIGZvciBBZG9iZTAeFw0wNTAxMTAwMTI5"
+ + "MTBaFw0xNTAxMTUwODAwMDBaMIGKMQswCQYDVQQGEwJVUzEWMBQGA1UECBMN"
+ + "TWFzc2FjaHVzZXR0czEQMA4GA1UEBxMHTmVlZGhhbTEVMBMGA1UEChMMR2Vv"
+ + "VHJ1c3QgSW5jMRMwEQYDVQQLEwpQcm9kdWN0aW9uMSUwIwYDVQQDExxhZG9i"
+ + "ZS10aW1lc3RhbXAuZ2VvdHJ1c3QuY29tMIGfMA0GCSqGSIb3DQEBAQUAA4GN"
+ + "ADCBiQKBgQDRbxJotLFPWQuuEDhKtOMaBUJepGxIvWxeahMbq1DVmqnk88+j"
+ + "w/5lfPICPzQZ1oHrcTLSAFM7Mrz3pyyQKQKMqUyiemzuG/77ESUNfBNSUfAF"
+ + "PdtHuDMU8Is8ABVnFk63L+wdlvvDIlKkE08+VTKCRdjmuBVltMpQ6QcLFQzm"
+ + "AQIDAQABo4GIMIGFMDoGA1UdHwQzMDEwL6AtoCuGKWh0dHA6Ly9jcmwuZ2Vv"
+ + "dHJ1c3QuY29tL2NybHMvYWRvYmVjYTEuY3JsMB8GA1UdIwQYMBaAFKuAWcNl"
+ + "g20dfRO9GcPsGo8NR2qjMA4GA1UdDwEB/wQEAwIGwDAWBgNVHSUBAf8EDDAK"
+ + "BggrBgEFBQcDCDANBgkqhkiG9w0BAQUFAAOCAQEAmnyXjdtX+F79Nf0KggTd"
+ + "6YC2MQD9s09IeXTd8TP3rBmizfM+7f3icggeCGakNfPRmIUMLoa0VM5Kt37T"
+ + "2X0TqzBWusfbKx7HnX4v1t/G8NJJlT4SShSHv+8bjjU4lUoCmW2oEcC5vXwP"
+ + "R5JfjCyois16npgcO05ZBT+LLDXyeBijE6qWmwLDfEpLyILzVRmyU4IE7jvm"
+ + "rgb3GXwDUvd3yQXGRRHbPCh3nj9hBGbuzyt7GnlqnEie3wzIyMG2ET/wvTX5"
+ + "4BFXKNe7lDLvZj/MXvd3V7gMTSVW0kAszKao56LfrVTgp1VX3UBQYwmQqaoA"
+ + "UwFezih+jEvjW6cYJo/ErDCCBKEwggOJoAMCAQICBD4cvSgwDQYJKoZIhvcN"
+ + "AQEFBQAwaTELMAkGA1UEBhMCVVMxIzAhBgNVBAoTGkFkb2JlIFN5c3RlbXMg"
+ + "SW5jb3Jwb3JhdGVkMR0wGwYDVQQLExRBZG9iZSBUcnVzdCBTZXJ2aWNlczEW"
+ + "MBQGA1UEAxMNQWRvYmUgUm9vdCBDQTAeFw0wMzAxMDgyMzM3MjNaFw0yMzAx"
+ + "MDkwMDA3MjNaMGkxCzAJBgNVBAYTAlVTMSMwIQYDVQQKExpBZG9iZSBTeXN0"
+ + "ZW1zIEluY29ycG9yYXRlZDEdMBsGA1UECxMUQWRvYmUgVHJ1c3QgU2Vydmlj"
+ + "ZXMxFjAUBgNVBAMTDUFkb2JlIFJvb3QgQ0EwggEiMA0GCSqGSIb3DQEBAQUA"
+ + "A4IBDwAwggEKAoIBAQDMT1SE96ei5zNTfz+cEohrLJlHZ34PHrmtFIj5wxDY"
+ + "HfDw1Z9pCi9ZNbDMbKlMnBWgn84gv6DPVOLgIGZFPzmGOH6cxI4HIsYk9gES"
+ + "sDXfVeppkLDbhTce4k4HskKhahNpoGbqgJERWSqbCHlaIEQtyb1zOIs8L+BD"
+ + "G12zC/CvNRop/u+mkt2BTJ09WY6tMTxAfpuRNgb84lyN0Y0m1VxFz69lP7Gq"
+ + "0mKW9Kg46rpgQvT0HEo1Fc74TiJWD5UYxfiWn5/7sLd4JemAa73WCvDGdJSd"
+ + "8w9Q25p3zktwgyONoMp4IERcPFRk8eqiMBmf6kwGTQZ4S16S3yLSyWezetIB"
+ + "AgMBAAGjggFPMIIBSzARBglghkgBhvhCAQEEBAMCAAcwgY4GA1UdHwSBhjCB"
+ + "gzCBgKB+oHykejB4MQswCQYDVQQGEwJVUzEjMCEGA1UEChMaQWRvYmUgU3lz"
+ + "dGVtcyBJbmNvcnBvcmF0ZWQxHTAbBgNVBAsTFEFkb2JlIFRydXN0IFNlcnZp"
+ + "Y2VzMRYwFAYDVQQDEw1BZG9iZSBSb290IENBMQ0wCwYDVQQDEwRDUkwxMCsG"
+ + "A1UdEAQkMCKADzIwMDMwMTA4MjMzNzIzWoEPMjAyMzAxMDkwMDA3MjNaMAsG"
+ + "A1UdDwQEAwIBBjAfBgNVHSMEGDAWgBSCtzhKk6qbEO+Au9lU4vEP+4Cc3jAd"
+ + "BgNVHQ4EFgQUgrc4SpOqmxDvgLvZVOLxD/uAnN4wDAYDVR0TBAUwAwEB/zAd"
+ + "BgkqhkiG9n0HQQAEEDAOGwhWNi4wOjQuMAMCBJAwDQYJKoZIhvcNAQEFBQAD"
+ + "ggEBADLan0N1wfpvyW/bqx02Nz68YRk2twI8HSNZmGye7k2F51TIIB+n1Lvi"
+ + "vwB3fSRrcC9cwTp2SbXT4COEKnFqIvPBJymYFfY1kOQETMONvJ9hHOf9JIzR"
+ + "REOMFrqbTaXUNS+8Ec6991E3jZ+Q5BTxGD++6VkSNfkzkvOe4NVrmnGbmUvI"
+ + "ccPhsWEJxOX6kfBCOjd9NPly6M2qYhwh6dX0ghDjewW2LWhWC35+kixvTXKC"
+ + "DO1WdLKduastKx0QX9sndXCP/R3X4gKgeeUc5f+vZEBRLZ6bR9tCpXwfwqZI"
+ + "sNe+kmlNpPYpV8V4ERjch1HKE7JinU8rMr0xpcH6UqsFiMgwggTLMIIDs6AD"
+ + "AgECAgQ+HL21MA0GCSqGSIb3DQEBBQUAMGkxCzAJBgNVBAYTAlVTMSMwIQYD"
+ + "VQQKExpBZG9iZSBTeXN0ZW1zIEluY29ycG9yYXRlZDEdMBsGA1UECxMUQWRv"
+ + "YmUgVHJ1c3QgU2VydmljZXMxFjAUBgNVBAMTDUFkb2JlIFJvb3QgQ0EwHhcN"
+ + "MDQwMTE3MDAwMzM5WhcNMTUwMTE1MDgwMDAwWjBFMQswCQYDVQQGEwJVUzEW"
+ + "MBQGA1UEChMNR2VvVHJ1c3QgSW5jLjEeMBwGA1UEAxMVR2VvVHJ1c3QgQ0Eg"
+ + "Zm9yIEFkb2JlMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAp+V3"
+ + "4GR4Wuc5hbyv0vVbKBMOVN1J+s5i9ZL9nph7n+X4esFs4epAJcFxJ4KnPuQH"
+ + "ZZ0oyHUU4Th70mWYgKwd6sEt1aR6ZT788Nvr3OHwTRwugN/G6QXqhU9ePpZJ"
+ + "OF1Ibsf1pcXNGvpLdcYK6+CX5DANMuIthb440XoNfC3dNBC0pF4mM4lmTjpl"
+ + "nQG8xK0rIFp4HoMpmyaIijz2qyjXdUNkg0fbDUq9eDTKAOLOg21u+AA8XKbC"
+ + "ewg1LWSV9CVy+fTHREmb1thBcrfkY1kCAvczsuquV3SMx8hRpa+4cIvKK/K1"
+ + "G7OrV0nsTyuaJ2MMST8b7bul/Xd81nu9Hsz4iQIDAQABo4IBnTCCAZkwEgYD"
+ + "VR0TAQH/BAgwBgEB/wIBATBQBgNVHSAESTBHMEUGCSqGSIb3LwECATA4MDYG"
+ + "CCsGAQUFBwIBFipodHRwczovL3d3dy5hZG9iZS5jb20vbWlzYy9wa2kvY2Rz"
+ + "X2NwLmh0bWwwFAYDVR0lBA0wCwYJKoZIhvcvAQEFMIGyBgNVHR8Egaowgacw"
+ + "IqAgoB6GHGh0dHA6Ly9jcmwuYWRvYmUuY29tL2Nkcy5jcmwwgYCgfqB8pHow"
+ + "eDELMAkGA1UEBhMCVVMxIzAhBgNVBAoTGkFkb2JlIFN5c3RlbXMgSW5jb3Jw"
+ + "b3JhdGVkMR0wGwYDVQQLExRBZG9iZSBUcnVzdCBTZXJ2aWNlczEWMBQGA1UE"
+ + "AxMNQWRvYmUgUm9vdCBDQTENMAsGA1UEAxMEQ1JMMTALBgNVHQ8EBAMCAQYw"
+ + "HwYDVR0jBBgwFoAUgrc4SpOqmxDvgLvZVOLxD/uAnN4wHQYDVR0OBBYEFKuA"
+ + "WcNlg20dfRO9GcPsGo8NR2qjMBkGCSqGSIb2fQdBAAQMMAobBFY2LjADAgSQ"
+ + "MA0GCSqGSIb3DQEBBQUAA4IBAQA/OVkuogCOsV4RYSzS4Lb1jImGRc4T2Z/d"
+ + "hJoUawhMX4aXWPSlqNOPIfhHflCvd+Whbarcd83NN5n3QmevUOFUREPrMQyA"
+ + "mkK0mpW6TSyLG5ckeCFL8qJwp/hhckk/H16m4hEXWyIFGfOecX3Sy+Y4kxcC"
+ + "lzSMadifedB+TiRpKFKcNphp5hEMkpyyJaGXpLnN/BLsaDyEN7JySExAopae"
+ + "UbUJCvCVIWKwoJ26ih3BG1aB+3yTHXeLIorextqWbq+dVz7me59Li8j5PAxe"
+ + "hXrc2phpKuhp8FaTScvnfMZc8TL4Dr1CHMRWIkqfZaCq3mC376Mww0iZtE5s"
+ + "iqB+AXVWMYIBgDCCAXwCAQEwSzBFMQswCQYDVQQGEwJVUzEWMBQGA1UEChMN"
+ + "R2VvVHJ1c3QgSW5jLjEeMBwGA1UEAxMVR2VvVHJ1c3QgQ0EgZm9yIEFkb2Jl"
+ + "AgIAjzAJBgUrDgMCGgUAoIGMMBoGCSqGSIb3DQEJAzENBgsqhkiG9w0BCRAB"
+ + "BDAcBgkqhkiG9w0BCQUxDxcNMDYwNDA0MjAyMDU3WjAjBgkqhkiG9w0BCQQx"
+ + "FgQUp7AnXBqoNcarvO7fMJut1og2U5AwKwYLKoZIhvcNAQkQAgwxHDAaMBgw"
+ + "FgQU1dH4eZTNhgxdiSABrat6zsPdth0wDQYJKoZIhvcNAQEBBQAEgYCinr/F"
+ + "rMiQz/MRm9ZD5YGcC0Qo2dRTPd0Aop8mZ4g1xAhKFLnp7lLsjCbkSDpVLDBh"
+ + "cnCk7CV+3FT5hlvt8OqZlR0CnkSnCswLFhrppiWle6cpxlwGqyAteC8uKtQu"
+ + "wjE5GtBKLcCOAzQYyyuNZZeB6oCZ+3mPhZ62FxrvvEGJCgAAAAAAAAAAAAAA"
+ + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
+ + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
+ + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
+ + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
+ + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
+ + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
+ + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
+ + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
+ + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==");
+
+ private final byte[] emptyDNCert = Base64.decode(
+ "MIICfTCCAeagAwIBAgIBajANBgkqhkiG9w0BAQQFADB8MQswCQYDVQQGEwJVUzEMMAoGA1UEChMD"
+ + "Q0RXMQkwBwYDVQQLEwAxCTAHBgNVBAcTADEJMAcGA1UECBMAMRowGAYDVQQDExFUZW1wbGFyIFRl"
+ + "c3QgMTAyNDEiMCAGCSqGSIb3DQEJARYTdGVtcGxhcnRlc3RAY2R3LmNvbTAeFw0wNjA1MjIwNTAw"
+ + "MDBaFw0xMDA1MjIwNTAwMDBaMHwxCzAJBgNVBAYTAlVTMQwwCgYDVQQKEwNDRFcxCTAHBgNVBAsT"
+ + "ADEJMAcGA1UEBxMAMQkwBwYDVQQIEwAxGjAYBgNVBAMTEVRlbXBsYXIgVGVzdCAxMDI0MSIwIAYJ"
+ + "KoZIhvcNAQkBFhN0ZW1wbGFydGVzdEBjZHcuY29tMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKB"
+ + "gQDH3aJpJBfM+A3d84j5YcU6zEQaQ76u5xO9NSBmHjZykKS2kCcUqPpvVOPDA5WgV22dtKPh+lYV"
+ + "iUp7wyCVwAKibq8HIbihHceFqMKzjwC639rMoDJ7bi/yzQWz1Zg+075a4FGPlUKn7Yfu89wKkjdW"
+ + "wDpRPXc/agqBnrx5pJTXzQIDAQABow8wDTALBgNVHQ8EBAMCALEwDQYJKoZIhvcNAQEEBQADgYEA"
+ + "RRsRsjse3i2/KClFVd6YLZ+7K1BE0WxFyY2bbytkwQJSxvv3vLSuweFUbhNxutb68wl/yW4GLy4b"
+ + "1QdyswNxrNDXTuu5ILKhRDDuWeocz83aG2KGtr3JlFyr3biWGEyn5WUOE6tbONoQDJ0oPYgI6CAc"
+ + "EHdUp0lioOCt6UOw7Cs=");
+
+ private final byte[] gostRFC4491_94 = Base64.decode(
+ "MIICCzCCAboCECMO42BGlSTOxwvklBgufuswCAYGKoUDAgIEMGkxHTAbBgNVBAMM" +
+ "FEdvc3RSMzQxMC05NCBleGFtcGxlMRIwEAYDVQQKDAlDcnlwdG9Qcm8xCzAJBgNV" +
+ "BAYTAlJVMScwJQYJKoZIhvcNAQkBFhhHb3N0UjM0MTAtOTRAZXhhbXBsZS5jb20w" +
+ "HhcNMDUwODE2MTIzMjUwWhcNMTUwODE2MTIzMjUwWjBpMR0wGwYDVQQDDBRHb3N0" +
+ "UjM0MTAtOTQgZXhhbXBsZTESMBAGA1UECgwJQ3J5cHRvUHJvMQswCQYDVQQGEwJS" +
+ "VTEnMCUGCSqGSIb3DQEJARYYR29zdFIzNDEwLTk0QGV4YW1wbGUuY29tMIGlMBwG" +
+ "BiqFAwICFDASBgcqhQMCAiACBgcqhQMCAh4BA4GEAASBgLuEZuF5nls02CyAfxOo" +
+ "GWZxV/6MVCUhR28wCyd3RpjG+0dVvrey85NsObVCNyaE4g0QiiQOHwxCTSs7ESuo" +
+ "v2Y5MlyUi8Go/htjEvYJJYfMdRv05YmKCYJo01x3pg+2kBATjeM+fJyR1qwNCCw+" +
+ "eMG1wra3Gqgqi0WBkzIydvp7MAgGBiqFAwICBANBABHHCH4S3ALxAiMpR3aPRyqB" +
+ "g1DjB8zy5DEjiULIc+HeIveF81W9lOxGkZxnrFjXBSqnjLeFKgF1hffXOAP7zUM=");
+
+ private final byte[] gostRFC4491_2001 = Base64.decode(
+ "MIIB0DCCAX8CECv1xh7CEb0Xx9zUYma0LiEwCAYGKoUDAgIDMG0xHzAdBgNVBAMM" +
+ "Fkdvc3RSMzQxMC0yMDAxIGV4YW1wbGUxEjAQBgNVBAoMCUNyeXB0b1BybzELMAkG" +
+ "A1UEBhMCUlUxKTAnBgkqhkiG9w0BCQEWGkdvc3RSMzQxMC0yMDAxQGV4YW1wbGUu" +
+ "Y29tMB4XDTA1MDgxNjE0MTgyMFoXDTE1MDgxNjE0MTgyMFowbTEfMB0GA1UEAwwW" +
+ "R29zdFIzNDEwLTIwMDEgZXhhbXBsZTESMBAGA1UECgwJQ3J5cHRvUHJvMQswCQYD" +
+ "VQQGEwJSVTEpMCcGCSqGSIb3DQEJARYaR29zdFIzNDEwLTIwMDFAZXhhbXBsZS5j" +
+ "b20wYzAcBgYqhQMCAhMwEgYHKoUDAgIkAAYHKoUDAgIeAQNDAARAhJVodWACGkB1" +
+ "CM0TjDGJLP3lBQN6Q1z0bSsP508yfleP68wWuZWIA9CafIWuD+SN6qa7flbHy7Df" +
+ "D2a8yuoaYDAIBgYqhQMCAgMDQQA8L8kJRLcnqeyn1en7U23Sw6pkfEQu3u0xFkVP" +
+ "vFQ/3cHeF26NG+xxtZPz3TaTVXdoiYkXYiD02rEx1bUcM97i");
+
+ private PublicKey dudPublicKey = new PublicKey()
+ {
+ public String getAlgorithm()
+ {
+ return null;
+ }
+
+ public String getFormat()
+ {
+ return null;
+ }
+
+ public byte[] getEncoded()
+ {
+ return null;
+ }
+
+ };
+
+ public String getName()
+ {
+ return "CertTest";
+ }
+
+ public void checkCertificate(
+ int id,
+ byte[] bytes)
+ {
+ ByteArrayInputStream bIn;
+ String dump = "";
+
+ try
+ {
+ bIn = new ByteArrayInputStream(bytes);
+
+ CertificateFactory fact = CertificateFactory.getInstance("X.509", "SC");
+
+ Certificate cert = fact.generateCertificate(bIn);
+
+ PublicKey k = cert.getPublicKey();
+ // System.out.println(cert);
+ }
+ catch (Exception e)
+ {
+ fail(dump + System.getProperty("line.separator") + getName() + ": "+ id + " failed - exception " + e.toString(), e);
+ }
+
+ }
+
+ public void checkNameCertificate(
+ int id,
+ byte[] bytes)
+ {
+ ByteArrayInputStream bIn;
+ String dump = "";
+
+ try
+ {
+ bIn = new ByteArrayInputStream(bytes);
+
+ CertificateFactory fact = CertificateFactory.getInstance("X.509", "SC");
+
+ X509Certificate cert = (X509Certificate)fact.generateCertificate(bIn);
+
+ PublicKey k = cert.getPublicKey();
+ if (!cert.getIssuerDN().toString().equals("C=DE,O=DATEV eG,0.2.262.1.10.7.20=1+CN=CA DATEV D03 1:PN"))
+ {
+ fail(id + " failed - name test.");
+ }
+ // System.out.println(cert);
+ }
+ catch (Exception e)
+ {
+ fail(dump + System.getProperty("line.separator") + getName() + ": "+ id + " failed - exception " + e.toString(), e);
+ }
+
+ }
+
+ public void checkKeyUsage(
+ int id,
+ byte[] bytes)
+ {
+ ByteArrayInputStream bIn;
+ String dump = "";
+
+ try
+ {
+ bIn = new ByteArrayInputStream(bytes);
+
+ CertificateFactory fact = CertificateFactory.getInstance("X.509", "SC");
+
+ X509Certificate cert = (X509Certificate)fact.generateCertificate(bIn);
+
+ PublicKey k = cert.getPublicKey();
+
+ if (cert.getKeyUsage()[7])
+ {
+ fail("error generating cert - key usage wrong.");
+ }
+
+ // System.out.println(cert);
+ }
+ catch (Exception e)
+ {
+ fail(dump + System.getProperty("line.separator") + getName() + ": "+ id + " failed - exception " + e.toString(), e);
+ }
+
+ }
+
+
+ public void checkSelfSignedCertificate(
+ int id,
+ byte[] bytes)
+ {
+ ByteArrayInputStream bIn;
+ String dump = "";
+
+ try
+ {
+ bIn = new ByteArrayInputStream(bytes);
+
+ CertificateFactory fact = CertificateFactory.getInstance("X.509", "SC");
+
+ Certificate cert = fact.generateCertificate(bIn);
+
+ PublicKey k = cert.getPublicKey();
+
+ cert.verify(k);
+ // System.out.println(cert);
+ }
+ catch (Exception e)
+ {
+ fail(dump + System.getProperty("line.separator") + getName() + ": "+ id + " failed - exception " + e.toString(), e);
+ }
+
+ }
+
+
+ /**
+ * Test a generated certificate with the sun provider
+ */
+ private void sunProviderCheck(byte[] encoding)
+ throws CertificateException
+ {
+ CertificateFactory certFact = CertificateFactory.getInstance("X.509");
+
+ certFact.generateCertificate(new ByteArrayInputStream(encoding));
+ }
+
+ /**
+ * we generate a self signed certificate for the sake of testing - RSA
+ */
+ public void checkCreation1()
+ throws Exception
+ {
+ //
+ // a sample key pair.
+ //
+ RSAPublicKeySpec pubKeySpec = new RSAPublicKeySpec(
+ new BigInteger("b4a7e46170574f16a97082b22be58b6a2a629798419be12872a4bdba626cfae9900f76abfb12139dce5de56564fab2b6543165a040c606887420e33d91ed7ed7", 16),
+ new BigInteger("11", 16));
+
+ RSAPrivateCrtKeySpec privKeySpec = new RSAPrivateCrtKeySpec(
+ new BigInteger("b4a7e46170574f16a97082b22be58b6a2a629798419be12872a4bdba626cfae9900f76abfb12139dce5de56564fab2b6543165a040c606887420e33d91ed7ed7", 16),
+ new BigInteger("11", 16),
+ new BigInteger("9f66f6b05410cd503b2709e88115d55daced94d1a34d4e32bf824d0dde6028ae79c5f07b580f5dce240d7111f7ddb130a7945cd7d957d1920994da389f490c89", 16),
+ new BigInteger("c0a0758cdf14256f78d4708c86becdead1b50ad4ad6c5c703e2168fbf37884cb", 16),
+ new BigInteger("f01734d7960ea60070f1b06f2bb81bfac48ff192ae18451d5e56c734a5aab8a5", 16),
+ new BigInteger("b54bb9edff22051d9ee60f9351a48591b6500a319429c069a3e335a1d6171391", 16),
+ new BigInteger("d3d83daf2a0cecd3367ae6f8ae1aeb82e9ac2f816c6fc483533d8297dd7884cd", 16),
+ new BigInteger("b8f52fc6f38593dabb661d3f50f8897f8106eee68b1bce78a95b132b4e5b5d19", 16));
+
+ //
+ // set up the keys
+ //
+ PrivateKey privKey;
+ PublicKey pubKey;
+
+ KeyFactory fact = KeyFactory.getInstance("RSA", "SC");
+
+ privKey = fact.generatePrivate(privKeySpec);
+ pubKey = fact.generatePublic(pubKeySpec);
+
+ //
+ // distinguished name table.
+ //
+ X500NameBuilder builder = new X500NameBuilder(BCStyle.INSTANCE);
+
+ builder.addRDN(BCStyle.C, "AU");
+ builder.addRDN(BCStyle.O, "The Legion of the Bouncy Castle");
+ builder.addRDN(BCStyle.L, "Melbourne");
+ builder.addRDN(BCStyle.ST, "Victoria");
+ builder.addRDN(BCStyle.E, "feedback-crypto@bouncycastle.org");
+
+ //
+ // extensions
+ //
+
+ //
+ // create the certificate - version 3 - without extensions
+ //
+ ContentSigner sigGen = new JcaContentSignerBuilder("SHA256WithRSAEncryption").setProvider(BC).build(privKey);
+ X509v3CertificateBuilder certGen = new JcaX509v3CertificateBuilder(builder.build(), BigInteger.valueOf(1), new Date(System.currentTimeMillis() - 50000), new Date(System.currentTimeMillis() + 50000),builder.build(), pubKey);
+
+ X509Certificate cert = new JcaX509CertificateConverter().setProvider(BC).getCertificate(certGen.build(sigGen));
+
+ cert.checkValidity(new Date());
+
+ cert.verify(pubKey);
+
+ cert.verify(cert.getPublicKey());
+
+ Set dummySet = cert.getNonCriticalExtensionOIDs();
+ if (dummySet != null)
+ {
+ fail("non-critical oid set should be null");
+ }
+ dummySet = cert.getCriticalExtensionOIDs();
+ if (dummySet != null)
+ {
+ fail("critical oid set should be null");
+ }
+
+ //
+ // create the certificate - version 3 - with extensions
+ //
+ sigGen = new JcaContentSignerBuilder("MD5WithRSAEncryption").setProvider(BC).build(privKey);
+ certGen = new JcaX509v3CertificateBuilder(builder.build(), BigInteger.valueOf(1)
+ , new Date(System.currentTimeMillis() - 50000)
+ , new Date(System.currentTimeMillis() + 50000)
+ , builder.build()
+ , pubKey)
+ .addExtension(new ASN1ObjectIdentifier("2.5.29.15"), true,
+ new X509KeyUsage(X509KeyUsage.encipherOnly))
+ .addExtension(new ASN1ObjectIdentifier("2.5.29.37"), true,
+ new DERSequence(KeyPurposeId.anyExtendedKeyUsage))
+ .addExtension(new ASN1ObjectIdentifier("2.5.29.17"), true,
+ new GeneralNames(new GeneralName[]
+ {
+ new GeneralName(GeneralName.rfc822Name, "test@test.test"),
+ new GeneralName(GeneralName.dNSName, "dom.test.test")
+ }));
+
+ X509CertificateHolder certHolder = certGen.build(sigGen);
+
+ cert = new JcaX509CertificateConverter().setProvider(BC).getCertificate(certHolder);
+
+ cert.checkValidity(new Date());
+
+ cert.verify(pubKey);
+ cert.verify(cert.getPublicKey());
+
+ ContentVerifierProvider contentVerifierProvider = new JcaContentVerifierProviderBuilder().setProvider(BC).build(pubKey);
+ if (!certHolder.isSignatureValid(contentVerifierProvider))
+ {
+ fail("signature test failed");
+ }
+
+ ByteArrayInputStream bIn = new ByteArrayInputStream(cert.getEncoded());
+ CertificateFactory certFact = CertificateFactory.getInstance("X.509", "SC");
+
+ cert = (X509Certificate)certFact.generateCertificate(bIn);
+
+ if (!cert.getKeyUsage()[7])
+ {
+ fail("error generating cert - key usage wrong.");
+ }
+
+ List l = cert.getExtendedKeyUsage();
+ if (!l.get(0).equals(KeyPurposeId.anyExtendedKeyUsage.getId()))
+ {
+ fail("failed extended key usage test");
+ }
+
+ Collection c = cert.getSubjectAlternativeNames();
+ Iterator it = c.iterator();
+ while (it.hasNext())
+ {
+ List gn = (List)it.next();
+ if (!gn.get(1).equals("test@test.test") && !gn.get(1).equals("dom.test.test"))
+ {
+ fail("failed subject alternative names test");
+ }
+ }
+
+ sunProviderCheck(certHolder.getEncoded());
+ sunProviderCheck(cert.getEncoded());
+
+ // System.out.println(cert);
+
+ //
+ // create the certificate - version 1
+ //
+ sigGen = new JcaContentSignerBuilder("MD5WithRSAEncryption").setProvider(BC).build(privKey);
+ X509v1CertificateBuilder certGen1 = new JcaX509v1CertificateBuilder(builder.build(), BigInteger.valueOf(1), new Date(System.currentTimeMillis() - 50000),new Date(System.currentTimeMillis() + 50000),builder.build(),pubKey);
+
+ cert = new JcaX509CertificateConverter().setProvider(BC).getCertificate(certGen1.build(sigGen));
+
+ cert.checkValidity(new Date());
+
+ cert.verify(pubKey);
+ cert.verify(cert.getPublicKey());
+
+ bIn = new ByteArrayInputStream(cert.getEncoded());
+ certFact = CertificateFactory.getInstance("X.509", "SC");
+
+ cert = (X509Certificate)certFact.generateCertificate(bIn);
+
+ // System.out.println(cert);
+ if (!cert.getIssuerDN().equals(cert.getSubjectDN()))
+ {
+ fail("name comparison fails");
+ }
+
+ sunProviderCheck(certHolder.getEncoded());
+ sunProviderCheck(cert.getEncoded());
+//
+ // a lightweight key pair.
+ //
+ RSAKeyParameters lwPubKey = new RSAKeyParameters(
+ false,
+ new BigInteger("b4a7e46170574f16a97082b22be58b6a2a629798419be12872a4bdba626cfae9900f76abfb12139dce5de56564fab2b6543165a040c606887420e33d91ed7ed7", 16),
+ new BigInteger("11", 16));
+
+ RSAPrivateCrtKeyParameters lwPrivKey = new RSAPrivateCrtKeyParameters(
+ new BigInteger("b4a7e46170574f16a97082b22be58b6a2a629798419be12872a4bdba626cfae9900f76abfb12139dce5de56564fab2b6543165a040c606887420e33d91ed7ed7", 16),
+ new BigInteger("11", 16),
+ new BigInteger("9f66f6b05410cd503b2709e88115d55daced94d1a34d4e32bf824d0dde6028ae79c5f07b580f5dce240d7111f7ddb130a7945cd7d957d1920994da389f490c89", 16),
+ new BigInteger("c0a0758cdf14256f78d4708c86becdead1b50ad4ad6c5c703e2168fbf37884cb", 16),
+ new BigInteger("f01734d7960ea60070f1b06f2bb81bfac48ff192ae18451d5e56c734a5aab8a5", 16),
+ new BigInteger("b54bb9edff22051d9ee60f9351a48591b6500a319429c069a3e335a1d6171391", 16),
+ new BigInteger("d3d83daf2a0cecd3367ae6f8ae1aeb82e9ac2f816c6fc483533d8297dd7884cd", 16),
+ new BigInteger("b8f52fc6f38593dabb661d3f50f8897f8106eee68b1bce78a95b132b4e5b5d19", 16));
+
+ //
+ // distinguished name table.
+ //
+ builder = new X500NameBuilder(BCStyle.INSTANCE);
+
+ builder.addRDN(BCStyle.C, "AU");
+ builder.addRDN(BCStyle.O, "The Legion of the Bouncy Castle");
+ builder.addRDN(BCStyle.L, "Melbourne");
+ builder.addRDN(BCStyle.ST, "Victoria");
+ builder.addRDN(BCStyle.E, "feedback-crypto@bouncycastle.org");
+
+ //
+ // extensions
+ //
+
+ //
+ // create the certificate - version 3 - without extensions
+ //
+ AlgorithmIdentifier sigAlgId = new DefaultSignatureAlgorithmIdentifierFinder().find("SHA256WithRSAEncryption");
+ AlgorithmIdentifier digAlgId = new DefaultDigestAlgorithmIdentifierFinder().find(sigAlgId);
+
+ sigGen = new BcRSAContentSignerBuilder(sigAlgId, digAlgId).build(lwPrivKey);
+ SubjectPublicKeyInfo pubInfo = new SubjectPublicKeyInfo(new AlgorithmIdentifier(PKCSObjectIdentifiers.rsaEncryption, DERNull.INSTANCE), new RSAPublicKey(lwPubKey.getModulus(), lwPubKey.getExponent()));
+ certGen = new X509v3CertificateBuilder(builder.build(), BigInteger.valueOf(1), new Date(System.currentTimeMillis() - 50000), new Date(System.currentTimeMillis() + 50000), builder.build(), pubInfo);
+
+ certHolder = certGen.build(sigGen);
+
+ cert = new JcaX509CertificateConverter().setProvider(BC).getCertificate(certHolder);
+
+ cert.checkValidity(new Date());
+
+ cert.verify(pubKey);
+
+ contentVerifierProvider = new BcRSAContentVerifierProviderBuilder(new DefaultDigestAlgorithmIdentifierFinder()).build(lwPubKey);
+
+ if (!certHolder.isSignatureValid(contentVerifierProvider))
+ {
+ fail("lw sig verification failed");
+ }
+ }
+
+ /**
+ * we generate a self signed certificate for the sake of testing - DSA
+ */
+ public void checkCreation2()
+ throws Exception
+ {
+ //
+ // set up the keys
+ //
+ PrivateKey privKey;
+ PublicKey pubKey;
+
+ try
+ {
+ KeyPairGenerator g = KeyPairGenerator.getInstance("DSA", "SUN");
+
+ g.initialize(512, new SecureRandom());
+
+ KeyPair p = g.generateKeyPair();
+
+ privKey = p.getPrivate();
+ pubKey = p.getPublic();
+ }
+ catch (Exception e)
+ {
+ fail("error setting up keys - " + e.toString());
+ return;
+ }
+
+ //
+ // distinguished name table.
+ //
+ X500NameBuilder builder = createStdBuilder();
+
+ //
+ // extensions
+ //
+
+ //
+ // create the certificate - version 3
+ //
+
+ ContentSigner sigGen = new JcaContentSignerBuilder("SHA1withDSA").setProvider(BC).build(privKey);
+ JcaX509v3CertificateBuilder certGen = new JcaX509v3CertificateBuilder(builder.build(),BigInteger.valueOf(1),new Date(System.currentTimeMillis() - 50000),new Date(System.currentTimeMillis() + 50000),builder.build(),pubKey);
+
+
+ X509Certificate cert = new JcaX509CertificateConverter().setProvider(BC).getCertificate(certGen.build(sigGen));
+
+ cert.checkValidity(new Date());
+
+ cert.verify(pubKey);
+
+ ByteArrayInputStream bIn = new ByteArrayInputStream(cert.getEncoded());
+ CertificateFactory fact = CertificateFactory.getInstance("X.509", BC);
+
+ cert = (X509Certificate)fact.generateCertificate(bIn);
+
+ // System.out.println(cert);
+
+
+ //
+ // create the certificate - version 1
+ //
+ sigGen = new JcaContentSignerBuilder("SHA1withDSA").setProvider(BC).build(privKey);
+ JcaX509v1CertificateBuilder certGen1 = new JcaX509v1CertificateBuilder(builder.build(),BigInteger.valueOf(1),new Date(System.currentTimeMillis() - 50000),new Date(System.currentTimeMillis() + 50000),builder.build(),pubKey);
+
+ cert = new JcaX509CertificateConverter().setProvider(BC).getCertificate(certGen1.build(sigGen));
+
+ cert.checkValidity(new Date());
+
+ cert.verify(pubKey);
+
+ bIn = new ByteArrayInputStream(cert.getEncoded());
+ fact = CertificateFactory.getInstance("X.509", BC);
+
+ cert = (X509Certificate)fact.generateCertificate(bIn);
+
+ //System.out.println(cert);
+
+ //
+ // exception test
+ //
+ try
+ {
+ certGen1 = new JcaX509v1CertificateBuilder(builder.build(),BigInteger.valueOf(1),new Date(System.currentTimeMillis() - 50000),new Date(System.currentTimeMillis() + 50000),builder.build(),dudPublicKey);
+
+
+ fail("key without encoding not detected in v1");
+ }
+ catch (IllegalArgumentException e)
+ {
+ // expected
+ }
+ }
+
+ private X500NameBuilder createStdBuilder()
+ {
+ X500NameBuilder builder = new X500NameBuilder(BCStyle.INSTANCE);
+
+ builder.addRDN(BCStyle.C, "AU");
+ builder.addRDN(BCStyle.O, "The Legion of the Bouncy Castle");
+ builder.addRDN(BCStyle.L, "Melbourne");
+ builder.addRDN(BCStyle.ST, "Victoria");
+ builder.addRDN(BCStyle.E, "feedback-crypto@bouncycastle.org");
+
+ return builder;
+ }
+
+ /**
+ * we generate a self signed certificate for the sake of testing - ECDSA
+ */
+ public void checkCreation3()
+ {
+ ECCurve curve = new ECCurve.Fp(
+ new BigInteger("883423532389192164791648750360308885314476597252960362792450860609699839"), // q
+ new BigInteger("7fffffffffffffffffffffff7fffffffffff8000000000007ffffffffffc", 16), // a
+ new BigInteger("6b016c3bdcf18941d0d654921475ca71a9db2fb27d1d37796185c2942c0a", 16)); // b
+
+ ECParameterSpec spec = new ECParameterSpec(
+ curve,
+ curve.decodePoint(Hex.decode("020ffa963cdca8816ccc33b8642bedf905c3d358573d3f27fbbd3b3cb9aaaf")), // G
+ new BigInteger("883423532389192164791648750360308884807550341691627752275345424702807307")); // n
+
+
+ ECPrivateKeySpec privKeySpec = new ECPrivateKeySpec(
+ new BigInteger("876300101507107567501066130761671078357010671067781776716671676178726717"), // d
+ spec);
+
+ ECPublicKeySpec pubKeySpec = new ECPublicKeySpec(
+ curve.decodePoint(Hex.decode("025b6dc53bc61a2548ffb0f671472de6c9521a9d2d2534e65abfcbd5fe0c70")), // Q
+ spec);
+
+ //
+ // set up the keys
+ //
+ PrivateKey privKey;
+ PublicKey pubKey;
+
+ try
+ {
+ KeyFactory fact = KeyFactory.getInstance("ECDSA", BC);
+
+ privKey = fact.generatePrivate(privKeySpec);
+ pubKey = fact.generatePublic(pubKeySpec);
+ }
+ catch (Exception e)
+ {
+ fail("error setting up keys - " + e.toString());
+ return;
+ }
+
+ //
+ // distinguished name table.
+ //
+ X500NameBuilder builder = createStdBuilder();
+
+
+ //
+ // toString test
+ //
+ X500Name p = builder.build();
+ String s = p.toString();
+
+ if (!s.equals("C=AU,O=The Legion of the Bouncy Castle,L=Melbourne,ST=Victoria,E=feedback-crypto@bouncycastle.org"))
+ {
+ fail("ordered X509Principal test failed - s = " + s + ".");
+ }
+
+// p = new X509Principal(attrs);
+// s = p.toString();
+//
+// //
+// // we need two of these as the hash code for strings changed...
+// //
+// if (!s.equals("O=The Legion of the Bouncy Castle,E=feedback-crypto@bouncycastle.org,ST=Victoria,L=Melbourne,C=AU") && !s.equals("ST=Victoria,L=Melbourne,C=AU,E=feedback-crypto@bouncycastle.org,O=The Legion of the Bouncy Castle"))
+// {
+// fail("unordered X509Principal test failed.");
+// }
+
+ //
+ // create the certificate - version 3
+ //
+ try
+ {
+ ContentSigner sigGen = new JcaContentSignerBuilder("SHA1withECDSA").setProvider(BC).build(privKey);
+ JcaX509v3CertificateBuilder certGen = new JcaX509v3CertificateBuilder(builder.build(),BigInteger.valueOf(1),new Date(System.currentTimeMillis() - 50000),new Date(System.currentTimeMillis() + 50000),builder.build(),pubKey);
+
+ X509Certificate cert = new JcaX509CertificateConverter().setProvider(BC).getCertificate(certGen.build(sigGen));
+
+ cert.checkValidity(new Date());
+
+ cert.verify(pubKey);
+
+ ByteArrayInputStream bIn = new ByteArrayInputStream(cert.getEncoded());
+ CertificateFactory fact = CertificateFactory.getInstance("X.509", BC);
+
+ cert = (X509Certificate)fact.generateCertificate(bIn);
+
+ //
+ // try with point compression turned off
+ //
+ ((ECPointEncoder)pubKey).setPointFormat("UNCOMPRESSED");
+
+ certGen = new JcaX509v3CertificateBuilder(builder.build(),BigInteger.valueOf(1),new Date(System.currentTimeMillis() - 50000),new Date(System.currentTimeMillis() + 50000),builder.build(),pubKey);
+
+ cert = new JcaX509CertificateConverter().setProvider(BC).getCertificate(certGen.build(sigGen));
+
+ cert.checkValidity(new Date());
+
+ cert.verify(pubKey);
+
+ bIn = new ByteArrayInputStream(cert.getEncoded());
+ fact = CertificateFactory.getInstance("X.509", BC);
+
+ cert = (X509Certificate)fact.generateCertificate(bIn);
+ // System.out.println(cert);
+ }
+ catch (Exception e)
+ {
+ fail("error setting generating cert - " + e.toString());
+ }
+
+ X509Principal pr = new X509Principal("O=\"The Bouncy Castle, The Legion of\",E=feedback-crypto@bouncycastle.org,ST=Victoria,L=Melbourne,C=AU");
+
+ if (!pr.toString().equals("O=The Bouncy Castle\\, The Legion of,E=feedback-crypto@bouncycastle.org,ST=Victoria,L=Melbourne,C=AU"))
+ {
+ fail("string based X509Principal test failed.");
+ }
+
+ pr = new X509Principal("O=The Bouncy Castle\\, The Legion of,E=feedback-crypto@bouncycastle.org,ST=Victoria,L=Melbourne,C=AU");
+
+ if (!pr.toString().equals("O=The Bouncy Castle\\, The Legion of,E=feedback-crypto@bouncycastle.org,ST=Victoria,L=Melbourne,C=AU"))
+ {
+ fail("string based X509Principal test failed.");
+ }
+
+ }
+
+ /**
+ * we generate a self signed certificate for the sake of testing - SHA224withECDSA
+ */
+ private void createECCert(String algorithm, ASN1ObjectIdentifier algOid)
+ throws Exception
+ {
+ ECCurve.Fp curve = new ECCurve.Fp(
+ new BigInteger("6864797660130609714981900799081393217269435300143305409394463459185543183397656052122559640661454554977296311391480858037121987999716643812574028291115057151"), // q (or p)
+ new BigInteger("01FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC", 16), // a
+ new BigInteger("0051953EB9618E1C9A1F929A21A0B68540EEA2DA725B99B315F3B8B489918EF109E156193951EC7E937B1652C0BD3BB1BF073573DF883D2C34F1EF451FD46B503F00", 16)); // b
+
+ ECParameterSpec spec = new ECParameterSpec(
+ curve,
+ curve.decodePoint(Hex.decode("0200C6858E06B70404E9CD9E3ECB662395B4429C648139053FB521F828AF606B4D3DBAA14B5E77EFE75928FE1DC127A2FFA8DE3348B3C1856A429BF97E7E31C2E5BD66")), // G
+ new BigInteger("01FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA51868783BF2F966B7FCC0148F709A5D03BB5C9B8899C47AEBB6FB71E91386409", 16)); // n
+
+ ECPrivateKeySpec privKeySpec = new ECPrivateKeySpec(
+ new BigInteger("5769183828869504557786041598510887460263120754767955773309066354712783118202294874205844512909370791582896372147797293913785865682804434049019366394746072023"), // d
+ spec);
+
+ ECPublicKeySpec pubKeySpec = new ECPublicKeySpec(
+ curve.decodePoint(Hex.decode("02006BFDD2C9278B63C92D6624F151C9D7A822CC75BD983B17D25D74C26740380022D3D8FAF304781E416175EADF4ED6E2B47142D2454A7AC7801DD803CF44A4D1F0AC")), // Q
+ spec);
+
+ //
+ // set up the keys
+ //
+ PrivateKey privKey;
+ PublicKey pubKey;
+
+ KeyFactory fact = KeyFactory.getInstance("ECDSA", BC);
+
+ privKey = fact.generatePrivate(privKeySpec);
+ pubKey = fact.generatePublic(pubKeySpec);
+
+
+ //
+ // distinguished name table.
+ //
+ X500NameBuilder builder = createStdBuilder();
+
+ //
+ // create the certificate - version 3
+ //
+ ContentSigner sigGen = new JcaContentSignerBuilder(algorithm).setProvider(BC).build(privKey);
+ X509v3CertificateBuilder certGen = new JcaX509v3CertificateBuilder(builder.build(),BigInteger.valueOf(1),new Date(System.currentTimeMillis() - 50000),new Date(System.currentTimeMillis() + 50000),builder.build(),pubKey);
+
+ X509Certificate cert = new JcaX509CertificateConverter().setProvider(BC).getCertificate(certGen.build(sigGen));
+
+ cert.checkValidity(new Date());
+
+ cert.verify(pubKey);
+
+ ByteArrayInputStream bIn = new ByteArrayInputStream(cert.getEncoded());
+ CertificateFactory certFact = CertificateFactory.getInstance("X.509", BC);
+
+ cert = (X509Certificate)certFact.generateCertificate(bIn);
+
+ //
+ // try with point compression turned off
+ //
+ ((ECPointEncoder)pubKey).setPointFormat("UNCOMPRESSED");
+
+ certGen = new JcaX509v3CertificateBuilder(builder.build(),BigInteger.valueOf(1),new Date(System.currentTimeMillis() - 50000),new Date(System.currentTimeMillis() + 50000),builder.build(),pubKey);
+
+ cert = new JcaX509CertificateConverter().setProvider(BC).getCertificate(certGen.build(sigGen));
+
+ cert.checkValidity(new Date());
+
+ cert.verify(pubKey);
+
+ bIn = new ByteArrayInputStream(cert.getEncoded());
+ certFact = CertificateFactory.getInstance("X.509", BC);
+
+ cert = (X509Certificate)certFact.generateCertificate(bIn);
+
+ if (!cert.getSigAlgOID().equals(algOid.toString()))
+ {
+ fail("ECDSA oid incorrect.");
+ }
+
+ if (cert.getSigAlgParams() != null)
+ {
+ fail("sig parameters present");
+ }
+
+ Signature sig = Signature.getInstance(algorithm, BC);
+
+ sig.initVerify(pubKey);
+
+ sig.update(cert.getTBSCertificate());
+
+ if (!sig.verify(cert.getSignature()))
+ {
+ fail("EC certificate signature not mapped correctly.");
+ }
+ // System.out.println(cert);
+ }
+
+ private void checkCRL(
+ int id,
+ byte[] bytes)
+ {
+ ByteArrayInputStream bIn;
+ String dump = "";
+
+ try
+ {
+ bIn = new ByteArrayInputStream(bytes);
+
+ CertificateFactory fact = CertificateFactory.getInstance("X.509", BC);
+
+ CRL cert = fact.generateCRL(bIn);
+
+ // System.out.println(cert);
+ }
+ catch (Exception e)
+ {
+ fail(dump + System.getProperty("line.separator") + getName() + ": "+ id + " failed - exception " + e.toString(), e);
+ }
+
+ }
+
+ public void checkCRLCreation1()
+ throws Exception
+ {
+ KeyPairGenerator kpGen = KeyPairGenerator.getInstance("RSA", BC);
+ Date now = new Date();
+ KeyPair pair = kpGen.generateKeyPair();
+ X509v2CRLBuilder crlGen = new X509v2CRLBuilder(new X500Name("CN=Test CA"), now);
+
+ crlGen.setNextUpdate(new Date(now.getTime() + 100000));
+
+ crlGen.addCRLEntry(BigInteger.ONE, now, CRLReason.privilegeWithdrawn);
+
+ crlGen.addExtension(X509Extensions.AuthorityKeyIdentifier, false, new AuthorityKeyIdentifierStructure(pair.getPublic()));
+
+ X509CRLHolder crl = crlGen.build(new JcaContentSignerBuilder("SHA256withRSAEncryption").setProvider(BC).build(pair.getPrivate()));
+
+ if (!crl.getIssuer().equals(new X500Name("CN=Test CA")))
+ {
+ fail("failed CRL issuer test");
+ }
+
+ Extension authExt = crl.getExtension(Extension.authorityKeyIdentifier);
+
+ if (authExt == null)
+ {
+ fail("failed to find CRL extension");
+ }
+
+ AuthorityKeyIdentifier authId = new AuthorityKeyIdentifierStructure(authExt);
+
+ X509CRLEntryHolder entry = crl.getRevokedCertificate(BigInteger.ONE);
+
+ if (entry == null)
+ {
+ fail("failed to find CRL entry");
+ }
+
+ if (!entry.getSerialNumber().equals(BigInteger.ONE))
+ {
+ fail("CRL cert serial number does not match");
+ }
+
+ if (!entry.hasExtensions())
+ {
+ fail("CRL entry extension not found");
+ }
+
+ Extension ext = entry.getExtension(X509Extension.reasonCode);
+
+ if (ext != null)
+ {
+ ASN1Enumerated reasonCode = (ASN1Enumerated)ASN1Enumerated.getInstance(ext.getParsedValue());
+
+ if (reasonCode.getValue().intValue() != CRLReason.privilegeWithdrawn)
+ {
+ fail("CRL entry reasonCode wrong");
+ }
+ }
+ else
+ {
+ fail("CRL entry reasonCode not found");
+ }
+ }
+
+ public void checkCRLCreation2()
+ throws Exception
+ {
+ KeyPairGenerator kpGen = KeyPairGenerator.getInstance("RSA", BC);
+
+ Date now = new Date();
+ KeyPair pair = kpGen.generateKeyPair();
+ X509v2CRLBuilder crlGen = new JcaX509v2CRLBuilder(new X500Principal("CN=Test CA"), now);
+
+ crlGen.setNextUpdate(new Date(now.getTime() + 100000));
+
+ Vector extOids = new Vector();
+ Vector extValues = new Vector();
+
+ CRLReason crlReason = CRLReason.lookup(CRLReason.privilegeWithdrawn);
+
+ try
+ {
+ extOids.addElement(X509Extensions.ReasonCode);
+ extValues.addElement(new X509Extension(false, new DEROctetString(crlReason.getEncoded())));
+ }
+ catch (IOException e)
+ {
+ throw new IllegalArgumentException("error encoding reason: " + e);
+ }
+
+ X509Extensions entryExtensions = new X509Extensions(extOids, extValues);
+
+ crlGen.addCRLEntry(BigInteger.ONE, now, entryExtensions);
+
+ crlGen.addExtension(X509Extensions.AuthorityKeyIdentifier, false, new AuthorityKeyIdentifierStructure(pair.getPublic()));
+
+ X509CRLHolder crlHolder = crlGen.build(new JcaContentSignerBuilder("SHA256withRSAEncryption").setProvider(BC).build(pair.getPrivate()));
+
+ X509CRL crl = new JcaX509CRLConverter().setProvider(BC).getCRL(crlHolder);
+
+ if (!crl.getIssuerX500Principal().equals(new X500Principal("CN=Test CA")))
+ {
+ fail("failed CRL issuer test");
+ }
+
+ byte[] authExt = crl.getExtensionValue(X509Extensions.AuthorityKeyIdentifier.getId());
+
+ if (authExt == null)
+ {
+ fail("failed to find CRL extension");
+ }
+
+ AuthorityKeyIdentifier authId = new AuthorityKeyIdentifierStructure(authExt);
+
+ X509CRLEntry entry = crl.getRevokedCertificate(BigInteger.ONE);
+
+ if (entry == null)
+ {
+ fail("failed to find CRL entry");
+ }
+
+ if (!entry.getSerialNumber().equals(BigInteger.ONE))
+ {
+ fail("CRL cert serial number does not match");
+ }
+
+ if (!entry.hasExtensions())
+ {
+ fail("CRL entry extension not found");
+ }
+
+ byte[] ext = entry.getExtensionValue(X509Extensions.ReasonCode.getId());
+
+ if (ext != null)
+ {
+ ASN1Enumerated reasonCode = (ASN1Enumerated)X509ExtensionUtil.fromExtensionValue(ext);
+
+ if (reasonCode.getValue().intValue() != CRLReason.privilegeWithdrawn)
+ {
+ fail("CRL entry reasonCode wrong");
+ }
+ }
+ else
+ {
+ fail("CRL entry reasonCode not found");
+ }
+ }
+
+ public void checkCRLCreation3()
+ throws Exception
+ {
+ KeyPairGenerator kpGen = KeyPairGenerator.getInstance("RSA", BC);
+ Date now = new Date();
+ KeyPair pair = kpGen.generateKeyPair();
+ X509v2CRLBuilder crlGen = new JcaX509v2CRLBuilder(new X500Principal("CN=Test CA"), now);
+
+ crlGen.setNextUpdate(new Date(now.getTime() + 100000));
+
+ Vector extOids = new Vector();
+ Vector extValues = new Vector();
+
+ CRLReason crlReason = CRLReason.lookup(CRLReason.privilegeWithdrawn);
+
+ try
+ {
+ extOids.addElement(X509Extensions.ReasonCode);
+ extValues.addElement(new X509Extension(false, new DEROctetString(crlReason.getEncoded())));
+ }
+ catch (IOException e)
+ {
+ throw new IllegalArgumentException("error encoding reason: " + e);
+ }
+
+ X509Extensions entryExtensions = new X509Extensions(extOids, extValues);
+
+ crlGen.addCRLEntry(BigInteger.ONE, now, entryExtensions);
+
+ crlGen.addExtension(X509Extensions.AuthorityKeyIdentifier, false, new AuthorityKeyIdentifierStructure(pair.getPublic()));
+
+ X509CRLHolder crlHolder = crlGen.build(new JcaContentSignerBuilder("SHA256withRSAEncryption").setProvider(BC).build(pair.getPrivate()));
+
+ X509CRL crl = new JcaX509CRLConverter().setProvider(BC).getCRL(crlHolder);
+
+ if (!crl.getIssuerX500Principal().equals(new X500Principal("CN=Test CA")))
+ {
+ fail("failed CRL issuer test");
+ }
+
+ byte[] authExt = crl.getExtensionValue(X509Extensions.AuthorityKeyIdentifier.getId());
+
+ if (authExt == null)
+ {
+ fail("failed to find CRL extension");
+ }
+
+ AuthorityKeyIdentifier authId = new AuthorityKeyIdentifierStructure(authExt);
+
+ X509CRLEntry entry = crl.getRevokedCertificate(BigInteger.ONE);
+
+ if (entry == null)
+ {
+ fail("failed to find CRL entry");
+ }
+
+ if (!entry.getSerialNumber().equals(BigInteger.ONE))
+ {
+ fail("CRL cert serial number does not match");
+ }
+
+ if (!entry.hasExtensions())
+ {
+ fail("CRL entry extension not found");
+ }
+
+ byte[] ext = entry.getExtensionValue(X509Extensions.ReasonCode.getId());
+
+ if (ext != null)
+ {
+ ASN1Enumerated reasonCode = (ASN1Enumerated)X509ExtensionUtil.fromExtensionValue(ext);
+
+ if (reasonCode.getValue().intValue() != CRLReason.privilegeWithdrawn)
+ {
+ fail("CRL entry reasonCode wrong");
+ }
+ }
+ else
+ {
+ fail("CRL entry reasonCode not found");
+ }
+
+ //
+ // check loading of existing CRL
+ //
+ now = new Date();
+ crlGen = new X509v2CRLBuilder(new X500Name("CN=Test CA"), now);
+
+ crlGen.setNextUpdate(new Date(now.getTime() + 100000));
+
+ crlGen.addCRL(new JcaX509CRLHolder(crl));
+
+ crlGen.addCRLEntry(BigInteger.valueOf(2), now, entryExtensions);
+
+ crlGen.addExtension(X509Extension.authorityKeyIdentifier, false, new AuthorityKeyIdentifierStructure(pair.getPublic()));
+
+ crlHolder = crlGen.build(new JcaContentSignerBuilder("SHA256withRSAEncryption").setProvider(BC).build(pair.getPrivate()));
+
+ int count = 0;
+ boolean oneFound = false;
+ boolean twoFound = false;
+
+ Iterator it = crlHolder.getRevokedCertificates().iterator();
+ while (it.hasNext())
+ {
+ X509CRLEntryHolder crlEnt = (X509CRLEntryHolder)it.next();
+
+ if (crlEnt.getSerialNumber().intValue() == 1)
+ {
+ oneFound = true;
+ Extension extn = crlEnt.getExtension(X509Extension.reasonCode);
+
+ if (extn != null)
+ {
+ ASN1Enumerated reasonCode = (ASN1Enumerated)ASN1Enumerated.getInstance(extn.getParsedValue());
+
+ if (reasonCode.getValue().intValue() != CRLReason.privilegeWithdrawn)
+ {
+ fail("CRL entry reasonCode wrong");
+ }
+ }
+ else
+ {
+ fail("CRL entry reasonCode not found");
+ }
+ }
+ else if (crlEnt.getSerialNumber().intValue() == 2)
+ {
+ twoFound = true;
+ }
+
+ count++;
+ }
+
+ if (count != 2)
+ {
+ fail("wrong number of CRLs found");
+ }
+
+ if (!oneFound || !twoFound)
+ {
+ fail("wrong CRLs found in copied list");
+ }
+
+ //
+ // check factory read back
+ //
+ CertificateFactory cFact = CertificateFactory.getInstance("X.509", BC);
+
+ X509CRL readCrl = (X509CRL)cFact.generateCRL(new ByteArrayInputStream(crlHolder.getEncoded()));
+
+ if (readCrl == null)
+ {
+ fail("crl not returned!");
+ }
+
+ Collection col = cFact.generateCRLs(new ByteArrayInputStream(crlHolder.getEncoded()));
+
+ if (col.size() != 1)
+ {
+ fail("wrong number of CRLs found in collection");
+ }
+ }
+
+ /**
+ * we generate a self signed certificate for the sake of testing - GOST3410
+ */
+ public void checkCreation4()
+ throws Exception
+ {
+ //
+ // set up the keys
+ //
+ PrivateKey privKey;
+ PublicKey pubKey;
+
+ KeyPairGenerator g = KeyPairGenerator.getInstance("GOST3410", BC);
+ GOST3410ParameterSpec gost3410P = new GOST3410ParameterSpec("GostR3410-94-CryptoPro-A");
+
+ g.initialize(gost3410P, new SecureRandom());
+
+ KeyPair p = g.generateKeyPair();
+
+ privKey = p.getPrivate();
+ pubKey = p.getPublic();
+
+ //
+ // distinguished name table.
+ //
+ X500NameBuilder builder = createStdBuilder();
+
+ //
+ // extensions
+ //
+
+ //
+ // create the certificate - version 3
+ //
+ ContentSigner sigGen = new JcaContentSignerBuilder("GOST3411withGOST3410").setProvider(BC).build(privKey);
+ X509v3CertificateBuilder certGen = new JcaX509v3CertificateBuilder(builder.build(),BigInteger.valueOf(1),new Date(System.currentTimeMillis() - 50000),new Date(System.currentTimeMillis() + 50000),builder.build(),pubKey);
+
+ X509Certificate cert = new JcaX509CertificateConverter().setProvider(BC).getCertificate(certGen.build(sigGen));
+
+ cert.checkValidity(new Date());
+
+ //
+ // check verifies in general
+ //
+ cert.verify(pubKey);
+
+ //
+ // check verifies with contained key
+ //
+ cert.verify(cert.getPublicKey());
+
+ ByteArrayInputStream bIn = new ByteArrayInputStream(cert.getEncoded());
+ CertificateFactory fact = CertificateFactory.getInstance("X.509", BC);
+
+ cert = (X509Certificate)fact.generateCertificate(bIn);
+
+ //System.out.println(cert);
+
+ //check getEncoded()
+ byte[] bytes = cert.getEncoded();
+ }
+
+ public void checkCreation5()
+ throws Exception
+ {
+ //
+ // a sample key pair.
+ //
+ RSAPublicKeySpec pubKeySpec = new RSAPublicKeySpec(
+ new BigInteger("b4a7e46170574f16a97082b22be58b6a2a629798419be12872a4bdba626cfae9900f76abfb12139dce5de56564fab2b6543165a040c606887420e33d91ed7ed7", 16),
+ new BigInteger("11", 16));
+
+ RSAPrivateCrtKeySpec privKeySpec = new RSAPrivateCrtKeySpec(
+ new BigInteger("b4a7e46170574f16a97082b22be58b6a2a629798419be12872a4bdba626cfae9900f76abfb12139dce5de56564fab2b6543165a040c606887420e33d91ed7ed7", 16),
+ new BigInteger("11", 16),
+ new BigInteger("9f66f6b05410cd503b2709e88115d55daced94d1a34d4e32bf824d0dde6028ae79c5f07b580f5dce240d7111f7ddb130a7945cd7d957d1920994da389f490c89", 16),
+ new BigInteger("c0a0758cdf14256f78d4708c86becdead1b50ad4ad6c5c703e2168fbf37884cb", 16),
+ new BigInteger("f01734d7960ea60070f1b06f2bb81bfac48ff192ae18451d5e56c734a5aab8a5", 16),
+ new BigInteger("b54bb9edff22051d9ee60f9351a48591b6500a319429c069a3e335a1d6171391", 16),
+ new BigInteger("d3d83daf2a0cecd3367ae6f8ae1aeb82e9ac2f816c6fc483533d8297dd7884cd", 16),
+ new BigInteger("b8f52fc6f38593dabb661d3f50f8897f8106eee68b1bce78a95b132b4e5b5d19", 16));
+
+ //
+ // set up the keys
+ //
+ SecureRandom rand = new SecureRandom();
+ PrivateKey privKey;
+ PublicKey pubKey;
+
+ KeyFactory fact = KeyFactory.getInstance("RSA", BC);
+
+ privKey = fact.generatePrivate(privKeySpec);
+ pubKey = fact.generatePublic(pubKeySpec);
+
+ //
+ // distinguished name table.
+ //
+ Vector ord = new Vector();
+ Vector values = new Vector();
+
+ X500NameBuilder builder = createStdBuilder();
+
+ //
+ // create base certificate - version 3
+ //
+ ContentSigner sigGen = new JcaContentSignerBuilder("MD5WithRSAEncryption").setProvider(BC).build(privKey);
+ X509v3CertificateBuilder certGen = new JcaX509v3CertificateBuilder(builder.build(),BigInteger.valueOf(1),new Date(System.currentTimeMillis() - 50000),new Date(System.currentTimeMillis() + 50000),builder.build(),pubKey)
+ .addExtension(new ASN1ObjectIdentifier("2.5.29.15"), true,
+ new X509KeyUsage(X509KeyUsage.encipherOnly))
+ .addExtension(new ASN1ObjectIdentifier("2.5.29.37"), true,
+ new DERSequence(KeyPurposeId.anyExtendedKeyUsage))
+ .addExtension(new ASN1ObjectIdentifier("2.5.29.17"), true,
+ new GeneralNames(new GeneralName(GeneralName.rfc822Name, "test@test.test")));
+
+ X509Certificate baseCert = new JcaX509CertificateConverter().setProvider(BC).getCertificate(certGen.build(sigGen));
+
+ //
+ // copy certificate
+ //
+
+ certGen = new JcaX509v3CertificateBuilder(builder.build(),BigInteger.valueOf(1),new Date(System.currentTimeMillis() - 50000),new Date(System.currentTimeMillis() + 50000),builder.build(),pubKey)
+ .copyAndAddExtension(new ASN1ObjectIdentifier("2.5.29.15"), true, baseCert)
+ .copyAndAddExtension(new ASN1ObjectIdentifier("2.5.29.37"), false, baseCert);
+
+ X509Certificate cert = new JcaX509CertificateConverter().setProvider(BC).getCertificate(certGen.build(sigGen));
+
+ cert.checkValidity(new Date());
+
+ cert.verify(pubKey);
+
+ if (!areEqual(baseCert.getExtensionValue("2.5.29.15"), cert.getExtensionValue("2.5.29.15")))
+ {
+ fail("2.5.29.15 differs");
+ }
+
+ if (!areEqual(baseCert.getExtensionValue("2.5.29.37"), cert.getExtensionValue("2.5.29.37")))
+ {
+ fail("2.5.29.37 differs");
+ }
+
+ //
+ // exception test
+ //
+
+ try
+ {
+ certGen.copyAndAddExtension(new ASN1ObjectIdentifier("2.5.99.99"), true, new JcaX509CertificateHolder(baseCert));
+
+ fail("exception not thrown on dud extension copy");
+ }
+ catch (NullPointerException e)
+ {
+ // expected
+ }
+
+// try
+// {
+// certGen.setPublicKey(dudPublicKey);
+//
+// certGen.generate(privKey, BC);
+//
+// fail("key without encoding not detected in v3");
+// }
+// catch (IllegalArgumentException e)
+// {
+// // expected
+// }
+
+ }
+
+ private void testForgedSignature()
+ throws Exception
+ {
+ String cert = "MIIBsDCCAVoCAQYwDQYJKoZIhvcNAQEFBQAwYzELMAkGA1UEBhMCQVUxEzARBgNV"
+ + "BAgTClF1ZWVuc2xhbmQxGjAYBgNVBAoTEUNyeXB0U29mdCBQdHkgTHRkMSMwIQYD"
+ + "VQQDExpTZXJ2ZXIgdGVzdCBjZXJ0ICg1MTIgYml0KTAeFw0wNjA5MTEyMzU4NTVa"
+ + "Fw0wNjEwMTEyMzU4NTVaMGMxCzAJBgNVBAYTAkFVMRMwEQYDVQQIEwpRdWVlbnNs"
+ + "YW5kMRowGAYDVQQKExFDcnlwdFNvZnQgUHR5IEx0ZDEjMCEGA1UEAxMaU2VydmVy"
+ + "IHRlc3QgY2VydCAoNTEyIGJpdCkwXDANBgkqhkiG9w0BAQEFAANLADBIAkEAn7PD"
+ + "hCeV/xIxUg8V70YRxK2A5jZbD92A12GN4PxyRQk0/lVmRUNMaJdq/qigpd9feP/u"
+ + "12S4PwTLb/8q/v657QIDAQABMA0GCSqGSIb3DQEBBQUAA0EAbynCRIlUQgaqyNgU"
+ + "DF6P14yRKUtX8akOP2TwStaSiVf/akYqfLFm3UGka5XbPj4rifrZ0/sOoZEEBvHQ"
+ + "e20sRA==";
+
+ CertificateFactory certFact = CertificateFactory.getInstance("X.509", BC);
+
+ X509Certificate x509 = (X509Certificate)certFact.generateCertificate(new ByteArrayInputStream(Base64.decode(cert)));
+ try
+ {
+ x509.verify(x509.getPublicKey());
+
+ fail("forged RSA signature passed");
+ }
+ catch (Exception e)
+ {
+ // expected
+ }
+ }
+
+
+ private void pemTest()
+ throws Exception
+ {
+ CertificateFactory cf = CertificateFactory.getInstance("X.509", BC);
+
+ Certificate cert = readPEMCert(cf, PEMData.CERTIFICATE_1);
+ if (cert == null)
+ {
+ fail("PEM cert not read");
+ }
+ cert = readPEMCert(cf, "-----BEGIN CERTIFICATE-----" + PEMData.CERTIFICATE_2);
+ if (cert == null)
+ {
+ fail("PEM cert with extraneous header not read");
+ }
+ CRL crl = cf.generateCRL(new ByteArrayInputStream(PEMData.CRL_1.getBytes("US-ASCII")));
+ if (crl == null)
+ {
+ fail("PEM crl not read");
+ }
+ Collection col = cf.generateCertificates(new ByteArrayInputStream(PEMData.CERTIFICATE_2.getBytes("US-ASCII")));
+ if (col.size() != 1 || !col.contains(cert))
+ {
+ fail("PEM cert collection not right");
+ }
+ col = cf.generateCRLs(new ByteArrayInputStream(PEMData.CRL_2.getBytes("US-ASCII")));
+ if (col.size() != 1 || !col.contains(crl))
+ {
+ fail("PEM crl collection not right");
+ }
+ }
+
+ private static Certificate readPEMCert(CertificateFactory cf, String pemData)
+ throws CertificateException, UnsupportedEncodingException
+ {
+ return cf.generateCertificate(new ByteArrayInputStream(pemData.getBytes("US-ASCII")));
+ }
+
+ private void pkcs7Test()
+ throws Exception
+ {
+ /*
+ ASN1EncodableVector certs = new ASN1EncodableVector();
+
+ certs.add(new ASN1InputStream(CertPathTest.rootCertBin).readObject());
+ certs.add(new DERTaggedObject(false, 2, new ASN1InputStream(AttrCertTest.attrCert).readObject()));
+
+ ASN1EncodableVector crls = new ASN1EncodableVector();
+
+ crls.add(new ASN1InputStream(CertPathTest.rootCrlBin).readObject());
+ SignedData sigData = new SignedData(new DERSet(), new ContentInfo(CMSObjectIdentifiers.data, null), new DERSet(certs), new DERSet(crls), new DERSet());
+
+ ContentInfo info = new ContentInfo(CMSObjectIdentifiers.signedData, sigData);
+
+ CertificateFactory cf = CertificateFactory.getInstance("X.509", BC);
+
+ X509Certificate cert = (X509Certificate)cf.generateCertificate(new ByteArrayInputStream(info.getEncoded()));
+ if (cert == null || !areEqual(cert.getEncoded(), certs.get(0).getDERObject().getEncoded()))
+ {
+ fail("PKCS7 cert not read");
+ }
+ X509CRL crl = (X509CRL)cf.generateCRL(new ByteArrayInputStream(info.getEncoded()));
+ if (crl == null || !areEqual(crl.getEncoded(), crls.get(0).getDERObject().getEncoded()))
+ {
+ fail("PKCS7 crl not read");
+ }
+ Collection col = cf.generateCertificates(new ByteArrayInputStream(info.getEncoded()));
+ if (col.size() != 1 || !col.contains(cert))
+ {
+ fail("PKCS7 cert collection not right");
+ }
+ col = cf.generateCRLs(new ByteArrayInputStream(info.getEncoded()));
+ if (col.size() != 1 || !col.contains(crl))
+ {
+ fail("PKCS7 crl collection not right");
+ }
+
+ // data with no certificates or CRLs
+
+ sigData = new SignedData(new DERSet(), new ContentInfo(CMSObjectIdentifiers.data, null), new DERSet(), new DERSet(), new DERSet());
+
+ info = new ContentInfo(CMSObjectIdentifiers.signedData, sigData);
+
+ cert = (X509Certificate)cf.generateCertificate(new ByteArrayInputStream(info.getEncoded()));
+ if (cert != null)
+ {
+ fail("PKCS7 cert present");
+ }
+ crl = (X509CRL)cf.generateCRL(new ByteArrayInputStream(info.getEncoded()));
+ if (crl != null)
+ {
+ fail("PKCS7 crl present");
+ }
+
+ // data with absent certificates and CRLS
+
+ sigData = new SignedData(new DERSet(), new ContentInfo(CMSObjectIdentifiers.data, null), null, null, new DERSet());
+
+ info = new ContentInfo(CMSObjectIdentifiers.signedData, sigData);
+
+ cert = (X509Certificate)cf.generateCertificate(new ByteArrayInputStream(info.getEncoded()));
+ if (cert != null)
+ {
+ fail("PKCS7 cert present");
+ }
+ crl = (X509CRL)cf.generateCRL(new ByteArrayInputStream(info.getEncoded()));
+ if (crl != null)
+ {
+ fail("PKCS7 crl present");
+ }
+
+ //
+ // sample message
+ //
+ InputStream in = new ByteArrayInputStream(pkcs7CrlProblem);
+ Collection certCol = cf.generateCertificates(in);
+ Collection crlCol = cf.generateCRLs(in);
+
+ if (crlCol.size() != 0)
+ {
+ fail("wrong number of CRLs: " + crlCol.size());
+ }
+
+ if (certCol.size() != 4)
+ {
+ fail("wrong number of Certs: " + certCol.size());
+ }
+ */
+ }
+
+ private void createPSSCert(String algorithm)
+ throws Exception
+ {
+ KeyPair pair = generateLongFixedKeys();
+
+ PrivateKey privKey = pair.getPrivate();
+ PublicKey pubKey = pair.getPublic();
+
+ //
+ // distinguished name table.
+ //
+
+ X500NameBuilder builder = createStdBuilder();
+
+ //
+ // create base certificate - version 3
+ //
+ ContentSigner sigGen = new JcaContentSignerBuilder(algorithm).setProvider(BC).build(privKey);
+ JcaX509v3CertificateBuilder certGen = new JcaX509v3CertificateBuilder(builder.build(),BigInteger.valueOf(1),
+ new Date(System.currentTimeMillis() - 50000),new Date(System.currentTimeMillis() + 50000),builder.build(),pubKey);
+
+ certGen.addExtension(new ASN1ObjectIdentifier("2.5.29.15"), true,
+ new X509KeyUsage(X509KeyUsage.encipherOnly));
+ certGen.addExtension(new ASN1ObjectIdentifier("2.5.29.37"), true,
+ new DERSequence(KeyPurposeId.anyExtendedKeyUsage));
+ certGen.addExtension(new ASN1ObjectIdentifier("2.5.29.17"), true,
+ new GeneralNames(new GeneralName(GeneralName.rfc822Name, "test@test.test")));
+
+ X509Certificate baseCert = new JcaX509CertificateConverter().setProvider(BC).getCertificate(certGen.build(sigGen));
+
+ baseCert.verify(pubKey);
+ }
+
+ private KeyPair generateLongFixedKeys()
+ throws NoSuchAlgorithmException, NoSuchProviderException, InvalidKeySpecException
+ {
+ RSAPublicKeySpec pubKeySpec = new RSAPublicKeySpec(
+ new BigInteger("a56e4a0e701017589a5187dc7ea841d156f2ec0e36ad52a44dfeb1e61f7ad991d8c51056ffedb162b4c0f283a12a88a394dff526ab7291cbb307ceabfce0b1dfd5cd9508096d5b2b8b6df5d671ef6377c0921cb23c270a70e2598e6ff89d19f105acc2d3f0cb35f29280e1386b6f64c4ef22e1e1f20d0ce8cffb2249bd9a2137",16),
+ new BigInteger("010001",16));
+
+ RSAPrivateCrtKeySpec privKeySpec = new RSAPrivateCrtKeySpec(
+ new BigInteger("a56e4a0e701017589a5187dc7ea841d156f2ec0e36ad52a44dfeb1e61f7ad991d8c51056ffedb162b4c0f283a12a88a394dff526ab7291cbb307ceabfce0b1dfd5cd9508096d5b2b8b6df5d671ef6377c0921cb23c270a70e2598e6ff89d19f105acc2d3f0cb35f29280e1386b6f64c4ef22e1e1f20d0ce8cffb2249bd9a2137",16),
+ new BigInteger("010001",16),
+ new BigInteger("33a5042a90b27d4f5451ca9bbbd0b44771a101af884340aef9885f2a4bbe92e894a724ac3c568c8f97853ad07c0266c8c6a3ca0929f1e8f11231884429fc4d9ae55fee896a10ce707c3ed7e734e44727a39574501a532683109c2abacaba283c31b4bd2f53c3ee37e352cee34f9e503bd80c0622ad79c6dcee883547c6a3b325",16),
+ new BigInteger("e7e8942720a877517273a356053ea2a1bc0c94aa72d55c6e86296b2dfc967948c0a72cbccca7eacb35706e09a1df55a1535bd9b3cc34160b3b6dcd3eda8e6443",16),
+ new BigInteger("b69dca1cf7d4d7ec81e75b90fcca874abcde123fd2700180aa90479b6e48de8d67ed24f9f19d85ba275874f542cd20dc723e6963364a1f9425452b269a6799fd",16),
+ new BigInteger("28fa13938655be1f8a159cbaca5a72ea190c30089e19cd274a556f36c4f6e19f554b34c077790427bbdd8dd3ede2448328f385d81b30e8e43b2fffa027861979",16),
+ new BigInteger("1a8b38f398fa712049898d7fb79ee0a77668791299cdfa09efc0e507acb21ed74301ef5bfd48be455eaeb6e1678255827580a8e4e8e14151d1510a82a3f2e729",16),
+ new BigInteger("27156aba4126d24a81f3a528cbfb27f56886f840a9f6e86e17a44b94fe9319584b8e22fdde1e5a2e3bd8aa5ba8d8584194eb2190acf832b847f13a3d24a79f4d",16));
+
+ KeyFactory fact = KeyFactory.getInstance("RSA", BC);
+
+ return new KeyPair(fact.generatePublic(pubKeySpec), fact.generatePrivate(privKeySpec));
+ }
+
+ private void rfc4491Test()
+ throws Exception
+ {
+ CertificateFactory certFact = CertificateFactory.getInstance("X.509", BC);
+
+ X509Certificate x509 = (X509Certificate)certFact.generateCertificate(new ByteArrayInputStream(gostRFC4491_94));
+
+ x509.verify(x509.getPublicKey(), BC);
+
+ x509 = (X509Certificate)certFact.generateCertificate(new ByteArrayInputStream(gostRFC4491_2001));
+
+ x509.verify(x509.getPublicKey(), BC);
+ }
+
+ private void testNullDerNullCert()
+ throws Exception
+ {
+ KeyPair pair = generateLongFixedKeys();
+ PublicKey pubKey = pair.getPublic();
+ PrivateKey privKey = pair.getPrivate();
+
+ ContentSigner sigGen = new JcaContentSignerBuilder("MD5WithRSAEncryption").setProvider(BC).build(privKey);
+ JcaX509v3CertificateBuilder certGen = new JcaX509v3CertificateBuilder(new X500Name("CN=Test"),BigInteger.valueOf(1),new Date(System.currentTimeMillis() - 50000),new Date(System.currentTimeMillis() + 50000),new X500Name("CN=Test"),pubKey);
+ X509Certificate cert = new JcaX509CertificateConverter().setProvider(BC).getCertificate(certGen.build(sigGen));
+
+ X509CertificateStructure struct = X509CertificateStructure.getInstance(ASN1Primitive.fromByteArray(cert.getEncoded()));
+
+ ASN1Encodable tbsCertificate = struct.getTBSCertificate();
+ AlgorithmIdentifier sig = struct.getSignatureAlgorithm();
+
+ ASN1EncodableVector v = new ASN1EncodableVector();
+
+ v.add(tbsCertificate);
+ v.add(new AlgorithmIdentifier(sig.getAlgorithm()));
+ v.add(struct.getSignature());
+
+ // verify
+ ByteArrayInputStream bIn;
+ String dump = "";
+
+ try
+ {
+ bIn = new ByteArrayInputStream(new DERSequence(v).getEncoded());
+
+ CertificateFactory fact = CertificateFactory.getInstance("X.509", BC);
+
+ cert = (X509Certificate)fact.generateCertificate(bIn);
+
+ cert.verify(cert.getPublicKey());
+ }
+ catch (Exception e)
+ {
+ fail(dump + System.getProperty("line.separator") + getName() + ": testNullDerNull failed - exception " + e.toString(), e);
+ }
+ }
+
+ private void testDirect()
+ throws Exception
+ {
+ KeyStore keyStore = KeyStore.getInstance("PKCS12", "SC");
+
+ ByteArrayInputStream input = new ByteArrayInputStream(testCAp12);
+
+ keyStore.load(input, "test".toCharArray());
+
+ X509Certificate certificate = (X509Certificate) keyStore.getCertificate("ca");
+ PrivateKey privateKey = (PrivateKey) keyStore.getKey("ca", null);
+
+ X500Name issuer = X500Name.getInstance(certificate.getIssuerX500Principal().getEncoded());
+
+ X509v2CRLBuilder builder = new X509v2CRLBuilder(issuer, new Date());
+
+ builder.addCRLEntry(certificate.getSerialNumber(), new Date(), CRLReason.cACompromise);
+
+ JcaContentSignerBuilder contentSignerBuilder = new JcaContentSignerBuilder("SHA256WithRSAEncryption");
+
+ contentSignerBuilder.setProvider("SC");
+
+ X509CRLHolder cRLHolder = builder.build(contentSignerBuilder.build(privateKey));
+
+ if (!cRLHolder.isSignatureValid(new JcaContentVerifierProviderBuilder().setProvider("SC").build(certificate)))
+ {
+ fail("CRL signature not valid");
+ }
+
+ X509CRLEntryHolder cRLEntryHolder = cRLHolder.getRevokedCertificate(certificate.getSerialNumber());
+
+ if (!cRLEntryHolder.getCertificateIssuer().equals(new GeneralNames(new GeneralName(cRLHolder.getIssuer()))))
+ {
+ fail("certificate issuer incorrect");
+ }
+
+ JcaX509CRLConverter converter = new JcaX509CRLConverter();
+
+ converter.setProvider("SC");
+
+ X509CRL crl = converter.getCRL(cRLHolder);
+
+ crl.verify(certificate.getPublicKey());
+
+ if (!crl.isRevoked(certificate))
+ {
+ fail("Certificate should be revoked");
+ }
+
+ // now encode the CRL and load the CRL with the JCE provider
+
+ CertificateFactory fac = CertificateFactory.getInstance("X.509");
+
+ X509CRL jceCRL = (X509CRL) fac.generateCRL(new ByteArrayInputStream(crl.getEncoded()));
+
+ jceCRL.verify(certificate.getPublicKey());
+
+ if (!jceCRL.isRevoked(certificate))
+ {
+ fail("This certificate should also be revoked");
+ }
+ }
+
+ private void testIndirect()
+ throws Exception
+ {
+ KeyStore keyStore = KeyStore.getInstance("PKCS12", "SC");
+
+ ByteArrayInputStream input = new ByteArrayInputStream(testCAp12);
+
+ keyStore.load(input, "test".toCharArray());
+
+ X509Certificate certificate = (X509Certificate) keyStore.getCertificate("ca");
+ PrivateKey privateKey = (PrivateKey) keyStore.getKey("ca", null);
+
+ X500Name crlIssuer = X500Name.getInstance(certificate.getSubjectX500Principal().getEncoded());
+ X500Name caName = X500Name.getInstance(certificate.getIssuerX500Principal().getEncoded());
+
+ X509v2CRLBuilder builder = new X509v2CRLBuilder(crlIssuer, new Date());
+
+ builder.addExtension(Extension.issuingDistributionPoint, true, new IssuingDistributionPoint(null, true, false));
+
+ ExtensionsGenerator extGen = new ExtensionsGenerator();
+
+ extGen.addExtension(Extension.reasonCode, false, CRLReason.lookup(CRLReason.cACompromise));
+ extGen.addExtension(Extension.certificateIssuer, true, new GeneralNames(new GeneralName(caName)));
+
+ builder.addCRLEntry(certificate.getSerialNumber(), new Date(), extGen.generate());
+
+ JcaContentSignerBuilder contentSignerBuilder = new JcaContentSignerBuilder("SHA256WithRSAEncryption");
+
+ contentSignerBuilder.setProvider("SC");
+
+ X509CRLHolder cRLHolder = builder.build(contentSignerBuilder.build(privateKey));
+
+ if (!cRLHolder.isSignatureValid(new JcaContentVerifierProviderBuilder().setProvider("SC").build(certificate)))
+ {
+ fail("CRL signature not valid");
+ }
+
+ X509CRLEntryHolder cRLEntryHolder = cRLHolder.getRevokedCertificate(certificate.getSerialNumber());
+
+ if (!cRLEntryHolder.getCertificateIssuer().equals(new GeneralNames(new GeneralName(X500Name.getInstance(certificate.getIssuerX500Principal().getEncoded())))))
+ {
+ fail("certificate issuer incorrect");
+ }
+
+ JcaX509CRLConverter converter = new JcaX509CRLConverter();
+
+ converter.setProvider("SC");
+
+ X509CRL crl = converter.getCRL(cRLHolder);
+
+ crl.verify(certificate.getPublicKey());
+
+ if (!crl.isRevoked(certificate))
+ {
+ fail("Certificate should be revoked");
+ }
+
+ // now encode the CRL and load the CRL with the JCE provider
+
+ CertificateFactory fac = CertificateFactory.getInstance("X.509");
+
+ X509CRL jceCRL = (X509CRL) fac.generateCRL(new ByteArrayInputStream(crl.getEncoded()));
+
+ jceCRL.verify(certificate.getPublicKey());
+
+ if (!jceCRL.isRevoked(certificate))
+ {
+ fail("This certificate should also be revoked");
+ }
+ }
+
+ private void testIndirect2()
+ throws Exception
+ {
+ KeyStore keyStore = KeyStore.getInstance("PKCS12", "SC");
+
+ ByteArrayInputStream input = new ByteArrayInputStream(testCAp12);
+
+ keyStore.load(input, "test".toCharArray());
+
+ X509Certificate certificate = (X509Certificate) keyStore.getCertificate("ca");
+ PrivateKey privateKey = (PrivateKey) keyStore.getKey("ca", null);
+
+ X500Name crlIssuer = X500Name.getInstance(certificate.getSubjectX500Principal().getEncoded());
+ X500Name caName = X500Name.getInstance(certificate.getIssuerX500Principal().getEncoded());
+
+ X509v2CRLBuilder builder = new X509v2CRLBuilder(crlIssuer, new Date());
+
+ builder.addExtension(Extension.issuingDistributionPoint, true, new IssuingDistributionPoint(null, true, false));
+
+ builder.addCRLEntry(BigInteger.valueOf(100), new Date(), CRLReason.cACompromise);
+ builder.addCRLEntry(BigInteger.valueOf(120), new Date(), CRLReason.cACompromise);
+
+ ExtensionsGenerator extGen = new ExtensionsGenerator();
+
+ extGen.addExtension(Extension.reasonCode, false, CRLReason.lookup(CRLReason.cACompromise));
+ extGen.addExtension(Extension.certificateIssuer, true, new GeneralNames(new GeneralName(caName)));
+
+ builder.addCRLEntry(certificate.getSerialNumber(), new Date(), extGen.generate());
+
+ builder.addCRLEntry(BigInteger.valueOf(130), new Date(), CRLReason.cACompromise);
+
+ JcaContentSignerBuilder contentSignerBuilder = new JcaContentSignerBuilder("SHA256WithRSAEncryption");
+
+ contentSignerBuilder.setProvider("SC");
+
+ X509CRLHolder cRLHolder = builder.build(contentSignerBuilder.build(privateKey));
+
+ if (!cRLHolder.isSignatureValid(new JcaContentVerifierProviderBuilder().setProvider("SC").build(certificate)))
+ {
+ fail("CRL signature not valid");
+ }
+
+ X509CRLEntryHolder cRLEntryHolder = cRLHolder.getRevokedCertificate(certificate.getSerialNumber());
+
+ if (!cRLEntryHolder.getCertificateIssuer().equals(new GeneralNames(new GeneralName(caName))))
+ {
+ fail("certificate issuer incorrect");
+ }
+
+ cRLEntryHolder = cRLHolder.getRevokedCertificate(BigInteger.valueOf(130));
+
+ if (!cRLEntryHolder.getCertificateIssuer().equals(new GeneralNames(new GeneralName(caName))))
+ {
+ fail("certificate issuer incorrect");
+ }
+
+ cRLEntryHolder = cRLHolder.getRevokedCertificate(BigInteger.valueOf(100));
+
+ if (!cRLEntryHolder.getCertificateIssuer().equals(new GeneralNames(new GeneralName(cRLHolder.getIssuer()))))
+ {
+ fail("certificate issuer incorrect");
+ }
+
+ JcaX509CRLConverter converter = new JcaX509CRLConverter();
+
+ converter.setProvider("SC");
+
+ X509CRL crl = converter.getCRL(cRLHolder);
+
+ crl.verify(certificate.getPublicKey());
+
+ X509CRLEntry crlEntry = crl.getRevokedCertificate(BigInteger.valueOf(100));
+
+ if (crlEntry.getCertificateIssuer() != null)
+ {
+ fail("JCA 1 certificate issuer incorrect");
+ }
+
+ crlEntry = crl.getRevokedCertificate(BigInteger.valueOf(130));
+ if (!crlEntry.getCertificateIssuer().equals(new X500Principal(caName.getEncoded())))
+ {
+ fail("JCA 2 certificate issuer incorrect");
+ }
+ }
+
+ // issuing distribution point must be set for an indirect CRL to be recognised
+ private void testMalformedIndirect()
+ throws Exception
+ {
+ KeyStore keyStore = KeyStore.getInstance("PKCS12", "SC");
+
+ ByteArrayInputStream input = new ByteArrayInputStream(testCAp12);
+
+ keyStore.load(input, "test".toCharArray());
+
+ X509Certificate certificate = (X509Certificate) keyStore.getCertificate("ca");
+ PrivateKey privateKey = (PrivateKey) keyStore.getKey("ca", null);
+
+ X500Name crlIssuer = X500Name.getInstance(certificate.getSubjectX500Principal().getEncoded());
+ X500Name caName = X500Name.getInstance(certificate.getIssuerX500Principal().getEncoded());
+
+ X509v2CRLBuilder builder = new X509v2CRLBuilder(crlIssuer, new Date());
+
+ ExtensionsGenerator extGen = new ExtensionsGenerator();
+
+ extGen.addExtension(Extension.reasonCode, false, CRLReason.lookup(CRLReason.cACompromise));
+ extGen.addExtension(Extension.certificateIssuer, true, new GeneralNames(new GeneralName(caName)));
+
+ builder.addCRLEntry(certificate.getSerialNumber(), new Date(), extGen.generate());
+
+ JcaContentSignerBuilder contentSignerBuilder = new JcaContentSignerBuilder("SHA256WithRSAEncryption");
+
+ contentSignerBuilder.setProvider("SC");
+
+ X509CRLHolder cRLHolder = builder.build(contentSignerBuilder.build(privateKey));
+
+ if (!cRLHolder.isSignatureValid(new JcaContentVerifierProviderBuilder().setProvider("SC").build(certificate)))
+ {
+ fail("CRL signature not valid");
+ }
+
+ X509CRLEntryHolder cRLEntryHolder = cRLHolder.getRevokedCertificate(certificate.getSerialNumber());
+
+ if (!cRLEntryHolder.getCertificateIssuer().equals(new GeneralNames(new GeneralName(cRLHolder.getIssuer()))))
+ {
+ fail("certificate issuer incorrect");
+ }
+
+ JcaX509CRLConverter converter = new JcaX509CRLConverter();
+
+ converter.setProvider("SC");
+
+ X509CRL crl = converter.getCRL(cRLHolder);
+
+ crl.verify(certificate.getPublicKey());
+
+ if (crl.isRevoked(certificate))
+ {
+ throw new Exception("Certificate should not be revoked");
+ }
+ }
+
+ public void performTest()
+ throws Exception
+ {
+ testDirect();
+ testIndirect();
+ testIndirect2();
+ testMalformedIndirect();
+
+ checkCertificate(1, cert1);
+ checkCertificate(2, cert2);
+ checkCertificate(3, cert3);
+ checkCertificate(4, cert4);
+ checkCertificate(5, cert5);
+ checkCertificate(6, oldEcdsa);
+ checkCertificate(7, cert7);
+
+ checkKeyUsage(8, keyUsage);
+ checkSelfSignedCertificate(9, uncompressedPtEC);
+ checkNameCertificate(10, nameCert);
+
+ checkSelfSignedCertificate(11, probSelfSignedCert);
+ checkSelfSignedCertificate(12, gostCA1);
+ checkSelfSignedCertificate(13, gostCA2);
+ checkSelfSignedCertificate(14, gost341094base);
+ checkSelfSignedCertificate(15, gost34102001base);
+ checkSelfSignedCertificate(16, gost341094A);
+ checkSelfSignedCertificate(17, gost341094B);
+ checkSelfSignedCertificate(17, gost34102001A);
+
+ checkCRL(1, crl1);
+
+ checkCreation1();
+ checkCreation2();
+ checkCreation3();
+ checkCreation4();
+ checkCreation5();
+
+ createECCert("SHA1withECDSA", X9ObjectIdentifiers.ecdsa_with_SHA1);
+ createECCert("SHA224withECDSA", X9ObjectIdentifiers.ecdsa_with_SHA224);
+ createECCert("SHA256withECDSA", X9ObjectIdentifiers.ecdsa_with_SHA256);
+ createECCert("SHA384withECDSA", X9ObjectIdentifiers.ecdsa_with_SHA384);
+ createECCert("SHA512withECDSA", X9ObjectIdentifiers.ecdsa_with_SHA512);
+
+ createPSSCert("SHA1withRSAandMGF1");
+ createPSSCert("SHA224withRSAandMGF1");
+ createPSSCert("SHA256withRSAandMGF1");
+ createPSSCert("SHA384withRSAandMGF1");
+
+ checkCRLCreation1();
+ checkCRLCreation2();
+ checkCRLCreation3();
+
+ pemTest();
+ pkcs7Test();
+ rfc4491Test();
+
+ testForgedSignature();
+
+ testNullDerNullCert();
+
+ checkCertificate(18, emptyDNCert);
+ }
+
+ public static void main(
+ String[] args)
+ {
+ Security.addProvider(new BouncyCastleProvider());
+
+ runTest(new CertTest());
+ }
+} \ No newline at end of file
diff --git a/pkix/src/test/java/org/spongycastle/cert/test/ConverterTest.java b/pkix/src/test/java/org/spongycastle/cert/test/ConverterTest.java
new file mode 100644
index 00000000..0c2f88b8
--- /dev/null
+++ b/pkix/src/test/java/org/spongycastle/cert/test/ConverterTest.java
@@ -0,0 +1,66 @@
+package org.spongycastle.cert.test;
+
+import java.math.BigInteger;
+import java.security.cert.X509CertSelector;
+
+import junit.framework.Test;
+import junit.framework.TestCase;
+import junit.framework.TestSuite;
+import org.spongycastle.asn1.DEROctetString;
+import org.spongycastle.asn1.x500.X500Name;
+import org.spongycastle.cert.selector.X509CertificateHolderSelector;
+import org.spongycastle.cert.selector.jcajce.JcaSelectorConverter;
+import org.spongycastle.cert.selector.jcajce.JcaX509CertSelectorConverter;
+import org.spongycastle.util.Arrays;
+
+public class ConverterTest
+ extends TestCase
+{
+ public void testCertificateSelectorConversion()
+ throws Exception
+ {
+ JcaX509CertSelectorConverter converter = new JcaX509CertSelectorConverter();
+ JcaSelectorConverter toSelector = new JcaSelectorConverter();
+
+ X509CertificateHolderSelector sid1 = new X509CertificateHolderSelector(new X500Name("CN=Test"), BigInteger.valueOf(1), new byte[20]);
+
+ X509CertSelector conv = converter.getCertSelector(sid1);
+
+ assertTrue(conv.getIssuerAsString().equals("CN=Test"));
+ assertTrue(Arrays.areEqual(conv.getSubjectKeyIdentifier(), new DEROctetString(new byte[20]).getEncoded()));
+ assertEquals(conv.getSerialNumber(), sid1.getSerialNumber());
+
+ X509CertificateHolderSelector sid2 = toSelector.getCertificateHolderSelector(conv);
+
+ assertEquals(sid1, sid2);
+
+ sid1 = new X509CertificateHolderSelector(new X500Name("CN=Test"), BigInteger.valueOf(1));
+
+ conv = converter.getCertSelector(sid1);
+
+ assertTrue(conv.getIssuerAsString().equals("CN=Test"));
+ assertNull(conv.getSubjectKeyIdentifier());
+ assertEquals(conv.getSerialNumber(), sid1.getSerialNumber());
+
+ sid2 = toSelector.getCertificateHolderSelector(conv);
+
+ assertEquals(sid1, sid2);
+
+ sid1 = new X509CertificateHolderSelector(new byte[20]);
+
+ conv = converter.getCertSelector(sid1);
+
+ assertNull(conv.getIssuerAsString());
+ assertTrue(Arrays.areEqual(conv.getSubjectKeyIdentifier(), new DEROctetString(new byte[20]).getEncoded()));
+ assertNull(conv.getSerialNumber());
+
+ sid2 = toSelector.getCertificateHolderSelector(conv);
+
+ assertEquals(sid1, sid2);
+ }
+
+ public static Test suite()
+ {
+ return new TestSuite(ConverterTest.class);
+ }
+}
diff --git a/pkix/src/test/java/org/spongycastle/cert/test/PEMData.java b/pkix/src/test/java/org/spongycastle/cert/test/PEMData.java
new file mode 100644
index 00000000..fff7f943
--- /dev/null
+++ b/pkix/src/test/java/org/spongycastle/cert/test/PEMData.java
@@ -0,0 +1,114 @@
+package org.spongycastle.cert.test;
+
+public class PEMData
+{
+ public static String CERTIFICATE_1 =
+ "-----BEGIN X509 CERTIFICATE-----\r"
+ + "MIIDXjCCAsegAwIBAgIBBzANBgkqhkiG9w0BAQQFADCBtzELMAkGA1UEBhMCQVUx\r"
+ + "ETAPBgNVBAgTCFZpY3RvcmlhMRgwFgYDVQQHEw9Tb3V0aCBNZWxib3VybmUxGjAY\r"
+ + "BgNVBAoTEUNvbm5lY3QgNCBQdHkgTHRkMR4wHAYDVQQLExVDZXJ0aWZpY2F0ZSBB\r"
+ + "dXRob3JpdHkxFTATBgNVBAMTDENvbm5lY3QgNCBDQTEoMCYGCSqGSIb3DQEJARYZ\r"
+ + "d2VibWFzdGVyQGNvbm5lY3Q0LmNvbS5hdTAeFw0wMDA2MDIwNzU2MjFaFw0wMTA2\r"
+ + "MDIwNzU2MjFaMIG4MQswCQYDVQQGEwJBVTERMA8GA1UECBMIVmljdG9yaWExGDAW\r"
+ + "BgNVBAcTD1NvdXRoIE1lbGJvdXJuZTEaMBgGA1UEChMRQ29ubmVjdCA0IFB0eSBM\r"
+ + "dGQxFzAVBgNVBAsTDldlYnNlcnZlciBUZWFtMR0wGwYDVQQDExR3d3cyLmNvbm5l\r"
+ + "Y3Q0LmNvbS5hdTEoMCYGCSqGSIb3DQEJARYZd2VibWFzdGVyQGNvbm5lY3Q0LmNv\r"
+ + "bS5hdTCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEArvDxclKAhyv7Q/Wmr2re\r"
+ + "Gw4XL9Cnh9e+6VgWy2AWNy/MVeXdlxzd7QAuc1eOWQkGQEiLPy5XQtTY+sBUJ3AO\r"
+ + "Rvd2fEVJIcjf29ey7bYua9J/vz5MG2KYo9/WCHIwqD9mmG9g0xLcfwq/s8ZJBswE\r"
+ + "7sb85VU+h94PTvsWOsWuKaECAwEAAaN3MHUwJAYDVR0RBB0wG4EZd2VibWFzdGVy\r"
+ + "QGNvbm5lY3Q0LmNvbS5hdTA6BglghkgBhvhCAQ0ELRYrbW9kX3NzbCBnZW5lcmF0\r"
+ + "ZWQgY3VzdG9tIHNlcnZlciBjZXJ0aWZpY2F0ZTARBglghkgBhvhCAQEEBAMCBkAw\r"
+ + "DQYJKoZIhvcNAQEEBQADgYEAotccfKpwSsIxM1Hae8DR7M/Rw8dg/RqOWx45HNVL\r"
+ + "iBS4/3N/TO195yeQKbfmzbAA2jbPVvIvGgTxPgO1MP4ZgvgRhasaa0qCJCkWvpM4\r"
+ + "yQf33vOiYQbpv4rTwzU8AmRlBG45WdjyNIigGV+oRc61aKCTnLq7zB8N3z1TF/bF\r"
+ + "5/8=\r"
+ + "-----END X509 CERTIFICATE-----\r";
+
+ public static String CERTIFICATE_2 =
+ "-----BEGIN CERTIFICATE-----\n"
+ + "MIIDXjCCAsegAwIBAgIBBzANBgkqhkiG9w0BAQQFADCBtzELMAkGA1UEBhMCQVUx\n"
+ + "ETAPBgNVBAgTCFZpY3RvcmlhMRgwFgYDVQQHEw9Tb3V0aCBNZWxib3VybmUxGjAY\n"
+ + "BgNVBAoTEUNvbm5lY3QgNCBQdHkgTHRkMR4wHAYDVQQLExVDZXJ0aWZpY2F0ZSBB\n"
+ + "dXRob3JpdHkxFTATBgNVBAMTDENvbm5lY3QgNCBDQTEoMCYGCSqGSIb3DQEJARYZ\n"
+ + "d2VibWFzdGVyQGNvbm5lY3Q0LmNvbS5hdTAeFw0wMDA2MDIwNzU2MjFaFw0wMTA2\n"
+ + "MDIwNzU2MjFaMIG4MQswCQYDVQQGEwJBVTERMA8GA1UECBMIVmljdG9yaWExGDAW\n"
+ + "BgNVBAcTD1NvdXRoIE1lbGJvdXJuZTEaMBgGA1UEChMRQ29ubmVjdCA0IFB0eSBM\n"
+ + "dGQxFzAVBgNVBAsTDldlYnNlcnZlciBUZWFtMR0wGwYDVQQDExR3d3cyLmNvbm5l\n"
+ + "Y3Q0LmNvbS5hdTEoMCYGCSqGSIb3DQEJARYZd2VibWFzdGVyQGNvbm5lY3Q0LmNv\n"
+ + "bS5hdTCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEArvDxclKAhyv7Q/Wmr2re\n"
+ + "Gw4XL9Cnh9e+6VgWy2AWNy/MVeXdlxzd7QAuc1eOWQkGQEiLPy5XQtTY+sBUJ3AO\n"
+ + "Rvd2fEVJIcjf29ey7bYua9J/vz5MG2KYo9/WCHIwqD9mmG9g0xLcfwq/s8ZJBswE\n"
+ + "7sb85VU+h94PTvsWOsWuKaECAwEAAaN3MHUwJAYDVR0RBB0wG4EZd2VibWFzdGVy\n"
+ + "QGNvbm5lY3Q0LmNvbS5hdTA6BglghkgBhvhCAQ0ELRYrbW9kX3NzbCBnZW5lcmF0\n"
+ + "ZWQgY3VzdG9tIHNlcnZlciBjZXJ0aWZpY2F0ZTARBglghkgBhvhCAQEEBAMCBkAw\n"
+ + "DQYJKoZIhvcNAQEEBQADgYEAotccfKpwSsIxM1Hae8DR7M/Rw8dg/RqOWx45HNVL\n"
+ + "iBS4/3N/TO195yeQKbfmzbAA2jbPVvIvGgTxPgO1MP4ZgvgRhasaa0qCJCkWvpM4\n"
+ + "yQf33vOiYQbpv4rTwzU8AmRlBG45WdjyNIigGV+oRc61aKCTnLq7zB8N3z1TF/bF\n"
+ + "5/8=\n"
+ + "-----END CERTIFICATE-----\n";
+
+ public static String CRL_1 =
+ "-----BEGIN X509 CRL-----\r\n"
+ + "MIICjTCCAfowDQYJKoZIhvcNAQECBQAwXzELMAkGA1UEBhMCVVMxIDAeBgNVBAoT\r\n"
+ + "F1JTQSBEYXRhIFNlY3VyaXR5LCBJbmMuMS4wLAYDVQQLEyVTZWN1cmUgU2VydmVy\r\n"
+ + "IENlcnRpZmljYXRpb24gQXV0aG9yaXR5Fw05NTA1MDIwMjEyMjZaFw05NTA2MDEw\r\n"
+ + "MDAxNDlaMIIBaDAWAgUCQQAABBcNOTUwMjAxMTcyNDI2WjAWAgUCQQAACRcNOTUw\r\n"
+ + "MjEwMDIxNjM5WjAWAgUCQQAADxcNOTUwMjI0MDAxMjQ5WjAWAgUCQQAADBcNOTUw\r\n"
+ + "MjI1MDA0NjQ0WjAWAgUCQQAAGxcNOTUwMzEzMTg0MDQ5WjAWAgUCQQAAFhcNOTUw\r\n"
+ + "MzE1MTkxNjU0WjAWAgUCQQAAGhcNOTUwMzE1MTk0MDQxWjAWAgUCQQAAHxcNOTUw\r\n"
+ + "MzI0MTk0NDMzWjAWAgUCcgAABRcNOTUwMzI5MjAwNzExWjAWAgUCcgAAERcNOTUw\r\n"
+ + "MzMwMDIzNDI2WjAWAgUCQQAAIBcNOTUwNDA3MDExMzIxWjAWAgUCcgAAHhcNOTUw\r\n"
+ + "NDA4MDAwMjU5WjAWAgUCcgAAQRcNOTUwNDI4MTcxNzI0WjAWAgUCcgAAOBcNOTUw\r\n"
+ + "NDI4MTcyNzIxWjAWAgUCcgAATBcNOTUwNTAyMDIxMjI2WjANBgkqhkiG9w0BAQIF\r\n"
+ + "AAN+AHqOEJXSDejYy0UwxxrH/9+N2z5xu/if0J6qQmK92W0hW158wpJg+ovV3+wQ\r\n"
+ + "wvIEPRL2rocL0tKfAsVq1IawSJzSNgxG0lrcla3MrJBnZ4GaZDu4FutZh72MR3Gt\r\n"
+ + "JaAL3iTJHJD55kK2D/VoyY1djlsPuNh6AEgdVwFAyp0v\r\n"
+ + "-----END X509 CRL-----\r\n";
+
+ public static String CRL_2 =
+ "-----BEGIN CRL-----\r\n"
+ + "MIICjTCCAfowDQYJKoZIhvcNAQECBQAwXzELMAkGA1UEBhMCVVMxIDAeBgNVBAoT\r\n"
+ + "F1JTQSBEYXRhIFNlY3VyaXR5LCBJbmMuMS4wLAYDVQQLEyVTZWN1cmUgU2VydmVy\r\n"
+ + "IENlcnRpZmljYXRpb24gQXV0aG9yaXR5Fw05NTA1MDIwMjEyMjZaFw05NTA2MDEw\r\n"
+ + "MDAxNDlaMIIBaDAWAgUCQQAABBcNOTUwMjAxMTcyNDI2WjAWAgUCQQAACRcNOTUw\r\n"
+ + "MjEwMDIxNjM5WjAWAgUCQQAADxcNOTUwMjI0MDAxMjQ5WjAWAgUCQQAADBcNOTUw\r\n"
+ + "MjI1MDA0NjQ0WjAWAgUCQQAAGxcNOTUwMzEzMTg0MDQ5WjAWAgUCQQAAFhcNOTUw\r\n"
+ + "MzE1MTkxNjU0WjAWAgUCQQAAGhcNOTUwMzE1MTk0MDQxWjAWAgUCQQAAHxcNOTUw\r\n"
+ + "MzI0MTk0NDMzWjAWAgUCcgAABRcNOTUwMzI5MjAwNzExWjAWAgUCcgAAERcNOTUw\r\n"
+ + "MzMwMDIzNDI2WjAWAgUCQQAAIBcNOTUwNDA3MDExMzIxWjAWAgUCcgAAHhcNOTUw\r\n"
+ + "NDA4MDAwMjU5WjAWAgUCcgAAQRcNOTUwNDI4MTcxNzI0WjAWAgUCcgAAOBcNOTUw\r\n"
+ + "NDI4MTcyNzIxWjAWAgUCcgAATBcNOTUwNTAyMDIxMjI2WjANBgkqhkiG9w0BAQIF\r\n"
+ + "AAN+AHqOEJXSDejYy0UwxxrH/9+N2z5xu/if0J6qQmK92W0hW158wpJg+ovV3+wQ\r\n"
+ + "wvIEPRL2rocL0tKfAsVq1IawSJzSNgxG0lrcla3MrJBnZ4GaZDu4FutZh72MR3Gt\r\n"
+ + "JaAL3iTJHJD55kK2D/VoyY1djlsPuNh6AEgdVwFAyp0v\r\n"
+ + "-----END CRL-----\r\n";
+
+ static String ATTRIBUTE_CERTIFICATE_1 =
+ "-----BEGIN X509 ATTRIBUTE CERTIFICATE-----\r\n"
+ + "MIIBuDCCASECAQEwZ6BlMGCkXjBcMQswCQYDVQQGEwJBVTEoMCYGA1UEChMfVGhl\r\n"
+ + "IExlZ2lvbiBvZiB0aGUgQm91bmN5IENhc3RsZTEjMCEGA1UECxMaQm91bmN5IFBy\r\n"
+ + "aW1hcnkgQ2VydGlmaWNhdGUCARSgYjBgpF4wXDELMAkGA1UEBhMCQVUxKDAmBgNV\r\n"
+ + "BAoTH1RoZSBMZWdpb24gb2YgdGhlIEJvdW5jeSBDYXN0bGUxIzAhBgNVBAsTGkJv\r\n"
+ + "dW5jeSBQcmltYXJ5IENlcnRpZmljYXRlMA0GCSqGSIb3DQEBBQUAAgEBMCIYDzIw\r\n"
+ + "MDUwNjEwMDI0MTMzWhgPMjAwNTA2MTAwMjQzMTNaMBkwFwYDVRhIMRAwDoEMREFV\r\n"
+ + "MTIzNDU2Nzg5MA0GCSqGSIb3DQEBBQUAA4GBALAYXT9zdxSR5zdPLAon1xIPehgI\r\n"
+ + "NZhjM7w0uu3OdzSV5sC31X1Kx9vi5RIWiM9VimRTwbQIod9POttD5QMXCwQb/fm7\r\n"
+ + "eiJqL2YBIXOeClB19VrQe8xQtMFbyuFpDiM7QdvIam9ShZZMEMGjv9QHI64M4b0G\r\n"
+ + "odUBlSsJwPPQjZSU\r\n"
+ + "-----END X509 ATTRIBUTE CERTIFICATE-----\r\n";
+
+ static String ATTRIBUTE_CERTIFICATE_2 =
+ "-----BEGIN ATTRIBUTE CERTIFICATE-----\r\n"
+ + "MIIBuDCCASECAQEwZ6BlMGCkXjBcMQswCQYDVQQGEwJBVTEoMCYGA1UEChMfVGhl\r\n"
+ + "IExlZ2lvbiBvZiB0aGUgQm91bmN5IENhc3RsZTEjMCEGA1UECxMaQm91bmN5IFBy\r\n"
+ + "aW1hcnkgQ2VydGlmaWNhdGUCARSgYjBgpF4wXDELMAkGA1UEBhMCQVUxKDAmBgNV\r\n"
+ + "BAoTH1RoZSBMZWdpb24gb2YgdGhlIEJvdW5jeSBDYXN0bGUxIzAhBgNVBAsTGkJv\r\n"
+ + "dW5jeSBQcmltYXJ5IENlcnRpZmljYXRlMA0GCSqGSIb3DQEBBQUAAgEBMCIYDzIw\r\n"
+ + "MDUwNjEwMDI0MTMzWhgPMjAwNTA2MTAwMjQzMTNaMBkwFwYDVRhIMRAwDoEMREFV\r\n"
+ + "MTIzNDU2Nzg5MA0GCSqGSIb3DQEBBQUAA4GBALAYXT9zdxSR5zdPLAon1xIPehgI\r\n"
+ + "NZhjM7w0uu3OdzSV5sC31X1Kx9vi5RIWiM9VimRTwbQIod9POttD5QMXCwQb/fm7\r\n"
+ + "eiJqL2YBIXOeClB19VrQe8xQtMFbyuFpDiM7QdvIam9ShZZMEMGjv9QHI64M4b0G\r\n"
+ + "odUBlSsJwPPQjZSU\r\n"
+ + "-----END ATTRIBUTE CERTIFICATE-----\r\n";
+}
diff --git a/pkix/src/test/java/org/spongycastle/cert/test/PKCS10Test.java b/pkix/src/test/java/org/spongycastle/cert/test/PKCS10Test.java
new file mode 100644
index 00000000..9bcada8c
--- /dev/null
+++ b/pkix/src/test/java/org/spongycastle/cert/test/PKCS10Test.java
@@ -0,0 +1,616 @@
+package org.spongycastle.cert.test;
+
+import java.math.BigInteger;
+import java.security.KeyFactory;
+import java.security.KeyPair;
+import java.security.KeyPairGenerator;
+import java.security.PrivateKey;
+import java.security.PublicKey;
+import java.security.SecureRandom;
+import java.security.Security;
+import java.security.Signature;
+import java.security.spec.RSAPrivateCrtKeySpec;
+import java.security.spec.RSAPublicKeySpec;
+
+import javax.security.auth.x500.X500Principal;
+
+import org.spongycastle.asn1.ASN1ObjectIdentifier;
+import org.spongycastle.asn1.DEROctetString;
+import org.spongycastle.asn1.cryptopro.CryptoProObjectIdentifiers;
+import org.spongycastle.asn1.pkcs.Attribute;
+import org.spongycastle.asn1.pkcs.PKCSObjectIdentifiers;
+import org.spongycastle.asn1.x500.X500Name;
+import org.spongycastle.asn1.x500.X500NameBuilder;
+import org.spongycastle.asn1.x500.style.BCStyle;
+import org.spongycastle.asn1.x509.BasicConstraints;
+import org.spongycastle.asn1.x509.Extension;
+import org.spongycastle.asn1.x509.Extensions;
+import org.spongycastle.asn1.x509.KeyUsage;
+import org.spongycastle.asn1.x9.X9ObjectIdentifiers;
+import org.spongycastle.cert.jcajce.JcaX509ExtensionUtils;
+import org.spongycastle.jce.ECGOST3410NamedCurveTable;
+import org.spongycastle.jce.ECNamedCurveTable;
+import org.spongycastle.jce.interfaces.ECPointEncoder;
+import org.spongycastle.jce.provider.BouncyCastleProvider;
+import org.spongycastle.jce.spec.ECNamedCurveParameterSpec;
+import org.spongycastle.jce.spec.ECParameterSpec;
+import org.spongycastle.jce.spec.ECPrivateKeySpec;
+import org.spongycastle.jce.spec.ECPublicKeySpec;
+import org.spongycastle.math.ec.ECCurve;
+import org.spongycastle.operator.ContentSigner;
+import org.spongycastle.operator.ContentVerifierProvider;
+import org.spongycastle.operator.jcajce.JcaContentSignerBuilder;
+import org.spongycastle.operator.jcajce.JcaContentVerifierProviderBuilder;
+import org.spongycastle.pkcs.PKCS10CertificationRequest;
+import org.spongycastle.pkcs.PKCS10CertificationRequestBuilder;
+import org.spongycastle.pkcs.jcajce.JcaPKCS10CertificationRequest;
+import org.spongycastle.pkcs.jcajce.JcaPKCS10CertificationRequestBuilder;
+import org.spongycastle.util.Arrays;
+import org.spongycastle.util.encoders.Base64;
+import org.spongycastle.util.encoders.Hex;
+import org.spongycastle.util.test.SimpleTest;
+
+/**
+ **/
+public class PKCS10Test
+ extends SimpleTest
+{
+ private static final String BC = BouncyCastleProvider.PROVIDER_NAME;
+
+ private byte[] gost3410EC_A = Base64.decode(
+ "MIIBOzCB6wIBADB/MQ0wCwYDVQQDEwR0ZXN0MRUwEwYDVQQKEwxEZW1vcyBDbyBMdGQxHjAcBgNV"
+ +"BAsTFUNyeXB0b2dyYXBoeSBkaXZpc2lvbjEPMA0GA1UEBxMGTW9zY293MQswCQYDVQQGEwJydTEZ"
+ +"MBcGCSqGSIb3DQEJARYKc2RiQGRvbC5ydTBjMBwGBiqFAwICEzASBgcqhQMCAiMBBgcqhQMCAh4B"
+ +"A0MABEBYx0P2D7YuuZo5HgdIAUKAXcLBDZ+4LYFgbKjrfStVfH59lc40BQ2FZ7M703hLpXK8GiBQ"
+ +"GEYpKaAuQZnMIpByoAAwCAYGKoUDAgIDA0EAgXMcTrhdOY2Er2tHOSAgnMezqrYxocZTWhxmW5Rl"
+ +"JY6lbXH5rndCn4swFzXU+YhgAsJv1wQBaoZEWRl5WV4/nA==");
+
+ private byte[] gost3410EC_B = Base64.decode(
+ "MIIBPTCB7QIBADCBgDENMAsGA1UEAxMEdGVzdDEWMBQGA1UEChMNRGVtb3MgQ28gTHRkLjEeMBwG"
+ +"A1UECxMVQ3J5cHRvZ3JhcGh5IGRpdmlzaW9uMQ8wDQYDVQQHEwZNb3Njb3cxCzAJBgNVBAYTAnJ1"
+ +"MRkwFwYJKoZIhvcNAQkBFgpzZGJAZG9sLnJ1MGMwHAYGKoUDAgITMBIGByqFAwICIwIGByqFAwIC"
+ +"HgEDQwAEQI5SLoWT7dZVilbV9j5B/fyIDuDs6x4pjqNC2TtFYbpRHrk/Wc5g/mcHvD80tsm5o1C7"
+ +"7cizNzkvAVUM4VT4Dz6gADAIBgYqhQMCAgMDQQAoT5TwJ8o+bSrxckymyo3diwG7ZbSytX4sRiKy"
+ +"wXPWRS9LlBvPO2NqwpS2HUnxSU8rzfL9fJcybATf7Yt1OEVq");
+
+ private byte[] gost3410EC_C = Base64.decode(
+ "MIIBRDCB9AIBADCBhzEVMBMGA1UEAxMMdGVzdCByZXF1ZXN0MRUwEwYDVQQKEwxEZW1vcyBDbyBM"
+ +"dGQxHjAcBgNVBAsTFUNyeXB0b2dyYXBoeSBkaXZpc2lvbjEPMA0GA1UEBxMGTW9zY293MQswCQYD"
+ +"VQQGEwJydTEZMBcGCSqGSIb3DQEJARYKc2RiQGRvbC5ydTBjMBwGBiqFAwICEzASBgcqhQMCAiMD"
+ +"BgcqhQMCAh4BA0MABEBcmGh7OmR4iqqj+ycYo1S1fS7r5PhisSQU2Ezuz8wmmmR2zeTZkdMYCOBa"
+ +"UTMNms0msW3wuYDho7nTDNscHTB5oAAwCAYGKoUDAgIDA0EAVoOMbfyo1Un4Ss7WQrUjHJoiaYW8"
+ +"Ime5LeGGU2iW3ieAv6es/FdMrwTKkqn5dhd3aL/itFg5oQbhyfXw5yw/QQ==");
+
+ private byte[] gost3410EC_ExA = Base64.decode(
+ "MIIBOzCB6wIBADB/MQ0wCwYDVQQDEwR0ZXN0MRUwEwYDVQQKEwxEZW1vcyBDbyBMdGQxHjAcBgNV"
+ + "BAsTFUNyeXB0b2dyYXBoeSBkaXZpc2lvbjEPMA0GA1UEBxMGTW9zY293MQswCQYDVQQGEwJydTEZ"
+ + "MBcGCSqGSIb3DQEJARYKc2RiQGRvbC5ydTBjMBwGBiqFAwICEzASBgcqhQMCAiQABgcqhQMCAh4B"
+ + "A0MABEDkqNT/3f8NHj6EUiWnK4JbVZBh31bEpkwq9z3jf0u8ZndG56Vt+K1ZB6EpFxLT7hSIos0w"
+ + "weZ2YuTZ4w43OgodoAAwCAYGKoUDAgIDA0EASk/IUXWxoi6NtcUGVF23VRV1L3undB4sRZLp4Vho"
+ + "gQ7m3CMbZFfJ2cPu6QyarseXGYHmazoirH5lGjEo535c1g==");
+
+ private byte[] gost3410EC_ExB = Base64.decode(
+ "MIIBPTCB7QIBADCBgDENMAsGA1UEAxMEdGVzdDEWMBQGA1UEChMNRGVtb3MgQ28gTHRkLjEeMBwG"
+ + "A1UECxMVQ3J5cHRvZ3JhcGh5IGRpdmlzaW9uMQ8wDQYDVQQHEwZNb3Njb3cxCzAJBgNVBAYTAnJ1"
+ + "MRkwFwYJKoZIhvcNAQkBFgpzZGJAZG9sLnJ1MGMwHAYGKoUDAgITMBIGByqFAwICJAEGByqFAwIC"
+ + "HgEDQwAEQMBWYUKPy/1Kxad9ChAmgoSWSYOQxRnXo7KEGLU5RNSXA4qMUvArWzvhav+EYUfTbWLh"
+ + "09nELDyHt2XQcvgQHnSgADAIBgYqhQMCAgMDQQAdaNhgH/ElHp64mbMaEo1tPCg9Q22McxpH8rCz"
+ + "E0QBpF4H5mSSQVGI5OAXHToetnNuh7gHHSynyCupYDEHTbkZ");
+
+ public String getName()
+ {
+ return "PKCS10CertRequest";
+ }
+
+ private void generationTest(int keySize, String keyName, String sigName, String provider)
+ throws Exception
+ {
+ KeyPairGenerator kpg = KeyPairGenerator.getInstance(keyName, "SC");
+
+ kpg.initialize(keySize);
+
+ KeyPair kp = kpg.genKeyPair();
+
+
+ X500NameBuilder x500NameBld = new X500NameBuilder(BCStyle.INSTANCE);
+
+ x500NameBld.addRDN(BCStyle.C, "AU");
+ x500NameBld.addRDN(BCStyle.O, "The Legion of the Bouncy Castle");
+ x500NameBld.addRDN(BCStyle.L, "Melbourne");
+ x500NameBld.addRDN(BCStyle.ST, "Victoria");
+ x500NameBld.addRDN(BCStyle.EmailAddress, "feedback-crypto@bouncycastle.org");
+
+ X500Name subject = x500NameBld.build();
+
+ PKCS10CertificationRequestBuilder requestBuilder = new JcaPKCS10CertificationRequestBuilder(subject, kp.getPublic());
+
+ PKCS10CertificationRequest req1 = requestBuilder.build(new JcaContentSignerBuilder(sigName).setProvider(provider).build(kp.getPrivate()));
+
+ JcaPKCS10CertificationRequest req2 = new JcaPKCS10CertificationRequest(req1.getEncoded()).setProvider(provider);
+
+ if (!req2.isSignatureValid(new JcaContentVerifierProviderBuilder().setProvider(provider).build(kp.getPublic())))
+ {
+ fail(sigName + ": Failed verify check.");
+ }
+
+ if (!Arrays.areEqual(req2.getPublicKey().getEncoded(), req1.getSubjectPublicKeyInfo().getEncoded()))
+ {
+ fail(keyName + ": Failed public key check.");
+ }
+ }
+
+ private void generationTestX500Principal(int keySize, String keyName, String sigName, String provider)
+ throws Exception
+ {
+ KeyPairGenerator kpg = KeyPairGenerator.getInstance(keyName, "SC");
+
+ kpg.initialize(keySize);
+
+ KeyPair kp = kpg.genKeyPair();
+
+
+ X500NameBuilder x500NameBld = new X500NameBuilder(BCStyle.INSTANCE);
+
+ x500NameBld.addRDN(BCStyle.C, "AU");
+ x500NameBld.addRDN(BCStyle.O, "The Legion of the Bouncy Castle");
+ x500NameBld.addRDN(BCStyle.L, "Melbourne");
+ x500NameBld.addRDN(BCStyle.ST, "Victoria");
+ x500NameBld.addRDN(BCStyle.EmailAddress, "feedback-crypto@bouncycastle.org");
+
+ X500Name subject = x500NameBld.build();
+
+ PKCS10CertificationRequestBuilder requestBuilder = new JcaPKCS10CertificationRequestBuilder(new X500Principal(subject.getEncoded()), kp.getPublic());
+
+ PKCS10CertificationRequest req1 = requestBuilder.build(new JcaContentSignerBuilder(sigName).setProvider(provider).build(kp.getPrivate()));
+
+ JcaPKCS10CertificationRequest req2 = new JcaPKCS10CertificationRequest(req1.getEncoded()).setProvider(provider);
+
+ if (!req2.isSignatureValid(new JcaContentVerifierProviderBuilder().setProvider(provider).build(kp.getPublic())))
+ {
+ fail(sigName + ": Failed verify check.");
+ }
+
+ if (!Arrays.areEqual(req2.getPublicKey().getEncoded(), req1.getSubjectPublicKeyInfo().getEncoded()))
+ {
+ fail(keyName + ": Failed public key check.");
+ }
+
+ if (!Arrays.areEqual(req2.getSubject().getEncoded(), req1.getSubject().getEncoded()))
+ {
+ fail(keyName + ": Failed subject key check.");
+ }
+ }
+
+ /*
+ * we generate a self signed certificate for the sake of testing - SHA224withECDSA
+ */
+ private void createECRequest(String algorithm, ASN1ObjectIdentifier algOid, ASN1ObjectIdentifier curveOid)
+ throws Exception
+ {
+ ECNamedCurveParameterSpec spec = ECNamedCurveTable.getParameterSpec(curveOid.getId());
+ KeyPairGenerator ecGen = KeyPairGenerator.getInstance("ECDSA", "SC");
+
+ ecGen.initialize(spec);
+
+ //
+ // set up the keys
+ //
+ PrivateKey privKey;
+ PublicKey pubKey;
+
+ KeyPair pair = ecGen.generateKeyPair();
+
+ privKey = pair.getPrivate();
+ pubKey = pair.getPublic();
+
+ ContentSigner signer = new JcaContentSignerBuilder(algorithm).setProvider(BC).build(privKey);
+
+ PKCS10CertificationRequestBuilder reqBuilder = new JcaPKCS10CertificationRequestBuilder(new X500Name("CN=XXX"), pubKey);
+ PKCS10CertificationRequest req = reqBuilder.build(signer);
+
+ ContentVerifierProvider verifier = new JcaContentVerifierProviderBuilder().setProvider(BC).build(pubKey);
+
+ if (!req.isSignatureValid(verifier))
+ {
+ fail("Failed verify check EC.");
+ }
+
+ req = new PKCS10CertificationRequest(req.getEncoded());
+ if (!req.isSignatureValid(verifier))
+ {
+ fail("Failed verify check EC encoded.");
+ }
+
+ //
+ // try with point compression turned off
+ //
+ ((ECPointEncoder)pubKey).setPointFormat("UNCOMPRESSED");
+
+ reqBuilder = new JcaPKCS10CertificationRequestBuilder(new X500Name("CN=XXX"), pubKey);
+ req = reqBuilder.build(signer);
+
+ if (!req.isSignatureValid(verifier))
+ {
+ fail("Failed verify check EC uncompressed.");
+ }
+
+ req = new PKCS10CertificationRequest(req.getEncoded());
+ if (!req.isSignatureValid(verifier))
+ {
+ fail("Failed verify check EC uncompressed encoded.");
+ }
+
+ if (!req.toASN1Structure().getSignatureAlgorithm().getAlgorithm().equals(algOid))
+ {
+ fail("ECDSA oid incorrect.");
+ }
+
+ if (req.toASN1Structure().getSignatureAlgorithm().getParameters() != null)
+ {
+ fail("ECDSA parameters incorrect.");
+ }
+
+ Signature sig = Signature.getInstance(algorithm, "SC");
+
+ sig.initVerify(pubKey);
+
+ sig.update(req.toASN1Structure().getCertificationRequestInfo().getEncoded());
+
+ if (!sig.verify(req.toASN1Structure().getSignature().getBytes()))
+ {
+ fail("signature not mapped correctly.");
+ }
+ }
+
+ private void createECRequest(String algorithm, ASN1ObjectIdentifier algOid)
+ throws Exception
+ {
+ ECCurve.Fp curve = new ECCurve.Fp(
+ new BigInteger("6864797660130609714981900799081393217269435300143305409394463459185543183397656052122559640661454554977296311391480858037121987999716643812574028291115057151"), // q (or p)
+ new BigInteger("01FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC", 16), // a
+ new BigInteger("0051953EB9618E1C9A1F929A21A0B68540EEA2DA725B99B315F3B8B489918EF109E156193951EC7E937B1652C0BD3BB1BF073573DF883D2C34F1EF451FD46B503F00", 16)); // b
+
+ ECParameterSpec spec = new ECParameterSpec(
+ curve,
+ curve.decodePoint(Hex.decode("0200C6858E06B70404E9CD9E3ECB662395B4429C648139053FB521F828AF606B4D3DBAA14B5E77EFE75928FE1DC127A2FFA8DE3348B3C1856A429BF97E7E31C2E5BD66")), // G
+ new BigInteger("01FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA51868783BF2F966B7FCC0148F709A5D03BB5C9B8899C47AEBB6FB71E91386409", 16)); // n
+
+ ECPrivateKeySpec privKeySpec = new ECPrivateKeySpec(
+ new BigInteger("5769183828869504557786041598510887460263120754767955773309066354712783118202294874205844512909370791582896372147797293913785865682804434049019366394746072023"), // d
+ spec);
+
+ ECPublicKeySpec pubKeySpec = new ECPublicKeySpec(
+ curve.decodePoint(Hex.decode("02006BFDD2C9278B63C92D6624F151C9D7A822CC75BD983B17D25D74C26740380022D3D8FAF304781E416175EADF4ED6E2B47142D2454A7AC7801DD803CF44A4D1F0AC")), // Q
+ spec);
+
+ //
+ // set up the keys
+ //
+ PrivateKey privKey;
+ PublicKey pubKey;
+
+ KeyFactory fact = KeyFactory.getInstance("ECDSA", "SC");
+
+ privKey = fact.generatePrivate(privKeySpec);
+ pubKey = fact.generatePublic(pubKeySpec);
+
+ PKCS10CertificationRequest req = new JcaPKCS10CertificationRequestBuilder(
+ new X500Name("CN=XXX"), pubKey).build(new JcaContentSignerBuilder(algorithm).setProvider(BC).build(privKey));
+ if (!req.isSignatureValid(new JcaContentVerifierProviderBuilder().setProvider(BC).build(pubKey)))
+ {
+ fail("Failed verify check EC.");
+ }
+
+ req = new PKCS10CertificationRequest(req.getEncoded());
+ if (!req.isSignatureValid(new JcaContentVerifierProviderBuilder().setProvider(BC).build(pubKey)))
+ {
+ fail("Failed verify check EC encoded.");
+ }
+
+ //
+ // try with point compression turned off
+ //
+ ((ECPointEncoder)pubKey).setPointFormat("UNCOMPRESSED");
+
+ req = new JcaPKCS10CertificationRequestBuilder(
+ new X500Name("CN=XXX"), pubKey).build(new JcaContentSignerBuilder(algorithm).setProvider(BC).build(privKey));
+ if (!req.isSignatureValid(new JcaContentVerifierProviderBuilder().setProvider(BC).build(pubKey)))
+ {
+ fail("Failed verify check EC uncompressed.");
+ }
+
+ JcaPKCS10CertificationRequest jcaReq = new JcaPKCS10CertificationRequest(new PKCS10CertificationRequest(req.getEncoded()));
+ if (!jcaReq.isSignatureValid(new JcaContentVerifierProviderBuilder().setProvider(BC).build(jcaReq.getPublicKey())))
+ {
+ fail("Failed verify check EC uncompressed encoded.");
+ }
+
+ if (!jcaReq.getSignatureAlgorithm().getAlgorithm().equals(algOid))
+ {
+ fail("ECDSA oid incorrect.");
+ }
+
+ if (jcaReq.getSignatureAlgorithm().getParameters() != null)
+ {
+ fail("ECDSA parameters incorrect.");
+ }
+
+ Signature sig = Signature.getInstance(algorithm, BC);
+
+ sig.initVerify(pubKey);
+
+ sig.update(req.toASN1Structure().getCertificationRequestInfo().getEncoded());
+
+ if (!sig.verify(req.getSignature()))
+ {
+ fail("signature not mapped correctly.");
+ }
+ }
+
+ private void createECGOSTRequest()
+ throws Exception
+ {
+ String algorithm = "GOST3411withECGOST3410";
+ KeyPairGenerator ecGostKpg = KeyPairGenerator.getInstance("ECGOST3410", "SC");
+
+ ecGostKpg.initialize(ECGOST3410NamedCurveTable.getParameterSpec("GostR3410-2001-CryptoPro-A"), new SecureRandom());
+
+ //
+ // set up the keys
+ //
+ KeyPair pair = ecGostKpg.generateKeyPair();
+ PrivateKey privKey = pair.getPrivate();
+ PublicKey pubKey = pair.getPublic();
+
+ PKCS10CertificationRequest req = new JcaPKCS10CertificationRequestBuilder(
+ new X500Name("CN=XXX"), pubKey).build(new JcaContentSignerBuilder(algorithm).setProvider(BC).build(privKey));
+ if (!req.isSignatureValid(new JcaContentVerifierProviderBuilder().setProvider(BC).build(pubKey)))
+ {
+ fail("Failed verify check EC.");
+ }
+
+ req = new PKCS10CertificationRequest(req.getEncoded());
+ if (!req.isSignatureValid(new JcaContentVerifierProviderBuilder().setProvider(BC).build(pubKey)))
+ {
+ fail("Failed verify check EC encoded.");
+ }
+
+ if (!req.getSignatureAlgorithm().getAlgorithm().equals(CryptoProObjectIdentifiers.gostR3411_94_with_gostR3410_2001))
+ {
+ fail("ECGOST oid incorrect.");
+ }
+
+ if (req.getSignatureAlgorithm().getParameters() != null)
+ {
+ fail("ECGOST parameters incorrect.");
+ }
+
+ Signature sig = Signature.getInstance(algorithm, "SC");
+
+ sig.initVerify(pubKey);
+
+ sig.update(req.toASN1Structure().getCertificationRequestInfo().getEncoded());
+
+ if (!sig.verify(req.getSignature()))
+ {
+ fail("signature not mapped correctly.");
+ }
+ }
+
+ private void createPSSTest(String algorithm)
+ throws Exception
+ {
+ RSAPublicKeySpec pubKeySpec = new RSAPublicKeySpec(
+ new BigInteger("a56e4a0e701017589a5187dc7ea841d156f2ec0e36ad52a44dfeb1e61f7ad991d8c51056ffedb162b4c0f283a12a88a394dff526ab7291cbb307ceabfce0b1dfd5cd9508096d5b2b8b6df5d671ef6377c0921cb23c270a70e2598e6ff89d19f105acc2d3f0cb35f29280e1386b6f64c4ef22e1e1f20d0ce8cffb2249bd9a2137",16),
+ new BigInteger("010001",16));
+
+ RSAPrivateCrtKeySpec privKeySpec = new RSAPrivateCrtKeySpec(
+ new BigInteger("a56e4a0e701017589a5187dc7ea841d156f2ec0e36ad52a44dfeb1e61f7ad991d8c51056ffedb162b4c0f283a12a88a394dff526ab7291cbb307ceabfce0b1dfd5cd9508096d5b2b8b6df5d671ef6377c0921cb23c270a70e2598e6ff89d19f105acc2d3f0cb35f29280e1386b6f64c4ef22e1e1f20d0ce8cffb2249bd9a2137",16),
+ new BigInteger("010001",16),
+ new BigInteger("33a5042a90b27d4f5451ca9bbbd0b44771a101af884340aef9885f2a4bbe92e894a724ac3c568c8f97853ad07c0266c8c6a3ca0929f1e8f11231884429fc4d9ae55fee896a10ce707c3ed7e734e44727a39574501a532683109c2abacaba283c31b4bd2f53c3ee37e352cee34f9e503bd80c0622ad79c6dcee883547c6a3b325",16),
+ new BigInteger("e7e8942720a877517273a356053ea2a1bc0c94aa72d55c6e86296b2dfc967948c0a72cbccca7eacb35706e09a1df55a1535bd9b3cc34160b3b6dcd3eda8e6443",16),
+ new BigInteger("b69dca1cf7d4d7ec81e75b90fcca874abcde123fd2700180aa90479b6e48de8d67ed24f9f19d85ba275874f542cd20dc723e6963364a1f9425452b269a6799fd",16),
+ new BigInteger("28fa13938655be1f8a159cbaca5a72ea190c30089e19cd274a556f36c4f6e19f554b34c077790427bbdd8dd3ede2448328f385d81b30e8e43b2fffa027861979",16),
+ new BigInteger("1a8b38f398fa712049898d7fb79ee0a77668791299cdfa09efc0e507acb21ed74301ef5bfd48be455eaeb6e1678255827580a8e4e8e14151d1510a82a3f2e729",16),
+ new BigInteger("27156aba4126d24a81f3a528cbfb27f56886f840a9f6e86e17a44b94fe9319584b8e22fdde1e5a2e3bd8aa5ba8d8584194eb2190acf832b847f13a3d24a79f4d",16));
+
+ KeyFactory fact = KeyFactory.getInstance("RSA", "SC");
+
+ PrivateKey privKey = fact.generatePrivate(privKeySpec);
+ PublicKey pubKey = fact.generatePublic(pubKeySpec);
+
+ PKCS10CertificationRequest req = new JcaPKCS10CertificationRequestBuilder(
+ new X500Name("CN=XXX"), pubKey).build(new JcaContentSignerBuilder(algorithm).setProvider(BC).build(privKey));
+ if (!req.isSignatureValid(new JcaContentVerifierProviderBuilder().setProvider(BC).build(pubKey)))
+ {
+ fail("Failed verify check PSS.");
+ }
+
+ JcaPKCS10CertificationRequest jcaReq = new JcaPKCS10CertificationRequest(req.getEncoded()).setProvider(BC);
+ if (!jcaReq.isSignatureValid(new JcaContentVerifierProviderBuilder().setProvider(BC).build(jcaReq.getPublicKey())))
+ {
+ fail("Failed verify check PSS encoded.");
+ }
+
+ if (!jcaReq.getSignatureAlgorithm().getAlgorithm().equals(PKCSObjectIdentifiers.id_RSASSA_PSS))
+ {
+ fail("PSS oid incorrect.");
+ }
+
+ if (jcaReq.getSignatureAlgorithm().getParameters() == null)
+ {
+ fail("PSS parameters incorrect.");
+ }
+
+ Signature sig = Signature.getInstance(algorithm, "SC");
+
+ sig.initVerify(pubKey);
+
+ sig.update(jcaReq.toASN1Structure().getCertificationRequestInfo().getEncoded());
+
+ if (!sig.verify(req.getSignature()))
+ {
+ fail("signature not mapped correctly.");
+ }
+ }
+
+ // previous code found to cause a NullPointerException
+ private void nullPointerTest()
+ throws Exception
+ {
+ KeyPairGenerator keyGen = KeyPairGenerator.getInstance("RSA", "SC");
+ keyGen.initialize(1024, new SecureRandom());
+ KeyPair pair = keyGen.generateKeyPair();
+ JcaX509ExtensionUtils extUtils = new JcaX509ExtensionUtils();
+
+ Extension[] ext = new Extension[] {
+ new Extension(Extension.basicConstraints, true, new DEROctetString(new BasicConstraints(true))),
+ new Extension(Extension.keyUsage, true, new DEROctetString(new KeyUsage(KeyUsage.keyCertSign | KeyUsage.cRLSign))),
+ new Extension(Extension.subjectKeyIdentifier, false, new DEROctetString(extUtils.createSubjectKeyIdentifier(pair.getPublic())))
+ };
+
+ PKCS10CertificationRequest p1 = new JcaPKCS10CertificationRequestBuilder(
+ new X500Name("cn=csr"),
+ pair.getPublic())
+ .addAttribute(PKCSObjectIdentifiers.pkcs_9_at_extensionRequest, new Extensions(ext))
+ .build(new JcaContentSignerBuilder("SHA1withRSA").setProvider(BC).build(pair.getPrivate()));
+ PKCS10CertificationRequest p2 = new JcaPKCS10CertificationRequestBuilder(
+ new X500Name("cn=csr"),
+ pair.getPublic())
+ .addAttribute(PKCSObjectIdentifiers.pkcs_9_at_extensionRequest, new Extensions(ext))
+ .build(new JcaContentSignerBuilder("SHA1withRSA").setProvider(BC).build(pair.getPrivate()));
+
+ if (!p1.equals(p2))
+ {
+ fail("cert request comparison failed");
+ }
+
+ Attribute[] attr1 = p1.getAttributes();
+ Attribute[] attr2 = p1.getAttributes();
+
+ checkAttrs(1, attr1, attr2);
+
+ attr1 = p1.getAttributes(PKCSObjectIdentifiers.pkcs_9_at_extensionRequest);
+ attr2 = p1.getAttributes(PKCSObjectIdentifiers.pkcs_9_at_extensionRequest);
+
+ checkAttrs(1, attr1, attr2);
+ }
+
+ private void checkAttrs(int expectedLength, Attribute[] attr1, Attribute[] attr2)
+ {
+ if (expectedLength != attr1.length)
+ {
+ fail("expected length mismatch");
+ }
+
+ if (attr1.length != attr2.length)
+ {
+ fail("atrribute length mismatch");
+ }
+
+ for (int i = 0; i != attr1.length; i++)
+ {
+ if (!attr1[i].equals(attr2[i]))
+ {
+ fail("atrribute mismatch");
+ }
+ }
+ }
+
+ public void performTest()
+ throws Exception
+ {
+ generationTest(512, "RSA", "SHA1withRSA", "SC");
+ generationTestX500Principal(512, "RSA", "SHA1withRSA", "SC");
+ generationTest(512, "GOST3410", "GOST3411withGOST3410", "SC");
+
+ if (Security.getProvider("SunRsaSign") != null)
+ {
+ generationTest(512, "RSA", "SHA1withRSA", "SunRsaSign");
+ }
+
+ // elliptic curve GOST A parameter set
+ JcaPKCS10CertificationRequest req = new JcaPKCS10CertificationRequest(gost3410EC_A).setProvider(BC);
+ if (!req.isSignatureValid(new JcaContentVerifierProviderBuilder().setProvider(BC).build(req.getPublicKey())))
+ {
+ fail("Failed verify check gost3410EC_A.");
+ }
+
+ // elliptic curve GOST B parameter set
+ req = new JcaPKCS10CertificationRequest(gost3410EC_B).setProvider(BC);
+ if (!req.isSignatureValid(new JcaContentVerifierProviderBuilder().setProvider(BC).build(req.getPublicKey())))
+ {
+ fail("Failed verify check gost3410EC_B.");
+ }
+
+ // elliptic curve GOST C parameter set
+ req = new JcaPKCS10CertificationRequest(gost3410EC_C).setProvider(BC);
+ if (!req.isSignatureValid(new JcaContentVerifierProviderBuilder().setProvider(BC).build(req.getPublicKey())))
+ {
+ fail("Failed verify check gost3410EC_C.");
+ }
+
+ // elliptic curve GOST ExA parameter set
+ req = new JcaPKCS10CertificationRequest(gost3410EC_ExA).setProvider(BC);
+ if (!req.isSignatureValid(new JcaContentVerifierProviderBuilder().setProvider(BC).build(req.getPublicKey())))
+ {
+ fail("Failed verify check gost3410EC_ExA.");
+ }
+
+ // elliptic curve GOST ExB parameter set
+ req = new JcaPKCS10CertificationRequest(gost3410EC_ExB).setProvider(BC);
+ if (!req.isSignatureValid(new JcaContentVerifierProviderBuilder().setProvider(BC).build(req.getPublicKey())))
+ {
+ fail("Failed verify check gost3410EC_ExA.");
+ }
+
+ // elliptic curve openSSL
+ KeyPairGenerator g = KeyPairGenerator.getInstance("ECDSA", "SC");
+
+ ECCurve curve = new ECCurve.Fp(
+ new BigInteger("883423532389192164791648750360308885314476597252960362792450860609699839"), // q
+ new BigInteger("7fffffffffffffffffffffff7fffffffffff8000000000007ffffffffffc", 16), // a
+ new BigInteger("6b016c3bdcf18941d0d654921475ca71a9db2fb27d1d37796185c2942c0a", 16)); // b
+
+ ECParameterSpec ecSpec = new ECParameterSpec(
+ curve,
+ curve.decodePoint(Hex.decode("020ffa963cdca8816ccc33b8642bedf905c3d358573d3f27fbbd3b3cb9aaaf")), // G
+ new BigInteger("883423532389192164791648750360308884807550341691627752275345424702807307")); // n
+
+ g.initialize(ecSpec, new SecureRandom());
+
+ KeyPair kp = g.generateKeyPair();
+
+ req = new JcaPKCS10CertificationRequest(new JcaPKCS10CertificationRequestBuilder(
+ new X500Name("CN=XXX"), kp.getPublic()).build(new JcaContentSignerBuilder( "ECDSAWITHSHA1").setProvider(BC).build(kp.getPrivate())));
+ if (!req.isSignatureValid(new JcaContentVerifierProviderBuilder().setProvider(BC).build(req.getPublicKey())))
+ {
+ fail("Failed verify check EC.");
+ }
+
+ createECRequest("SHA1withECDSA", X9ObjectIdentifiers.ecdsa_with_SHA1);
+ createECRequest("SHA224withECDSA", X9ObjectIdentifiers.ecdsa_with_SHA224);
+ createECRequest("SHA256withECDSA", X9ObjectIdentifiers.ecdsa_with_SHA256);
+ createECRequest("SHA384withECDSA", X9ObjectIdentifiers.ecdsa_with_SHA384);
+ createECRequest("SHA512withECDSA", X9ObjectIdentifiers.ecdsa_with_SHA512);
+
+ createECRequest("SHA1withECDSA", X9ObjectIdentifiers.ecdsa_with_SHA1, new ASN1ObjectIdentifier("1.3.132.0.34"));
+
+ createECGOSTRequest();
+
+ createPSSTest("SHA1withRSAandMGF1");
+ createPSSTest("SHA224withRSAandMGF1");
+ createPSSTest("SHA256withRSAandMGF1");
+ createPSSTest("SHA384withRSAandMGF1");
+
+ nullPointerTest();
+ }
+
+ public static void main(
+ String[] args)
+ {
+ Security.addProvider(new BouncyCastleProvider());
+
+ runTest(new PKCS10Test());
+ }
+}
diff --git a/pkix/src/test/java/org/spongycastle/cert/test/SHA1DigestCalculator.java b/pkix/src/test/java/org/spongycastle/cert/test/SHA1DigestCalculator.java
new file mode 100644
index 00000000..61bfe6e6
--- /dev/null
+++ b/pkix/src/test/java/org/spongycastle/cert/test/SHA1DigestCalculator.java
@@ -0,0 +1,44 @@
+package org.spongycastle.cert.test;
+
+import java.io.ByteArrayOutputStream;
+import java.io.OutputStream;
+
+import org.spongycastle.asn1.oiw.OIWObjectIdentifiers;
+import org.spongycastle.asn1.x509.AlgorithmIdentifier;
+import org.spongycastle.crypto.Digest;
+import org.spongycastle.crypto.digests.SHA1Digest;
+import org.spongycastle.operator.DigestCalculator;
+
+
+class SHA1DigestCalculator
+ implements DigestCalculator
+{
+ private ByteArrayOutputStream bOut = new ByteArrayOutputStream();
+
+ public AlgorithmIdentifier getAlgorithmIdentifier()
+ {
+ return new AlgorithmIdentifier(OIWObjectIdentifiers.idSHA1);
+ }
+
+ public OutputStream getOutputStream()
+ {
+ return bOut;
+ }
+
+ public byte[] getDigest()
+ {
+ byte[] bytes = bOut.toByteArray();
+
+ bOut.reset();
+
+ Digest sha1 = new SHA1Digest();
+
+ sha1.update(bytes, 0, bytes.length);
+
+ byte[] digest = new byte[sha1.getDigestSize()];
+
+ sha1.doFinal(digest, 0);
+
+ return digest;
+ }
+}
diff --git a/pkix/src/test/java/org/spongycastle/cert/test/X509ExtensionUtilsTest.java b/pkix/src/test/java/org/spongycastle/cert/test/X509ExtensionUtilsTest.java
new file mode 100644
index 00000000..0b073009
--- /dev/null
+++ b/pkix/src/test/java/org/spongycastle/cert/test/X509ExtensionUtilsTest.java
@@ -0,0 +1,55 @@
+package org.spongycastle.cert.test;
+
+import java.io.IOException;
+
+import org.spongycastle.asn1.ASN1Primitive;
+import org.spongycastle.asn1.x509.SubjectKeyIdentifier;
+import org.spongycastle.asn1.x509.SubjectPublicKeyInfo;
+import org.spongycastle.cert.X509ExtensionUtils;
+import org.spongycastle.util.Arrays;
+import org.spongycastle.util.encoders.Base64;
+import org.spongycastle.util.encoders.Hex;
+import org.spongycastle.util.test.SimpleTest;
+
+public class X509ExtensionUtilsTest
+ extends SimpleTest
+{
+ private static byte[] pubKeyInfo = Base64.decode(
+ "MFgwCwYJKoZIhvcNAQEBA0kAMEYCQQC6wMMmHYMZszT/7bNFMn+gaZoiWJLVP8ODRuu1C2jeAe" +
+ "QpxM+5Oe7PaN2GNy3nBE4EOYkB5pMJWA0y9n04FX8NAgED");
+
+ private static byte[] shaID = Hex.decode("d8128a06d6c2feb0865994a2936e7b75b836a021");
+ private static byte[] shaTruncID = Hex.decode("436e7b75b836a021");
+ private X509ExtensionUtils x509ExtensionUtils = new X509ExtensionUtils(new SHA1DigestCalculator());
+
+ public String getName()
+ {
+ return "X509ExtensionUtilsTest";
+ }
+
+ public void performTest()
+ throws IOException
+ {
+ SubjectPublicKeyInfo pubInfo = SubjectPublicKeyInfo.getInstance(ASN1Primitive.fromByteArray(pubKeyInfo));
+
+ SubjectKeyIdentifier ski = x509ExtensionUtils.createSubjectKeyIdentifier(pubInfo);
+
+ if (!Arrays.areEqual(shaID, ski.getKeyIdentifier()))
+ {
+ fail("SHA-1 ID does not match");
+ }
+
+ ski = x509ExtensionUtils.createTruncatedSubjectKeyIdentifier(pubInfo);
+
+ if (!Arrays.areEqual(shaTruncID, ski.getKeyIdentifier()))
+ {
+ fail("truncated SHA-1 ID does not match");
+ }
+ }
+
+ public static void main(
+ String[] args)
+ {
+ runTest(new X509ExtensionUtilsTest());
+ }
+}