1 /*
   2  * Copyright (c) 2018, 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 import javax.net.ssl.KeyManagerFactory;
  25 import javax.net.ssl.SSLContext;
  26 import javax.net.ssl.SSLEngine;
  27 import javax.net.ssl.SSLEngineResult;
  28 import javax.net.ssl.SSLException;
  29 import javax.net.ssl.SSLHandshakeException;
  30 import javax.net.ssl.SSLParameters;
  31 import javax.net.ssl.TrustManager;
  32 import javax.net.ssl.X509TrustManager;
  33 import java.io.ByteArrayInputStream;
  34 import java.nio.ByteBuffer;
  35 import java.security.KeyStore;
  36 import java.security.cert.CertificateException;
  37 import java.security.cert.X509Certificate;
  38 import java.util.Base64;
  39 
  40 /*
  41  * @test
  42  * @bug 8211339 8234728
  43  * @summary Verify hostname returns an exception instead of null pointer when
  44  * creating a new engine
  45  * @run main NullHostnameCheck TLSv1
  46  * @run main NullHostnameCheck TLSv1.1
  47  * @run main NullHostnameCheck TLSv1.2
  48  * @run main NullHostnameCheck TLSv1.3
  49  */
  50 
  51 
  52 public final class NullHostnameCheck {
  53 
  54     public static void main(String[] args) throws Exception {
  55         String protocol = args[0];
  56         KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType());
  57         keyStore.load(
  58                 new ByteArrayInputStream(Base64.getDecoder().
  59                         decode(keystoreB64)),
  60                 "123456".toCharArray());
  61         KeyManagerFactory kmf = KeyManagerFactory.getInstance(
  62                 KeyManagerFactory.getDefaultAlgorithm());
  63         kmf.init(keyStore, "123456".toCharArray());
  64         SSLContext serverCtx = SSLContext.getInstance(protocol);
  65         serverCtx.init(kmf.getKeyManagers(), null, null);
  66         SSLEngine serverEngine = serverCtx.createSSLEngine("localhost", -1);
  67         serverEngine.setUseClientMode(false);
  68 
  69         SSLContext clientCtx = SSLContext.getInstance(protocol);
  70         clientCtx.init(null, new TrustManager[] {
  71                 new X509TrustManager() {
  72                     @Override
  73                     public void checkClientTrusted(
  74                             X509Certificate[] x509Certificates, String s) {
  75                     }
  76 
  77                     @Override
  78                     public void checkServerTrusted(
  79                             X509Certificate[] x509Certificates, String s) {
  80                     }
  81 
  82                     @Override
  83                     public X509Certificate[] getAcceptedIssuers() {
  84                         return new X509Certificate[0];
  85                     }
  86                 }
  87         }, null);
  88 
  89         SSLEngine clientEngine = clientCtx.createSSLEngine();
  90         clientEngine.setUseClientMode(true);
  91 
  92         SSLParameters sslParameters = clientEngine.getSSLParameters();
  93         sslParameters.setEndpointIdentificationAlgorithm("HTTPS");
  94         clientEngine.setSSLParameters(sslParameters);
  95         try {
  96             handshake(clientEngine, serverEngine);
  97             throw new Exception("Value was not null.  Unexpected.");
  98         } catch (SSLHandshakeException e) {
  99             if (e.getCause() instanceof CertificateException) {
 100                 System.out.println("Correct Exception class thrown:\n\t" +
 101                         e.getMessage());
 102                 return;
 103             }
 104             throw e;
 105         }
 106     }
 107 
 108     private static void handshake(SSLEngine clientEngine,
 109             SSLEngine serverEngine) throws SSLException{
 110         ByteBuffer cTOs = ByteBuffer.allocate(
 111                 clientEngine.getSession().getPacketBufferSize());
 112         ByteBuffer sTOc = ByteBuffer.allocate(
 113                 serverEngine.getSession().getPacketBufferSize());
 114 
 115         ByteBuffer serverAppReadBuffer = ByteBuffer.allocate(
 116                 serverEngine.getSession().getApplicationBufferSize());
 117         ByteBuffer clientAppReadBuffer = ByteBuffer.allocate(
 118                 clientEngine.getSession().getApplicationBufferSize());
 119 
 120         clientEngine.beginHandshake();
 121         serverEngine.beginHandshake();
 122 
 123         ByteBuffer empty = ByteBuffer.allocate(0);
 124 
 125         SSLEngineResult clientResult;
 126         SSLEngineResult serverResult;
 127 
 128         boolean clientHandshakeFinished = false;
 129         boolean serverHandshakeFinished = false;
 130 
 131         do {
 132             if (!clientHandshakeFinished) {
 133                 clientResult = clientEngine.wrap(empty, cTOs);
 134                 runDelegatedTasks(clientResult, clientEngine);
 135 
 136                 if (isHandshakeFinished(clientResult)) {
 137                     clientHandshakeFinished = true;
 138                 }
 139             }
 140 
 141             if (!serverHandshakeFinished) {
 142                 serverResult = serverEngine.wrap(empty, sTOc);
 143                 runDelegatedTasks(serverResult, serverEngine);
 144 
 145                 if (isHandshakeFinished(serverResult)) {
 146                     serverHandshakeFinished = true;
 147                 }
 148             }
 149 
 150             cTOs.flip();
 151             sTOc.flip();
 152 
 153             if (!clientHandshakeFinished) {
 154                 clientResult = clientEngine.unwrap(sTOc, clientAppReadBuffer);
 155 
 156                 runDelegatedTasks(clientResult, clientEngine);
 157 
 158                 if (isHandshakeFinished(clientResult)) {
 159                     clientHandshakeFinished = true;
 160                 }
 161             }
 162 
 163             if (!serverHandshakeFinished) {
 164                 serverResult = serverEngine.unwrap(cTOs, serverAppReadBuffer);
 165                 runDelegatedTasks(serverResult, serverEngine);
 166 
 167                 if (isHandshakeFinished(serverResult)) {
 168                     serverHandshakeFinished = true;
 169                 }
 170             }
 171 
 172             sTOc.compact();
 173             cTOs.compact();
 174         } while (!clientHandshakeFinished || !serverHandshakeFinished);
 175     }
 176 
 177     private static boolean isHandshakeFinished(SSLEngineResult result) {
 178         return result.getHandshakeStatus() ==
 179                 SSLEngineResult.HandshakeStatus.FINISHED;
 180     }
 181 
 182     private static void runDelegatedTasks(SSLEngineResult result,
 183             SSLEngine engine) {
 184         if (result.getHandshakeStatus() ==
 185                 SSLEngineResult.HandshakeStatus.NEED_TASK) {
 186             for (;;) {
 187                 Runnable task = engine.getDelegatedTask();
 188                 if (task == null) {
 189                     break;
 190                 }
 191                 task.run();
 192             }
 193         }
 194     }
 195 
 196     // Base64 of PKCS12 Keystore
 197     /*
 198      * Certificate
 199      * "signature algorithm": "SHA384withRSA",
 200      * "issuer"             : "CN=test, OU=test, O=test, L=test, ST=test, C=test",
 201      * "not before"         : "2019-12-05 12:43:23.000 IST",
 202      * "not  after"         : "2049-11-27 12:43:23.000 IST",
 203      * "subject"            : "CN=test, OU=test, O=test, L=test, ST=test, C=test",
 204      * "subject public key" : "RSA",
 205      */
 206     static final String keystoreB64 =
 207         "MIIQZwIBAzCCECAGCSqGSIb3DQEHAaCCEBEEghANMIIQCTCCCeUGCSqGSIb3DQEHA"
 208         + "aCCCdYEggnSMIIJzjCCCcoGCyqGSIb3DQEMCgECoIIJezCCCXcwKQYKKoZIhvcNAQ"
 209         + "wBAzAbBBSaZBiYmowTxFT4KJxZhMHTVOC9OQIDAMNQBIIJSBnoVGtJKPsoiSU095y"
 210         + "50x27NJQd727oJwMXqA8kdxCcE1tBowtO8P44ctSEvwJQlB7dR9PxHB6LcfCdMfpa"
 211         + "GObVCH1/6jHzhRolI9JMAfXlvliAHKZSjuQd2USw1Y65/+0VYvKslXGU4hWhGQWh2"
 212         + "ksUCBIIcC2A3sA3afF/JPrlfLCEbzYpcfAsv+Z7wEEr6YD11HIHfbOgu2/HU6phL2"
 213         + "RMJDK9iLgP9mu6FzRFk+93BSguWXfbeJyPlzA8dcTzkXDyfVDx4Wd+UExWq0fx179"
 214         + "b74MWkwEk76TowEkcGkrnugwOKnqBmyvmBkbl1827+ChZprZ3zGw69IkuRsdDSYGb"
 215         + "IWVAB/psB0zX3TvsKHcraZm34oNJdSNpYrS0OWA8lSm5NdcfTzi6WLxWwxz55PvZg"
 216         + "OP3pVyXmtAalyBujs6AOsLkJIMLGvWAYeD+72ook8fqpW7s5e/HA7MshXrlMMflpD"
 217         + "m708kK5VnfdgzQsAGr6YfOYOKnyhoqskmzDYccuSz59owKiuGMgHpum0zVE8yyVwb"
 218         + "esXfP3v7eiPuGvsxzq5DE6jaY4F+GoxdLbL4jDWocnWiZewnuYxQwd1vKIKTww/TG"
 219         + "8RObPUEB38+/LNpgb7+5Oap45rujygiPFWD9+mTzKkLGkM6ItRo4qOwtKAqbjPIVk"
 220         + "MDCovcr2TCrZfE8ZbQnU/q2LR5eC6ZpOMFNRZggm92n0+FmDuEKjR7lu2mQF4IDan"
 221         + "SiYgS1+nBhfG9pcNP3yCpwoBHIImtZX5GObKqgvMqQ746KXhv40xwnNqXGypBNKYN"
 222         + "jRJQmG2/m++2A6DUo+xCTNbD7g0pQbNOjKsGVMXUBTyDiyGqSUHH2EDxe37wcPVih"
 223         + "ezcv5L1X48y3tSVD9czhjCDJ54sd0B3+LoEXs5/0xYmMvQ74zUx6iwE87FZ/duMbs"
 224         + "N3dDWvIgqgjaoGnfRLy4lRRxYhn2/r1lesQtzNlZ3YkHZKmpgQkLm+yChFqxi7qm+"
 225         + "ec/y+GSTm+ascK1ju1NG3f/SUdl7KqZ/J7DnDfQwyg7jiY+QOcr7UNRSeddQozxu7"
 226         + "j07y/wiGX4z3+JSGBlnlWtOyLo5YERbheVHh1LfCSM4KQDcjxUnIlmsCqILwDYbVm"
 227         + "aNJ3crkU22I5IVFcoF30v7gvMj4VFXcBYPCSJrkqNIIgZs6YPYwht3akquIz2ovXV"
 228         + "CqD3TH527dBRAgpeZNs3/L8xCaYiHNUKXv9CRaHVQMTKk9zi3CTJoKo5TCsWR8l9h"
 229         + "cJpcQnmNs5Jv9Jnq/zoet230r3iHkiGNAoXTlekqSER7vBVLHwPY7rogXP6WyAi67"
 230         + "AYK/B5iVQcplEHs3n+MeZJgj9C7S0Zslxmym0mWw7l+4YjvyX+RGJVUvk+3TkWO8E"
 231         + "WHKOX1+hQH9RBbcNqH4FeRZrh3P8wZQDMFfcr3vD0tLAnuqdMy+qAPA+kKWpu5K0D"
 232         + "0W/ifEizq4Zf8VyzYU6UZaAQbloJadSkruXIwvUpHBZ+M8MHQ2AmRNd0vwyTBlhOI"
 233         + "CzWU5E5OXtW/f5jA/ugl7PSqjwe5IYTsZaYstKqqZJMIPTzB/IxPtzVyoN15fG9GR"
 234         + "kk43U6HPS9SdeVTGVmNLn6SM8keLo1yUh5BZ0J0b+K/7C1GfJeNxcv0lGpkrh5wWc"
 235         + "ABzJ86+3daky6+aR6ldY2CF7mr/dcc3MnjgDNnx86wYIysC3HOkhgyIXD28+O1aTY"
 236         + "oAvlmidNC9wb2/JJk7cHQatL02LG4/ql5GQ+dS1wOU7S1MVVGYDlZ7uiFmKPqC1Tv"
 237         + "qVxQnBqPnggKSLWucVKFcjsvXKasMvRl99f4Y7qRAjgM6EHa7rNyWIflRe6ZLNBlj"
 238         + "16mW293a4FL1jTosNlZoCN8xb1zDdb/NCISqkX6/sq7wDOn4t+m+78ckof4GNmTOM"
 239         + "WSaRDJIuLM9c1stLHpcyif37oZum86FnB9Zw9qlQGdgLYnRPeZXV1rZuC1L9fugCN"
 240         + "M4WcUQ20fmPOgyO4RGLsxCbZZJBJj0y7CAMthepMnzaEO9Z2O9BFaM4zpL2ng7GvO"
 241         + "a26DQiHO5RFVjUpslUdmPuX7U5xkRfjJ025pqTvHVLfzWmsU53ZbkgiJ/0xxa1Emd"
 242         + "5y0X2keTVfm7q5duNVVN1A6r50++RANI7NJaSLFTMm8Y5P79g4o7UmtCLSesUdTsF"
 243         + "8swVR5slE3O7ErNr3drLfYVEF9FaB7vcuMDqxCNuahX8TCMJg0vqpO8+EXRNkieb9"
 244         + "KSgcLD5WRjzGm7e/B5uACxWc50iY6lYvIVW5Itot95OHWZ5xdq3a3fIIb4MDQ2/nx"
 245         + "lozhRHaHTBI9GAwy1/XcDJWMr+tI9rLGCB7hX8dVqNtYO93/oF3gvBiiNSw5qmUQ2"
 246         + "qxepZEih5KfhHAVq44RbQMiBA5E2bVBisuNTPUAaA/Fzzsvky8vBq/M5usy8+RXj6"
 247         + "m+mSZCUPpSTTunIUnu0bRLb2inccthEielCThk1FLKQCLSpsAo1h7kzuNJIeeJSCM"
 248         + "cWXpZEURziXwE5KCl3jcY+dOLLMEI05F/UyRwZ/k1a2qW78Bc3DivIh2w/4ZBAS9q"
 249         + "hERIY52y8VcnJ/+/7u45bnpIjkJShZTM1qmzgDCHQa/G5OpnqtI2nDPSNzOpTWA47"
 250         + "6+AH0ZQoUKxHt6MJP3QLpnrw6xPSE2gR19KRvFZr0NtGJ+SPy418eFYMtJgPvOyI4"
 251         + "XwYYCLrmMCkSGrqfbhwKK6rgYMVDg0fsBT1OAZGKD8QM51hXFt8p0HQS0UuddwCTA"
 252         + "/KwyIt6Iw7Leb70yoTEJz3CVU4X4faohXV48gNtZhquawRDvqyBSFS5F8M4s/pJZK"
 253         + "C5UY3MXifF1+LhSXjdQK7RwNs9XcCbIy+6Fi2wAKDX9MasXnzfzFVuQq1XtMoPVVS"
 254         + "9gSqWXGbYuadDIto3gGIKUt3BT9nj/B0J/ENqlSsGsT0+fiya+p5thXOkI8r7X82P"
 255         + "SxV0048QnP7cbuDG97AjOOAcEMsBdCrF3jWGYNd1nK7eKQ8DCrXEKoQhY0IY2sHpU"
 256         + "5Cu24KW9M1RwIb/XtOEBun89edaKhfk1uDLlvgQ4huYDmfcu4Ebh6DRbHzwSNMK17"
 257         + "qDgp8/mbAui0ATZBW7bTQNw3WMS0ltbdCj0ki28Udg1udYY6r6wwWkXE/mccgbXz0"
 258         + "L3g72JfEIO/A56+rFubofZCHuf5AVkDE8MBcGCSqGSIb3DQEJFDEKHggAdABlAHMA"
 259         + "dDAhBgkqhkiG9w0BCRUxFAQSVGltZSAxNTc1NTMwMDAzMjk3MIIGHAYJKoZIhvcNA"
 260         + "QcGoIIGDTCCBgkCAQAwggYCBgkqhkiG9w0BBwEwKQYKKoZIhvcNAQwBBjAbBBRZLo"
 261         + "kYmrJuiANzYxRFL9HmSVKYhQIDAMNQgIIFyPEfYqIJqAd13B5D4EFLs7VrUNaWoeO"
 262         + "XNRVl5da6N7gMlG5gVpPRjRUCHyaBB066ZdGEquwkidgCdIAfIolcnyGv7a7PZvZM"
 263         + "bJ8AUXjkf9q7zp0Uwc0k4zQ3Nmev5QxSx+f33J+AOQT4T1CRMxwpNOwrtzRoNVZFD"
 264         + "oTCnxHBdTvmbCcuMsHYZQk+vLQpud4dI1AKccExjOc86ZAne2Df37LHB/2gxElSOn"
 265         + "G9VkdIlKHLPbrk4JNcNSZs3VOOi3tEwAlBx9Xllg95aH3ziBPYKgk/u6M567tEnoH"
 266         + "PDiss9+WeNJP9Tgsc6WPu33GTNxtxSLx4mffR3x0upSbFvhIP4t07aCtOZVwD/Hdw"
 267         + "VmptatFvVSMiQSM1vf89zjAvdK3UFXTr/jDze4tF35y/UTlor8sbINQy3dZCEpCim"
 268         + "G1MfDdSG+K5BZoHTny5bG2YM8a9EHtmZfq4i3GJE85M652UVlVDgDnk+PhgyIFWuJ"
 269         + "6KFgWjUWio6RRhRvcTCJbk5soV+IFa4BppNMako9W8B2UvqIIV2XrxvFEh4QFkpsW"
 270         + "13qEUGp33qUkAPhuz/NJ4InVh29CGSBnoWprIL/dKwdbTGudlrjnMs6pwURmlWVcJ"
 271         + "FuPJFsBpyCQEeAtKS7TXaVJOTkfHdX4tYgN5SxEA0EGoddrKgWu48Dj1u2oC7ruZ9"
 272         + "6J0zznFIr4FzBobv/woWx66EnCWyQLqjSCxipYeer+7ARDmHwgyj+CvgMsfkLa1VL"
 273         + "LhFDDj0Efdt9IdKj4Nnhh+r9WkNsr+HGiwSgCDn/Hk1AWSvlxxsqFrUBCi6NMSG2l"
 274         + "sM4MzCTrT47dJDPS0go0jIS5E4o3Hc/GMUlhaQaQX8iYaZQk4k1/OsRDoui+FuViU"
 275         + "wIVuAne6AQhgy+9KMzmcgByFxAAoo5b0fDy/PgSG+C3wSs6brFmJIOw1exUIf2E/m"
 276         + "9ATce4vT3CYKLvhk6dmHDK5jSvTrBU4njGVEW8DlW+GSf8jqABDW/PcAf0Y6T0hqv"
 277         + "zTuWlpxv2O3QLeVbDTrIEe1bgRz8HaaiHznXe8oUbCC1xw5FaSAjXJLX0mlKtQ48z"
 278         + "xdimSM7B4Pa6iz2q0m8PRzPaad+VyqD3xp53FaR3K9vNT0PXQwJIDZzxl3gYFisbN"
 279         + "1KxUDtppnkrBwQx9iPH7zQvbNTQiyoUYnF4sAkECIduh/K+ZIAM8zGJH7NTNIrkK/"
 280         + "piehq5/fVAXCr/tdSWeg88gsn0HjNRChuqYz1yFBaQvgMLQ7h/C7k0GP/l2pcUxr8"
 281         + "/zDkFr1FFiUN9e2E0nlCO/FUxFZ3PO25D0ZrjAN7h4WLCybClC+Fdy+RhLAtK7Vuz"
 282         + "zHwBMPNMMvlreXrSv/EE/37oN5OqA8YrDlPpiDuETS6xPkwkJti/ifrwzvakhBUbB"
 283         + "dVd0De2QNctDQBnCFVb1lybbUtSF1Ol5Klcjt7UhFyq0ZkoVXhP2YqEJ7yLOaIKCk"
 284         + "AdjOwCtb01L83/LhounfQLxIG8S2SQwMyxYua6k9BpQLJA36y2uu4+3OZIO4JRura"
 285         + "drfjN6hGkGam8EvxM8UwrC//TDOHJUEy3IgNV4B4EJWs9lFTL9PO+kBlRFSeL5Son"
 286         + "jLB/qZC+i8ssJ8oFkIrl+X7rRcooosbVaNvFIR2FpGCdx8bGoFV6pkfwpJ0hO4dOP"
 287         + "nzFm24vBa6UrftojK/z234/h3W0yZScR5CvoSoU+tn1+3G3Q6a4+hdMwF6WjyO3Ne"
 288         + "xfMRSvMkAqOqHiptdnz7QDQ7LgGIF6igtGEIpKo4urPAg+RnwqKG6NIYOA32QmU35"
 289         + "B4+EJhhYZNINZm0NR5ZM0t9BpUiv6DGl8yZiRX1x4Nu35CLlAT8hWSqgMpb8mw5SQ"
 290         + "rQ4dNggVaJ9lO1j1G4hV6umuyX6L1wtOyeQ9aNg3hIZGLPe4pkzahqI2KKlPWpksm"
 291         + "MJVIi5WmlvEmFC/UkkUUICjo3KzKPHq7bYmdmDDNLwf9jOeAfq/UNxu4nO8wPjAhM"
 292         + "AkGBSsOAwIaBQAEFJrJtKCo0WZ7ewFOiudk30HHA6e0BBRXe6IQoFcDFIzKAyXokh"
 293         + "y3daZV4AIDAYag";
 294 }