Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/openjdk-multiarch-jdk8u
Path: blob/aarch64-shenandoah-jdk8u272-b10/jdk/src/share/classes/sun/security/pkcs11/P11TlsKeyMaterialGenerator.java
38919 views
1
/*
2
* Copyright (c) 2005, 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.pkcs11;
27
28
import java.util.*;
29
30
import java.security.*;
31
import java.security.spec.AlgorithmParameterSpec;
32
33
import javax.crypto.*;
34
import javax.crypto.spec.*;
35
36
import sun.security.internal.spec.*;
37
import sun.security.internal.interfaces.TlsMasterSecret;
38
39
import static sun.security.pkcs11.TemplateManager.*;
40
import sun.security.pkcs11.wrapper.*;
41
import static sun.security.pkcs11.wrapper.PKCS11Constants.*;
42
43
/**
44
* KeyGenerator to calculate the SSL/TLS key material (cipher keys and ivs,
45
* mac keys) from the master secret.
46
*
47
* @author Andreas Sterbenz
48
* @since 1.6
49
*/
50
public final class P11TlsKeyMaterialGenerator extends KeyGeneratorSpi {
51
52
private final static String MSG = "TlsKeyMaterialGenerator must be "
53
+ "initialized using a TlsKeyMaterialParameterSpec";
54
55
// token instance
56
private final Token token;
57
58
// algorithm name
59
private final String algorithm;
60
61
// mechanism id
62
private long mechanism;
63
64
// parameter spec
65
private TlsKeyMaterialParameterSpec spec;
66
67
// master secret as a P11Key
68
private P11Key p11Key;
69
70
// version, e.g. 0x0301
71
private int version;
72
73
P11TlsKeyMaterialGenerator(Token token, String algorithm, long mechanism)
74
throws PKCS11Exception {
75
super();
76
this.token = token;
77
this.algorithm = algorithm;
78
this.mechanism = mechanism;
79
}
80
81
protected void engineInit(SecureRandom random) {
82
throw new InvalidParameterException(MSG);
83
}
84
85
protected void engineInit(AlgorithmParameterSpec params,
86
SecureRandom random) throws InvalidAlgorithmParameterException {
87
if (params instanceof TlsKeyMaterialParameterSpec == false) {
88
throw new InvalidAlgorithmParameterException(MSG);
89
}
90
this.spec = (TlsKeyMaterialParameterSpec)params;
91
try {
92
p11Key = P11SecretKeyFactory.convertKey
93
(token, spec.getMasterSecret(), "TlsMasterSecret");
94
} catch (InvalidKeyException e) {
95
throw new InvalidAlgorithmParameterException("init() failed", e);
96
}
97
version = (spec.getMajorVersion() << 8) | spec.getMinorVersion();
98
if ((version < 0x0300) && (version > 0x0303)) {
99
throw new InvalidAlgorithmParameterException("Only SSL 3.0," +
100
" TLS 1.0, TLS 1.1, and TLS 1.2 are supported");
101
}
102
// we assume the token supports both the CKM_SSL3_* and the CKM_TLS_*
103
// mechanisms
104
}
105
106
protected void engineInit(int keysize, SecureRandom random) {
107
throw new InvalidParameterException(MSG);
108
}
109
110
protected SecretKey engineGenerateKey() {
111
if (spec == null) {
112
throw new IllegalStateException
113
("TlsKeyMaterialGenerator must be initialized");
114
}
115
if (version == 0x0300) {
116
mechanism = CKM_SSL3_KEY_AND_MAC_DERIVE;
117
} else if (version == 0x0301 || version == 0x0302) {
118
mechanism = CKM_TLS_KEY_AND_MAC_DERIVE;
119
}
120
int macBits = spec.getMacKeyLength() << 3;
121
int ivBits = spec.getIvLength() << 3;
122
123
int expandedKeyBits = spec.getExpandedCipherKeyLength() << 3;
124
int keyBits = spec.getCipherKeyLength() << 3;
125
boolean isExportable;
126
if (expandedKeyBits != 0) {
127
isExportable = true;
128
} else {
129
isExportable = false;
130
expandedKeyBits = keyBits;
131
}
132
133
CK_SSL3_RANDOM_DATA random = new CK_SSL3_RANDOM_DATA
134
(spec.getClientRandom(), spec.getServerRandom());
135
Object params = null;
136
CK_MECHANISM ckMechanism = null;
137
if (version < 0x0303) {
138
params = new CK_SSL3_KEY_MAT_PARAMS
139
(macBits, keyBits, ivBits, isExportable, random);
140
ckMechanism = new CK_MECHANISM(mechanism, (CK_SSL3_KEY_MAT_PARAMS)params);
141
} else if (version == 0x0303) {
142
params = new CK_TLS12_KEY_MAT_PARAMS
143
(macBits, keyBits, ivBits, isExportable, random,
144
Functions.getHashMechId(spec.getPRFHashAlg()));
145
ckMechanism = new CK_MECHANISM(mechanism, (CK_TLS12_KEY_MAT_PARAMS)params);
146
}
147
148
String cipherAlgorithm = spec.getCipherAlgorithm();
149
long keyType = P11SecretKeyFactory.getKeyType(cipherAlgorithm);
150
if (keyType < 0) {
151
if (keyBits != 0) {
152
throw new ProviderException
153
("Unknown algorithm: " + spec.getCipherAlgorithm());
154
} else {
155
// NULL encryption ciphersuites
156
keyType = CKK_GENERIC_SECRET;
157
}
158
}
159
160
Session session = null;
161
try {
162
session = token.getObjSession();
163
CK_ATTRIBUTE[] attributes;
164
if (keyBits != 0) {
165
attributes = new CK_ATTRIBUTE[] {
166
new CK_ATTRIBUTE(CKA_CLASS, CKO_SECRET_KEY),
167
new CK_ATTRIBUTE(CKA_KEY_TYPE, keyType),
168
new CK_ATTRIBUTE(CKA_VALUE_LEN, expandedKeyBits >> 3),
169
};
170
} else {
171
// ciphersuites with NULL ciphers
172
attributes = new CK_ATTRIBUTE[0];
173
}
174
attributes = token.getAttributes
175
(O_GENERATE, CKO_SECRET_KEY, keyType, attributes);
176
long p11KeyID = p11Key.getKeyID();
177
try {
178
token.p11.C_DeriveKey(session.id(),
179
ckMechanism, p11KeyID, attributes);
180
} finally {
181
p11Key.releaseKeyID();
182
}
183
184
CK_SSL3_KEY_MAT_OUT out = null;
185
if (params instanceof CK_SSL3_KEY_MAT_PARAMS) {
186
out = ((CK_SSL3_KEY_MAT_PARAMS)params).pReturnedKeyMaterial;
187
} else if (params instanceof CK_TLS12_KEY_MAT_PARAMS) {
188
out = ((CK_TLS12_KEY_MAT_PARAMS)params).pReturnedKeyMaterial;
189
}
190
// Note that the MAC keys do not inherit all attributes from the
191
// template, but they do inherit the sensitive/extractable/token
192
// flags, which is all P11Key cares about.
193
SecretKey clientMacKey, serverMacKey;
194
195
// The MAC size may be zero for GCM mode.
196
//
197
// PKCS11 does not support GCM mode as the author made the comment,
198
// so the macBits is unlikely to be zero. It's only a place holder.
199
if (macBits != 0) {
200
clientMacKey = P11Key.secretKey
201
(session, out.hClientMacSecret, "MAC", macBits, attributes);
202
serverMacKey = P11Key.secretKey
203
(session, out.hServerMacSecret, "MAC", macBits, attributes);
204
} else {
205
clientMacKey = null;
206
serverMacKey = null;
207
}
208
209
SecretKey clientCipherKey, serverCipherKey;
210
if (keyBits != 0) {
211
clientCipherKey = P11Key.secretKey(session, out.hClientKey,
212
cipherAlgorithm, expandedKeyBits, attributes);
213
serverCipherKey = P11Key.secretKey(session, out.hServerKey,
214
cipherAlgorithm, expandedKeyBits, attributes);
215
} else {
216
clientCipherKey = null;
217
serverCipherKey = null;
218
}
219
IvParameterSpec clientIv = (out.pIVClient == null)
220
? null : new IvParameterSpec(out.pIVClient);
221
IvParameterSpec serverIv = (out.pIVServer == null)
222
? null : new IvParameterSpec(out.pIVServer);
223
224
return new TlsKeyMaterialSpec(clientMacKey, serverMacKey,
225
clientCipherKey, clientIv, serverCipherKey, serverIv);
226
227
} catch (Exception e) {
228
throw new ProviderException("Could not generate key", e);
229
} finally {
230
token.releaseSession(session);
231
}
232
}
233
234
}
235
236