diff options
Diffstat (limited to 'pkix/src/test/java/org/spongycastle/cert')
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( + "MIACAQMwgAYJKoZIhvcNAQcBoIAkgASCA+gwgDCABgkqhkiG9w0BBwGggCSA" + + "BIID6DCCCFIwggL/BgsqhkiG9w0BDAoBAqCCArIwggKuMCgGCiqGSIb3DQEM" + + "AQMwGgQUjWJR94N+oDQ1XlXO/kUSwu3UOL0CAgQABIICgFjzMa65mpNKYQRA" + + "+avbnOjYZ7JkTA5XY7CBcOVwNySY6/ye5Ms6VYl7mCgqzzdDQhT02Th8wXMr" + + "fibaC5E/tJRfdWt1zYr9NTLxLG6iCNPXJGGV6aXznv+UFTnzbzGGIAf0zpYf" + + "DOOUMusnBeJO2GVETk6DyjtVqx0sLAJKDZQadpao4K5mr5t4bz7zGoykoKNN" + + "TRH1tcrb6FYIPy5cf9vAHbyEB6pBdRjFQMYt50fpQGdQ8az9vvf6fLgQe20x" + + "e9PtDeqVU+5xNHeWauyVWIjp5penVkptAMYBr5qqNHfg1WuP2V1BO4SI/VWQ" + + "+EBKzlOjbH84KDVPDtOQGtmGYmZElxvfpz+S5rHajfzgIKQDT6Y4PTKPtMuF" + + "3OYcrVb7EKhTv1lXEQcNrR2+Apa4r2SZnTBq+1JeAGMNzwsMbAEcolljNiVs" + + "Lbvxng/WYTBb7+v8EjhthVdyMIY9KoKLXWMtfadEchRPqHGcEJDJ0BlwaVcn" + + "UQrexG/UILyVCaKc8yZOI9plAquDx2bGHi6FI4LdToAllX6gX2GncTeuCSuo" + + "o0//DBO3Hj7Pj5sGPZsSqzVQ1kH90/jResUN3vm09WtXKo8TELmmjA1yMqXe" + + "1r0mP6uN+yvjF1djC9SjovIh/jOG2RiqRy7bGtPRRchgIJCJlC1UoWygJpD6" + + "5dlzKMnQLikJ5BhsCIx2F96rmQXXKd7pIwCH7tiKHefQrszHpYO7QvBhwLsk" + + "y1bUnakLrgF3wdgwGGxbmuE9mNRVh3piVLGtVw6pH/9jOjmJ6JPbZ8idOpl5" + + "fEXOc81CFHTwv/U4oTfjKej4PTCZr58tYO6DdhA5XoEGNmjv4rgZJH1m6iUx" + + "OjATBgkqhkiG9w0BCRQxBh4EAGMAYTAjBgkqhkiG9w0BCRUxFgQUKBwy0CF7" + + "51A+BhNFCrsws2AG0nYwggVLBgsqhkiG9w0BDAoBAqCCBPowggT2MCgGCiqG" + + "SIb3DQEMAQMwGgQUf9t4IA/TP6OsH4GCiDg1BsRCqTwCAgQABIIEyHjGPJZg" + + "zhkF93/jM4WTnQUgWOR3PlTmhUSKjyMCLUBSrICocLVsz316NHPT3lqr0Lu2" + + "eKXlE5GRDp/c8RToTzMvEDdwi2PHP8sStrGJa1ruNRpOMnVAj8gnyd5KcyYJ" + + "3j+Iv/56hzPFXsZMg8gtbPphRxb3xHEZj/xYXYfUhfdElezrBIID6LcWRZS2" + + "MuuVddZToLOIdVWSTDZLscR6BIID6Ok+m+VC82JjvLNK4pZqO7Re9s/KAxV9" + + "f3wfJ7C7kmr8ar4Mlp9jYfO11lCcBEL86sM93JypgayWp53NN2nYQjnQDafR" + + "NrtlthQuR36ir2DEuSp4ySqsSXX/nD3AVOvrpbN88RUIK8Yx36tRaBOBL8tv" + + "9aKDfgpWKK4NHxA7V3QkHCAVqLpUZlIvVqEcvjNpzn6ydDQLGk7x5itNlWdn" + + "Kq/LfgMlXrTY/kKC4k7xogFS/FRIR10NP3lU+vAEa5T299QZv7c7n2OSVg6K" + + "xEXwjYNhfsLP3PlaCppouc2xsq/zSvymZPWsVztuoMwEfVeTtoSEUU8cqOiw" + + "Q1NpGtvrO1R28uRdelAVcrIu0qBAbdB5xb+xMfMhVhk7iuSZsYzKJVjK1CNK" + + "4w+zNqfkZQQOdh1Qj1t5u/22HDTSzZKTot4brIywo6lxboFE0IDJwU8y62vF" + + "4PEBPJDeXBuzbqurQhMS19J8h9wjw2quPAJ0E8dPR5B/1qPAuWYs1i2z2AtL" + + "FwNU2B+u53EpI4kM/+Wh3wPZ7lxlXcooUc3+5tZdBqcN+s1A2JU5fkMu05/J" + + "FSMG89+L5cwygPZssQ0uQFMqIpbbJp2IF76DYvVOdMnnWMgmw4n9sTcLb7Tf" + + "GZAQEr3OLtXHxTAX6WnQ1rdDMiMGTvx4Kj1JrtENPI8Y7m6bhIfSuwUk4v3j" + + "/DlPmCzGKsZHfjUvaqiZ/Kg+V4gdOMiIlhUwrR3jbxrX1xXNJ+RjwQzC0wX8" + + "C8kGF4hK/DUil20EVZNmrTgqsBBqKLMKDNM7rGhyadlG1eg55rJL07ROmXfY" + + "PbMtgPQBVVGcvM58jsW8NlCF5XUBNVSOfNSePUOOccPMTCt4VqRZobciIn7i" + + "G6lGby6sS8KMRxmnviLWNVWqWyxjFhuv3S8zVplFmzJR7oXk8bcGW9QV93yN" + + "fceR9ZVQdEITPTqVE3r2sgrzgFYZAJ+tMzDfkL4NcSBnivfCS1APRttG1RHJ" + + "6nxjpf1Ya6CGkM17BdAeEtdXqBb/0B9n0hgPA8EIe5hfL+cGRx4aO8HldCMb" + + "YQUFIOFmuj4xn83eFSlh2zllSVaVj0epIqtcXWWefVpjZKlOgoivrTy9JSGp" + + "fbsDw/xZMPGYHehbtm60alZK/t4yrfyGLkeWq7FjK31WfIgx9KAEQM4G1cPx" + + "dX6Jj0YdoWKrJh7GdqoCSdrwtR5NkG8ecuYPm9P+UUFg+nbcqR7zWVv0MulQ" + + "X4LQoKN8iOXZYZDmKbgLYdh4BY8bqVELaHFZ3rU33EUoATO+43IQXHq5qyB5" + + "xJVvT6AEggPo0DNHyUyRNMHoT3feYuDiQszN/4N5qVLZL6UeBIGGwmAQq7CK" + + "2A2P67/7bjze+LZcvXgoBmkKPn9hVembyEPwow6wGVhrGDWiEvdNE/Tp3n6D" + + "NqLIOhnWfTnsinWNXIlqxa6V/jE+MBcGCSqGSIb3DQEJFDEKHggAcgBvAG8A" + + "dDAjBgkqhkiG9w0BCRUxFgQUioImRvGskdQCWPVdgD2wKGBiE/0AAAAAAAAw" + + "gAYJKoZIhvcNAQcGoIAwgAIBADCABgkqhkiG9w0BBwEwKAYKKoZIhvcNAQwB" + + "BjAaBBTOsaVE8IK7OpXHzfobYSfBfnKvTwICBACggASCCLirl2JOsxIiKwDT" + + "/iW4D7qRq4W2mdXiLuH8RTJzfARcWtfWRrszakA6Fi0WAsslor3EYMgBpNtJ" + + "yctpSfAO2ToEWNlzqRNffiy1UvxC7Pxo9coaDBfsD9hi253dxsCS+fkGlywA" + + "eSlHJ2JEhDz7Y7CO6i95LzvZTzz7075UZvSP5FcVjNlKyfDMVVN3tPXl5/Ej" + + "4l/rakdyg72d/ajx/VaG5S81Oy2sjTdG+j6G7aMgpAx7dkgiNr65f9rLU7M9" + + "sm24II3RZzfUcjHHSZUvwtXIJSBnHkYft7GqzCFHnikLapFh9ObMdc4qTQQA" + + "H7Upo0WD/rxgdKN0Bdj9BLZHm1Ixca6rBVOecg80t/kFXipwBihMUmPbHlWB" + + "UGjX1kDRyfvqlcDDWr7elGenqNX1qTYCGi41ChLC9igaQRP48NI3aqgx0bu4" + + "P2G19T+/E7UZrCc8VIlKUEGRNKSqVtC7IlqyoLdPms9TXzrYJkklB0m23VXI" + + "PyJ5MmmRFXOAtLXwqnLGNLYcafbS2F4MPOjkclWgEtOHKmJctBRI14eMlpN2" + + "gBMTYxVkOG7ehUtMbWnjTvivqRxsYPmRCC+m7wiHQodtm2fgJtfwhpRSmLu1" + + "/KHohc6ESh62ACsn8nfBthsbzuDxV0fsCgbUDomjWpGs+nBgZFYGAkE1z2Ao" + + "Xd7CvA3PZJ5HFtyJrEu8VAbCtU5ZLjXzbALiJ7BqJdzigqsxeieabsR+GCKz" + + "Drwk1RltTIZnP3EeQbD+mGPa2BjchseaaLNMVDngkc91Zdg2j18dfIabG4AS" + + "CvfM4DfwPdwD2UT48V8608u5OWc7O2sIcxVWv1IrbEFLSKchTPPnfKmdDji3" + + "LEoD6t1VPYfn0Ch/NEANOLdncsOUDzQCWscA3+6pkfH8ZaCxfyUU/SHGYKkW" + + "7twRpR9ka3Wr7rjMjmT0c24YNIUx9ZDt7iquCAdyRHHc13JQ+IWaoqo1z3b8" + + "tz6AIfm1dWgcMlzEAc80Jg/SdASCA+g2sROpkVxAyhOY/EIp1Fm+PSIPQ5dE" + + "r5wV7ne2gr40Zuxs5Mrra9Jm79hrErhe4nepA6/DkcHqVDW5sqDwSgLuwVui" + + "I2yjBt4xBShc6jUxKTRN43cMlZa4rKaEF636gBMUZHDD+zTRE5rtHKFggvwc" + + "LiitHXI+Fg9mH/h0cQRDYebc02bQikxKagfeUxm0DbEFH172VV+4L69MP6SY" + + "eyMyRyBXNvLBKDVI5klORE7ZMJGCf2pi3vQr+tSM3W51QmK3HuL+tcish4QW" + + "WOxVimmczo7tT/JPwSWcklTV4uvnAVLEfptl66Bu9I2/Kn3yPWElAoQvHjMD" + + "O47+CVcuhgX5OXt0Sy8OX09j733FG4XFImnBneae6FrxNoi3tMRyHaIwBjIo" + + "8VvqhWjPIJKytMT2/42TpsuD4Pj64m77sIx0rAjmU7s0kG4YdkgeSi+1R4X7" + + "hkEFVJe3fId7/sItU2BMHkQGBDELAP7gJFzqTLDuSoiVNJ6kB6vkC+VQ7nmn" + + "0xyzrOTNcrSBGc2dCXEI6eYi8/2K9y7ZS9dOEUi8SHfc4WNT4EJ8Qsvn61EW" + + "jM8Ye5av/t3iE8NGtiMbbsIorEweL8y88vEMkgqZ7MpLbb2iiAv8Zm16GWAv" + + "GRD7rUJfi/3dcXiskUCOg5rIRcn2ImVehqKAPArLbLAx7NJ6UZmB+99N3DpH" + + "Jk81BkWPwQF8UlPdwjQh7qJUHTjEYAQI2wmL2jttToq59g3xbrLVUM/5X2Xy" + + "Fy619lDydw0TZiGq8zA39lwT92WpziDeV5/vuj2gpcFs3f0cUSJlPsw7Y0mE" + + "D/uPk7Arn/iP1oZboM9my/H3tm3rOP5xYxkXI/kVsNucTMLwd4WWdtKk3DLg" + + "Ms1tcEdAUQ/ZJ938OJf1uzSixDhlMVedweIJMw72V9VpWUf+QC+SHOvGpdSz" + + "2a7mU340J0rsQp7HnS71XWPjtxVCN0Mva+gnF+VTEnamQFEETrEydaqFYQEh" + + "im5qr32YOiQiwdrIXJ+p9bNxAbaDBmBI/1bdDU9ffr+AGrxxgjvYGiUQk0d/" + + "SDvxlE+S9EZlTWirRatglklVndYdkzJDte7ZJSgjlXkbTgy++QW/xRQ0Ya3o" + + "ouQepoTkJ2b48ELe4KCKKTOfR0fTzd0578hSdpYuOCylYBZeuLIo6JH3VeoV" + + "dggXMYHtYPuj+ABN3utwP/5s5LZ553sMkI/0bJq8ytE/+BFh1rTbRksAuT6B" + + "d98lpDAXjyM1HcKD78YiXotdSISU+pYkIbyn4UG8SKzV9mCxAed1cgjE1BWW" + + "DUB+xwlFMQTFpj8fhhYYMcwUF8tmv22Snemkaq3pjJKPBIIB7/jK7pfLMSSS" + + "5ojMvWzu9mTegbl9v2K73XqZ/N4LZ5BqxnMdCBM4cCbA2LMwX8WAVlKper6X" + + "zdTxRf4SWuzzlOXIyhWaH1g9Yp3PkaWh/BpPne/DXZmfyrTCPWGlbu1oqdKq" + + "CgORN9B0+biTWiqgozvtbnCkK+LXqRYbghsWNlOhpm5NykUl7T2xRswYK8gz" + + "5vq/xCY5hq+TvgZOT0Fzx426nbNqyGmdjbCpPf2t4s5o3C48WhNSg3vSSJes" + + "RVJ4dV1TfXkytIKk/gzLafJfS+AcLeE48MyCOohhLFHdYC9f+lrk51xEANTc" + + "xpn26JO1sO7iha8iccRmMYwi6tgDRVKFp6X5VVHXy8hXzxEbWWFL/GkUIjyD" + + "hm0KXaarhP9Iah+/j6CI6eVLIhyMsA5itsYX+bJ0I8KmVkXelbwX7tcwSUAs" + + "0Wq8oiV8Mi+DawkhTWE2etz07uMseR71jHEr7KE6WXo+SO995Xyop74fLtje" + + "GLZroH91GWF4rDZvTJg9l8319oqF0DJ7bTukl3CJqVS3sVNrRIF33vRsmqWL" + + "BaaZ1Q8Bt04L19Ka2HsEYLMfTLPGO7HSb9baHezRCQTnVoABm+8iZEXj3Od9" + + "ga9TnxFa5KhXerqUscjdXPauElDwmqGhCgAAAAAAAAAAAAAAAAAAAAAAADA9" + + "MCEwCQYFKw4DAhoFAAQUWT4N9h+ObRftdP8+GldXCQRf9JoEFDjO/tjAH7We" + + "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( + "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" + +"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()); + } +} |