1 /* 2 * Copyright (c) 2012, 2018, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. Oracle designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Oracle in the LICENSE file that accompanied this code. 10 * 11 * This code is distributed in the hope that it will be useful, but WITHOUT 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 * version 2 for more details (a copy is included in the LICENSE file that 15 * accompanied this code). 16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 26 package sun.security.ssl; 27 28 import java.nio.ByteBuffer; 29 import java.security.InvalidKeyException; 30 import java.security.NoSuchAlgorithmException; 31 import java.util.Arrays; 32 import javax.crypto.Mac; 33 import javax.crypto.SecretKey; 34 import sun.security.ssl.CipherSuite.MacAlg; 35 36 /** 37 * This class represents an SSL/TLS message authentication token, 38 * which encapsulates a sequence number and ensures that attempts to 39 * delete or reorder messages can be detected. 40 */ 41 abstract class Authenticator { 42 // byte array containing the additional authentication information for 43 // each record 44 protected final byte[] block; // at least 8 bytes for sequence number 45 Authenticator(byte[] block)46 private Authenticator(byte[] block) { 47 this.block = block; 48 } 49 50 /** 51 * Constructs the message authentication token for the specified 52 * SSL/TLS protocol. 53 */ valueOf(ProtocolVersion protocolVersion)54 static Authenticator valueOf(ProtocolVersion protocolVersion) { 55 if (protocolVersion.useTLS13PlusSpec()) { 56 return new TLS13Authenticator(protocolVersion); 57 } else if (protocolVersion.useTLS10PlusSpec()) { 58 return new TLS10Authenticator(protocolVersion); 59 } else { 60 return new SSL30Authenticator(); 61 } 62 } 63 64 @SuppressWarnings({"unchecked"}) 65 static <T extends Authenticator & MAC> T valueOf(ProtocolVersion protocolVersion, MacAlg macAlg, SecretKey key)66 valueOf(ProtocolVersion protocolVersion, MacAlg macAlg, 67 SecretKey key) throws NoSuchAlgorithmException, 68 InvalidKeyException { 69 if (protocolVersion.useTLS13PlusSpec()) { 70 throw new RuntimeException("No MacAlg used in TLS 1.3"); 71 } else if (protocolVersion.useTLS10PlusSpec()) { 72 return (T)(new TLS10Mac(protocolVersion, macAlg, key)); 73 } else { 74 return (T)(new SSL30Mac(protocolVersion, macAlg, key)); 75 } 76 } 77 nullTlsMac()78 static Authenticator nullTlsMac() { 79 return new SSLNullMac(); 80 } 81 82 /** 83 * Checks whether the sequence number is close to wrap. 84 * 85 * Sequence numbers are of type uint64 and may not exceed 2^64-1. 86 * Sequence numbers do not wrap. When the sequence number is near 87 * to wrap, we need to close the connection immediately. 88 * 89 * @return true if the sequence number is close to wrap 90 */ seqNumOverflow()91 abstract boolean seqNumOverflow(); 92 93 /** 94 * Checks whether the sequence number close to renew. 95 * 96 * Sequence numbers are of type uint64 and may not exceed 2^64-1. 97 * Sequence numbers do not wrap. If a TLS 98 * implementation would need to wrap a sequence number, it must 99 * renegotiate instead. 100 * 101 * @return true if the sequence number is huge enough to renew 102 */ seqNumIsHuge()103 abstract boolean seqNumIsHuge(); 104 105 /** 106 * Gets the current sequence number. 107 * 108 * @return the byte array of the current sequence number 109 */ sequenceNumber()110 final byte[] sequenceNumber() { 111 return Arrays.copyOf(block, 8); 112 } 113 114 /** 115 * Increase the sequence number. 116 */ increaseSequenceNumber()117 final void increaseSequenceNumber() { 118 /* 119 * The sequence number in the block array is a 64-bit 120 * number stored in big-endian format. 121 */ 122 int k = 7; 123 while ((k >= 0) && (++block[k] == 0)) { 124 k--; 125 } 126 } 127 128 /** 129 * Acquires the current message authentication information with the 130 * specified record type and fragment length, and then increases the 131 * sequence number if using implicit sequence number. 132 * 133 * @param type the record type 134 * @param length the fragment of the record 135 * @param sequence the explicit sequence number of the record 136 * 137 * @return the byte array of the current message authentication information 138 */ acquireAuthenticationBytes( byte type, int length, byte[] sequence)139 byte[] acquireAuthenticationBytes( 140 byte type, int length, byte[] sequence) { 141 throw new UnsupportedOperationException("Used by AEAD algorithms only"); 142 } 143 144 private static class SSLAuthenticator extends Authenticator { SSLAuthenticator(byte[] block)145 private SSLAuthenticator(byte[] block) { 146 super(block); 147 } 148 149 @Override seqNumOverflow()150 boolean seqNumOverflow() { 151 /* 152 * Conservatively, we don't allow more records to be generated 153 * when there are only 2^8 sequence numbers left. 154 */ 155 return (block.length != 0 && 156 block[0] == (byte)0xFF && block[1] == (byte)0xFF && 157 block[2] == (byte)0xFF && block[3] == (byte)0xFF && 158 block[4] == (byte)0xFF && block[5] == (byte)0xFF && 159 block[6] == (byte)0xFF); 160 } 161 162 @Override seqNumIsHuge()163 boolean seqNumIsHuge() { 164 return (block.length != 0 && 165 block[0] == (byte)0xFF && block[1] == (byte)0xFF && 166 block[2] == (byte)0xFF && block[3] == (byte)0xFF); 167 } 168 } 169 170 // For null MAC only. 171 private static class SSLNullAuthenticator extends SSLAuthenticator { SSLNullAuthenticator()172 private SSLNullAuthenticator() { 173 super(new byte[8]); 174 } 175 } 176 177 // For SSL 3.0 178 private static class SSL30Authenticator extends SSLAuthenticator { 179 // Block size of SSL v3.0: 180 // sequence number + record type + + record length 181 private static final int BLOCK_SIZE = 11; // 8 + 1 + 2 182 SSL30Authenticator()183 private SSL30Authenticator() { 184 super(new byte[BLOCK_SIZE]); 185 } 186 187 @Override acquireAuthenticationBytes( byte type, int length, byte[] sequence)188 byte[] acquireAuthenticationBytes( 189 byte type, int length, byte[] sequence) { 190 byte[] ad = block.clone(); 191 192 // Increase the implicit sequence number in the block array. 193 increaseSequenceNumber(); 194 195 ad[8] = type; 196 ad[9] = (byte)(length >> 8); 197 ad[10] = (byte)(length); 198 199 return ad; 200 } 201 } 202 203 // For TLS 1.0 - 1.2 204 private static class TLS10Authenticator extends SSLAuthenticator { 205 // Block size of TLS v1.0/1.1/1.2. 206 // sequence number + record type + protocol version + record length 207 private static final int BLOCK_SIZE = 13; // 8 + 1 + 2 + 2 208 TLS10Authenticator(ProtocolVersion protocolVersion)209 private TLS10Authenticator(ProtocolVersion protocolVersion) { 210 super(new byte[BLOCK_SIZE]); 211 block[9] = protocolVersion.major; 212 block[10] = protocolVersion.minor; 213 } 214 215 @Override acquireAuthenticationBytes( byte type, int length, byte[] sequence)216 byte[] acquireAuthenticationBytes( 217 byte type, int length, byte[] sequence) { 218 byte[] ad = block.clone(); 219 if (sequence != null) { 220 if (sequence.length != 8) { 221 throw new RuntimeException( 222 "Insufficient explicit sequence number bytes"); 223 } 224 225 System.arraycopy(sequence, 0, ad, 0, sequence.length); 226 } else { // Otherwise, use the implicit sequence number. 227 // Increase the implicit sequence number in the block array. 228 increaseSequenceNumber(); 229 } 230 231 ad[8] = type; 232 ad[11] = (byte)(length >> 8); 233 ad[12] = (byte)(length); 234 235 return ad; 236 } 237 } 238 239 // For TLS 1.3 240 private static final class TLS13Authenticator extends SSLAuthenticator { 241 // Block size of TLS v1.3: 242 // record type + protocol version + record length + sequence number 243 private static final int BLOCK_SIZE = 13; // 1 + 2 + 2 + 8 244 TLS13Authenticator(ProtocolVersion protocolVersion)245 private TLS13Authenticator(ProtocolVersion protocolVersion) { 246 super(new byte[BLOCK_SIZE]); 247 block[9] = ProtocolVersion.TLS12.major; 248 block[10] = ProtocolVersion.TLS12.minor; 249 } 250 251 @Override acquireAuthenticationBytes( byte type, int length, byte[] sequence)252 byte[] acquireAuthenticationBytes( 253 byte type, int length, byte[] sequence) { 254 byte[] ad = Arrays.copyOfRange(block, 8, 13); 255 256 // Increase the implicit sequence number in the block array. 257 increaseSequenceNumber(); 258 259 ad[0] = type; 260 ad[3] = (byte)(length >> 8); 261 ad[4] = (byte)(length & 0xFF); 262 263 return ad; 264 } 265 } 266 267 interface MAC { macAlg()268 MacAlg macAlg(); 269 270 /** 271 * Compute and returns the MAC for the remaining data 272 * in this ByteBuffer. 273 * 274 * On return, the bb position == limit, and limit will 275 * have not changed. 276 * 277 * @param type record type 278 * @param bb a ByteBuffer in which the position and limit 279 * demarcate the data to be MAC'd. 280 * @param isSimulated if true, simulate the MAC computation 281 * @param sequence the explicit sequence number, or null if using 282 * the implicit sequence number for the computation 283 * 284 * @return the MAC result 285 */ compute(byte type, ByteBuffer bb, byte[] sequence, boolean isSimulated)286 byte[] compute(byte type, ByteBuffer bb, 287 byte[] sequence, boolean isSimulated); 288 289 290 /** 291 * Compute and returns the MAC for the remaining data 292 * in this ByteBuffer. 293 * 294 * On return, the bb position == limit, and limit will 295 * have not changed. 296 * 297 * @param type record type 298 * @param bb a ByteBuffer in which the position and limit 299 * demarcate the data to be MAC'd. 300 * @param isSimulated if true, simulate the MAC computation 301 * 302 * @return the MAC result 303 */ compute(byte type, ByteBuffer bb, boolean isSimulated)304 default byte[] compute(byte type, ByteBuffer bb, boolean isSimulated) { 305 return compute(type, bb, null, isSimulated); 306 } 307 } 308 309 private class MacImpl implements MAC { 310 // internal identifier for the MAC algorithm 311 private final MacAlg macAlg; 312 313 // JCE Mac object 314 private final Mac mac; 315 MacImpl()316 private MacImpl() { 317 macAlg = MacAlg.M_NULL; 318 mac = null; 319 } 320 MacImpl(ProtocolVersion protocolVersion, MacAlg macAlg, SecretKey key)321 private MacImpl(ProtocolVersion protocolVersion, MacAlg macAlg, 322 SecretKey key) throws NoSuchAlgorithmException, 323 InvalidKeyException { 324 if (macAlg == null) { 325 throw new RuntimeException("Null MacAlg"); 326 } 327 328 // using SSL MAC computation? 329 boolean useSSLMac = (protocolVersion.id < ProtocolVersion.TLS10.id); 330 String algorithm; 331 switch (macAlg) { 332 case M_MD5: 333 algorithm = useSSLMac ? "SslMacMD5" : "HmacMD5"; 334 break; 335 case M_SHA: 336 algorithm = useSSLMac ? "SslMacSHA1" : "HmacSHA1"; 337 break; 338 case M_SHA256: 339 algorithm = "HmacSHA256"; // TLS 1.2+ 340 break; 341 case M_SHA384: 342 algorithm = "HmacSHA384"; // TLS 1.2+ 343 break; 344 default: 345 throw new RuntimeException("Unknown MacAlg " + macAlg); 346 } 347 348 Mac m = JsseJce.getMac(algorithm); 349 m.init(key); 350 this.macAlg = macAlg; 351 this.mac = m; 352 } 353 354 @Override macAlg()355 public MacAlg macAlg() { 356 return macAlg; 357 } 358 359 @Override compute(byte type, ByteBuffer bb, byte[] sequence, boolean isSimulated)360 public byte[] compute(byte type, ByteBuffer bb, 361 byte[] sequence, boolean isSimulated) { 362 363 if (macAlg.size == 0) { 364 return new byte[0]; 365 } 366 367 if (!isSimulated) { 368 // Uses the explicit sequence number for the computation. 369 byte[] additional = 370 acquireAuthenticationBytes(type, bb.remaining(), sequence); 371 mac.update(additional); 372 } 373 mac.update(bb); 374 375 return mac.doFinal(); 376 } 377 } 378 379 // NULL SSL MAC 380 private static final 381 class SSLNullMac extends SSLNullAuthenticator implements MAC { 382 private final MacImpl macImpl; SSLNullMac()383 public SSLNullMac() { 384 super(); 385 this.macImpl = new MacImpl(); 386 } 387 388 @Override macAlg()389 public MacAlg macAlg() { 390 return macImpl.macAlg; 391 } 392 393 @Override compute(byte type, ByteBuffer bb, byte[] sequence, boolean isSimulated)394 public byte[] compute(byte type, ByteBuffer bb, 395 byte[] sequence, boolean isSimulated) { 396 return macImpl.compute(type, bb, sequence, isSimulated); 397 } 398 } 399 400 // For SSL 3.0 401 private static final 402 class SSL30Mac extends SSL30Authenticator implements MAC { 403 private final MacImpl macImpl; SSL30Mac(ProtocolVersion protocolVersion, MacAlg macAlg, SecretKey key)404 public SSL30Mac(ProtocolVersion protocolVersion, 405 MacAlg macAlg, SecretKey key) throws NoSuchAlgorithmException, 406 InvalidKeyException { 407 super(); 408 this.macImpl = new MacImpl(protocolVersion, macAlg, key); 409 } 410 411 @Override macAlg()412 public MacAlg macAlg() { 413 return macImpl.macAlg; 414 } 415 416 @Override compute(byte type, ByteBuffer bb, byte[] sequence, boolean isSimulated)417 public byte[] compute(byte type, ByteBuffer bb, 418 byte[] sequence, boolean isSimulated) { 419 return macImpl.compute(type, bb, sequence, isSimulated); 420 } 421 } 422 423 // For TLS 1.0 - 1.2 424 private static final 425 class TLS10Mac extends TLS10Authenticator implements MAC { 426 private final MacImpl macImpl; TLS10Mac(ProtocolVersion protocolVersion, MacAlg macAlg, SecretKey key)427 public TLS10Mac(ProtocolVersion protocolVersion, 428 MacAlg macAlg, SecretKey key) throws NoSuchAlgorithmException, 429 InvalidKeyException { 430 super(protocolVersion); 431 this.macImpl = new MacImpl(protocolVersion, macAlg, key); 432 } 433 434 @Override macAlg()435 public MacAlg macAlg() { 436 return macImpl.macAlg; 437 } 438 439 @Override compute(byte type, ByteBuffer bb, byte[] sequence, boolean isSimulated)440 public byte[] compute(byte type, ByteBuffer bb, 441 byte[] sequence, boolean isSimulated) { 442 return macImpl.compute(type, bb, sequence, isSimulated); 443 } 444 } 445 toLong(byte[] recordEnS)446 static final long toLong(byte[] recordEnS) { 447 if (recordEnS != null && recordEnS.length == 8) { 448 return ((recordEnS[0] & 0xFFL) << 56) | 449 ((recordEnS[1] & 0xFFL) << 48) | 450 ((recordEnS[2] & 0xFFL) << 40) | 451 ((recordEnS[3] & 0xFFL) << 32) | 452 ((recordEnS[4] & 0xFFL) << 24) | 453 ((recordEnS[5] & 0xFFL) << 16) | 454 ((recordEnS[6] & 0xFFL) << 8) | 455 (recordEnS[7] & 0xFFL); 456 } 457 458 return -1L; 459 } 460 } 461