Path: blob/master/src/java.base/share/classes/sun/security/util/ECParameters.java
41159 views
/*1* Copyright (c) 2006, 2014, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation. Oracle designates this7* particular file as subject to the "Classpath" exception as provided8* by Oracle in the LICENSE file that accompanied this code.9*10* This code is distributed in the hope that it will be useful, but WITHOUT11* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or12* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License13* version 2 for more details (a copy is included in the LICENSE file that14* accompanied this code).15*16* You should have received a copy of the GNU General Public License version17* 2 along with this work; if not, write to the Free Software Foundation,18* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.19*20* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA21* or visit www.oracle.com if you need additional information or have any22* questions.23*/2425package sun.security.util;2627import java.io.IOException;2829import java.security.*;30import java.security.spec.*;3132/**33* This class implements encoding and decoding of Elliptic Curve parameters34* as specified in RFC 3279.35*36* However, only named curves are currently supported.37*38* ASN.1 from RFC 3279 follows. Note that X9.62 (2005) has added some additional39* options.40*41* <pre>42* EcpkParameters ::= CHOICE {43* ecParameters ECParameters,44* namedCurve OBJECT IDENTIFIER,45* implicitlyCA NULL }46*47* ECParameters ::= SEQUENCE {48* version ECPVer, -- version is always 149* fieldID FieldID, -- identifies the finite field over50* -- which the curve is defined51* curve Curve, -- coefficients a and b of the52* -- elliptic curve53* base ECPoint, -- specifies the base point P54* -- on the elliptic curve55* order INTEGER, -- the order n of the base point56* cofactor INTEGER OPTIONAL -- The integer h = #E(Fq)/n57* }58*59* ECPVer ::= INTEGER {ecpVer1(1)}60*61* Curve ::= SEQUENCE {62* a FieldElement,63* b FieldElement,64* seed BIT STRING OPTIONAL }65*66* FieldElement ::= OCTET STRING67*68* ECPoint ::= OCTET STRING69* </pre>70*71* @since 1.672* @author Andreas Sterbenz73*/74public final class ECParameters extends AlgorithmParametersSpi {7576// used by ECPublicKeyImpl and ECPrivateKeyImpl77public static AlgorithmParameters getAlgorithmParameters(ECParameterSpec spec)78throws InvalidKeyException {79try {80AlgorithmParameters params =81AlgorithmParameters.getInstance("EC", "SunEC");82params.init(spec);83return params;84} catch (GeneralSecurityException e) {85throw new InvalidKeyException("EC parameters error", e);86}87}8889/*90* The parameters these AlgorithmParameters object represents.91* Currently, it is always an instance of NamedCurve.92*/93private NamedCurve namedCurve;9495// A public constructor is required by AlgorithmParameters class.96public ECParameters() {97// empty98}99100// AlgorithmParameterSpi methods101102protected void engineInit(AlgorithmParameterSpec paramSpec)103throws InvalidParameterSpecException {104105if (paramSpec == null) {106throw new InvalidParameterSpecException107("paramSpec must not be null");108}109110if (paramSpec instanceof NamedCurve) {111namedCurve = (NamedCurve)paramSpec;112return;113}114115if (paramSpec instanceof ECParameterSpec) {116namedCurve = CurveDB.lookup((ECParameterSpec)paramSpec);117} else if (paramSpec instanceof ECGenParameterSpec) {118String name = ((ECGenParameterSpec)paramSpec).getName();119namedCurve = CurveDB.lookup(name);120} else if (paramSpec instanceof ECKeySizeParameterSpec) {121int keySize = ((ECKeySizeParameterSpec)paramSpec).getKeySize();122namedCurve = CurveDB.lookup(keySize);123} else {124throw new InvalidParameterSpecException125("Only ECParameterSpec and ECGenParameterSpec supported");126}127128if (namedCurve == null) {129throw new InvalidParameterSpecException(130"Not a supported curve: " + paramSpec);131}132}133134protected void engineInit(byte[] params) throws IOException {135DerValue encodedParams = new DerValue(params);136if (encodedParams.tag == DerValue.tag_ObjectId) {137ObjectIdentifier oid = encodedParams.getOID();138NamedCurve spec = CurveDB.lookup(oid.toString());139if (spec == null) {140throw new IOException("Unknown named curve: " + oid);141}142143namedCurve = spec;144return;145}146147throw new IOException("Only named ECParameters supported");148149// The code below is incomplete.150// It is left as a starting point for a complete parsing implementation.151152/*153if (encodedParams.tag != DerValue.tag_Sequence) {154throw new IOException("Unsupported EC parameters, tag: " +155encodedParams.tag);156}157158encodedParams.data.reset();159160DerInputStream in = encodedParams.data;161162int version = in.getInteger();163if (version != 1) {164throw new IOException("Unsupported EC parameters version: " +165version);166}167ECField field = parseField(in);168EllipticCurve curve = parseCurve(in, field);169ECPoint point = parsePoint(in, curve);170171BigInteger order = in.getBigInteger();172int cofactor = 0;173174if (in.available() != 0) {175cofactor = in.getInteger();176}177178// XXX HashAlgorithm optional179180if (encodedParams.data.available() != 0) {181throw new IOException("encoded params have " +182encodedParams.data.available() +183" extra bytes");184}185186return new ECParameterSpec(curve, point, order, cofactor);187*/188}189190protected void engineInit(byte[] params, String decodingMethod)191throws IOException {192engineInit(params);193}194195protected <T extends AlgorithmParameterSpec> T196engineGetParameterSpec(Class<T> spec)197throws InvalidParameterSpecException {198199if (spec.isAssignableFrom(ECParameterSpec.class)) {200return spec.cast(namedCurve);201}202203if (spec.isAssignableFrom(ECGenParameterSpec.class)) {204// Ensure the name is the Object ID205String name = namedCurve.getObjectId();206return spec.cast(new ECGenParameterSpec(name));207}208209if (spec.isAssignableFrom(ECKeySizeParameterSpec.class)) {210int keySize = namedCurve.getCurve().getField().getFieldSize();211return spec.cast(new ECKeySizeParameterSpec(keySize));212}213214throw new InvalidParameterSpecException(215"Only ECParameterSpec and ECGenParameterSpec supported");216}217218protected byte[] engineGetEncoded() throws IOException {219return namedCurve.getEncoded();220}221222protected byte[] engineGetEncoded(String encodingMethod)223throws IOException {224return engineGetEncoded();225}226227protected String engineToString() {228if (namedCurve == null) {229return "Not initialized";230}231232return namedCurve.toString();233}234}235236237238