History

My first initial commit with all of mine experimental changes.

Dmitry Kabak (userdima committed 13 years ago

Commit d37b88d1 parent 3f5b46618352 files · +2598093 −-8690Browse files

Showing the changes to java/pkg/sun/security/ec/ECParameters.java (1 of 18352 files). Show all

Unified · Split

java/pkg/sun/security/ec/ECParameters.java+349−0
@@ -0,0 +1,349 @@
1+/*
2+ * Copyright (c) 2006, 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;
27+
28+import java.io.IOException;
29+import java.math.BigInteger;
30+
31+import java.security.*;
32+import java.security.spec.*;
33+
34+import sun.security.util.*;
35+
36+/**
37+ * This class implements encoding and decoding of Elliptic Curve parameters
38+ * as specified in RFC 3279.
39+ *
40+ * However, only named curves are currently supported.
41+ *
42+ * ASN.1 from RFC 3279 follows. Note that X9.62 (2005) has added some additional
43+ * options.
44+ *
45+ * <pre>
46+ * EcpkParameters ::= CHOICE {
47+ * ecParameters ECParameters,
48+ * namedCurve OBJECT IDENTIFIER,
49+ * implicitlyCA NULL }
50+ *
51+ * ECParameters ::= SEQUENCE {
52+ * version ECPVer, -- version is always 1
53+ * fieldID FieldID, -- identifies the finite field over
54+ * -- which the curve is defined
55+ * curve Curve, -- coefficients a and b of the
56+ * -- elliptic curve
57+ * base ECPoint, -- specifies the base point P
58+ * -- on the elliptic curve
59+ * order INTEGER, -- the order n of the base point
60+ * cofactor INTEGER OPTIONAL -- The integer h = #E(Fq)/n
61+ * }
62+ *
63+ * ECPVer ::= INTEGER {ecpVer1(1)}
64+ *
65+ * Curve ::= SEQUENCE {
66+ * a FieldElement,
67+ * b FieldElement,
68+ * seed BIT STRING OPTIONAL }
69+ *
70+ * FieldElement ::= OCTET STRING
71+ *
72+ * ECPoint ::= OCTET STRING
73+ * </pre>
74+ *
75+ * @since 1.6
76+ * @author Andreas Sterbenz
77+ */
78+public final class ECParameters extends AlgorithmParametersSpi {
79+
80+ public ECParameters() {
81+ // empty
82+ }
83+
84+ // Used by SunPKCS11 and SunJSSE.
85+ public static ECPoint decodePoint(byte[] data, EllipticCurve curve)
86+ throws IOException {
87+ if ((data.length == 0) || (data[0] != 4)) {
88+ throw new IOException("Only uncompressed point format supported");
89+ }
90+ int n = (curve.getField().getFieldSize() + 7 ) >> 3;
91+ if (data.length != (n * 2) + 1) {
92+ throw new IOException("Point does not match field size");
93+ }
94+ byte[] xb = new byte[n];
95+ byte[] yb = new byte[n];
96+ System.arraycopy(data, 1, xb, 0, n);
97+ System.arraycopy(data, n + 1, yb, 0, n);
98+ return new ECPoint(new BigInteger(1, xb), new BigInteger(1, yb));
99+ }
100+
101+ // Used by SunPKCS11 and SunJSSE.
102+ public static byte[] encodePoint(ECPoint point, EllipticCurve curve) {
103+ // get field size in bytes (rounding up)
104+ int n = (curve.getField().getFieldSize() + 7) >> 3;
105+ byte[] xb = trimZeroes(point.getAffineX().toByteArray());
106+ byte[] yb = trimZeroes(point.getAffineY().toByteArray());
107+ if ((xb.length > n) || (yb.length > n)) {
108+ throw new RuntimeException
109+ ("Point coordinates do not match field size");
110+ }
111+ byte[] b = new byte[1 + (n << 1)];
112+ b[0] = 4; // uncompressed
113+ System.arraycopy(xb, 0, b, n - xb.length + 1, xb.length);
114+ System.arraycopy(yb, 0, b, b.length - yb.length, yb.length);
115+ return b;
116+ }
117+
118+ // Copied from the SunPKCS11 code - should be moved to a common location.
119+ // trim leading (most significant) zeroes from the result
120+ static byte[] trimZeroes(byte[] b) {
121+ int i = 0;
122+ while ((i < b.length - 1) && (b[i] == 0)) {
123+ i++;
124+ }
125+ if (i == 0) {
126+ return b;
127+ }
128+ byte[] t = new byte[b.length - i];
129+ System.arraycopy(b, i, t, 0, t.length);
130+ return t;
131+ }
132+
133+ // Convert the given ECParameterSpec object to a NamedCurve object.
134+ // If params does not represent a known named curve, return null.
135+ // Used by SunPKCS11.
136+ public static NamedCurve getNamedCurve(ECParameterSpec params) {
137+ if ((params instanceof NamedCurve) || (params == null)) {
138+ return (NamedCurve)params;
139+ }
140+ // This is a hack to allow SunJSSE to work with 3rd party crypto
141+ // providers for ECC and not just SunPKCS11.
142+ // This can go away once we decide how to expose curve names in the
143+ // public API.
144+ // Note that it assumes that the 3rd party provider encodes named
145+ // curves using the short form, not explicitly. If it did that, then
146+ // the SunJSSE TLS ECC extensions are wrong, which could lead to
147+ // interoperability problems.
148+ int fieldSize = params.getCurve().getField().getFieldSize();
149+ for (ECParameterSpec namedCurve : NamedCurve.knownECParameterSpecs()) {
150+ // ECParameterSpec does not define equals, so check all the
151+ // components ourselves.
152+ // Quick field size check first
153+ if (namedCurve.getCurve().getField().getFieldSize() != fieldSize) {
154+ continue;
155+ }
156+ if (namedCurve.getCurve().equals(params.getCurve()) == false) {
157+ continue;
158+ }
159+ if (namedCurve.getGenerator().equals(params.getGenerator()) == false) {
160+ continue;
161+ }
162+ if (namedCurve.getOrder().equals(params.getOrder()) == false) {
163+ continue;
164+ }
165+ if (namedCurve.getCofactor() != params.getCofactor()) {
166+ continue;
167+ }
168+ // everything matches our named curve, return it
169+ return (NamedCurve)namedCurve;
170+ }
171+ // no match found
172+ return null;
173+ }
174+
175+ // Used by SunJSSE.
176+ public static String getCurveName(ECParameterSpec params) {
177+ NamedCurve curve = getNamedCurve(params);
178+ return (curve == null) ? null : curve.getObjectIdentifier().toString();
179+ }
180+
181+ // Used by SunPKCS11.
182+ public static byte[] encodeParameters(ECParameterSpec params) {
183+ NamedCurve curve = getNamedCurve(params);
184+ if (curve == null) {
185+ throw new RuntimeException("Not a known named curve: " + params);
186+ }
187+ return curve.getEncoded();
188+ }
189+
190+ // Used by SunPKCS11.
191+ public static ECParameterSpec decodeParameters(byte[] params) throws IOException {
192+ DerValue encodedParams = new DerValue(params);
193+ if (encodedParams.tag == DerValue.tag_ObjectId) {
194+ ObjectIdentifier oid = encodedParams.getOID();
195+ ECParameterSpec spec = NamedCurve.getECParameterSpec(oid);
196+ if (spec == null) {
197+ throw new IOException("Unknown named curve: " + oid);
198+ }
199+ return spec;
200+ }
201+
202+ throw new IOException("Only named ECParameters supported");
203+
204+ // The code below is incomplete.
205+ // It is left as a starting point for a complete parsing implementation.
206+
207+/*
208+ if (encodedParams.tag != DerValue.tag_Sequence) {
209+ throw new IOException("Unsupported EC parameters, tag: " + encodedParams.tag);
210+ }
211+
212+ encodedParams.data.reset();
213+
214+ DerInputStream in = encodedParams.data;
215+
216+ int version = in.getInteger();
217+ if (version != 1) {
218+ throw new IOException("Unsupported EC parameters version: " + version);
219+ }
220+ ECField field = parseField(in);
221+ EllipticCurve curve = parseCurve(in, field);
222+ ECPoint point = parsePoint(in, curve);
223+
224+ BigInteger order = in.getBigInteger();
225+ int cofactor = 0;
226+
227+ if (in.available() != 0) {
228+ cofactor = in.getInteger();
229+ }
230+
231+ // XXX HashAlgorithm optional
232+
233+ if (encodedParams.data.available() != 0) {
234+ throw new IOException("encoded params have " +
235+ encodedParams.data.available() +
236+ " extra bytes");
237+ }
238+
239+ return new ECParameterSpec(curve, point, order, cofactor);
240+*/
241+ }
242+
243+/*
244+ private static final ObjectIdentifier fieldTypePrime =
245+ ObjectIdentifier.newInternal(new int[] {1, 2, 840, 10045, 1, 1});
246+
247+ private static final ObjectIdentifier fieldTypeChar2 =
248+ ObjectIdentifier.newInternal(new int[] {1, 2, 840, 10045, 1, 2});
249+
250+ private static ECField parseField(DerInputStream in) throws IOException {
251+ DerValue v = in.getDerValue();
252+ ObjectIdentifier oid = v.data.getOID();
253+ if (oid.equals(fieldTypePrime) == false) {
254+ throw new IOException("Only prime fields supported: " + oid);
255+ }
256+ BigInteger fieldSize = v.data.getBigInteger();
257+ return new ECFieldFp(fieldSize);
258+ }
259+
260+ private static EllipticCurve parseCurve(DerInputStream in, ECField field)
261+ throws IOException {
262+ DerValue v = in.getDerValue();
263+ byte[] ab = v.data.getOctetString();
264+ byte[] bb = v.data.getOctetString();
265+ return new EllipticCurve(field, new BigInteger(1, ab), new BigInteger(1, bb));
266+ }
267+
268+ private static ECPoint parsePoint(DerInputStream in, EllipticCurve curve)
269+ throws IOException {
270+ byte[] data = in.getOctetString();
271+ return decodePoint(data, curve);
272+ }
273+*/
274+
275+ // used by ECPublicKeyImpl and ECPrivateKeyImpl
276+ static AlgorithmParameters getAlgorithmParameters(ECParameterSpec spec)
277+ throws InvalidKeyException {
278+ try {
279+ AlgorithmParameters params = AlgorithmParameters.getInstance
280+ ("EC", ECKeyFactory.ecInternalProvider);
281+ params.init(spec);
282+ return params;
283+ } catch (GeneralSecurityException e) {
284+ throw new InvalidKeyException("EC parameters error", e);
285+ }
286+ }
287+
288+ // AlgorithmParameterSpi methods
289+
290+ // The parameters these AlgorithmParameters object represents.
291+ // Currently, it is always an instance of NamedCurve.
292+ private ECParameterSpec paramSpec;
293+
294+ protected void engineInit(AlgorithmParameterSpec paramSpec)
295+ throws InvalidParameterSpecException {
296+ if (paramSpec instanceof ECParameterSpec) {
297+ this.paramSpec = getNamedCurve((ECParameterSpec)paramSpec);
298+ if (this.paramSpec == null) {
299+ throw new InvalidParameterSpecException
300+ ("Not a supported named curve: " + paramSpec);
301+ }
302+ } else if (paramSpec instanceof ECGenParameterSpec) {
303+ String name = ((ECGenParameterSpec)paramSpec).getName();
304+ ECParameterSpec spec = NamedCurve.getECParameterSpec(name);
305+ if (spec == null) {
306+ throw new InvalidParameterSpecException("Unknown curve: " + name);
307+ }
308+ this.paramSpec = spec;
309+ } else if (paramSpec == null) {
310+ throw new InvalidParameterSpecException
311+ ("paramSpec must not be null");
312+ } else {
313+ throw new InvalidParameterSpecException
314+ ("Only ECParameterSpec and ECGenParameterSpec supported");
315+ }
316+ }
317+
318+ protected void engineInit(byte[] params) throws IOException {
319+ paramSpec = decodeParameters(params);
320+ }
321+
322+ protected void engineInit(byte[] params, String decodingMethod) throws IOException {
323+ engineInit(params);
324+ }
325+
326+ protected <T extends AlgorithmParameterSpec> T engineGetParameterSpec(Class<T> spec)
327+ throws InvalidParameterSpecException {
328+ if (spec.isAssignableFrom(ECParameterSpec.class)) {
329+ return (T)paramSpec;
330+ } else if (spec.isAssignableFrom(ECGenParameterSpec.class)) {
331+ return (T)new ECGenParameterSpec(getCurveName(paramSpec));
332+ } else {
333+ throw new InvalidParameterSpecException
334+ ("Only ECParameterSpec and ECGenParameterSpec supported");
335+ }
336+ }
337+
338+ protected byte[] engineGetEncoded() throws IOException {
339+ return encodeParameters(paramSpec);
340+ }
341+
342+ protected byte[] engineGetEncoded(String encodingMethod) throws IOException {
343+ return engineGetEncoded();
344+ }
345+
346+ protected String engineToString() {
347+ return paramSpec.toString();
348+ }
349+}