1 /* 2 * Copyright (c) 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.io.IOException; 29 import java.security.InvalidAlgorithmParameterException; 30 import java.security.NoSuchAlgorithmException; 31 import java.security.ProviderException; 32 import java.security.spec.AlgorithmParameterSpec; 33 import javax.crypto.KeyGenerator; 34 import javax.crypto.SecretKey; 35 import sun.security.internal.spec.TlsMasterSecretParameterSpec; 36 import sun.security.ssl.CipherSuite.HashAlg; 37 import static sun.security.ssl.CipherSuite.HashAlg.H_NONE; 38 39 enum SSLMasterKeyDerivation implements SSLKeyDerivationGenerator { 40 SSL30 ("kdf_ssl30", S30MasterSecretKeyDerivationGenerator.instance), 41 TLS10 ("kdf_tls10", T10MasterSecretKeyDerivationGenerator.instance), 42 TLS12 ("kdf_tls12", T12MasterSecretKeyDerivationGenerator.instance), 43 TLS13 ("kdf_tls13", null); 44 45 final String name; 46 final SSLKeyDerivationGenerator keyDerivationGenerator; 47 48 SSLMasterKeyDerivation(String name, 49 SSLKeyDerivationGenerator keyDerivationGenerator) { 50 this.name = name; 51 this.keyDerivationGenerator = keyDerivationGenerator; 52 } 53 54 static SSLMasterKeyDerivation valueOf(ProtocolVersion protocolVersion) { 55 switch (protocolVersion) { 56 case SSL30: 57 return SSLMasterKeyDerivation.SSL30; 58 case TLS10: 59 case TLS11: 60 case DTLS10: 61 return SSLMasterKeyDerivation.TLS10; 62 case TLS12: 63 case DTLS12: 64 return SSLMasterKeyDerivation.TLS12; 65 case TLS13: 66 case DTLS13: 67 return SSLMasterKeyDerivation.TLS13; 68 default: 69 return null; 70 } 71 } 72 73 @Override 74 public SSLKeyDerivation createKeyDerivation(HandshakeContext context, 75 SecretKey secretKey) throws IOException { 76 return keyDerivationGenerator.createKeyDerivation(context, secretKey); 77 } 78 79 private static final class S30MasterSecretKeyDerivationGenerator 80 implements SSLKeyDerivationGenerator { 81 private static final S30MasterSecretKeyDerivationGenerator instance = 82 new S30MasterSecretKeyDerivationGenerator(); 83 84 // Prevent instantiation of this class. 85 private S30MasterSecretKeyDerivationGenerator() { 86 // blank 87 } 88 89 @Override 90 public SSLKeyDerivation createKeyDerivation( 91 HandshakeContext context, SecretKey secretKey) throws IOException { 92 return new LegacyMasterKeyDerivation(context, secretKey); 93 } 94 } 95 96 97 private static final class T10MasterSecretKeyDerivationGenerator 98 implements SSLKeyDerivationGenerator { 99 private static final T10MasterSecretKeyDerivationGenerator instance = 100 new T10MasterSecretKeyDerivationGenerator(); 101 102 // Prevent instantiation of this class. 103 private T10MasterSecretKeyDerivationGenerator() { 104 // blank 105 } 106 107 @Override 108 public SSLKeyDerivation createKeyDerivation( 109 HandshakeContext context, SecretKey secretKey) throws IOException { 110 return new LegacyMasterKeyDerivation(context, secretKey); 111 } 112 } 113 114 private static final class T12MasterSecretKeyDerivationGenerator 115 implements SSLKeyDerivationGenerator { 116 private static final T12MasterSecretKeyDerivationGenerator instance = 117 new T12MasterSecretKeyDerivationGenerator(); 118 119 // Prevent instantiation of this class. 120 private T12MasterSecretKeyDerivationGenerator() { 121 // blank 122 } 123 124 @Override 125 public SSLKeyDerivation createKeyDerivation( 126 HandshakeContext context, SecretKey secretKey) throws IOException { 127 return new LegacyMasterKeyDerivation(context, secretKey); 128 } 129 130 } 131 132 private static final 133 class LegacyMasterKeyDerivation implements SSLKeyDerivation { 134 135 final HandshakeContext context; 136 final SecretKey preMasterSecret; 137 138 LegacyMasterKeyDerivation( 139 HandshakeContext context, SecretKey preMasterSecret) { 140 this.context = context; 141 this.preMasterSecret = preMasterSecret; 142 } 143 144 @Override 145 @SuppressWarnings("deprecation") 146 public SecretKey deriveKey(String algorithm, 147 AlgorithmParameterSpec params) throws IOException { 148 149 CipherSuite cipherSuite = context.negotiatedCipherSuite; 150 ProtocolVersion protocolVersion = context.negotiatedProtocol; 151 152 // What algs/params do we need to use? 153 String masterAlg; 154 HashAlg hashAlg; 155 156 byte majorVersion = protocolVersion.major; 157 byte minorVersion = protocolVersion.minor; 158 if (protocolVersion.isDTLS) { 159 // Use TLS version number for DTLS key calculation 160 if (protocolVersion.id == ProtocolVersion.DTLS10.id) { 161 majorVersion = ProtocolVersion.TLS11.major; 162 minorVersion = ProtocolVersion.TLS11.minor; 163 164 masterAlg = "SunTlsMasterSecret"; 165 hashAlg = H_NONE; 166 } else { // DTLS 1.2 167 majorVersion = ProtocolVersion.TLS12.major; 168 minorVersion = ProtocolVersion.TLS12.minor; 169 170 masterAlg = "SunTls12MasterSecret"; 171 hashAlg = cipherSuite.hashAlg; 172 } 173 } else { 174 if (protocolVersion.id >= ProtocolVersion.TLS12.id) { 175 masterAlg = "SunTls12MasterSecret"; 176 hashAlg = cipherSuite.hashAlg; 177 } else { 178 masterAlg = "SunTlsMasterSecret"; 179 hashAlg = H_NONE; 180 } 181 } 182 183 TlsMasterSecretParameterSpec spec; 184 if (context.handshakeSession.useExtendedMasterSecret) { 185 // reset to use the extended master secret algorithm 186 masterAlg = "SunTlsExtendedMasterSecret"; 187 188 // For the session hash, use the handshake messages up to and 189 // including the ClientKeyExchange message. 190 context.handshakeHash.utilize(); 191 byte[] sessionHash = context.handshakeHash.digest(); 192 spec = new TlsMasterSecretParameterSpec( 193 preMasterSecret, 194 (majorVersion & 0xFF), (minorVersion & 0xFF), 195 sessionHash, 196 hashAlg.name, hashAlg.hashLength, hashAlg.blockSize); 197 } else { 198 spec = new TlsMasterSecretParameterSpec( 199 preMasterSecret, 200 (majorVersion & 0xFF), (minorVersion & 0xFF), 201 context.clientHelloRandom.randomBytes, 202 context.serverHelloRandom.randomBytes, 203 hashAlg.name, hashAlg.hashLength, hashAlg.blockSize); 204 } 205 206 try { 207 KeyGenerator kg = JsseJce.getKeyGenerator(masterAlg); 208 kg.init(spec); 209 return kg.generateKey(); 210 } catch (InvalidAlgorithmParameterException | 211 NoSuchAlgorithmException iae) { 212 // unlikely to happen, otherwise, must be a provider exception 213 // 214 // For RSA premaster secrets, do not signal a protocol error 215 // due to the Bleichenbacher attack. See comments further down. 216 if (SSLLogger.isOn && SSLLogger.isOn("handshake")) { 217 SSLLogger.fine("RSA master secret generation error.", iae); 218 } 219 throw new ProviderException(iae); 220 } 221 } 222 } 223 }