1 package org.bouncycastle.jce.provider.test;
2 
3 import java.io.ByteArrayInputStream;
4 import java.io.IOException;
5 import java.math.BigInteger;
6 import java.net.InetAddress;
7 import java.net.UnknownHostException;
8 import java.security.InvalidKeyException;
9 import java.security.NoSuchAlgorithmException;
10 import java.security.NoSuchProviderException;
11 import java.security.Principal;
12 import java.security.Provider;
13 import java.security.PublicKey;
14 import java.security.Security;
15 import java.security.Signature;
16 import java.security.SignatureException;
17 import java.security.cert.CertPath;
18 import java.security.cert.CertPathValidator;
19 import java.security.cert.CertPathValidatorException;
20 import java.security.cert.CertStore;
21 import java.security.cert.CertStoreParameters;
22 import java.security.cert.Certificate;
23 import java.security.cert.CertificateEncodingException;
24 import java.security.cert.CertificateException;
25 import java.security.cert.CertificateExpiredException;
26 import java.security.cert.CertificateFactory;
27 import java.security.cert.CertificateNotYetValidException;
28 import java.security.cert.CertificateParsingException;
29 import java.security.cert.CollectionCertStoreParameters;
30 import java.security.cert.PKIXBuilderParameters;
31 import java.security.cert.PKIXCertPathChecker;
32 import java.security.cert.PKIXCertPathValidatorResult;
33 import java.security.cert.PKIXParameters;
34 import java.security.cert.PolicyNode;
35 import java.security.cert.TrustAnchor;
36 import java.security.cert.X509CRL;
37 import java.security.cert.X509CertSelector;
38 import java.security.cert.X509Certificate;
39 import java.util.ArrayList;
40 import java.util.Collection;
41 import java.util.Collections;
42 import java.util.Date;
43 import java.util.Enumeration;
44 import java.util.HashSet;
45 import java.util.List;
46 import java.util.Set;
47 
48 import javax.security.auth.x500.X500Principal;
49 
50 import org.bouncycastle.asn1.ASN1BitString;
51 import org.bouncycastle.asn1.ASN1Encodable;
52 import org.bouncycastle.asn1.ASN1Encoding;
53 import org.bouncycastle.asn1.ASN1InputStream;
54 import org.bouncycastle.asn1.ASN1ObjectIdentifier;
55 import org.bouncycastle.asn1.ASN1Primitive;
56 import org.bouncycastle.asn1.ASN1Sequence;
57 import org.bouncycastle.asn1.ASN1String;
58 import org.bouncycastle.asn1.DERBitString;
59 import org.bouncycastle.asn1.DERIA5String;
60 import org.bouncycastle.asn1.DERNull;
61 import org.bouncycastle.asn1.DEROctetString;
62 import org.bouncycastle.asn1.misc.MiscObjectIdentifiers;
63 import org.bouncycastle.asn1.misc.NetscapeCertType;
64 import org.bouncycastle.asn1.misc.NetscapeRevocationURL;
65 import org.bouncycastle.asn1.misc.VerisignCzagExtension;
66 import org.bouncycastle.asn1.util.ASN1Dump;
67 import org.bouncycastle.asn1.x500.X500Name;
68 import org.bouncycastle.asn1.x500.style.RFC4519Style;
69 import org.bouncycastle.asn1.x509.AlgorithmIdentifier;
70 import org.bouncycastle.asn1.x509.BasicConstraints;
71 import org.bouncycastle.asn1.x509.Extension;
72 import org.bouncycastle.asn1.x509.GeneralName;
73 import org.bouncycastle.asn1.x509.KeyUsage;
74 import org.bouncycastle.asn1.x509.X509CertificateStructure;
75 import org.bouncycastle.asn1.x509.X509Extension;
76 import org.bouncycastle.asn1.x509.X509Extensions;
77 import org.bouncycastle.jce.X509Principal;
78 import org.bouncycastle.jce.provider.BouncyCastleProvider;
79 import org.bouncycastle.util.Arrays;
80 import org.bouncycastle.util.Integers;
81 import org.bouncycastle.util.Strings;
82 import org.bouncycastle.util.encoders.Base64;
83 import org.bouncycastle.util.encoders.Hex;
84 import org.bouncycastle.util.test.SimpleTest;
85 
86 public class CertPathValidatorTest
87     extends SimpleTest
88 {
89     private byte[] AC_PR = Base64.decode(
90         "LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tDQpNSUlFU1RDQ0F6R2dBd0lC"
91             + "QWdJQkJUQU5CZ2txaGtpRzl3MEJBUVVGQURDQnRERUxNQWtHQTFVRUJoTUNR"
92             + "bEl4DQpFekFSQmdOVkJBb1RDa2xEVUMxQ2NtRnphV3d4UFRBN0JnTlZCQXNU"
93             + "TkVsdWMzUnBkSFYwYnlCT1lXTnBiMjVoDQpiQ0JrWlNCVVpXTnViMnh2WjJs"
94             + "aElHUmhJRWx1Wm05eWJXRmpZVzhnTFNCSlZFa3hFVEFQQmdOVkJBY1RDRUp5"
95             + "DQpZWE5wYkdsaE1Rc3dDUVlEVlFRSUV3SkVSakV4TUM4R0ExVUVBeE1vUVhW"
96             + "MGIzSnBaR0ZrWlNCRFpYSjBhV1pwDQpZMkZrYjNKaElGSmhhWG9nUW5KaGMy"
97             + "bHNaV2x5WVRBZUZ3MHdNakEwTURReE9UTTVNREJhRncwd05UQTBNRFF5DQpN"
98             + "elU1TURCYU1HRXhDekFKQmdOVkJBWVRBa0pTTVJNd0VRWURWUVFLRXdwSlEx"
99             + "QXRRbkpoYzJsc01UMHdPd1lEDQpWUVFERXpSQmRYUnZjbWxrWVdSbElFTmxj"
100             + "blJwWm1sallXUnZjbUVnWkdFZ1VISmxjMmxrWlc1amFXRWdaR0VnDQpVbVZ3"
101             + "ZFdKc2FXTmhNSUlCSWpBTkJna3Foa2lHOXcwQkFRRUZBQU9DQVE4QU1JSUJD"
102             + "Z0tDQVFFQXMwc0t5NGsrDQp6b016aldyMTQxeTVYQ045UGJMZERFQXN2cjZ4"
103             + "Z0NCN1l5bEhIQ1NBYmpGR3dOQ0R5NlVxN1h0VjZ6UHdIMXpGDQpFWENlS3Jm"
104             + "UUl5YXBXSEZ4V1VKajBMblFrY1RZM1FOR1huK0JuVk9EVTZDV3M1c3NoZktH"
105             + "RXZyVlQ1Z214V1NmDQp4OFlsdDgzY1dwUE1QZzg3VDlCaHVIbHQzazh2M2Ev"
106             + "NmRPbmF2dytOYTAyZExBaDBlNzZqcCtQUS9LK0pHZlBuDQphQjVVWURrZkd0"
107             + "em5uTTNBV01tY3VJK0o0ek5OMDZaa3ZnbDFsdEo2UU1qcnZEUFlSak9ndDlT"
108             + "cklpY1NmbEo4DQptVDdHWGRRaXJnQUNXc3g1QURBSklRK253TU1vNHlyTUtx"
109             + "SlFhNFFDMHhhT0QvdkdVcG9SaDQzT0FTZFp3c3YvDQpPWFlybmVJeVAwVCs4"
110             + "UUlEQVFBQm80RzNNSUcwTUQwR0ExVWRId1EyTURRd01xQXdvQzZHTEdoMGRI"
111             + "QTZMeTloDQpZM0poYVhvdWFXTndZbkpoYzJsc0xtZHZkaTVpY2k5TVExSmhZ"
112             + "M0poYVhvdVkzSnNNQklHQTFVZElBUUxNQWt3DQpCd1lGWUV3QkFRRXdIUVlE"
113             + "VlIwT0JCWUVGREpUVFlKNE9TWVB5T09KZkVMZXhDaHppK2hiTUI4R0ExVWRJ"
114             + "d1FZDQpNQmFBRklyNjhWZUVFUk0xa0VMNlYwbFVhUTJreFBBM01BNEdBMVVk"
115             + "RHdFQi93UUVBd0lCQmpBUEJnTlZIUk1CDQpBZjhFQlRBREFRSC9NQTBHQ1Nx"
116             + "R1NJYjNEUUVCQlFVQUE0SUJBUUJRUFNoZ1lidnFjaWV2SDVVb3ZMeXhkbkYr"
117             + "DQpFcjlOeXF1SWNkMnZ3Y0N1SnpKMkQ3WDBUcWhHQ0JmUEpVVkdBVWorS0NP"
118             + "SDFCVkgva1l1OUhsVHB1MGtKWFBwDQpBQlZkb2hJUERqRHhkbjhXcFFSL0Yr"
119             + "ejFDaWtVcldIMDR4eTd1N1p6UUpLSlBuR0loY1FpOElyRm1PYkllMEc3DQpY"
120             + "WTZPTjdPRUZxY21KTFFHWWdtRzFXMklXcytQd1JwWTdENGhLVEFoVjFSNkVv"
121             + "amE1L3BPcmVDL09kZXlQWmVxDQo1SUZTOUZZZk02U0Npd2hrK3l2Q1FHbVo0"
122             + "YzE5SjM0ZjVFYkRrK1NQR2tEK25EQ0E3L3VMUWNUMlJURE14SzBaDQpuZlo2"
123             + "Nm1Sc0ZjcXRGaWdScjVFcmtKZDdoUVV6eHNOV0VrNzJEVUFIcVgvNlNjeWtt"
124             + "SkR2V0plSUpqZlcNCi0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0NCg==");
125 
126     private byte[] AC_RAIZ_ICPBRASIL = Base64.decode(
127         "LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tDQpNSUlFdURDQ0E2Q2dBd0lC"
128             + "QWdJQkJEQU5CZ2txaGtpRzl3MEJBUVVGQURDQnRERUxNQWtHQTFVRUJoTUNR"
129             + "bEl4DQpFekFSQmdOVkJBb1RDa2xEVUMxQ2NtRnphV3d4UFRBN0JnTlZCQXNU"
130             + "TkVsdWMzUnBkSFYwYnlCT1lXTnBiMjVoDQpiQ0JrWlNCVVpXTnViMnh2WjJs"
131             + "aElHUmhJRWx1Wm05eWJXRmpZVzhnTFNCSlZFa3hFVEFQQmdOVkJBY1RDRUp5"
132             + "DQpZWE5wYkdsaE1Rc3dDUVlEVlFRSUV3SkVSakV4TUM4R0ExVUVBeE1vUVhW"
133             + "MGIzSnBaR0ZrWlNCRFpYSjBhV1pwDQpZMkZrYjNKaElGSmhhWG9nUW5KaGMy"
134             + "bHNaV2x5WVRBZUZ3MHdNVEV4TXpBeE1qVTRNREJhRncweE1URXhNekF5DQpN"
135             + "elU1TURCYU1JRzBNUXN3Q1FZRFZRUUdFd0pDVWpFVE1CRUdBMVVFQ2hNS1NV"
136             + "TlFMVUp5WVhOcGJERTlNRHNHDQpBMVVFQ3hNMFNXNXpkR2wwZFhSdklFNWhZ"
137             + "Mmx2Ym1Gc0lHUmxJRlJsWTI1dmJHOW5hV0VnWkdFZ1NXNW1iM0p0DQpZV05o"
138             + "YnlBdElFbFVTVEVSTUE4R0ExVUVCeE1JUW5KaGMybHNhV0V4Q3pBSkJnTlZC"
139             + "QWdUQWtSR01URXdMd1lEDQpWUVFERXloQmRYUnZjbWxrWVdSbElFTmxjblJw"
140             + "Wm1sallXUnZjbUVnVW1GcGVpQkNjbUZ6YVd4bGFYSmhNSUlCDQpJakFOQmdr"
141             + "cWhraUc5dzBCQVFFRkFBT0NBUThBTUlJQkNnS0NBUUVBd1BNdWR3WC9odm0r"
142             + "VWgyYi9sUUFjSFZBDQppc2FtYUxrV2Rrd1A5L1MvdE9LSWdSckw2T3krWklH"
143             + "bE9VZGQ2dVl0azlNYS8zcFVwZ2NmTkFqMHZZbTVnc3lqDQpRbzllbXNjK3g2"
144             + "bTRWV3drOWlxTVpTQ0s1RVFrQXEvVXQ0bjdLdUxFMStnZGZ0d2RJZ3hmVXNQ"
145             + "dDRDeU5yWTUwDQpRVjU3S00yVVQ4eDVycm16RWpyN1RJQ0dwU1VBbDJnVnFl"
146             + "NnhhaWkrYm1ZUjFRcm1XYUJTQUc1OUxya3Jqcll0DQpiUmhGYm9VRGUxREsr"
147             + "NlQ4czVMNms4Yzhva3BiSHBhOXZlTXp0RFZDOXNQSjYwTVdYaDZhblZLbzFV"
148             + "Y0xjYlVSDQp5RWVOdlpuZVZSS0FBVTZvdXdkakR2d2xzYUt5ZEZLd2VkMFRv"
149             + "UTQ3Ym1VS2djbSt3VjNlVFJrMzZVT25Ud0lEDQpBUUFCbzRIU01JSFBNRTRH"
150             + "QTFVZElBUkhNRVV3UXdZRllFd0JBUUF3T2pBNEJnZ3JCZ0VGQlFjQ0FSWXNh"
151             + "SFIwDQpjRG92TDJGamNtRnBlaTVwWTNCaWNtRnphV3d1WjI5MkxtSnlMMFJR"
152             + "UTJGamNtRnBlaTV3WkdZd1BRWURWUjBmDQpCRFl3TkRBeW9EQ2dMb1lzYUhS"
153             + "MGNEb3ZMMkZqY21GcGVpNXBZM0JpY21GemFXd3VaMjkyTG1KeUwweERVbUZq"
154             + "DQpjbUZwZWk1amNtd3dIUVlEVlIwT0JCWUVGSXI2OFZlRUVSTTFrRUw2VjBs"
155             + "VWFRMmt4UEEzTUE4R0ExVWRFd0VCDQovd1FGTUFNQkFmOHdEZ1lEVlIwUEFR"
156             + "SC9CQVFEQWdFR01BMEdDU3FHU0liM0RRRUJCUVVBQTRJQkFRQVpBNWMxDQpV"
157             + "L2hnSWg2T2NnTEFmaUpnRldwdm1EWldxbFYzMC9iSEZwajhpQm9iSlNtNXVE"
158             + "cHQ3VGlyWWgxVXhlM2ZRYUdsDQpZakplKzl6ZCtpelBSYkJxWFBWUUEzNEVY"
159             + "Y3drNHFwV3VmMWhIcmlXZmRyeDhBY3FTcXI2Q3VRRndTcjc1Rm9zDQpTemx3"
160             + "REFEYTcwbVQ3d1pqQW1RaG5aeDJ4SjZ3ZldsVDlWUWZTLy9KWWVJYzdGdWUy"
161             + "Sk5MZDAwVU9TTU1haUsvDQp0NzllbktOSEVBMmZ1cEgzdkVpZ2Y1RWg0YlZB"
162             + "TjVWb2hyVG02TVk1M3g3WFFaWnIxTUU3YTU1bEZFblNlVDB1DQptbE9BalIy"
163             + "bUFidlNNNVg1b1NaTnJtZXRkenlUajJmbENNOENDN01MYWIwa2tkbmdSSWxV"
164             + "QkdIRjEvUzVubVBiDQpLKzlBNDZzZDMzb3FLOG44DQotLS0tLUVORCBDRVJU"
165             + "SUZJQ0FURS0tLS0tDQo=");
166 
167     private byte[] schefer = Base64.decode(
168         "MIIEnDCCBAWgAwIBAgICIPAwDQYJKoZIhvcNAQEEBQAwgcAxCzAJBgNVBAYT"
169             + "AkRFMQ8wDQYDVQQIEwZIRVNTRU4xGDAWBgNVBAcTDzY1MDA4IFdpZXNiYWRl"
170             + "bjEaMBgGA1UEChMRU0NIVUZBIEhPTERJTkcgQUcxGjAYBgNVBAsTEVNDSFVG"
171             + "QSBIT0xESU5HIEFHMSIwIAYDVQQDExlJbnRlcm5ldCBCZW51dHplciBTZXJ2"
172             + "aWNlMSowKAYJKoZIhvcNAQkBFht6ZXJ0aWZpa2F0QHNjaHVmYS1vbmxpbmUu"
173             + "ZGUwHhcNMDQwMzMwMTEwODAzWhcNMDUwMzMwMTEwODAzWjCBnTELMAkGA1UE"
174             + "BhMCREUxCjAIBgNVBAcTASAxIzAhBgNVBAoTGlNIUyBJbmZvcm1hdGlvbnNz"
175             + "eXN0ZW1lIEFHMRwwGgYDVQQLExM2MDAvMDU5NDktNjAwLzA1OTQ5MRgwFgYD"
176             + "VQQDEw9TY2hldHRlciBTdGVmYW4xJTAjBgkqhkiG9w0BCQEWFlN0ZWZhbi5T"
177             + "Y2hldHRlckBzaHMuZGUwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAJD0"
178             + "95Bi76fkAMjJNTGPDiLPHmZXNsmakngDeS0juzKMeJA+TjXFouhYh6QyE4Bl"
179             + "Nf18fT4mInlgLefwf4t6meIWbiseeTo7VQdM+YrbXERMx2uHsRcgZMsiMYHM"
180             + "kVfYMK3SMJ4nhCmZxrBkoTRed4gXzVA1AA8YjjTqMyyjvt4TAgMBAAGjggHE"
181             + "MIIBwDAJBgNVHRMEAjAAMBEGCWCGSAGG+EIBAQQEAwIEsDALBgNVHQ8EBAMC"
182             + "BNAwOQYJYIZIAYb4QgENBCwWKlplcnRpZmlrYXQgbnVyIGZ1ZXIgU0NIVUZB"
183             + "LU9ubGluZSBndWVsdGlnLjAdBgNVHQ4EFgQUXReirhBfg0Yhf6MsBWoo/nPa"
184             + "hGwwge0GA1UdIwSB5TCB4oAUf2UyCaBV9JUeG9lS1Yo6OFBUdEKhgcakgcMw"
185             + "gcAxCzAJBgNVBAYTAkRFMQ8wDQYDVQQIEwZIRVNTRU4xGDAWBgNVBAcTDzY1"
186             + "MDA4IFdpZXNiYWRlbjEaMBgGA1UEChMRU0NIVUZBIEhPTERJTkcgQUcxGjAY"
187             + "BgNVBAsTEVNDSFVGQSBIT0xESU5HIEFHMSIwIAYDVQQDExlJbnRlcm5ldCBC"
188             + "ZW51dHplciBTZXJ2aWNlMSowKAYJKoZIhvcNAQkBFht6ZXJ0aWZpa2F0QHNj"
189             + "aHVmYS1vbmxpbmUuZGWCAQAwIQYDVR0RBBowGIEWU3RlZmFuLlNjaGV0dGVy"
190             + "QHNocy5kZTAmBgNVHRIEHzAdgRt6ZXJ0aWZpa2F0QHNjaHVmYS1vbmxpbmUu"
191             + "ZGUwDQYJKoZIhvcNAQEEBQADgYEAWzZtN9XQ9uyrFXqSy3hViYwV751+XZr0"
192             + "YH5IFhIS+9ixNAu8orP3bxqTaMhpwoU7T/oSsyGGSkb3fhzclgUADbA2lrOI"
193             + "GkeB/m+FArTwRbwpqhCNTwZywOp0eDosgPjCX1t53BB/m/2EYkRiYdDGsot0"
194             + "kQPOVGSjQSQ4+/D+TM8=");
195 
196     // circular dependency certificates
197     private static final byte[] circCA = Base64.decode(
198         "MIIDTzCCAjegAwIBAgIDARAAMA0GCSqGSIb3DQEBBQUAMDkxCzAJBgNVBAYT"
199             + "AkZSMRAwDgYDVQQKEwdHSVAtQ1BTMRgwFgYDVQQLEw9HSVAtQ1BTIEFOT05Z"
200             + "TUUwHhcNMDQxMDExMDAwMDAxWhcNMTQxMjMxMjM1OTU5WjA5MQswCQYDVQQG"
201             + "EwJGUjEQMA4GA1UEChMHR0lQLUNQUzEYMBYGA1UECxMPR0lQLUNQUyBBTk9O"
202             + "WU1FMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA3WyWDwcM58aU"
203             + "hPX4ueI1mwETt3WdQtMfIdRiCXeBrjCkYCc7nIgCmGbnfTzXSplHRgKColWh"
204             + "q/Z+1rHYayje1gjAEU2+4/r1P2pnBmPgquDuguktCIbDtCcGZu0ylyKeHh37"
205             + "aeIKzkcmRSLRzvGf/eO3RdFksrvaPaSjqCVfGRXVDKK2uftE8rIFJE+bCqow"
206             + "6+WiaAaDDiJaSJPuu5hC1NA5jw0/BFodlCuAvl1GJ8A+TICkYWcSpKS9bkSC"
207             + "0i8xdGbSSk94shA1PdDvRdFMfFys8g4aupBXV8yqqEAUkBYmOtZSJckc3W4y"
208             + "2Gx53y7vY07Xh63mcgtJs2T82WJICwIDAQABo2AwXjAdBgNVHQ4EFgQU8c/P"
209             + "NNJaL0srd9SwHwgtvwPB/3cwDgYDVR0PAQH/BAQDAgIEMBkGA1UdIAQSMBAw"
210             + "DgYMKoF6AUcDBwgAAAABMBIGA1UdEwEB/wQIMAYBAf8CAQEwDQYJKoZIhvcN"
211             + "AQEFBQADggEBAHRjYDPJKlfUzID0YzajZpgR/i2ngJrJqYeaWCmwzBgNUPad"
212             + "uBKSGHmPVg21sfULMSnirnR+e90i/D0EVzLwQzcbjPDD/85rp9QDCeMxqqPe"
213             + "9ZCHGs2BpE/HOQMP0QfQ3/Kpk7SvOH/ZcpIf6+uE6lLBQYAGs5cxvtTGOzZk"
214             + "jCVFG+TrAnF4V5sNkn3maCWiYLmyqcnxtKEFSONy2bYqqudx/dBBlRrDbRfZ"
215             + "9XsCBdiXAHY1hFHldbfDs8rslmkXJi3fJC028HZYB6oiBX/JE7BbMk7bRnUf"
216             + "HSpP7Sjxeso2SY7Yit+hQDVAlqTDGmh6kLt/hQMpsOMry4vgBL6XHKw=");
217 
218     private static final byte[] circCRLCA = Base64.decode(
219         "MIIDXDCCAkSgAwIBAgIDASAAMA0GCSqGSIb3DQEBBQUAMDkxCzAJBgNVBAYT"
220             + "AkZSMRAwDgYDVQQKEwdHSVAtQ1BTMRgwFgYDVQQLEw9HSVAtQ1BTIEFOT05Z"
221             + "TUUwHhcNMDQxMDExMDAwMDAxWhcNMTQxMjMxMjM1OTU5WjA5MQswCQYDVQQG"
222             + "EwJGUjEQMA4GA1UEChMHR0lQLUNQUzEYMBYGA1UECxMPR0lQLUNQUyBBTk9O"
223             + "WU1FMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAwfEcFK0g7Kfo"
224             + "o5f2IBF7VEd/AG+RVGSds0Yg+u2kNYu4k04HR/+tOdBQtJvyr4W5jrQKsC5X"
225             + "skeFWMyWaFKzAjZDWB52HWp/kiMivGcxnYDuYf5piukSC+d2+vL8YaAphDzV"
226             + "HPnxEKqoM/J66uUussDTqfcL3JC/Bc7kBwn4srrsZOsamMWTQQtEqVQxNN7A"
227             + "ROSRsdiTt3hMOKditc9/NBNmjZWxgc7Twr/SaZ8CfN5wf2wuOl23knWL0QsJ"
228             + "0lSMBSBTzTcfAke4/jIT7d4nVMp3t7dsna8rt56pFK4wpRFGuCt+1P5gi51x"
229             + "xVSdI+JoNXv6zGO4o8YVaRpC5rQeGQIDAQABo20wazAfBgNVHSMEGDAWgBTx"
230             + "z8800lovSyt31LAfCC2/A8H/dzAdBgNVHQ4EFgQUGa3SbBrJx/wa2MQwhWPl"
231             + "dwLw1+IwDgYDVR0PAQH/BAQDAgECMBkGA1UdIAQSMBAwDgYMKoF6AUcDBwgA"
232             + "AAABMA0GCSqGSIb3DQEBBQUAA4IBAQAPDpYe2WPYnXTLsXSIUREBNMLmg+/7"
233             + "4Yhq9uOm5Hb5LVkDuHoEHGfmpXXEvucx5Ehu69hw+F4YSrd9wPjOiG8G6GXi"
234             + "RcrK8nE8XDvvV+E1HpJ7NKN4fSAoSb+0gliiq3aF15bvXP8nfespdd/x1xWQ"
235             + "mpYCx/mJeuqONQv2/D/7hfRKYoDBaAkWGodenPFPVs6FxwnEuH2R+KWCUdA9"
236             + "L04v8JBeL3kZiALkU7+DCCm7A0imUAgeeArbAbfIPu6eDygm+XndZ9qi7o4O"
237             + "AntPxrqbeXFIbDrQ4GV1kpxnW+XpSGDd96SWKe715gxkkDBppR5IKYJwRb6O"
238             + "1TRQIf2F+muQ");
239 
240     private static final byte[] circCRL = Base64.decode(
241         "MIIB1DCBvQIBATANBgkqhkiG9w0BAQUFADA5MQswCQYDVQQGEwJGUjEQMA4G"
242             + "A1UEChMHR0lQLUNQUzEYMBYGA1UECxMPR0lQLUNQUyBBTk9OWU1FFw0xMDAx"
243             + "MDcwMzAwMTVaFw0xMDAxMTMwMzAwMTVaMACgTjBMMB8GA1UdIwQYMBaAFBmt"
244             + "0mwaycf8GtjEMIVj5XcC8NfiMAsGA1UdFAQEAgILgzAcBgNVHRIEFTATgRFh"
245             + "Yy1naXBAZ2lwLWNwcy5mcjANBgkqhkiG9w0BAQUFAAOCAQEAtF1DdFl1MQvf"
246             + "vNkbrCPuppNYcHen4+za/ZDepKuwHsH/OpKuaDJc4LndRgd5IwzfpCHkQGzt"
247             + "shK50bakN8oaYJgthKIOIJzR+fn6NMjftfR2a27Hdk2o3eQXRHQ360qMbpSy"
248             + "qPb3WfuBhxO2/DlLChJP+OxZIHtT/rNYgE0tlIv7swYi81Gq+DafzaZ9+A5t"
249             + "I0L2Gp/NUDsp5dF6PllAGiXQzl27qkcu+r50w+u0gul3nobXgbwPcMSYuWUz"
250             + "1lhA+uDn/EUWV4RSiJciCGSS10WCkFh1/YPo++mV15KDB0m+8chscrSu/bAl"
251             + "B19LxL/pCX3qr5iLE9ss3olVImyFZg==");
252 
checkCircProcessing()253     private void checkCircProcessing()
254         throws Exception
255     {
256         CertificateFactory cf = CertificateFactory.getInstance("X.509", "BC");
257 
258         X509Certificate caCert = (X509Certificate)cf.generateCertificate(new ByteArrayInputStream(circCA));
259         X509Certificate crlCaCert = (X509Certificate)cf.generateCertificate(new ByteArrayInputStream(circCRLCA));
260         X509CRL crl = (X509CRL)cf.generateCRL(new ByteArrayInputStream(circCRL));
261 
262         List list = new ArrayList();
263 
264         list.add(caCert);
265         list.add(crlCaCert);
266         list.add(crl);
267 
268         CertStoreParameters ccsp = new CollectionCertStoreParameters(list);
269         CertStore store = CertStore.getInstance("Collection", ccsp);
270 
271         Date validDate = new Date(crl.getThisUpdate().getTime() + 60 * 60 * 1000);
272 
273         //validating path
274         List certchain = new ArrayList();
275 
276         certchain.add(crlCaCert);
277         CertPath cp = CertificateFactory.getInstance("X.509", "BC").generateCertPath(certchain);
278 
279         Set trust = new HashSet();
280         trust.add(new TrustAnchor(caCert, null));
281 
282         CertPathValidator cpv = CertPathValidator.getInstance("PKIX", "BC");
283         //PKIXParameters param = new PKIXParameters(trust);
284 
285         PKIXBuilderParameters param = new PKIXBuilderParameters(trust, null);
286         X509CertSelector certSelector = new X509CertSelector();
287         certSelector.setCertificate(crlCaCert);
288         param.setTargetCertConstraints(certSelector);
289         param.addCertStore(store);
290         param.setRevocationEnabled(true);
291         param.setDate(validDate);
292 
293         PKIXCertPathValidatorResult result = (PKIXCertPathValidatorResult)cpv.validate(cp, param);
294     }
295 
checkPolicyProcessingAtDomainMatch()296     private void checkPolicyProcessingAtDomainMatch()
297         throws Exception
298     {
299         CertificateFactory cf = CertificateFactory.getInstance("X.509", "BC");
300 
301         X509Certificate root = (X509Certificate)cf.generateCertificate(this.getClass().getResourceAsStream("qvRooCa3.crt"));
302         X509Certificate ca1 = (X509Certificate)cf.generateCertificate(this.getClass().getResourceAsStream("suvaRoot1.crt"));
303         X509Certificate ca2 = (X509Certificate)cf.generateCertificate(this.getClass().getResourceAsStream("suvaEmail1.crt"));
304         X509Certificate ee = (X509Certificate)cf.generateCertificate(this.getClass().getResourceAsStream("suvaEE.crt"));
305 
306         List certchain = new ArrayList();
307         certchain.add(ee);
308         certchain.add(ca2);
309         certchain.add(ca1);
310 
311         Set trust = new HashSet();
312         trust.add(new TrustAnchor(root, null));
313 
314         CertPathValidator cpv = CertPathValidator.getInstance("PKIX", "BC");
315         PKIXParameters param = new PKIXParameters(trust);
316         param.setRevocationEnabled(false);
317         param.setDate(new Date(0x156445410b4L)); // around 1st August 2016
318 
319         CertPath cp = cf.generateCertPath(certchain);
320 
321         MyChecker checker = new MyChecker();
322         param.addCertPathChecker(checker);
323 
324         PKIXCertPathValidatorResult result =
325             (PKIXCertPathValidatorResult)cpv.validate(cp, param);
326     }
327 
testEmptyPath()328     public void testEmptyPath()
329         throws Exception
330     {
331         CertificateFactory cf = CertificateFactory.getInstance("X.509", "BC");
332         X509Certificate rootCert = (X509Certificate)cf.generateCertificate(new ByteArrayInputStream(CertPathTest.rootCertBin));
333 
334         List list = new ArrayList();
335         list.add(rootCert);
336         CollectionCertStoreParameters ccsp = new CollectionCertStoreParameters(list);
337         CertStore store = CertStore.getInstance("Collection", ccsp, "BC");
338 
339         List certchain = new ArrayList();
340         CertPath cp = CertificateFactory.getInstance("X.509", "BC").generateCertPath(certchain);
341         Set trust = new HashSet();
342         trust.add(new TrustAnchor(rootCert, null));
343 
344         CertPathValidator cpv = CertPathValidator.getInstance("PKIX", "BC");
345         PKIXParameters param = new PKIXParameters(trust);
346         param.addCertStore(store);
347         MyChecker checker = new MyChecker();
348         param.addCertPathChecker(checker);
349 
350         try
351         {
352             cpv.validate(cp, param);
353         }
354         catch (CertPathValidatorException e)
355         {
356             if (!"Certification path is empty.".equals(e.getMessage()))
357             {
358                 fail("message mismatch");
359             }
360         }
361     }
362 
363 
constraintTest()364     private void constraintTest()
365         throws Exception
366     {
367         CertificateFactory cf = CertificateFactory.getInstance("X.509", "BC");
368 
369         X509Certificate rootCert = (X509Certificate)cf.generateCertificate(this.getClass().getResourceAsStream("CERT_CI_ECDSA_NIST.pem"));
370         X509Certificate interCert = (X509Certificate)cf.generateCertificate(this.getClass().getResourceAsStream("CERT_EUM_ECDSA_NIST.pem"));
371         X509Certificate finalCert = (X509Certificate)cf.generateCertificate(this.getClass().getResourceAsStream("CERT_EUICC_ECDSA_NIST.pem"));
372 
373         List list = new ArrayList();
374         list.add(interCert);
375         list.add(finalCert);
376 
377         CertPath certPath = cf.generateCertPath(list);
378 
379         Set trust = new HashSet();
380         trust.add(new TrustAnchor(rootCert, null));
381 
382         CertPathValidator cpv = CertPathValidator.getInstance("PKIX", "BC");
383         PKIXParameters param = new PKIXParameters(trust);
384         param.setRevocationEnabled(false);
385 
386         cpv.validate(certPath, param);
387 
388     }
389 
performTest()390     public void performTest()
391         throws Exception
392     {
393         constraintTest();
394 
395         CertificateFactory cf = CertificateFactory.getInstance("X.509", "BC");
396 
397         // initialise CertStore
398         X509Certificate rootCert = (X509Certificate)cf.generateCertificate(new ByteArrayInputStream(CertPathTest.rootCertBin));
399         X509Certificate interCert = (X509Certificate)cf.generateCertificate(new ByteArrayInputStream(CertPathTest.interCertBin));
400         X509Certificate finalCert = (X509Certificate)cf.generateCertificate(new ByteArrayInputStream(CertPathTest.finalCertBin));
401         X509CRL rootCrl = (X509CRL)cf.generateCRL(new ByteArrayInputStream(CertPathTest.rootCrlBin));
402         X509CRL interCrl = (X509CRL)cf.generateCRL(new ByteArrayInputStream(CertPathTest.interCrlBin));
403         List list = new ArrayList();
404         list.add(rootCert);
405         list.add(interCert);
406         list.add(finalCert);
407         list.add(rootCrl);
408         list.add(interCrl);
409         CollectionCertStoreParameters ccsp = new CollectionCertStoreParameters(list);
410         CertStore store = CertStore.getInstance("Collection", ccsp, "BC");
411         Date validDate = new Date(rootCrl.getThisUpdate().getTime() + 60 * 60 * 1000);
412         //validating path
413         List certchain = new ArrayList();
414         certchain.add(finalCert);
415         certchain.add(interCert);
416 
417         CertPath cp = CertificateFactory.getInstance("X.509", "BC").generateCertPath(certchain);
418         Set trust = new HashSet();
419         trust.add(new TrustAnchor(rootCert, null));
420 
421         CertPathValidator cpv = CertPathValidator.getInstance("PKIX", "BC");
422         PKIXParameters param = new PKIXParameters(trust);
423         param.addCertStore(store);
424         param.setDate(validDate);
425         MyChecker checker = new MyChecker();
426         param.addCertPathChecker(checker);
427 
428         PKIXCertPathValidatorResult result =
429             (PKIXCertPathValidatorResult)cpv.validate(cp, param);
430         PolicyNode policyTree = result.getPolicyTree();
431         PublicKey subjectPublicKey = result.getPublicKey();
432 
433         if (checker.getCount() != 2)
434         {
435             fail("checker not evaluated for each certificate");
436         }
437 
438         if (!subjectPublicKey.equals(finalCert.getPublicKey()))
439         {
440             fail("wrong public key returned");
441         }
442 
443         isTrue(result.getTrustAnchor().getTrustedCert().equals(rootCert));
444 
445         // try a path with trust anchor included.
446         certchain.clear();
447         certchain.add(finalCert);
448         certchain.add(interCert);
449         certchain.add(rootCert);
450 
451         cp = CertificateFactory.getInstance("X.509", "BC").generateCertPath(certchain);
452 
453         cpv = CertPathValidator.getInstance("PKIX", "BC");
454         param = new PKIXParameters(trust);
455         param.addCertStore(store);
456         param.setDate(validDate);
457 
458         result = (PKIXCertPathValidatorResult)cpv.validate(cp, param);
459 
460         isTrue(result.getTrustAnchor().getTrustedCert().equals(rootCert));
461 
462         //
463         // invalid path containing a valid one test
464         //
465         try
466         {
467             // initialise CertStore
468             rootCert = (X509Certificate)cf.generateCertificate(new ByteArrayInputStream(AC_RAIZ_ICPBRASIL));
469             interCert = (X509Certificate)cf.generateCertificate(new ByteArrayInputStream(AC_PR));
470             finalCert = (X509Certificate)cf.generateCertificate(new ByteArrayInputStream(schefer));
471 
472             list = new ArrayList();
473             list.add(rootCert);
474             list.add(interCert);
475             list.add(finalCert);
476 
477             ccsp = new CollectionCertStoreParameters(list);
478             store = CertStore.getInstance("Collection", ccsp);
479             validDate = new Date(finalCert.getNotBefore().getTime() + 60 * 60 * 1000);
480 
481             //validating path
482             certchain = new ArrayList();
483             certchain.add(finalCert);
484             certchain.add(interCert);
485 
486             cp = CertificateFactory.getInstance("X.509", "BC").generateCertPath(certchain);
487             trust = new HashSet();
488             trust.add(new TrustAnchor(rootCert, null));
489 
490             cpv = CertPathValidator.getInstance("PKIX", "BC");
491             param = new PKIXParameters(trust);
492             param.addCertStore(store);
493             param.setRevocationEnabled(false);
494             param.setDate(validDate);
495 
496             result = (PKIXCertPathValidatorResult)cpv.validate(cp, param);
497             policyTree = result.getPolicyTree();
498             subjectPublicKey = result.getPublicKey();
499 
500             fail("Invalid path validated");
501         }
502         catch (Exception e)
503         {
504             if (!(e instanceof CertPathValidatorException
505                 && e.getMessage().startsWith("Could not validate certificate signature.")))
506             {
507                 fail("unexpected exception", e);
508             }
509         }
510 
511         checkCircProcessing();
512         checkPolicyProcessingAtDomainMatch();
513         validateWithExtendedKeyUsage();
514         testEmptyPath();
515         checkInvalidCertPath();
516     }
517 
518     // extended key usage chain
519     static byte[] extEE = Base64.decode("MIICtDCCAh2gAwIBAgIBAzANBgkqhkiG9w0BAQUFADCBkjELMAkGA1UEBhMCQVUxKDAmBgNVBAoMH1RoZSBMZWdpb24gb2YgdGhlIEJvdW5jeSBDYXN0bGUxKDAmBgNVBAsMH0JvdW5jeSBJbnRlcm1lZGlhdGUgQ2VydGlmaWNhdGUxLzAtBgkqhkiG9w0BCQEWIGZlZWRiYWNrLWNyeXB0b0Bib3VuY3ljYXN0bGUub3JnMB4XDTE1MDMyNDAzNTEwOVoXDTE1MDUyMzAzNTEwOVowgZYxCzAJBgNVBAYTAkFVMSgwJgYDVQQKDB9UaGUgTGVnaW9uIG9mIHRoZSBCb3VuY3kgQ2FzdGxlMRIwEAYDVQQHDAlNZWxib3VybmUxGDAWBgNVBAMMD0VyaWMgSC4gRWNoaWRuYTEvMC0GCSqGSIb3DQEJARYgZmVlZGJhY2stY3J5cHRvQGJvdW5jeWNhc3RsZS5vcmcwWjANBgkqhkiG9w0BAQEFAANJADBGAkEAtKfkYXBXTxapcIKyK+WLaipil5hBm+EocqS9umJs+umQD3ar+xITnc5d5WVk+rK2VDFloEDGBoh0IOM9ke1+1wIBEaNaMFgwHQYDVR0OBBYEFNBs7G01g7xVEhsMyz7+1yamFmRoMB8GA1UdIwQYMBaAFJQIM28yQPeHN9rRIKrtLqduyckeMBYGA1UdJQEB/wQMMAoGCCsGAQUFBwMDMA0GCSqGSIb3DQEBBQUAA4GBAICrsNswvaXFMreUHHRHrhU4QqPOds8XJe0INx3v/5TfyjPPDMihMEm8WtWbVpFgFAqUQoZscf8cE/SO5375unYFgxrK+p2/je9E82VLF4Xb0cWizjQoWvvTmvFYjt43cGGXgySFLTrW87ju9uNFr/l4W9xvI0hoLI96vEW7Ccho");
520     static byte[] extCA = Base64.decode("MIIDIzCCAoygAwIBAgIBAjANBgkqhkiG9w0BAQUFADBcMQswCQYDVQQGEwJBVTEoMCYGA1UECgwfVGhlIExlZ2lvbiBvZiB0aGUgQm91bmN5IENhc3RsZTEjMCEGA1UECwwaQm91bmN5IFByaW1hcnkgQ2VydGlmaWNhdGUwHhcNMTUwMzI0MDM1MTA5WhcNMTUwNTIzMDM1MTA5WjCBkjELMAkGA1UEBhMCQVUxKDAmBgNVBAoMH1RoZSBMZWdpb24gb2YgdGhlIEJvdW5jeSBDYXN0bGUxKDAmBgNVBAsMH0JvdW5jeSBJbnRlcm1lZGlhdGUgQ2VydGlmaWNhdGUxLzAtBgkqhkiG9w0BCQEWIGZlZWRiYWNrLWNyeXB0b0Bib3VuY3ljYXN0bGUub3JnMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCN4NETxec2lpyNKwR6JD+P4Y7a1kzenoQtNmkjDKSG98/d4fjuxU0ZBf/wSsyF5hCT4YDK3GzqQH8ZPUS7DpRJuNu0l4TNnjYmDDngapRymZeMbtgwByTohxmM/t4g8/veZY+ivQeL6Uajkr00nytJxIbiDEBViOMGcGyQFzCOaQIDAP//o4G9MIG6MB0GA1UdDgQWBBSUCDNvMkD3hzfa0SCq7S6nbsnJHjCBhAYDVR0jBH0we4AUwDYZB63EiJeoXnJvawnr5ebxKVyhYKReMFwxCzAJBgNVBAYTAkFVMSgwJgYDVQQKDB9UaGUgTGVnaW9uIG9mIHRoZSBCb3VuY3kgQ2FzdGxlMSMwIQYDVQQLDBpCb3VuY3kgUHJpbWFyeSBDZXJ0aWZpY2F0ZYIBATASBgNVHRMBAf8ECDAGAQH/AgEAMA0GCSqGSIb3DQEBBQUAA4GBAJqUlDjse7Og+7qkkFsiXHzQ8FxT82hzfcji8W7bPwZddCPBEluxCJiJBPYXWsLvwo6BEmCDzT9lLQZ+QZyL1fVbOVHiI24hAalbEBEIrEO4GXMD9spqRQ5yoTJ8CgZHTPo0rJkH/ebprp0YHtahVF440zBOvuLM0QTYpERgO2Oe");
521     static byte[] extTrust = Base64.decode("MIICJTCCAY4CAQEwDQYJKoZIhvcNAQEFBQAwXDELMAkGA1UEBhMCQVUxKDAmBgNVBAoMH1RoZSBMZWdpb24gb2YgdGhlIEJvdW5jeSBDYXN0bGUxIzAhBgNVBAsMGkJvdW5jeSBQcmltYXJ5IENlcnRpZmljYXRlMB4XDTE1MDMyNDAzNTEwOVoXDTE1MDUyMzAzNTEwOVowXDELMAkGA1UEBhMCQVUxKDAmBgNVBAoMH1RoZSBMZWdpb24gb2YgdGhlIEJvdW5jeSBDYXN0bGUxIzAhBgNVBAsMGkJvdW5jeSBQcmltYXJ5IENlcnRpZmljYXRlMIGdMA0GCSqGSIb3DQEBAQUAA4GLADCBhwKBgQCyWdLW5ienaMlL42Fkwtn8edl6q5JTFA5b8XdRGXcx1vdUDSUJ57n/7gpwpuJtVuktLt1/hauoVgC2kInzX2vb88KY4FhCU12fBk5rA5HLfTBuCi0gxN+057SalkC96ibBCtacPwUAfOJRPO5Ez+AZmOYrbDY30/wDkQebJu421QIBETANBgkqhkiG9w0BAQUFAAOBgQCDNfqQnQbbmnGzZTl7ccWIyw7SPzWnijpKsQpuRNGkoXfkCcuQLZudytEFZGEL0cycNBnierjJWAn78zGpCQtab01r1GwytRMYz8qO5IIrhsJ4XNafNypYZbi0WtPa07UCQp8tipMbfQNLzSkvkIAaD5IfhdaWKLrSQJwmGg7YAg==");
522 
validateWithExtendedKeyUsage()523     private void validateWithExtendedKeyUsage()
524         throws Exception
525     {
526         CertificateFactory cf = CertificateFactory.getInstance("X.509", "BC");
527 
528         X509Certificate rootCert = (X509Certificate)cf.generateCertificate(new ByteArrayInputStream(extTrust));
529         X509Certificate interCert = (X509Certificate)cf.generateCertificate(new ByteArrayInputStream(extCA));
530         X509Certificate finalCert = (X509Certificate)cf.generateCertificate(new ByteArrayInputStream(extEE));
531 
532         List list = new ArrayList();
533         list.add(rootCert);
534         list.add(interCert);
535         list.add(finalCert);
536 
537         CollectionCertStoreParameters ccsp = new CollectionCertStoreParameters(list);
538         CertStore store = CertStore.getInstance("Collection", ccsp, "BC");
539         Date validDate = new Date(rootCert.getNotBefore().getTime() + 60 * 60 * 1000);
540         //validating path
541         List certchain = new ArrayList();
542         certchain.add(finalCert);
543         certchain.add(interCert);
544         CertPath cp = CertificateFactory.getInstance("X.509", "BC").generateCertPath(certchain);
545         Set trust = new HashSet();
546         trust.add(new TrustAnchor(rootCert, null));
547 
548         CertPathValidator cpv = CertPathValidator.getInstance("PKIX", "BC");
549         PKIXParameters param = new PKIXParameters(trust);
550         param.addCertStore(store);
551         param.setDate(validDate);
552         param.setRevocationEnabled(false);
553 
554         PKIXCertPathValidatorResult result = (PKIXCertPathValidatorResult)cpv.validate(cp, param);
555     }
556 
557     // invalid EE certificate
558     static byte[] extInvEE = Base64.decode("MIICJjCCAY+gAwIBAAIGAV3Y0TnDMA0GCSqGSIb3DQEBCwUAMBExDzANBgNVBAMMBktQMSBDQTAeFw0xNzA4MTIyMzM5MzJaFw0xNzA4MTMwMDA5MzdaMBExDzANBgNVBAMMBktQMSBFRTCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAuOcqkp2+HBCuwRDwfR7kkUYXMdhScDG8m6A3Af6hpG86nAimNoVIQe3REaQ6IO0XSdd13rjjRwIXsUFLsrQhQJczF5JeyWXcaYqZyNNbUwFuLeSqOsLS63ltjOJYqOJRxY03Cr//baGWvxGXcRvHoZkg1nEXPcMZhgsy/9JxVoUCAwEAAaOBiDCBhTBABgNVHSMEOTA3gBSPMqzNmTdyjQmr9W1TSDW1h0ZzFaEXpBUwEzERMA8GA1UEAwwIS1AxIFJPT1SCBgFd2NE5wjAdBgNVHQ4EFgQUC1rtYrQdQkA3CLTeV1kbVIdysKQwEgYDVR0TAQH/BAgwBgEB/wIBADAOBgNVHQ8BAf8EBAMCAYYwDQYJKoZIhvcNAQELBQADgYEAGr841G7E84Ow9+fFGW1zzXeTRfxsafdT/bHXCS75bjF2YPitKLcRLkm92VPxANRXIpmt++3iU/oduWqkLsfXnfTGmCwtjj/XrCvkCBQ4GONwmegltJEThMud0XOEB1UN6tfTINfLYpbyfOdE/wLy4Rte0t43aOTTOBo+/SapYOE=");
559     static byte[] extInvCA = Base64.decode("MIICKDCCAZGgAwIBAgIGAV3Y0TnCMA0GCSqGSIb3DQEBCwUAMBMxETAPBgNVBAMMCEtQMSBST09UMB4XDTE3MDgxMjIzMzkzMloXDTE3MDgxMzAwMDkzN1owETEPMA0GA1UEAwwGS1AxIENBMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC7Qd/cTP5S0GoPcomcZU5QlJcb1uWydvmQx3U6p4/KOZBhk6JXQeSzT8QZ/gd+9vfosA62SEX+dq7MvxxzeERxdIsVU0zZ1TrYNxlQjnYXiYRVXBczowsxseQ9oSGD94Y4buhrMAltmIHijdzGRVMY41FZmWqNXqsEwQXj6ULX+QIDAQABo4GIMIGFMEAGA1UdIwQ5MDeAFAbfd2S3aiwFww3/0ocLa6ULQjJMoRekFTATMREwDwYDVQQDDAhLUDEgUk9PVIIGAV3Y0TnBMB0GA1UdDgQWBBSPMqzNmTdyjQmr9W1TSDW1h0ZzFTASBgNVHRMBAf8ECDAGAQH/AgEAMA4GA1UdDwEB/wQEAwIBhjANBgkqhkiG9w0BAQsFAAOBgQCnmxQYy6LnvRSMxkTsGIQa4LB51O8skbWc4KYVDfcvTYQuvn6rE/ZoYf82jKXJzXksffanfjn/b38l4l8hwAcBQ8we9yjCkjO8OVDUlYiSGYUhH2ZJrl2+K2Z6wpakZ9Lz3pZ/PSS1FIsVd4I1jkexAdAm1+uMlfWXVt/uTZx98w==");
560     static byte[] extInvTrust = Base64.decode("MIIBmjCCAQMCBgFd2NE5wTANBgkqhkiG9w0BAQsFADATMREwDwYDVQQDDAhLUDEgUk9PVDAeFw0xNzA4MTIyMzM5MzJaFw0xNzA4MTMwMDA5MzdaMBMxETAPBgNVBAMMCEtQMSBST09UMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC8U3p6Y9ah0yQ58wpI3H6vQPMdhN6Hh+zuiNzwX3AIpEspUFTfqXJ6EIhqh/EraDnLnoFBajzihwS1y6a+ZyXYKa5pxbFsslmzms+ozcTaJ4mSMiC+DHbGYdOAEzwx2nsEt7UKyrlnl5h2kQFusUPmnXXEorIxhpS2Lul+zEBo1wIDAQABMA0GCSqGSIb3DQEBCwUAA4GBABClwXaJ8S66GmeySf1thOPc1GxIHuubezIjcBbECLZQqn7iwuzp+eft1vtnqNP7BWM1xBZkSe+/2xUsArc1rb1ffZHF3k92+WLbpDh3+NsQIod/91HRWUuu/S2g9oMK4b7BH8JrmBgy3ewtpNZwOaKF613GPCeGv3ya5Z24vBu+");
561 
562     static byte[] extInvV2Trust = Base64.decode("MIIBmjCCAQMCBgFd2NhVgTANBgkqhkiG9w0BAQsFADATMREwDwYDVQQDDAhLUDEgUk9PVDAeFw0xNzA4MTIyMzQ3MThaFw0xNzA4MTMwMDE3MjNaMBMxETAPBgNVBAMMCEtQMSBST09UMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCQaASWM5avAAJ57eHQ2zQ0k/mAiYSOkRKDLEzptDPYfzuQtTdAlBPn7tsYx+Ylge4YQwtx5bQZbc3apinBK9tn+c++go0kUF1cec2bacYyFokSP2r48j6ZhlY4MYGfrvfWHULrG2JL2BMeuZVP+wiqXktXCEKVG1fh1m6RY0TJPwIDAQABMA0GCSqGSIb3DQEBCwUAA4GBAC9mXO2i2vltBZZa7RMkizvhzhsehDHbEqvJd2aoWE9JG4sDo2tiIVN5vbq9EWLZVga3ejFzmQ+FI1Ty0xX3fwDgvUyxsveGTs40xwA9TEgVk1KNTQQs+sLE9rRB7L0giKn2DDmHFsOPL1KwxdzqD7vYhJr5av3eAsJpMxF+Anyg");
563     static byte[] extInvV2CA = Base64.decode("MIICKDCCAZGgAwIBAgIGAV3Y2FWCMA0GCSqGSIb3DQEBCwUAMBMxETAPBgNVBAMMCEtQMSBST09UMB4XDTE3MDgxMjIzNDcxOFoXDTE3MDgxMzAwMTcyM1owETEPMA0GA1UEAwwGS1AxIENBMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCgb8h3h9d/FzhIc+PMbF0vwdiDKw7N3dNyY6TrmzCMC1mYDXSKmxxDwNKZCKj6VSNfbTDqxYKlZMoGVT8Cl/iE/+XEhOKYLv73rzTqzdMizqcQTCvwps1enGxI5wPBYKGCMWrpJui5RWV9wH6hMvmzSSZq7bdWTvc/pIltCpIj8wIDAQABo4GIMIGFMEAGA1UdIwQ5MDeAFMOcs/uWpVOkGRQJrVIp6cN6tCJQoRekFTATMREwDwYDVQQDDAhLUDEgUk9PVIIGAV3Y2FWBMB0GA1UdDgQWBBTsZ2B5JbgKm9/up2hOcYVyOaM1SjASBgNVHRMBAf8ECDAGAQH/AgEAMA4GA1UdDwEB/wQEAwIBhjANBgkqhkiG9w0BAQsFAAOBgQBI8J1bKh/e+uEZtfngKMADS1PSHztAPFFKXgeIfYeJDRznnamtbheensdxrA+aoriJbJfHxmjecr4xA8+s0uN9GPtQ3+ad1K5Sg6mfzsXtNPf3xa9y0pIWOGZavr1s/QugoPLQxEiuHrvkHX5+sZlx47KoBQJ8LBRmJydeSvxz1g==");
564     static byte[] extInvV2EE = Base64.decode("MIICJjCCAY+gAwIBAQIGAV3Y2FWDMA0GCSqGSIb3DQEBCwUAMBExDzANBgNVBAMMBktQMSBDQTAeFw0xNzA4MTIyMzQ3MThaFw0xNzA4MTMwMDE3MjNaMBExDzANBgNVBAMMBktQMSBFRTCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAzWXxtMpnjz8Q1qTdwpB66W2D0vEHhqow2PTsvfQdENL4AFESE1C7Cj3lLBTei1vRHCnpM0jdNghBW8k/u2b2tqeeWLBqwul0tEGbjtUwkYV2WgtTGmiYZZFfMH35HIvqlZMwIIdZqz4lEdkPiAPEUOELvycpVDFnWjF0qah5LqsCAwEAAaOBiDCBhTBABgNVHSMEOTA3gBTsZ2B5JbgKm9/up2hOcYVyOaM1SqEXpBUwEzERMA8GA1UEAwwIS1AxIFJPT1SCBgFd2NhVgjAdBgNVHQ4EFgQUfeKdn63Gmlkub8m8bwjqJook5ywwEgYDVR0TAQH/BAgwBgEB/wIBADAOBgNVHQ8BAf8EBAMCAYYwDQYJKoZIhvcNAQELBQADgYEAco35KYLE683l53J6V1q2tcMV3EpM39tifkL7Kl38oX9d3SGiKkEO6YFeQekRyto0Z91mPq7Pe/oOfDrfsY3r9KX7oqnhOKBnnR/58atM9udVLvuLfCJpxiroAldSkhRKvHG5MrFwZyDcVkTZF4GDrP6bojp32wVfU5EYkfwcJN8=");
565 
566     static byte[] extInvVersionTrust = Base64.decode("MIIBmjCCAQMCBgFd2RZiPjANBgkqhkiG9w0BAQsFADATMREwDwYDVQQDDAhLUDEgUk9PVDAeFw0xNzA4MTMwMDU1MDRaFw0xNzA4MTMwMTI1MDlaMBMxETAPBgNVBAMMCEtQMSBST09UMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCPn6zObnrjGPUb0ozc3MCOOcHwtQABZmUHtB1jxRXWwYXKo+iTms2wJjDS5fhz2UmUptsbdFwPdvT2t7K8cpaZBcovC3jLvEAMmjO+nU3FQrdopZ6MhBjpgIezAvJ9LUhrYctqUJzfViqtLl0dL+YRjaVdfCz5z0iZn4rv2VSf3QIDAQABMA0GCSqGSIb3DQEBCwUAA4GBAHtS9RjMIRzeEpH9MKIaMLR7wVb55MYW7E2CVuIbsHmT+KyDBFsYbAylgc76cH1b8F53ECygS9jCpzfKtO61WVPPlUhsL13i2XbzCtj8DSPXaW5pgvpwClQZ+dpGFz8D/MYLSdjTdls8dbhJ5O08ckSKcrIGHcF90oeepVXOmiTw");
567     static byte[] extInvVersionCA = Base64.decode(    "MIICKDCCAZGgAwIBAgIGAV3ZFmI/MA0GCSqGSIb3DQEBCwUAMBMxETAPBgNVBAMMCEtQMSBST09UMB4XDTE3MDgxMzAwNTUwNFoXDTE3MDgxMzAxMjUwOVowETEPMA0GA1UEAwwGS1AxIENBMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQChlaZhX9/eHmtfravHzs/E0g6ZhWTmD9aNNvuuz/GCBF9AMS6QQCGVhEzxESn0gLzs1bM/9M/EaylHS3Ecvi6QYdkrTKRDj38FDzrDhiPlM3TxY0XuUQ3Py590k8yZDcuEeVEQeoUx83qOnO7o/cL+vECfMj9ImYFFgY5sMcKkVQIDAQABo4GIMIGFMEAGA1UdIwQ5MDeAFAfTyJtmNkinVjfd7/2Giy6krDTpoRekFTATMREwDwYDVQQDDAhLUDEgUk9PVIIGAV3ZFmI+MB0GA1UdDgQWBBQkMq+wajXvKQaJtSdpvDJn77bU9zASBgNVHRMBAf8ECDAGAQH/AgEAMA4GA1UdDwEB/wQEAwIBhjANBgkqhkiG9w0BAQsFAAOBgQAqmKtykmixemAvppo2tTmekLsL93+/DMR+oz1iK2rjhqYzEF1/pM9VUyG+Ni1924U8tzGbXv2lL3MiToRSyjO50HHfnE7PfOvNiTUj73PTn27tPl03eWO3CtsOTGxtE2vpNyXyFXm4SFZlSicOXE0o/kUrNGVYvnjs/jjcNlPiHQ==");
568     static byte[] extInvVersionEE = Base64.decode(   "MIICJjCCAY+gAwIBBQIGAV3ZFmJAMA0GCSqGSIb3DQEBCwUAMBExDzANBgNVBAMMBktQMSBDQTAeFw0xNzA4MTMwMDU1MDRaFw0xNzA4MTMwMTI1MDlaMBExDzANBgNVBAMMBktQMSBFRTCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEA6PXdCOvE33+mMcal/rC+I7zdJqcc6OBhn+Lyku29TRcYplMA5mkh7WkjLtRYBUAzHukN/GXb1Mo+dFkvCnKO/l4gLWyVuf23rL6iELt8X1KVJdJlrDElCmTgl6lA0Omq7QhNrsv5Vdk7mK2mbJzl0bj4fcu5dc23nQXEskmGrZsCAwEAAaOBiDCBhTBABgNVHSMEOTA3gBQkMq+wajXvKQaJtSdpvDJn77bU96EXpBUwEzERMA8GA1UEAwwIS1AxIFJPT1SCBgFd2RZiPzAdBgNVHQ4EFgQU3Nw/DFxNqK1fRhc/W8W4o3mkCHQwEgYDVR0TAQH/BAgwBgEB/wIBADAOBgNVHQ8BAf8EBAMCAYYwDQYJKoZIhvcNAQELBQADgYEAjMTiKgLC2Kb5+elvfD/+CM8pNeLt5Y43sMSTpgIrebdWPA2hyvjvW/upsIYIquGrymOYBU/K0abQlkNUbBHpQCQMPQ6iPXuhTQj/P7rt7McLl6OXV/DQqgF+39y0xWAzoZbgMKrQaSr9oRmEVt6xzLM92JS67w8Xgbh39PGBfEg=");
569 
570     static byte[] extInvExtTrust = Base64.decode("MIIBmjCCAQMCBgFd2SFqKjANBgkqhkiG9w0BAQsFADATMREwDwYDVQQDDAhLUDEgUk9PVDAeFw0xNzA4MTMwMTA3MDdaFw0xNzA4MTMwMTM3MTJaMBMxETAPBgNVBAMMCEtQMSBST09UMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDEY3toxiphhoeoTd79/Uznb1YyKjYgxtXkYVQLZ+Q76bJFQftVVcUHw25/A/2qgSc8XPflGRpn82Qn/B7s3fxEglgeY0ekdYjea5+jZSJj70p1QcC60yH1NKGxE0ASBuv/22IoHhdu5dOTmiWegikKUXblBD1wAxbbvOcXFs2x/wIDAQABMA0GCSqGSIb3DQEBCwUAA4GBAJPG9wt9edpTaCc0z03xGNF/M6x5cLx5eLgZaBFt+FO3S1xWIVby+iU8Hw2mzHOc58Fghw1jEwLaslQYadx9667NedGu7dYyY318h+VhaDppQqkhJiQl5Q8aTvVNt60fDEVLjvB7E6Z+CafVGR1jNrXxLDe6zVf/BZJK7QrkTKh4");
571     static byte[] extInvExtCA = Base64.decode("MIICKDCCAZGgAwIBAgIGAV3ZIWorMA0GCSqGSIb3DQEBCwUAMBMxETAPBgNVBAMMCEtQMSBST09UMB4XDTE3MDgxMzAxMDcwN1oXDTE3MDgxMzAxMzcxMlowETEPMA0GA1UEAwwGS1AxIENBMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCJKySmanEENpLJdPwpM/v0I7H0bW9ZlIxRpiL+/Z4uvF3j0r0O42Tm+dW8Ub42DzHcQ8pK/n/k2Wb4Jf7cP8+TGTAne3bgC24USW131XUZxaunGt4tCqZ0RNWpmBQUcUM0lgntDSfcvyv3QFB+nwLc93GYij9l3FaeUcHkwFiKsQIDAQABo4GIMIGFMEAGA1UdIwQ5MDeAFLnC9UF+JqEqboFH84ab9dEAkwEBoRekFTATMREwDwYDVQQDDAhLUDEgUk9PVIIGAV3ZIWoqMB0GA1UdDgQWBBQkr/0UP1MKPGQH7bkRNctHMsVQsjASBgNVHRMBAf8ECDAGAQH/AgEAMA4GA1UdDwEB/wQEAwIBhjANBgkqhkiG9w0BAQsFAAOBgQCZxLwkAPif1H2P398MHK3NLf3mrmLsP41ZphdHnSLNROlY9PdO5I/dfhElzVXW2oxecIIKbOQsjZe0FOSGvZHEhLftQmOdfGc5QfGf5w9CSFCCBe5vHdMjglRLVhNB51jz6DB7Dp0MjFDgkQI4lBHaiMVkE+HUZjNLwBddHH58Sw==");
572     static byte[] extInvExtEE = Base64.decode("MIICNjCCAZ+gAwIBAgIGAV3ZIWosMA0GCSqGSIb3DQEBCwUAMBExDzANBgNVBAMMBktQMSBDQTAeFw0xNzA4MTMwMTA3MDdaFw0xNzA4MTMwMTM3MTJaMBExDzANBgNVBAMMBktQMSBFRTCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAj6WOoo8xHLLo+CT0l288xZDK3OsF64lPfNVkFnrRI65Ywl89M19nNF5Q24hF1FS6getO5oU+BhvRqft1/De22SME9SzKqs3G6uMxACKrMqgni1QBEOC/DdZ5Uaxh2s4lEgxbN0PQZIarAgLtAIgzRM4CrvofxFMwQy/neUuWmeMCAwEAAaOBmDCBlTBABgNVHSMEOTA3gBQkr/0UP1MKPGQH7bkRNctHMsVQsqEXpBUwEzERMA8GA1UEAwwIS1AxIFJPT1SCBgFd2SFqKzAdBgNVHQ4EFgQU/yuQXlvqXJQsbqB6whCPu5bwFCAwEgYDVR0TAQH/BAgwBgEB/wIBADAOBgNVHQ8BAf8EBAMCAYYwDgYDVR0PAQH/BAQDAgGGMA0GCSqGSIb3DQEBCwUAA4GBABYUGar9s7wlM3Qlnja7uc7U8FqU+xH4e8/Jk64ku7DdwXelEbKo/FTFAzh464aiFP4eMDOH7YThXyTruPudEAvYyWY7eaEgRqA2MmL0uWHSrN+HR9aBeqrMCJK/E2e1egvk2whJHMimhDUFJ3cIPsFhazMvLTnVgWGMjOqQtuP+");
573 
checkInvalidCertPath()574     private void checkInvalidCertPath()
575         throws Exception
576     {
577         checkInvalidPath(extInvTrust, extInvCA, extInvEE, "version 1 certificate contains extra data");
578         checkInvalidPath(extInvV2Trust, extInvV2CA, extInvV2EE, "version 2 certificate cannot contain extensions");
579         checkInvalidPath(extInvVersionTrust, extInvVersionCA, extInvVersionEE, "version number not recognised");
580         checkInvalidPath(extInvExtTrust, extInvExtCA, extInvExtEE, "repeated extension found: 2.5.29.15");
581     }
582 
checkInvalidPath(byte[] root, byte[] inter, byte[] ee, String expected)583     private void checkInvalidPath(byte[] root, byte[] inter, byte[] ee, String expected)
584         throws Exception
585     {
586         X509Certificate rootCert = new X509CertificateObject(X509CertificateStructure.getInstance(root));
587         X509Certificate interCert = new X509CertificateObject(X509CertificateStructure.getInstance(inter));
588         X509Certificate finalCert = new X509CertificateObject(X509CertificateStructure.getInstance(ee));
589         List list = new ArrayList();
590         list.add(rootCert);
591         list.add(interCert);
592         list.add(finalCert);
593 
594         CollectionCertStoreParameters ccsp = new CollectionCertStoreParameters(list);
595         CertStore store = CertStore.getInstance("Collection", ccsp, "BC");
596         Date validDate = new Date(rootCert.getNotBefore().getTime() + 60 * 1000);
597         //validating path
598         List certchain = new ArrayList();
599         certchain.add(finalCert);
600         certchain.add(interCert);
601         CertPath cp = CertificateFactory.getInstance("X.509", "BC").generateCertPath(certchain);
602         Set trust = new HashSet();
603         trust.add(new TrustAnchor(rootCert, null));
604 
605         CertPathValidator cpv = CertPathValidator.getInstance("PKIX", "BC");
606         PKIXParameters param = new PKIXParameters(trust);
607         param.addCertStore(store);
608         param.setDate(validDate);
609         param.setRevocationEnabled(false);
610 
611         try
612         {
613             PKIXCertPathValidatorResult result = (PKIXCertPathValidatorResult)cpv.validate(cp, param);
614             fail("valid path passed");
615         }
616         catch (CertPathValidatorException e)
617         {
618             isTrue(e.getMessage().equals(expected));
619         }
620 
621         // check that our cert factory also rejects - the EE is always the invalid one
622         CertificateFactory cf = CertificateFactory.getInstance("X.509", "BC");
623 
624         try
625         {
626             cf.generateCertificate(new ByteArrayInputStream(ee));
627         }
628         catch (CertificateException e)
629         {
630             isTrue(e.getMessage().equals("parsing issue: " + expected));
631         }
632     }
633 
getName()634     public String getName()
635     {
636         return "CertPathValidator";
637     }
638 
main( String[] args)639     public static void main(
640         String[] args)
641     {
642         Security.addProvider(new BouncyCastleProvider());
643 
644         runTest(new CertPathValidatorTest());
645     }
646 
647     private static class MyChecker
648         extends PKIXCertPathChecker
649     {
650         private static int count;
651 
init(boolean forward)652         public void init(boolean forward)
653             throws CertPathValidatorException
654         {
655             //To change body of implemented methods use File | Settings | File Templates.
656         }
657 
isForwardCheckingSupported()658         public boolean isForwardCheckingSupported()
659         {
660             return true;
661         }
662 
getSupportedExtensions()663         public Set getSupportedExtensions()
664         {
665             return null;
666         }
667 
check(Certificate cert, Collection unresolvedCritExts)668         public void check(Certificate cert, Collection unresolvedCritExts)
669             throws CertPathValidatorException
670         {
671             count++;
672         }
673 
getCount()674         public int getCount()
675         {
676             return count;
677         }
678     }
679 
680     public static class X509CertificateObject
681         extends X509Certificate
682     {
683         static final String CERTIFICATE_POLICIES = Extension.certificatePolicies.getId();
684         static final String POLICY_MAPPINGS = Extension.policyMappings.getId();
685         static final String INHIBIT_ANY_POLICY = Extension.inhibitAnyPolicy.getId();
686         static final String ISSUING_DISTRIBUTION_POINT = Extension.issuingDistributionPoint.getId();
687         static final String FRESHEST_CRL = Extension.freshestCRL.getId();
688         static final String DELTA_CRL_INDICATOR = Extension.deltaCRLIndicator.getId();
689         static final String POLICY_CONSTRAINTS = Extension.policyConstraints.getId();
690         static final String BASIC_CONSTRAINTS = Extension.basicConstraints.getId();
691         static final String CRL_DISTRIBUTION_POINTS = Extension.cRLDistributionPoints.getId();
692         static final String SUBJECT_ALTERNATIVE_NAME = Extension.subjectAlternativeName.getId();
693         static final String NAME_CONSTRAINTS = Extension.nameConstraints.getId();
694         static final String AUTHORITY_KEY_IDENTIFIER = Extension.authorityKeyIdentifier.getId();
695         static final String KEY_USAGE = Extension.keyUsage.getId();
696         static final String CRL_NUMBER = Extension.cRLNumber.getId();
697         static final String ANY_POLICY = "2.5.29.32.0";
698 
699         private org.bouncycastle.asn1.x509.X509CertificateStructure c;
700         private BasicConstraints basicConstraints;
701         private boolean[] keyUsage;
702         private boolean hashValueSet;
703         private int hashValue;
704 
X509CertificateObject( org.bouncycastle.asn1.x509.X509CertificateStructure c)705         public X509CertificateObject(
706             org.bouncycastle.asn1.x509.X509CertificateStructure c)
707             throws CertificateParsingException
708         {
709             this.c = c;
710 
711             try
712             {
713                 byte[] bytes = this.getExtensionBytes("2.5.29.19");
714 
715                 if (bytes != null)
716                 {
717                     basicConstraints = BasicConstraints.getInstance(ASN1Primitive.fromByteArray(bytes));
718                 }
719             }
720             catch (Exception e)
721             {
722                 throw new CertificateParsingException("cannot construct BasicConstraints: " + e);
723             }
724 
725             try
726             {
727                 byte[] bytes = this.getExtensionBytes("2.5.29.15");
728                 if (bytes != null)
729                 {
730                     ASN1BitString bits = DERBitString.getInstance(ASN1Primitive.fromByteArray(bytes));
731 
732                     bytes = bits.getBytes();
733                     int length = (bytes.length * 8) - bits.getPadBits();
734 
735                     keyUsage = new boolean[(length < 9) ? 9 : length];
736 
737                     for (int i = 0; i != length; i++)
738                     {
739                         keyUsage[i] = (bytes[i / 8] & (0x80 >>> (i % 8))) != 0;
740                     }
741                 }
742                 else
743                 {
744                     keyUsage = null;
745                 }
746             }
747             catch (Exception e)
748             {
749                 throw new CertificateParsingException("cannot construct KeyUsage: " + e);
750             }
751         }
752 
checkValidity()753         public void checkValidity()
754             throws CertificateExpiredException, CertificateNotYetValidException
755         {
756             this.checkValidity(new Date());
757         }
758 
checkValidity( Date date)759         public void checkValidity(
760             Date date)
761             throws CertificateExpiredException, CertificateNotYetValidException
762         {
763             if (date.getTime() > this.getNotAfter().getTime())  // for other VM compatibility
764             {
765                 throw new CertificateExpiredException("certificate expired on " + c.getEndDate().getTime());
766             }
767 
768             if (date.getTime() < this.getNotBefore().getTime())
769             {
770                 throw new CertificateNotYetValidException("certificate not valid till " + c.getStartDate().getTime());
771             }
772         }
773 
getVersion()774         public int getVersion()
775         {
776             return c.getVersion();
777         }
778 
getSerialNumber()779         public BigInteger getSerialNumber()
780         {
781             return c.getSerialNumber().getValue();
782         }
783 
getIssuerDN()784         public Principal getIssuerDN()
785         {
786             try
787             {
788                 return new X509Principal(X500Name.getInstance(c.getIssuer().getEncoded()));
789             }
790             catch (IOException e)
791             {
792                 return null;
793             }
794         }
795 
getIssuerX500Principal()796         public X500Principal getIssuerX500Principal()
797         {
798             try
799             {
800                 return new X500Principal(c.getIssuer().getEncoded());
801             }
802             catch (IOException e)
803             {
804                 throw new IllegalStateException("can't encode issuer DN");
805             }
806         }
807 
getSubjectDN()808         public Principal getSubjectDN()
809         {
810             return new X509Principal(X500Name.getInstance(c.getSubject().toASN1Primitive()));
811         }
812 
getSubjectX500Principal()813         public X500Principal getSubjectX500Principal()
814         {
815             try
816             {
817                 return new X500Principal(c.getSubject().getEncoded());
818             }
819             catch (IOException e)
820             {
821                 throw new IllegalStateException("can't encode issuer DN");
822             }
823         }
824 
getNotBefore()825         public Date getNotBefore()
826         {
827             return c.getStartDate().getDate();
828         }
829 
getNotAfter()830         public Date getNotAfter()
831         {
832             return c.getEndDate().getDate();
833         }
834 
getTBSCertificate()835         public byte[] getTBSCertificate()
836             throws CertificateEncodingException
837         {
838             try
839             {
840                 return c.getTBSCertificate().getEncoded(ASN1Encoding.DER);
841             }
842             catch (IOException e)
843             {
844                 throw new CertificateEncodingException(e.toString());
845             }
846         }
847 
getSignature()848         public byte[] getSignature()
849         {
850             return c.getSignature().getOctets();
851         }
852 
853         /**
854          * return a more "meaningful" representation for the signature algorithm used in
855          * the certficate.
856          */
getSigAlgName()857         public String getSigAlgName()
858         {
859             Provider prov = Security.getProvider(BouncyCastleProvider.PROVIDER_NAME);
860 
861             if (prov != null)
862             {
863                 String algName = prov.getProperty("Alg.Alias.Signature." + this.getSigAlgOID());
864 
865                 if (algName != null)
866                 {
867                     return algName;
868                 }
869             }
870 
871             Provider[] provs = Security.getProviders();
872 
873             //
874             // search every provider looking for a real algorithm
875             //
876             for (int i = 0; i != provs.length; i++)
877             {
878                 String algName = provs[i].getProperty("Alg.Alias.Signature." + this.getSigAlgOID());
879                 if (algName != null)
880                 {
881                     return algName;
882                 }
883             }
884 
885             return this.getSigAlgOID();
886         }
887 
888         /**
889          * return the object identifier for the signature.
890          */
getSigAlgOID()891         public String getSigAlgOID()
892         {
893             return c.getSignatureAlgorithm().getAlgorithm().getId();
894         }
895 
896         /**
897          * return the signature parameters, or null if there aren't any.
898          */
getSigAlgParams()899         public byte[] getSigAlgParams()
900         {
901             if (c.getSignatureAlgorithm().getParameters() != null)
902             {
903                 try
904                 {
905                     return c.getSignatureAlgorithm().getParameters().toASN1Primitive().getEncoded(ASN1Encoding.DER);
906                 }
907                 catch (IOException e)
908                 {
909                     return null;
910                 }
911             }
912             else
913             {
914                 return null;
915             }
916         }
917 
getIssuerUniqueID()918         public boolean[] getIssuerUniqueID()
919         {
920             DERBitString id = c.getTBSCertificate().getIssuerUniqueId();
921 
922             if (id != null)
923             {
924                 byte[] bytes = id.getBytes();
925                 boolean[] boolId = new boolean[bytes.length * 8 - id.getPadBits()];
926 
927                 for (int i = 0; i != boolId.length; i++)
928                 {
929                     boolId[i] = (bytes[i / 8] & (0x80 >>> (i % 8))) != 0;
930                 }
931 
932                 return boolId;
933             }
934 
935             return null;
936         }
937 
getSubjectUniqueID()938         public boolean[] getSubjectUniqueID()
939         {
940             DERBitString id = c.getTBSCertificate().getSubjectUniqueId();
941 
942             if (id != null)
943             {
944                 byte[] bytes = id.getBytes();
945                 boolean[] boolId = new boolean[bytes.length * 8 - id.getPadBits()];
946 
947                 for (int i = 0; i != boolId.length; i++)
948                 {
949                     boolId[i] = (bytes[i / 8] & (0x80 >>> (i % 8))) != 0;
950                 }
951 
952                 return boolId;
953             }
954 
955             return null;
956         }
957 
getKeyUsage()958         public boolean[] getKeyUsage()
959         {
960             return keyUsage;
961         }
962 
getExtendedKeyUsage()963         public List getExtendedKeyUsage()
964             throws CertificateParsingException
965         {
966             byte[] bytes = this.getExtensionBytes("2.5.29.37");
967 
968             if (bytes != null)
969             {
970                 try
971                 {
972                     ASN1InputStream dIn = new ASN1InputStream(bytes);
973                     ASN1Sequence seq = (ASN1Sequence)dIn.readObject();
974                     List list = new ArrayList();
975 
976                     for (int i = 0; i != seq.size(); i++)
977                     {
978                         list.add(((ASN1ObjectIdentifier)seq.getObjectAt(i)).getId());
979                     }
980 
981                     return Collections.unmodifiableList(list);
982                 }
983                 catch (Exception e)
984                 {
985                     throw new CertificateParsingException("error processing extended key usage extension");
986                 }
987             }
988 
989             return null;
990         }
991 
getBasicConstraints()992         public int getBasicConstraints()
993         {
994             if (basicConstraints != null)
995             {
996                 if (basicConstraints.isCA())
997                 {
998                     if (basicConstraints.getPathLenConstraint() == null)
999                     {
1000                         return Integer.MAX_VALUE;
1001                     }
1002                     else
1003                     {
1004                         return basicConstraints.getPathLenConstraint().intValue();
1005                     }
1006                 }
1007                 else
1008                 {
1009                     return -1;
1010                 }
1011             }
1012 
1013             return -1;
1014         }
1015 
getSubjectAlternativeNames()1016         public Collection getSubjectAlternativeNames()
1017             throws CertificateParsingException
1018         {
1019             return getAlternativeNames(getExtensionBytes(Extension.subjectAlternativeName.getId()));
1020         }
1021 
getIssuerAlternativeNames()1022         public Collection getIssuerAlternativeNames()
1023             throws CertificateParsingException
1024         {
1025             return getAlternativeNames(getExtensionBytes(Extension.issuerAlternativeName.getId()));
1026         }
1027 
getCriticalExtensionOIDs()1028         public Set getCriticalExtensionOIDs()
1029         {
1030             if (this.getVersion() == 3)
1031             {
1032                 Set set = new HashSet();
1033                 X509Extensions extensions = c.getTBSCertificate().getExtensions();
1034 
1035                 if (extensions != null)
1036                 {
1037                     Enumeration e = extensions.oids();
1038 
1039                     while (e.hasMoreElements())
1040                     {
1041                         ASN1ObjectIdentifier oid = (ASN1ObjectIdentifier)e.nextElement();
1042                         X509Extension ext = extensions.getExtension(oid);
1043 
1044                         if (ext.isCritical())
1045                         {
1046                             set.add(oid.getId());
1047                         }
1048                     }
1049 
1050                     return set;
1051                 }
1052             }
1053 
1054             return null;
1055         }
1056 
getExtensionBytes(String oid)1057         private byte[] getExtensionBytes(String oid)
1058         {
1059             X509Extensions exts = c.getTBSCertificate().getExtensions();
1060 
1061             if (exts != null)
1062             {
1063                 X509Extension ext = exts.getExtension(new ASN1ObjectIdentifier(oid));
1064                 if (ext != null)
1065                 {
1066                     return ext.getValue().getOctets();
1067                 }
1068             }
1069 
1070             return null;
1071         }
1072 
getExtensionValue(String oid)1073         public byte[] getExtensionValue(String oid)
1074         {
1075             X509Extensions exts = c.getTBSCertificate().getExtensions();
1076 
1077             if (exts != null)
1078             {
1079                 X509Extension ext = exts.getExtension(new ASN1ObjectIdentifier(oid));
1080 
1081                 if (ext != null)
1082                 {
1083                     try
1084                     {
1085                         return ext.getValue().getEncoded();
1086                     }
1087                     catch (Exception e)
1088                     {
1089                         throw new IllegalStateException("error parsing " + e.toString());
1090                     }
1091                 }
1092             }
1093 
1094             return null;
1095         }
1096 
getNonCriticalExtensionOIDs()1097         public Set getNonCriticalExtensionOIDs()
1098         {
1099             if (this.getVersion() == 3)
1100             {
1101                 Set set = new HashSet();
1102                 X509Extensions extensions = c.getTBSCertificate().getExtensions();
1103 
1104                 if (extensions != null)
1105                 {
1106                     Enumeration e = extensions.oids();
1107 
1108                     while (e.hasMoreElements())
1109                     {
1110                         ASN1ObjectIdentifier oid = (ASN1ObjectIdentifier)e.nextElement();
1111                         X509Extension ext = extensions.getExtension(oid);
1112 
1113                         if (!ext.isCritical())
1114                         {
1115                             set.add(oid.getId());
1116                         }
1117                     }
1118 
1119                     return set;
1120                 }
1121             }
1122 
1123             return null;
1124         }
1125 
hasUnsupportedCriticalExtension()1126         public boolean hasUnsupportedCriticalExtension()
1127         {
1128             if (this.getVersion() == 3)
1129             {
1130                 X509Extensions extensions = c.getTBSCertificate().getExtensions();
1131 
1132                 if (extensions != null)
1133                 {
1134                     Enumeration e = extensions.oids();
1135 
1136                     while (e.hasMoreElements())
1137                     {
1138                         ASN1ObjectIdentifier oid = (ASN1ObjectIdentifier)e.nextElement();
1139                         String oidId = oid.getId();
1140 
1141                         if (oidId.equals(KEY_USAGE)
1142                             || oidId.equals(CERTIFICATE_POLICIES)
1143                             || oidId.equals(POLICY_MAPPINGS)
1144                             || oidId.equals(INHIBIT_ANY_POLICY)
1145                             || oidId.equals(CRL_DISTRIBUTION_POINTS)
1146                             || oidId.equals(ISSUING_DISTRIBUTION_POINT)
1147                             || oidId.equals(DELTA_CRL_INDICATOR)
1148                             || oidId.equals(POLICY_CONSTRAINTS)
1149                             || oidId.equals(BASIC_CONSTRAINTS)
1150                             || oidId.equals(SUBJECT_ALTERNATIVE_NAME)
1151                             || oidId.equals(NAME_CONSTRAINTS))
1152                         {
1153                             continue;
1154                         }
1155 
1156                         X509Extension ext = extensions.getExtension(oid);
1157 
1158                         if (ext.isCritical())
1159                         {
1160                             return true;
1161                         }
1162                     }
1163                 }
1164             }
1165 
1166             return false;
1167         }
1168 
getPublicKey()1169         public PublicKey getPublicKey()
1170         {
1171             try
1172             {
1173                 return BouncyCastleProvider.getPublicKey(c.getSubjectPublicKeyInfo());
1174             }
1175             catch (IOException e)
1176             {
1177                 return null;   // should never happen...
1178             }
1179         }
1180 
getEncoded()1181         public byte[] getEncoded()
1182             throws CertificateEncodingException
1183         {
1184             try
1185             {
1186                 return c.getEncoded(ASN1Encoding.DER);
1187             }
1188             catch (IOException e)
1189             {
1190                 throw new CertificateEncodingException(e.toString());
1191             }
1192         }
1193 
equals( Object o)1194         public boolean equals(
1195             Object o)
1196         {
1197             if (o == this)
1198             {
1199                 return true;
1200             }
1201 
1202             if (!(o instanceof Certificate))
1203             {
1204                 return false;
1205             }
1206 
1207             Certificate other = (Certificate)o;
1208 
1209             try
1210             {
1211                 byte[] b1 = this.getEncoded();
1212                 byte[] b2 = other.getEncoded();
1213 
1214                 return Arrays.areEqual(b1, b2);
1215             }
1216             catch (CertificateEncodingException e)
1217             {
1218                 return false;
1219             }
1220         }
1221 
hashCode()1222         public synchronized int hashCode()
1223         {
1224             if (!hashValueSet)
1225             {
1226                 hashValue = calculateHashCode();
1227                 hashValueSet = true;
1228             }
1229 
1230             return hashValue;
1231         }
1232 
calculateHashCode()1233         private int calculateHashCode()
1234         {
1235             try
1236             {
1237                 int hashCode = 0;
1238                 byte[] certData = this.getEncoded();
1239                 for (int i = 1; i < certData.length; i++)
1240                 {
1241                     hashCode += certData[i] * i;
1242                 }
1243                 return hashCode;
1244             }
1245             catch (CertificateEncodingException e)
1246             {
1247                 return 0;
1248             }
1249         }
1250 
toString()1251         public String toString()
1252         {
1253             StringBuffer buf = new StringBuffer();
1254             String nl = Strings.lineSeparator();
1255 
1256             buf.append("  [0]         Version: ").append(this.getVersion()).append(nl);
1257             buf.append("         SerialNumber: ").append(this.getSerialNumber()).append(nl);
1258             buf.append("             IssuerDN: ").append(this.getIssuerDN()).append(nl);
1259             buf.append("           Start Date: ").append(this.getNotBefore()).append(nl);
1260             buf.append("           Final Date: ").append(this.getNotAfter()).append(nl);
1261             buf.append("            SubjectDN: ").append(this.getSubjectDN()).append(nl);
1262             buf.append("           Public Key: ").append(this.getPublicKey()).append(nl);
1263             buf.append("  Signature Algorithm: ").append(this.getSigAlgName()).append(nl);
1264 
1265             byte[] sig = this.getSignature();
1266 
1267             buf.append("            Signature: ").append(new String(Hex.encode(sig, 0, 20))).append(nl);
1268             for (int i = 20; i < sig.length; i += 20)
1269             {
1270                 if (i < sig.length - 20)
1271                 {
1272                     buf.append("                       ").append(new String(Hex.encode(sig, i, 20))).append(nl);
1273                 }
1274                 else
1275                 {
1276                     buf.append("                       ").append(new String(Hex.encode(sig, i, sig.length - i))).append(nl);
1277                 }
1278             }
1279 
1280             X509Extensions extensions = c.getTBSCertificate().getExtensions();
1281 
1282             if (extensions != null)
1283             {
1284                 Enumeration e = extensions.oids();
1285 
1286                 if (e.hasMoreElements())
1287                 {
1288                     buf.append("       Extensions: \n");
1289                 }
1290 
1291                 while (e.hasMoreElements())
1292                 {
1293                     ASN1ObjectIdentifier oid = (ASN1ObjectIdentifier)e.nextElement();
1294                     X509Extension ext = extensions.getExtension(oid);
1295 
1296                     if (ext.getValue() != null)
1297                     {
1298                         byte[] octs = ext.getValue().getOctets();
1299                         ASN1InputStream dIn = new ASN1InputStream(octs);
1300                         buf.append("                       critical(").append(ext.isCritical()).append(") ");
1301                         try
1302                         {
1303                             if (oid.equals(Extension.basicConstraints))
1304                             {
1305                                 buf.append(BasicConstraints.getInstance(dIn.readObject())).append(nl);
1306                             }
1307                             else if (oid.equals(Extension.keyUsage))
1308                             {
1309                                 buf.append(KeyUsage.getInstance(dIn.readObject())).append(nl);
1310                             }
1311                             else if (oid.equals(MiscObjectIdentifiers.netscapeCertType))
1312                             {
1313                                 buf.append(new NetscapeCertType((DERBitString)dIn.readObject())).append(nl);
1314                             }
1315                             else if (oid.equals(MiscObjectIdentifiers.netscapeRevocationURL))
1316                             {
1317                                 buf.append(new NetscapeRevocationURL((DERIA5String)dIn.readObject())).append(nl);
1318                             }
1319                             else if (oid.equals(MiscObjectIdentifiers.verisignCzagExtension))
1320                             {
1321                                 buf.append(new VerisignCzagExtension((DERIA5String)dIn.readObject())).append(nl);
1322                             }
1323                             else
1324                             {
1325                                 buf.append(oid.getId());
1326                                 buf.append(" value = ").append(ASN1Dump.dumpAsString(dIn.readObject())).append(nl);
1327                                 //buf.append(" value = ").append("*****").append(nl);
1328                             }
1329                         }
1330                         catch (Exception ex)
1331                         {
1332                             buf.append(oid.getId());
1333                             //     buf.append(" value = ").append(new String(Hex.encode(ext.getExtnValue().getOctets()))).append(nl);
1334                             buf.append(" value = ").append("*****").append(nl);
1335                         }
1336                     }
1337                     else
1338                     {
1339                         buf.append(nl);
1340                     }
1341                 }
1342             }
1343 
1344             return buf.toString();
1345         }
1346 
verify( PublicKey key)1347         public final void verify(
1348             PublicKey key)
1349             throws CertificateException, NoSuchAlgorithmException,
1350             InvalidKeyException, NoSuchProviderException, SignatureException
1351         {
1352             Signature signature;
1353             String sigName = "SHA256withRSA";
1354 
1355             try
1356             {
1357                 signature = Signature.getInstance(sigName, BouncyCastleProvider.PROVIDER_NAME);
1358             }
1359             catch (Exception e)
1360             {
1361                 signature = Signature.getInstance(sigName);
1362             }
1363 
1364             checkSignature(key, signature);
1365         }
1366 
verify( PublicKey key, String sigProvider)1367         public final void verify(
1368             PublicKey key,
1369             String sigProvider)
1370             throws CertificateException, NoSuchAlgorithmException,
1371             InvalidKeyException, NoSuchProviderException, SignatureException
1372         {
1373             String sigName = "SHA256withRSA";
1374             Signature signature;
1375 
1376             if (sigProvider != null)
1377             {
1378                 signature = Signature.getInstance(sigName, sigProvider);
1379             }
1380             else
1381             {
1382                 signature = Signature.getInstance(sigName);
1383             }
1384 
1385             checkSignature(key, signature);
1386         }
1387 
verify( PublicKey key, Provider sigProvider)1388         public final void verify(
1389             PublicKey key,
1390             Provider sigProvider)
1391             throws CertificateException, NoSuchAlgorithmException,
1392             InvalidKeyException, SignatureException
1393         {
1394             String sigName = "SHA256withRSA";
1395             Signature signature;
1396 
1397             if (sigProvider != null)
1398             {
1399                 signature = Signature.getInstance(sigName, sigProvider);
1400             }
1401             else
1402             {
1403                 signature = Signature.getInstance(sigName);
1404             }
1405 
1406             checkSignature(key, signature);
1407         }
1408 
checkSignature( PublicKey key, Signature signature)1409         private void checkSignature(
1410             PublicKey key,
1411             Signature signature)
1412             throws CertificateException, NoSuchAlgorithmException,
1413             SignatureException, InvalidKeyException
1414         {
1415             if (!isAlgIdEqual(c.getSignatureAlgorithm(), c.getTBSCertificate().getSignature()))
1416             {
1417                 throw new CertificateException("signature algorithm in TBS cert not same as outer cert");
1418             }
1419 
1420             ASN1Encodable params = c.getSignatureAlgorithm().getParameters();
1421 
1422             signature.initVerify(key);
1423 
1424             signature.update(this.getTBSCertificate());
1425 
1426             if (!signature.verify(this.getSignature()))
1427             {
1428                 throw new SignatureException("certificate does not verify with supplied key");
1429             }
1430         }
1431 
isAlgIdEqual(AlgorithmIdentifier id1, AlgorithmIdentifier id2)1432         private boolean isAlgIdEqual(AlgorithmIdentifier id1, AlgorithmIdentifier id2)
1433         {
1434             if (!id1.getAlgorithm().equals(id2.getAlgorithm()))
1435             {
1436                 return false;
1437             }
1438 
1439             if (id1.getParameters() == null)
1440             {
1441                 if (id2.getParameters() != null && !id2.getParameters().equals(DERNull.INSTANCE))
1442                 {
1443                     return false;
1444                 }
1445 
1446                 return true;
1447             }
1448 
1449             if (id2.getParameters() == null)
1450             {
1451                 if (id1.getParameters() != null && !id1.getParameters().equals(DERNull.INSTANCE))
1452                 {
1453                     return false;
1454                 }
1455 
1456                 return true;
1457             }
1458 
1459             return id1.getParameters().equals(id2.getParameters());
1460         }
1461 
getAlternativeNames(byte[] extVal)1462         private static Collection getAlternativeNames(byte[] extVal)
1463             throws CertificateParsingException
1464         {
1465             if (extVal == null)
1466             {
1467                 return null;
1468             }
1469             try
1470             {
1471                 Collection temp = new ArrayList();
1472                 Enumeration it = ASN1Sequence.getInstance(extVal).getObjects();
1473                 while (it.hasMoreElements())
1474                 {
1475                     GeneralName genName = GeneralName.getInstance(it.nextElement());
1476                     List list = new ArrayList();
1477                     list.add(Integers.valueOf(genName.getTagNo()));
1478                     switch (genName.getTagNo())
1479                     {
1480                     case GeneralName.ediPartyName:
1481                     case GeneralName.x400Address:
1482                     case GeneralName.otherName:
1483                         list.add(genName.getEncoded());
1484                         break;
1485                     case GeneralName.directoryName:
1486                         list.add(X500Name.getInstance(RFC4519Style.INSTANCE, genName.getName()).toString());
1487                         break;
1488                     case GeneralName.dNSName:
1489                     case GeneralName.rfc822Name:
1490                     case GeneralName.uniformResourceIdentifier:
1491                         list.add(((ASN1String)genName.getName()).getString());
1492                         break;
1493                     case GeneralName.registeredID:
1494                         list.add(ASN1ObjectIdentifier.getInstance(genName.getName()).getId());
1495                         break;
1496                     case GeneralName.iPAddress:
1497                         byte[] addrBytes = DEROctetString.getInstance(genName.getName()).getOctets();
1498                         final String addr;
1499                         try
1500                         {
1501                             addr = InetAddress.getByAddress(addrBytes).getHostAddress();
1502                         }
1503                         catch (UnknownHostException e)
1504                         {
1505                             continue;
1506                         }
1507                         list.add(addr);
1508                         break;
1509                     default:
1510                         throw new IOException("Bad tag number: " + genName.getTagNo());
1511                     }
1512 
1513                     temp.add(Collections.unmodifiableList(list));
1514                 }
1515                 if (temp.size() == 0)
1516                 {
1517                     return null;
1518                 }
1519                 return Collections.unmodifiableCollection(temp);
1520             }
1521             catch (Exception e)
1522             {
1523                 throw new CertificateParsingException(e.getMessage());
1524             }
1525         }
1526     }
1527 }
1528 
1529