1 /* 2 * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. 8 * 9 * This code is distributed in the hope that it will be useful, but WITHOUT 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 12 * version 2 for more details (a copy is included in the LICENSE file that 13 * accompanied this code). 14 * 15 * You should have received a copy of the GNU General Public License version 16 * 2 along with this work; if not, write to the Free Software Foundation, 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 * 19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 * or visit www.oracle.com if you need additional information or have any 21 * questions. 22 */ 23 24 /* 25 * @test 26 * @bug 7166570 27 * @summary JSSE certificate validation has started to fail for 28 * certificate chains 29 * 30 * SunJSSE does not support dynamic system properties, no way to re-use 31 * system properties in samevm/agentvm mode. 32 * @run main/othervm BasicConstraints PKIX 33 * @run main/othervm BasicConstraints SunX509 34 */ 35 36 import java.net.*; 37 import java.util.*; 38 import java.io.*; 39 import javax.net.ssl.*; 40 import java.security.KeyStore; 41 import java.security.KeyFactory; 42 import java.security.cert.*; 43 import java.security.spec.*; 44 import java.security.interfaces.*; 45 import java.math.BigInteger; 46 47 import java.util.Base64; 48 49 public class BasicConstraints { 50 51 /* 52 * ============================================================= 53 * Set the various variables needed for the tests, then 54 * specify what tests to run on each side. 55 */ 56 57 /* 58 * Should we run the client or server in a separate thread? 59 * Both sides can throw exceptions, but do you have a preference 60 * as to which side should be the main thread. 61 */ 62 static boolean separateServerThread = true; 63 64 /* 65 * Where do we find the keystores? 66 */ 67 // Certificate information: 68 // Issuer: C=US, O=Java, OU=SunJSSE Test Serivce 69 // Validity 70 // Not Before: May 5 02:40:50 2012 GMT 71 // Not After : Apr 15 02:40:50 2033 GMT 72 // Subject: C=US, O=Java, OU=SunJSSE Test Serivce 73 // X509v3 Subject Key Identifier: 74 // DD:4E:8D:2A:11:C0:83:03:F0:AC:EB:A2:BF:F9:F2:7D:C8:69:1F:9B 75 // X509v3 Authority Key Identifier: 76 // keyid:DD:4E:8D:2A:11:C0:83:03:F0:AC:EB:A2:BF:F9:F2:7D:C8:69:1F:9B 77 // DirName:/C=US/O=Java/OU=SunJSSE Test Serivce 78 // serial:00 79 static String trusedCertStr = 80 "-----BEGIN CERTIFICATE-----\n" + 81 "MIICkjCCAfugAwIBAgIBADANBgkqhkiG9w0BAQIFADA7MQswCQYDVQQGEwJVUzEN\n" + 82 "MAsGA1UEChMESmF2YTEdMBsGA1UECxMUU3VuSlNTRSBUZXN0IFNlcml2Y2UwHhcN\n" + 83 "MTIwNTA1MDI0MDUwWhcNMzMwNDE1MDI0MDUwWjA7MQswCQYDVQQGEwJVUzENMAsG\n" + 84 "A1UEChMESmF2YTEdMBsGA1UECxMUU3VuSlNTRSBUZXN0IFNlcml2Y2UwgZ8wDQYJ\n" + 85 "KoZIhvcNAQEBBQADgY0AMIGJAoGBANtiq0AIJK+iVRwFrqcD7fYXTCbMYC5Qz/k6\n" + 86 "AXBy7/1rI8wDhEJLE3m/+NSqiJwZcmdq2dNh/1fJFrwvzuURbc9+paOBWeHbN+Sc\n" + 87 "x3huw91oPZme385VpoK3G13rSE114S/rF4DM9mz4EStFhSHXATjtdbskNOAYGLTV\n" + 88 "x8uEy9GbAgMBAAGjgaUwgaIwHQYDVR0OBBYEFN1OjSoRwIMD8Kzror/58n3IaR+b\n" + 89 "MGMGA1UdIwRcMFqAFN1OjSoRwIMD8Kzror/58n3IaR+boT+kPTA7MQswCQYDVQQG\n" + 90 "EwJVUzENMAsGA1UEChMESmF2YTEdMBsGA1UECxMUU3VuSlNTRSBUZXN0IFNlcml2\n" + 91 "Y2WCAQAwDwYDVR0TAQH/BAUwAwEB/zALBgNVHQ8EBAMCAQYwDQYJKoZIhvcNAQEC\n" + 92 "BQADgYEAjjkJesQrkbr36N40egybaIxw7RcqT6iy5fkAGS1JYlBDk8uSCK1o6bCH\n" + 93 "ls5EpYcGeEoabSS73WRdkO1lgeyWDduO4ef8cCCSpmpT6/YdZG0QS1PtcREeVig+\n" + 94 "Zr25jNemS4ADHX0aaXP4kiV/G80cR7nX5t5XCUm4bYdbwM07NgI=\n" + 95 "-----END CERTIFICATE-----"; 96 static String trustedPrivateKey = // Private key in the format of PKCS#8 97 "MIICeAIBADANBgkqhkiG9w0BAQEFAASCAmIwggJeAgEAAoGBANtiq0AIJK+iVRwF\n" + 98 "rqcD7fYXTCbMYC5Qz/k6AXBy7/1rI8wDhEJLE3m/+NSqiJwZcmdq2dNh/1fJFrwv\n" + 99 "zuURbc9+paOBWeHbN+Scx3huw91oPZme385VpoK3G13rSE114S/rF4DM9mz4EStF\n" + 100 "hSHXATjtdbskNOAYGLTVx8uEy9GbAgMBAAECgYEA2VjHkIiA0ABjkX+PqKeb+VLb\n" + 101 "fxS7tSca5C8zfdRhLxAWRui0/3ihst0eCJNrBDuxvAOACovsDWyLuaUjtI2v2ysz\n" + 102 "vz6SPyGy82PhQOFzyKQuQ814N6EpothpiZzF0yFchfKIGhUsdY89UrGs9nM7m6NT\n" + 103 "rztYvgIu4avg2VPR2AECQQD+pFAqipR2BplQRIuuRSZfHRxvoEyDjT1xnHJsC6WP\n" + 104 "I5hCLghL91MhQGWbP4EJMKYQOTRVukWlcp2Kycpf+P5hAkEA3I43gmVUAPEdyZdY\n" + 105 "fatW7OaLlbbYJb6qEtpCZ1Rwe/BIvm6H6E3qSi/lpz7Ia7WDulpbF6BawHH3pRFq\n" + 106 "CUY5ewJBAP3pUDqrRpBN0jB0uSeDslhjSciQ+dqvSpZv3rSYBHUvlBJhnkpJiy37\n" + 107 "7ZUZhIxqYxyIPgRBolLwb+FFh7OdL+ECQCtldDic9WVmC+VheRDpCKZ+SlK/8lGi\n" + 108 "7VXeShiIvcU1JysJFoa35fSI7hf1O3wt7+hX5PqGG7Un94EsJwACKEcCQQC1TWt6\n" + 109 "ArKH6tRxKjOxFtqfs8fgEVYUaOr3j1jF4KBUuX2mtQtddZe3VfJ2wPsuKMMxmhkB\n" + 110 "e7xWWZnJsErt2e+E"; 111 112 // Certificate information: 113 // Issuer: C=US, O=Java, OU=SunJSSE Test Serivce 114 // Validity 115 // Not Before: May 5 02:40:53 2012 GMT 116 // Not After : Jan 21 02:40:53 2032 GMT 117 // Subject: C=US, O=Java, OU=SunJSSE Test Serivce, CN=casigner 118 // X509v3 Subject Key Identifier: 119 // 13:07:E0:11:07:DB:EB:33:23:87:31:D0:DB:7E:16:56:BE:11:90:0A 120 // X509v3 Authority Key Identifier: 121 // keyid:DD:4E:8D:2A:11:C0:83:03:F0:AC:EB:A2:BF:F9:F2:7D:C8:69:1F:9B 122 // DirName:/C=US/O=Java/OU=SunJSSE Test Serivce 123 // serial:00 124 static String caSignerStr = 125 "-----BEGIN CERTIFICATE-----\n" + 126 "MIICqDCCAhGgAwIBAgIBAjANBgkqhkiG9w0BAQQFADA7MQswCQYDVQQGEwJVUzEN\n" + 127 "MAsGA1UEChMESmF2YTEdMBsGA1UECxMUU3VuSlNTRSBUZXN0IFNlcml2Y2UwHhcN\n" + 128 "MTIwNTA1MDI0MDUzWhcNMzIwMTIxMDI0MDUzWjBOMQswCQYDVQQGEwJVUzENMAsG\n" + 129 "A1UEChMESmF2YTEdMBsGA1UECxMUU3VuSlNTRSBUZXN0IFNlcml2Y2UxETAPBgNV\n" + 130 "BAMTCGNhc2lnbmVyMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC+x8+o7oM0\n" + 131 "ct/LZmZLXBL4CQ8jrULD5P7NtEW0hg/zxBFZfBHf+44Oo2eMPYZj+7xaREOH5BmV\n" + 132 "KRYlzRtONAaC5Ng4Mrm5UKNPcMIIUjUOvm7vWM4oSTMSfoEcSX+vp99uUAkw3w7Z\n" + 133 "+frYDm1M4At/j0b+lLij71GFN2L8drpgPQIDAQABo4GoMIGlMB0GA1UdDgQWBBQT\n" + 134 "B+ARB9vrMyOHMdDbfhZWvhGQCjBjBgNVHSMEXDBagBTdTo0qEcCDA/Cs66K/+fJ9\n" + 135 "yGkfm6E/pD0wOzELMAkGA1UEBhMCVVMxDTALBgNVBAoTBEphdmExHTAbBgNVBAsT\n" + 136 "FFN1bkpTU0UgVGVzdCBTZXJpdmNlggEAMBIGA1UdEwEB/wQIMAYBAf8CAQEwCwYD\n" + 137 "VR0PBAQDAgEGMA0GCSqGSIb3DQEBBAUAA4GBAI+LXA/UCPkTANablUkt80JNPWsl\n" + 138 "pS4XLNgPxWaN0bkRDs5oI4ooWAz1rwpeJ/nfetOvWlpmrVjSeovBFja5Hl+dUHTf\n" + 139 "VfuyzkxXbhuNiJIpo1mVBpNsjwu9YRxuwX6UA2LTUQpgvtVJEE012x3zRvxBCbu2\n" + 140 "Y/v1R5fZ4c+hXDfC\n" + 141 "-----END CERTIFICATE-----"; 142 static String caSignerPrivateKey = // Private key in the format of PKCS#8 143 "MIICdgIBADANBgkqhkiG9w0BAQEFAASCAmAwggJcAgEAAoGBAL7Hz6jugzRy38tm\n" + 144 "ZktcEvgJDyOtQsPk/s20RbSGD/PEEVl8Ed/7jg6jZ4w9hmP7vFpEQ4fkGZUpFiXN\n" + 145 "G040BoLk2DgyublQo09wwghSNQ6+bu9YzihJMxJ+gRxJf6+n325QCTDfDtn5+tgO\n" + 146 "bUzgC3+PRv6UuKPvUYU3Yvx2umA9AgMBAAECgYBYvu30cW8LONyt62Zua9hPFTe7\n" + 147 "qt9B7QYyfkdmoG5PQMepTrOp84SzfoOukvgvDm0huFuJnSvhXQl2cCDhkgXskvFj\n" + 148 "Hh7KBCFViVXokGdq5YoS0/KYMyQV0TZfJUvILBl51uc4/siQ2tClC/N4sa+1JhgW\n" + 149 "a6dFGfRjiUKSSlmMwQJBAPWpIz3Q/c+DYMvoQr5OD8EaYwYIevlTdXb97RnJJh2b\n" + 150 "UnhB9jrqesJiHYVzPmP0ukyPOXOwlp2T5Am4Kw0LFOkCQQDGz150NoHOp28Mvyc4\n" + 151 "CTqz/zYzUhy2eCJESl196uyP4N65Y01VYQ3JDww4DlsXiU17tVSbgA9TCcfTYOzy\n" + 152 "vyw1AkARUky+1hafZCcWGZljK8PmnMKwsTZikCTvL/Zg5BMA8Wu+OQBwpQnk3OAy\n" + 153 "Aa87gw0DyvGFG8Vy9POWT9sRP1/JAkBqP0hrMvYMSs6+MSn0eHo2151PsAJIQcuO\n" + 154 "U2/Da1khSzu8N6WMi2GiobgV/RYRbf9KrY2ZzMZjykZQYOxAjopBAkEAghCu38cN\n" + 155 "aOsW6ueo24uzsWI1FTdE+qWNVEi3RSP120xXBCyhaBjIq4WVSlJK9K2aBaJpit3j\n" + 156 "iQ5tl6zrLlxQhg=="; 157 158 // Certificate information: 159 // Issuer: C=US, O=Java, OU=SunJSSE Test Serivce, CN=casigner 160 // Validity 161 // Not Before: May 5 02:40:57 2012 GMT 162 // Not After : Jan 21 02:40:57 2032 GMT 163 // Subject: C=US, O=Java, OU=SunJSSE Test Serivce, CN=certissuer 164 // X509v3 Subject Key Identifier: 165 // 39:0E:C6:33:B1:50:BC:73:07:31:E5:D8:04:F7:BB:97:55:CF:9B:C8 166 // X509v3 Authority Key Identifier: 167 // keyid:13:07:E0:11:07:DB:EB:33:23:87:31:D0:DB:7E:16:56:BE:11:90:0A 168 // DirName:/C=US/O=Java/OU=SunJSSE Test Serivce 169 // serial:02 170 static String certIssuerStr = 171 "-----BEGIN CERTIFICATE-----\n" + 172 "MIICvjCCAiegAwIBAgIBAzANBgkqhkiG9w0BAQQFADBOMQswCQYDVQQGEwJVUzEN\n" + 173 "MAsGA1UEChMESmF2YTEdMBsGA1UECxMUU3VuSlNTRSBUZXN0IFNlcml2Y2UxETAP\n" + 174 "BgNVBAMTCGNhc2lnbmVyMB4XDTEyMDUwNTAyNDA1N1oXDTMyMDEyMTAyNDA1N1ow\n" + 175 "UDELMAkGA1UEBhMCVVMxDTALBgNVBAoTBEphdmExHTAbBgNVBAsTFFN1bkpTU0Ug\n" + 176 "VGVzdCBTZXJpdmNlMRMwEQYDVQQDEwpjZXJ0aXNzdWVyMIGfMA0GCSqGSIb3DQEB\n" + 177 "AQUAA4GNADCBiQKBgQCyz55zinU6kNL/LeiTNiBI0QWYmDG0YTotuC4D75liBNqs\n" + 178 "7Mmladsh2mTtQUAwmuGaGzaZV25a+cUax0DXZoyBwdbTI09u1bUYsZcaUUKbPoCC\n" + 179 "HH26e4jLFL4olW13Sv4ZAd57tIYevMw+Fp5f4fLPFGegCJTFlv2Qjpmic/cuvQID\n" + 180 "AQABo4GpMIGmMB0GA1UdDgQWBBQ5DsYzsVC8cwcx5dgE97uXVc+byDBjBgNVHSME\n" + 181 "XDBagBQTB+ARB9vrMyOHMdDbfhZWvhGQCqE/pD0wOzELMAkGA1UEBhMCVVMxDTAL\n" + 182 "BgNVBAoTBEphdmExHTAbBgNVBAsTFFN1bkpTU0UgVGVzdCBTZXJpdmNlggECMBMG\n" + 183 "A1UdEwEB/wQJMAcBAf8CAgQAMAsGA1UdDwQEAwIBBjANBgkqhkiG9w0BAQQFAAOB\n" + 184 "gQCQTagenCdClT98C+oTJGJrw/dUBD9K3tE6ZJKPMc/2bUia8G5ei1C0eXj4mWG2\n" + 185 "lu9umR6C90/A6qB050QB2h50qtqxSrkpu+ym1yypauZpg7U3nUY9wZWJNI1vqrQZ\n" + 186 "pqUMRcXY3iQIVKx+Qj+4/Za1wwFQzpEoGmqRW31V1SdMEw==\n" + 187 "-----END CERTIFICATE-----"; 188 static String certIssuerPrivateKey = // Private key in the format of PKCS#8 189 "MIICeQIBADANBgkqhkiG9w0BAQEFAASCAmMwggJfAgEAAoGBALLPnnOKdTqQ0v8t\n" + 190 "6JM2IEjRBZiYMbRhOi24LgPvmWIE2qzsyaVp2yHaZO1BQDCa4ZobNplXblr5xRrH\n" + 191 "QNdmjIHB1tMjT27VtRixlxpRQps+gIIcfbp7iMsUviiVbXdK/hkB3nu0hh68zD4W\n" + 192 "nl/h8s8UZ6AIlMWW/ZCOmaJz9y69AgMBAAECgYEAjtew2tgm4gxDojqIauF4VPM1\n" + 193 "pzsdqd1p3pAdomNLgrQiBLZ8N7oiph6TNb1EjA+OXc+ThFgF/oM9ZDD8qZZwcvjN\n" + 194 "qDZlpTkFs2TaGcyEZfUaMB45NHVs6Nn+pSkagSNwwy3xeyAct7sQEzGNTDlEwVv5\n" + 195 "7V9LQutQtBd6xT48KzkCQQDpNRfv2OFNG/6GtzJoO68oJhpnpl2MsYNi4ntRkre/\n" + 196 "6uXpiCYaDskcrPMRwOOs0m7mxG+Ev+uKnLnSoEMm1GCbAkEAxEmDtiD0Psb8Z9BL\n" + 197 "ZRb83Jqho3xe2MCAh3xUfz9b/Mhae9dZ44o4OCgQZuwvW1mczF0NtpgZl93BmYa2\n" + 198 "hTwHhwJBAKHrEj6ep/fA6x0gD2idoATRR94VfbiU+7NpqtO9ecVP0+gsdr/66hn1\n" + 199 "3yLBeZLh3MxvMTrLgkAQh1i9m0JXjOcCQQClLXAHHegrw+u3uNMZeKTFR+Lp3sk6\n" + 200 "AZSnbvr0Me9I45kxSeG81x3ENALJecvIRbrrRws5MvmmkNhQR8rkh8WVAkEAk6b+\n" + 201 "aVtmBgUaTS5+FFlHGHJY9HFrfT1a1C/dwyMuqlmbC3YsBmZaMOlKli5TXNybLff8\n" + 202 "5KMeGEpXMzgC7AscGA=="; 203 204 // Certificate information: 205 // Issuer: C=US, O=Java, OU=SunJSSE Test Serivce, CN=certissuer 206 // Validity 207 // Not Before: May 5 02:41:01 2012 GMT 208 // Not After : Jan 21 02:41:01 2032 GMT 209 // Subject: C=US, O=Java, OU=SunJSSE Test Serivce, CN=localhost 210 // X509v3 Subject Key Identifier: 211 // AD:C0:2C:4C:E4:C2:2E:A1:BB:5D:92:BE:66:E0:4E:E0:0D:2F:11:EF 212 // X509v3 Authority Key Identifier: 213 // keyid:39:0E:C6:33:B1:50:BC:73:07:31:E5:D8:04:F7:BB:97:55:CF:9B:C8 214 static String serverCertStr = 215 "-----BEGIN CERTIFICATE-----\n" + 216 "MIICjTCCAfagAwIBAgIBBDANBgkqhkiG9w0BAQQFADBQMQswCQYDVQQGEwJVUzEN\n" + 217 "MAsGA1UEChMESmF2YTEdMBsGA1UECxMUU3VuSlNTRSBUZXN0IFNlcml2Y2UxEzAR\n" + 218 "BgNVBAMTCmNlcnRpc3N1ZXIwHhcNMTIwNTA1MDI0MTAxWhcNMzIwMTIxMDI0MTAx\n" + 219 "WjBPMQswCQYDVQQGEwJVUzENMAsGA1UEChMESmF2YTEdMBsGA1UECxMUU3VuSlNT\n" + 220 "RSBUZXN0IFNlcml2Y2UxEjAQBgNVBAMTCWxvY2FsaG9zdDCBnzANBgkqhkiG9w0B\n" + 221 "AQEFAAOBjQAwgYkCgYEAvwaUd7wmBSKqycEstYLWD26vkU08DM39EtaT8wL9HnQ0\n" + 222 "fgPblwBFI4zdLa2cuYXRZcFUb04N8nrkcpR0D6kkE+AlFAoRWrrZF80B7JTbtEK4\n" + 223 "1PIeurihXvUT+4MpzGLOojIihMfvM4ufelblD56SInso4WFHm7t4qCln88J1gjkC\n" + 224 "AwEAAaN4MHYwCwYDVR0PBAQDAgPoMB0GA1UdDgQWBBStwCxM5MIuobtdkr5m4E7g\n" + 225 "DS8R7zAfBgNVHSMEGDAWgBQ5DsYzsVC8cwcx5dgE97uXVc+byDAnBgNVHSUEIDAe\n" + 226 "BggrBgEFBQcDAQYIKwYBBQUHAwIGCCsGAQUFBwMDMA0GCSqGSIb3DQEBBAUAA4GB\n" + 227 "AGfwcfdvEG/nSCiAn2MGbYHp34mgF3OA1SJLWUW0LvWJhwm2cn4AXlSoyvbwrkaB\n" + 228 "IDDCwhJvvc0vUyL2kTx7sqVaFTq3mDs+ktlB/FfH0Pb+i8FE+g+7T42Iw/j0qxHL\n" + 229 "YmgbrjBQf5WYN1AvBE/rrPt9aOtS3UsqtVGW574b0shW\n" + 230 "-----END CERTIFICATE-----"; 231 static String serverPrivateKey = // Private key in the format of PKCS#8 232 "MIICdAIBADANBgkqhkiG9w0BAQEFAASCAl4wggJaAgEAAoGBAL8GlHe8JgUiqsnB\n" + 233 "LLWC1g9ur5FNPAzN/RLWk/MC/R50NH4D25cARSOM3S2tnLmF0WXBVG9ODfJ65HKU\n" + 234 "dA+pJBPgJRQKEVq62RfNAeyU27RCuNTyHrq4oV71E/uDKcxizqIyIoTH7zOLn3pW\n" + 235 "5Q+ekiJ7KOFhR5u7eKgpZ/PCdYI5AgMBAAECf3CscOYvFD3zNMnMJ5LomVqA7w3F\n" + 236 "gKYM2jlCWAH+wU41PMEXhW6Lujw92jgXL1o+lERwxFzirVdZJWZwKgUSvzP1G0h3\n" + 237 "fkucq1/UWnToK+8NSXNM/yS8hXbBgSEoJo5f7LKcIi1Ev6doBVofMxs+njzyWKbM\n" + 238 "Nb7rOLHadghoon0CQQDgQzbzzSN8Dc1YmmylhI5v+0sQRHH0DL7D24k4Weh4vInG\n" + 239 "EAbt4x8M7ZKEo8/dv0s4hbmNmAnJl93/RRxIyEqLAkEA2g87DiswSQam2pZ8GlrO\n" + 240 "+w4Qg9mH8uxx8ou2rl0XlHzH1XiTNbkjfY0EZoL7L31BHFk9n11Fb2P85g6ws+Hy\n" + 241 "ywJAM/xgyLNM/nzUlS128geAXUULaYH0SHaL4isJ7B4rXZGW/mrIsGxtzjlkNYsj\n" + 242 "rGujrD6TfNc5rZmexIXowJZtcQJBAIww+pCzZ4mrgx5JXWQ8OZHiiu+ZrPOa2+9J\n" + 243 "r5sOMpi+WGN/73S8oHqZbNjTINZ5OqEVJq8MchWZPQBTNXuQql0CQHEjUzzkCQa3\n" + 244 "j6JTa2KAdqyvLOx0XF9zcc1gA069uNQI2gPUHS8V215z57f/gMGnDNhVfLs/vMKz\n" + 245 "sFkVZ3zg7As="; 246 247 // Certificate information: 248 // Issuer: C=US, O=Java, OU=SunJSSE Test Serivce, CN=certissuer 249 // Validity 250 // Not Before: May 5 02:41:02 2012 GMT 251 // Not After : Jan 21 02:41:02 2032 GMT 252 // Subject: C=US, O=Java, OU=SunJSSE Test Serivce, CN=InterOp Tester 253 // X509v3 Subject Key Identifier: 254 // 57:7D:E2:33:33:60:DF:DD:5E:ED:81:3F:EB:F2:1B:59:7F:50:9C:99 255 // X509v3 Authority Key Identifier: 256 // keyid:39:0E:C6:33:B1:50:BC:73:07:31:E5:D8:04:F7:BB:97:55:CF:9B:C8 257 static String clientCertStr = 258 "-----BEGIN CERTIFICATE-----\n" + 259 "MIICaTCCAdKgAwIBAgIBBTANBgkqhkiG9w0BAQQFADBQMQswCQYDVQQGEwJVUzEN\n" + 260 "MAsGA1UEChMESmF2YTEdMBsGA1UECxMUU3VuSlNTRSBUZXN0IFNlcml2Y2UxEzAR\n" + 261 "BgNVBAMTCmNlcnRpc3N1ZXIwHhcNMTIwNTA1MDI0MTAyWhcNMzIwMTIxMDI0MTAy\n" + 262 "WjBUMQswCQYDVQQGEwJVUzENMAsGA1UEChMESmF2YTEdMBsGA1UECxMUU3VuSlNT\n" + 263 "RSBUZXN0IFNlcml2Y2UxFzAVBgNVBAMTDkludGVyT3AgVGVzdGVyMIGfMA0GCSqG\n" + 264 "SIb3DQEBAQUAA4GNADCBiQKBgQC1pA71nDg1KhhnHjRdi/eVDUa7uFZAtN8R9huu\n" + 265 "pTwFoyqSX8lDMz8jDawOMmaI9dVZLjTh3hnf4KBEqQOearFVz45yBOjlgPLBuI4F\n" + 266 "D/ORhgmDaIu2NK+c1yj6YQlyiO0DPwh55GtPLVG3iuEpejU7gQyaMuTaddoXrO7s\n" + 267 "xwzanQIDAQABo08wTTALBgNVHQ8EBAMCA+gwHQYDVR0OBBYEFFd94jMzYN/dXu2B\n" + 268 "P+vyG1l/UJyZMB8GA1UdIwQYMBaAFDkOxjOxULxzBzHl2AT3u5dVz5vIMA0GCSqG\n" + 269 "SIb3DQEBBAUAA4GBAHTgB5W7wnl7Jnb4wNQcb6JdR8FRHIdslcRfnReFfZBHZZux\n" + 270 "ChpA1lf62KIzYohKoxQXXMul86vnVSHnXq5xctHEmxCBnALEnoAcCOv6wfWqEA7g\n" + 271 "2rX+ydmu+0ArbqKhSOypZ7K3ame0UOJJ6HDxdsgBYJuotmSou4KKq9e8GF+d\n" + 272 "-----END CERTIFICATE-----"; 273 static String clientPrivateKey = // Private key in the format of PKCS#8 274 "MIICeAIBADANBgkqhkiG9w0BAQEFAASCAmIwggJeAgEAAoGBALWkDvWcODUqGGce\n" + 275 "NF2L95UNRru4VkC03xH2G66lPAWjKpJfyUMzPyMNrA4yZoj11VkuNOHeGd/goESp\n" + 276 "A55qsVXPjnIE6OWA8sG4jgUP85GGCYNoi7Y0r5zXKPphCXKI7QM/CHnka08tUbeK\n" + 277 "4Sl6NTuBDJoy5Np12hes7uzHDNqdAgMBAAECgYEAjLwygwapXjfhdHQoqpp6F9iT\n" + 278 "h3sKCVSaybXgOO75lHyZzZO9wv1/288KEm3mmBOxXEm6245UievnAYvaq/GKt93O\n" + 279 "pj2zRefBzZjGbz0v84fmna/MN6zUUYX1PcVRMKWLx9HKKmQihzwoXdBX0o9PPXdi\n" + 280 "LfzujNa/q8/mpI5PmEECQQDZwLSaL7OReWZTY4NoQuNzwhx5IKJUOtCFQfmHKZSW\n" + 281 "wtXntZf+E5W9tGaDY5wjpq5cilKDAHdEAlFWxDe1PoE1AkEA1YuTBpctOLBfquFn\n" + 282 "Y/S3lzGVlnIHDk3dj4bFglkoJ2bCdlwRNUyBSjAjBDcbYhper8S7GlEN5SiEdz9I\n" + 283 "3OjIyQJBAKEPMgYhZjYhjxf6sQV7A/VpC9pj0u1uGzGVXNUmYisorUKXRHa/UbBh\n" + 284 "MLnaAXE1Jh54iRMwUwbQmA0PUQ0T0EkCQQCcr6/umwhkWw2nHYK2Vf5LoudGn15M\n" + 285 "AZg7UsEjVnXfC0hOfllmCT+ohs96rVCbWAv33lsHAUg3x9YChV3aMbf5AkAj1kuV\n" + 286 "jUTgFKjediyQC6uof7YdLn+gQGiXK1XE0GBN4WMkzcLiS0jC+MFTgKfFnFdh9K0y\n" + 287 "fswYKdTA/o8RKaa5"; 288 289 static char passphrase[] = "passphrase".toCharArray(); 290 291 /* 292 * Is the server ready to serve? 293 */ 294 volatile static boolean serverReady = false; 295 296 /* 297 * Turn on SSL debugging? 298 */ 299 static boolean debug = false; 300 301 /* 302 * Define the server side of the test. 303 * 304 * If the server prematurely exits, serverReady will be set to true 305 * to avoid infinite hangs. 306 */ 307 void doServerSide() throws Exception { 308 SSLContext context = getSSLContext(true); 309 SSLServerSocketFactory sslssf = context.getServerSocketFactory(); 310 311 SSLServerSocket sslServerSocket = 312 (SSLServerSocket)sslssf.createServerSocket(serverPort); 313 serverPort = sslServerSocket.getLocalPort(); 314 SSLSocket sslSocket = null; 315 try { 316 /* 317 * Signal Client, we're ready for his connect. 318 */ 319 serverReady = true; 320 321 sslSocket = (SSLSocket) sslServerSocket.accept(); 322 sslSocket.setNeedClientAuth(true); 323 324 InputStream sslIS = sslSocket.getInputStream(); 325 OutputStream sslOS = sslSocket.getOutputStream(); 326 327 sslIS.read(); 328 sslOS.write(85); 329 sslOS.flush(); 330 } finally { 331 if (sslSocket != null) { 332 sslSocket.close(); 333 } 334 sslServerSocket.close(); 335 } 336 } 337 338 /* 339 * Define the client side of the test. 340 * 341 * If the server prematurely exits, serverReady will be set to true 342 * to avoid infinite hangs. 343 */ 344 void doClientSide() throws Exception { 345 /* 346 * Wait for server to get started. 347 */ 348 while (!serverReady) { 349 Thread.sleep(50); 350 } 351 352 SSLContext context = getSSLContext(false); 353 SSLSocketFactory sslsf = context.getSocketFactory(); 354 355 SSLSocket sslSocket = 356 (SSLSocket)sslsf.createSocket("localhost", serverPort); 357 try { 358 InputStream sslIS = sslSocket.getInputStream(); 359 OutputStream sslOS = sslSocket.getOutputStream(); 360 361 sslOS.write(280); 362 sslOS.flush(); 363 sslIS.read(); 364 } finally { 365 sslSocket.close(); 366 } 367 } 368 369 // get the ssl context 370 private static SSLContext getSSLContext(boolean isServer) throws Exception { 371 372 // generate certificate from cert string 373 CertificateFactory cf = CertificateFactory.getInstance("X.509"); 374 375 // create a key store 376 KeyStore ks = KeyStore.getInstance("JKS"); 377 ks.load(null, null); 378 379 // import the trused cert 380 ByteArrayInputStream is = 381 new ByteArrayInputStream(trusedCertStr.getBytes()); 382 Certificate trusedCert = cf.generateCertificate(is); 383 is.close(); 384 385 ks.setCertificateEntry("SunJSSE Test Serivce", trusedCert); 386 387 // import the certificate chain and key 388 Certificate[] chain = new Certificate[3]; 389 390 is = new ByteArrayInputStream(caSignerStr.getBytes()); 391 Certificate caSignerCert = cf.generateCertificate(is); 392 is.close(); 393 chain[2] = caSignerCert; 394 395 is = new ByteArrayInputStream(certIssuerStr.getBytes()); 396 Certificate certIssuerCert = cf.generateCertificate(is); 397 is.close(); 398 chain[1] = certIssuerCert; 399 400 PKCS8EncodedKeySpec priKeySpec = null; 401 if (isServer) { 402 priKeySpec = new PKCS8EncodedKeySpec( 403 Base64.getMimeDecoder().decode(serverPrivateKey)); 404 is = new ByteArrayInputStream(serverCertStr.getBytes()); 405 } else { 406 priKeySpec = new PKCS8EncodedKeySpec( 407 Base64.getMimeDecoder().decode(clientPrivateKey)); 408 is = new ByteArrayInputStream(clientCertStr.getBytes()); 409 } 410 KeyFactory kf = KeyFactory.getInstance("RSA"); 411 RSAPrivateKey priKey = (RSAPrivateKey)kf.generatePrivate(priKeySpec); 412 Certificate keyCert = cf.generateCertificate(is); 413 is.close(); 414 chain[0] = keyCert; 415 416 ks.setKeyEntry("End Entity", priKey, passphrase, chain); 417 418 // check the certification path 419 PKIXParameters paras = new PKIXParameters(ks); 420 paras.setRevocationEnabled(false); 421 CertPath path = cf.generateCertPath(Arrays.asList(chain)); 422 CertPathValidator cv = CertPathValidator.getInstance("PKIX"); 423 cv.validate(path, paras); 424 425 // create SSL context 426 TrustManagerFactory tmf = TrustManagerFactory.getInstance(tmAlgorithm); 427 tmf.init(ks); 428 429 SSLContext ctx = SSLContext.getInstance("TLS"); 430 KeyManagerFactory kmf = KeyManagerFactory.getInstance("NewSunX509"); 431 kmf.init(ks, passphrase); 432 433 ctx.init(kmf.getKeyManagers(), tmf.getTrustManagers(), null); 434 ks = null; 435 436 return ctx; 437 } 438 439 private static String tmAlgorithm; // trust manager 440 441 private static void parseArguments(String[] args) { 442 tmAlgorithm = args[0]; 443 } 444 445 /* 446 * ============================================================= 447 * The remainder is just support stuff 448 */ 449 450 // use any free port by default 451 volatile int serverPort = 0; 452 453 volatile Exception serverException = null; 454 volatile Exception clientException = null; 455 456 public static void main(String args[]) throws Exception { 457 if (debug) 458 System.setProperty("javax.net.debug", "all"); 459 460 461 /* 462 * Get the customized arguments. 463 */ 464 parseArguments(args); 465 466 /* 467 * Start the tests. 468 */ 469 new BasicConstraints(); 470 } 471 472 Thread clientThread = null; 473 Thread serverThread = null; 474 /* 475 * Primary constructor, used to drive remainder of the test. 476 * 477 * Fork off the other side, then do your work. 478 */ 479 BasicConstraints() throws Exception { 480 if (separateServerThread) { 481 startServer(true); 482 startClient(false); 483 } else { 484 startClient(true); 485 startServer(false); 486 } 487 488 /* 489 * Wait for other side to close down. 490 */ 491 if (separateServerThread) { 492 serverThread.join(); 493 } else { 494 clientThread.join(); 495 } 496 497 /* 498 * When we get here, the test is pretty much over. 499 * 500 * If the main thread excepted, that propagates back 501 * immediately. If the other thread threw an exception, we 502 * should report back. 503 */ 504 if (serverException != null) 505 throw serverException; 506 if (clientException != null) 507 throw clientException; 508 } 509 510 void startServer(boolean newThread) throws Exception { 511 if (newThread) { 512 serverThread = new Thread() { 513 public void run() { 514 try { 515 doServerSide(); 516 } catch (Exception e) { 517 /* 518 * Our server thread just died. 519 * 520 * Release the client, if not active already... 521 */ 522 System.err.println("Server died..."); 523 serverReady = true; 524 serverException = e; 525 } 526 } 527 }; 528 serverThread.start(); 529 } else { 530 doServerSide(); 531 } 532 } 533 534 void startClient(boolean newThread) throws Exception { 535 if (newThread) { 536 clientThread = new Thread() { 537 public void run() { 538 try { 539 doClientSide(); 540 } catch (Exception e) { 541 /* 542 * Our client thread just died. 543 */ 544 System.err.println("Client died..."); 545 clientException = e; 546 } 547 } 548 }; 549 clientThread.start(); 550 } else { 551 doClientSide(); 552 } 553 } 554 555 }