Path: blob/master/test/jdk/javax/net/ssl/ServerName/SSLSocketSNISensitive.java
41152 views
/*1* Copyright (c) 2012, 2015, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation. Oracle designates this7* particular file as subject to the "Classpath" exception as provided8* by Oracle in the LICENSE file that accompanied this code.9*10* This code is distributed in the hope that it will be useful, but WITHOUT11* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or12* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License13* version 2 for more details (a copy is included in the LICENSE file that14* accompanied this code).15*16* You should have received a copy of the GNU General Public License version17* 2 along with this work; if not, write to the Free Software Foundation,18* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.19*20* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA21* or visit www.oracle.com if you need additional information or have any22* questions.23*/2425//26// SunJSSE does not support dynamic system properties, no way to re-use27// system properties in samevm/agentvm mode.28//2930/*31* @test32* @bug 706832133* @summary Support TLS Server Name Indication (SNI) Extension in JSSE Server34* @run main/othervm SSLSocketSNISensitive PKIX www.example.com35* @run main/othervm SSLSocketSNISensitive SunX509 www.example.com36* @run main/othervm SSLSocketSNISensitive PKIX www.example.net37* @run main/othervm SSLSocketSNISensitive SunX509 www.example.net38* @run main/othervm SSLSocketSNISensitive PKIX www.invalid.com39* @run main/othervm SSLSocketSNISensitive SunX509 www.invalid.com40*/4142import java.net.*;43import java.util.*;44import java.io.*;45import javax.net.ssl.*;46import java.security.Security;47import java.security.KeyStore;48import java.security.KeyFactory;49import java.security.cert.Certificate;50import java.security.cert.X509Certificate;51import java.security.cert.CertificateFactory;52import java.security.spec.*;53import java.security.interfaces.*;54import java.util.Base64;5556// Note: this test case works only on TLS 1.2 and prior versions because of57// the use of MD5withRSA signed certificate.58public class SSLSocketSNISensitive {5960/*61* =============================================================62* Set the various variables needed for the tests, then63* specify what tests to run on each side.64*/6566/*67* Should we run the client or server in a separate thread?68* Both sides can throw exceptions, but do you have a preference69* as to which side should be the main thread.70*/71static boolean separateServerThread = false;7273/*74* Where do we find the keystores?75*/76// Certificates and key used in the test.77static 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-----";9495// web server certificate, www.example.com96static 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-----";112113// Private key in the format of PKCS#8114static 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==";129130// web server certificate, www.example.net131static 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-----";147148static 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==";163164// web server certificate, www.invalid.com165static 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-----";181182static 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=";197198// This is a certificate for client199static 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-----";215216static 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";231232static String[] serverCerts = {targetCertStr_A,233targetCertStr_B, targetCertStr_C};234static String[] serverKeys = {targetPrivateKey_A,235targetPrivateKey_B, targetPrivateKey_C};236static String[] clientCerts = {targetCertStr_D};237static String[] clientKeys = {targetPrivateKey_D};238239static char passphrase[] = "passphrase".toCharArray();240241/*242* Is the server ready to serve?243*/244volatile static boolean serverReady = false;245246/*247* Turn on SSL debugging?248*/249static boolean debug = false;250251/*252* Define the server side of the test.253*254* If the server prematurely exits, serverReady will be set to true255* to avoid infinite hangs.256*/257void doServerSide() throws Exception {258SSLContext context = generateSSLContext(false);259SSLServerSocketFactory sslssf = context.getServerSocketFactory();260SSLServerSocket sslServerSocket =261(SSLServerSocket)sslssf.createServerSocket(serverPort);262serverPort = sslServerSocket.getLocalPort();263264/*265* Signal Client, we're ready for his connect.266*/267serverReady = true;268269SSLSocket sslSocket = (SSLSocket)sslServerSocket.accept();270try {271sslSocket.setSoTimeout(5000);272sslSocket.setSoLinger(true, 5);273274InputStream sslIS = sslSocket.getInputStream();275OutputStream sslOS = sslSocket.getOutputStream();276277sslIS.read();278sslOS.write('A');279sslOS.flush();280281SSLSession session = sslSocket.getSession();282checkCertificate(session.getLocalCertificates(),283clientRequestedHostname);284} finally {285sslSocket.close();286sslServerSocket.close();287}288}289290/*291* Define the client side of the test.292*293* If the server prematurely exits, serverReady will be set to true294* to avoid infinite hangs.295*/296void doClientSide() throws Exception {297298/*299* Wait for server to get started.300*/301while (!serverReady) {302Thread.sleep(50);303}304305SSLContext context = generateSSLContext(true);306SSLSocketFactory sslsf = context.getSocketFactory();307308SSLSocket sslSocket =309(SSLSocket)sslsf.createSocket("localhost", serverPort);310311SNIHostName serverName = new SNIHostName(clientRequestedHostname);312List<SNIServerName> serverNames = new ArrayList<>(1);313serverNames.add(serverName);314SSLParameters params = sslSocket.getSSLParameters();315params.setServerNames(serverNames);316sslSocket.setSSLParameters(params);317318try {319sslSocket.setSoTimeout(5000);320sslSocket.setSoLinger(true, 5);321322InputStream sslIS = sslSocket.getInputStream();323OutputStream sslOS = sslSocket.getOutputStream();324325sslOS.write('B');326sslOS.flush();327sslIS.read();328329SSLSession session = sslSocket.getSession();330checkCertificate(session.getPeerCertificates(),331clientRequestedHostname);332} finally {333sslSocket.close();334}335}336337private static void checkCertificate(Certificate[] certs,338String hostname) throws Exception {339if (certs != null && certs.length != 0) {340X509Certificate x509Cert = (X509Certificate)certs[0];341342String subject = x509Cert.getSubjectX500Principal().getName();343344if (!subject.contains(hostname)) {345throw new Exception(346"Not the expected certificate: " + subject);347}348}349}350351/*352* =============================================================353* The remainder is just support stuff354*/355private static String tmAlgorithm; // trust manager356private static String clientRequestedHostname; // server name indication357358private static void parseArguments(String[] args) {359tmAlgorithm = args[0];360clientRequestedHostname = args[1];361}362363private static SSLContext generateSSLContext(boolean isClient)364throws Exception {365366// generate certificate from cert string367CertificateFactory cf = CertificateFactory.getInstance("X.509");368369// create a key store370KeyStore ks = KeyStore.getInstance("JKS");371ks.load(null, null);372373// import the trused cert374ByteArrayInputStream is =375new ByteArrayInputStream(trustedCertStr.getBytes());376Certificate trusedCert = cf.generateCertificate(is);377is.close();378379ks.setCertificateEntry("RSA Export Signer", trusedCert);380381String[] certStrs = null;382String[] keyStrs = null;383if (isClient) {384certStrs = clientCerts;385keyStrs = clientKeys;386} else {387certStrs = serverCerts;388keyStrs = serverKeys;389}390391for (int i = 0; i < certStrs.length; i++) {392// generate the private key.393String keySpecStr = keyStrs[i];394PKCS8EncodedKeySpec priKeySpec = new PKCS8EncodedKeySpec(395Base64.getMimeDecoder().decode(keySpecStr));396KeyFactory kf = KeyFactory.getInstance("RSA");397RSAPrivateKey priKey =398(RSAPrivateKey)kf.generatePrivate(priKeySpec);399400// generate certificate chain401String keyCertStr = certStrs[i];402is = new ByteArrayInputStream(keyCertStr.getBytes());403Certificate keyCert = cf.generateCertificate(is);404is.close();405406Certificate[] chain = new Certificate[2];407chain[0] = keyCert;408chain[1] = trusedCert;409410// import the key entry.411ks.setKeyEntry("key-entry-" + i, priKey, passphrase, chain);412}413414// create SSL context415TrustManagerFactory tmf = TrustManagerFactory.getInstance(tmAlgorithm);416tmf.init(ks);417418SSLContext ctx = SSLContext.getInstance("TLSv1.2");419KeyManagerFactory kmf = KeyManagerFactory.getInstance("NewSunX509");420kmf.init(ks, passphrase);421422ctx.init(kmf.getKeyManagers(), tmf.getTrustManagers(), null);423ks = null;424425return ctx;426}427428// use any free port by default429volatile int serverPort = 0;430431volatile Exception serverException = null;432volatile Exception clientException = null;433434public static void main(String[] args) throws Exception {435// MD5 is used in this test case, don't disable MD5 algorithm.436Security.setProperty("jdk.certpath.disabledAlgorithms",437"MD2, RSA keySize < 1024");438Security.setProperty("jdk.tls.disabledAlgorithms",439"SSLv3, RC4, DH keySize < 768");440441if (debug)442System.setProperty("javax.net.debug", "all");443444/*445* Get the customized arguments.446*/447parseArguments(args);448449/*450* Start the tests.451*/452new SSLSocketSNISensitive();453}454455Thread clientThread = null;456Thread serverThread = null;457458/*459* Primary constructor, used to drive remainder of the test.460*461* Fork off the other side, then do your work.462*/463SSLSocketSNISensitive() throws Exception {464try {465if (separateServerThread) {466startServer(true);467startClient(false);468} else {469startClient(true);470startServer(false);471}472} catch (Exception e) {473// swallow for now. Show later474}475476/*477* Wait for other side to close down.478*/479if (separateServerThread) {480serverThread.join();481} else {482clientThread.join();483}484485/*486* When we get here, the test is pretty much over.487* Which side threw the error?488*/489Exception local;490Exception remote;491String whichRemote;492493if (separateServerThread) {494remote = serverException;495local = clientException;496whichRemote = "server";497} else {498remote = clientException;499local = serverException;500whichRemote = "client";501}502503/*504* If both failed, return the curthread's exception, but also505* print the remote side Exception506*/507if ((local != null) && (remote != null)) {508System.out.println(whichRemote + " also threw:");509remote.printStackTrace();510System.out.println();511throw local;512}513514if (remote != null) {515throw remote;516}517518if (local != null) {519throw local;520}521}522523void startServer(boolean newThread) throws Exception {524if (newThread) {525serverThread = new Thread() {526public void run() {527try {528doServerSide();529} catch (Exception e) {530/*531* Our server thread just died.532*533* Release the client, if not active already...534*/535System.err.println("Server died, because of " + e);536serverReady = true;537serverException = e;538}539}540};541serverThread.start();542} else {543try {544doServerSide();545} catch (Exception e) {546serverException = e;547} finally {548serverReady = true;549}550}551}552553void startClient(boolean newThread) throws Exception {554if (newThread) {555clientThread = new Thread() {556public void run() {557try {558doClientSide();559} catch (Exception e) {560/*561* Our client thread just died.562*/563System.err.println("Client died, because of " + e);564clientException = e;565}566}567};568clientThread.start();569} else {570try {571doClientSide();572} catch (Exception e) {573clientException = e;574}575}576}577}578579580