/** * Returns server ssl engine. * * @param context - SSLContext to get SSLEngine from. * @param useSNI - flag used to enable or disable using SNI extension. * Needed for Kerberos. */ public static SSLEngine getServerSSLEngine( SSLContext context, boolean useSNI) { SSLEngine serverEngine = context.createSSLEngine(); serverEngine.setUseClientMode(false); if (useSNI) { SNIMatcher matcher = SNIHostName.createSNIMatcher(SNI_PATTERN); List<SNIMatcher> matchers = new ArrayList<>(); matchers.add(matcher); SSLParameters params = serverEngine.getSSLParameters(); params.setSNIMatchers(matchers); serverEngine.setSSLParameters(params); } return serverEngine; }
@Override public String chooseServerAlias(String keyType, Principal[] issuers, Socket socket) { if (!keyType.equals("RSA") || !(socket instanceof SSLSocket)) return null; SSLSocket sslSocket = (SSLSocket) socket; SSLParameters params = sslSocket.getSSLParameters(); Iterator<SNIMatcher> it = params.getSNIMatchers().iterator(); if (!it.hasNext()) { return "default.example.com"; } SniHostnameMatcher matcher = (SniHostnameMatcher) it.next(); if (matcher.isSniEnabled()) { return matcher.getSniHostname(); } else { return "default.example.com"; } }
boolean isMatched(Collection<SNIMatcher> matchers) { if (sniMap != null && !sniMap.isEmpty()) { for (SNIMatcher matcher : matchers) { SNIServerName sniName = sniMap.get(matcher.getType()); if (sniName != null && (!matcher.matches(sniName))) { return false; } } } return true; }
/** * Applies SSLParameters to newly accepted connections. */ @Override synchronized public void setSSLParameters(SSLParameters params) { super.setSSLParameters(params); // the super implementation does not handle the following parameters identificationProtocol = params.getEndpointIdentificationAlgorithm(); algorithmConstraints = params.getAlgorithmConstraints(); preferLocalCipherSuites = params.getUseCipherSuitesOrder(); Collection<SNIMatcher> matchers = params.getSNIMatchers(); if (matchers != null) { sniMatchers = params.getSNIMatchers(); } }
static SSLEchoServer init(String cipherSuiteFilter, String sniPattern) throws NoSuchAlgorithmException, IOException { SSLContext context = SSLContext.getDefault(); SSLServerSocketFactory ssf = (SSLServerSocketFactory) context.getServerSocketFactory(); SSLServerSocket ssocket = (SSLServerSocket) ssf.createServerSocket(0); // specify enabled cipher suites if (cipherSuiteFilter != null) { String[] ciphersuites = UnboundSSLUtils.filterStringArray( ssf.getSupportedCipherSuites(), cipherSuiteFilter); System.out.println("Server: enabled cipher suites: " + Arrays.toString(ciphersuites)); ssocket.setEnabledCipherSuites(ciphersuites); } // specify SNI matcher pattern if (sniPattern != null) { System.out.println("Server: set SNI matcher: " + sniPattern); SNIMatcher matcher = SNIHostName.createSNIMatcher(sniPattern); List<SNIMatcher> matchers = new ArrayList<>(); matchers.add(matcher); SSLParameters params = ssocket.getSSLParameters(); params.setSNIMatchers(matchers); ssocket.setSSLParameters(params); } return new SSLEchoServer(ssocket); }
/** * Applies SSLParameters to newly accepted connections. */ @Override public synchronized void setSSLParameters(SSLParameters params) { super.setSSLParameters(params); // the super implementation does not handle the following parameters identificationProtocol = params.getEndpointIdentificationAlgorithm(); algorithmConstraints = params.getAlgorithmConstraints(); preferLocalCipherSuites = params.getUseCipherSuitesOrder(); Collection<SNIMatcher> matchers = params.getSNIMatchers(); if (matchers != null) { sniMatchers = params.getSNIMatchers(); } applicationProtocols = params.getApplicationProtocols(); }
/** * Returns server ssl engine. * * @param context - SSLContext to get SSLEngine from. * @param useSNI - flag used to enable or disable using SNI extension. * Needed for Kerberos. */ public static SSLEngine getServerSSLEngine(SSLContext context, boolean useSNI) { SSLEngine serverEngine = context.createSSLEngine(); serverEngine.setUseClientMode(false); if (useSNI) { SNIMatcher matcher = SNIHostName.createSNIMatcher(SNI_PATTERN); List<SNIMatcher> matchers = new ArrayList<>(); matchers.add(matcher); SSLParameters params = serverEngine.getSSLParameters(); params.setSNIMatchers(matchers); serverEngine.setSSLParameters(params); } return serverEngine; }
@Test public void test_SSLParameters_setSNIMatchers_duplicatedNameThrows() throws Exception { TestUtils.assumeSNIHostnameAvailable(); SSLParameters p = new SSLParameters(); ArrayList<SNIMatcher> dupeMatchers = new ArrayList<SNIMatcher>(); dupeMatchers.add(SNIHostName.createSNIMatcher("www\\.example\\.com")); dupeMatchers.add(SNIHostName.createSNIMatcher("www\\.example\\.com")); try { p.setSNIMatchers(dupeMatchers); fail("Should throw IllegalArgumentException when matchers are duplicated"); } catch (IllegalArgumentException expected) { // Ignored. } }
@Test public void test_SSLParameters_setSNIMatchers_setEmpty_getEmpty() throws Exception { TestUtils.assumeSNIHostnameAvailable(); SSLParameters p = new SSLParameters(); p.setSNIMatchers( Collections.singletonList(SNIHostName.createSNIMatcher("www\\.example\\.com"))); assertEquals(1, p.getSNIMatchers().size()); p.setSNIMatchers(Collections.<SNIMatcher>emptyList()); Collection<SNIMatcher> actual = p.getSNIMatchers(); assertNotNull(actual); assertEquals(0, actual.size()); }
@Test public void test_SSLParameters_getSNIMatchers_unmodifiable() throws Exception { TestUtils.assumeSNIHostnameAvailable(); SSLParameters p = new SSLParameters(); p.setSNIMatchers( Collections.singletonList(SNIHostName.createSNIMatcher("www\\.example\\.com"))); Collection<SNIMatcher> actual = p.getSNIMatchers(); try { actual.add(SNIHostName.createSNIMatcher("www\\.google\\.com")); fail("Should not allow modification of list"); } catch (UnsupportedOperationException expected) { // Ignored. } }