Logo Search packages:      
Sourcecode: mysql-connector-java version File versions  Download package

ExportControlled.java

/*
 Copyright (c) 2002, 2010, Oracle and/or its affiliates. All rights reserved.
 

  The MySQL Connector/J is licensed under the terms of the GPLv2
  <http://www.gnu.org/licenses/old-licenses/gpl-2.0.html>, like most MySQL Connectors.
  There are special exceptions to the terms and conditions of the GPLv2 as it is applied to
  this software, see the FLOSS License Exception
  <http://www.mysql.com/about/legal/licensing/foss-exception.html>.

  This program is free software; you can redistribute it and/or modify it under the terms
  of the GNU General Public License as published by the Free Software Foundation; version 2
  of the License.

  This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
  without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  See the GNU General Public License for more details.

  You should have received a copy of the GNU General Public License along with this
  program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth
  Floor, Boston, MA 02110-1301  USA



 */
package com.mysql.jdbc;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import java.security.KeyManagementException;
import java.security.KeyStore;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.security.UnrecoverableKeyException;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import java.sql.SQLException;

import javax.net.ssl.KeyManagerFactory;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSocketFactory;
import javax.net.ssl.TrustManagerFactory;
import javax.net.ssl.X509TrustManager;

/**
 * Holds functionality that falls under export-control regulations.
 * 
 * @author Mark Matthews
 * 
 * @version $Id: ExportControlled.java,v 1.1.2.1 2005/05/13 18:58:38 mmatthews
 *          Exp $
 */
00056 public class ExportControlled {
      private static final String SQL_STATE_BAD_SSL_PARAMS = "08000";

      protected static boolean enabled() {
            // we may wish to un-static-ify this class
            // this static method call may be removed entirely by the compiler
            return true;
      }

      /**
       * Converts the socket being used in the given MysqlIO to an SSLSocket by
       * performing the SSL/TLS handshake.
       * 
       * @param mysqlIO
       *            the MysqlIO instance containing the socket to convert to an
       *            SSLSocket.
       * 
       * @throws CommunicationsException
       *             if the handshake fails, or if this distribution of
       *             Connector/J doesn't contain the SSL crytpo hooks needed to
       *             perform the handshake.
       */
00078       protected static void transformSocketToSSLSocket(MysqlIO mysqlIO)
                  throws SQLException {
            javax.net.ssl.SSLSocketFactory sslFact = getSSLSocketFactoryDefaultOrConfigured(mysqlIO);

            try {
                  mysqlIO.mysqlConnection = sslFact.createSocket(
                              mysqlIO.mysqlConnection, mysqlIO.host, mysqlIO.port, true);

                  // need to force TLSv1, or else JSSE tries to do a SSLv2 handshake
                  // which MySQL doesn't understand
                  ((javax.net.ssl.SSLSocket) mysqlIO.mysqlConnection)
                              .setEnabledProtocols(new String[] { "TLSv1" }); //$NON-NLS-1$
                  ((javax.net.ssl.SSLSocket) mysqlIO.mysqlConnection)
                              .startHandshake();

                  if (mysqlIO.connection.getUseUnbufferedInput()) {
                        mysqlIO.mysqlInput = mysqlIO.mysqlConnection.getInputStream();
                  } else {
                        mysqlIO.mysqlInput = new BufferedInputStream(
                                    mysqlIO.mysqlConnection.getInputStream(), 16384);
                  }

                  mysqlIO.mysqlOutput = new BufferedOutputStream(
                              mysqlIO.mysqlConnection.getOutputStream(), 16384);

                  mysqlIO.mysqlOutput.flush();
            } catch (IOException ioEx) {
                  throw SQLError.createCommunicationsException(mysqlIO.connection,
                              mysqlIO.getLastPacketSentTimeMs(), mysqlIO.getLastPacketReceivedTimeMs(),
                              ioEx, mysqlIO.getExceptionInterceptor());
            }
      }

      private ExportControlled() { /* prevent instantiation */
      }

      private static SSLSocketFactory getSSLSocketFactoryDefaultOrConfigured(
                  MysqlIO mysqlIO) throws SQLException {
            String clientCertificateKeyStoreUrl = mysqlIO.connection
                        .getClientCertificateKeyStoreUrl();
            String trustCertificateKeyStoreUrl = mysqlIO.connection
                        .getTrustCertificateKeyStoreUrl();
            String clientCertificateKeyStoreType = mysqlIO.connection
                        .getClientCertificateKeyStoreType();
            String clientCertificateKeyStorePassword = mysqlIO.connection
                        .getClientCertificateKeyStorePassword();
            String trustCertificateKeyStoreType = mysqlIO.connection
                        .getTrustCertificateKeyStoreType();
            String trustCertificateKeyStorePassword = mysqlIO.connection
                        .getTrustCertificateKeyStorePassword();

            if (StringUtils.isNullOrEmpty(clientCertificateKeyStoreUrl)
                        && StringUtils.isNullOrEmpty(trustCertificateKeyStoreUrl)) {
                  if (mysqlIO.connection.getVerifyServerCertificate()) {
                        return (javax.net.ssl.SSLSocketFactory) javax.net.ssl.SSLSocketFactory
                                    .getDefault();
                  }
            }

            TrustManagerFactory tmf = null;
            KeyManagerFactory kmf = null;

            try {
                  tmf = TrustManagerFactory.getInstance(TrustManagerFactory
                              .getDefaultAlgorithm());
                  kmf = KeyManagerFactory.getInstance(KeyManagerFactory
                              .getDefaultAlgorithm());
            } catch (NoSuchAlgorithmException nsae) {
                  throw SQLError
                              .createSQLException(
                                          "Default algorithm definitions for TrustManager and/or KeyManager are invalid.  Check java security properties file.",
                                          SQL_STATE_BAD_SSL_PARAMS, 0, false, mysqlIO.getExceptionInterceptor());
            }

            if (!StringUtils.isNullOrEmpty(clientCertificateKeyStoreUrl)) {
                  try {
                        if (!StringUtils.isNullOrEmpty(clientCertificateKeyStoreType)) {
                              KeyStore clientKeyStore = KeyStore
                                          .getInstance(clientCertificateKeyStoreType);
                              URL ksURL = new URL(clientCertificateKeyStoreUrl);
                              char[] password = (clientCertificateKeyStorePassword == null) ? new char[0]
                                          : clientCertificateKeyStorePassword.toCharArray();
                              clientKeyStore.load(ksURL.openStream(), password);
                              kmf.init(clientKeyStore, password);
                        }
                  } catch (UnrecoverableKeyException uke) {
                        throw SQLError
                                    .createSQLException(
                                                "Could not recover keys from client keystore.  Check password?",
                                                SQL_STATE_BAD_SSL_PARAMS, 0, false, mysqlIO.getExceptionInterceptor());
                  } catch (NoSuchAlgorithmException nsae) {
                        throw SQLError.createSQLException(
                                    "Unsupported keystore algorithm [" + nsae.getMessage()
                                                + "]", SQL_STATE_BAD_SSL_PARAMS, 0, false, mysqlIO.getExceptionInterceptor());
                  } catch (KeyStoreException kse) {
                        throw SQLError.createSQLException(
                                    "Could not create KeyStore instance ["
                                                + kse.getMessage() + "]", SQL_STATE_BAD_SSL_PARAMS, 0, false, mysqlIO.getExceptionInterceptor());
                  } catch (CertificateException nsae) {
                        throw SQLError.createSQLException("Could not load client"
                                    + clientCertificateKeyStoreType + " keystore from "
                                    + clientCertificateKeyStoreUrl, mysqlIO.getExceptionInterceptor());
                  } catch (MalformedURLException mue) {
                        throw SQLError.createSQLException(clientCertificateKeyStoreUrl
                                    + " does not appear to be a valid URL.", SQL_STATE_BAD_SSL_PARAMS, 0,
                                    false, mysqlIO.getExceptionInterceptor());
                  } catch (IOException ioe) {
                        SQLException sqlEx = SQLError.createSQLException("Cannot open "
                                    + clientCertificateKeyStoreUrl + " ["
                                    + ioe.getMessage() + "]", SQL_STATE_BAD_SSL_PARAMS, 0, false, mysqlIO.getExceptionInterceptor());
                        sqlEx.initCause(ioe);
                        
                        throw sqlEx;
                  }
            }

            if (!StringUtils.isNullOrEmpty(trustCertificateKeyStoreUrl)) {

                  try {
                        if (!StringUtils.isNullOrEmpty(trustCertificateKeyStoreType)) {
                              KeyStore trustKeyStore = KeyStore
                                          .getInstance(trustCertificateKeyStoreType);
                              URL ksURL = new URL(trustCertificateKeyStoreUrl);
      
                              char[] password = (trustCertificateKeyStorePassword == null) ? new char[0]
                                          : trustCertificateKeyStorePassword.toCharArray();
                              trustKeyStore.load(ksURL.openStream(), password);
                              tmf.init(trustKeyStore);
                        }
                  } catch (NoSuchAlgorithmException nsae) {
                        throw SQLError.createSQLException(
                                    "Unsupported keystore algorithm [" + nsae.getMessage()
                                                + "]", SQL_STATE_BAD_SSL_PARAMS, 0, false, mysqlIO.getExceptionInterceptor());
                  } catch (KeyStoreException kse) {
                        throw SQLError.createSQLException(
                                    "Could not create KeyStore instance ["
                                                + kse.getMessage() + "]", SQL_STATE_BAD_SSL_PARAMS, 0, false, mysqlIO.getExceptionInterceptor());
                  } catch (CertificateException nsae) {
                        throw SQLError.createSQLException("Could not load trust"
                                    + trustCertificateKeyStoreType + " keystore from "
                                    + trustCertificateKeyStoreUrl, SQL_STATE_BAD_SSL_PARAMS, 0, false, mysqlIO.getExceptionInterceptor());
                  } catch (MalformedURLException mue) {
                        throw SQLError.createSQLException(trustCertificateKeyStoreUrl
                                    + " does not appear to be a valid URL.", SQL_STATE_BAD_SSL_PARAMS, 0,
                                    false, mysqlIO.getExceptionInterceptor());
                  } catch (IOException ioe) {
                        SQLException sqlEx = SQLError.createSQLException("Cannot open "
                                    + trustCertificateKeyStoreUrl + " [" + ioe.getMessage()
                                    + "]", SQL_STATE_BAD_SSL_PARAMS, 0, false, mysqlIO.getExceptionInterceptor());
                        
                        sqlEx.initCause(ioe);
                        
                        throw sqlEx;
                  }
            }

            SSLContext sslContext = null;

            try {
                  sslContext = SSLContext.getInstance("TLS");
                  sslContext.init(StringUtils.isNullOrEmpty(clientCertificateKeyStoreUrl) ?  null : kmf.getKeyManagers(), mysqlIO.connection
                              .getVerifyServerCertificate() ? tmf.getTrustManagers()
                              : new X509TrustManager[] { new X509TrustManager() {
                                    public void checkClientTrusted(X509Certificate[] chain,
                                                String authType) {
                                          // return without complaint
                                    }

                                    public void checkServerTrusted(X509Certificate[] chain,
                                                String authType) throws CertificateException {
                                          // return without complaint
                                    }

                                    public X509Certificate[] getAcceptedIssuers() {
                                          return null;
                                    }
                              } }, null);

                  return sslContext.getSocketFactory();
            } catch (NoSuchAlgorithmException nsae) {
                  throw SQLError.createSQLException("TLS"
                              + " is not a valid SSL protocol.",
                              SQL_STATE_BAD_SSL_PARAMS, 0, false, mysqlIO.getExceptionInterceptor());
            } catch (KeyManagementException kme) {
                  throw SQLError.createSQLException("KeyManagementException: "
                              + kme.getMessage(), SQL_STATE_BAD_SSL_PARAMS, 0, false, mysqlIO.getExceptionInterceptor());
            }
      }
}

Generated by  Doxygen 1.6.0   Back to index