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