Path: blob/aarch64-shenandoah-jdk8u272-b10/jdk/test/java/security/cert/X509CertSelectorTest.java
47279 views
/*1* Copyright (c) 2000, 2016, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation.7*8* This code is distributed in the hope that it will be useful, but WITHOUT9* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or10* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License11* version 2 for more details (a copy is included in the LICENSE file that12* accompanied this code).13*14* You should have received a copy of the GNU General Public License version15* 2 along with this work; if not, write to the Free Software Foundation,16* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.17*18* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA19* or visit www.oracle.com if you need additional information or have any20* questions.21*/22import static sun.security.x509.GeneralNameInterface.NAME_DIRECTORY;23import static sun.security.x509.NameConstraintsExtension.EXCLUDED_SUBTREES;24import static sun.security.x509.NameConstraintsExtension.PERMITTED_SUBTREES;2526import java.io.ByteArrayInputStream;27import java.io.ByteArrayOutputStream;28import java.io.IOException;29import java.io.InputStream;30import java.math.BigInteger;31import java.security.GeneralSecurityException;32import java.security.KeyFactory;33import java.security.PublicKey;34import java.security.cert.CertificateException;35import java.security.cert.CertificateFactory;36import java.security.cert.X509CertSelector;37import java.security.cert.X509Certificate;38import java.security.spec.X509EncodedKeySpec;39import java.util.Base64;40import java.util.Calendar;41import java.util.Date;42import java.util.HashSet;43import java.util.Iterator;44import java.util.List;45import java.util.Set;4647import sun.security.util.DerInputStream;48import sun.security.util.DerOutputStream;49import sun.security.util.DerValue;50import sun.security.util.ObjectIdentifier;51import sun.security.x509.AlgorithmId;52import sun.security.x509.AuthorityKeyIdentifierExtension;53import sun.security.x509.CertificatePoliciesExtension;54import sun.security.x509.DNSName;55import sun.security.x509.GeneralName;56import sun.security.x509.GeneralNameInterface;57import sun.security.x509.GeneralNames;58import sun.security.x509.GeneralSubtree;59import sun.security.x509.GeneralSubtrees;60import sun.security.x509.KeyIdentifier;61import sun.security.x509.NameConstraintsExtension;62import sun.security.x509.PolicyInformation;63import sun.security.x509.PrivateKeyUsageExtension;64import sun.security.x509.SubjectAlternativeNameExtension;65import sun.security.x509.X500Name;6667/*68* @test69* @bug 807493170* @summary This class tests the X509CertSelector. The tests check particular criteria71* by setting them to a value that should match our test certificate and72* ensuring that they do match, then setting them to a value that should not73* match our test certificate and ensuring that they do not match.74*/75public class X509CertSelectorTest {76/*77Certificate:78Data:79Version: 3 (0x2)80Serial Number: 954172088 (0x38df82b8)81Signature Algorithm: dsaWithSHA182Issuer: C=us, O=sun, OU=testing83Validity84Not Before: Mar 27 15:48:08 2000 GMT85Not After : Jun 25 14:48:08 2000 GMT86Subject: C=us, O=sun, OU=testing, CN=mullan87Subject Public Key Info:88Public Key Algorithm: dsaEncryption89pub: 090P: 091Q: 092G: 093X509v3 extensions:94X509v3 Name Constraints: critical950D.B0@.>1.0...U....us1.096..U.97..sun1.0...U....testing1.098..U....mullan99X509v3 Subject Key Identifier:10056:E8:88:AE:9D:B5:3F:2B:CB:A0:4C:4B:E2:87:53:07:33:77:1B:DF101X509v3 Authority Key Identifier:102keyid:8E:DD:AF:6F:EE:02:12:F4:61:E9:2F:E3:64:1A:6F:71:32:25:20:C0103104X509v3 Subject Alternative Name:105email:[email protected]106X509v3 Private Key Usage Period:107Not Before: Jan 1 05:00:00 2000 GMT, Not After: Jan 1 05:00:00 2001 GMT108X509v3 Key Usage: critical109Digital Signature110X509v3 Certificate Policies:1110$0\..*...0.0...+.......0..112Testing...113Signature Algorithm: dsaWithSHA1114r:11544:c7:35:40:5d:6c:28:75:7f:73:b2:f8:0d:72:6c:11609:65:b8:81:14117s:11876:79:f5:c7:37:3b:0d:9b:db:70:2f:20:80:36:e3:11980:e8:a6:c6:71120*/121private static final String testCert =122"-----BEGIN CERTIFICATE-----\n" +123"MIICLjCCAeygAwIBAgIEON+CuDALBgcqhkjOOAQDBQAwLTELMAkGA1UEBhMCdXMx\n" +124"DDAKBgNVBAoTA3N1bjEQMA4GA1UECxMHdGVzdGluZzAeFw0wMDAzMjcxNTQ4MDha\n" +125"Fw0wMDA2MjUxNDQ4MDhaMD4xCzAJBgNVBAYTAnVzMQwwCgYDVQQKEwNzdW4xEDAO\n" +126"BgNVBAsTB3Rlc3RpbmcxDzANBgNVBAMTBm11bGxhbjAcMBQGByqGSM44BAEwCQIB\n" +127"AAIBAAIBAAMEAAIBAKOCASMwggEfMFAGA1UdHgEB/wRGMESgQjBApD4xCzAJBgNV\n" +128"BAYTAnVzMQwwCgYDVQQKEwNzdW4xEDAOBgNVBAsTB3Rlc3RpbmcxDzANBgNVBAMT\n" +129"Bm11bGxhbjAdBgNVHQ4EFgQUVuiIrp21PyvLoExL4odTBzN3G98wHwYDVR0jBBgw\n" +130"FoAUjt2vb+4CEvRh6S/jZBpvcTIlIMAwHgYDVR0RBBcwFYETbXVsbGFuQGVhc3Qu\n" +131"c3VuLmNvbTArBgNVHRAEJDAigA8yMDAwMDEwMTA1MDAwMFqBDzIwMDEwMTAxMDUw\n" +132"MDAwWjAPBgNVHQ8BAf8EBQMDB4AAMC0GA1UdIAQmMCQwIgYEKoSAADAaMBgGCCsG\n" +133"AQUFBwICMAwSClRlc3RpbmcuLi4wCwYHKoZIzjgEAwUAAy8AMCwCFETHNUBdbCh1\n" +134"f3Oy+A1ybAlluIEUAhR2efXHNzsNm9twLyCANuOA6KbGcQ==\n" +135"-----END CERTIFICATE-----\n" +136"";137138private static final String testKey =139"MIIBtjCCASsGByqGSM44BAEwggEeAoGBAIVWPEkcxbxhQRCqVzg55tNqbP5j0K4kdu4bkmXvfqC5\n" +140"+qA75DvnfzsOJseb+9AuKXWk/DvCzFDmrY1YaU3scZC3OQEO9lEO3F4VDKOaudY6OT1SI22pAIwz\n" +141"j5pvq+i7zOp4xUqkQUeh/4iQSfxOT5UrFGjkcbnbpVkCXD/GxAz7AhUAjtnm3dVIddUUHl6wxpZ7\n" +142"GcA6gSsCgYAf/PXzQtemgIDjpFrNNSgTEKkLposBXKatAM+gUKlMUjf8SQvquqPxDtRrscGjXkoL\n" +143"oTkaR7/akULYFpBvUcFkeIFiCnJg8M9XhCWdLvn9MPt+jR2oxookvCb9xLtD6WvIM/wd/nZ1iK4u\n" +144"iY1+q85xvns/Awbtwl7oZDAwE2TUKAOBhAACgYBDc9UZ+3xsZubUZvRG5cpyJceYpJp2exOPVJXn\n" +145"jR4CcR+cT9bAJpFSxqE/8KtNHXxHdu4f3DU67IMOVDpugzihyzXJvNm3w2H9x+6xczHG2wjvAJeh\n" +146"X62EWbUatxPXFAoVKZWuUbaYaZzdWBDtNRrCuKKsLo0GFy8g2BZISuD3jw==\n" +147"";148149// Certificate to run tests on150private final X509Certificate cert;151152public static void main(String[] args) throws Exception {153X509CertSelectorTest test = new X509CertSelectorTest();154test.doTest();155}156157public X509CertSelectorTest() throws CertificateException, IOException {158cert = (X509Certificate) CertificateFactory.getInstance("X.509")159.generateCertificate(new ByteArrayInputStream(testCert.getBytes()));160}161162// Runs the test.163private void doTest() throws Exception {164System.out.println("START OF TESTS FOR " + "X509CertSelector");165166testSerialNumber();167testIssuer();168testSubjectKeyIdentifier();169testAuthorityKeyIdentifier();170testCertificateValid();171testPrivateKeyValid();172testSubjectPublicKeyAlgID();173testKeyUsage();174testSubjectAltName();175testPolicy();176testPathToName();177testSubject();178testSubjectPublicKey();179testNameConstraints();180testBasicConstraints();181testCertificate();182}183184// Tests matching on the serial number contained in the certificate.185private void testSerialNumber() {186System.out.println("X.509 Certificate Match on serialNumber");187// bad match188X509CertSelector selector = new X509CertSelector();189selector.setSerialNumber(new BigInteger("999999999"));190checkMatch(selector, cert, false);191192// good match193selector.setSerialNumber(cert.getSerialNumber());194checkMatch(selector, cert, true);195}196197// Tests matching on the issuer name contained in the certificate.198private void testIssuer() throws IOException {199System.out.println("X.509 Certificate Match on issuer");200// bad match201X509CertSelector selector = new X509CertSelector();202selector.setIssuer("ou=bogus,ou=east,o=sun,c=us");203checkMatch(selector, cert, false);204205// good match206selector.setIssuer((cert.getIssuerX500Principal()).getName("RFC2253"));207checkMatch(selector, cert, true);208}209210/*211* Tests matching on the subject key identifier contained in the212* certificate.213*/214private void testSubjectKeyIdentifier() throws IOException {215System.out.println("X.509 Certificate Match on subjectKeyIdentifier");216// bad match217X509CertSelector selector = new X509CertSelector();218byte[] b = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };219selector.setSubjectKeyIdentifier(b);220checkMatch(selector, cert, false);221222// good match223DerInputStream in = new DerInputStream(cert.getExtensionValue("2.5.29.14"));224byte[] encoded = in.getOctetString();225selector.setSubjectKeyIdentifier(encoded);226checkMatch(selector, cert, true);227}228229/*230* Tests matching on the authority key identifier contained in the231* certificate.232*/233private void testAuthorityKeyIdentifier() throws IOException {234System.out.println("X.509 Certificate Match on authorityKeyIdentifier");235// bad match236X509CertSelector selector = new X509CertSelector();237byte[] b = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };238AuthorityKeyIdentifierExtension a = new AuthorityKeyIdentifierExtension(new KeyIdentifier(b), null, null);239selector.setAuthorityKeyIdentifier(a.getExtensionValue());240checkMatch(selector, cert, false);241242// good match243DerInputStream in = new DerInputStream(cert.getExtensionValue("2.5.29.35"));244byte[] encoded = in.getOctetString();245selector.setAuthorityKeyIdentifier(encoded);246checkMatch(selector, cert, true);247}248249/*250* Tests matching on the certificate validity component contained in the251* certificate.252*/253private void testCertificateValid() {254System.out.println("X.509 Certificate Match on certificateValid");255// bad match256X509CertSelector selector = new X509CertSelector();257Calendar cal = Calendar.getInstance();258cal.set(1968, 12, 31);259selector.setCertificateValid(cal.getTime());260checkMatch(selector, cert, false);261262// good match263selector.setCertificateValid(cert.getNotBefore());264checkMatch(selector, cert, true);265}266267/*268* Tests matching on the private key validity component contained in the269* certificate.270*/271private void testPrivateKeyValid() throws IOException, CertificateException {272System.out.println("X.509 Certificate Match on privateKeyValid");273// bad match274X509CertSelector selector = new X509CertSelector();275Calendar cal = Calendar.getInstance();276cal.set(1968, 12, 31);277selector.setPrivateKeyValid(cal.getTime());278checkMatch(selector, cert, false);279280// good match281DerInputStream in = new DerInputStream(cert.getExtensionValue("2.5.29.16"));282byte[] encoded = in.getOctetString();283PrivateKeyUsageExtension ext = new PrivateKeyUsageExtension(false, encoded);284Date validDate = (Date) ext.get(PrivateKeyUsageExtension.NOT_BEFORE);285selector.setPrivateKeyValid(validDate);286checkMatch(selector, cert, true);287288}289290private ObjectIdentifier getCertPubKeyAlgOID(X509Certificate xcert) throws IOException {291byte[] encodedKey = xcert.getPublicKey().getEncoded();292DerValue val = new DerValue(encodedKey);293if (val.tag != DerValue.tag_Sequence) {294throw new RuntimeException("invalid key format");295}296297return AlgorithmId.parse(val.data.getDerValue()).getOID();298}299300/*301* Tests matching on the subject public key algorithm ID component contained302* in the certificate.303*/304private void testSubjectPublicKeyAlgID() throws IOException {305System.out.println("X.509 Certificate Match on subjectPublicKeyAlgID");306// bad match307X509CertSelector selector = new X509CertSelector();308selector.setSubjectPublicKeyAlgID("2.5.29.14");309checkMatch(selector, cert, false);310311// good match312selector.setSubjectPublicKeyAlgID(getCertPubKeyAlgOID(cert).toString());313checkMatch(selector, cert, true);314315}316317// Tests matching on the key usage extension contained in the certificate.318private void testKeyUsage() {319System.out.println("X.509 Certificate Match on keyUsage");320// bad match321X509CertSelector selector = new X509CertSelector();322boolean[] keyUsage = { true, false, true, false, true, false, true, false };323selector.setKeyUsage(keyUsage);324System.out.println("Selector = " + selector.toString());325checkMatch(selector, cert, false);326327// good match328selector.setKeyUsage(cert.getKeyUsage());329System.out.println("Selector = " + selector.toString());330checkMatch(selector, cert, true);331}332333/*334* Tests matching on the subject alternative name extension contained in the335* certificate.336*/337private void testSubjectAltName() throws IOException {338System.out.println("X.509 Certificate Match on subjectAltName");339// bad match340X509CertSelector selector = new X509CertSelector();341GeneralNameInterface dnsName = new DNSName("foo.com");342DerOutputStream tmp = new DerOutputStream();343dnsName.encode(tmp);344selector.addSubjectAlternativeName(2, tmp.toByteArray());345checkMatch(selector, cert, false);346347// good match348DerInputStream in = new DerInputStream(cert.getExtensionValue("2.5.29.17"));349byte[] encoded = in.getOctetString();350SubjectAlternativeNameExtension ext = new SubjectAlternativeNameExtension(false, encoded);351GeneralNames names = (GeneralNames) ext.get(SubjectAlternativeNameExtension.SUBJECT_NAME);352GeneralName name = (GeneralName) names.get(0);353selector.setSubjectAlternativeNames(null);354DerOutputStream tmp2 = new DerOutputStream();355name.getName().encode(tmp2);356selector.addSubjectAlternativeName(name.getType(), tmp2.toByteArray());357checkMatch(selector, cert, true);358359// good match 2 (matches at least one)360selector.setMatchAllSubjectAltNames(false);361selector.addSubjectAlternativeName(2, "foo.com");362checkMatch(selector, cert, true);363}364365/*366* Tests matching on the policy constraints extension contained in the367* certificate.368*/369private void testPolicy() throws IOException {370System.out.println("X.509 Certificate Match on certificatePolicies");371// test encoding of CertificatePoliciesExtension because we wrote the372// code373// bad match374X509CertSelector selector = new X509CertSelector();375Set<String> s = new HashSet<>();376s.add(new String("1.2.5.7.68"));377selector.setPolicy(s);378checkMatch(selector, cert, false);379380// good match381DerInputStream in = new DerInputStream(cert.getExtensionValue("2.5.29.32"));382CertificatePoliciesExtension ext = new CertificatePoliciesExtension(false, in.getOctetString());383List<PolicyInformation> policies = ext.get(CertificatePoliciesExtension.POLICIES);384// match on the first policy id385PolicyInformation policyInfo = (PolicyInformation) policies.get(0);386s.clear();387s.add(policyInfo.getPolicyIdentifier().getIdentifier().toString());388selector.setPolicy(s);389checkMatch(selector, cert, true);390}391392/*393* Tests matching on the name constraints extension contained in the394* certificate.395*/396private void testPathToName() throws IOException {397System.out.println("X.509 Certificate Match on pathToName");398399X509CertSelector selector = null;400DerInputStream in = new DerInputStream(cert.getExtensionValue("2.5.29.30"));401byte[] encoded = in.getOctetString();402NameConstraintsExtension ext = new NameConstraintsExtension(false, encoded);403GeneralSubtrees permitted = (GeneralSubtrees) ext.get(PERMITTED_SUBTREES);404GeneralSubtrees excluded = (GeneralSubtrees) ext.get(EXCLUDED_SUBTREES);405406// bad matches on pathToName within excluded subtrees407if (excluded != null) {408Iterator<GeneralSubtree> e = excluded.iterator();409while (e.hasNext()) {410GeneralSubtree tree = e.next();411if (tree.getName().getType() == NAME_DIRECTORY) {412X500Name excludedDN1 = new X500Name(tree.getName().toString());413X500Name excludedDN2 = new X500Name("CN=Bogus, " + tree.getName().toString());414DerOutputStream derDN1 = new DerOutputStream();415DerOutputStream derDN2 = new DerOutputStream();416excludedDN1.encode(derDN1);417excludedDN2.encode(derDN2);418selector = new X509CertSelector();419selector.addPathToName(NAME_DIRECTORY, derDN1.toByteArray());420checkMatch(selector, cert, false);421selector.setPathToNames(null);422selector.addPathToName(NAME_DIRECTORY, derDN2.toByteArray());423checkMatch(selector, cert, false);424}425}426}427428// good matches on pathToName within permitted subtrees429if (permitted != null) {430Iterator<GeneralSubtree> e = permitted.iterator();431while (e.hasNext()) {432GeneralSubtree tree = e.next();433if (tree.getName().getType() == NAME_DIRECTORY) {434X500Name permittedDN1 = new X500Name(tree.getName().toString());435X500Name permittedDN2 = new X500Name("CN=good, " + tree.getName().toString());436DerOutputStream derDN1 = new DerOutputStream();437DerOutputStream derDN2 = new DerOutputStream();438permittedDN1.encode(derDN1);439permittedDN2.encode(derDN2);440selector = new X509CertSelector();441selector.addPathToName(NAME_DIRECTORY, derDN1.toByteArray());442checkMatch(selector, cert, true);443selector.setPathToNames(null);444selector.addPathToName(NAME_DIRECTORY, derDN2.toByteArray());445checkMatch(selector, cert, true);446}447}448}449}450451// Tests matching on the subject name contained in the certificate.452private void testSubject() throws IOException {453System.out.println("X.509 Certificate Match on subject");454// bad match455X509CertSelector selector = new X509CertSelector();456selector.setSubject("ou=bogus,ou=east,o=sun,c=us");457checkMatch(selector, cert, false);458459// good match460selector.setSubject(cert.getSubjectX500Principal().getName("RFC2253"));461checkMatch(selector, cert, true);462}463464// Tests matching on the subject public key contained in the certificate.465private void testSubjectPublicKey() throws IOException, GeneralSecurityException {466System.out.println("X.509 Certificate Match on subject public key");467// bad match468X509CertSelector selector = new X509CertSelector();469X509EncodedKeySpec keySpec = new X509EncodedKeySpec(470Base64.getMimeDecoder().decode(testKey.getBytes()));471KeyFactory keyFactory = KeyFactory.getInstance("DSA");472PublicKey pubKey = keyFactory.generatePublic(keySpec);473selector.setSubjectPublicKey(pubKey);474checkMatch(selector, cert, false);475476// good match477selector.setSubjectPublicKey(cert.getPublicKey());478checkMatch(selector, cert, true);479}480481// Tests matching on the name constraints contained in the certificate.482private void testNameConstraints() throws IOException {483System.out.println("X.509 Certificate Match on name constraints");484// bad match485GeneralSubtrees subjectTree = new GeneralSubtrees();486subjectTree.add(getGeneralSubtree((X500Name) cert.getSubjectDN()));487NameConstraintsExtension ext = new NameConstraintsExtension((GeneralSubtrees) null, subjectTree);488X509CertSelector selector = new X509CertSelector();489selector.setNameConstraints(ext.getExtensionValue());490checkMatch(selector, cert, false);491492// good match493ext = new NameConstraintsExtension(subjectTree, null);494selector.setNameConstraints(ext.getExtensionValue());495checkMatch(selector, cert, true);496}497498// Tests matching on basic constraints.499private void testBasicConstraints() {500System.out.println("X.509 Certificate Match on basic constraints");501// bad match502X509CertSelector selector = new X509CertSelector();503int mpl = cert.getBasicConstraints();504selector.setBasicConstraints(0);505checkMatch(selector, cert, false);506507// good match508selector.setBasicConstraints(mpl);509checkMatch(selector, cert, true);510}511512// Tests certificateEquals criterion513private void testCertificate() {514System.out.println("X.509 Certificate Match on certificateEquals criterion");515516X509CertSelector selector = new X509CertSelector();517// good match518selector.setCertificate(cert);519checkMatch(selector, cert, true);520}521522private void checkMatch(X509CertSelector selector, X509Certificate cert, boolean match) {523boolean result = selector.match(cert);524if (match != result)525throw new RuntimeException(selector + " match " + cert + " is " + result + ", but expect " + match);526}527528private static GeneralSubtree getGeneralSubtree(GeneralNameInterface gni) {529// Create a new GeneralSubtree with the specified name, 0 base, and530// unlimited length531GeneralName gn = new GeneralName(gni);532GeneralSubtree subTree = new GeneralSubtree(gn, 0, -1);533return subTree;534}535}536537538