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