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