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+
26+package com.sun.crypto.provider;
27+
28+import java.security.*;
29+import java.security.spec.AlgorithmParameterSpec;
30+
31+import javax.crypto.*;
32+import javax.crypto.spec.*;
33+
34+import sun.security.internal.interfaces.TlsMasterSecret;
35+import sun.security.internal.spec.*;
36+
37+import 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+ */
45+public 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+}