1 package org.bouncycastle.cert.test; 2 3 import java.io.ByteArrayInputStream; 4 import java.io.IOException; 5 import java.math.BigInteger; 6 import java.security.KeyFactory; 7 import java.security.PrivateKey; 8 import java.security.PublicKey; 9 import java.security.Security; 10 import java.security.cert.CertificateFactory; 11 import java.security.cert.X509Certificate; 12 import java.security.spec.RSAPrivateCrtKeySpec; 13 import java.security.spec.RSAPublicKeySpec; 14 import java.util.ArrayList; 15 import java.util.Collection; 16 import java.util.Date; 17 import java.util.List; 18 import java.util.Set; 19 20 import org.bouncycastle.asn1.ASN1Encodable; 21 import org.bouncycastle.asn1.ASN1EncodableVector; 22 import org.bouncycastle.asn1.ASN1ObjectIdentifier; 23 import org.bouncycastle.asn1.ASN1String; 24 import org.bouncycastle.asn1.DEROctetString; 25 import org.bouncycastle.asn1.DERSequence; 26 import org.bouncycastle.asn1.x500.X500Name; 27 import org.bouncycastle.asn1.x509.Attribute; 28 import org.bouncycastle.asn1.x509.GeneralName; 29 import org.bouncycastle.asn1.x509.GeneralNames; 30 import org.bouncycastle.asn1.x509.Extension; 31 import org.bouncycastle.cert.AttributeCertificateHolder; 32 import org.bouncycastle.cert.AttributeCertificateIssuer; 33 import org.bouncycastle.cert.X509AttributeCertificateHolder; 34 import org.bouncycastle.cert.X509v2AttributeCertificateBuilder; 35 import org.bouncycastle.cert.jcajce.JcaCertStore; 36 import org.bouncycastle.cert.jcajce.JcaX509CertificateHolder; 37 import org.bouncycastle.jce.provider.BouncyCastleProvider; 38 import org.bouncycastle.operator.ContentSigner; 39 import org.bouncycastle.operator.jcajce.JcaContentSignerBuilder; 40 import org.bouncycastle.operator.jcajce.JcaContentVerifierProviderBuilder; 41 import org.bouncycastle.util.Store; 42 import org.bouncycastle.util.encoders.Base64; 43 import org.bouncycastle.util.test.SimpleTest; 44 45 public class AttrCertTest 46 extends SimpleTest 47 { 48 private static final String BC = BouncyCastleProvider.PROVIDER_NAME; 49 50 private static final RSAPrivateCrtKeySpec RSA_PRIVATE_KEY_SPEC = new RSAPrivateCrtKeySpec( 51 new BigInteger("b4a7e46170574f16a97082b22be58b6a2a629798419be12872a4bdba626cfae9900f76abfb12139dce5de56564fab2b6543165a040c606887420e33d91ed7ed7", 16), 52 new BigInteger("11", 16), 53 new BigInteger("9f66f6b05410cd503b2709e88115d55daced94d1a34d4e32bf824d0dde6028ae79c5f07b580f5dce240d7111f7ddb130a7945cd7d957d1920994da389f490c89", 16), 54 new BigInteger("c0a0758cdf14256f78d4708c86becdead1b50ad4ad6c5c703e2168fbf37884cb", 16), 55 new BigInteger("f01734d7960ea60070f1b06f2bb81bfac48ff192ae18451d5e56c734a5aab8a5", 16), 56 new BigInteger("b54bb9edff22051d9ee60f9351a48591b6500a319429c069a3e335a1d6171391", 16), 57 new BigInteger("d3d83daf2a0cecd3367ae6f8ae1aeb82e9ac2f816c6fc483533d8297dd7884cd", 16), 58 new BigInteger("b8f52fc6f38593dabb661d3f50f8897f8106eee68b1bce78a95b132b4e5b5d19", 16)); 59 60 public static byte[] attrCert = Base64.decode( 61 "MIIHQDCCBqkCAQEwgZChgY2kgYowgYcxHDAaBgkqhkiG9w0BCQEWDW1sb3JjaEB2" 62 + "dC5lZHUxHjAcBgNVBAMTFU1hcmt1cyBMb3JjaCAobWxvcmNoKTEbMBkGA1UECxMS" 63 + "VmlyZ2luaWEgVGVjaCBVc2VyMRAwDgYDVQQLEwdDbGFzcyAyMQswCQYDVQQKEwJ2" 64 + "dDELMAkGA1UEBhMCVVMwgYmkgYYwgYMxGzAZBgkqhkiG9w0BCQEWDHNzaGFoQHZ0" 65 + "LmVkdTEbMBkGA1UEAxMSU3VtaXQgU2hhaCAoc3NoYWgpMRswGQYDVQQLExJWaXJn" 66 + "aW5pYSBUZWNoIFVzZXIxEDAOBgNVBAsTB0NsYXNzIDExCzAJBgNVBAoTAnZ0MQsw" 67 + "CQYDVQQGEwJVUzANBgkqhkiG9w0BAQQFAAIBBTAiGA8yMDAzMDcxODE2MDgwMloY" 68 + "DzIwMDMwNzI1MTYwODAyWjCCBU0wggVJBgorBgEEAbRoCAEBMYIFORaCBTU8UnVs" 69 + "ZSBSdWxlSWQ9IkZpbGUtUHJpdmlsZWdlLVJ1bGUiIEVmZmVjdD0iUGVybWl0Ij4K" 70 + "IDxUYXJnZXQ+CiAgPFN1YmplY3RzPgogICA8U3ViamVjdD4KICAgIDxTdWJqZWN0" 71 + "TWF0Y2ggTWF0Y2hJZD0idXJuOm9hc2lzOm5hbWVzOnRjOnhhY21sOjEuMDpmdW5j" 72 + "dGlvbjpzdHJpbmctZXF1YWwiPgogICAgIDxBdHRyaWJ1dGVWYWx1ZSBEYXRhVHlw" 73 + "ZT0iaHR0cDovL3d3dy53My5vcmcvMjAwMS9YTUxTY2hlbWEjc3RyaW5nIj4KICAg" 74 + "ICAgIENOPU1hcmt1cyBMb3JjaDwvQXR0cmlidXRlVmFsdWU+CiAgICAgPFN1Ympl" 75 + "Y3RBdHRyaWJ1dGVEZXNpZ25hdG9yIEF0dHJpYnV0ZUlkPSJ1cm46b2FzaXM6bmFt" 76 + "ZXM6dGM6eGFjbWw6MS4wOnN1YmplY3Q6c3ViamVjdC1pZCIgRGF0YVR5cGU9Imh0" 77 + "dHA6Ly93d3cudzMub3JnLzIwMDEvWE1MU2NoZW1hI3N0cmluZyIgLz4gCiAgICA8" 78 + "L1N1YmplY3RNYXRjaD4KICAgPC9TdWJqZWN0PgogIDwvU3ViamVjdHM+CiAgPFJl" 79 + "c291cmNlcz4KICAgPFJlc291cmNlPgogICAgPFJlc291cmNlTWF0Y2ggTWF0Y2hJ" 80 + "ZD0idXJuOm9hc2lzOm5hbWVzOnRjOnhhY21sOjEuMDpmdW5jdGlvbjpzdHJpbmct" 81 + "ZXF1YWwiPgogICAgIDxBdHRyaWJ1dGVWYWx1ZSBEYXRhVHlwZT0iaHR0cDovL3d3" 82 + "dy53My5vcmcvMjAwMS9YTUxTY2hlbWEjYW55VVJJIj4KICAgICAgaHR0cDovL3p1" 83 + "bmkuY3MudnQuZWR1PC9BdHRyaWJ1dGVWYWx1ZT4KICAgICA8UmVzb3VyY2VBdHRy" 84 + "aWJ1dGVEZXNpZ25hdG9yIEF0dHJpYnV0ZUlkPSJ1cm46b2FzaXM6bmFtZXM6dGM6" 85 + "eGFjbWw6MS4wOnJlc291cmNlOnJlc291cmNlLWlkIiBEYXRhVHlwZT0iaHR0cDov" 86 + "L3d3dy53My5vcmcvMjAwMS9YTUxTY2hlbWEjYW55VVJJIiAvPiAKICAgIDwvUmVz" 87 + "b3VyY2VNYXRjaD4KICAgPC9SZXNvdXJjZT4KICA8L1Jlc291cmNlcz4KICA8QWN0" 88 + "aW9ucz4KICAgPEFjdGlvbj4KICAgIDxBY3Rpb25NYXRjaCBNYXRjaElkPSJ1cm46" 89 + "b2FzaXM6bmFtZXM6dGM6eGFjbWw6MS4wOmZ1bmN0aW9uOnN0cmluZy1lcXVhbCI+" 90 + "CiAgICAgPEF0dHJpYnV0ZVZhbHVlIERhdGFUeXBlPSJodHRwOi8vd3d3LnczLm9y" 91 + "Zy8yMDAxL1hNTFNjaGVtYSNzdHJpbmciPgpEZWxlZ2F0ZSBBY2Nlc3MgICAgIDwv" 92 + "QXR0cmlidXRlVmFsdWU+CgkgIDxBY3Rpb25BdHRyaWJ1dGVEZXNpZ25hdG9yIEF0" 93 + "dHJpYnV0ZUlkPSJ1cm46b2FzaXM6bmFtZXM6dGM6eGFjbWw6MS4wOmFjdGlvbjph" 94 + "Y3Rpb24taWQiIERhdGFUeXBlPSJodHRwOi8vd3d3LnczLm9yZy8yMDAxL1hNTFNj" 95 + "aGVtYSNzdHJpbmciIC8+IAogICAgPC9BY3Rpb25NYXRjaD4KICAgPC9BY3Rpb24+" 96 + "CiAgPC9BY3Rpb25zPgogPC9UYXJnZXQ+CjwvUnVsZT4KMA0GCSqGSIb3DQEBBAUA" 97 + "A4GBAGiJSM48XsY90HlYxGmGVSmNR6ZW2As+bot3KAfiCIkUIOAqhcphBS23egTr" 98 + "6asYwy151HshbPNYz+Cgeqs45KkVzh7bL/0e1r8sDVIaaGIkjHK3CqBABnfSayr3" 99 + "Rd1yBoDdEv8Qb+3eEPH6ab9021AsLEnJ6LWTmybbOpMNZ3tv"); 100 101 byte[] signCert = Base64.decode( 102 "MIIGjTCCBXWgAwIBAgICAPswDQYJKoZIhvcNAQEEBQAwaTEdMBsGCSqGSIb3DQEJ" 103 + "ARYOaXJtaGVscEB2dC5lZHUxLjAsBgNVBAMTJVZpcmdpbmlhIFRlY2ggQ2VydGlm" 104 + "aWNhdGlvbiBBdXRob3JpdHkxCzAJBgNVBAoTAnZ0MQswCQYDVQQGEwJVUzAeFw0w" 105 + "MzAxMzExMzUyMTRaFw0wNDAxMzExMzUyMTRaMIGDMRswGQYJKoZIhvcNAQkBFgxz" 106 + "c2hhaEB2dC5lZHUxGzAZBgNVBAMTElN1bWl0IFNoYWggKHNzaGFoKTEbMBkGA1UE" 107 + "CxMSVmlyZ2luaWEgVGVjaCBVc2VyMRAwDgYDVQQLEwdDbGFzcyAxMQswCQYDVQQK" 108 + "EwJ2dDELMAkGA1UEBhMCVVMwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAPDc" 109 + "scgSKmsEp0VegFkuitD5j5PUkDuzLjlfaYONt2SN8WeqU4j2qtlCnsipa128cyKS" 110 + "JzYe9duUdNxquh5BPIkMkHBw4jHoQA33tk0J/sydWdN74/AHPpPieK5GHwhU7GTG" 111 + "rCCS1PJRxjXqse79ExAlul+gjQwHeldAC+d4A6oZAgMBAAGjggOmMIIDojAMBgNV" 112 + "HRMBAf8EAjAAMBEGCWCGSAGG+EIBAQQEAwIFoDAOBgNVHQ8BAf8EBAMCA/gwHQYD" 113 + "VR0lBBYwFAYIKwYBBQUHAwIGCCsGAQUFBwMEMB0GA1UdDgQWBBRUIoWAzlXbzBYE" 114 + "yVTjQFWyMMKo1jCBkwYDVR0jBIGLMIGIgBTgc3Fm+TGqKDhen+oKfbl+xVbj2KFt" 115 + "pGswaTEdMBsGCSqGSIb3DQEJARYOaXJtaGVscEB2dC5lZHUxLjAsBgNVBAMTJVZp" 116 + "cmdpbmlhIFRlY2ggQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkxCzAJBgNVBAoTAnZ0" 117 + "MQswCQYDVQQGEwJVU4IBADCBiwYJYIZIAYb4QgENBH4WfFZpcmdpbmlhIFRlY2gg" 118 + "Q2VydGlmaWNhdGlvbiBBdXRob3JpdHkgZGlnaXRhbCBjZXJ0aWZpY2F0ZXMgYXJl" 119 + "IHN1YmplY3QgdG8gcG9saWNpZXMgbG9jYXRlZCBhdCBodHRwOi8vd3d3LnBraS52" 120 + "dC5lZHUvY2EvY3BzLy4wFwYDVR0RBBAwDoEMc3NoYWhAdnQuZWR1MBkGA1UdEgQS" 121 + "MBCBDmlybWhlbHBAdnQuZWR1MEMGCCsGAQUFBwEBBDcwNTAzBggrBgEFBQcwAoYn" 122 + "aHR0cDovL2JveDE3Ny5jYy52dC5lZHUvY2EvaXNzdWVycy5odG1sMEQGA1UdHwQ9" 123 + "MDswOaA3oDWGM2h0dHA6Ly9ib3gxNzcuY2MudnQuZWR1L2h0ZG9jcy1wdWJsaWMv" 124 + "Y3JsL2NhY3JsLmNybDBUBgNVHSAETTBLMA0GCysGAQQBtGgFAQEBMDoGCysGAQQB" 125 + "tGgFAQEBMCswKQYIKwYBBQUHAgEWHWh0dHA6Ly93d3cucGtpLnZ0LmVkdS9jYS9j" 126 + "cHMvMD8GCWCGSAGG+EIBBAQyFjBodHRwOi8vYm94MTc3LmNjLnZ0LmVkdS9jZ2kt" 127 + "cHVibGljL2NoZWNrX3Jldl9jYT8wPAYJYIZIAYb4QgEDBC8WLWh0dHA6Ly9ib3gx" 128 + "NzcuY2MudnQuZWR1L2NnaS1wdWJsaWMvY2hlY2tfcmV2PzBLBglghkgBhvhCAQcE" 129 + "PhY8aHR0cHM6Ly9ib3gxNzcuY2MudnQuZWR1L35PcGVuQ0E4LjAxMDYzMC9jZ2kt" 130 + "cHVibGljL3JlbmV3YWw/MCwGCWCGSAGG+EIBCAQfFh1odHRwOi8vd3d3LnBraS52" 131 + "dC5lZHUvY2EvY3BzLzANBgkqhkiG9w0BAQQFAAOCAQEAHJ2ls9yjpZVcu5DqiE67" 132 + "r7BfkdMnm7IOj2v8cd4EAlPp6OPBmjwDMwvKRBb/P733kLBqFNWXWKTpT008R0KB" 133 + "8kehbx4h0UPz9vp31zhGv169+5iReQUUQSIwTGNWGLzrT8kPdvxiSAvdAJxcbRBm" 134 + "KzDic5I8PoGe48kSCkPpT1oNmnivmcu5j1SMvlx0IS2BkFMksr0OHiAW1elSnE/N" 135 + "RuX2k73b3FucwVxB3NRo3vgoHPCTnh9r4qItAHdxFlF+pPtbw2oHESKRfMRfOIHz" 136 + "CLQWSIa6Tvg4NIV3RRJ0sbCObesyg08lymalQMdkXwtRn5eGE00SHWwEUjSXP2gR" 137 + "3g=="); 138 139 static byte[] certWithBaseCertificateID = Base64.decode( 140 "MIIBqzCCARQCAQEwSKBGMD6kPDA6MQswCQYDVQQGEwJJVDEOMAwGA1UEChMFVU5JVE4xDDAKBgNV" 141 + "BAsTA0RJVDENMAsGA1UEAxMEcm9vdAIEAVMVjqB6MHikdjB0MQswCQYDVQQGEwJBVTEoMCYGA1UE" 142 + "ChMfVGhlIExlZ2lvbiBvZiB0aGUgQm91bmN5IENhc3RsZTEjMCEGA1UECxMaQm91bmN5IFByaW1h" 143 + "cnkgQ2VydGlmaWNhdGUxFjAUBgNVBAMTDUJvdW5jeSBDYXN0bGUwDQYJKoZIhvcNAQEFBQACBQKW" 144 + "RhnHMCIYDzIwMDUxMjEyMTIwMDQyWhgPMjAwNTEyMTkxMjAxMzJaMA8wDQYDVRhIMQaBBGVWSVAw" 145 + "DQYJKoZIhvcNAQEFBQADgYEAUAVin9StDaA+InxtXq/av6rUQLI9p1X6louBcj4kYJnxRvTrHpsr" 146 + "N3+i9Uq/uk5lRdAqmPFvcmSbuE3TRAsjrXON5uFiBBKZ1AouLqcr8nHbwcdwjJ9TyUNO9I4hfpSH" 147 + "UHHXMtBKgp4MOkhhX8xTGyWg3hp23d3GaUeg/IYlXBI="); 148 149 byte[] holderCertWithBaseCertificateID = Base64.decode( 150 "MIIBwDCCASmgAwIBAgIEAVMVjjANBgkqhkiG9w0BAQUFADA6MQswCQYDVQQGEwJJVDEOMAwGA1UE" 151 + "ChMFVU5JVE4xDDAKBgNVBAsTA0RJVDENMAsGA1UEAxMEcm9vdDAeFw0wNTExMTExMjAxMzJaFw0w" 152 + "NjA2MTYxMjAxMzJaMD4xCzAJBgNVBAYTAklUMQ4wDAYDVQQKEwVVTklUTjEMMAoGA1UECxMDRElU" 153 + "MREwDwYDVQQDEwhMdWNhQm9yejBaMA0GCSqGSIb3DQEBAQUAA0kAMEYCQQC0p+RhcFdPFqlwgrIr" 154 + "5YtqKmKXmEGb4ShypL26Ymz66ZAPdqv7EhOdzl3lZWT6srZUMWWgQMYGiHQg4z2R7X7XAgERoxUw" 155 + "EzARBglghkgBhvhCAQEEBAMCBDAwDQYJKoZIhvcNAQEFBQADgYEAsX50VPQQCWmHvPq9y9DeCpmS" 156 + "4szcpFAhpZyn6gYRwY9CRZVtmZKH8713XhkGDWcIEMcG0u3oTz3tdKgPU5uyIPrDEWr6w8ClUj4x" 157 + "5aVz5c2223+dVY7KES//JSB2bE/KCIchN3kAioQ4K8O3e0OL6oDVjsqKGw5bfahgKuSIk/Q="); 158 159 getName()160 public String getName() 161 { 162 return "AttrCertTest"; 163 } 164 testCertWithBaseCertificateID()165 private void testCertWithBaseCertificateID() 166 throws Exception 167 { 168 X509AttributeCertificateHolder attrCert = new X509AttributeCertificateHolder(certWithBaseCertificateID); 169 CertificateFactory fact = CertificateFactory.getInstance("X.509", "BC"); 170 X509Certificate cert = (X509Certificate)fact.generateCertificate(new ByteArrayInputStream(holderCertWithBaseCertificateID)); 171 172 AttributeCertificateHolder holder = attrCert.getHolder(); 173 174 if (holder.getEntityNames() != null) 175 { 176 fail("entity names set when none expected"); 177 } 178 179 if (!holder.getSerialNumber().equals(cert.getSerialNumber())) 180 { 181 fail("holder serial number doesn't match"); 182 } 183 184 if (!holder.getIssuer()[0].equals(new JcaX509CertificateHolder(cert).getIssuer())) 185 { 186 fail("holder issuer doesn't match"); 187 } 188 189 if (!holder.match(new JcaX509CertificateHolder(cert))) 190 { 191 fail("holder not matching holder certificate"); 192 } 193 194 if (!holder.equals(holder.clone())) 195 { 196 fail("holder clone test failed"); 197 } 198 199 if (!attrCert.getIssuer().equals(attrCert.getIssuer().clone())) 200 { 201 fail("issuer clone test failed"); 202 } 203 204 //equalityAndHashCodeTest(attrCert, certWithBaseCertificateID); 205 } 206 equalityAndHashCodeTest(X509AttributeCertificateHolder attrCert, byte[] encoding)207 private void equalityAndHashCodeTest(X509AttributeCertificateHolder attrCert, byte[] encoding) 208 throws IOException 209 { 210 if (!attrCert.equals(attrCert)) 211 { 212 fail("same certificate not equal"); 213 } 214 215 if (!attrCert.getHolder().equals(attrCert.getHolder())) 216 { 217 fail("same holder not equal"); 218 } 219 220 if (!attrCert.getIssuer().equals(attrCert.getIssuer())) 221 { 222 fail("same issuer not equal"); 223 } 224 225 if (attrCert.getHolder().equals(attrCert.getIssuer())) 226 { 227 fail("wrong holder equal"); 228 } 229 230 if (attrCert.getIssuer().equals(attrCert.getHolder())) 231 { 232 fail("wrong issuer equal"); 233 } 234 235 X509AttributeCertificateHolder attrCert2 = new X509AttributeCertificateHolder(encoding); 236 237 if (attrCert2.getHolder().hashCode() != attrCert.getHolder().hashCode()) 238 { 239 fail("holder hashCode test failed"); 240 } 241 242 if (!attrCert2.getHolder().equals(attrCert.getHolder())) 243 { 244 fail("holder equals test failed"); 245 } 246 247 if (attrCert2.getIssuer().hashCode() != attrCert.getIssuer().hashCode()) 248 { 249 fail("issuer hashCode test failed"); 250 } 251 252 if (!attrCert2.getIssuer().equals(attrCert.getIssuer())) 253 { 254 fail("issuer equals test failed"); 255 } 256 } 257 testGenerateWithCert()258 private void testGenerateWithCert() 259 throws Exception 260 { 261 CertificateFactory fact = CertificateFactory.getInstance("X.509","BC"); 262 X509Certificate iCert = (X509Certificate)fact.generateCertificate(new ByteArrayInputStream(signCert)); 263 264 // 265 // a sample key pair. 266 // 267 RSAPublicKeySpec pubKeySpec = new RSAPublicKeySpec( 268 new BigInteger("b4a7e46170574f16a97082b22be58b6a2a629798419be12872a4bdba626cfae9900f76abfb12139dce5de56564fab2b6543165a040c606887420e33d91ed7ed7", 16), 269 new BigInteger("11", 16)); 270 271 // 272 // set up the keys 273 // 274 PrivateKey privKey; 275 PublicKey pubKey; 276 277 KeyFactory kFact = KeyFactory.getInstance("RSA", "BC"); 278 279 privKey = kFact.generatePrivate(RSA_PRIVATE_KEY_SPEC); 280 pubKey = kFact.generatePublic(pubKeySpec); 281 282 X509v2AttributeCertificateBuilder gen = new X509v2AttributeCertificateBuilder( 283 new AttributeCertificateHolder(new JcaX509CertificateHolder(iCert)), 284 new AttributeCertificateIssuer(new X500Name("cn=test")), 285 BigInteger.valueOf(1), 286 new Date(System.currentTimeMillis() - 50000), 287 new Date(System.currentTimeMillis() + 50000)); 288 289 // the actual attributes 290 GeneralName roleName = new GeneralName(GeneralName.rfc822Name, "DAU123456789"); 291 ASN1EncodableVector roleSyntax = new ASN1EncodableVector(); 292 roleSyntax.add(roleName); 293 294 // roleSyntax OID: 2.5.24.72; 295 296 gen.addAttribute(new ASN1ObjectIdentifier("2.5.24.72"), new DERSequence(roleSyntax)); 297 298 ContentSigner sigGen = new JcaContentSignerBuilder("SHA1WithRSAEncryption").setProvider(BC).build(privKey); 299 300 X509AttributeCertificateHolder aCert = gen.build(sigGen); 301 302 if (!aCert.isValidOn(new Date())) 303 { 304 fail("certificate invalid"); 305 } 306 307 if (!aCert.isSignatureValid(new JcaContentVerifierProviderBuilder().setProvider(BC).build(pubKey))) 308 { 309 fail("certificate signature not valid"); 310 } 311 312 AttributeCertificateHolder holder = aCert.getHolder(); 313 314 if (holder.getEntityNames() != null) 315 { 316 fail("entity names set when none expected"); 317 } 318 319 if (!holder.getSerialNumber().equals(iCert.getSerialNumber())) 320 { 321 fail("holder serial number doesn't match"); 322 } 323 324 if (!holder.getIssuer()[0].equals(new JcaX509CertificateHolder(iCert).getIssuer())) 325 { 326 fail("holder issuer doesn't match"); 327 } 328 329 if (!holder.match(new JcaX509CertificateHolder(iCert))) 330 { 331 fail("generated holder not matching holder certificate"); 332 } 333 334 Attribute[] attrs = aCert.getAttributes(new ASN1ObjectIdentifier("2.5.24.72")); 335 336 if (attrs == null) 337 { 338 fail("attributes related to 2.5.24.72 not found"); 339 } 340 341 Attribute attr = attrs[0]; 342 343 if (!attr.getAttrType().getId().equals("2.5.24.72")) 344 { 345 fail("attribute oid mismatch"); 346 } 347 348 ASN1Encodable[] values = attr.getAttrValues().toArray(); 349 350 GeneralName role = GeneralNames.getInstance(values[0]).getNames()[0]; 351 352 if (role.getTagNo() != GeneralName.rfc822Name) 353 { 354 fail("wrong general name type found in role"); 355 } 356 357 if (!((ASN1String)role.getName()).getString().equals("DAU123456789")) 358 { 359 fail("wrong general name value found in role"); 360 } 361 362 X509Certificate sCert = (X509Certificate)fact.generateCertificate(new ByteArrayInputStream(holderCertWithBaseCertificateID)); 363 364 if (holder.match(new JcaX509CertificateHolder(sCert))) 365 { 366 fail("generated holder matching wrong certificate"); 367 } 368 369 equalityAndHashCodeTest(aCert, aCert.getEncoded()); 370 } 371 testGenerateWithPrincipal()372 private void testGenerateWithPrincipal() 373 throws Exception 374 { 375 CertificateFactory fact = CertificateFactory.getInstance("X.509","BC"); 376 X509Certificate iCert = (X509Certificate)fact.generateCertificate(new ByteArrayInputStream(signCert)); 377 378 // 379 // a sample key pair. 380 // 381 RSAPublicKeySpec pubKeySpec = new RSAPublicKeySpec( 382 new BigInteger("b4a7e46170574f16a97082b22be58b6a2a629798419be12872a4bdba626cfae9900f76abfb12139dce5de56564fab2b6543165a040c606887420e33d91ed7ed7", 16), 383 new BigInteger("11", 16)); 384 385 // 386 // set up the keys 387 // 388 PrivateKey privKey; 389 PublicKey pubKey; 390 391 KeyFactory kFact = KeyFactory.getInstance("RSA", "BC"); 392 393 privKey = kFact.generatePrivate(RSA_PRIVATE_KEY_SPEC); 394 pubKey = kFact.generatePublic(pubKeySpec); 395 396 X509v2AttributeCertificateBuilder gen = new X509v2AttributeCertificateBuilder( 397 new AttributeCertificateHolder(new JcaX509CertificateHolder(iCert).getSubject()), 398 new AttributeCertificateIssuer(new X500Name("cn=test")), 399 BigInteger.valueOf(1), 400 new Date(System.currentTimeMillis() - 50000), 401 new Date(System.currentTimeMillis() + 50000)); 402 403 // the actual attributes 404 GeneralName roleName = new GeneralName(GeneralName.rfc822Name, "DAU123456789"); 405 ASN1EncodableVector roleSyntax = new ASN1EncodableVector(); 406 roleSyntax.add(roleName); 407 408 // roleSyntax OID: 2.5.24.72 409 410 gen.addAttribute(new ASN1ObjectIdentifier("2.5.24.72"), new DERSequence(roleSyntax)); 411 412 ContentSigner sigGen = new JcaContentSignerBuilder("SHA1WithRSAEncryption").setProvider(BC).build(privKey); 413 414 X509AttributeCertificateHolder aCert = gen.build(sigGen); 415 416 if (!aCert.isValidOn(new Date())) 417 { 418 fail("certificate invalid"); 419 } 420 421 if (!aCert.isSignatureValid(new JcaContentVerifierProviderBuilder().setProvider(BC).build(pubKey))) 422 { 423 fail("certificate signature not valid"); 424 } 425 426 AttributeCertificateHolder holder = aCert.getHolder(); 427 428 if (holder.getEntityNames() == null) 429 { 430 fail("entity names not set when expected"); 431 } 432 433 if (holder.getSerialNumber() != null) 434 { 435 fail("holder serial number found when none expected"); 436 } 437 438 if (holder.getIssuer() != null) 439 { 440 fail("holder issuer found when none expected"); 441 } 442 443 if (!holder.match(new JcaX509CertificateHolder(iCert))) 444 { 445 fail("generated holder not matching holder certificate"); 446 } 447 448 X509Certificate sCert = (X509Certificate)fact.generateCertificate(new ByteArrayInputStream(holderCertWithBaseCertificateID)); 449 450 if (holder.match(sCert)) 451 { 452 fail("principal generated holder matching wrong certificate"); 453 } 454 455 equalityAndHashCodeTest(aCert, aCert.getEncoded()); 456 } 457 performTest()458 public void performTest() 459 throws Exception 460 { 461 X509AttributeCertificateHolder aCert = new X509AttributeCertificateHolder(attrCert); 462 CertificateFactory fact = CertificateFactory.getInstance("X.509","BC"); 463 X509Certificate sCert = (X509Certificate)fact.generateCertificate(new ByteArrayInputStream(signCert)); 464 465 if (!aCert.isSignatureValid(new JcaContentVerifierProviderBuilder().setProvider(BC).build(sCert))) 466 { 467 fail("certificate signature not valid"); 468 } 469 470 // 471 // search test 472 // 473 474 List list = new ArrayList(); 475 476 list.add(sCert); 477 478 Store store = new JcaCertStore(list); 479 480 Collection certs = store.getMatches(aCert.getIssuer()); 481 if (certs.size() != 1 || !certs.contains(new JcaX509CertificateHolder(sCert))) 482 { 483 fail("sCert not found by issuer"); 484 } 485 486 Attribute[] attrs = aCert.getAttributes(new ASN1ObjectIdentifier("1.3.6.1.4.1.6760.8.1.1")); 487 if (attrs == null || attrs.length != 1) 488 { 489 fail("attribute not found"); 490 } 491 492 // 493 // reencode test 494 // 495 aCert = new X509AttributeCertificateHolder(aCert.getEncoded()); 496 497 if (!aCert.isSignatureValid(new JcaContentVerifierProviderBuilder().setProvider(BC).build(sCert))) 498 { 499 fail("certificate signature not valid"); 500 } 501 502 X509AttributeCertificateHolder saCert = new X509AttributeCertificateHolder(aCert.getEncoded()); 503 504 if (!aCert.getNotAfter().equals(saCert.getNotAfter())) 505 { 506 fail("failed date comparison"); 507 } 508 509 // base generator test 510 511 // 512 // a sample key pair. 513 // 514 RSAPublicKeySpec pubKeySpec = new RSAPublicKeySpec( 515 new BigInteger("b4a7e46170574f16a97082b22be58b6a2a629798419be12872a4bdba626cfae9900f76abfb12139dce5de56564fab2b6543165a040c606887420e33d91ed7ed7", 16), 516 new BigInteger("11", 16)); 517 518 RSAPrivateCrtKeySpec privKeySpec = RSA_PRIVATE_KEY_SPEC; 519 520 // 521 // set up the keys 522 // 523 PrivateKey privKey; 524 PublicKey pubKey; 525 526 KeyFactory kFact = KeyFactory.getInstance("RSA", "BC"); 527 528 privKey = kFact.generatePrivate(privKeySpec); 529 pubKey = kFact.generatePublic(pubKeySpec); 530 531 X509v2AttributeCertificateBuilder gen = new X509v2AttributeCertificateBuilder( 532 aCert.getHolder(), 533 aCert.getIssuer(), 534 aCert.getSerialNumber(), 535 new Date(System.currentTimeMillis() - 50000), 536 new Date(System.currentTimeMillis() + 50000)); 537 538 gen.addAttribute(attrs[0].getAttrType(), attrs[0].getAttributeValues()); 539 540 ContentSigner sigGen = new JcaContentSignerBuilder("SHA1WithRSAEncryption").setProvider(BC).build(privKey); 541 542 aCert = gen.build(sigGen); 543 544 if (!aCert.isValidOn(new Date())) 545 { 546 fail("certificate not valid"); 547 } 548 549 if (!aCert.isSignatureValid(new JcaContentVerifierProviderBuilder().setProvider(BC).build(pubKey))) 550 { 551 fail("signature not valid"); 552 } 553 554 // as the issuer is the same this should still work (even though it is not 555 // technically correct 556 557 certs = store.getMatches(aCert.getIssuer()); 558 if (certs.size() != 1 || !certs.contains(new JcaX509CertificateHolder(sCert))) 559 { 560 fail("sCert not found by issuer"); 561 } 562 563 attrs = aCert.getAttributes(new ASN1ObjectIdentifier("1.3.6.1.4.1.6760.8.1.1")); 564 if (attrs == null || attrs.length != 1) 565 { 566 fail("attribute not found"); 567 } 568 569 // 570 // reencode test 571 // 572 aCert = new X509AttributeCertificateHolder(aCert.getEncoded()); 573 574 if (!aCert.isSignatureValid(new JcaContentVerifierProviderBuilder().setProvider(BC).build(pubKey))) 575 { 576 fail("signature not valid"); 577 } 578 579 AttributeCertificateIssuer issuer = aCert.getIssuer(); 580 581 X500Name[] principals = issuer.getNames(); 582 583 // 584 // test holder 585 // 586 AttributeCertificateHolder holder = aCert.getHolder(); 587 588 if (holder.getEntityNames() == null) 589 { 590 fail("entity names not set"); 591 } 592 593 if (holder.getSerialNumber() != null) 594 { 595 fail("holder serial number set when none expected"); 596 } 597 598 if (holder.getIssuer() != null) 599 { 600 fail("holder issuer set when none expected"); 601 } 602 603 principals = holder.getEntityNames(); 604 605 // X500Principal principal0 = new X500Principal(principals[0].getEncoded()); 606 // if (!principal0.toString().equals("C=US, O=vt, OU=Class 2, OU=Virginia Tech User, CN=Markus Lorch (mlorch), EMAILADDRESS=mlorch@vt.edu")) 607 // { 608 // fail("principal[0] for entity names don't match"); 609 // } 610 611 // 612 // extension test 613 // 614 615 if (aCert.hasExtensions()) 616 { 617 fail("hasExtensions true with no extensions"); 618 } 619 620 gen.addExtension(new ASN1ObjectIdentifier("1.1"), true, new DEROctetString(new byte[10])); 621 622 gen.addExtension(new ASN1ObjectIdentifier("2.2"), false, new DEROctetString(new byte[20])); 623 624 aCert = gen.build(new JcaContentSignerBuilder("SHA1withRSA").setProvider(BC).build(privKey)); 625 626 Set exts = aCert.getCriticalExtensionOIDs(); 627 628 if (exts.size() != 1 || !exts.contains(new ASN1ObjectIdentifier("1.1"))) 629 { 630 fail("critical extension test failed"); 631 } 632 633 exts = aCert.getNonCriticalExtensionOIDs(); 634 635 if (exts.size() != 1 || !exts.contains(new ASN1ObjectIdentifier("2.2"))) 636 { 637 fail("non-critical extension test failed"); 638 } 639 640 if (aCert.getCriticalExtensionOIDs().isEmpty()) 641 { 642 fail("critical extensions not found"); 643 } 644 645 Extension ext = aCert.getExtension(new ASN1ObjectIdentifier("1.1")); 646 ASN1Encodable extValue = ext.getParsedValue(); 647 648 if (!extValue.equals(new DEROctetString(new byte[10]))) 649 { 650 fail("wrong extension value found for 1.1"); 651 } 652 653 testCertWithBaseCertificateID(); 654 testGenerateWithCert(); 655 testGenerateWithPrincipal(); 656 } 657 main( String[] args)658 public static void main( 659 String[] args) 660 { 661 Security.addProvider(new BouncyCastleProvider()); 662 663 runTest(new AttrCertTest()); 664 } 665 } 666