1 /* 2 * Copyright (C) 2017 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 package org.conscrypt; 18 19 import static org.conscrypt.TestUtils.UTF_8; 20 import static org.junit.Assert.assertArrayEquals; 21 import static org.junit.Assert.assertEquals; 22 import static org.junit.Assert.assertNull; 23 24 import java.util.Arrays; 25 import java.util.HashSet; 26 import org.junit.Test; 27 import org.junit.runner.RunWith; 28 import org.junit.runners.JUnit4; 29 30 @RunWith(JUnit4.class) 31 public class SSLUtilsTest { 32 private static final byte[] VALID_CHARACTERS = 33 "0123456789abcdefghijklmnopqrstuvwxyz".getBytes(UTF_8); 34 35 @Test 36 public void noProtocolsShouldSucceed() { 37 byte[] expected = new byte[0]; 38 byte[] actual = SSLUtils.encodeProtocols(EmptyArray.STRING); 39 assertArrayEquals(expected, actual); 40 } 41 42 @Test(expected = IllegalArgumentException.class) 43 public void emptyProtocolShouldThrow() { 44 SSLUtils.encodeProtocols(new String[] {""}); 45 } 46 47 @Test(expected = IllegalArgumentException.class) 48 public void longProtocolShouldThrow() { 49 SSLUtils.encodeProtocols(new String[] {new String(newValidProtocol(256), UTF_8)}); 50 } 51 52 @Test(expected = IllegalArgumentException.class) 53 public void protocolWithInvalidCharacterShouldThrow() { 54 SSLUtils.encodeProtocols(new String[] {"This is a bad character: "}); 55 } 56 57 @Test 58 public void encodeProtocolsShouldSucceed() { 59 byte[][] protocols = new byte[][]{ 60 "protocol-1".getBytes(UTF_8), 61 "protocol-2".getBytes(UTF_8), 62 "protocol-3".getBytes(UTF_8), 63 }; 64 byte[] expected = getExpectedEncodedBytes(protocols); 65 byte[] actual = SSLUtils.encodeProtocols(toStrings(protocols)); 66 assertArrayEquals(expected, actual); 67 } 68 69 @Test(expected = NullPointerException.class) 70 public void decodeNullProtocolsShouldThrow() { 71 SSLUtils.decodeProtocols(null); 72 } 73 74 @Test 75 public void decodeEmptyProtocolsShouldSucceed() { 76 assertArrayEquals(EmptyArray.STRING, SSLUtils.decodeProtocols(EmptyArray.BYTE)); 77 } 78 79 @Test 80 public void decodeProtocolsShouldSucceed() { 81 byte[][] protocols = new byte[][]{ 82 "protocol-1".getBytes(UTF_8), 83 "protocol-2".getBytes(UTF_8), 84 "protocol-3".getBytes(UTF_8), 85 }; 86 byte[] encoded = getExpectedEncodedBytes(protocols); 87 String[] strings = SSLUtils.decodeProtocols(encoded); 88 assertArrayEquals(toStrings(protocols), strings); 89 } 90 91 @Test 92 public void testGetClientKeyType() throws Exception { 93 // See http://www.ietf.org/assignments/tls-parameters/tls-parameters.xml 94 byte b = Byte.MIN_VALUE; 95 do { 96 String byteString = Byte.toString(b); 97 String keyType = SSLUtils.getClientKeyType(b); 98 switch (b) { 99 case 1: 100 assertEquals(byteString, "RSA", keyType); 101 break; 102 case 64: 103 assertEquals(byteString, "EC", keyType); 104 break; 105 default: 106 assertNull(byteString, keyType); 107 } 108 b++; 109 } while (b != Byte.MIN_VALUE); 110 } 111 112 @Test 113 public void testGetSupportedClientKeyTypes() throws Exception { 114 // Create an array with all possible values. Also, duplicate all values. 115 byte[] allClientCertificateTypes = new byte[512]; 116 for (int i = 0; i < allClientCertificateTypes.length; i++) { 117 allClientCertificateTypes[i] = (byte) i; 118 } 119 assertEquals(new HashSet<String>(Arrays.asList("RSA", "EC")), 120 SSLUtils.getSupportedClientKeyTypes(allClientCertificateTypes)); 121 } 122 123 private static String[] toStrings(byte[][] protocols) { 124 int numProtocols = protocols.length; 125 String[] out = new String[numProtocols]; 126 for(int i = 0; i < numProtocols; ++i) { 127 out[i] = new String(protocols[i], UTF_8); 128 } 129 return out; 130 } 131 132 private static byte[] getExpectedEncodedBytes(byte[][] protocols) { 133 int numProtocols = protocols.length; 134 int encodedLength = numProtocols; 135 for (byte[] protocol : protocols) { 136 encodedLength += protocol.length; 137 } 138 byte[] encoded = new byte[encodedLength]; 139 for(int encodedIndex = 0, i = 0; i < numProtocols; ++i) { 140 byte[] protocol = protocols[i]; 141 encoded[encodedIndex++] = (byte) protocol.length; 142 System.arraycopy(protocol, 0, encoded, encodedIndex, protocol.length); 143 encodedIndex += protocol.length; 144 } 145 return encoded; 146 } 147 148 private static byte[] newValidProtocol(int length) { 149 byte[] chars = new byte[length]; 150 for (int i = 0; i < length; ++i) { 151 int charIndex = i % VALID_CHARACTERS.length; 152 chars[i] = VALID_CHARACTERS[charIndex]; 153 } 154 return chars; 155 } 156 } 157