32636
|
1 |
/*
|
|
2 |
* Copyright (c) 2000, 2015, Oracle and/or its affiliates. All rights reserved.
|
|
3 |
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
|
4 |
*
|
|
5 |
* This code is free software; you can redistribute it and/or modify it
|
|
6 |
* under the terms of the GNU General Public License version 2 only, as
|
|
7 |
* published by the Free Software Foundation.
|
|
8 |
*
|
|
9 |
* This code is distributed in the hope that it will be useful, but WITHOUT
|
|
10 |
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
|
11 |
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
|
12 |
* version 2 for more details (a copy is included in the LICENSE file that
|
|
13 |
* accompanied this code).
|
|
14 |
*
|
|
15 |
* You should have received a copy of the GNU General Public License version
|
|
16 |
* 2 along with this work; if not, write to the Free Software Foundation,
|
|
17 |
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
|
18 |
*
|
|
19 |
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
|
20 |
* or visit www.oracle.com if you need additional information or have any
|
|
21 |
* questions.
|
|
22 |
*/
|
|
23 |
import static sun.security.x509.GeneralNameInterface.NAME_DIRECTORY;
|
|
24 |
import static sun.security.x509.NameConstraintsExtension.EXCLUDED_SUBTREES;
|
|
25 |
import static sun.security.x509.NameConstraintsExtension.PERMITTED_SUBTREES;
|
|
26 |
|
|
27 |
import java.io.ByteArrayInputStream;
|
|
28 |
import java.io.ByteArrayOutputStream;
|
|
29 |
import java.io.IOException;
|
|
30 |
import java.io.InputStream;
|
|
31 |
import java.math.BigInteger;
|
|
32 |
import java.security.GeneralSecurityException;
|
|
33 |
import java.security.KeyFactory;
|
|
34 |
import java.security.PublicKey;
|
|
35 |
import java.security.cert.CertificateException;
|
|
36 |
import java.security.cert.CertificateFactory;
|
|
37 |
import java.security.cert.X509CertSelector;
|
|
38 |
import java.security.cert.X509Certificate;
|
|
39 |
import java.security.spec.X509EncodedKeySpec;
|
|
40 |
import java.util.Base64;
|
|
41 |
import java.util.Calendar;
|
|
42 |
import java.util.Date;
|
|
43 |
import java.util.HashSet;
|
|
44 |
import java.util.Iterator;
|
|
45 |
import java.util.List;
|
|
46 |
import java.util.Set;
|
|
47 |
|
|
48 |
import sun.security.util.DerInputStream;
|
|
49 |
import sun.security.util.DerOutputStream;
|
|
50 |
import sun.security.util.DerValue;
|
|
51 |
import sun.security.util.ObjectIdentifier;
|
|
52 |
import sun.security.x509.AlgorithmId;
|
|
53 |
import sun.security.x509.AuthorityKeyIdentifierExtension;
|
|
54 |
import sun.security.x509.CertificatePoliciesExtension;
|
|
55 |
import sun.security.x509.DNSName;
|
|
56 |
import sun.security.x509.GeneralName;
|
|
57 |
import sun.security.x509.GeneralNameInterface;
|
|
58 |
import sun.security.x509.GeneralNames;
|
|
59 |
import sun.security.x509.GeneralSubtree;
|
|
60 |
import sun.security.x509.GeneralSubtrees;
|
|
61 |
import sun.security.x509.KeyIdentifier;
|
|
62 |
import sun.security.x509.NameConstraintsExtension;
|
|
63 |
import sun.security.x509.PolicyInformation;
|
|
64 |
import sun.security.x509.PrivateKeyUsageExtension;
|
|
65 |
import sun.security.x509.SubjectAlternativeNameExtension;
|
|
66 |
import sun.security.x509.X500Name;
|
|
67 |
|
|
68 |
/*
|
|
69 |
* @test
|
|
70 |
* @bug 8074931
|
|
71 |
* @summary This class tests the X509CertSelector. The tests check particular criteria
|
|
72 |
* by setting them to a value that should match our test certificate and
|
|
73 |
* ensuring that they do match, then setting them to a value that should not
|
|
74 |
* match our test certificate and ensuring that they do not match.
|
|
75 |
* @modules java.base/sun.security.x509
|
|
76 |
* java.base/sun.security.util
|
|
77 |
*/
|
|
78 |
public class X509CertSelectorTest {
|
|
79 |
/*
|
|
80 |
Certificate:
|
|
81 |
Data:
|
|
82 |
Version: 3 (0x2)
|
|
83 |
Serial Number: 954172088 (0x38df82b8)
|
|
84 |
Signature Algorithm: dsaWithSHA1
|
|
85 |
Issuer: C=us, O=sun, OU=testing
|
|
86 |
Validity
|
|
87 |
Not Before: Mar 27 15:48:08 2000 GMT
|
|
88 |
Not After : Jun 25 14:48:08 2000 GMT
|
|
89 |
Subject: C=us, O=sun, OU=testing, CN=mullan
|
|
90 |
Subject Public Key Info:
|
|
91 |
Public Key Algorithm: dsaEncryption
|
|
92 |
pub: 0
|
|
93 |
P: 0
|
|
94 |
Q: 0
|
|
95 |
G: 0
|
|
96 |
X509v3 extensions:
|
|
97 |
X509v3 Name Constraints: critical
|
|
98 |
0D.B0@.>1.0...U....us1.0
|
|
99 |
..U.
|
|
100 |
..sun1.0...U....testing1.0
|
|
101 |
..U....mullan
|
|
102 |
X509v3 Subject Key Identifier:
|
|
103 |
56:E8:88:AE:9D:B5:3F:2B:CB:A0:4C:4B:E2:87:53:07:33:77:1B:DF
|
|
104 |
X509v3 Authority Key Identifier:
|
|
105 |
keyid:8E:DD:AF:6F:EE:02:12:F4:61:E9:2F:E3:64:1A:6F:71:32:25:20:C0
|
|
106 |
|
|
107 |
X509v3 Subject Alternative Name:
|
|
108 |
email:mullan@east.sun.com
|
|
109 |
X509v3 Private Key Usage Period:
|
|
110 |
Not Before: Jan 1 05:00:00 2000 GMT, Not After: Jan 1 05:00:00 2001 GMT
|
|
111 |
X509v3 Key Usage: critical
|
|
112 |
Digital Signature
|
|
113 |
X509v3 Certificate Policies:
|
|
114 |
0$0\..*...0.0...+.......0..
|
|
115 |
Testing...
|
|
116 |
Signature Algorithm: dsaWithSHA1
|
|
117 |
r:
|
|
118 |
44:c7:35:40:5d:6c:28:75:7f:73:b2:f8:0d:72:6c:
|
|
119 |
09:65:b8:81:14
|
|
120 |
s:
|
|
121 |
76:79:f5:c7:37:3b:0d:9b:db:70:2f:20:80:36:e3:
|
|
122 |
80:e8:a6:c6:71
|
|
123 |
*/
|
|
124 |
private static final String testCert =
|
|
125 |
"-----BEGIN CERTIFICATE-----\n" +
|
|
126 |
"MIICLjCCAeygAwIBAgIEON+CuDALBgcqhkjOOAQDBQAwLTELMAkGA1UEBhMCdXMx\n" +
|
|
127 |
"DDAKBgNVBAoTA3N1bjEQMA4GA1UECxMHdGVzdGluZzAeFw0wMDAzMjcxNTQ4MDha\n" +
|
|
128 |
"Fw0wMDA2MjUxNDQ4MDhaMD4xCzAJBgNVBAYTAnVzMQwwCgYDVQQKEwNzdW4xEDAO\n" +
|
|
129 |
"BgNVBAsTB3Rlc3RpbmcxDzANBgNVBAMTBm11bGxhbjAcMBQGByqGSM44BAEwCQIB\n" +
|
|
130 |
"AAIBAAIBAAMEAAIBAKOCASMwggEfMFAGA1UdHgEB/wRGMESgQjBApD4xCzAJBgNV\n" +
|
|
131 |
"BAYTAnVzMQwwCgYDVQQKEwNzdW4xEDAOBgNVBAsTB3Rlc3RpbmcxDzANBgNVBAMT\n" +
|
|
132 |
"Bm11bGxhbjAdBgNVHQ4EFgQUVuiIrp21PyvLoExL4odTBzN3G98wHwYDVR0jBBgw\n" +
|
|
133 |
"FoAUjt2vb+4CEvRh6S/jZBpvcTIlIMAwHgYDVR0RBBcwFYETbXVsbGFuQGVhc3Qu\n" +
|
|
134 |
"c3VuLmNvbTArBgNVHRAEJDAigA8yMDAwMDEwMTA1MDAwMFqBDzIwMDEwMTAxMDUw\n" +
|
|
135 |
"MDAwWjAPBgNVHQ8BAf8EBQMDB4AAMC0GA1UdIAQmMCQwIgYEKoSAADAaMBgGCCsG\n" +
|
|
136 |
"AQUFBwICMAwSClRlc3RpbmcuLi4wCwYHKoZIzjgEAwUAAy8AMCwCFETHNUBdbCh1\n" +
|
|
137 |
"f3Oy+A1ybAlluIEUAhR2efXHNzsNm9twLyCANuOA6KbGcQ==\n" +
|
|
138 |
"-----END CERTIFICATE-----\n" +
|
|
139 |
"";
|
|
140 |
|
|
141 |
private static final String testKey =
|
|
142 |
"MIIBtjCCASsGByqGSM44BAEwggEeAoGBAIVWPEkcxbxhQRCqVzg55tNqbP5j0K4kdu4bkmXvfqC5\n" +
|
|
143 |
"+qA75DvnfzsOJseb+9AuKXWk/DvCzFDmrY1YaU3scZC3OQEO9lEO3F4VDKOaudY6OT1SI22pAIwz\n" +
|
|
144 |
"j5pvq+i7zOp4xUqkQUeh/4iQSfxOT5UrFGjkcbnbpVkCXD/GxAz7AhUAjtnm3dVIddUUHl6wxpZ7\n" +
|
|
145 |
"GcA6gSsCgYAf/PXzQtemgIDjpFrNNSgTEKkLposBXKatAM+gUKlMUjf8SQvquqPxDtRrscGjXkoL\n" +
|
|
146 |
"oTkaR7/akULYFpBvUcFkeIFiCnJg8M9XhCWdLvn9MPt+jR2oxookvCb9xLtD6WvIM/wd/nZ1iK4u\n" +
|
|
147 |
"iY1+q85xvns/Awbtwl7oZDAwE2TUKAOBhAACgYBDc9UZ+3xsZubUZvRG5cpyJceYpJp2exOPVJXn\n" +
|
|
148 |
"jR4CcR+cT9bAJpFSxqE/8KtNHXxHdu4f3DU67IMOVDpugzihyzXJvNm3w2H9x+6xczHG2wjvAJeh\n" +
|
|
149 |
"X62EWbUatxPXFAoVKZWuUbaYaZzdWBDtNRrCuKKsLo0GFy8g2BZISuD3jw==\n" +
|
|
150 |
"";
|
|
151 |
|
|
152 |
// Certificate to run tests on
|
|
153 |
private final X509Certificate cert;
|
|
154 |
|
|
155 |
public static void main(String[] args) throws Exception {
|
|
156 |
X509CertSelectorTest test = new X509CertSelectorTest();
|
|
157 |
test.doTest();
|
|
158 |
}
|
|
159 |
|
|
160 |
public X509CertSelectorTest() throws CertificateException, IOException {
|
|
161 |
cert = (X509Certificate) CertificateFactory.getInstance("X.509")
|
|
162 |
.generateCertificate(new ByteArrayInputStream(testCert.getBytes()));
|
|
163 |
}
|
|
164 |
|
|
165 |
// Runs the test.
|
|
166 |
private void doTest() throws Exception {
|
|
167 |
System.out.println("START OF TESTS FOR " + "X509CertSelector");
|
|
168 |
|
|
169 |
testSerialNumber();
|
|
170 |
testIssuer();
|
|
171 |
testSubjectKeyIdentifier();
|
|
172 |
testAuthorityKeyIdentifier();
|
|
173 |
testCertificateValid();
|
|
174 |
testPrivateKeyValid();
|
|
175 |
testSubjectPublicKeyAlgID();
|
|
176 |
testKeyUsage();
|
|
177 |
testSubjectAltName();
|
|
178 |
testPolicy();
|
|
179 |
testPathToName();
|
|
180 |
testSubject();
|
|
181 |
testSubjectPublicKey();
|
|
182 |
testNameConstraints();
|
|
183 |
testBasicConstraints();
|
|
184 |
testCertificate();
|
|
185 |
}
|
|
186 |
|
|
187 |
// Tests matching on the serial number contained in the certificate.
|
|
188 |
private void testSerialNumber() {
|
|
189 |
System.out.println("X.509 Certificate Match on serialNumber");
|
|
190 |
// bad match
|
|
191 |
X509CertSelector selector = new X509CertSelector();
|
|
192 |
selector.setSerialNumber(new BigInteger("999999999"));
|
|
193 |
checkMatch(selector, cert, false);
|
|
194 |
|
|
195 |
// good match
|
|
196 |
selector.setSerialNumber(cert.getSerialNumber());
|
|
197 |
checkMatch(selector, cert, true);
|
|
198 |
}
|
|
199 |
|
|
200 |
// Tests matching on the issuer name contained in the certificate.
|
|
201 |
private void testIssuer() throws IOException {
|
|
202 |
System.out.println("X.509 Certificate Match on issuer");
|
|
203 |
// bad match
|
|
204 |
X509CertSelector selector = new X509CertSelector();
|
|
205 |
selector.setIssuer("ou=bogus,ou=east,o=sun,c=us");
|
|
206 |
checkMatch(selector, cert, false);
|
|
207 |
|
|
208 |
// good match
|
|
209 |
selector.setIssuer((cert.getIssuerX500Principal()).getName("RFC2253"));
|
|
210 |
checkMatch(selector, cert, true);
|
|
211 |
}
|
|
212 |
|
|
213 |
/*
|
|
214 |
* Tests matching on the subject key identifier contained in the
|
|
215 |
* certificate.
|
|
216 |
*/
|
|
217 |
private void testSubjectKeyIdentifier() throws IOException {
|
|
218 |
System.out.println("X.509 Certificate Match on subjectKeyIdentifier");
|
|
219 |
// bad match
|
|
220 |
X509CertSelector selector = new X509CertSelector();
|
|
221 |
byte[] b = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
|
|
222 |
selector.setSubjectKeyIdentifier(b);
|
|
223 |
checkMatch(selector, cert, false);
|
|
224 |
|
|
225 |
// good match
|
|
226 |
DerInputStream in = new DerInputStream(cert.getExtensionValue("2.5.29.14"));
|
|
227 |
byte[] encoded = in.getOctetString();
|
|
228 |
selector.setSubjectKeyIdentifier(encoded);
|
|
229 |
checkMatch(selector, cert, true);
|
|
230 |
}
|
|
231 |
|
|
232 |
/*
|
|
233 |
* Tests matching on the authority key identifier contained in the
|
|
234 |
* certificate.
|
|
235 |
*/
|
|
236 |
private void testAuthorityKeyIdentifier() throws IOException {
|
|
237 |
System.out.println("X.509 Certificate Match on authorityKeyIdentifier");
|
|
238 |
// bad match
|
|
239 |
X509CertSelector selector = new X509CertSelector();
|
|
240 |
byte[] b = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
|
|
241 |
AuthorityKeyIdentifierExtension a = new AuthorityKeyIdentifierExtension(new KeyIdentifier(b), null, null);
|
|
242 |
selector.setAuthorityKeyIdentifier(a.getExtensionValue());
|
|
243 |
checkMatch(selector, cert, false);
|
|
244 |
|
|
245 |
// good match
|
|
246 |
DerInputStream in = new DerInputStream(cert.getExtensionValue("2.5.29.35"));
|
|
247 |
byte[] encoded = in.getOctetString();
|
|
248 |
selector.setAuthorityKeyIdentifier(encoded);
|
|
249 |
checkMatch(selector, cert, true);
|
|
250 |
}
|
|
251 |
|
|
252 |
/*
|
|
253 |
* Tests matching on the certificate validity component contained in the
|
|
254 |
* certificate.
|
|
255 |
*/
|
|
256 |
private void testCertificateValid() {
|
|
257 |
System.out.println("X.509 Certificate Match on certificateValid");
|
|
258 |
// bad match
|
|
259 |
X509CertSelector selector = new X509CertSelector();
|
|
260 |
Calendar cal = Calendar.getInstance();
|
|
261 |
cal.set(1968, 12, 31);
|
|
262 |
selector.setCertificateValid(cal.getTime());
|
|
263 |
checkMatch(selector, cert, false);
|
|
264 |
|
|
265 |
// good match
|
|
266 |
selector.setCertificateValid(cert.getNotBefore());
|
|
267 |
checkMatch(selector, cert, true);
|
|
268 |
}
|
|
269 |
|
|
270 |
/*
|
|
271 |
* Tests matching on the private key validity component contained in the
|
|
272 |
* certificate.
|
|
273 |
*/
|
|
274 |
private void testPrivateKeyValid() throws IOException, CertificateException {
|
|
275 |
System.out.println("X.509 Certificate Match on privateKeyValid");
|
|
276 |
// bad match
|
|
277 |
X509CertSelector selector = new X509CertSelector();
|
|
278 |
Calendar cal = Calendar.getInstance();
|
|
279 |
cal.set(1968, 12, 31);
|
|
280 |
selector.setPrivateKeyValid(cal.getTime());
|
|
281 |
checkMatch(selector, cert, false);
|
|
282 |
|
|
283 |
// good match
|
|
284 |
DerInputStream in = new DerInputStream(cert.getExtensionValue("2.5.29.16"));
|
|
285 |
byte[] encoded = in.getOctetString();
|
|
286 |
PrivateKeyUsageExtension ext = new PrivateKeyUsageExtension(false, encoded);
|
|
287 |
Date validDate = (Date) ext.get(PrivateKeyUsageExtension.NOT_BEFORE);
|
|
288 |
selector.setPrivateKeyValid(validDate);
|
|
289 |
checkMatch(selector, cert, true);
|
|
290 |
|
|
291 |
}
|
|
292 |
|
|
293 |
private ObjectIdentifier getCertPubKeyAlgOID(X509Certificate xcert) throws IOException {
|
|
294 |
byte[] encodedKey = xcert.getPublicKey().getEncoded();
|
|
295 |
DerValue val = new DerValue(encodedKey);
|
|
296 |
if (val.tag != DerValue.tag_Sequence) {
|
|
297 |
throw new RuntimeException("invalid key format");
|
|
298 |
}
|
|
299 |
|
|
300 |
return AlgorithmId.parse(val.data.getDerValue()).getOID();
|
|
301 |
}
|
|
302 |
|
|
303 |
/*
|
|
304 |
* Tests matching on the subject public key algorithm ID component contained
|
|
305 |
* in the certificate.
|
|
306 |
*/
|
|
307 |
private void testSubjectPublicKeyAlgID() throws IOException {
|
|
308 |
System.out.println("X.509 Certificate Match on subjectPublicKeyAlgID");
|
|
309 |
// bad match
|
|
310 |
X509CertSelector selector = new X509CertSelector();
|
|
311 |
selector.setSubjectPublicKeyAlgID("2.5.29.14");
|
|
312 |
checkMatch(selector, cert, false);
|
|
313 |
|
|
314 |
// good match
|
|
315 |
selector.setSubjectPublicKeyAlgID(getCertPubKeyAlgOID(cert).toString());
|
|
316 |
checkMatch(selector, cert, true);
|
|
317 |
|
|
318 |
}
|
|
319 |
|
|
320 |
// Tests matching on the key usage extension contained in the certificate.
|
|
321 |
private void testKeyUsage() {
|
|
322 |
System.out.println("X.509 Certificate Match on keyUsage");
|
|
323 |
// bad match
|
|
324 |
X509CertSelector selector = new X509CertSelector();
|
|
325 |
boolean[] keyUsage = { true, false, true, false, true, false, true, false };
|
|
326 |
selector.setKeyUsage(keyUsage);
|
|
327 |
System.out.println("Selector = " + selector.toString());
|
|
328 |
checkMatch(selector, cert, false);
|
|
329 |
|
|
330 |
// good match
|
|
331 |
selector.setKeyUsage(cert.getKeyUsage());
|
|
332 |
System.out.println("Selector = " + selector.toString());
|
|
333 |
checkMatch(selector, cert, true);
|
|
334 |
}
|
|
335 |
|
|
336 |
/*
|
|
337 |
* Tests matching on the subject alternative name extension contained in the
|
|
338 |
* certificate.
|
|
339 |
*/
|
|
340 |
private void testSubjectAltName() throws IOException {
|
|
341 |
System.out.println("X.509 Certificate Match on subjectAltName");
|
|
342 |
// bad match
|
|
343 |
X509CertSelector selector = new X509CertSelector();
|
|
344 |
GeneralNameInterface dnsName = new DNSName("foo.com");
|
|
345 |
DerOutputStream tmp = new DerOutputStream();
|
|
346 |
dnsName.encode(tmp);
|
|
347 |
selector.addSubjectAlternativeName(2, tmp.toByteArray());
|
|
348 |
checkMatch(selector, cert, false);
|
|
349 |
|
|
350 |
// good match
|
|
351 |
DerInputStream in = new DerInputStream(cert.getExtensionValue("2.5.29.17"));
|
|
352 |
byte[] encoded = in.getOctetString();
|
|
353 |
SubjectAlternativeNameExtension ext = new SubjectAlternativeNameExtension(false, encoded);
|
|
354 |
GeneralNames names = (GeneralNames) ext.get(SubjectAlternativeNameExtension.SUBJECT_NAME);
|
|
355 |
GeneralName name = (GeneralName) names.get(0);
|
|
356 |
selector.setSubjectAlternativeNames(null);
|
|
357 |
DerOutputStream tmp2 = new DerOutputStream();
|
|
358 |
name.getName().encode(tmp2);
|
|
359 |
selector.addSubjectAlternativeName(name.getType(), tmp2.toByteArray());
|
|
360 |
checkMatch(selector, cert, true);
|
|
361 |
|
|
362 |
// good match 2 (matches at least one)
|
|
363 |
selector.setMatchAllSubjectAltNames(false);
|
|
364 |
selector.addSubjectAlternativeName(2, "foo.com");
|
|
365 |
checkMatch(selector, cert, true);
|
|
366 |
}
|
|
367 |
|
|
368 |
/*
|
|
369 |
* Tests matching on the policy constraints extension contained in the
|
|
370 |
* certificate.
|
|
371 |
*/
|
|
372 |
private void testPolicy() throws IOException {
|
|
373 |
System.out.println("X.509 Certificate Match on certificatePolicies");
|
|
374 |
// test encoding of CertificatePoliciesExtension because we wrote the
|
|
375 |
// code
|
|
376 |
// bad match
|
|
377 |
X509CertSelector selector = new X509CertSelector();
|
|
378 |
Set<String> s = new HashSet<>();
|
|
379 |
s.add(new String("1.2.5.7.68"));
|
|
380 |
selector.setPolicy(s);
|
|
381 |
checkMatch(selector, cert, false);
|
|
382 |
|
|
383 |
// good match
|
|
384 |
DerInputStream in = new DerInputStream(cert.getExtensionValue("2.5.29.32"));
|
|
385 |
CertificatePoliciesExtension ext = new CertificatePoliciesExtension(false, in.getOctetString());
|
|
386 |
List<PolicyInformation> policies = ext.get(CertificatePoliciesExtension.POLICIES);
|
|
387 |
// match on the first policy id
|
|
388 |
PolicyInformation policyInfo = (PolicyInformation) policies.get(0);
|
|
389 |
s.clear();
|
|
390 |
s.add(policyInfo.getPolicyIdentifier().getIdentifier().toString());
|
|
391 |
selector.setPolicy(s);
|
|
392 |
checkMatch(selector, cert, true);
|
|
393 |
}
|
|
394 |
|
|
395 |
/*
|
|
396 |
* Tests matching on the name constraints extension contained in the
|
|
397 |
* certificate.
|
|
398 |
*/
|
|
399 |
private void testPathToName() throws IOException {
|
|
400 |
System.out.println("X.509 Certificate Match on pathToName");
|
|
401 |
|
|
402 |
X509CertSelector selector = null;
|
|
403 |
DerInputStream in = new DerInputStream(cert.getExtensionValue("2.5.29.30"));
|
|
404 |
byte[] encoded = in.getOctetString();
|
|
405 |
NameConstraintsExtension ext = new NameConstraintsExtension(false, encoded);
|
|
406 |
GeneralSubtrees permitted = (GeneralSubtrees) ext.get(PERMITTED_SUBTREES);
|
|
407 |
GeneralSubtrees excluded = (GeneralSubtrees) ext.get(EXCLUDED_SUBTREES);
|
|
408 |
|
|
409 |
// bad matches on pathToName within excluded subtrees
|
|
410 |
if (excluded != null) {
|
|
411 |
Iterator<GeneralSubtree> e = excluded.iterator();
|
|
412 |
while (e.hasNext()) {
|
|
413 |
GeneralSubtree tree = e.next();
|
|
414 |
if (tree.getName().getType() == NAME_DIRECTORY) {
|
|
415 |
X500Name excludedDN1 = new X500Name(tree.getName().toString());
|
|
416 |
X500Name excludedDN2 = new X500Name("CN=Bogus, " + tree.getName().toString());
|
|
417 |
DerOutputStream derDN1 = new DerOutputStream();
|
|
418 |
DerOutputStream derDN2 = new DerOutputStream();
|
|
419 |
excludedDN1.encode(derDN1);
|
|
420 |
excludedDN2.encode(derDN2);
|
|
421 |
selector = new X509CertSelector();
|
|
422 |
selector.addPathToName(NAME_DIRECTORY, derDN1.toByteArray());
|
|
423 |
checkMatch(selector, cert, false);
|
|
424 |
selector.setPathToNames(null);
|
|
425 |
selector.addPathToName(NAME_DIRECTORY, derDN2.toByteArray());
|
|
426 |
checkMatch(selector, cert, false);
|
|
427 |
}
|
|
428 |
}
|
|
429 |
}
|
|
430 |
|
|
431 |
// good matches on pathToName within permitted subtrees
|
|
432 |
if (permitted != null) {
|
|
433 |
Iterator<GeneralSubtree> e = permitted.iterator();
|
|
434 |
while (e.hasNext()) {
|
|
435 |
GeneralSubtree tree = e.next();
|
|
436 |
if (tree.getName().getType() == NAME_DIRECTORY) {
|
|
437 |
X500Name permittedDN1 = new X500Name(tree.getName().toString());
|
|
438 |
X500Name permittedDN2 = new X500Name("CN=good, " + tree.getName().toString());
|
|
439 |
DerOutputStream derDN1 = new DerOutputStream();
|
|
440 |
DerOutputStream derDN2 = new DerOutputStream();
|
|
441 |
permittedDN1.encode(derDN1);
|
|
442 |
permittedDN2.encode(derDN2);
|
|
443 |
selector = new X509CertSelector();
|
|
444 |
selector.addPathToName(NAME_DIRECTORY, derDN1.toByteArray());
|
|
445 |
checkMatch(selector, cert, true);
|
|
446 |
selector.setPathToNames(null);
|
|
447 |
selector.addPathToName(NAME_DIRECTORY, derDN2.toByteArray());
|
|
448 |
checkMatch(selector, cert, true);
|
|
449 |
}
|
|
450 |
}
|
|
451 |
}
|
|
452 |
}
|
|
453 |
|
|
454 |
// Tests matching on the subject name contained in the certificate.
|
|
455 |
private void testSubject() throws IOException {
|
|
456 |
System.out.println("X.509 Certificate Match on subject");
|
|
457 |
// bad match
|
|
458 |
X509CertSelector selector = new X509CertSelector();
|
|
459 |
selector.setSubject("ou=bogus,ou=east,o=sun,c=us");
|
|
460 |
checkMatch(selector, cert, false);
|
|
461 |
|
|
462 |
// good match
|
|
463 |
selector.setSubject(cert.getSubjectX500Principal().getName("RFC2253"));
|
|
464 |
checkMatch(selector, cert, true);
|
|
465 |
}
|
|
466 |
|
|
467 |
// Tests matching on the subject public key contained in the certificate.
|
|
468 |
private void testSubjectPublicKey() throws IOException, GeneralSecurityException {
|
|
469 |
System.out.println("X.509 Certificate Match on subject public key");
|
|
470 |
// bad match
|
|
471 |
X509CertSelector selector = new X509CertSelector();
|
|
472 |
X509EncodedKeySpec keySpec = new X509EncodedKeySpec(
|
|
473 |
Base64.getMimeDecoder().decode(testKey.getBytes()));
|
|
474 |
KeyFactory keyFactory = KeyFactory.getInstance("DSA");
|
|
475 |
PublicKey pubKey = keyFactory.generatePublic(keySpec);
|
|
476 |
selector.setSubjectPublicKey(pubKey);
|
|
477 |
checkMatch(selector, cert, false);
|
|
478 |
|
|
479 |
// good match
|
|
480 |
selector.setSubjectPublicKey(cert.getPublicKey());
|
|
481 |
checkMatch(selector, cert, true);
|
|
482 |
}
|
|
483 |
|
|
484 |
// Tests matching on the name constraints contained in the certificate.
|
|
485 |
private void testNameConstraints() throws IOException {
|
|
486 |
System.out.println("X.509 Certificate Match on name constraints");
|
|
487 |
// bad match
|
|
488 |
GeneralSubtrees subjectTree = new GeneralSubtrees();
|
|
489 |
subjectTree.add(getGeneralSubtree((X500Name) cert.getSubjectDN()));
|
|
490 |
NameConstraintsExtension ext = new NameConstraintsExtension((GeneralSubtrees) null, subjectTree);
|
|
491 |
X509CertSelector selector = new X509CertSelector();
|
|
492 |
selector.setNameConstraints(ext.getExtensionValue());
|
|
493 |
checkMatch(selector, cert, false);
|
|
494 |
|
|
495 |
// good match
|
|
496 |
ext = new NameConstraintsExtension(subjectTree, null);
|
|
497 |
selector.setNameConstraints(ext.getExtensionValue());
|
|
498 |
checkMatch(selector, cert, true);
|
|
499 |
}
|
|
500 |
|
|
501 |
// Tests matching on basic constraints.
|
|
502 |
private void testBasicConstraints() {
|
|
503 |
System.out.println("X.509 Certificate Match on basic constraints");
|
|
504 |
// bad match
|
|
505 |
X509CertSelector selector = new X509CertSelector();
|
|
506 |
int mpl = cert.getBasicConstraints();
|
|
507 |
selector.setBasicConstraints(0);
|
|
508 |
checkMatch(selector, cert, false);
|
|
509 |
|
|
510 |
// good match
|
|
511 |
selector.setBasicConstraints(mpl);
|
|
512 |
checkMatch(selector, cert, true);
|
|
513 |
}
|
|
514 |
|
|
515 |
// Tests certificateEquals criterion
|
|
516 |
private void testCertificate() {
|
|
517 |
System.out.println("X.509 Certificate Match on certificateEquals criterion");
|
|
518 |
|
|
519 |
X509CertSelector selector = new X509CertSelector();
|
|
520 |
// good match
|
|
521 |
selector.setCertificate(cert);
|
|
522 |
checkMatch(selector, cert, true);
|
|
523 |
}
|
|
524 |
|
|
525 |
private void checkMatch(X509CertSelector selector, X509Certificate cert, boolean match) {
|
|
526 |
boolean result = selector.match(cert);
|
|
527 |
if (match != result)
|
|
528 |
throw new RuntimeException(selector + " match " + cert + " is " + result + ", but expect " + match);
|
|
529 |
}
|
|
530 |
|
|
531 |
private static GeneralSubtree getGeneralSubtree(GeneralNameInterface gni) {
|
|
532 |
// Create a new GeneralSubtree with the specified name, 0 base, and
|
|
533 |
// unlimited length
|
|
534 |
GeneralName gn = new GeneralName(gni);
|
|
535 |
GeneralSubtree subTree = new GeneralSubtree(gn, 0, -1);
|
|
536 |
return subTree;
|
|
537 |
}
|
|
538 |
}
|