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/P11TlsPrfGenerator.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.security.*;
29
import java.security.spec.AlgorithmParameterSpec;
30
31
import javax.crypto.*;
32
import javax.crypto.spec.*;
33
34
import sun.security.internal.spec.TlsPrfParameterSpec;
35
36
import static sun.security.pkcs11.TemplateManager.*;
37
import sun.security.pkcs11.wrapper.*;
38
import static sun.security.pkcs11.wrapper.PKCS11Constants.*;
39
40
/**
41
* KeyGenerator for the TLS PRF. Note that although the PRF is used in a number
42
* of places during the handshake, this class is usually only used to calculate
43
* the Finished messages. The reason is that for those other uses more specific
44
* PKCS#11 mechanisms have been defined (CKM_SSL3_MASTER_KEY_DERIVE, etc.).
45
*
46
* <p>This class supports the CKM_TLS_PRF mechanism from PKCS#11 v2.20 and
47
* the older NSS private mechanism.
48
*
49
* @author Andreas Sterbenz
50
* @since 1.6
51
*/
52
final class P11TlsPrfGenerator extends KeyGeneratorSpi {
53
54
private final static String MSG =
55
"TlsPrfGenerator must be initialized using a TlsPrfParameterSpec";
56
57
// token instance
58
private final Token token;
59
60
// algorithm name
61
private final String algorithm;
62
63
// mechanism id
64
private final long mechanism;
65
66
private TlsPrfParameterSpec spec;
67
68
private P11Key p11Key;
69
70
P11TlsPrfGenerator(Token token, String algorithm, long mechanism)
71
throws PKCS11Exception {
72
super();
73
this.token = token;
74
this.algorithm = algorithm;
75
this.mechanism = mechanism;
76
}
77
78
protected void engineInit(SecureRandom random) {
79
throw new InvalidParameterException(MSG);
80
}
81
82
protected void engineInit(AlgorithmParameterSpec params,
83
SecureRandom random) throws InvalidAlgorithmParameterException {
84
if (params instanceof TlsPrfParameterSpec == false) {
85
throw new InvalidAlgorithmParameterException(MSG);
86
}
87
this.spec = (TlsPrfParameterSpec)params;
88
SecretKey key = spec.getSecret();
89
if (key == null) {
90
key = NULL_KEY;
91
}
92
try {
93
p11Key = P11SecretKeyFactory.convertKey(token, key, null);
94
} catch (InvalidKeyException e) {
95
throw new InvalidAlgorithmParameterException("init() failed", e);
96
}
97
}
98
99
// SecretKeySpec does not allow zero length keys, so we define our
100
// own class.
101
//
102
// As an anonymous class cannot make any guarantees about serialization
103
// compatibility, it is nonsensical for an anonymous class to define a
104
// serialVersionUID. Suppress warnings relative to missing serialVersionUID
105
// field in the anonymous subclass of serializable SecretKey.
106
@SuppressWarnings("serial")
107
private static final SecretKey NULL_KEY = new SecretKey() {
108
public byte[] getEncoded() {
109
return new byte[0];
110
}
111
public String getFormat() {
112
return "RAW";
113
}
114
public String getAlgorithm() {
115
return "Generic";
116
}
117
};
118
119
protected void engineInit(int keysize, SecureRandom random) {
120
throw new InvalidParameterException(MSG);
121
}
122
123
protected SecretKey engineGenerateKey() {
124
if (spec == null) {
125
throw new IllegalStateException("TlsPrfGenerator must be initialized");
126
}
127
byte[] seed = spec.getSeed();
128
129
// TLS 1.2
130
if (mechanism == CKM_TLS_MAC) {
131
SecretKey k = null;
132
int ulServerOrClient = 0;
133
if (spec.getLabel().equals("server finished")) {
134
ulServerOrClient = 1;
135
}
136
if (spec.getLabel().equals("client finished")) {
137
ulServerOrClient = 2;
138
}
139
140
if (ulServerOrClient != 0) {
141
// Finished message
142
CK_TLS_MAC_PARAMS params = new CK_TLS_MAC_PARAMS(
143
Functions.getHashMechId(spec.getPRFHashAlg()),
144
spec.getOutputLength(), ulServerOrClient);
145
Session session = null;
146
long keyID = p11Key.getKeyID();
147
try {
148
session = token.getOpSession();
149
token.p11.C_SignInit(session.id(),
150
new CK_MECHANISM(mechanism, params), keyID);
151
token.p11.C_SignUpdate(session.id(), 0, seed, 0, seed.length);
152
byte[] out = token.p11.C_SignFinal
153
(session.id(), spec.getOutputLength());
154
return new SecretKeySpec(out, "TlsPrf");
155
} catch (PKCS11Exception e) {
156
throw new ProviderException("Could not calculate PRF", e);
157
} finally {
158
p11Key.releaseKeyID();
159
token.releaseSession(session);
160
}
161
} else {
162
throw new ProviderException("Only Finished message authentication code"+
163
" generation supported for TLS 1.2.");
164
}
165
}
166
167
byte[] label = P11Util.getBytesUTF8(spec.getLabel());
168
169
if (mechanism == CKM_NSS_TLS_PRF_GENERAL) {
170
Session session = null;
171
long keyID = p11Key.getKeyID();
172
try {
173
session = token.getOpSession();
174
token.p11.C_SignInit
175
(session.id(), new CK_MECHANISM(mechanism), keyID);
176
token.p11.C_SignUpdate(session.id(), 0, label, 0, label.length);
177
token.p11.C_SignUpdate(session.id(), 0, seed, 0, seed.length);
178
byte[] out = token.p11.C_SignFinal
179
(session.id(), spec.getOutputLength());
180
return new SecretKeySpec(out, "TlsPrf");
181
} catch (PKCS11Exception e) {
182
throw new ProviderException("Could not calculate PRF", e);
183
} finally {
184
p11Key.releaseKeyID();
185
token.releaseSession(session);
186
}
187
}
188
189
// mechanism == CKM_TLS_PRF
190
191
byte[] out = new byte[spec.getOutputLength()];
192
CK_TLS_PRF_PARAMS params = new CK_TLS_PRF_PARAMS(seed, label, out);
193
194
Session session = null;
195
long keyID = p11Key.getKeyID();
196
try {
197
session = token.getOpSession();
198
token.p11.C_DeriveKey(session.id(),
199
new CK_MECHANISM(mechanism, params), keyID, null);
200
return new SecretKeySpec(out, "TlsPrf");
201
} catch (PKCS11Exception e) {
202
throw new ProviderException("Could not calculate PRF", e);
203
} finally {
204
p11Key.releaseKeyID();
205
token.releaseSession(session);
206
}
207
}
208
209
}
210
211