1/* 2 * Copyright (C) 2015 Square, Inc. 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16package com.squareup.okhttp; 17 18import org.junit.Test; 19 20import java.util.Arrays; 21import java.util.LinkedHashSet; 22import java.util.Set; 23import javax.net.ssl.SSLSocket; 24import javax.net.ssl.SSLSocketFactory; 25 26import static org.junit.Assert.assertEquals; 27import static org.junit.Assert.assertFalse; 28import static org.junit.Assert.assertNull; 29import static org.junit.Assert.assertTrue; 30 31public final class ConnectionSpecTest { 32 33 @Test 34 public void cleartextBuilder() throws Exception { 35 ConnectionSpec cleartextSpec = new ConnectionSpec.Builder(false).build(); 36 assertFalse(cleartextSpec.isTls()); 37 } 38 39 @Test 40 public void tlsBuilder_explicitCiphers() throws Exception { 41 ConnectionSpec tlsSpec = new ConnectionSpec.Builder(true) 42 .cipherSuites(CipherSuite.TLS_RSA_WITH_RC4_128_MD5) 43 .tlsVersions(TlsVersion.TLS_1_2) 44 .supportsTlsExtensions(true) 45 .build(); 46 assertEquals(Arrays.asList(CipherSuite.TLS_RSA_WITH_RC4_128_MD5), tlsSpec.cipherSuites()); 47 assertEquals(Arrays.asList(TlsVersion.TLS_1_2), tlsSpec.tlsVersions()); 48 assertTrue(tlsSpec.supportsTlsExtensions()); 49 } 50 51 @Test 52 public void tlsBuilder_defaultCiphers() throws Exception { 53 ConnectionSpec tlsSpec = new ConnectionSpec.Builder(true) 54 .tlsVersions(TlsVersion.TLS_1_2) 55 .supportsTlsExtensions(true) 56 .build(); 57 assertNull(tlsSpec.cipherSuites()); 58 assertEquals(Arrays.asList(TlsVersion.TLS_1_2), tlsSpec.tlsVersions()); 59 assertTrue(tlsSpec.supportsTlsExtensions()); 60 } 61 62 @Test 63 public void tls_defaultCiphers_noFallbackIndicator() throws Exception { 64 ConnectionSpec tlsSpec = new ConnectionSpec.Builder(true) 65 .tlsVersions(TlsVersion.TLS_1_2) 66 .supportsTlsExtensions(false) 67 .build(); 68 69 SSLSocket socket = (SSLSocket) SSLSocketFactory.getDefault().createSocket(); 70 socket.setEnabledCipherSuites(new String[] { 71 CipherSuite.TLS_RSA_WITH_RC4_128_MD5.javaName, 72 CipherSuite.TLS_RSA_WITH_RC4_128_SHA.javaName, 73 }); 74 socket.setEnabledProtocols(new String[] { 75 TlsVersion.TLS_1_2.javaName, 76 TlsVersion.TLS_1_1.javaName, 77 }); 78 79 assertTrue(tlsSpec.isCompatible(socket)); 80 tlsSpec.apply(socket, false /* isFallback */); 81 82 assertEquals(createSet(TlsVersion.TLS_1_2.javaName), createSet(socket.getEnabledProtocols())); 83 84 Set<String> expectedCipherSet = 85 createSet( 86 CipherSuite.TLS_RSA_WITH_RC4_128_MD5.javaName, 87 CipherSuite.TLS_RSA_WITH_RC4_128_SHA.javaName); 88 assertEquals(expectedCipherSet, expectedCipherSet); 89 } 90 91 @Test 92 public void tls_defaultCiphers_withFallbackIndicator() throws Exception { 93 ConnectionSpec tlsSpec = new ConnectionSpec.Builder(true) 94 .tlsVersions(TlsVersion.TLS_1_2) 95 .supportsTlsExtensions(false) 96 .build(); 97 98 SSLSocket socket = (SSLSocket) SSLSocketFactory.getDefault().createSocket(); 99 socket.setEnabledCipherSuites(new String[] { 100 CipherSuite.TLS_RSA_WITH_RC4_128_MD5.javaName, 101 CipherSuite.TLS_RSA_WITH_RC4_128_SHA.javaName, 102 }); 103 socket.setEnabledProtocols(new String[] { 104 TlsVersion.TLS_1_2.javaName, 105 TlsVersion.TLS_1_1.javaName, 106 }); 107 108 assertTrue(tlsSpec.isCompatible(socket)); 109 tlsSpec.apply(socket, true /* isFallback */); 110 111 assertEquals(createSet(TlsVersion.TLS_1_2.javaName), createSet(socket.getEnabledProtocols())); 112 113 Set<String> expectedCipherSet = 114 createSet( 115 CipherSuite.TLS_RSA_WITH_RC4_128_MD5.javaName, 116 CipherSuite.TLS_RSA_WITH_RC4_128_SHA.javaName); 117 if (Arrays.asList(socket.getSupportedCipherSuites()).contains("TLS_FALLBACK_SCSV")) { 118 expectedCipherSet.add("TLS_FALLBACK_SCSV"); 119 } 120 assertEquals(expectedCipherSet, expectedCipherSet); 121 } 122 123 @Test 124 public void tls_explicitCiphers() throws Exception { 125 ConnectionSpec tlsSpec = new ConnectionSpec.Builder(true) 126 .cipherSuites(CipherSuite.TLS_RSA_WITH_RC4_128_MD5) 127 .tlsVersions(TlsVersion.TLS_1_2) 128 .supportsTlsExtensions(false) 129 .build(); 130 131 SSLSocket socket = (SSLSocket) SSLSocketFactory.getDefault().createSocket(); 132 socket.setEnabledCipherSuites(new String[] { 133 CipherSuite.TLS_RSA_WITH_RC4_128_MD5.javaName, 134 CipherSuite.TLS_RSA_WITH_RC4_128_SHA.javaName, 135 }); 136 socket.setEnabledProtocols(new String[] { 137 TlsVersion.TLS_1_2.javaName, 138 TlsVersion.TLS_1_1.javaName, 139 }); 140 141 assertTrue(tlsSpec.isCompatible(socket)); 142 tlsSpec.apply(socket, true /* isFallback */); 143 144 assertEquals(createSet(TlsVersion.TLS_1_2.javaName), createSet(socket.getEnabledProtocols())); 145 146 Set<String> expectedCipherSet = createSet(CipherSuite.TLS_RSA_WITH_RC4_128_MD5.javaName); 147 if (Arrays.asList(socket.getSupportedCipherSuites()).contains("TLS_FALLBACK_SCSV")) { 148 expectedCipherSet.add("TLS_FALLBACK_SCSV"); 149 } 150 assertEquals(expectedCipherSet, expectedCipherSet); 151 } 152 153 @Test 154 public void tls_stringCiphersAndVersions() throws Exception { 155 // Supporting arbitrary input strings allows users to enable suites and versions that are not 156 // yet known to the library, but are supported by the platform. 157 ConnectionSpec tlsSpec = new ConnectionSpec.Builder(ConnectionSpec.MODERN_TLS) 158 .cipherSuites("MAGIC-CIPHER") 159 .tlsVersions("TLS9k") 160 .build(); 161 } 162 163 public void tls_missingRequiredCipher() throws Exception { 164 ConnectionSpec tlsSpec = new ConnectionSpec.Builder(true) 165 .cipherSuites(CipherSuite.TLS_RSA_WITH_RC4_128_MD5) 166 .tlsVersions(TlsVersion.TLS_1_2) 167 .supportsTlsExtensions(false) 168 .build(); 169 170 SSLSocket socket = (SSLSocket) SSLSocketFactory.getDefault().createSocket(); 171 socket.setEnabledProtocols(new String[] { 172 TlsVersion.TLS_1_2.javaName, 173 TlsVersion.TLS_1_1.javaName, 174 }); 175 176 socket.setEnabledCipherSuites(new String[] { 177 CipherSuite.TLS_RSA_WITH_RC4_128_SHA.javaName, 178 CipherSuite.TLS_RSA_WITH_RC4_128_MD5.javaName, 179 }); 180 assertTrue(tlsSpec.isCompatible(socket)); 181 182 socket.setEnabledCipherSuites(new String[] { 183 CipherSuite.TLS_RSA_WITH_RC4_128_SHA.javaName, 184 }); 185 assertFalse(tlsSpec.isCompatible(socket)); 186 } 187 188 @Test 189 public void tls_missingTlsVersion() throws Exception { 190 ConnectionSpec tlsSpec = new ConnectionSpec.Builder(true) 191 .cipherSuites(CipherSuite.TLS_RSA_WITH_RC4_128_MD5) 192 .tlsVersions(TlsVersion.TLS_1_2) 193 .supportsTlsExtensions(false) 194 .build(); 195 196 SSLSocket socket = (SSLSocket) SSLSocketFactory.getDefault().createSocket(); 197 socket.setEnabledCipherSuites(new String[] { 198 CipherSuite.TLS_RSA_WITH_RC4_128_MD5.javaName, 199 }); 200 201 socket.setEnabledProtocols( 202 new String[] { TlsVersion.TLS_1_2.javaName, TlsVersion.TLS_1_1.javaName }); 203 assertTrue(tlsSpec.isCompatible(socket)); 204 205 socket.setEnabledProtocols(new String[] { TlsVersion.TLS_1_1.javaName }); 206 assertFalse(tlsSpec.isCompatible(socket)); 207 } 208 209 private static Set<String> createSet(String... values) { 210 return new LinkedHashSet<String>(Arrays.asList(values)); 211 } 212} 213