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
18package org.conscrypt;
19
20import java.io.BufferedInputStream;
21import java.io.FileInputStream;
22import java.io.IOException;
23import java.io.InputStream;
24import java.security.GeneralSecurityException;
25import java.security.KeyManagementException;
26import java.security.KeyStore;
27import java.security.SecureRandom;
28import javax.net.ssl.KeyManager;
29import javax.net.ssl.KeyManagerFactory;
30import javax.net.ssl.TrustManager;
31import javax.net.ssl.TrustManagerFactory;
32
33/**
34 * Support class for this package.
35 *
36 * @hide
37 */
38@Internal
39public final class DefaultSSLContextImpl extends OpenSSLContextImpl {
40
41    /**
42     * Accessed by SSLContextImpl(DefaultSSLContextImpl) holding the
43     * DefaultSSLContextImpl.class monitor
44     */
45    private static KeyManager[] KEY_MANAGERS;
46
47    /**
48     * Accessed by SSLContextImpl(DefaultSSLContextImpl) holding the
49     * DefaultSSLContextImpl.class monitor
50     */
51    private static TrustManager[] TRUST_MANAGERS;
52
53    /**
54     * DefaultSSLContextImpl delegates the work to the super class since there
55     * is no way to put a synchronized around both the call to super and the
56     * rest of this constructor to guarantee that we don't have races in
57     * creating the state shared between all default SSLContexts.
58     */
59    public DefaultSSLContextImpl() throws GeneralSecurityException, IOException {
60        super();
61    }
62
63    // TODO javax.net.ssl.keyStoreProvider system property
64    KeyManager[] getKeyManagers () throws GeneralSecurityException, IOException {
65        if (KEY_MANAGERS != null) {
66            return KEY_MANAGERS;
67        }
68        // find KeyStore, KeyManagers
69        String keystore = System.getProperty("javax.net.ssl.keyStore");
70        if (keystore == null) {
71            return null;
72        }
73        String keystorepwd = System.getProperty("javax.net.ssl.keyStorePassword");
74        char[] pwd = (keystorepwd == null) ? null : keystorepwd.toCharArray();
75
76        KeyStore ks = KeyStore.getInstance(KeyStore.getDefaultType());
77        InputStream is = null;
78        try {
79            is = new BufferedInputStream(new FileInputStream(keystore));
80            ks.load(is, pwd);
81        } finally {
82            if (is != null) {
83                is.close();
84            }
85        }
86
87        String kmfAlg = KeyManagerFactory.getDefaultAlgorithm();
88        KeyManagerFactory kmf = KeyManagerFactory.getInstance(kmfAlg);
89        kmf.init(ks, pwd);
90        KEY_MANAGERS = kmf.getKeyManagers();
91        return KEY_MANAGERS;
92    }
93
94    // TODO javax.net.ssl.trustStoreProvider system property
95    TrustManager[] getTrustManagers() throws GeneralSecurityException, IOException {
96        if (TRUST_MANAGERS != null) {
97            return TRUST_MANAGERS;
98        }
99
100        // find TrustStore, TrustManagers
101        String keystore = System.getProperty("javax.net.ssl.trustStore");
102        if (keystore == null) {
103            return null;
104        }
105        String keystorepwd = System.getProperty("javax.net.ssl.trustStorePassword");
106        char[] pwd = (keystorepwd == null) ? null : keystorepwd.toCharArray();
107
108        // TODO Defaults: jssecacerts; cacerts
109        KeyStore ks = KeyStore.getInstance(KeyStore.getDefaultType());
110        InputStream is = null;
111        try {
112            is = new BufferedInputStream(new FileInputStream(keystore));
113            ks.load(is, pwd);
114        } finally {
115            if (is != null) {
116                is.close();
117            }
118        }
119        String tmfAlg = TrustManagerFactory.getDefaultAlgorithm();
120        TrustManagerFactory tmf = TrustManagerFactory.getInstance(tmfAlg);
121        tmf.init(ks);
122        TRUST_MANAGERS = tmf.getTrustManagers();
123        return TRUST_MANAGERS;
124    }
125
126    @Override
127    public void engineInit(KeyManager[] kms, TrustManager[] tms,
128            SecureRandom sr) throws KeyManagementException {
129        throw new KeyManagementException("Do not init() the default SSLContext ");
130    }
131}
132