Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/mobile
Path: blob/master/src/jdk.crypto.ec/share/classes/sun/security/ec/ed/EdDSASignature.java
41162 views
1
/*
2
* Copyright (c) 2020, 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.ec.ed;
27
28
import sun.security.ec.point.AffinePoint;
29
30
import java.io.ByteArrayOutputStream;
31
import java.security.AlgorithmParameters;
32
import java.security.InvalidAlgorithmParameterException;
33
import java.security.InvalidKeyException;
34
import java.security.InvalidParameterException;
35
import java.security.NoSuchAlgorithmException;
36
import java.security.PrivateKey;
37
import java.security.ProviderException;
38
import java.security.PublicKey;
39
import java.security.SecureRandom;
40
import java.security.SignatureException;
41
import java.security.SignatureSpi;
42
import java.security.interfaces.EdECPrivateKey;
43
import java.security.interfaces.EdECPublicKey;
44
import java.security.spec.AlgorithmParameterSpec;
45
import java.security.spec.EdDSAParameterSpec;
46
import java.security.spec.NamedParameterSpec;
47
import java.util.function.Function;
48
49
public class EdDSASignature extends SignatureSpi {
50
51
private interface MessageAccumulator {
52
void add(byte b);
53
void add(byte[] data, int off, int len);
54
byte[] getMessage();
55
}
56
57
private static class DigestAccumulator implements MessageAccumulator {
58
private final EdDSAParameters.Digester digester;
59
60
DigestAccumulator(EdDSAParameters.Digester digester) {
61
this.digester = digester;
62
}
63
64
@Override
65
public void add(byte b) {
66
digester.update(b);
67
}
68
@Override
69
public void add(byte[] data, int off, int len) {
70
digester.update(data, off, len);
71
}
72
@Override
73
public byte[] getMessage() {
74
return digester.digest();
75
}
76
}
77
78
private static class MemoryAccumulator implements MessageAccumulator {
79
ByteArrayOutputStream message = new ByteArrayOutputStream();
80
81
@Override
82
public void add(byte b) {
83
message.write(b);
84
}
85
@Override
86
public void add(byte[] data, int off, int len) {
87
message.write(data, off, len);
88
}
89
@Override
90
public byte[] getMessage() {
91
return message.toByteArray();
92
}
93
}
94
95
private byte[] privateKey;
96
private AffinePoint publicKeyPoint;
97
private byte[] publicKeyBytes;
98
private EdDSAOperations ops;
99
private EdDSAParameters lockedParams = null;
100
private MessageAccumulator message = null;
101
private EdDSAParameterSpec sigParams = new EdDSAParameterSpec(false);
102
103
public EdDSASignature() {
104
// do nothing
105
}
106
107
EdDSASignature(NamedParameterSpec paramSpec) {
108
lockedParams = EdDSAParameters.get(ProviderException::new, paramSpec);
109
}
110
111
@Override
112
protected void engineInitVerify(PublicKey publicKey)
113
throws InvalidKeyException {
114
115
if (!(publicKey instanceof EdECPublicKey)) {
116
throw new InvalidKeyException("Unsupported key type");
117
}
118
EdECPublicKey edKey = (EdECPublicKey) publicKey;
119
EdDSAParameters params = EdDSAParameters.get(
120
InvalidKeyException::new, edKey.getParams());
121
122
initImpl(params);
123
this.privateKey = null;
124
this.publicKeyPoint = ops.decodeAffinePoint(InvalidKeyException::new,
125
edKey.getPoint());
126
EdDSAPublicKeyImpl pubKeyImpl = new EdDSAPublicKeyImpl(params,
127
edKey.getPoint());
128
this.publicKeyBytes = pubKeyImpl.getEncodedPoint();
129
}
130
131
@Override
132
protected void engineInitSign(PrivateKey privateKey)
133
throws InvalidKeyException {
134
engineInitSign(privateKey, null);
135
}
136
137
@Override
138
protected void engineInitSign(PrivateKey privateKey, SecureRandom random)
139
throws InvalidKeyException {
140
141
if (!(privateKey instanceof EdECPrivateKey)) {
142
throw new InvalidKeyException("Unsupported key type");
143
}
144
EdECPrivateKey edKey = (EdECPrivateKey) privateKey;
145
146
initImpl(edKey.getParams());
147
this.privateKey = edKey.getBytes().orElseThrow(
148
() -> new InvalidKeyException("No private key value"));
149
this.publicKeyPoint = null;
150
this.publicKeyBytes = null;
151
}
152
153
private
154
<T extends Throwable>
155
void checkLockedParams(Function<String, T> exception,
156
EdDSAParameters params) throws T {
157
if (lockedParams != null && lockedParams != params) {
158
throw exception.apply("Parameters must be " +
159
lockedParams.getName());
160
}
161
}
162
163
private void ensureMessageInit() throws SignatureException {
164
if (message == null) {
165
initMessage();
166
}
167
}
168
169
private void initMessage() throws SignatureException {
170
if (this.ops == null) {
171
throw new SignatureException("not initialized");
172
}
173
EdDSAParameters params = ops.getParameters();
174
175
if (sigParams.isPrehash()) {
176
this.message = new DigestAccumulator(params.createDigester(64));
177
} else {
178
this.message = new MemoryAccumulator();
179
}
180
}
181
182
@Override
183
protected void engineUpdate(byte b) throws SignatureException {
184
ensureMessageInit();
185
this.message.add(b);
186
}
187
188
@Override
189
protected void engineUpdate(byte[] b, int off, int len)
190
throws SignatureException {
191
192
ensureMessageInit();
193
this.message.add(b, off, len);
194
}
195
196
@Override
197
protected byte[] engineSign() throws SignatureException {
198
if (privateKey == null) {
199
throw new SignatureException("Missing private key");
200
}
201
ensureMessageInit();
202
byte[] result = ops.sign(this.sigParams, this.privateKey,
203
message.getMessage());
204
message = null;
205
return result;
206
}
207
208
@Override
209
protected boolean engineVerify(byte[] sigBytes) throws SignatureException {
210
if (publicKeyBytes == null) {
211
throw new SignatureException("Missing publicKey");
212
}
213
if (message == null) {
214
return false;
215
}
216
boolean result = ops.verify(this.sigParams, this.publicKeyPoint,
217
this.publicKeyBytes, message.getMessage(), sigBytes);
218
message = null;
219
return result;
220
}
221
222
private void initImpl(EdDSAParameters params) throws InvalidKeyException {
223
checkLockedParams(InvalidKeyException::new, params);
224
225
try {
226
this.ops = new EdDSAOperations(params);
227
} catch (NoSuchAlgorithmException ex) {
228
throw new ProviderException(ex);
229
}
230
// message is (re)set to null
231
// it will be initialized on first update
232
this.message = null;
233
}
234
235
private void initImpl(NamedParameterSpec paramSpec)
236
throws InvalidKeyException {
237
238
EdDSAParameters params = EdDSAParameters.get(
239
InvalidKeyException::new, paramSpec);
240
initImpl(params);
241
}
242
243
@Deprecated
244
@Override
245
protected Object engineGetParameter(String param)
246
throws InvalidParameterException {
247
throw new UnsupportedOperationException("getParameter() not supported");
248
}
249
250
@Deprecated
251
@Override
252
protected void engineSetParameter(String param, Object value)
253
throws InvalidParameterException {
254
255
throw new UnsupportedOperationException("setParameter() not supported");
256
}
257
258
@Override
259
protected void engineSetParameter(AlgorithmParameterSpec params)
260
throws InvalidAlgorithmParameterException {
261
262
// by convention, ignore null parameters
263
if (params == null) {
264
return;
265
}
266
267
if (params instanceof EdDSAParameterSpec) {
268
if (message != null) {
269
// sign/verify in progress
270
throw new InvalidParameterException("Cannot change signature " +
271
"parameters during operation");
272
}
273
EdDSAParameterSpec edDsaParams = (EdDSAParameterSpec) params;
274
checkContextLength(edDsaParams);
275
276
this.sigParams = edDsaParams;
277
} else {
278
throw new InvalidAlgorithmParameterException(
279
"Only EdDSAParameterSpec supported");
280
}
281
}
282
283
private static void checkContextLength(EdDSAParameterSpec edDsaParams)
284
throws InvalidAlgorithmParameterException {
285
286
if (edDsaParams.getContext().isPresent()) {
287
byte[] context = edDsaParams.getContext().get();
288
if (context.length > 255) {
289
throw new InvalidAlgorithmParameterException(
290
"Context is longer than 255 bytes");
291
}
292
}
293
}
294
295
// There is no RFC-defined ASN.1 for prehash and context (RFC 8410)
296
@Override
297
protected AlgorithmParameters engineGetParameters() {
298
return null;
299
}
300
301
public static class Ed25519 extends EdDSASignature {
302
303
public Ed25519() {
304
super(NamedParameterSpec.ED25519);
305
}
306
}
307
308
public static class Ed448 extends EdDSASignature {
309
310
public Ed448() {
311
super(NamedParameterSpec.ED448);
312
}
313
}
314
}
315
316