src/java.base/share/classes/com/sun/net/ssl/internal/www/protocol/https/DelegateHttpsURLConnection.java
branchJDK-8200758-branch
changeset 57253 f0e513137db2
parent 57241 e11f3bf34083
parent 54055 289fd6cb7480
child 57254 c1b92a014e89
equal deleted inserted replaced
57241:e11f3bf34083 57253:f0e513137db2
     1 /*
       
     2  * Copyright (c) 2001, 2017, 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 package com.sun.net.ssl.internal.www.protocol.https;
       
    27 
       
    28 import java.net.URL;
       
    29 import java.net.Proxy;
       
    30 import java.io.IOException;
       
    31 import java.util.Collection;
       
    32 import java.util.List;
       
    33 import java.util.Iterator;
       
    34 
       
    35 import java.security.Principal;
       
    36 import java.security.cert.*;
       
    37 
       
    38 import javax.security.auth.x500.X500Principal;
       
    39 
       
    40 import sun.security.util.HostnameChecker;
       
    41 import sun.security.util.DerValue;
       
    42 import sun.security.x509.X500Name;
       
    43 
       
    44 import sun.net.www.protocol.https.AbstractDelegateHttpsURLConnection;
       
    45 
       
    46 /**
       
    47  * This class was introduced to provide an additional level of
       
    48  * abstraction between javax.net.ssl.HttpURLConnection and
       
    49  * com.sun.net.ssl.HttpURLConnection objects. <p>
       
    50  *
       
    51  * javax.net.ssl.HttpURLConnection is used in the new sun.net version
       
    52  * of protocol implementation (this one)
       
    53  * com.sun.net.ssl.HttpURLConnection is used in the com.sun version.
       
    54  *
       
    55  */
       
    56 @Deprecated(since="9")
       
    57 @SuppressWarnings("deprecation") // HttpsURLConnection is deprecated
       
    58 public class DelegateHttpsURLConnection extends AbstractDelegateHttpsURLConnection {
       
    59 
       
    60     // we need a reference to the HttpsURLConnection to get
       
    61     // the properties set there
       
    62     // we also need it to be public so that it can be referenced
       
    63     // from sun.net.www.protocol.http.HttpURLConnection
       
    64     // this is for ResponseCache.put(URI, URLConnection)
       
    65     // second parameter needs to be cast to javax.net.ssl.HttpsURLConnection
       
    66     // instead of AbstractDelegateHttpsURLConnection
       
    67 
       
    68     public com.sun.net.ssl.HttpsURLConnection httpsURLConnection;
       
    69 
       
    70     DelegateHttpsURLConnection(URL url,
       
    71             sun.net.www.protocol.http.Handler handler,
       
    72             com.sun.net.ssl.HttpsURLConnection httpsURLConnection)
       
    73             throws IOException {
       
    74         this(url, null, handler, httpsURLConnection);
       
    75     }
       
    76 
       
    77     DelegateHttpsURLConnection(URL url, Proxy p,
       
    78             sun.net.www.protocol.http.Handler handler,
       
    79             com.sun.net.ssl.HttpsURLConnection httpsURLConnection)
       
    80             throws IOException {
       
    81         super(url, p, handler);
       
    82         this.httpsURLConnection = httpsURLConnection;
       
    83     }
       
    84 
       
    85     protected javax.net.ssl.SSLSocketFactory getSSLSocketFactory() {
       
    86         return httpsURLConnection.getSSLSocketFactory();
       
    87     }
       
    88 
       
    89     protected javax.net.ssl.HostnameVerifier getHostnameVerifier() {
       
    90         // note: getHostnameVerifier() never returns null
       
    91         return new VerifierWrapper(httpsURLConnection.getHostnameVerifier());
       
    92     }
       
    93 
       
    94     /*
       
    95      * Called by layered delegator's finalize() method to handle closing
       
    96      * the underlying object.
       
    97      */
       
    98     protected void dispose() throws Throwable {
       
    99         super.finalize();
       
   100     }
       
   101 }
       
   102 
       
   103 class VerifierWrapper implements javax.net.ssl.HostnameVerifier {
       
   104     @SuppressWarnings("deprecation")
       
   105     private com.sun.net.ssl.HostnameVerifier verifier;
       
   106 
       
   107     @SuppressWarnings("deprecation")
       
   108     VerifierWrapper(com.sun.net.ssl.HostnameVerifier verifier) {
       
   109         this.verifier = verifier;
       
   110     }
       
   111 
       
   112     /*
       
   113      * In com.sun.net.ssl.HostnameVerifier the method is defined
       
   114      * as verify(String urlHostname, String certHostname).
       
   115      * This means we need to extract the hostname from the X.509 certificate
       
   116      * in this wrapper.
       
   117      */
       
   118     public boolean verify(String hostname, javax.net.ssl.SSLSession session) {
       
   119         try {
       
   120             Certificate[] serverChain = session.getPeerCertificates();
       
   121             if ((serverChain == null) || (serverChain.length == 0)) {
       
   122                 return false;
       
   123             }
       
   124             if (serverChain[0] instanceof X509Certificate == false) {
       
   125                 return false;
       
   126             }
       
   127             X509Certificate serverCert = (X509Certificate)serverChain[0];
       
   128             String serverName = getServername(serverCert);
       
   129             if (serverName == null) {
       
   130                 return false;
       
   131             }
       
   132             return verifier.verify(hostname, serverName);
       
   133         } catch (javax.net.ssl.SSLPeerUnverifiedException e) {
       
   134             return false;
       
   135         }
       
   136     }
       
   137 
       
   138     /*
       
   139      * Extract the name of the SSL server from the certificate.
       
   140      *
       
   141      * Note this code is essentially a subset of the hostname extraction
       
   142      * code in HostnameChecker.
       
   143      */
       
   144     private static String getServername(X509Certificate peerCert) {
       
   145         try {
       
   146             // compare to subjectAltNames if dnsName is present
       
   147             Collection<List<?>> subjAltNames = peerCert.getSubjectAlternativeNames();
       
   148             if (subjAltNames != null) {
       
   149                 for (Iterator<List<?>> itr = subjAltNames.iterator(); itr.hasNext(); ) {
       
   150                     List<?> next = itr.next();
       
   151                     if (((Integer)next.get(0)).intValue() == 2) {
       
   152                         // compare dNSName with host in url
       
   153                         String dnsName = ((String)next.get(1));
       
   154                         return dnsName;
       
   155                     }
       
   156                 }
       
   157             }
       
   158 
       
   159             // else check against common name in the subject field
       
   160             X500Name subject = HostnameChecker.getSubjectX500Name(peerCert);
       
   161 
       
   162             DerValue derValue = subject.findMostSpecificAttribute
       
   163                                                 (X500Name.commonName_oid);
       
   164             if (derValue != null) {
       
   165                 try {
       
   166                     String name = derValue.getAsString();
       
   167                     return name;
       
   168                 } catch (IOException e) {
       
   169                     // ignore
       
   170                 }
       
   171             }
       
   172         } catch (java.security.cert.CertificateException e) {
       
   173             // ignore
       
   174         }
       
   175         return null;
       
   176     }
       
   177 
       
   178 }