001/*
002 * oauth2-oidc-sdk
003 *
004 * Copyright 2012-2016, Connect2id Ltd and contributors.
005 *
006 * Licensed under the Apache License, Version 2.0 (the "License"); you may not use
007 * this file except in compliance with the License. You may obtain a copy of the
008 * License at
009 *
010 *    http://www.apache.org/licenses/LICENSE-2.0
011 *
012 * Unless required by applicable law or agreed to in writing, software distributed
013 * under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
014 * CONDITIONS OF ANY KIND, either express or implied. See the License for the
015 * specific language governing permissions and limitations under the License.
016 */
017
018package com.nimbusds.oauth2.sdk.util.tls;
019
020
021import java.security.*;
022import javax.net.ssl.*;
023
024
025/**
026 * TLS / SSL utilities.
027 */
028public final class TLSUtils {
029        
030        
031        /**
032         * Creates a new SSL socket factory with with a custom trust store for
033         * server or CA root X.509 certificates / certificate chains.
034         *
035         * <p>The SSL socket factory is created using TLS 1.3, the default JCA
036         * provider and the default secure random generator.
037         *
038         * @param trustStore The trust store to use. Must be initialised /
039         *                   loaded. If {@code null} the default trust store
040         *                   for resolving the server certificates will be
041         *                   used.
042         *
043         * @return The SSL socket factory.
044         *
045         * @throws NoSuchAlgorithmException  On a unsupported TLS algorithm.
046         * @throws KeyStoreException         On a trust store exception.
047         * @throws KeyManagementException    On a key management exception.
048         * @throws UnrecoverableKeyException On a key retrieval exception.
049         */
050        public static SSLSocketFactory createSSLSocketFactory(final KeyStore trustStore)
051                throws NoSuchAlgorithmException, KeyStoreException, KeyManagementException, UnrecoverableKeyException {
052                
053                return createSSLSocketFactory(trustStore, null, null, TLSVersion.TLS_1_3);
054        }
055        
056        
057        /**
058         * Creates a new SSL socket factory with with a custom trust store for
059         * server or CA root X.509 certificates / certificate chains.
060         *
061         * <p>The SSL socket factory is created using the default JCA provider
062         * and the default secure random generator.
063         *
064         * @param trustStore The trust store to use. Must be initialised /
065         *                   loaded. If {@code null} the default trust store
066         *                   for resolving the server certificates will be
067         *                   used.
068         * @param tlsVersion The TLS version to use. {@link TLSVersion#TLS_1_3}
069         *                   is recommended. Must not be {@code null}.
070         *
071         * @return The SSL socket factory.
072         *
073         * @throws NoSuchAlgorithmException  On a unsupported TLS algorithm.
074         * @throws KeyStoreException         On a trust store exception.
075         * @throws KeyManagementException    On a key management exception.
076         * @throws UnrecoverableKeyException On a key retrieval exception.
077         */
078        public static SSLSocketFactory createSSLSocketFactory(final KeyStore trustStore, final TLSVersion tlsVersion)
079                throws NoSuchAlgorithmException, KeyStoreException, KeyManagementException, UnrecoverableKeyException {
080                
081                return createSSLSocketFactory(trustStore, null, null, tlsVersion);
082        }
083        
084        
085        /**
086         * Creates a new SSL socket factory with with a custom trust store for
087         * server (or CA) certificates and / or custom key store for client
088         * keys and certificates.
089         *
090         * <p>If a trust store is specified it should contain the required
091         * server or CA root X.509 certificates / certificate chains.
092         *
093         * <p>If a key store is specified it should contain the required one
094         * more private client keys with matching X.509 certificates.
095         *
096         * <p>The SSL socket factory is created using the default JCA provider
097         * and the default secure random generator.
098         *
099         * @param trustStore The trust store to use. Must be initialised /
100         *                   loaded. If {@code null} the default trust store
101         *                   for resolving the server certificates will be
102         *                   used.
103         * @param keyStore   The key store to use. Must be initialised /
104         *                   loaded. If {@code null} no client certificates
105         *                   will be presented.
106         * @param keyPw      The password protecting the private client key(s),
107         *                   empty array or {@code null} if none or not
108         *                   applicable.
109         * @param tlsVersion The TLS version to use. {@link TLSVersion#TLS_1_3}
110         *                   is recommended. Must not be {@code null}.
111         *
112         * @return The SSL socket factory.
113         *
114         * @throws NoSuchAlgorithmException  On a unsupported TLS algorithm.
115         * @throws KeyStoreException         On a trust store exception.
116         * @throws KeyManagementException    On a key management exception.
117         * @throws UnrecoverableKeyException On a key retrieval exception.
118         */
119        public static SSLSocketFactory createSSLSocketFactory(final KeyStore trustStore,
120                                                              final KeyStore keyStore,
121                                                              final char[] keyPw,
122                                                              final TLSVersion tlsVersion)
123                throws NoSuchAlgorithmException, KeyStoreException, KeyManagementException, UnrecoverableKeyException {
124                
125                final SSLContext sslContext = SSLContext.getInstance(tlsVersion.toString());
126                
127                TrustManager[] trustManagers = null;
128                if (trustStore != null) {
129                        TrustManagerFactory tmf = TrustManagerFactory.getInstance("PKIX");
130                        tmf.init(trustStore);
131                        trustManagers = tmf.getTrustManagers();
132                }
133                
134                KeyManager[] keyManagers = null;
135                if (keyStore != null) {
136                        KeyManagerFactory kmf = KeyManagerFactory.getInstance("PKIX");
137                        kmf.init(keyStore, keyPw);
138                        keyManagers = kmf.getKeyManagers();
139                }
140                
141                sslContext.init(keyManagers, trustManagers, null);
142                
143                return sslContext.getSocketFactory();
144        }
145        
146        
147        /**
148         * Prevents public instantiation.
149         */
150        private TLSUtils() {}
151}