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