1 /* 2 * Copyright (C) 2016 The Android Open Source Project 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 */ 16 17 /* 18 * Copyright 2016 The Netty Project 19 * 20 * The Netty Project licenses this file to you under the Apache License, 21 * version 2.0 (the "License"); you may not use this file except in compliance 22 * with the License. You may obtain a copy of the License at: 23 * 24 * http://www.apache.org/licenses/LICENSE-2.0 25 * 26 * Unless required by applicable law or agreed to in writing, software 27 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 28 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 29 * License for the specific language governing permissions and limitations 30 * under the License. 31 */ 32 33 package org.conscrypt; 34 35 import static java.lang.Math.min; 36 import static org.conscrypt.NativeConstants.SSL3_RT_ALERT; 37 import static org.conscrypt.NativeConstants.SSL3_RT_APPLICATION_DATA; 38 import static org.conscrypt.NativeConstants.SSL3_RT_CHANGE_CIPHER_SPEC; 39 import static org.conscrypt.NativeConstants.SSL3_RT_HANDSHAKE; 40 import static org.conscrypt.NativeConstants.SSL3_RT_HEADER_LENGTH; 41 import static org.conscrypt.NativeConstants.SSL3_RT_MAX_PACKET_SIZE; 42 43 import java.nio.ByteBuffer; 44 import java.security.cert.CertificateEncodingException; 45 import java.security.cert.X509Certificate; 46 import java.util.HashSet; 47 import java.util.Set; 48 import javax.net.ssl.SSLException; 49 import javax.net.ssl.SSLHandshakeException; 50 import javax.net.ssl.SSLPeerUnverifiedException; 51 import javax.security.cert.CertificateException; 52 53 /** 54 * Utility methods for SSL packet processing. Copied from the Netty project. 55 * <p> 56 * This is a public class to allow testing to occur on Android via CTS. 57 */ 58 final class SSLUtils { 59 static final boolean USE_ENGINE_SOCKET_BY_DEFAULT = Boolean.parseBoolean( 60 System.getProperty("org.conscrypt.useEngineSocketByDefault", "false")); 61 private static final int MAX_PROTOCOL_LENGTH = 255; 62 63 // TODO(nathanmittler): Should these be in NativeConstants? 64 enum SessionType { 65 /** 66 * Identifies OpenSSL sessions. 67 */ 68 OPEN_SSL(1), 69 70 /** 71 * Identifies OpenSSL sessions with OCSP stapled data. 72 */ 73 OPEN_SSL_WITH_OCSP(2), 74 75 /** 76 * Identifies OpenSSL sessions with TLS SCT data. 77 */ 78 OPEN_SSL_WITH_TLS_SCT(3); 79 SessionType(int value)80 SessionType(int value) { 81 this.value = value; 82 } 83 isSupportedType(int type)84 static final boolean isSupportedType(int type) { 85 return type == OPEN_SSL.value || type == OPEN_SSL_WITH_OCSP.value 86 || type == OPEN_SSL_WITH_TLS_SCT.value; 87 } 88 89 final int value; 90 } 91 92 /** 93 * States for SSL engines. 94 */ 95 static final class EngineStates { EngineStates()96 private EngineStates() {} 97 98 /** 99 * The engine is constructed, but the initial handshake hasn't been started 100 */ 101 static final int STATE_NEW = 0; 102 103 /** 104 * The client/server mode of the engine has been set. 105 */ 106 static final int STATE_MODE_SET = 1; 107 108 /** 109 * The handshake has been started 110 */ 111 static final int STATE_HANDSHAKE_STARTED = 2; 112 113 /** 114 * Listeners of the handshake have been notified of completion but the handshake call 115 * hasn't returned. 116 */ 117 static final int STATE_HANDSHAKE_COMPLETED = 3; 118 119 /** 120 * The handshake call returned but the listeners have not yet been notified. This is expected 121 * behaviour in cut-through mode, where SSL_do_handshake returns before the handshake is 122 * complete. We can now start writing data to the socket. 123 */ 124 static final int STATE_READY_HANDSHAKE_CUT_THROUGH = 4; 125 126 /** 127 * The handshake call has returned and the listeners have been notified. Ready to begin 128 * writing data. 129 */ 130 static final int STATE_READY = 5; 131 132 /** 133 * The inbound direction of the engine has been closed. 134 */ 135 static final int STATE_CLOSED_INBOUND = 6; 136 137 /** 138 * The outbound direction of the engine has been closed. 139 */ 140 static final int STATE_CLOSED_OUTBOUND = 7; 141 142 /** 143 * The engine has been closed. 144 */ 145 static final int STATE_CLOSED = 8; 146 } 147 148 /** 149 * This is the maximum overhead when encrypting plaintext as defined by 150 * <a href="https://www.ietf.org/rfc/rfc5246.txt">rfc5264</a>, 151 * <a href="https://www.ietf.org/rfc/rfc5289.txt">rfc5289</a> and openssl implementation itself. 152 * 153 * Please note that we use a padding of 16 here as openssl uses PKC#5 which uses 16 bytes 154 * whilethe spec itself allow up to 255 bytes. 16 bytes is the max for PKC#5 (which handles it 155 * the same way as PKC#7) as we use a block size of 16. See <a 156 * href="https://tools.ietf.org/html/rfc5652#section-6.3">rfc5652#section-6.3</a>. 157 * 158 * 16 (IV) + 48 (MAC) + 1 (Padding_length field) + 15 (Padding) + 1 (ContentType) + 2 159 * (ProtocolVersion) + 2 (Length) 160 * 161 * TODO: We may need to review this calculation once TLS 1.3 becomes available. 162 */ 163 private static final int MAX_ENCRYPTION_OVERHEAD_LENGTH = 15 + 48 + 1 + 16 + 1 + 2 + 2; 164 165 private static final int MAX_ENCRYPTION_OVERHEAD_DIFF = 166 Integer.MAX_VALUE - MAX_ENCRYPTION_OVERHEAD_LENGTH; 167 168 /** Key type: RSA certificate. */ 169 private static final String KEY_TYPE_RSA = "RSA"; 170 171 /** Key type: Elliptic Curve certificate. */ 172 private static final String KEY_TYPE_EC = "EC"; 173 174 /** 175 * Returns key type constant suitable for calling X509KeyManager.chooseServerAlias or 176 * X509ExtendedKeyManager.chooseEngineServerAlias. Returns {@code null} for key exchanges that 177 * do not use X.509 for server authentication. 178 */ getServerX509KeyType(long sslCipherNative)179 static String getServerX509KeyType(long sslCipherNative) throws SSLException { 180 String kx_name = NativeCrypto.SSL_CIPHER_get_kx_name(sslCipherNative); 181 if (kx_name.equals("RSA") || kx_name.equals("DHE_RSA") || kx_name.equals("ECDHE_RSA")) { 182 return KEY_TYPE_RSA; 183 } else if (kx_name.equals("ECDHE_ECDSA")) { 184 return KEY_TYPE_EC; 185 } else { 186 return null; 187 } 188 } 189 190 /** 191 * Similar to getServerKeyType, but returns value given TLS 192 * ClientCertificateType byte values from a CertificateRequest 193 * message for use with X509KeyManager.chooseClientAlias or 194 * X509ExtendedKeyManager.chooseEngineClientAlias. 195 * <p> 196 * Visible for testing. 197 */ getClientKeyType(byte clientCertificateType)198 static String getClientKeyType(byte clientCertificateType) { 199 // See also http://www.ietf.org/assignments/tls-parameters/tls-parameters.xml 200 switch (clientCertificateType) { 201 case NativeConstants.TLS_CT_RSA_SIGN: 202 return KEY_TYPE_RSA; // RFC rsa_sign 203 case NativeConstants.TLS_CT_ECDSA_SIGN: 204 return KEY_TYPE_EC; // RFC ecdsa_sign 205 default: 206 return null; 207 } 208 } 209 210 /** 211 * Gets the supported key types for client certificates based on the 212 * {@code ClientCertificateType} values provided by the server. 213 * 214 * @param clientCertificateTypes {@code ClientCertificateType} values provided by the server. 215 * See https://www.ietf.org/assignments/tls-parameters/tls-parameters.xml. 216 * @return supported key types that can be used in {@code X509KeyManager.chooseClientAlias} and 217 * {@code X509ExtendedKeyManager.chooseEngineClientAlias}. 218 * 219 * Visible for testing. 220 */ getSupportedClientKeyTypes(byte[] clientCertificateTypes)221 static Set<String> getSupportedClientKeyTypes(byte[] clientCertificateTypes) { 222 Set<String> result = new HashSet<String>(clientCertificateTypes.length); 223 for (byte keyTypeCode : clientCertificateTypes) { 224 String keyType = SSLUtils.getClientKeyType(keyTypeCode); 225 if (keyType == null) { 226 // Unsupported client key type -- ignore 227 continue; 228 } 229 result.add(keyType); 230 } 231 return result; 232 } 233 encodeIssuerX509Principals(X509Certificate[] certificates)234 static byte[][] encodeIssuerX509Principals(X509Certificate[] certificates) 235 throws CertificateEncodingException { 236 byte[][] principalBytes = new byte[certificates.length][]; 237 for (int i = 0; i < certificates.length; i++) { 238 principalBytes[i] = certificates[i].getIssuerX500Principal().getEncoded(); 239 } 240 return principalBytes; 241 } 242 243 /** 244 * Converts the peer certificates into a cert chain. 245 */ toCertificateChain(X509Certificate[] certificates)246 static javax.security.cert.X509Certificate[] toCertificateChain(X509Certificate[] certificates) 247 throws SSLPeerUnverifiedException { 248 try { 249 javax.security.cert.X509Certificate[] chain = 250 new javax.security.cert.X509Certificate[certificates.length]; 251 252 for (int i = 0; i < certificates.length; i++) { 253 byte[] encoded = certificates[i].getEncoded(); 254 chain[i] = javax.security.cert.X509Certificate.getInstance(encoded); 255 } 256 return chain; 257 } catch (CertificateEncodingException e) { 258 SSLPeerUnverifiedException exception = new SSLPeerUnverifiedException(e.getMessage()); 259 exception.initCause(exception); 260 throw exception; 261 } catch (CertificateException e) { 262 SSLPeerUnverifiedException exception = new SSLPeerUnverifiedException(e.getMessage()); 263 exception.initCause(exception); 264 throw exception; 265 } 266 } 267 268 /** 269 * Calculates the minimum bytes required in the encrypted output buffer for the given number of 270 * plaintext source bytes. 271 */ calculateOutNetBufSize(int pendingBytes)272 static int calculateOutNetBufSize(int pendingBytes) { 273 return min(SSL3_RT_MAX_PACKET_SIZE, 274 MAX_ENCRYPTION_OVERHEAD_LENGTH + min(MAX_ENCRYPTION_OVERHEAD_DIFF, pendingBytes)); 275 } 276 277 /** 278 * Wraps the given exception if it's not already a {@link SSLHandshakeException}. 279 */ toSSLHandshakeException(Throwable e)280 static SSLHandshakeException toSSLHandshakeException(Throwable e) { 281 if (e instanceof SSLHandshakeException) { 282 return (SSLHandshakeException) e; 283 } 284 285 return (SSLHandshakeException) new SSLHandshakeException(e.getMessage()).initCause(e); 286 } 287 288 /** 289 * Wraps the given exception if it's not already a {@link SSLException}. 290 */ toSSLException(Throwable e)291 static SSLException toSSLException(Throwable e) { 292 if (e instanceof SSLException) { 293 return (SSLException) e; 294 } 295 return new SSLException(e); 296 } 297 298 /** 299 * Return how much bytes can be read out of the encrypted data. Be aware that this method will 300 * not 301 * increase the readerIndex of the given {@link ByteBuffer}. 302 * 303 * @param buffers The {@link ByteBuffer}s to read from. Be aware that they must have at least 304 * {@link org.conscrypt.NativeConstants#SSL3_RT_HEADER_LENGTH} bytes to read, otherwise it will 305 * throw an {@link IllegalArgumentException}. 306 * @return length The length of the encrypted packet that is included in the buffer. This will 307 * return {@code -1} if the given {@link ByteBuffer} is not encrypted at all. 308 * @throws IllegalArgumentException Is thrown if the given {@link ByteBuffer} has not at least 309 * {@link org.conscrypt.NativeConstants#SSL3_RT_HEADER_LENGTH} bytes to read. 310 */ getEncryptedPacketLength(ByteBuffer[] buffers, int offset)311 static int getEncryptedPacketLength(ByteBuffer[] buffers, int offset) { 312 ByteBuffer buffer = buffers[offset]; 313 314 // Check if everything we need is in one ByteBuffer. If so we can make use of the fast-path. 315 if (buffer.remaining() >= SSL3_RT_HEADER_LENGTH) { 316 return getEncryptedPacketLength(buffer); 317 } 318 319 // We need to copy 5 bytes into a temporary buffer so we can parse out the packet length 320 // easily. 321 ByteBuffer tmp = ByteBuffer.allocate(SSL3_RT_HEADER_LENGTH); 322 do { 323 buffer = buffers[offset++]; 324 int pos = buffer.position(); 325 int limit = buffer.limit(); 326 if (buffer.remaining() > tmp.remaining()) { 327 buffer.limit(pos + tmp.remaining()); 328 } 329 try { 330 tmp.put(buffer); 331 } finally { 332 // Restore the original indices. 333 buffer.limit(limit); 334 buffer.position(pos); 335 } 336 } while (tmp.hasRemaining()); 337 338 // Done, flip the buffer so we can read from it. 339 tmp.flip(); 340 return getEncryptedPacketLength(tmp); 341 } 342 343 /** 344 * Encodes a list of protocols into the wire-format (length-prefixed 8-bit strings). 345 * Requires that all strings be encoded with US-ASCII. 346 * 347 * @param protocols the list of protocols to be encoded 348 * @return the encoded form of the protocol list. 349 */ toLengthPrefixedList(String... protocols)350 static byte[] toLengthPrefixedList(String... protocols) { 351 // Calculate the encoded length. 352 int length = 0; 353 for (int i = 0; i < protocols.length; ++i) { 354 int protocolLength = protocols[i].length(); 355 356 // Verify that the length is valid here, so that we don't attempt to allocate an array 357 // below if the threshold is violated. 358 if (protocolLength == 0 || protocolLength > MAX_PROTOCOL_LENGTH) { 359 throw new IllegalArgumentException("Protocol has invalid length (" 360 + protocolLength + "): " + protocols[i]); 361 } 362 363 // Include a 1-byte prefix for each protocol. 364 length += 1 + protocolLength; 365 } 366 367 byte[] data = new byte[length]; 368 for (int dataIndex = 0, i = 0; i < protocols.length; ++i) { 369 String protocol = protocols[i]; 370 int protocolLength = protocol.length(); 371 372 // Add the length prefix. 373 data[dataIndex++] = (byte) protocolLength; 374 for (int ci = 0; ci < protocolLength; ++ci) { 375 char c = protocol.charAt(ci); 376 if (c > Byte.MAX_VALUE) { 377 // Enforce US-ASCII 378 throw new IllegalArgumentException("Protocol contains invalid character: " 379 + c + "(protocol=" + protocol + ")"); 380 } 381 data[dataIndex++] = (byte) c; 382 } 383 } 384 return data; 385 } 386 getEncryptedPacketLength(ByteBuffer buffer)387 private static int getEncryptedPacketLength(ByteBuffer buffer) { 388 int packetLength = 0; 389 int pos = buffer.position(); 390 // SSLv3 or TLS - Check ContentType 391 switch (unsignedByte(buffer.get(pos))) { 392 case SSL3_RT_CHANGE_CIPHER_SPEC: 393 case SSL3_RT_ALERT: 394 case SSL3_RT_HANDSHAKE: 395 case SSL3_RT_APPLICATION_DATA: 396 break; 397 default: 398 // SSLv2 or bad data 399 return -1; 400 } 401 402 // SSLv3 or TLS - Check ProtocolVersion 403 int majorVersion = unsignedByte(buffer.get(pos + 1)); 404 if (majorVersion != 3) { 405 // Neither SSLv3 or TLSv1 (i.e. SSLv2 or bad data) 406 return -1; 407 } 408 409 // SSLv3 or TLS 410 packetLength = unsignedShort(buffer.getShort(pos + 3)) + SSL3_RT_HEADER_LENGTH; 411 if (packetLength <= SSL3_RT_HEADER_LENGTH) { 412 // Neither SSLv3 or TLSv1 (i.e. SSLv2 or bad data) 413 return -1; 414 } 415 return packetLength; 416 } 417 unsignedByte(byte b)418 private static short unsignedByte(byte b) { 419 return (short) (b & 0xFF); 420 } 421 unsignedShort(short s)422 private static int unsignedShort(short s) { 423 return s & 0xFFFF; 424 } 425 SSLUtils()426 private SSLUtils() {} 427 } 428