1 /* 2 * Copyright (c) 2012, 2015, 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. Oracle designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Oracle in the LICENSE file that accompanied this code. 10 * 11 * This code is distributed in the hope that it will be useful, but WITHOUT 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 * version 2 for more details (a copy is included in the LICENSE file that 15 * accompanied this code). 16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 26 // 27 // SunJSSE does not support dynamic system properties, no way to re-use 28 // system properties in samevm/agentvm mode. 29 // 30 31 /* 32 * @test 33 * @bug 7068321 34 * @summary Support TLS Server Name Indication (SNI) Extension in JSSE Server 35 * @run main/othervm SSLSocketSNISensitive PKIX www.example.com 36 * @run main/othervm SSLSocketSNISensitive SunX509 www.example.com 37 * @run main/othervm SSLSocketSNISensitive PKIX www.example.net 38 * @run main/othervm SSLSocketSNISensitive SunX509 www.example.net 39 * @run main/othervm SSLSocketSNISensitive PKIX www.invalid.com 40 * @run main/othervm SSLSocketSNISensitive SunX509 www.invalid.com 41 */ 42 43 import java.net.*; 44 import java.util.*; 45 import java.io.*; 46 import javax.net.ssl.*; 47 import java.security.Security; 48 import java.security.KeyStore; 49 import java.security.KeyFactory; 50 import java.security.cert.Certificate; 51 import java.security.cert.X509Certificate; 52 import java.security.cert.CertificateFactory; 53 import java.security.spec.*; 54 import java.security.interfaces.*; 55 import java.util.Base64; 56 57 // Note: this test case works only on TLS 1.2 and prior versions because of 58 // the use of MD5withRSA signed certificate. 59 public class SSLSocketSNISensitive { 60 61 /* 62 * ============================================================= 63 * Set the various variables needed for the tests, then 64 * specify what tests to run on each side. 65 */ 66 67 /* 68 * Should we run the client or server in a separate thread? 69 * Both sides can throw exceptions, but do you have a preference 70 * as to which side should be the main thread. 71 */ 72 static boolean separateServerThread = false; 73 74 /* 75 * Where do we find the keystores? 76 */ 77 // Certificates and key used in the test. 78 static String trustedCertStr = 79 "-----BEGIN CERTIFICATE-----\n" + 80 "MIICkjCCAfugAwIBAgIBADANBgkqhkiG9w0BAQQFADA7MQswCQYDVQQGEwJVUzEN\n" + 81 "MAsGA1UEChMESmF2YTEdMBsGA1UECxMUU3VuSlNTRSBUZXN0IFNlcml2Y2UwHhcN\n" + 82 "MTIwNDE3MTIwNjA3WhcNMzMwMzI4MTIwNjA3WjA7MQswCQYDVQQGEwJVUzENMAsG\n" + 83 "A1UEChMESmF2YTEdMBsGA1UECxMUU3VuSlNTRSBUZXN0IFNlcml2Y2UwgZ8wDQYJ\n" + 84 "KoZIhvcNAQEBBQADgY0AMIGJAoGBANY+7Enp+1S566kLcKk+qe4Ki6BxaHGZ+v7r\n" + 85 "vLksx9IQZCbAEf4YLbrZhKzKD3SPIJXyxPFwknAknIh3Knk8mViOZks7T8L3GnJr\n" + 86 "TBaVvDyTzDJum/QYiahfO2qpfN/Oya2UILmqsBAeLyWpzbQsAyWBXfoUtkOUgnzK\n" + 87 "fk6QAKYrAgMBAAGjgaUwgaIwHQYDVR0OBBYEFEtmQi7jT1ijXOafPsfkrLwSVu9e\n" + 88 "MGMGA1UdIwRcMFqAFEtmQi7jT1ijXOafPsfkrLwSVu9eoT+kPTA7MQswCQYDVQQG\n" + 89 "EwJVUzENMAsGA1UEChMESmF2YTEdMBsGA1UECxMUU3VuSlNTRSBUZXN0IFNlcml2\n" + 90 "Y2WCAQAwDwYDVR0TAQH/BAUwAwEB/zALBgNVHQ8EBAMCAQYwDQYJKoZIhvcNAQEE\n" + 91 "BQADgYEAkKWxMc4+ODk5WwLXXweB8/IKfVfrizNn0KLEgsZ6xNXFIXDpiPGAFcgl\n" + 92 "MzFO424JgyvUulsUc/X16Cnuwwntkk6KUG7vEV7h4o9sAV7Cax3gfQE/EZFb4ybn\n" + 93 "aBm1UsujMKd/ovqbbbxJbmOWzCeo0QfIGleDEyh3NBBZ0i11Kiw=\n" + 94 "-----END CERTIFICATE-----"; 95 96 // web server certificate, www.example.com 97 static String targetCertStr_A = 98 "-----BEGIN CERTIFICATE-----\n" + 99 "MIICVTCCAb6gAwIBAgIBAjANBgkqhkiG9w0BAQQFADA7MQswCQYDVQQGEwJVUzEN\n" + 100 "MAsGA1UEChMESmF2YTEdMBsGA1UECxMUU3VuSlNTRSBUZXN0IFNlcml2Y2UwHhcN\n" + 101 "MTIwNDE3MTIwNjA4WhcNMzIwMTAzMTIwNjA4WjBVMQswCQYDVQQGEwJVUzENMAsG\n" + 102 "A1UEChMESmF2YTEdMBsGA1UECxMUU3VuSlNTRSBUZXN0IFNlcml2Y2UxGDAWBgNV\n" + 103 "BAMTD3d3dy5leGFtcGxlLmNvbTCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEA\n" + 104 "4zFp3PZNzsd3ZwG6FNNWO9eSN+UBymlf8oCwpKJM2tIinmMWvWIXnlx/2UXIfSAq\n" + 105 "QEG3aXkAFyEiGGpQlBbqcfrESsHsiz2pnnm5dG2v/eS0Bwz1jmcuNmwnh3UQw2Vl\n" + 106 "+BLk8ukdrLjiCT8jARiHExYf1Xg+wUqQ9y8NV26hdaUCAwEAAaNPME0wCwYDVR0P\n" + 107 "BAQDAgPoMB0GA1UdDgQWBBQwtx+gqzn2w4y82brXlp7tqBYEZDAfBgNVHSMEGDAW\n" + 108 "gBRLZkIu409Yo1zmnz7H5Ky8ElbvXjANBgkqhkiG9w0BAQQFAAOBgQAJWo8B6Ud+\n" + 109 "/OU+UcZLihlfMX02OSlK2ZB7mfqpj2G3JT9yb0A+VbY3uuajmaYYIIxl3kXGz/n8\n" + 110 "M2Q/Ux/MDxG+IFKHC26Kuj4dAQgzjq2pILVPTE2QnaQTNCsgVZtTaC47SG9FRSoC\n" + 111 "qvnIvn/oTpKSqus76I1cR4joDtiV2OEuVw==\n" + 112 "-----END CERTIFICATE-----"; 113 114 // Private key in the format of PKCS#8 115 static String targetPrivateKey_A = 116 "MIICdgIBADANBgkqhkiG9w0BAQEFAASCAmAwggJcAgEAAoGBAOMxadz2Tc7Hd2cB\n" + 117 "uhTTVjvXkjflAcppX/KAsKSiTNrSIp5jFr1iF55cf9lFyH0gKkBBt2l5ABchIhhq\n" + 118 "UJQW6nH6xErB7Is9qZ55uXRtr/3ktAcM9Y5nLjZsJ4d1EMNlZfgS5PLpHay44gk/\n" + 119 "IwEYhxMWH9V4PsFKkPcvDVduoXWlAgMBAAECgYAqX2nuIyXp3fvgA0twXOYlbRRB\n" + 120 "Rn3qAXM6qFPJsNeCrFR2k+aG1cev6nKR1FkLNTeMGnWZv06MAcr5IML8i7WXyG4C\n" + 121 "LY/C0gedn94FDKFlln+bTENwQTGjn4lKysDA+IuNpasTeMCajbic+dPByhIdTOjZ\n" + 122 "iMCyxbLfpk40zQopVQJBAPyfGmkeHB3GjdbdgujWCGKb2UxBa4O8dy3O4l2yizTn\n" + 123 "uUqMGcwGY4ciNSVvZQ7jKo4vDmkSuYib4/woPChaNfMCQQDmO0BQuSWYGNtSwV35\n" + 124 "lafZfX1dNCLKm1iNA6A12evXgvQiE9WT4mqionig0VZW16HtiY4/BkHOcos/K9Um\n" + 125 "ARQHAkA8mkaRtSF1my5nv1gqVz5Hua+VdZQ/VDUbDiiL5cszc+ulkJqXsWirAG/T\n" + 126 "fTe3LJQG7A7+8fkEZrF4yoY0AAA1AkEAotokezULj5N9iAL5SzL9wIzQYV4ggfny\n" + 127 "YATBjXXxKccakwQ+ndWZIiMUeoS4ssLialhTgucVI0fIkU2a/r/ifwJAc6e+5Pvh\n" + 128 "MghQj/U788Od/v6rgqz/NGsduZ7uilCMcWiwA73OR2MHMH/OIuoofuEPrfuV9isV\n" + 129 "xVXhgpKfP/pdOA=="; 130 131 // web server certificate, www.example.net 132 static String targetCertStr_B = 133 "-----BEGIN CERTIFICATE-----\n" + 134 "MIICVTCCAb6gAwIBAgIBBDANBgkqhkiG9w0BAQQFADA7MQswCQYDVQQGEwJVUzEN\n" + 135 "MAsGA1UEChMESmF2YTEdMBsGA1UECxMUU3VuSlNTRSBUZXN0IFNlcml2Y2UwHhcN\n" + 136 "MTIwNDE3MTIwNjA5WhcNMzIwMTAzMTIwNjA5WjBVMQswCQYDVQQGEwJVUzENMAsG\n" + 137 "A1UEChMESmF2YTEdMBsGA1UECxMUU3VuSlNTRSBUZXN0IFNlcml2Y2UxGDAWBgNV\n" + 138 "BAMTD3d3dy5leGFtcGxlLm5ldDCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEA\n" + 139 "2VlzF1fvWYczDChrUeJiLJ1M/dIShCaOTfYGiXfQGEZCAWTacUclwr+rVMnZ75/c\n" + 140 "wwg5pNdXRijxMil8DBTS1gFcIFQhosLHvzIAe6ULlg/xB+/L6KBz+NTWfo/2KF6t\n" + 141 "xatmcToNrCcwi7eUOfbzQje65Tizs56jJYem2m7Rk0ECAwEAAaNPME0wCwYDVR0P\n" + 142 "BAQDAgPoMB0GA1UdDgQWBBQT/FR0cAWcZQ7h0X79KGki34OSQjAfBgNVHSMEGDAW\n" + 143 "gBRLZkIu409Yo1zmnz7H5Ky8ElbvXjANBgkqhkiG9w0BAQQFAAOBgQB67cPIT6fz\n" + 144 "6Ws8fBpYgW2ad4ci66i1WduBD9CpGFE+jRK2feRj6hvYBXocKj0AMWUFIEB2E3hA\n" + 145 "oIjxcf1GxIpHVl9DjlhxqXbA0Ktl7/NGNRlDSLTizOTl3FB1mMTlOGvXDVmpcFhl\n" + 146 "HuoP1hYvhTsBwPx5igGNchuPtDIUzL2mXw==\n" + 147 "-----END CERTIFICATE-----"; 148 149 static String targetPrivateKey_B = 150 "MIICdgIBADANBgkqhkiG9w0BAQEFAASCAmAwggJcAgEAAoGBANlZcxdX71mHMwwo\n" + 151 "a1HiYiydTP3SEoQmjk32Bol30BhGQgFk2nFHJcK/q1TJ2e+f3MMIOaTXV0Yo8TIp\n" + 152 "fAwU0tYBXCBUIaLCx78yAHulC5YP8Qfvy+igc/jU1n6P9ihercWrZnE6DawnMIu3\n" + 153 "lDn280I3uuU4s7OeoyWHptpu0ZNBAgMBAAECgYEAl19H26sfhD+32rDPxZCgBShs\n" + 154 "dZ33zVe45i0Bcn4iTLWpxKTDyf7eGps4rO2DvfKdYqt40ggzvSZIjUH9JcDe8GmG\n" + 155 "d3m0ILB7pg4jsFlpyeHpTO8grPLxA1G9s3o0DoFpz/rooqgFfe/DrRDmRoOSkgfV\n" + 156 "/gseIbgJHRO/Ctyvdh0CQQD6uFd0HxhH1jl/JzvPzIH4LSnPcdEh9zsMEb6uzh75\n" + 157 "9qL+IHD5N2I/pYZTKqDFIwhJf701+LKag55AX/zrDt7rAkEA3e00AbnwanDMa6Wj\n" + 158 "+gFekUQveSVra38LiihzCkyVvQpFjbiF1rUhSNQ0dpU5/hmrYF0C6H9VXAesfkUY\n" + 159 "WhpDgwJAYjgZOop77piDycZK7isFt32p5XSHIzFBVocVFlH1XKM8UyXOXDNQL/Le\n" + 160 "XnJSrSf+NRzvuNcG0PVC56Ey6brXpQJAY4M4vcltt5zq3R5CQBmbGRJ1IyKXX3Vx\n" + 161 "bDslEqoyvri7ZYgnY5aG3UxiVgYmIf3KrgQnCLAIS6MZQumiuMxsFwJAK5pEG063\n" + 162 "9ngUof4fDMvZphqZjZR1zMKz/V/9ge0DWBINaqFgsgebNu+MyImsC8C6WKjGmV/2\n" + 163 "f1MY0D7sC2vU/Q=="; 164 165 // web server certificate, www.invalid.com 166 static String targetCertStr_C = 167 "-----BEGIN CERTIFICATE-----\n" + 168 "MIICVTCCAb6gAwIBAgIBAzANBgkqhkiG9w0BAQQFADA7MQswCQYDVQQGEwJVUzEN\n" + 169 "MAsGA1UEChMESmF2YTEdMBsGA1UECxMUU3VuSlNTRSBUZXN0IFNlcml2Y2UwHhcN\n" + 170 "MTIwNDE3MTIwNjA5WhcNMzIwMTAzMTIwNjA5WjBVMQswCQYDVQQGEwJVUzENMAsG\n" + 171 "A1UEChMESmF2YTEdMBsGA1UECxMUU3VuSlNTRSBUZXN0IFNlcml2Y2UxGDAWBgNV\n" + 172 "BAMTD3d3dy5pbnZhbGlkLmNvbTCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEA\n" + 173 "q6MyQwzCr2nJ41l0frmHL0qULSyW51MhevBC+1W28i0LE/efrmpwV3LdnlQEGFak\n" + 174 "DLDwtnff3iru8dSMcA7KdWVkivsE7ZTP+qFDaWBAy7XXiSsv6yZ2Nh4jJb0YcD28\n" + 175 "45zk2nAl5Az1/PuoTi1vpQxzFZKuBm1HGgz3MEZvBvMCAwEAAaNPME0wCwYDVR0P\n" + 176 "BAQDAgPoMB0GA1UdDgQWBBRRMifrND015Nm8N6gV5X7cg1YjjjAfBgNVHSMEGDAW\n" + 177 "gBRLZkIu409Yo1zmnz7H5Ky8ElbvXjANBgkqhkiG9w0BAQQFAAOBgQBjkUO6Ri/B\n" + 178 "uDC2gDMIyL5+NTe/1dPPQYM4HhCNa/KQYvU5lzCKO9Vpa+i+nyrUNNXUu8Tkyq4Y\n" + 179 "A+aGSm6+FT/i9rFwkYUdorBtD3KfQiwTIWrVERXBkWI5iZNaVZhx0TFy4vUpf65d\n" + 180 "QtwkbHpC66fdKc2EdLXkuY9KkmtZZJJ7YA==\n" + 181 "-----END CERTIFICATE-----"; 182 183 static String targetPrivateKey_C = 184 "MIICdwIBADANBgkqhkiG9w0BAQEFAASCAmEwggJdAgEAAoGBAKujMkMMwq9pyeNZ\n" + 185 "dH65hy9KlC0sludTIXrwQvtVtvItCxP3n65qcFdy3Z5UBBhWpAyw8LZ3394q7vHU\n" + 186 "jHAOynVlZIr7BO2Uz/qhQ2lgQMu114krL+smdjYeIyW9GHA9vOOc5NpwJeQM9fz7\n" + 187 "qE4tb6UMcxWSrgZtRxoM9zBGbwbzAgMBAAECgYASJDK40Y12Wvki1Z6xkkyOnBRj\n" + 188 "XfYpRykfxGtgA2RN3qLwHlk7Zzaul46DIKA6LlYynTUkJDF+Ww1cdDnP0lBlwcmM\n" + 189 "iD0ck3zYyYBLhQHuVbkK3SYE+ANRhM0icvvqANP2at/U4awQcPNEae/KCiecLNu3\n" + 190 "CJGqyhPDdrEAqPuJGQJBAN46pQC6l3yrcSYE2s53jSmsm2HVVOFlFXjU6k/RMTxG\n" + 191 "FfDJtGUAOQ37rPQ06ugr/gjLAmmPp+FXozaBdA32D80CQQDFuGRgv3WYqbglIcRL\n" + 192 "JRs6xlj9w1F97s/aiUenuwhIPNiUoRbV7mnNuZ/sGF0svOVE7SazRjuFX6UqL9Y9\n" + 193 "HzG/AkEA170pCI8cl4w8eUNHRB9trGKEKjMXhwVCFh7lJf2ZBcGodSzr8w2HVhrZ\n" + 194 "Ke7hiemDYffrbJ1oxmv05+o+x3r0lQJBAL6adVm2+FyFMFnLZXmzeb59O4jWY5bt\n" + 195 "Qz6/HG6bpO5OidMuP99YCHMkQQDOs/PO3Y5GuAoW6IY4n/Y9S2B80+0CQBl1/H9/\n" + 196 "0n/vrb6vW6Azds49tuS82RFAnOhtwTyBEajs08WF8rZQ3WD2RHJnH0+jjfL0anIp\n" + 197 "dQBSeNN7s7b6rRk="; 198 199 // This is a certificate for client 200 static String targetCertStr_D= 201 "-----BEGIN CERTIFICATE-----\n" + 202 "MIICVDCCAb2gAwIBAgIBBTANBgkqhkiG9w0BAQQFADA7MQswCQYDVQQGEwJVUzEN\n" + 203 "MAsGA1UEChMESmF2YTEdMBsGA1UECxMUU3VuSlNTRSBUZXN0IFNlcml2Y2UwHhcN\n" + 204 "MTIwNDE3MTIwNjEwWhcNMzIwMTAzMTIwNjEwWjBUMQswCQYDVQQGEwJVUzENMAsG\n" + 205 "A1UEChMESmF2YTEdMBsGA1UECxMUU3VuSlNTRSBUZXN0IFNlcml2Y2UxFzAVBgNV\n" + 206 "BAMTDkludGVyT3AgVGVzdGVyMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDo\n" + 207 "Q/KoAIAC2ljFfW2KwjnxTzi4NQJeUuk2seqKpsAY8x4O5dvixzUl6142zmljapqi\n" + 208 "bJloQVpfB+CEc5/l4h5gzGRVzkuqP1oPzDrpZ5GsvmvuHenV/TzCIgX1cLETzQVt\n" + 209 "6Rk06okoBPnw3hDJEJiEc1Rv7HCE8p/p+SaiHrskwwIDAQABo08wTTALBgNVHQ8E\n" + 210 "BAMCA+gwHQYDVR0OBBYEFPr91O33RIGfFSqza2AwQIgE4QswMB8GA1UdIwQYMBaA\n" + 211 "FEtmQi7jT1ijXOafPsfkrLwSVu9eMA0GCSqGSIb3DQEBBAUAA4GBANIDFYgAhoj3\n" + 212 "B8u1YpqeoEp2Lt9TwrYBshaIrbmBPCwCGio0JIsoov3n8BCSg5F+8MnOtPl+TjeO\n" + 213 "0Ug+7guPdCk/wg8YNxLHgSsQlpcNJDjWiErqmUPVrg5BPPQb65qMund6KTmMN0y6\n" + 214 "4EbSmxRpZO/N0/5oK4umTk0EeXKNekBj\n" + 215 "-----END CERTIFICATE-----"; 216 217 static String targetPrivateKey_D = 218 "MIICdQIBADANBgkqhkiG9w0BAQEFAASCAl8wggJbAgEAAoGBAOhD8qgAgALaWMV9\n" + 219 "bYrCOfFPOLg1Al5S6Tax6oqmwBjzHg7l2+LHNSXrXjbOaWNqmqJsmWhBWl8H4IRz\n" + 220 "n+XiHmDMZFXOS6o/Wg/MOulnkay+a+4d6dX9PMIiBfVwsRPNBW3pGTTqiSgE+fDe\n" + 221 "EMkQmIRzVG/scITyn+n5JqIeuyTDAgMBAAECgYBw37yIKp4LRONJLnhSq6sO+0n8\n" + 222 "Mz6waiiN/Q6XTQwj09pysQAYCGlqwSRrDAqpVsBJWO+Ae+oYLrLMi4hUZnwN75v3\n" + 223 "pe1nXlrD11RmPLXwBxqFxNSvAs2FgLHZEtwHI7Bn8KybT/8bGkQ8csLceInYtMDD\n" + 224 "MuTyy2KRk/pj60zIKQJBAPgebQiAH6viFQ88AwHaNvQhlUfwmSC1i6f8LVoeqaHC\n" + 225 "lnP0LJBwlyDeeEInhHrCR2ibnCB6I/Pig+49XQgabK8CQQDvpJwuGEbsOO+3rkJJ\n" + 226 "OpOw4toG0QJZdRnT6l8I6BlboQRZSfFh+lGGahvFXkxc4KdUpJ7QPtXU7HHk6Huk\n" + 227 "8RYtAkA9CW8VGj+wTuuTVdX/jKjcIa7RhbSFwWNbrcOSWdys+Gt+luCnn6rt4QyA\n" + 228 "aaxDbquWZkFgE+voQR7nap0KM0XtAkAznd0WAJymHM1lXt9gLoHJQ9N6TGKZKiPa\n" + 229 "BU1a+cMcfV4WbVrUo7oTnZ9Fr73681iXXq3mZOJh7lvJ1llreZIxAkBEnbiTgEf4\n" + 230 "tvku68jHcRbRPmdS7CBSWNEBaHLOm4pUSTcxVTKKMHw7vmM5/UYUxJ8QNKCYxn6O\n" + 231 "+vtiBwBawwzN"; 232 233 static String[] serverCerts = {targetCertStr_A, 234 targetCertStr_B, targetCertStr_C}; 235 static String[] serverKeys = {targetPrivateKey_A, 236 targetPrivateKey_B, targetPrivateKey_C}; 237 static String[] clientCerts = {targetCertStr_D}; 238 static String[] clientKeys = {targetPrivateKey_D}; 239 240 static char passphrase[] = "passphrase".toCharArray(); 241 242 /* 243 * Is the server ready to serve? 244 */ 245 volatile static boolean serverReady = false; 246 247 /* 248 * Turn on SSL debugging? 249 */ 250 static boolean debug = false; 251 252 /* 253 * Define the server side of the test. 254 * 255 * If the server prematurely exits, serverReady will be set to true 256 * to avoid infinite hangs. 257 */ 258 void doServerSide() throws Exception { 259 SSLContext context = generateSSLContext(false); 260 SSLServerSocketFactory sslssf = context.getServerSocketFactory(); 261 SSLServerSocket sslServerSocket = 262 (SSLServerSocket)sslssf.createServerSocket(serverPort); 263 serverPort = sslServerSocket.getLocalPort(); 264 265 /* 266 * Signal Client, we're ready for his connect. 267 */ 268 serverReady = true; 269 270 SSLSocket sslSocket = (SSLSocket)sslServerSocket.accept(); 271 try { 272 sslSocket.setSoTimeout(5000); 273 sslSocket.setSoLinger(true, 5); 274 275 InputStream sslIS = sslSocket.getInputStream(); 276 OutputStream sslOS = sslSocket.getOutputStream(); 277 278 sslIS.read(); 279 sslOS.write('A'); 280 sslOS.flush(); 281 282 SSLSession session = sslSocket.getSession(); 283 checkCertificate(session.getLocalCertificates(), 284 clientRequestedHostname); 285 } finally { 286 sslSocket.close(); 287 sslServerSocket.close(); 288 } 289 } 290 291 /* 292 * Define the client side of the test. 293 * 294 * If the server prematurely exits, serverReady will be set to true 295 * to avoid infinite hangs. 296 */ 297 void doClientSide() throws Exception { 298 299 /* 300 * Wait for server to get started. 301 */ 302 while (!serverReady) { 303 Thread.sleep(50); 304 } 305 306 SSLContext context = generateSSLContext(true); 307 SSLSocketFactory sslsf = context.getSocketFactory(); 308 309 SSLSocket sslSocket = 310 (SSLSocket)sslsf.createSocket("localhost", serverPort); 311 312 SNIHostName serverName = new SNIHostName(clientRequestedHostname); 313 List<SNIServerName> serverNames = new ArrayList<>(1); 314 serverNames.add(serverName); 315 SSLParameters params = sslSocket.getSSLParameters(); 316 params.setServerNames(serverNames); 317 sslSocket.setSSLParameters(params); 318 319 try { 320 sslSocket.setSoTimeout(5000); 321 sslSocket.setSoLinger(true, 5); 322 323 InputStream sslIS = sslSocket.getInputStream(); 324 OutputStream sslOS = sslSocket.getOutputStream(); 325 326 sslOS.write('B'); 327 sslOS.flush(); 328 sslIS.read(); 329 330 SSLSession session = sslSocket.getSession(); 331 checkCertificate(session.getPeerCertificates(), 332 clientRequestedHostname); 333 } finally { 334 sslSocket.close(); 335 } 336 } 337 338 private static void checkCertificate(Certificate[] certs, 339 String hostname) throws Exception { 340 if (certs != null && certs.length != 0) { 341 X509Certificate x509Cert = (X509Certificate)certs[0]; 342 343 String subject = x509Cert.getSubjectX500Principal().getName(); 344 345 if (!subject.contains(hostname)) { 346 throw new Exception( 347 "Not the expected certificate: " + subject); 348 } 349 } 350 } 351 352 /* 353 * ============================================================= 354 * The remainder is just support stuff 355 */ 356 private static String tmAlgorithm; // trust manager 357 private static String clientRequestedHostname; // server name indication 358 359 private static void parseArguments(String[] args) { 360 tmAlgorithm = args[0]; 361 clientRequestedHostname = args[1]; 362 } 363 364 private static SSLContext generateSSLContext(boolean isClient) 365 throws Exception { 366 367 // generate certificate from cert string 368 CertificateFactory cf = CertificateFactory.getInstance("X.509"); 369 370 // create a key store 371 KeyStore ks = KeyStore.getInstance("JKS"); 372 ks.load(null, null); 373 374 // import the trused cert 375 ByteArrayInputStream is = 376 new ByteArrayInputStream(trustedCertStr.getBytes()); 377 Certificate trusedCert = cf.generateCertificate(is); 378 is.close(); 379 380 ks.setCertificateEntry("RSA Export Signer", trusedCert); 381 382 String[] certStrs = null; 383 String[] keyStrs = null; 384 if (isClient) { 385 certStrs = clientCerts; 386 keyStrs = clientKeys; 387 } else { 388 certStrs = serverCerts; 389 keyStrs = serverKeys; 390 } 391 392 for (int i = 0; i < certStrs.length; i++) { 393 // generate the private key. 394 String keySpecStr = keyStrs[i]; 395 PKCS8EncodedKeySpec priKeySpec = new PKCS8EncodedKeySpec( 396 Base64.getMimeDecoder().decode(keySpecStr)); 397 KeyFactory kf = KeyFactory.getInstance("RSA"); 398 RSAPrivateKey priKey = 399 (RSAPrivateKey)kf.generatePrivate(priKeySpec); 400 401 // generate certificate chain 402 String keyCertStr = certStrs[i]; 403 is = new ByteArrayInputStream(keyCertStr.getBytes()); 404 Certificate keyCert = cf.generateCertificate(is); 405 is.close(); 406 407 Certificate[] chain = new Certificate[2]; 408 chain[0] = keyCert; 409 chain[1] = trusedCert; 410 411 // import the key entry. 412 ks.setKeyEntry("key-entry-" + i, priKey, passphrase, chain); 413 } 414 415 // create SSL context 416 TrustManagerFactory tmf = TrustManagerFactory.getInstance(tmAlgorithm); 417 tmf.init(ks); 418 419 SSLContext ctx = SSLContext.getInstance("TLSv1.2"); 420 KeyManagerFactory kmf = KeyManagerFactory.getInstance("NewSunX509"); 421 kmf.init(ks, passphrase); 422 423 ctx.init(kmf.getKeyManagers(), tmf.getTrustManagers(), null); 424 ks = null; 425 426 return ctx; 427 } 428 429 // use any free port by default 430 volatile int serverPort = 0; 431 432 volatile Exception serverException = null; 433 volatile Exception clientException = null; 434 435 public static void main(String[] args) throws Exception { 436 // MD5 is used in this test case, don't disable MD5 algorithm. 437 Security.setProperty("jdk.certpath.disabledAlgorithms", 438 "MD2, RSA keySize < 1024"); 439 Security.setProperty("jdk.tls.disabledAlgorithms", 440 "SSLv3, RC4, DH keySize < 768"); 441 442 if (debug) 443 System.setProperty("javax.net.debug", "all"); 444 445 /* 446 * Get the customized arguments. 447 */ 448 parseArguments(args); 449 450 /* 451 * Start the tests. 452 */ 453 new SSLSocketSNISensitive(); 454 } 455 456 Thread clientThread = null; 457 Thread serverThread = null; 458 459 /* 460 * Primary constructor, used to drive remainder of the test. 461 * 462 * Fork off the other side, then do your work. 463 */ 464 SSLSocketSNISensitive() throws Exception { 465 try { 466 if (separateServerThread) { 467 startServer(true); 468 startClient(false); 469 } else { 470 startClient(true); 471 startServer(false); 472 } 473 } catch (Exception e) { 474 // swallow for now. Show later 475 } 476 477 /* 478 * Wait for other side to close down. 479 */ 480 if (separateServerThread) { 481 serverThread.join(); 482 } else { 483 clientThread.join(); 484 } 485 486 /* 487 * When we get here, the test is pretty much over. 488 * Which side threw the error? 489 */ 490 Exception local; 491 Exception remote; 492 String whichRemote; 493 494 if (separateServerThread) { 495 remote = serverException; 496 local = clientException; 497 whichRemote = "server"; 498 } else { 499 remote = clientException; 500 local = serverException; 501 whichRemote = "client"; 502 } 503 504 /* 505 * If both failed, return the curthread's exception, but also 506 * print the remote side Exception 507 */ 508 if ((local != null) && (remote != null)) { 509 System.out.println(whichRemote + " also threw:"); 510 remote.printStackTrace(); 511 System.out.println(); 512 throw local; 513 } 514 515 if (remote != null) { 516 throw remote; 517 } 518 519 if (local != null) { 520 throw local; 521 } 522 } 523 524 void startServer(boolean newThread) throws Exception { 525 if (newThread) { 526 serverThread = new Thread() { 527 public void run() { 528 try { 529 doServerSide(); 530 } catch (Exception e) { 531 /* 532 * Our server thread just died. 533 * 534 * Release the client, if not active already... 535 */ 536 System.err.println("Server died, because of " + e); 537 serverReady = true; 538 serverException = e; 539 } 540 } 541 }; 542 serverThread.start(); 543 } else { 544 try { 545 doServerSide(); 546 } catch (Exception e) { 547 serverException = e; 548 } finally { 549 serverReady = true; 550 } 551 } 552 } 553 554 void startClient(boolean newThread) throws Exception { 555 if (newThread) { 556 clientThread = new Thread() { 557 public void run() { 558 try { 559 doClientSide(); 560 } catch (Exception e) { 561 /* 562 * Our client thread just died. 563 */ 564 System.err.println("Client died, because of " + e); 565 clientException = e; 566 } 567 } 568 }; 569 clientThread.start(); 570 } else { 571 try { 572 doClientSide(); 573 } catch (Exception e) { 574 clientException = e; 575 } 576 } 577 } 578 }