| package org.bouncycastle.cert.test; |
| |
| import java.io.ByteArrayInputStream; |
| import java.io.IOException; |
| import java.math.BigInteger; |
| import java.security.KeyFactory; |
| import java.security.PublicKey; |
| import java.security.Security; |
| import java.security.cert.CertificateFactory; |
| import java.security.cert.X509Certificate; |
| import java.security.spec.X509EncodedKeySpec; |
| |
| import org.bouncycastle.asn1.ASN1Primitive; |
| import org.bouncycastle.asn1.DEROctetString; |
| import org.bouncycastle.asn1.x500.X500Name; |
| import org.bouncycastle.asn1.x509.AuthorityKeyIdentifier; |
| import org.bouncycastle.asn1.x509.GeneralName; |
| import org.bouncycastle.asn1.x509.GeneralNames; |
| import org.bouncycastle.asn1.x509.SubjectKeyIdentifier; |
| import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo; |
| import org.bouncycastle.cert.X509CertificateHolder; |
| import org.bouncycastle.cert.X509ExtensionUtils; |
| import org.bouncycastle.cert.jcajce.JcaX509ExtensionUtils; |
| import org.bouncycastle.jce.provider.BouncyCastleProvider; |
| import org.bouncycastle.util.Arrays; |
| import org.bouncycastle.util.encoders.Base64; |
| import org.bouncycastle.util.encoders.Hex; |
| import org.bouncycastle.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 static byte[] v0Cert = Base64.decode("MIIBuTCCASICAQEwDQYJKoZIhvcNAQEFBQAwJTEWMBQGA1UECgwNQm91bmN5IENhc3RsZTELMAkGA1UEBhMCQVUwHhcNMTUwNzIxMjIwNzI3WhcNMTUxMDI5MjIwNzI3WjAlMRYwFAYDVQQKDA1Cb3VuY3kgQ2FzdGxlMQswCQYDVQQGEwJBVTCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEA9MhYrfDoC69iS/56gdvuwOvXKMsx9dSBZnK9KOnCFtc3fTeVp+61CeExuKXafqz0ZK/5ps0D+RMCOcIZXtXZsdC3CwgVx3k/CHKgrnp51v8sbgFzRrGr68Mp9Dr01wdgxjDCGgToUiBybU8IhsUc2nmwn3+Y+ZoIOvyQDuh3hXUCAwEAATANBgkqhkiG9w0BAQUFAAOBgQDvpEa3KFe7b+y7/MPNloabj6lfwW4vdKk4bg9+yMHFsb62OB8/RP4sJ+XIB91cGYINgA4d511juc9t6t7kEp6GijqWwAUtQfbyhZIO8DsCl96y3RfUag1L7Q3pn0SfyW0NAI8O9eKG/Hl6WmxRlvx3zmKz1bU+VSlnZoYt+6qZyg=="); |
| private static byte[] v3Cert = Base64.decode("MIICKzCCAZSgAwIBAgIBAjANBgkqhkiG9w0BAQUFADAlMRYwFAYDVQQKDA1Cb3VuY3kgQ2FzdGxlMQswCQYDVQQGEwJBVTAeFw0xNTA3MjEyMjA3MjdaFw0xNTEwMjkyMjA3MjdaMEMxDDAKBgNVBAMMA0JvYjEOMAwGA1UECwwFU2FsZXMxFjAUBgNVBAoMDUJvdW5jeSBDYXN0bGUxCzAJBgNVBAYTAkFVMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCHpUGlsn0Y+az7XGj3wq+om/kGNbdP+bKE6Du6x92Mq2SC8Fez5RdOkhJJqxk5U8O+Hj9dqoxBkpeqA5NA52agXNz4WlSDBii17U9PPoj7LPXlfXMujf18k/IY71M79/XRjj/xbqNEJQQAH+EHyFMVxFDaOHJ4huL3gq/C7v9tTQIDAQABo00wSzAdBgNVHQ4EFgQUxHM/5+X91RvdmNdbNFZ02Fug92wwHwYDVR0jBBgwFoAU8NRqCpfiTCDshX7mgx4L6KeXxJ0wCQYDVR0TBAIwADANBgkqhkiG9w0BAQUFAAOBgQCvqwjs+9IiWGlLmFc9b+ON7upBb8JCwVh5+Ks7F4waZ5gmLuUXZLEeMDvosSB6bPFgDWSIZsdxn/V4/hUMEJkvfRZJ5J/k1a7Yogi3XyFcE4k1p1W5ZQ+wm+CQwAWmOFdpJUCMsC1h2xJUu9agEPWowdc9P2+LL04ghFq9SnXsYg=="); |
| |
| public String getName() |
| { |
| return "X509ExtensionUtilsTest"; |
| } |
| |
| public void performTest() |
| throws Exception |
| { |
| basicTest(); |
| jcaTest(); |
| } |
| |
| public void basicTest() |
| throws IOException |
| { |
| X509ExtensionUtils x509ExtensionUtils = new X509ExtensionUtils(new SHA1DigestCalculator()); |
| |
| SubjectPublicKeyInfo pubInfo = SubjectPublicKeyInfo.getInstance(ASN1Primitive.fromByteArray(pubKeyInfo)); |
| |
| SubjectKeyIdentifier ski = x509ExtensionUtils.createSubjectKeyIdentifier(pubInfo); |
| |
| if (!Arrays.areEqual(shaID, ski.getKeyIdentifier())) |
| { |
| fail("basic SHA-1 ID does not match"); |
| } |
| |
| ski = x509ExtensionUtils.createTruncatedSubjectKeyIdentifier(pubInfo); |
| |
| if (!Arrays.areEqual(shaTruncID, ski.getKeyIdentifier())) |
| { |
| fail("basic truncated SHA-1 ID does not match"); |
| } |
| |
| AuthorityKeyIdentifier authKeyId = x509ExtensionUtils.createAuthorityKeyIdentifier(new X509CertificateHolder(v0Cert)); |
| if (!authKeyId.getAuthorityCertIssuer().equals(new GeneralNames(new GeneralName(new X500Name("O=Bouncy Castle, C=AU"))))) |
| { |
| fail("v0 issuer not matched"); |
| } |
| if (!Arrays.areEqual(Hex.decode("f0d46a0a97e24c20ec857ee6831e0be8a797c49d"), authKeyId.getKeyIdentifier())) |
| { |
| fail("v0 keyID not matched"); |
| } |
| if (!authKeyId.getAuthorityCertSerialNumber().equals(BigInteger.valueOf(1))) |
| { |
| fail("v0 serial not matched"); |
| } |
| |
| authKeyId = x509ExtensionUtils.createAuthorityKeyIdentifier(new X509CertificateHolder(v3Cert)); |
| if (!authKeyId.getAuthorityCertIssuer().equals(new GeneralNames(new GeneralName(new X500Name("O=Bouncy Castle, C=AU"))))) |
| { |
| fail("v3 issuer not matched"); |
| } |
| if (!Arrays.areEqual(Hex.decode("c4733fe7e5fdd51bdd98d75b345674d85ba0f76c"), authKeyId.getKeyIdentifier())) |
| { |
| fail("v3 keyID not matched"); |
| } |
| if (!authKeyId.getAuthorityCertSerialNumber().equals(BigInteger.valueOf(2))) |
| { |
| fail("v3 serial not matched"); |
| } |
| } |
| |
| public void jcaTest() |
| throws Exception |
| { |
| JcaX509ExtensionUtils x509ExtensionUtils = new JcaX509ExtensionUtils(); |
| |
| PublicKey key = KeyFactory.getInstance("RSA", "BC").generatePublic(new X509EncodedKeySpec(pubKeyInfo)); |
| |
| SubjectKeyIdentifier ski = x509ExtensionUtils.createSubjectKeyIdentifier(key); |
| |
| if (!Arrays.areEqual(shaID, ski.getKeyIdentifier())) |
| { |
| fail("jca SHA-1 ID does not match"); |
| } |
| |
| ski = x509ExtensionUtils.createTruncatedSubjectKeyIdentifier(key); |
| |
| if (!Arrays.areEqual(shaTruncID, ski.getKeyIdentifier())) |
| { |
| fail("jca truncated SHA-1 ID does not match"); |
| } |
| |
| CertificateFactory cFact = CertificateFactory.getInstance("X.509", "BC"); |
| |
| X509Certificate v0certificate = (X509Certificate)cFact.generateCertificate(new ByteArrayInputStream(v0Cert)); |
| X509Certificate v3certificate = (X509Certificate)cFact.generateCertificate(new ByteArrayInputStream(v3Cert)); |
| |
| AuthorityKeyIdentifier authKeyId = x509ExtensionUtils.createAuthorityKeyIdentifier(v0certificate); |
| if (!authKeyId.getAuthorityCertIssuer().equals(new GeneralNames(new GeneralName(new X500Name("O=Bouncy Castle, C=AU"))))) |
| { |
| fail("v0 issuer not matched"); |
| } |
| if (!Arrays.areEqual(Hex.decode("f0d46a0a97e24c20ec857ee6831e0be8a797c49d"), authKeyId.getKeyIdentifier())) |
| { |
| fail("v0 keyID not matched"); |
| } |
| if (!authKeyId.getAuthorityCertSerialNumber().equals(BigInteger.valueOf(1))) |
| { |
| fail("v0 serial not matched"); |
| } |
| |
| authKeyId = x509ExtensionUtils.createAuthorityKeyIdentifier(v3certificate); |
| if (!authKeyId.getAuthorityCertIssuer().equals(new GeneralNames(new GeneralName(new X500Name("O=Bouncy Castle, C=AU"))))) |
| { |
| fail("v3 issuer not matched"); |
| } |
| if (!Arrays.areEqual(Hex.decode("c4733fe7e5fdd51bdd98d75b345674d85ba0f76c"), authKeyId.getKeyIdentifier())) |
| { |
| fail("v3 keyID not matched"); |
| } |
| if (!authKeyId.getAuthorityCertSerialNumber().equals(BigInteger.valueOf(2))) |
| { |
| fail("v3 serial not matched"); |
| } |
| |
| // simulate the JCA X509Certificate.getExtension() method. |
| authKeyId = AuthorityKeyIdentifier.getInstance(JcaX509ExtensionUtils.parseExtensionValue(new DEROctetString(authKeyId).getEncoded())); |
| if (!authKeyId.getAuthorityCertIssuer().equals(new GeneralNames(new GeneralName(new X500Name("O=Bouncy Castle, C=AU"))))) |
| { |
| fail("v3 issuer not matched"); |
| } |
| if (!Arrays.areEqual(Hex.decode("c4733fe7e5fdd51bdd98d75b345674d85ba0f76c"), authKeyId.getKeyIdentifier())) |
| { |
| fail("v3 keyID not matched"); |
| } |
| if (!authKeyId.getAuthorityCertSerialNumber().equals(BigInteger.valueOf(2))) |
| { |
| fail("v3 serial not matched"); |
| } |
| } |
| |
| public static void main( |
| String[] args) |
| { |
| Security.addProvider(new BouncyCastleProvider()); |
| |
| runTest(new X509ExtensionUtilsTest()); |
| } |
| } |