2362N/A * Copyright (c) 2006, Oracle and/or its affiliates. All rights reserved. 0N/A * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 0N/A * This code is free software; you can redistribute it and/or modify it 0N/A * under the terms of the GNU General Public License version 2 only, as 2362N/A * published by the Free Software Foundation. Oracle designates this 0N/A * particular file as subject to the "Classpath" exception as provided 2362N/A * by Oracle in the LICENSE file that accompanied this code. 0N/A * This code is distributed in the hope that it will be useful, but WITHOUT 0N/A * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 0N/A * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 0N/A * version 2 for more details (a copy is included in the LICENSE file that 0N/A * accompanied this code). 0N/A * You should have received a copy of the GNU General Public License version 0N/A * 2 along with this work; if not, write to the Free Software Foundation, 0N/A * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 2362N/A * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 2362N/A * or visit www.oracle.com if you need additional information or have any 0N/A * This class implements encoding and decoding of Elliptic Curve parameters 0N/A * as specified in RFC 3279. 0N/A * However, only named curves are currently supported. 0N/A * ASN.1 from RFC 3279 follows. Note that X9.62 (2005) has added some additional 0N/A * EcpkParameters ::= CHOICE { 0N/A * ecParameters ECParameters, 0N/A * namedCurve OBJECT IDENTIFIER, 0N/A * implicitlyCA NULL } 0N/A * ECParameters ::= SEQUENCE { 0N/A * version ECPVer, -- version is always 1 0N/A * fieldID FieldID, -- identifies the finite field over 0N/A * -- which the curve is defined 0N/A * curve Curve, -- coefficients a and b of the 0N/A * base ECPoint, -- specifies the base point P 0N/A * -- on the elliptic curve 0N/A * order INTEGER, -- the order n of the base point 0N/A * cofactor INTEGER OPTIONAL -- The integer h = #E(Fq)/n 0N/A * ECPVer ::= INTEGER {ecpVer1(1)} 0N/A * Curve ::= SEQUENCE { 0N/A * seed BIT STRING OPTIONAL } 0N/A * FieldElement ::= OCTET STRING 0N/A * ECPoint ::= OCTET STRING 0N/A * @author Andreas Sterbenz 0N/A // Used by SunPKCS11 and SunJSSE. 0N/A // Used by SunPKCS11 and SunJSSE. 0N/A // get field size in bytes (rounding up) 0N/A (
"Point coordinates do not match field size");
0N/A byte[] b =
new byte[
1 + (n <<
1)];
0N/A b[
0] =
4;
// uncompressed 0N/A // Copied from the SunPKCS11 code - should be moved to a common location. 0N/A // trim leading (most significant) zeroes from the result 0N/A // Convert the given ECParameterSpec object to a NamedCurve object. 0N/A // If params does not represent a known named curve, return null. 0N/A // Used by SunPKCS11. 0N/A // This is a hack to allow SunJSSE to work with 3rd party crypto 0N/A // providers for ECC and not just SunPKCS11. 0N/A // This can go away once we decide how to expose curve names in the 0N/A // Note that it assumes that the 3rd party provider encodes named 0N/A // curves using the short form, not explicitly. If it did that, then 0N/A // the SunJSSE TLS ECC extensions are wrong, which could lead to 0N/A // interoperability problems. 0N/A // ECParameterSpec does not define equals, so check all the 0N/A // components ourselves. 0N/A // Quick field size check first 0N/A // everything matches our named curve, return it 0N/A // Used by SunPKCS11. 0N/A // Used by SunPKCS11. 0N/A // The code below is incomplete. 0N/A // It is left as a starting point for a complete parsing implementation. 0N/A if (encodedParams.tag != DerValue.tag_Sequence) { 0N/A throw new IOException("Unsupported EC parameters, tag: " + encodedParams.tag); 0N/A encodedParams.data.reset(); 0N/A DerInputStream in = encodedParams.data; 0N/A int version = in.getInteger(); 0N/A throw new IOException("Unsupported EC parameters version: " + version); 0N/A ECField field = parseField(in); 0N/A EllipticCurve curve = parseCurve(in, field); 0N/A ECPoint point = parsePoint(in, curve); 0N/A BigInteger order = in.getBigInteger(); 0N/A if (in.available() != 0) { 0N/A cofactor = in.getInteger(); 0N/A // XXX HashAlgorithm optional 0N/A if (encodedParams.data.available() != 0) { 0N/A throw new IOException("encoded params have " + 0N/A encodedParams.data.available() + 0N/A return new ECParameterSpec(curve, point, order, cofactor); 0N/A private static final ObjectIdentifier fieldTypePrime = 0N/A ObjectIdentifier.newInternal(new int[] {1, 2, 840, 10045, 1, 1}); 0N/A private static final ObjectIdentifier fieldTypeChar2 = 0N/A ObjectIdentifier.newInternal(new int[] {1, 2, 840, 10045, 1, 2}); 0N/A private static ECField parseField(DerInputStream in) throws IOException { 0N/A DerValue v = in.getDerValue(); 0N/A ObjectIdentifier oid = v.data.getOID(); 0N/A if (oid.equals(fieldTypePrime) == false) { 0N/A throw new IOException("Only prime fields supported: " + oid); 0N/A BigInteger fieldSize = v.data.getBigInteger(); 0N/A return new ECFieldFp(fieldSize); 0N/A private static EllipticCurve parseCurve(DerInputStream in, ECField field) 0N/A throws IOException { 0N/A DerValue v = in.getDerValue(); 0N/A byte[] ab = v.data.getOctetString(); 0N/A byte[] bb = v.data.getOctetString(); 0N/A return new EllipticCurve(field, new BigInteger(1, ab), new BigInteger(1, bb)); 0N/A private static ECPoint parsePoint(DerInputStream in, EllipticCurve curve) 0N/A throws IOException { 0N/A byte[] data = in.getOctetString(); 0N/A return decodePoint(data, curve); 0N/A // used by ECPublicKeyImpl and ECPrivateKeyImpl 0N/A // AlgorithmParameterSpi methods 0N/A // The parameters these AlgorithmParameters object represents. 0N/A // Currently, it is always an instance of NamedCurve. 0N/A (
"paramSpec must not be null");
0N/A (
"Only ECParameterSpec and ECGenParameterSpec supported");
0N/A (
"Only ECParameterSpec and ECGenParameterSpec supported");