History

My first initial commit with all of mine experimental changes.

Dmitry Kabak (userdima committed 13 years ago

Commit d37b88d1 parent 3f5b46618352 files · +2598093 −-8690Browse files

Showing the changes to java/pkg/com/sun/crypto/provider/TlsKeyMaterialGenerator.java (1 of 18352 files). Show all

Unified · Split

java/pkg/com/sun/crypto/provider/TlsKeyMaterialGenerator.java+277−0
@@ -0,0 +1,277 @@
1/*
2 * Copyright (c) 2005, 2010, 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
26package com.sun.crypto.provider;
27
28import java.security.*;
29import java.security.spec.AlgorithmParameterSpec;
30
31import javax.crypto.*;
32import javax.crypto.spec.*;
33
34import sun.security.internal.interfaces.TlsMasterSecret;
35import sun.security.internal.spec.*;
36
37import static com.sun.crypto.provider.TlsPrfGenerator.*;
38
39/**
40 * KeyGenerator implementation for the SSL/TLS master secret derivation.
41 *
42 * @author Andreas Sterbenz
43 * @since 1.6
44 */
45public final class TlsKeyMaterialGenerator extends KeyGeneratorSpi {
46
47 private final static String MSG = "TlsKeyMaterialGenerator must be "
48 + "initialized using a TlsKeyMaterialParameterSpec";
49
50 private TlsKeyMaterialParameterSpec spec;
51
52 private int protocolVersion;
53
54 public TlsKeyMaterialGenerator() {
55 }
56
57 protected void engineInit(SecureRandom random) {
58 throw new InvalidParameterException(MSG);
59 }
60
61 protected void engineInit(AlgorithmParameterSpec params,
62 SecureRandom random) throws InvalidAlgorithmParameterException {
63 if (params instanceof TlsKeyMaterialParameterSpec == false) {
64 throw new InvalidAlgorithmParameterException(MSG);
65 }
66 this.spec = (TlsKeyMaterialParameterSpec)params;
67 if ("RAW".equals(spec.getMasterSecret().getFormat()) == false) {
68 throw new InvalidAlgorithmParameterException(
69 "Key format must be RAW");
70 }
71 protocolVersion = (spec.getMajorVersion() << 8)
72 | spec.getMinorVersion();
73 if ((protocolVersion < 0x0300) || (protocolVersion > 0x0303)) {
74 throw new InvalidAlgorithmParameterException(
75 "Only SSL 3.0, TLS 1.0/1.1/1.2 supported");
76 }
77 }
78
79 protected void engineInit(int keysize, SecureRandom random) {
80 throw new InvalidParameterException(MSG);
81 }
82
83 protected SecretKey engineGenerateKey() {
84 if (spec == null) {
85 throw new IllegalStateException(
86 "TlsKeyMaterialGenerator must be initialized");
87 }
88 try {
89 return engineGenerateKey0();
90 } catch (GeneralSecurityException e) {
91 throw new ProviderException(e);
92 }
93 }
94
95 private SecretKey engineGenerateKey0() throws GeneralSecurityException {
96 byte[] masterSecret = spec.getMasterSecret().getEncoded();
97
98 byte[] clientRandom = spec.getClientRandom();
99 byte[] serverRandom = spec.getServerRandom();
100
101 SecretKey clientMacKey = null;
102 SecretKey serverMacKey = null;
103 SecretKey clientCipherKey = null;
104 SecretKey serverCipherKey = null;
105 IvParameterSpec clientIv = null;
106 IvParameterSpec serverIv = null;
107
108 int macLength = spec.getMacKeyLength();
109 int expandedKeyLength = spec.getExpandedCipherKeyLength();
110 boolean isExportable = (expandedKeyLength != 0);
111 int keyLength = spec.getCipherKeyLength();
112 int ivLength = spec.getIvLength();
113
114 int keyBlockLen = macLength + keyLength
115 + (isExportable ? 0 : ivLength);
116 keyBlockLen <<= 1;
117 byte[] keyBlock = new byte[keyBlockLen];
118
119 // These may be used again later for exportable suite calculations.
120 MessageDigest md5 = null;
121 MessageDigest sha = null;
122
123 // generate key block
124 if (protocolVersion >= 0x0303) {
125 // TLS 1.2
126 byte[] seed = concat(serverRandom, clientRandom);
127 keyBlock = doTLS12PRF(masterSecret, LABEL_KEY_EXPANSION, seed,
128 keyBlockLen, spec.getPRFHashAlg(),
129 spec.getPRFHashLength(), spec.getPRFBlockSize());
130 } else if (protocolVersion >= 0x0301) {
131 // TLS 1.0/1.1
132 md5 = MessageDigest.getInstance("MD5");
133 sha = MessageDigest.getInstance("SHA1");
134 byte[] seed = concat(serverRandom, clientRandom);
135 keyBlock = doTLS10PRF(masterSecret, LABEL_KEY_EXPANSION, seed,
136 keyBlockLen, md5, sha);
137 } else {
138 // SSL
139 md5 = MessageDigest.getInstance("MD5");
140 sha = MessageDigest.getInstance("SHA1");
141 keyBlock = new byte[keyBlockLen];
142
143 byte[] tmp = new byte[20];
144 for (int i = 0, remaining = keyBlockLen;
145 remaining > 0;
146 i++, remaining -= 16) {
147
148 sha.update(SSL3_CONST[i]);
149 sha.update(masterSecret);
150 sha.update(serverRandom);
151 sha.update(clientRandom);
152 sha.digest(tmp, 0, 20);
153
154 md5.update(masterSecret);
155 md5.update(tmp);
156
157 if (remaining >= 16) {
158 md5.digest(keyBlock, i << 4, 16);
159 } else {
160 md5.digest(tmp, 0, 16);
161 System.arraycopy(tmp, 0, keyBlock, i << 4, remaining);
162 }
163 }
164 }
165
166 // partition keyblock into individual secrets
167
168 int ofs = 0;
169 byte[] tmp = new byte[macLength];
170
171 // mac keys
172 System.arraycopy(keyBlock, ofs, tmp, 0, macLength);
173 ofs += macLength;
174 clientMacKey = new SecretKeySpec(tmp, "Mac");
175
176 System.arraycopy(keyBlock, ofs, tmp, 0, macLength);
177 ofs += macLength;
178 serverMacKey = new SecretKeySpec(tmp, "Mac");
179
180 if (keyLength == 0) { // SSL_RSA_WITH_NULL_* ciphersuites
181 return new TlsKeyMaterialSpec(clientMacKey, serverMacKey);
182 }
183
184 String alg = spec.getCipherAlgorithm();
185
186 // cipher keys
187 byte[] clientKeyBytes = new byte[keyLength];
188 System.arraycopy(keyBlock, ofs, clientKeyBytes, 0, keyLength);
189 ofs += keyLength;
190
191 byte[] serverKeyBytes = new byte[keyLength];
192 System.arraycopy(keyBlock, ofs, serverKeyBytes, 0, keyLength);
193 ofs += keyLength;
194
195 if (isExportable == false) {
196 // cipher keys
197 clientCipherKey = new SecretKeySpec(clientKeyBytes, alg);
198 serverCipherKey = new SecretKeySpec(serverKeyBytes, alg);
199
200 // IV keys if needed.
201 if (ivLength != 0) {
202 tmp = new byte[ivLength];
203
204 System.arraycopy(keyBlock, ofs, tmp, 0, ivLength);
205 ofs += ivLength;
206 clientIv = new IvParameterSpec(tmp);
207
208 System.arraycopy(keyBlock, ofs, tmp, 0, ivLength);
209 ofs += ivLength;
210 serverIv = new IvParameterSpec(tmp);
211 }
212 } else {
213 // if exportable suites, calculate the alternate
214 // cipher key expansion and IV generation
215 if (protocolVersion >= 0x0302) {
216 // TLS 1.1+
217 throw new RuntimeException(
218 "Internal Error: TLS 1.1+ should not be negotiating" +
219 "exportable ciphersuites");
220 } else if (protocolVersion == 0x0301) {
221 // TLS 1.0
222 byte[] seed = concat(clientRandom, serverRandom);
223
224 tmp = doTLS10PRF(clientKeyBytes, LABEL_CLIENT_WRITE_KEY, seed,
225 expandedKeyLength, md5, sha);
226 clientCipherKey = new SecretKeySpec(tmp, alg);
227
228 tmp = doTLS10PRF(serverKeyBytes, LABEL_SERVER_WRITE_KEY, seed,
229 expandedKeyLength, md5, sha);
230 serverCipherKey = new SecretKeySpec(tmp, alg);
231
232 if (ivLength != 0) {
233 tmp = new byte[ivLength];
234 byte[] block = doTLS10PRF(null, LABEL_IV_BLOCK, seed,
235 ivLength << 1, md5, sha);
236 System.arraycopy(block, 0, tmp, 0, ivLength);
237 clientIv = new IvParameterSpec(tmp);
238 System.arraycopy(block, ivLength, tmp, 0, ivLength);
239 serverIv = new IvParameterSpec(tmp);
240 }
241 } else {
242 // SSLv3
243 tmp = new byte[expandedKeyLength];
244
245 md5.update(clientKeyBytes);
246 md5.update(clientRandom);
247 md5.update(serverRandom);
248 System.arraycopy(md5.digest(), 0, tmp, 0, expandedKeyLength);
249 clientCipherKey = new SecretKeySpec(tmp, alg);
250
251 md5.update(serverKeyBytes);
252 md5.update(serverRandom);
253 md5.update(clientRandom);
254 System.arraycopy(md5.digest(), 0, tmp, 0, expandedKeyLength);
255 serverCipherKey = new SecretKeySpec(tmp, alg);
256
257 if (ivLength != 0) {
258 tmp = new byte[ivLength];
259
260 md5.update(clientRandom);
261 md5.update(serverRandom);
262 System.arraycopy(md5.digest(), 0, tmp, 0, ivLength);
263 clientIv = new IvParameterSpec(tmp);
264
265 md5.update(serverRandom);
266 md5.update(clientRandom);
267 System.arraycopy(md5.digest(), 0, tmp, 0, ivLength);
268 serverIv = new IvParameterSpec(tmp);
269 }
270 }
271 }
272
273 return new TlsKeyMaterialSpec(clientMacKey, serverMacKey,
274 clientCipherKey, clientIv, serverCipherKey, serverIv);
275 }
276
277}