1 /*
   2  * Copyright (c) 1996, 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.  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 sun.security.ssl;
  27 
  28 import java.io.IOException;
  29 import java.net.InetAddress;
  30 import java.net.Socket;
  31 import javax.net.ssl.SSLParameters;
  32 import javax.net.ssl.SSLServerSocket;
  33 
  34 /**
  35  * This class provides a simple way for servers to support conventional
  36  * use of the Secure Sockets Layer (SSL).  Application code uses an
  37  * SSLServerSocketImpl exactly like it uses a regular TCP ServerSocket; the
  38  * difference is that the connections established are secured using SSL.
  39  *
  40  * <P> Also, the constructors take an explicit authentication context
  41  * parameter, giving flexibility with respect to how the server socket
  42  * authenticates itself.  That policy flexibility is not exposed through
  43  * the standard SSLServerSocketFactory API.
  44  *
  45  * <P> System security defaults prevent server sockets from accepting
  46  * connections if they the authentication context has not been given
  47  * a certificate chain and its matching private key.  If the clients
  48  * of your application support "anonymous" cipher suites, you may be
  49  * able to configure a server socket to accept those suites.
  50  *
  51  * @see SSLSocketImpl
  52  * @see SSLServerSocketFactoryImpl
  53  *
  54  * @author David Brownell
  55  */
  56 final class SSLServerSocketImpl extends SSLServerSocket {
  57     private final SSLContextImpl        sslContext;
  58     private final SSLConfiguration      sslConfig;
  59 
  60     SSLServerSocketImpl(SSLContextImpl sslContext) throws IOException {
  61 
  62         super();
  63         this.sslContext = sslContext;
  64         this.sslConfig = new SSLConfiguration(sslContext, false);
  65         this.sslConfig.isClientMode = false;
  66     }
  67 
  68     SSLServerSocketImpl(SSLContextImpl sslContext,
  69             int port, int backlog) throws IOException {
  70 
  71         super(port, backlog);
  72         this.sslContext = sslContext;
  73         this.sslConfig = new SSLConfiguration(sslContext, false);
  74         this.sslConfig.isClientMode = false;
  75     }
  76 
  77     SSLServerSocketImpl(SSLContextImpl sslContext,
  78             int port, int backlog, InetAddress address) throws IOException {
  79 
  80         super(port, backlog, address);
  81         this.sslContext = sslContext;
  82         this.sslConfig = new SSLConfiguration(sslContext, false);
  83         this.sslConfig.isClientMode = false;
  84     }
  85 
  86     @Override
  87     public synchronized String[] getEnabledCipherSuites() {
  88         return CipherSuite.namesOf(sslConfig.enabledCipherSuites);
  89     }
  90 
  91     @Override
  92     public synchronized void setEnabledCipherSuites(String[] suites) {
  93         sslConfig.enabledCipherSuites =
  94                 CipherSuite.validValuesOf(suites);
  95     }
  96 
  97     @Override
  98     public String[] getSupportedCipherSuites() {
  99         return CipherSuite.namesOf(sslContext.getSupportedCipherSuites());
 100     }
 101 
 102     @Override
 103     public String[] getSupportedProtocols() {
 104         return ProtocolVersion.toStringArray(
 105                 sslContext.getSupportedProtocolVersions());
 106     }
 107 
 108     @Override
 109     public synchronized String[] getEnabledProtocols() {
 110         return ProtocolVersion.toStringArray(sslConfig.enabledProtocols);
 111     }
 112 
 113     @Override
 114     public synchronized void setEnabledProtocols(String[] protocols) {
 115         if (protocols == null) {
 116             throw new IllegalArgumentException("Protocols cannot be null");
 117         }
 118 
 119         sslConfig.enabledProtocols = ProtocolVersion.namesOf(protocols);
 120     }
 121 
 122     @Override
 123     public synchronized void setNeedClientAuth(boolean need) {
 124         sslConfig.clientAuthType =
 125                 (need ? ClientAuthType.CLIENT_AUTH_REQUIRED :
 126                         ClientAuthType.CLIENT_AUTH_NONE);
 127     }
 128 
 129     @Override
 130     public synchronized boolean getNeedClientAuth() {
 131         return (sslConfig.clientAuthType ==
 132                         ClientAuthType.CLIENT_AUTH_REQUIRED);
 133     }
 134 
 135     @Override
 136     public synchronized void setWantClientAuth(boolean want) {
 137         sslConfig.clientAuthType =
 138                 (want ? ClientAuthType.CLIENT_AUTH_REQUESTED :
 139                         ClientAuthType.CLIENT_AUTH_NONE);
 140     }
 141 
 142     @Override
 143     public synchronized boolean getWantClientAuth() {
 144         return (sslConfig.clientAuthType ==
 145                         ClientAuthType.CLIENT_AUTH_REQUESTED);
 146     }
 147 
 148     @Override
 149     public synchronized void setUseClientMode(boolean useClientMode) {
 150         /*
 151          * If we need to change the client mode and the enabled
 152          * protocols and cipher suites haven't specifically been
 153          * set by the user, change them to the corresponding
 154          * default ones.
 155          */
 156         if (sslConfig.isClientMode != useClientMode) {
 157             if (sslContext.isDefaultProtocolVesions(
 158                     sslConfig.enabledProtocols)) {
 159                 sslConfig.enabledProtocols =
 160                         sslContext.getDefaultProtocolVersions(!useClientMode);
 161             }
 162 
 163             if (sslContext.isDefaultCipherSuiteList(
 164                     sslConfig.enabledCipherSuites)) {
 165                 sslConfig.enabledCipherSuites =
 166                         sslContext.getDefaultCipherSuites(!useClientMode);
 167             }
 168 
 169             sslConfig.isClientMode = useClientMode;
 170         }
 171     }
 172 
 173     @Override
 174     public synchronized boolean getUseClientMode() {
 175         return sslConfig.isClientMode;
 176     }
 177 
 178     @Override
 179     public synchronized void setEnableSessionCreation(boolean flag) {
 180         sslConfig.enableSessionCreation = flag;
 181     }
 182 
 183     @Override
 184     public synchronized boolean getEnableSessionCreation() {
 185         return sslConfig.enableSessionCreation;
 186     }
 187 
 188     @Override
 189     public synchronized SSLParameters getSSLParameters() {
 190         return sslConfig.getSSLParameters();
 191     }
 192 
 193     @Override
 194     public synchronized void setSSLParameters(SSLParameters params) {
 195         sslConfig.setSSLParameters(params);
 196     }
 197 
 198     @Override
 199     public Socket accept() throws IOException {
 200         SSLSocketImpl s = new SSLSocketImpl(sslContext, sslConfig);
 201 
 202         implAccept(s);
 203         s.doneConnect();
 204         return s;
 205     }
 206 
 207     @Override
 208     public String toString() {
 209         return "[SSL: "+ super.toString() + "]";
 210     }
 211 }