1 /* 2 * Licensed to the Apache Software Foundation (ASF) under one or more 3 * contributor license agreements. See the NOTICE file distributed with 4 * this work for additional information regarding copyright ownership. 5 * The ASF licenses this file to You under the Apache License, Version 2.0 6 * (the "License"); you may not use this file except in compliance with 7 * the License. You may obtain a copy of the License at 8 * 9 * http://www.apache.org/licenses/LICENSE-2.0 10 * 11 * Unless required by applicable law or agreed to in writing, software 12 * distributed under the License is distributed on an "AS IS" BASIS, 13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 * See the License for the specific language governing permissions and 15 * limitations under the License. 16 */ 17 18 package org.conscrypt; 19 20 import java.io.IOException; 21 import java.security.GeneralSecurityException; 22 import java.security.KeyManagementException; 23 import java.security.SecureRandom; 24 import javax.net.ssl.KeyManager; 25 import javax.net.ssl.SSLContextSpi; 26 import javax.net.ssl.SSLEngine; 27 import javax.net.ssl.SSLServerSocketFactory; 28 import javax.net.ssl.SSLSocketFactory; 29 import javax.net.ssl.TrustManager; 30 31 /** 32 * Implementation of SSLContext service provider interface. 33 */ 34 public class SSLContextImpl extends SSLContextSpi { 35 36 /** 37 * The default SSLContextImpl for use with SSLContext.getInstance("Default"). 38 * Protected by the DefaultSSLContextImpl.class monitor. 39 */ 40 private static DefaultSSLContextImpl DEFAULT_SSL_CONTEXT_IMPL; 41 42 /** Client session cache. */ 43 private final ClientSessionContext clientSessionContext; 44 45 /** Server session cache. */ 46 private final ServerSessionContext serverSessionContext; 47 48 protected SSLParametersImpl sslParameters; 49 50 public SSLContextImpl() { 51 clientSessionContext = new ClientSessionContext(); 52 serverSessionContext = new ServerSessionContext(); 53 } 54 55 /** 56 * Constuctor for the DefaultSSLContextImpl. 57 * @param dummy is null, used to distinguish this case from the 58 * public SSLContextImpl() constructor. 59 */ 60 protected SSLContextImpl(DefaultSSLContextImpl dummy) 61 throws GeneralSecurityException, IOException { 62 synchronized (DefaultSSLContextImpl.class) { 63 if (DEFAULT_SSL_CONTEXT_IMPL == null) { 64 clientSessionContext = new ClientSessionContext(); 65 serverSessionContext = new ServerSessionContext(); 66 DEFAULT_SSL_CONTEXT_IMPL = (DefaultSSLContextImpl)this; 67 } else { 68 clientSessionContext = DEFAULT_SSL_CONTEXT_IMPL.engineGetClientSessionContext(); 69 serverSessionContext = DEFAULT_SSL_CONTEXT_IMPL.engineGetServerSessionContext(); 70 } 71 sslParameters = new SSLParametersImpl(DEFAULT_SSL_CONTEXT_IMPL.getKeyManagers(), 72 DEFAULT_SSL_CONTEXT_IMPL.getTrustManagers(), 73 null, 74 clientSessionContext, 75 serverSessionContext); 76 } 77 } 78 79 /** 80 * Initializes this {@code SSLContext} instance. All of the arguments are 81 * optional, and the security providers will be searched for the required 82 * implementations of the needed algorithms. 83 * 84 * @param kms the key sources or {@code null} 85 * @param tms the trust decision sources or {@code null} 86 * @param sr the randomness source or {@code null} 87 * @throws KeyManagementException if initializing this instance fails 88 */ 89 @Override 90 public void engineInit(KeyManager[] kms, TrustManager[] tms, 91 SecureRandom sr) throws KeyManagementException { 92 sslParameters = new SSLParametersImpl(kms, tms, sr, 93 clientSessionContext, serverSessionContext); 94 } 95 96 @Override 97 public SSLSocketFactory engineGetSocketFactory() { 98 if (sslParameters == null) { 99 throw new IllegalStateException("SSLContext is not initialized."); 100 } 101 return new SSLSocketFactoryImpl(sslParameters); 102 } 103 104 @Override 105 public SSLServerSocketFactory engineGetServerSocketFactory() { 106 if (sslParameters == null) { 107 throw new IllegalStateException("SSLContext is not initialized."); 108 } 109 return new SSLServerSocketFactoryImpl(sslParameters); 110 } 111 112 @Override 113 public SSLEngine engineCreateSSLEngine(String host, int port) { 114 if (sslParameters == null) { 115 throw new IllegalStateException("SSLContext is not initialized."); 116 } 117 SSLParametersImpl p = (SSLParametersImpl) sslParameters.clone(); 118 p.setUseClientMode(false); 119 return new SSLEngineImpl(host, port, p); 120 } 121 122 @Override 123 public SSLEngine engineCreateSSLEngine() { 124 if (sslParameters == null) { 125 throw new IllegalStateException("SSLContext is not initialized."); 126 } 127 SSLParametersImpl p = (SSLParametersImpl) sslParameters.clone(); 128 p.setUseClientMode(false); 129 return new SSLEngineImpl(p); 130 } 131 132 @Override 133 public ServerSessionContext engineGetServerSessionContext() { 134 return serverSessionContext; 135 } 136 137 @Override 138 public ClientSessionContext engineGetClientSessionContext() { 139 return clientSessionContext; 140 } 141 } 142