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 }