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/util/ECUtil.java
38830 views
1
/*
2
* Copyright (c) 2006, 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.util;
27
28
import java.io.IOException;
29
30
import java.math.BigInteger;
31
32
import java.security.*;
33
34
import java.security.interfaces.*;
35
36
import java.security.spec.*;
37
38
import java.util.Arrays;
39
40
import sun.security.x509.X509Key;
41
42
public final class ECUtil {
43
44
// Used by SunPKCS11 and SunJSSE.
45
public static ECPoint decodePoint(byte[] data, EllipticCurve curve)
46
throws IOException {
47
if ((data.length == 0) || (data[0] != 4)) {
48
throw new IOException("Only uncompressed point format supported");
49
}
50
// Per ANSI X9.62, an encoded point is a 1 byte type followed by
51
// ceiling(log base 2 field-size / 8) bytes of x and the same of y.
52
int n = (data.length - 1) / 2;
53
if (n != ((curve.getField().getFieldSize() + 7 ) >> 3)) {
54
throw new IOException("Point does not match field size");
55
}
56
57
byte[] xb = Arrays.copyOfRange(data, 1, 1 + n);
58
byte[] yb = Arrays.copyOfRange(data, n + 1, n + 1 + n);
59
60
return new ECPoint(new BigInteger(1, xb), new BigInteger(1, yb));
61
}
62
63
// Used by SunPKCS11 and SunJSSE.
64
public static byte[] encodePoint(ECPoint point, EllipticCurve curve) {
65
// get field size in bytes (rounding up)
66
int n = (curve.getField().getFieldSize() + 7) >> 3;
67
byte[] xb = trimZeroes(point.getAffineX().toByteArray());
68
byte[] yb = trimZeroes(point.getAffineY().toByteArray());
69
if ((xb.length > n) || (yb.length > n)) {
70
throw new RuntimeException
71
("Point coordinates do not match field size");
72
}
73
byte[] b = new byte[1 + (n << 1)];
74
b[0] = 4; // uncompressed
75
System.arraycopy(xb, 0, b, n - xb.length + 1, xb.length);
76
System.arraycopy(yb, 0, b, b.length - yb.length, yb.length);
77
return b;
78
}
79
80
public static byte[] trimZeroes(byte[] b) {
81
int i = 0;
82
while ((i < b.length - 1) && (b[i] == 0)) {
83
i++;
84
}
85
if (i == 0) {
86
return b;
87
}
88
89
return Arrays.copyOfRange(b, i, b.length);
90
}
91
92
public static AlgorithmParameters getECParameters(Provider p) {
93
try {
94
if (p != null) {
95
return AlgorithmParameters.getInstance("EC", p);
96
}
97
98
return AlgorithmParameters.getInstance("EC");
99
} catch (NoSuchAlgorithmException nsae) {
100
throw new RuntimeException(nsae);
101
}
102
}
103
104
public static byte[] encodeECParameterSpec(Provider p,
105
ECParameterSpec spec) {
106
AlgorithmParameters parameters = getECParameters(p);
107
108
try {
109
parameters.init(spec);
110
} catch (InvalidParameterSpecException ipse) {
111
throw new RuntimeException("Not a known named curve: " + spec);
112
}
113
114
try {
115
return parameters.getEncoded();
116
} catch (IOException ioe) {
117
// it is a bug if this should happen
118
throw new RuntimeException(ioe);
119
}
120
}
121
122
public static ECParameterSpec getECParameterSpec(Provider p,
123
ECParameterSpec spec) {
124
AlgorithmParameters parameters = getECParameters(p);
125
126
try {
127
parameters.init(spec);
128
return parameters.getParameterSpec(ECParameterSpec.class);
129
} catch (InvalidParameterSpecException ipse) {
130
return null;
131
}
132
}
133
134
public static ECParameterSpec getECParameterSpec(Provider p,
135
byte[] params)
136
throws IOException {
137
AlgorithmParameters parameters = getECParameters(p);
138
139
parameters.init(params);
140
141
try {
142
return parameters.getParameterSpec(ECParameterSpec.class);
143
} catch (InvalidParameterSpecException ipse) {
144
return null;
145
}
146
}
147
148
public static ECParameterSpec getECParameterSpec(Provider p, String name) {
149
AlgorithmParameters parameters = getECParameters(p);
150
151
try {
152
parameters.init(new ECGenParameterSpec(name));
153
return parameters.getParameterSpec(ECParameterSpec.class);
154
} catch (InvalidParameterSpecException ipse) {
155
return null;
156
}
157
}
158
159
public static ECParameterSpec getECParameterSpec(Provider p, int keySize) {
160
AlgorithmParameters parameters = getECParameters(p);
161
162
try {
163
parameters.init(new ECKeySizeParameterSpec(keySize));
164
return parameters.getParameterSpec(ECParameterSpec.class);
165
} catch (InvalidParameterSpecException ipse) {
166
return null;
167
}
168
169
}
170
171
public static String getCurveName(Provider p, ECParameterSpec spec) {
172
ECGenParameterSpec nameSpec;
173
AlgorithmParameters parameters = getECParameters(p);
174
175
try {
176
parameters.init(spec);
177
nameSpec = parameters.getParameterSpec(ECGenParameterSpec.class);
178
} catch (InvalidParameterSpecException ipse) {
179
return null;
180
}
181
182
if (nameSpec == null) {
183
return null;
184
}
185
186
return nameSpec.getName();
187
}
188
189
public static boolean equals(ECParameterSpec spec1, ECParameterSpec spec2) {
190
if (spec1 == spec2) {
191
return true;
192
}
193
194
if (spec1 == null || spec2 == null) {
195
return false;
196
}
197
return (spec1.getCofactor() == spec2.getCofactor() &&
198
spec1.getOrder().equals(spec2.getOrder()) &&
199
spec1.getCurve().equals(spec2.getCurve()) &&
200
spec1.getGenerator().equals(spec2.getGenerator()));
201
}
202
203
// Convert the concatenation R and S in into their DER encoding
204
public static byte[] encodeSignature(byte[] signature) throws SignatureException {
205
206
try {
207
208
int n = signature.length >> 1;
209
byte[] bytes = new byte[n];
210
System.arraycopy(signature, 0, bytes, 0, n);
211
BigInteger r = new BigInteger(1, bytes);
212
System.arraycopy(signature, n, bytes, 0, n);
213
BigInteger s = new BigInteger(1, bytes);
214
215
DerOutputStream out = new DerOutputStream(signature.length + 10);
216
out.putInteger(r);
217
out.putInteger(s);
218
DerValue result =
219
new DerValue(DerValue.tag_Sequence, out.toByteArray());
220
221
return result.toByteArray();
222
223
} catch (Exception e) {
224
throw new SignatureException("Could not encode signature", e);
225
}
226
}
227
228
// Convert the DER encoding of R and S into a concatenation of R and S
229
public static byte[] decodeSignature(byte[] sig) throws SignatureException {
230
231
try {
232
// Enforce strict DER checking for signatures
233
DerInputStream in = new DerInputStream(sig, 0, sig.length, false);
234
DerValue[] values = in.getSequence(2);
235
236
// check number of components in the read sequence
237
// and trailing data
238
if ((values.length != 2) || (in.available() != 0)) {
239
throw new IOException("Invalid encoding for signature");
240
}
241
242
BigInteger r = values[0].getPositiveBigInteger();
243
BigInteger s = values[1].getPositiveBigInteger();
244
245
// trim leading zeroes
246
byte[] rBytes = trimZeroes(r.toByteArray());
247
byte[] sBytes = trimZeroes(s.toByteArray());
248
int k = Math.max(rBytes.length, sBytes.length);
249
// r and s each occupy half the array
250
byte[] result = new byte[k << 1];
251
System.arraycopy(rBytes, 0, result, k - rBytes.length,
252
rBytes.length);
253
System.arraycopy(sBytes, 0, result, result.length - sBytes.length,
254
sBytes.length);
255
return result;
256
257
} catch (Exception e) {
258
throw new SignatureException("Invalid encoding for signature", e);
259
}
260
}
261
262
private ECUtil() {}
263
}
264
265