| /* |
| * Copyright (c) 2003, 2020, Oracle and/or its affiliates. All rights reserved. |
| * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
| * |
| * This code is free software; you can redistribute it and/or modify it |
| * under the terms of the GNU General Public License version 2 only, as |
| * published by the Free Software Foundation. |
| * |
| * This code is distributed in the hope that it will be useful, but WITHOUT |
| * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or |
| * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License |
| * version 2 for more details (a copy is included in the LICENSE file that |
| * accompanied this code). |
| * |
| * You should have received a copy of the GNU General Public License version |
| * 2 along with this work; if not, write to the Free Software Foundation, |
| * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. |
| * |
| * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA |
| * or visit www.oracle.com if you need additional information or have any |
| * questions. |
| */ |
| |
| /** |
| * |
| * @author Sean Mullan |
| * @author Steve Hanna |
| * |
| */ |
| |
| package jdk.test.lib.security; |
| |
| import java.io.ByteArrayInputStream; |
| import java.io.File; |
| import java.io.FileInputStream; |
| import java.io.IOException; |
| import java.io.InputStream; |
| import java.nio.file.Files; |
| import java.nio.file.Path; |
| import java.nio.file.Paths; |
| import java.security.KeyFactory; |
| import java.security.NoSuchAlgorithmException; |
| import java.security.PrivateKey; |
| import java.security.cert.CRLException; |
| import java.security.cert.CertPath; |
| import java.security.cert.CertPathBuilder; |
| import java.security.cert.CertPathValidator; |
| import java.security.cert.CertStore; |
| import java.security.cert.CertificateException; |
| import java.security.cert.CertificateFactory; |
| import java.security.cert.CollectionCertStoreParameters; |
| import java.security.cert.PKIXBuilderParameters; |
| import java.security.cert.PKIXCertPathBuilderResult; |
| import java.security.cert.PKIXCertPathValidatorResult; |
| import java.security.cert.PKIXParameters; |
| import java.security.cert.X509CRL; |
| import java.security.cert.X509Certificate; |
| import java.security.spec.InvalidKeySpecException; |
| import java.security.spec.PKCS8EncodedKeySpec; |
| import java.util.ArrayList; |
| import java.util.Base64; |
| import java.util.HashSet; |
| import java.util.List; |
| import java.util.Set; |
| import java.util.function.Predicate; |
| import java.util.stream.Collectors; |
| import java.util.stream.Stream; |
| |
| /** |
| * Static utility methods useful for testing certificate/certpath APIs. |
| */ |
| public class CertUtils { |
| |
| private CertUtils() {} |
| |
| /* |
| * Version: 3 (0x2) |
| * Serial Number: |
| * 7b:bb:a0:55:00:9d:69:16:1e:cb:e2:ad:25:d1:32:ff:fa:52:1b:05 |
| * Signature Algorithm: sha256WithRSAEncryption |
| * Issuer: CN = localhost |
| * Validity |
| * Not Before: Aug 1 11:58:25 2019 GMT |
| * Not After : Jul 29 11:58:25 2029 GMT |
| * Subject: CN = localhost |
| */ |
| public static final String RSA_CERT = |
| "-----BEGIN CERTIFICATE-----\n" + |
| "MIIDCTCCAfGgAwIBAgIUe7ugVQCdaRYey+KtJdEy//pSGwUwDQYJKoZIhvcNAQEL\n" + |
| "BQAwFDESMBAGA1UEAwwJbG9jYWxob3N0MB4XDTE5MDgwMTExNTgyNVoXDTI5MDcy\n" + |
| "OTExNTgyNVowFDESMBAGA1UEAwwJbG9jYWxob3N0MIIBIjANBgkqhkiG9w0BAQEF\n" + |
| "AAOCAQ8AMIIBCgKCAQEAxDGfn+GQEErnE1ErBaYpH8+rFgUS/nhFuaKLMNsYMtAY\n" + |
| "GI7XvnwzSMeYou6tDobi0WMxlnQRSlVEmmT6OPOOC9RLnt2qdU2klXVR5DCzVTrp\n" + |
| "wX5TILkP+KzePRQFrpi4z6Fx15cIVhP4OdPUd4rwAffD+nYaijQezLuKwdBKBHlt\n" + |
| "GBGxn978Ppcmx/6qAfFZjhtxJXBM7LzUPkDs6jHy10FK9KkqjmmB6zXM0Rvv8nN3\n" + |
| "9o55H3LnbO4XSIoRUGwSISSiHEBHbOZyBblDc0yoRAnjqxSDIj5oxessfDt5gG6C\n" + |
| "LqrUyfLDo7pbmQrdBoH2NEX9yScYVE1MnlRA6LusCQIDAQABo1MwUTAdBgNVHQ4E\n" + |
| "FgQUbZzwnSvM67UCB3ng5fTGcL24uqUwHwYDVR0jBBgwFoAUbZzwnSvM67UCB3ng\n" + |
| "5fTGcL24uqUwDwYDVR0TAQH/BAUwAwEB/zANBgkqhkiG9w0BAQsFAAOCAQEAgAtI\n" + |
| "feN7JySd5HdEqA0/vvCCoBJ/Z9//3OxQyW8NnkmVW3F1eMIWII/vOdYj1WJgq1uK\n" + |
| "a4GKiUVgEYTVSJxwj3mBmvd9o93Im9BSI0RkGOQOTnCLJNTksAD+2qO4F984xucS\n" + |
| "/R2BChlbik7+7uPZ7qnhfDmxyMJqtUuze/JkA4IrVssbFM30j70gGjNNd/waBsR2\n" + |
| "upI29x7LSCdPkXmwUuzUR5/zBHaR4pZ2nQvsfxoP384BvpM1SCNrBUGvxGzDDiGA\n" + |
| "pOJwIJoTEU7gGaHF8BeEUtC1YbSDWr+dN4IM7uzL6sdVs8xPVxkeptlVU7cDIyiN\n" + |
| "DPm3K0U4oj/KoFfMHg==\n" + |
| "-----END CERTIFICATE-----"; |
| public static final String RSA_KEY = |
| "MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQDEMZ+f4ZAQSucT\n" + |
| "USsFpikfz6sWBRL+eEW5oosw2xgy0BgYjte+fDNIx5ii7q0OhuLRYzGWdBFKVUSa\n" + |
| "ZPo4844L1Eue3ap1TaSVdVHkMLNVOunBflMguQ/4rN49FAWumLjPoXHXlwhWE/g5\n" + |
| "09R3ivAB98P6dhqKNB7Mu4rB0EoEeW0YEbGf3vw+lybH/qoB8VmOG3ElcEzsvNQ+\n" + |
| "QOzqMfLXQUr0qSqOaYHrNczRG+/yc3f2jnkfcuds7hdIihFQbBIhJKIcQEds5nIF\n" + |
| "uUNzTKhECeOrFIMiPmjF6yx8O3mAboIuqtTJ8sOjuluZCt0GgfY0Rf3JJxhUTUye\n" + |
| "VEDou6wJAgMBAAECggEAFwYn0HB9IpxXr9mnrdsJGnWZg1UHHJvqutVLdmlP1q67\n" + |
| "FS62POGAdzsNO5m872Z++cmlSR3H5axKB8Bv6P0UH2lDkpo65dc9yFhjSt84PHlU\n" + |
| "c2Oqx71QFYPb9NkDrbC4h41Pudg8nzVqvQaR+ZFxhxmXgy4XAT8KmkYsC4CxHwMY\n" + |
| "FYCHsNc8kpyXc7P5bbjpdQHMwpBP3dyo42h8cim8P2c5pKM0ipSm4vD9r8NIbvG7\n" + |
| "+bzLBC0aJCfL0wY2c8qRD2k5Xl/NRKovya8v6IUCyigyJV5DZMOfRqCMDeMuiaxl\n" + |
| "cvKqIPO5wxE3Wt36cEPZGO6GI6H+tzXZT0+y0+OfXQKBgQD5kR2GscpFhc+/A9Qn\n" + |
| "QQxeMHjDqXUjP11Czg+/K2vKjC+RHNIzOh+4jGWNb9nlMSu22IRltRzyDOrPRytB\n" + |
| "RT2o5rUGSv/oZ/lEMMyHz+xPaBfegYSCkZ3h01iL1fdAUALHtzG5c6S8JXhtWzHk\n" + |
| "q/dk6iXPfTtSREBkwv7c43vXTwKBgQDJQE0ZvgTSnscA+GkM1R7tH0hqKyk/xeus\n" + |
| "/xu23EraiIg4qoJ7Lk2IRvOkgotuK/SK+qoWlBr3OwBRzByxBXSdjdciZ5jbOc1g\n" + |
| "TA4Qwma6R9ukYdW+W95nYmsgyOi0+7tX9oVJatBJGyq3atayUANy8Lun4kSRdurn\n" + |
| "WibRxuxxJwKBgQCq62vhV9pECwTguWqPB8nEqEXNGz2SSk9A9YdrUf2c1q2tIKQF\n" + |
| "WYVoCx9x4mzEvwxFSbxDO+r7C0W1d/Rz20wDZR4NlUf2j170CMfLK+eX6p6OUP3D\n" + |
| "vp72jpxSCNQxQ5rj1N9FN6JXCQKVQqPFDNF+V65VkFsUWJIRcErEVTf3mQKBgAiW\n" + |
| "AbQTc0k5FOxprLGrdgJPz1sYNE5QN1nOGHSYuWjRYl5oh+CRfSVPQZ3HJAOzRF+Z\n" + |
| "iiAkeXIKxly3BJJY1TzTjFYfbVoNAUIWfJMieBeCcVB2DBRu/vISNNfVOnheNQPv\n" + |
| "tIgJUpGL4yqoGDjLSRpiQt9Ku/ooxKTSJ83TWssJAoGAflsMfkS9hdoAcWMUWkPU\n" + |
| "VMTP/yHshZKJK66uAtLJYvSLXMJAN4uCIobiPM0EsdLxTh1nrL36NmWsTZlMhMsS\n" + |
| "rPaBIT6f6m2M2+8ixiJoZ1ut2iyKxkkvWcECbXqjWw6ndGyAoL1/7OR5guJliePy\n" + |
| "axFzqDc4QQBTtrjLYuHGi9k="; |
| |
| /* |
| * Version: 3 (0x2) |
| * Serial Number: |
| * 3c:09:6b:31:d7:7c:00:93:b2:79:54:f9:c2:3c:d2:dd:76:56:f0:50 |
| * Signature Algorithm: ecdsa-with-SHA256 |
| * Issuer: CN = localhost |
| * Validity |
| * Not Before: Aug 1 11:58:34 2019 GMT |
| * Not After : Jul 29 11:58:34 2029 GMT |
| * Subject: CN = localhost |
| */ |
| public static final String ECDSA_CERT = |
| "-----BEGIN CERTIFICATE-----\n" + |
| "MIIBfjCCASOgAwIBAgIUPAlrMdd8AJOyeVT5wjzS3XZW8FAwCgYIKoZIzj0EAwIw\n" + |
| "FDESMBAGA1UEAwwJbG9jYWxob3N0MB4XDTE5MDgwMTExNTgzNFoXDTI5MDcyOTEx\n" + |
| "NTgzNFowFDESMBAGA1UEAwwJbG9jYWxob3N0MFkwEwYHKoZIzj0CAQYIKoZIzj0D\n" + |
| "AQcDQgAEs8ThmP8Xi9aBkB3WPfHRflpk6u44/9NIH4IiRSmbB7jmgCH3rP50izNR\n" + |
| "va4fKIZUJ0vPCS9zBr4rKVco9Z6qV6NTMFEwHQYDVR0OBBYEFFgf2AXMfO1OpBul\n" + |
| "ArF1gqmVA04YMB8GA1UdIwQYMBaAFFgf2AXMfO1OpBulArF1gqmVA04YMA8GA1Ud\n" + |
| "EwEB/wQFMAMBAf8wCgYIKoZIzj0EAwIDSQAwRgIhAKWR1yXjBedp6hOoxvZ8n9e8\n" + |
| "k2ZPdboTfyIRvCw9O4BUAiEAuHsWWs34c3xPCxsyoxbpgkBLwdZ1pZASbCMbgZ59\n" + |
| "RYo=\n" + |
| "-----END CERTIFICATE-----"; |
| public static final String ECDSA_KEY = |
| "MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQgajTO2cTGJdOUawrQ\n" + |
| "XqGfGuX6AEevTXQY0hlVHAVx516hRANCAASzxOGY/xeL1oGQHdY98dF+WmTq7jj/\n" + |
| "00gfgiJFKZsHuOaAIfes/nSLM1G9rh8ohlQnS88JL3MGvispVyj1nqpX"; |
| |
| /* |
| * This EC-key certificate is singed by the above RSA CA, namely RSA_CERT. |
| * |
| * Version: 3 (0x2) |
| * Serial Number: |
| * 6a:5e:bb:97:3c:f8:0a:0d:ef:0a:ca:72:0b:6d:7f:b5:e0:af:b2:86 |
| * Signature Algorithm: sha256WithRSAEncryption |
| * Issuer: CN = localhost |
| * Validity |
| * Not Before: Apr 14 08:14:04 2020 GMT |
| * Not After : Apr 12 08:14:04 2030 GMT |
| * Subject: CN = localhost |
| */ |
| public static final String ECRSA_CERT = |
| "-----BEGIN CERTIFICATE-----\n" + |
| "MIICLTCCARWgAwIBAgIUal67lzz4Cg3vCspyC21/teCvsoYwDQYJKoZIhvcNAQEL\n" + |
| "BQAwFDESMBAGA1UEAwwJbG9jYWxob3N0MB4XDTIwMDQxNDA4MTQwNFoXDTMwMDQx\n" + |
| "MjA4MTQwNFowFDESMBAGA1UEAwwJbG9jYWxob3N0MFkwEwYHKoZIzj0CAQYIKoZI\n" + |
| "zj0DAQcDQgAEZOIGqyJHpWFhyiRbZACdNBYHvXTzWVWMC10RW8vfxiOPAZBlPzqn\n" + |
| "d2X6/bGhSN1EkrMl8YlJTAKvZcGaaKFUHKNCMEAwHQYDVR0OBBYEFCl9FR9xeNjc\n" + |
| "5+Zkg/Rrk7JpTKnFMB8GA1UdIwQYMBaAFG2c8J0rzOu1Agd54OX0xnC9uLqlMA0G\n" + |
| "CSqGSIb3DQEBCwUAA4IBAQCPcwr88n/vjsHPByiF28P2cEZ02JdQH0FQVe+6Xw7t\n" + |
| "Rn62aTAmS3kaHovXXrFpDpwgz+BMtGSNVTeR7zFttAZLyYb6w6rD8tCfZqHqOTC8\n" + |
| "ctCHz7D2QnsH3tdSV1J7A8N3+P8t4cmCs1AED92yLhy9sumXBvZ2ZskpUtcA5nZB\n" + |
| "djTvyJ3F74835w0s2FzWPnTULvBmit2Z94b22QyZLkFhThUpMBlu2LmXosLrdfji\n" + |
| "xVcV68tpQ1nk1o9tE4V7h4/SjYVaDM1fmlaY+eM3XcbK30mVyktty5ScuOMhLpb6\n" + |
| "RFP/QKvmQ/2l4+rj/epV84ImDuEAhkBGOU6vo4X4l1Du\n" + |
| "-----END CERTIFICATE-----"; |
| public static final String ECRSA_KEY = |
| "MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQgldlJrkmEDVtzh4r9\n" + |
| "NO8Yn/89mZuBhKPasVgpRjKQxRyhRANCAARk4garIkelYWHKJFtkAJ00Fge9dPNZ\n" + |
| "VYwLXRFby9/GI48BkGU/Oqd3Zfr9saFI3USSsyXxiUlMAq9lwZpooVQc"; |
| |
| /* |
| * Version: 3 (0x2) |
| Serial Number: |
| 76:07:da:cb:0f:8a:89:26:72:cb:db:20:ec:df:b2:52:50:01:6a:56 |
| Signature Algorithm: rsassaPss |
| Hash Algorithm: sha256 |
| Mask Algorithm: mgf1 with sha256 |
| Salt Length: 0xDE |
| Trailer Field: 0xBC (default) |
| Issuer: CN = localhost |
| Validity |
| Not Before: Aug 1 11:58:40 2019 GMT |
| Not After : Jul 29 11:58:40 2029 GMT |
| Subject: CN = localhost |
| */ |
| public static final String RSASSAPSS_CERT = |
| "-----BEGIN CERTIFICATE-----\n" + |
| "MIIDaTCCAiCgAwIBAgIUdgfayw+KiSZyy9sg7N+yUlABalYwPgYJKoZIhvcNAQEK\n" + |
| "MDGgDTALBglghkgBZQMEAgGhGjAYBgkqhkiG9w0BAQgwCwYJYIZIAWUDBAIBogQC\n" + |
| "AgDeMBQxEjAQBgNVBAMMCWxvY2FsaG9zdDAeFw0xOTA4MDExMTU4NDBaFw0yOTA3\n" + |
| "MjkxMTU4NDBaMBQxEjAQBgNVBAMMCWxvY2FsaG9zdDCCASAwCwYJKoZIhvcNAQEK\n" + |
| "A4IBDwAwggEKAoIBAQC5igqwiTdawCKIDmGVXAnYSIj5QIiMW4VzeWj87+bWqMec\n" + |
| "9uiOkFBI9c1y3CMoAPu9SEBbycAMadExB0pRq93Kz7pO30nyOFwDhvnArqg0e+mn\n" + |
| "6yaJeYWkQFX0HNS/vBwlVPLSkyuE80Tt1bND7ur4z31hT6H16nDBfx14b9aXW9j0\n" + |
| "L2zqZbyq4jhbELeBK0DtD1tpmJsYHxXjL174fDQ0dArNjIq529veS9z+FjdpuZTm\n" + |
| "e3XxOyWofA0EV4t3wN7x5RvI0pTo7Na+15TjTlhwHTuaiUPsOvMg73sI+3OxXGHI\n" + |
| "GDoOgqliYqHH0SkTYWpZF9Be3Th/R90Qg7Pvzo4HAgMBAAGjUzBRMB0GA1UdDgQW\n" + |
| "BBRQAfLTSK6mt9aKxrWbHUKsKwrBfDAfBgNVHSMEGDAWgBRQAfLTSK6mt9aKxrWb\n" + |
| "HUKsKwrBfDAPBgNVHRMBAf8EBTADAQH/MD4GCSqGSIb3DQEBCjAxoA0wCwYJYIZI\n" + |
| "AWUDBAIBoRowGAYJKoZIhvcNAQEIMAsGCWCGSAFlAwQCAaIEAgIA3gOCAQEAQPJz\n" + |
| "TGugNS+wmxe6BGHmWLLsRJAQn/lr+3dJIfkfBlmkc43tSdL5R+5LfkNjE7sCUW4s\n" + |
| "FFKVlQH8XzHbJH0USNp+yxJBjBv5XpXW+mrhGhCBiIoEXce78irNJLy6dJPIFo/m\n" + |
| "z4Lt2YS5VassInrBvb9KyNlinpqJ5sjptLM2Nc77Rv/uFOkgTNwyuAi+LYuP1lEm\n" + |
| "4AZcywjfxBv/mmuZ8oAgPj50cN0gsgQmi/bofiZsK4GrZpSncjMYZvG/C4WF2Zem\n" + |
| "cd7KZtQoPrv3bSE3gyotN04wE2nFLsaR2gheuv0URitDPAzpv8QV3WjEUt6uaFZi\n" + |
| "K6deQ/N/JiwhoqjM+Q==\n" + |
| "-----END CERTIFICATE-----"; |
| public static final String RSASSAPSS_KEY = |
| "MIIEuwIBADALBgkqhkiG9w0BAQoEggSnMIIEowIBAAKCAQEAuYoKsIk3WsAiiA5h\n" + |
| "lVwJ2EiI+UCIjFuFc3lo/O/m1qjHnPbojpBQSPXNctwjKAD7vUhAW8nADGnRMQdK\n" + |
| "Uavdys+6Tt9J8jhcA4b5wK6oNHvpp+smiXmFpEBV9BzUv7wcJVTy0pMrhPNE7dWz\n" + |
| "Q+7q+M99YU+h9epwwX8deG/Wl1vY9C9s6mW8quI4WxC3gStA7Q9baZibGB8V4y9e\n" + |
| "+Hw0NHQKzYyKudvb3kvc/hY3abmU5nt18TslqHwNBFeLd8De8eUbyNKU6OzWvteU\n" + |
| "405YcB07molD7DrzIO97CPtzsVxhyBg6DoKpYmKhx9EpE2FqWRfQXt04f0fdEIOz\n" + |
| "786OBwIDAQABAoIBAH4eO03st9fUKqTZQbPJMFf4VkM3fpoJzBjGOntUh1D6wVUM\n" + |
| "8N+XcTtm+hRNVwhmQrhTWIwMA6NsemodToNdlBG8SiQ624Tukn1DTpmPH38ti5I8\n" + |
| "4aEpHZKcuNCKmIMMVwV5TOWebEKfKgeQ754J1Wbzg4KWIr2KcsLUqS+otfGDsOMK\n" + |
| "nuIhFQhamtNFzuWSRIYJl5jfNcnXmeTivVNywE0Q/PGD3lLn8xB3Bk6uNTAUFBdc\n" + |
| "nbK7efViSfuNY+kZbHne+mcSGiBJPSzTfd25+/JhYaKFjPiQsIqPAwnZK80LBdeb\n" + |
| "lxf3zSzpgbx9Jai+kULZJsrVoReZlS6fxeqzZAECgYEA4jRcR6tEQGImsIT7zBTS\n" + |
| "FYTsqr0wzuUl2m3mNNQX9ZIKEVJxv9Vevyd4eQIwQRwgPM2U2JLsXPjVFc/fCAJO\n" + |
| "KuLY5sXog4b0c8cHjA8nbJbmjKHkXfgCnKFGoXvUV13LgFg9DX6hzkCKMJxDO9R+\n" + |
| "pE9k6HXq58yyDvRBvFOCuYECgYEA0fpxa0gwCmyMKQeFnBPd53rnPOBoW2YKnIzR\n" + |
| "/X1q6YRFdeRgvcBXScPknU1nvoxAtRqHYDSI3d/sHMzZ+qb0BBoD7i2qjKsSH32u\n" + |
| "jP5m5+psPebJ0UEH/bTUbETWEu9rt8sapag6Mp1QL6uYZW5OOULCpGYa9KcfX93A\n" + |
| "hwgeO4cCgYBy+mptg4CNuVYxI2dZtLuUdJxXrRLCF3fGL1Z0Q9pp2HGFnIJ1H9+p\n" + |
| "CkcSOyqL7d/1CApAi23ZVCH7lE2ppIJXCjd2FeK5+D8JGoGbj5haedl2YlPR795j\n" + |
| "/xYHvwmP3v0xn6ho05UrYWLckpEaOEim/DQudMGSUVmwgDdpookwAQKBgQCv6RhL\n" + |
| "wFY+5WEmnl6YuywUWSqQHZBPwdTyAieKLh/7MgzfD0zcqt51td84yTg4slcjYe43\n" + |
| "8ssW1hmApz2Wd3fGV+UjDK7s2gR8zVYGWLrtX77+vPImlEyVh4DOk3yksF+Vwlm4\n" + |
| "no7jCFe9GAy8LQTrg7p87+11OO1X6vb4KRzq0QKBgCZD8lN/qHpscBQucx60vToU\n" + |
| "247vlb9LmzsMFVUeyJhg/v1+1kswIImuYC+X0nO8yF++mD8OyWIZaXZAkmEsU9qF\n" + |
| "ZCdo4KHSmFTKm6mCPW+5tro3GCsavRZqFHeQF8iVRsN3V86q6wRlMvyYmKMLd0Ko\n" + |
| "0CyaEnQ+kBtL6IaeVNQV"; |
| |
| /* |
| * Version: 3 (0x2) |
| * Serial Number: |
| * 49:33:8a:a8:cd:d9:14:f8:09:a1:0c:2f:67:a3:27:a6:fc:df:25:f8 |
| * Signature Algorithm: dsa_with_SHA256 |
| * Issuer: CN = localhost |
| * Validity |
| * Not Before: Aug 1 12:01:30 2019 GMT |
| * Not After : Jul 27 12:01:30 2039 GMT |
| * Subject: CN = localhost |
| */ |
| public static final String DSA_CERT = |
| "-----BEGIN CERTIFICATE-----\n" + |
| "MIIEbzCCBBSgAwIBAgIUSTOKqM3ZFPgJoQwvZ6MnpvzfJfgwCwYJYIZIAWUDBAMC\n" + |
| "MBQxEjAQBgNVBAMMCWxvY2FsaG9zdDAeFw0xOTA4MDExMjAxMzBaFw0zOTA3Mjcx\n" + |
| "MjAxMzBaMBQxEjAQBgNVBAMMCWxvY2FsaG9zdDCCA0cwggI5BgcqhkjOOAQBMIIC\n" + |
| "LAKCAQEAsFMaoryk333Vm0JY8QEu1y0HmQkvp5dlM/4ozMj8l6hx8HYo+LYTQD4e\n" + |
| "t7b7xUf5sYc4mjxpwbV4uf8Q4G1BHfJCGdGKxKigObsbDqpRRBlubHppOX6F6mRz\n" + |
| "wgaNRfWqlZbcSa+X82SfagtjMVKrH75eIs74U7EBQRun7XilrDFKuG6c98cY1JFI\n" + |
| "BpAp/Sw+kEk0LYYgdGIVWhNCunECcqWtdz1AEBzHOiqEthKTzF+o1qxBFCYjOnZo\n" + |
| "wkgG5fqXDc4Rb0iNyxSQXK/lTi/4r6IABY3u7f5NOhj0GmRbbCA/Ef0i6GQKJqzk\n" + |
| "hfzTQDwRsvX17xLFTOeNQb26dvm23wIhAL6RNExpfF++/0Ph4mkPqxuDLHWACa/y\n" + |
| "3VeNr8NjO7ovAoIBABndio/73FVBpnpbFdT1DnqY3IWUbpr40zudROuGWvSd66Ia\n" + |
| "pNtRb/fcgMm3UjAq92SjbF+Rn+gf1ylm1LCtE4xeN02gxCJnR9/HKmuSTDnVOH5F\n" + |
| "62yjQaEPZ7rG2cr7fP67YiW1b3nTQSL11y62MVvp+JH1BMVd4gYMop7wG8eRajFr\n" + |
| "hW3AY6dz5J2w6fywvZTIXzv1cZS7be1adcdYSvkFs9V6bT+lQHKNpqM8aab61Kp9\n" + |
| "aB3+p39nKYm6KPpc/wuSHs5Ez5C89mLrHB4l6xZAMAWqwkDnUmiRScwfyOIKG8VY\n" + |
| "2c9GtfZOCB21dupwXGruFH1tcg5IP7wHJddOWCADggEGAAKCAQEAkrNcrwgXKVWc\n" + |
| "gwv4CAJhRAH0svQChcLI1I5+6FB8KomN4xVW+obJcNag3qbTCd3V3mHu6gITxxkq\n" + |
| "EoA2zCBQFMAIGW2G1PkqOlBK8K3hOut/IEbWmiMlC51P0AUHBd1NDCY6q96Y+mot\n" + |
| "ogGc3lMQZK5mWseUirP6Qt43N7Ev57PXypKC5MnQKA2+NEhhiHvDruSBloj9zu+w\n" + |
| "oNhXZP+0dPBb96eeHwcRj25MSuhY+Jpg2OoU+FzDvx7QDEqkq801EBdr9WOiY9hx\n" + |
| "DpbUZH3mLYo9tzBwDK8RngPlcwlMpuR/A3pu6qLAGJHnVWb1c9mhNHv+8p5to74k\n" + |
| "2RqOaSU26aNTMFEwHQYDVR0OBBYEFJ8MbprhtUOkVraW76QALKQnZ6yNMB8GA1Ud\n" + |
| "IwQYMBaAFJ8MbprhtUOkVraW76QALKQnZ6yNMA8GA1UdEwEB/wQFMAMBAf8wCwYJ\n" + |
| "YIZIAWUDBAMCA0gAMEUCIHaOTmgo0rK4EWGLruxLiTcHZs1KanLrf9FlKbmur9Ee\n" + |
| "AiEAnE+fxuTBexuPj2elmnxViUj/UYo/NlC4OarhIO1SCzk=\n" + |
| "-----END CERTIFICATE-----"; |
| public static final String DSA_KEY = |
| "MIICZQIBADCCAjkGByqGSM44BAEwggIsAoIBAQCwUxqivKTffdWbQljxAS7XLQeZ\n" + |
| "CS+nl2Uz/ijMyPyXqHHwdij4thNAPh63tvvFR/mxhziaPGnBtXi5/xDgbUEd8kIZ\n" + |
| "0YrEqKA5uxsOqlFEGW5semk5foXqZHPCBo1F9aqVltxJr5fzZJ9qC2MxUqsfvl4i\n" + |
| "zvhTsQFBG6fteKWsMUq4bpz3xxjUkUgGkCn9LD6QSTQthiB0YhVaE0K6cQJypa13\n" + |
| "PUAQHMc6KoS2EpPMX6jWrEEUJiM6dmjCSAbl+pcNzhFvSI3LFJBcr+VOL/ivogAF\n" + |
| "je7t/k06GPQaZFtsID8R/SLoZAomrOSF/NNAPBGy9fXvEsVM541Bvbp2+bbfAiEA\n" + |
| "vpE0TGl8X77/Q+HiaQ+rG4MsdYAJr/LdV42vw2M7ui8CggEAGd2Kj/vcVUGmelsV\n" + |
| "1PUOepjchZRumvjTO51E64Za9J3rohqk21Fv99yAybdSMCr3ZKNsX5Gf6B/XKWbU\n" + |
| "sK0TjF43TaDEImdH38cqa5JMOdU4fkXrbKNBoQ9nusbZyvt8/rtiJbVvedNBIvXX\n" + |
| "LrYxW+n4kfUExV3iBgyinvAbx5FqMWuFbcBjp3PknbDp/LC9lMhfO/VxlLtt7Vp1\n" + |
| "x1hK+QWz1XptP6VAco2mozxppvrUqn1oHf6nf2cpiboo+lz/C5IezkTPkLz2Yusc\n" + |
| "HiXrFkAwBarCQOdSaJFJzB/I4gobxVjZz0a19k4IHbV26nBcau4UfW1yDkg/vAcl\n" + |
| "105YIAQjAiEAvP+ZQ7yzUk8rNgk65U/SF++Eyt+i+WR1UBvGxAEEKIQ="; |
| |
| private static final String TEST_SRC = System.getProperty("test.src", "."); |
| |
| /** |
| * Get a PEM-encoded PKCS8 private key from a string. |
| * |
| * @param keyAlgo the key algorithm |
| * @param keyStr string containing the PEM-encoded PKCS8 private key |
| * @return the private key |
| * @throws NoSuchAlgorithmException if no Provider supports a KeyFactorySpi |
| * implementation for the specified algorithm |
| * @throws InvalidKeySpecException if the given key specification is |
| * inappropriate for this key factory to produce a private key. |
| */ |
| public static PrivateKey getKeyFromString(String keyAlgo, String keyStr) |
| throws NoSuchAlgorithmException, InvalidKeySpecException { |
| KeyFactory keyFactory = KeyFactory.getInstance(keyAlgo); |
| PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec( |
| Base64.getMimeDecoder().decode(keyStr)); |
| PrivateKey key = keyFactory.generatePrivate(keySpec); |
| return key; |
| } |
| |
| /** |
| * Get a PEM-encoded PKCS8 private key from a file. |
| * |
| * @param keyAlgo the key algorithm |
| * @param keyPath path to file containing the PEM-encoded PKCS8 private key |
| * @return the private key |
| * @throws NoSuchAlgorithmException if no Provider supports a KeyFactorySpi |
| * implementation for the specified algorithm |
| * @throws InvalidKeySpecException if the given key specification is |
| * inappropriate for this key factory to produce a private key. |
| */ |
| public static PrivateKey getKeyFromFile(String keyAlgo, String keyPath) |
| throws NoSuchAlgorithmException, InvalidKeySpecException { |
| return getKeyFromString( |
| keyAlgo, |
| |
| // Filter the below lines if any |
| // -----BEGIN PRIVATE KEY----- |
| // -----END PRIVATE KEY----- |
| readFile(keyPath, line -> !line.startsWith("-----"))); |
| } |
| |
| /** |
| * Get an X.509 certificate from an input stream. |
| * |
| * @param input an input stream with the certificate data. |
| * @return the X509Certificate |
| * @throws CertificateException on parsing errors. |
| * @throws IOException on input stream errors. |
| */ |
| public static X509Certificate getCertFromStream(InputStream input) |
| throws CertificateException, IOException { |
| try { |
| CertificateFactory certFactory |
| = CertificateFactory.getInstance("X.509"); |
| return (X509Certificate) certFactory.generateCertificate(input); |
| } finally { |
| if (input != null) { |
| input.close(); |
| } |
| } |
| } |
| |
| /** |
| * Get a PEM-encoded X.509 certificate from a string. |
| * |
| * @param cert string containing the PEM-encoded certificate |
| * @return the X509Certificate |
| * @throws CertificateException if the certificate type is not supported |
| * or cannot be parsed |
| * @throws IOException |
| */ |
| public static X509Certificate getCertFromString(String certStr) |
| throws CertificateException, IOException { |
| return getCertFromStream(new ByteArrayInputStream(certStr.getBytes())); |
| } |
| |
| /** |
| * Get a X.509 certificate from a file. |
| * |
| * @param certFilePath path to file containing certificate |
| * @return the X509Certificate |
| * @throws CertificateException if the certificate type is not supported |
| * or cannot be parsed |
| * @throws IOException if the file cannot be opened |
| */ |
| public static X509Certificate getCertFromFile(String certFilePath) |
| throws CertificateException, IOException { |
| return getCertFromStream( |
| Files.newInputStream(Paths.get(TEST_SRC, certFilePath))); |
| } |
| |
| /** |
| * Get a DER-encoded X.509 CRL from a file. |
| * |
| * @param crlFilePath path to file containing DER-encoded CRL |
| * @return the X509CRL |
| * @throws CertificateException if the crl type is not supported |
| * @throws CRLException if the crl cannot be parsed |
| * @throws IOException if the file cannot be opened |
| */ |
| public static X509CRL getCRLFromFile(String crlFilePath) |
| throws CertificateException, CRLException, IOException { |
| File crlFile = new File(TEST_SRC, crlFilePath); |
| try (FileInputStream fis = new FileInputStream(crlFile)) { |
| return (X509CRL) |
| CertificateFactory.getInstance("X.509").generateCRL(fis); |
| } |
| } |
| |
| /** |
| * Get a PEM-encoded X.509 crl from a string. |
| * |
| * @param crl string containing the PEM-encoded crl |
| * @return the X509CRL |
| * @throws CertificateException if the crl type is not supported |
| * @throws CRLException if the crl cannot be parsed |
| */ |
| public static X509CRL getCRLFromString(String crl) |
| throws CertificateException, CRLException { |
| byte[] crlBytes = crl.getBytes(); |
| ByteArrayInputStream bais = new ByteArrayInputStream(crlBytes); |
| return (X509CRL) |
| CertificateFactory.getInstance("X.509").generateCRL(bais); |
| } |
| |
| /** |
| * Read a bunch of certs from files and create a CertPath from them. |
| * |
| * @param fileNames an array of <code>String</code>s that are file names |
| * @throws Exception on error |
| */ |
| public static CertPath buildPath(String [] fileNames) throws Exception { |
| return buildPath("", fileNames); |
| } |
| |
| /** |
| * Read a bunch of certs from files and create a CertPath from them. |
| * |
| * @param relPath relative path containing certs (must end in |
| * file.separator) |
| * @param fileNames an array of <code>String</code>s that are file names |
| * @throws Exception on error |
| */ |
| public static CertPath buildPath(String relPath, String [] fileNames) |
| throws Exception { |
| List<X509Certificate> list = new ArrayList<X509Certificate>(); |
| for (int i = 0; i < fileNames.length; i++) { |
| list.add(0, getCertFromFile(relPath + fileNames[i])); |
| } |
| CertificateFactory cf = CertificateFactory.getInstance("X509"); |
| return(cf.generateCertPath(list)); |
| } |
| |
| |
| /** |
| * Read a bunch of certs from files and create a CertStore from them. |
| * |
| * @param fileNames an array of <code>String</code>s that are file names |
| * @return the <code>CertStore</code> created |
| * @throws Exception on error |
| */ |
| public static CertStore createStore(String [] fileNames) throws Exception { |
| return createStore("", fileNames); |
| } |
| |
| /** |
| * Read a bunch of certs from files and create a CertStore from them. |
| * |
| * @param relPath relative path containing certs (must end in |
| * file.separator) |
| * @param fileNames an array of <code>String</code>s that are file names |
| * @return the <code>CertStore</code> created |
| * @throws Exception on error |
| */ |
| public static CertStore createStore(String relPath, String [] fileNames) |
| throws Exception { |
| Set<X509Certificate> certs = new HashSet<X509Certificate>(); |
| for (int i = 0; i < fileNames.length; i++) { |
| certs.add(getCertFromFile(relPath + fileNames[i])); |
| } |
| return CertStore.getInstance("Collection", |
| new CollectionCertStoreParameters(certs)); |
| } |
| |
| /** |
| * Read a bunch of CRLs from files and create a CertStore from them. |
| * |
| * @param fileNames an array of <code>String</code>s that are file names |
| * @return the <code>CertStore</code> created |
| * @throws Exception on error |
| */ |
| public static CertStore createCRLStore(String [] fileNames) |
| throws Exception { |
| return createCRLStore("", fileNames); |
| } |
| |
| /** |
| * Read a bunch of CRLs from files and create a CertStore from them. |
| * |
| * @param relPath relative path containing CRLs (must end in file.separator) |
| * @param fileNames an array of <code>String</code>s that are file names |
| * @return the <code>CertStore</code> created |
| * @throws Exception on error |
| */ |
| public static CertStore createCRLStore(String relPath, String [] fileNames) |
| throws Exception { |
| Set<X509CRL> crls = new HashSet<X509CRL>(); |
| for (int i = 0; i < fileNames.length; i++) { |
| crls.add(getCRLFromFile(relPath + fileNames[i])); |
| } |
| return CertStore.getInstance("Collection", |
| new CollectionCertStoreParameters(crls)); |
| } |
| |
| /** |
| * Perform a PKIX path build. On failure, throw an exception. |
| * |
| * @param params PKIXBuilderParameters to use in validation |
| * @throws Exception on error |
| */ |
| public static PKIXCertPathBuilderResult build(PKIXBuilderParameters params) |
| throws Exception { |
| CertPathBuilder builder = |
| CertPathBuilder.getInstance("PKIX"); |
| return (PKIXCertPathBuilderResult) builder.build(params); |
| } |
| |
| /** |
| * Perform a PKIX validation. On failure, throw an exception. |
| * |
| * @param path CertPath to validate |
| * @param params PKIXParameters to use in validation |
| * @throws Exception on error |
| */ |
| public static PKIXCertPathValidatorResult validate |
| (CertPath path, PKIXParameters params) throws Exception { |
| CertPathValidator validator = |
| CertPathValidator.getInstance("PKIX"); |
| return (PKIXCertPathValidatorResult) validator.validate(path, params); |
| } |
| |
| /** |
| * Get the content of a file with given filter condition. |
| * |
| * @param relativeFilePath path to file that relative to test.src directory. |
| * @param predicate The condition for filtering file content |
| * @return the file content |
| */ |
| private static String readFile(String relativeFilePath, |
| Predicate<String> predicate) { |
| Path filePath = Paths.get(TEST_SRC, relativeFilePath); |
| try (Stream<String> lines = Files.lines(filePath)) { |
| Stream<String> interStream = null; |
| if (predicate != null) { |
| interStream = lines.filter(predicate); |
| } |
| return interStream != null |
| ? interStream.collect(Collectors.joining("\n")) |
| : lines.collect(Collectors.joining("\n")); |
| } catch (IOException e) { |
| throw new RuntimeException("Cannot read file", e); |
| } |
| } |
| } |