/* * Copyright (c) 2004, PostgreSQL Global Development Group * See the LICENSE file in the project root for more information. */package org.postgresql.ssl;import org.postgresql.PGProperty;import org.postgresql.core.PGStream;import org.postgresql.core.SocketFactoryFactory;import org.postgresql.jdbc.SslMode;import org.postgresql.util.GT;import org.postgresql.util.ObjectFactory;import org.postgresql.util.PSQLException;import org.postgresql.util.PSQLState;import java.io.IOException;import java.util.Properties;import java.util.logging.Level;import java.util.logging.Logger;import javax.net.ssl.HostnameVerifier;import javax.net.ssl.SSLSocket;import javax.net.ssl.SSLSocketFactory;public class MakeSSL extends ObjectFactory {  private static final Logger LOGGER = Logger.getLogger(MakeSSL.class.getName());  public static void convert(PGStream stream, Properties info)      throws PSQLException, IOException {    LOGGER.log(Level.FINE, "converting regular socket connection to ssl");    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 PSQLException(GT.tr("SSL error: {0}", ex.getMessage()),          PSQLState.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(PGStream stream, Properties info, SSLSocket newConnection)      throws PSQLException {    HostnameVerifier hvn;    String sslhostnameverifier = PGProperty.SSL_HOSTNAME_VERIFIER.get(info);    if (sslhostnameverifier == null) {      hvn = PGjdbcHostnameVerifier.INSTANCE;      sslhostnameverifier = "PgjdbcHostnameVerifier";    } else {      try {        // BUG: CWE-665 Improper Initialization        // hvn = (HostnameVerifier) instantiate(sslhostnameverifier, info, false, null);        // FIXED:         hvn = instantiate(HostnameVerifier.class, sslhostnameverifier, info, false, null);      } catch (Exception e) {        throw new PSQLException(            GT.tr("The HostnameVerifier class provided {0} could not be instantiated.",                sslhostnameverifier),            PSQLState.CONNECTION_FAILURE, e);      }    }    if (hvn.verify(stream.getHostSpec().getHost(), newConnection.getSession())) {      return;    }    throw new PSQLException(        GT.tr("The hostname {0} could not be verified by hostnameverifier {1}.",            stream.getHostSpec().getHost(), sslhostnameverifier),        PSQLState.CONNECTION_FAILURE);  }}