/* * Copyright (c) 2004, PostgreSQL Global Development Group * See the LICENSE file in the project root for more information. */ package com.amazon.redshift.ssl; import com.amazon.redshift.RedshiftProperty; import com.amazon.redshift.core.RedshiftStream; import com.amazon.redshift.core.SocketFactoryFactory; import com.amazon.redshift.jdbc.SslMode; import com.amazon.redshift.util.GT; import com.amazon.redshift.util.ObjectFactory; import com.amazon.redshift.util.RedshiftException; import com.amazon.redshift.util.RedshiftState; import java.io.IOException; import java.util.Properties; import javax.net.ssl.HostnameVerifier; import javax.net.ssl.SSLSocket; import javax.net.ssl.SSLSocketFactory; public class MakeSSL extends ObjectFactory { public static void convert(RedshiftStream stream, Properties info) throws RedshiftException, IOException { SSLSocketFactory factory = SocketFactoryFactory.getSslSocketFactory(info); SSLSocket newConnection; try { newConnection = (SSLSocket) factory.createSocket(stream.getSocket(), stream.getHostSpec().getHost(), stream.getHostSpec().getPort(), true); // We must invoke manually, otherwise the exceptions are hidden newConnection.setUseClientMode(true); newConnection.startHandshake(); } catch (IOException ex) { throw new RedshiftException(GT.tr("SSL error: {0}", ex.getMessage()), RedshiftState.CONNECTION_FAILURE, ex); } if (factory instanceof LibPQFactory) { // throw any KeyManager exception ((LibPQFactory) factory).throwKeyManagerException(); } SslMode sslMode = SslMode.of(info); if (sslMode.verifyPeerName()) { verifyPeerName(stream, info, newConnection); } stream.changeSocket(newConnection); } private static void verifyPeerName(RedshiftStream stream, Properties info, SSLSocket newConnection) throws RedshiftException { HostnameVerifier hvn; String sslhostnameverifier = RedshiftProperty.SSL_HOSTNAME_VERIFIER.get(info); if (sslhostnameverifier == null) { hvn = RedshiftjdbcHostnameVerifier.INSTANCE; sslhostnameverifier = "RedshiftjdbcHostnameVerifier"; } else { try { hvn = instantiate(HostnameVerifier.class, sslhostnameverifier, info, false, null); } catch (Exception e) { throw new RedshiftException( GT.tr("The HostnameVerifier class provided {0} could not be instantiated.", sslhostnameverifier), RedshiftState.CONNECTION_FAILURE, e); } } if (hvn.verify(stream.getHostSpec().getHost(), newConnection.getSession())) { return; } throw new RedshiftException( GT.tr("The hostname {0} could not be verified by hostnameverifier {1}.", stream.getHostSpec().getHost(), sslhostnameverifier), RedshiftState.CONNECTION_FAILURE); } }