title: Java - SSLServerSocket with only TLS
body: <p>I am trying to open an <code>SSLServerSocket</code> with custom keystore/truststore and with only <code>TLSv1.2</code> enabled.
  Here is my related code for opening such socket:</p>
  
  <pre><code>SSLContext sslContext = null;
  ServerSocket serverSocket = null;
  KeyManagerFactory kmf = null;
  KeyStore keystore = loadKeyStore(KEYSTORE_FILE);
  if (keystore == null) {
      // throw exception
  }
  char[] psw = System.console().readPassword("Enter password for the key materials in file \"%s\":", KEYSTORE_FILE);
  try {
      kmf = KeyManagerFactory.getInstance("PKIX");
      kmf.init(keystore, psw);
  } catch (NoSuchAlgorithmException | UnrecoverableKeyException | KeyStoreException e) {
      e.printStackTrace();
      kmf = null;
      // throw exception
  }
  try {
      sslContext = SSLContext.getInstance("TLSv1.2");
      System.out.println(kmf==null); // prints false
      sslContext.init(kmf==null?null:kmf.getKeyManagers(), null, null);
  } catch (NoSuchAlgorithmException | KeyManagementException e) {
      // throw exception
  }
  
  try {
      serverSocket = sslContext.getServerSocketFactory().createServerSocket(PORT, BACKLOG, HOST);
      ((SSLServerSocket)serverSocket).setEnabledProtocols(new String[]{"TLSv1.2"});
  } catch (IOException e) {
      // throw exception
  }
  </code></pre>
  
  <p>the <code>loadKeyStore</code> function is, </p>
  
  <pre><code>private static KeyStore loadKeyStore(String filename) {
      KeyStore keystore = null;
      FileInputStream fis = null;
      try {
          keystore = KeyStore.getInstance("JKS");
          char[] psw = System.console().readPassword("Enter password for the KeyStore file \"%s\":", filename);
          if (psw != null) {
              fis = new FileInputStream(filename);
              keystore.load(fis, psw);
          }
      } catch (KeyStoreException | NoSuchAlgorithmException | CertificateException | IOException e) {
          keystore = null;
          LogManager.getLogger().fatal("cannot load KeyStore from file \"" + filename + "\".", e);
      } finally {
          if (fis != null) {
              try {
                  fis.close();
              } catch (IOException e) {
                  LogManager.getLogger().error("cannot close file " + filename, e);
              }
              fis = null;
          }
      }
      return keystore;
  }
  </code></pre>
  
  <p>I accept connections in a different thread as</p>
  
  <pre><code>while (!stopped) {
      Socket socket = null;
      try {
          socket = serverSocket.accept();
      } catch (IOException e) {
          if (!stopped) {
              logger.error("exception while accepting connections.", e);
          }
          break;
      }
      // start new threads to handle this connection
  }
  </code></pre>
  
  <p>The problem is, when I enter <a href="https://HOST:PORT" rel="nofollow noreferrer">https://HOST:PORT</a> at Firefox, it says:</p>
  
  <blockquote>
    <p>Firefox cannot guarantee the safety of your data on HOST because it
    uses <strong>SSLv3</strong>, a broken security protocol. Advanced info:
    ssl_error_no_cypher_overlap</p>
  </blockquote>
  
  <p>How can I open a server socket that accepts only TLSv1.2 connections?</p>
  
  <p>P.S. I have tried changing "TLSv1.2" strings in the code to "TLS", one by one, but nothing changed.</p>
  
  <p><strong>EDIT:</strong> I edited the code as follows:</p>
  
  <pre><code>serverSocket = sslContext.getServerSocketFactory().createServerSocket(port, backlog, host);
  ((SSLServerSocket)serverSocket).setEnabledProtocols(new String[]{"TLSv1.2"});
  for (String s: ((SSLServerSocket)serverSocket).getEnabledCipherSuites()) {
      System.out.println(s);
  }
  </code></pre>
  
  <p>and the output is,</p>
  
  <blockquote>
    <p>TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256
    TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256 TLS_RSA_WITH_AES_128_CBC_SHA256
    TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256
    TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256
    TLS_DHE_RSA_WITH_AES_128_CBC_SHA256
    TLS_DHE_DSS_WITH_AES_128_CBC_SHA256
    TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA
    TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA TLS_RSA_WITH_AES_128_CBC_SHA
    TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA TLS_ECDH_RSA_WITH_AES_128_CBC_SHA
    TLS_DHE_RSA_WITH_AES_128_CBC_SHA TLS_DHE_DSS_WITH_AES_128_CBC_SHA
    TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256
    TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 TLS_RSA_WITH_AES_128_GCM_SHA256
    TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256
    TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256
    TLS_DHE_RSA_WITH_AES_128_GCM_SHA256
    TLS_DHE_DSS_WITH_AES_128_GCM_SHA256
    TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA
    TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA SSL_RSA_WITH_3DES_EDE_CBC_SHA
    TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA
    TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA
    SSL_DHE_DSS_WITH_3DES_EDE_CBC_SHA TLS_ECDHE_ECDSA_WITH_RC4_128_SHA
    TLS_ECDHE_RSA_WITH_RC4_128_SHA SSL_RSA_WITH_RC4_128_SHA
    TLS_ECDH_ECDSA_WITH_RC4_128_SHA TLS_ECDH_RSA_WITH_RC4_128_SHA
    SSL_RSA_WITH_RC4_128_MD5 TLS_EMPTY_RENEGOTIATION_INFO_SCSV</p>
  </blockquote>
  
  <p>I am not sure, but it seems the problem is not about missing enabled cipher suites. Right?</p>
  
  <p><strong>EDIT2:</strong> I have tried <code>openssl s_client -connect HOST:PORT</code>, and the result is
  <img src="https://i.stack.imgur.com/PZMOa.png" alt="output"></p>