source: Ballon/out/artifacts/geisa_artifact/WEB-INF/lib/mysql-connector-java-5.1.21/src/com/mysql/jdbc/ExportControlled.java @ 848

Last change on this file since 848 was 766, checked in by npipsl, 11 years ago
File size: 10.4 KB
Line 
1/*
2 Copyright (c) 2002, 2010, Oracle and/or its affiliates. All rights reserved.
3 
4
5  The MySQL Connector/J is licensed under the terms of the GPLv2
6  <http://www.gnu.org/licenses/old-licenses/gpl-2.0.html>, like most MySQL Connectors.
7  There are special exceptions to the terms and conditions of the GPLv2 as it is applied to
8  this software, see the FLOSS License Exception
9  <http://www.mysql.com/about/legal/licensing/foss-exception.html>.
10
11  This program is free software; you can redistribute it and/or modify it under the terms
12  of the GNU General Public License as published by the Free Software Foundation; version 2
13  of the License.
14
15  This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
16  without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
17  See the GNU General Public License for more details.
18
19  You should have received a copy of the GNU General Public License along with this
20  program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth
21  Floor, Boston, MA 02110-1301  USA
22
23
24
25 */
26package com.mysql.jdbc;
27
28import java.io.BufferedInputStream;
29import java.io.BufferedOutputStream;
30import java.io.IOException;
31import java.net.MalformedURLException;
32import java.net.URL;
33import java.security.KeyManagementException;
34import java.security.KeyStore;
35import java.security.KeyStoreException;
36import java.security.NoSuchAlgorithmException;
37import java.security.UnrecoverableKeyException;
38import java.security.cert.CertificateException;
39import java.security.cert.X509Certificate;
40import java.sql.SQLException;
41
42import javax.net.ssl.KeyManagerFactory;
43import javax.net.ssl.SSLContext;
44import javax.net.ssl.SSLSocketFactory;
45import javax.net.ssl.TrustManagerFactory;
46import javax.net.ssl.X509TrustManager;
47
48/**
49 * Holds functionality that falls under export-control regulations.
50 *
51 * @author Mark Matthews
52 *
53 * @version $Id: ExportControlled.java,v 1.1.2.1 2005/05/13 18:58:38 mmatthews
54 *          Exp $
55 */
56public class ExportControlled {
57        private static final String SQL_STATE_BAD_SSL_PARAMS = "08000";
58
59        protected static boolean enabled() {
60                // we may wish to un-static-ify this class
61                // this static method call may be removed entirely by the compiler
62                return true;
63        }
64
65        /**
66         * Converts the socket being used in the given MysqlIO to an SSLSocket by
67         * performing the SSL/TLS handshake.
68         *
69         * @param mysqlIO
70         *            the MysqlIO instance containing the socket to convert to an
71         *            SSLSocket.
72         *
73         * @throws CommunicationsException
74         *             if the handshake fails, or if this distribution of
75         *             Connector/J doesn't contain the SSL crytpo hooks needed to
76         *             perform the handshake.
77         */
78        protected static void transformSocketToSSLSocket(MysqlIO mysqlIO)
79                        throws SQLException {
80                javax.net.ssl.SSLSocketFactory sslFact = getSSLSocketFactoryDefaultOrConfigured(mysqlIO);
81
82                try {
83                        mysqlIO.mysqlConnection = sslFact.createSocket(
84                                        mysqlIO.mysqlConnection, mysqlIO.host, mysqlIO.port, true);
85
86                        // need to force TLSv1, or else JSSE tries to do a SSLv2 handshake
87                        // which MySQL doesn't understand
88                        ((javax.net.ssl.SSLSocket) mysqlIO.mysqlConnection)
89                                        .setEnabledProtocols(new String[] { "TLSv1" }); //$NON-NLS-1$
90                        ((javax.net.ssl.SSLSocket) mysqlIO.mysqlConnection)
91                                        .startHandshake();
92
93                        if (mysqlIO.connection.getUseUnbufferedInput()) {
94                                mysqlIO.mysqlInput = mysqlIO.mysqlConnection.getInputStream();
95                        } else {
96                                mysqlIO.mysqlInput = new BufferedInputStream(
97                                                mysqlIO.mysqlConnection.getInputStream(), 16384);
98                        }
99
100                        mysqlIO.mysqlOutput = new BufferedOutputStream(
101                                        mysqlIO.mysqlConnection.getOutputStream(), 16384);
102
103                        mysqlIO.mysqlOutput.flush();
104                } catch (IOException ioEx) {
105                        throw SQLError.createCommunicationsException(mysqlIO.connection,
106                                        mysqlIO.getLastPacketSentTimeMs(), mysqlIO.getLastPacketReceivedTimeMs(),
107                                        ioEx, mysqlIO.getExceptionInterceptor());
108                }
109        }
110
111        private ExportControlled() { /* prevent instantiation */
112        }
113
114        private static SSLSocketFactory getSSLSocketFactoryDefaultOrConfigured(
115                        MysqlIO mysqlIO) throws SQLException {
116                String clientCertificateKeyStoreUrl = mysqlIO.connection
117                                .getClientCertificateKeyStoreUrl();
118                String trustCertificateKeyStoreUrl = mysqlIO.connection
119                                .getTrustCertificateKeyStoreUrl();
120                String clientCertificateKeyStoreType = mysqlIO.connection
121                                .getClientCertificateKeyStoreType();
122                String clientCertificateKeyStorePassword = mysqlIO.connection
123                                .getClientCertificateKeyStorePassword();
124                String trustCertificateKeyStoreType = mysqlIO.connection
125                                .getTrustCertificateKeyStoreType();
126                String trustCertificateKeyStorePassword = mysqlIO.connection
127                                .getTrustCertificateKeyStorePassword();
128
129                if (StringUtils.isNullOrEmpty(clientCertificateKeyStoreUrl)
130                                && StringUtils.isNullOrEmpty(trustCertificateKeyStoreUrl)) {
131                        if (mysqlIO.connection.getVerifyServerCertificate()) {
132                                return (javax.net.ssl.SSLSocketFactory) javax.net.ssl.SSLSocketFactory
133                                                .getDefault();
134                        }
135                }
136
137                TrustManagerFactory tmf = null;
138                KeyManagerFactory kmf = null;
139
140                try {
141                        tmf = TrustManagerFactory.getInstance(TrustManagerFactory
142                                        .getDefaultAlgorithm());
143                        kmf = KeyManagerFactory.getInstance(KeyManagerFactory
144                                        .getDefaultAlgorithm());
145                } catch (NoSuchAlgorithmException nsae) {
146                        throw SQLError
147                                        .createSQLException(
148                                                        "Default algorithm definitions for TrustManager and/or KeyManager are invalid.  Check java security properties file.",
149                                                        SQL_STATE_BAD_SSL_PARAMS, 0, false, mysqlIO.getExceptionInterceptor());
150                }
151
152                if (!StringUtils.isNullOrEmpty(clientCertificateKeyStoreUrl)) {
153                        try {
154                                if (!StringUtils.isNullOrEmpty(clientCertificateKeyStoreType)) {
155                                        KeyStore clientKeyStore = KeyStore
156                                                        .getInstance(clientCertificateKeyStoreType);
157                                        URL ksURL = new URL(clientCertificateKeyStoreUrl);
158                                        char[] password = (clientCertificateKeyStorePassword == null) ? new char[0]
159                                                        : clientCertificateKeyStorePassword.toCharArray();
160                                        clientKeyStore.load(ksURL.openStream(), password);
161                                        kmf.init(clientKeyStore, password);
162                                }
163                        } catch (UnrecoverableKeyException uke) {
164                                throw SQLError
165                                                .createSQLException(
166                                                                "Could not recover keys from client keystore.  Check password?",
167                                                                SQL_STATE_BAD_SSL_PARAMS, 0, false, mysqlIO.getExceptionInterceptor());
168                        } catch (NoSuchAlgorithmException nsae) {
169                                throw SQLError.createSQLException(
170                                                "Unsupported keystore algorithm [" + nsae.getMessage()
171                                                                + "]", SQL_STATE_BAD_SSL_PARAMS, 0, false, mysqlIO.getExceptionInterceptor());
172                        } catch (KeyStoreException kse) {
173                                throw SQLError.createSQLException(
174                                                "Could not create KeyStore instance ["
175                                                                + kse.getMessage() + "]", SQL_STATE_BAD_SSL_PARAMS, 0, false, mysqlIO.getExceptionInterceptor());
176                        } catch (CertificateException nsae) {
177                                throw SQLError.createSQLException("Could not load client"
178                                                + clientCertificateKeyStoreType + " keystore from "
179                                                + clientCertificateKeyStoreUrl, mysqlIO.getExceptionInterceptor());
180                        } catch (MalformedURLException mue) {
181                                throw SQLError.createSQLException(clientCertificateKeyStoreUrl
182                                                + " does not appear to be a valid URL.", SQL_STATE_BAD_SSL_PARAMS, 0,
183                                                false, mysqlIO.getExceptionInterceptor());
184                        } catch (IOException ioe) {
185                                SQLException sqlEx = SQLError.createSQLException("Cannot open "
186                                                + clientCertificateKeyStoreUrl + " ["
187                                                + ioe.getMessage() + "]", SQL_STATE_BAD_SSL_PARAMS, 0, false, mysqlIO.getExceptionInterceptor());
188                                sqlEx.initCause(ioe);
189                               
190                                throw sqlEx;
191                        }
192                }
193
194                if (!StringUtils.isNullOrEmpty(trustCertificateKeyStoreUrl)) {
195
196                        try {
197                                if (!StringUtils.isNullOrEmpty(trustCertificateKeyStoreType)) {
198                                        KeyStore trustKeyStore = KeyStore
199                                                        .getInstance(trustCertificateKeyStoreType);
200                                        URL ksURL = new URL(trustCertificateKeyStoreUrl);
201       
202                                        char[] password = (trustCertificateKeyStorePassword == null) ? new char[0]
203                                                        : trustCertificateKeyStorePassword.toCharArray();
204                                        trustKeyStore.load(ksURL.openStream(), password);
205                                        tmf.init(trustKeyStore);
206                                }
207                        } catch (NoSuchAlgorithmException nsae) {
208                                throw SQLError.createSQLException(
209                                                "Unsupported keystore algorithm [" + nsae.getMessage()
210                                                                + "]", SQL_STATE_BAD_SSL_PARAMS, 0, false, mysqlIO.getExceptionInterceptor());
211                        } catch (KeyStoreException kse) {
212                                throw SQLError.createSQLException(
213                                                "Could not create KeyStore instance ["
214                                                                + kse.getMessage() + "]", SQL_STATE_BAD_SSL_PARAMS, 0, false, mysqlIO.getExceptionInterceptor());
215                        } catch (CertificateException nsae) {
216                                throw SQLError.createSQLException("Could not load trust"
217                                                + trustCertificateKeyStoreType + " keystore from "
218                                                + trustCertificateKeyStoreUrl, SQL_STATE_BAD_SSL_PARAMS, 0, false, mysqlIO.getExceptionInterceptor());
219                        } catch (MalformedURLException mue) {
220                                throw SQLError.createSQLException(trustCertificateKeyStoreUrl
221                                                + " does not appear to be a valid URL.", SQL_STATE_BAD_SSL_PARAMS, 0,
222                                                false, mysqlIO.getExceptionInterceptor());
223                        } catch (IOException ioe) {
224                                SQLException sqlEx = SQLError.createSQLException("Cannot open "
225                                                + trustCertificateKeyStoreUrl + " [" + ioe.getMessage()
226                                                + "]", SQL_STATE_BAD_SSL_PARAMS, 0, false, mysqlIO.getExceptionInterceptor());
227                               
228                                sqlEx.initCause(ioe);
229                               
230                                throw sqlEx;
231                        }
232                }
233
234                SSLContext sslContext = null;
235
236                try {
237                        sslContext = SSLContext.getInstance("TLS");
238                        sslContext.init(StringUtils.isNullOrEmpty(clientCertificateKeyStoreUrl) ?  null : kmf.getKeyManagers(), mysqlIO.connection
239                                        .getVerifyServerCertificate() ? tmf.getTrustManagers()
240                                        : new X509TrustManager[] { new X509TrustManager() {
241                                                public void checkClientTrusted(X509Certificate[] chain,
242                                                                String authType) {
243                                                        // return without complaint
244                                                }
245
246                                                public void checkServerTrusted(X509Certificate[] chain,
247                                                                String authType) throws CertificateException {
248                                                        // return without complaint
249                                                }
250
251                                                public X509Certificate[] getAcceptedIssuers() {
252                                                        return null;
253                                                }
254                                        } }, null);
255
256                        return sslContext.getSocketFactory();
257                } catch (NoSuchAlgorithmException nsae) {
258                        throw SQLError.createSQLException("TLS"
259                                        + " is not a valid SSL protocol.",
260                                        SQL_STATE_BAD_SSL_PARAMS, 0, false, mysqlIO.getExceptionInterceptor());
261                } catch (KeyManagementException kme) {
262                        throw SQLError.createSQLException("KeyManagementException: "
263                                        + kme.getMessage(), SQL_STATE_BAD_SSL_PARAMS, 0, false, mysqlIO.getExceptionInterceptor());
264                }
265        }
266}
Note: See TracBrowser for help on using the repository browser.