2525import java .io .StreamCorruptedException ;
2626import java .io .UncheckedIOException ;
2727import java .math .BigInteger ;
28+ import java .security .AlgorithmParameters ;
29+ import java .security .GeneralSecurityException ;
2830import java .security .interfaces .ECKey ;
2931import java .security .spec .ECField ;
30- import java .security .spec .ECFieldFp ;
32+ import java .security .spec .ECGenParameterSpec ;
3133import java .security .spec .ECParameterSpec ;
3234import java .security .spec .ECPoint ;
3335import java .security .spec .EllipticCurve ;
4345import org .apache .sshd .common .NamedResource ;
4446import org .apache .sshd .common .OptionalFeature ;
4547import org .apache .sshd .common .config .keys .KeyEntryResolver ;
48+ import org .apache .sshd .common .config .keys .KeyUtils ;
4649import org .apache .sshd .common .digest .BuiltinDigests ;
4750import org .apache .sshd .common .digest .Digest ;
4851import org .apache .sshd .common .digest .DigestFactory ;
5154import org .apache .sshd .common .util .GenericUtils ;
5255import org .apache .sshd .common .util .NumberUtils ;
5356import org .apache .sshd .common .util .ValidateUtils ;
57+ import org .apache .sshd .common .util .security .SecurityUtils ;
5458
5559/**
5660 * Utilities for working with elliptic curves.
5761 *
5862 * @author <a href="mailto:dev@mina.apache.org">Apache MINA SSHD Project</a>
5963 */
6064public enum ECCurves implements KeyTypeIndicator , KeySizeIndicator , NamedResource , OptionalFeature {
61- nistp256 (Constants .NISTP256 , new int [] { 1 , 2 , 840 , 10045 , 3 , 1 , 7 },
62- new ECParameterSpec (
63- new EllipticCurve (
64- new ECFieldFp (
65- new BigInteger ("FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFF" , 16 )),
66- new BigInteger ("FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFC" , 16 ),
67- new BigInteger ("5ac635d8aa3a93e7b3ebbd55769886bc651d06b0cc53b0f63bce3c3e27d2604b" , 16 )),
68- new ECPoint (
69- new BigInteger ("6B17D1F2E12C4247F8BCE6E563A440F277037D812DEB33A0F4A13945D898C296" , 16 ),
70- new BigInteger ("4FE342E2FE1A7F9B8EE7EB4A7C0F9E162BCE33576B315ECECBB6406837BF51F5" , 16 )),
71- new BigInteger ("FFFFFFFF00000000FFFFFFFFFFFFFFFFBCE6FAADA7179E84F3B9CAC2FC632551" , 16 ),
72- 1 ),
73- 32 ,
74- BuiltinDigests .sha256 ),
75- nistp384 (Constants .NISTP384 , new int [] { 1 , 3 , 132 , 0 , 34 },
76- new ECParameterSpec (
77- new EllipticCurve (
78- new ECFieldFp (
79- new BigInteger (
80- "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFF0000000000000000FFFFFFFF" ,
81- 16 )),
82- new BigInteger (
83- "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFF0000000000000000FFFFFFFC" ,
84- 16 ),
85- new BigInteger (
86- "B3312FA7E23EE7E4988E056BE3F82D19181D9C6EFE8141120314088F5013875AC656398D8A2ED19D2A85C8EDD3EC2AEF" ,
87- 16 )),
88- new ECPoint (
89- new BigInteger (
90- "AA87CA22BE8B05378EB1C71EF320AD746E1D3B628BA79B9859F741E082542A385502F25DBF55296C3A545E3872760AB7" ,
91- 16 ),
92- new BigInteger (
93- "3617DE4A96262C6F5D9E98BF9292DC29F8F41DBD289A147CE9DA3113B5F0B8C00A60B1CE1D7E819D7A431D7C90EA0E5F" ,
94- 16 )),
95- new BigInteger (
96- "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC7634D81F4372DDF581A0DB248B0A77AECEC196ACCC52973" ,
97- 16 ),
98- 1 ),
99- 48 ,
100- BuiltinDigests .sha384 ),
101- nistp521 (Constants .NISTP521 , new int [] { 1 , 3 , 132 , 0 , 35 },
102- new ECParameterSpec (
103- new EllipticCurve (
104- new ECFieldFp (
105- new BigInteger (
106- "01FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
107- + "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF" ,
108- 16 )),
109- new BigInteger (
110- "01FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
111- + "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC" ,
112- 16 ),
113- new BigInteger (
114- "0051953EB9618E1C9A1F929A21A0B68540EEA2DA725B99B315F3B8B489918EF109E156193951"
115- + "EC7E937B1652C0BD3BB1BF073573DF883D2C34F1EF451FD46B503F00" ,
116- 16 )),
117- new ECPoint (
118- new BigInteger (
119- "00C6858E06B70404E9CD9E3ECB662395B4429C648139053FB521F828AF606B4D3DBAA14B5E77"
120- + "EFE75928FE1DC127A2FFA8DE3348B3C1856A429BF97E7E31C2E5BD66" ,
121- 16 ),
122- new BigInteger (
123- "011839296A789A3BC0045C8A5FB42C7D1BD998F54449579B446817AFBD17273E662C97EE7299"
124- + "5EF42640C550B9013FAD0761353C7086A272C24088BE94769FD16650" ,
125- 16 )),
126- new BigInteger (
127- "01FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA51868783BF2F966B"
128- + "7FCC0148F709A5D03BB5C9B8899C47AEBB6FB71E91386409" ,
129- 16 ),
130- 1 ),
131- 66 ,
132- BuiltinDigests .sha512 );
65+
66+ // See RFC 5656: https://datatracker.ietf.org/doc/html/rfc5656#section-10.1
67+ nistp256 (Constants .NISTP256 , "secp256r1" , new int [] { 1 , 2 , 840 , 10045 , 3 , 1 , 7 }, 32 , BuiltinDigests .sha256 ),
68+ nistp384 (Constants .NISTP384 , "secp384r1" , new int [] { 1 , 3 , 132 , 0 , 34 }, 48 , BuiltinDigests .sha384 ),
69+ nistp521 (Constants .NISTP521 , "secp521r1" , new int [] { 1 , 3 , 132 , 0 , 35 }, 66 , BuiltinDigests .sha512 );
13370
13471 /**
13572 * A {@link Set} of all the known curves
@@ -159,25 +96,42 @@ public enum ECCurves implements KeyTypeIndicator, KeySizeIndicator, NamedResourc
15996 .collect (Collectors .toList ()));
16097
16198 private final String name ;
99+ private final String secName ;
162100 private final String keyType ;
163101 private final String oidString ;
164102 private final List <Integer > oidValue ;
165- private final ECParameterSpec params ;
166- private final int keySize ;
167103 private final int numOctets ;
168104 private final DigestFactory digestFactory ;
169105
170- ECCurves (String name , int [] oid , ECParameterSpec params , int numOctets , DigestFactory digestFactory ) {
106+ private ECParameterSpec params ;
107+ private volatile int keySize = -1 ;
108+
109+ ECCurves (String name , String secName , int [] oid , int numOctets , DigestFactory digestFactory ) {
171110 this .name = ValidateUtils .checkNotNullAndNotEmpty (name , "No curve name" );
111+ this .secName = ValidateUtils .checkNotNullAndNotEmpty (secName , "No SEC curve name" );
172112 this .oidString = NumberUtils .join ('.' , ValidateUtils .checkNotNullAndNotEmpty (oid , "No OID" ));
173113 this .oidValue = Collections .unmodifiableList (NumberUtils .asList (oid ));
174114 this .keyType = Constants .ECDSA_SHA2_PREFIX + name ;
175- this .params = ValidateUtils .checkNotNull (params , "No EC params for %s" , name );
176- this .keySize = getCurveSize (params );
177115 this .numOctets = numOctets ;
178116 this .digestFactory = Objects .requireNonNull (digestFactory , "No digestFactory" );
179117 }
180118
119+ private ECParameterSpec getParams (String secName ) {
120+ try {
121+ AlgorithmParameters paramsFactory = SecurityUtils .getAlgorithmParameters (KeyUtils .EC_ALGORITHM );
122+ // Although ECGenParameterSpec exists since Java 1.5 the parameter names were documented only in Java 14
123+ // with JDK-8210755. But the names were available all the time and are also supported in Bouncy Castle.
124+ //
125+ // Note that the names must not be the NIST names but the SEC names.
126+ //
127+ // See also https://www.secg.org/sec2-v2.pdf for the name definitions and the exact numerical parameters.
128+ paramsFactory .init (new ECGenParameterSpec (secName ));
129+ return paramsFactory .getParameterSpec (ECParameterSpec .class );
130+ } catch (GeneralSecurityException e ) {
131+ return null ;
132+ }
133+ }
134+
181135 @ Override // The curve's standard name
182136 public final String getName () {
183137 return name ;
@@ -202,12 +156,22 @@ public final boolean isSupported() {
202156 }
203157
204158 public final ECParameterSpec getParameters () {
205- return params ;
159+ synchronized (this ) {
160+ if (params == null ) {
161+ params = ValidateUtils .checkNotNull (getParams (secName ), "No EC params for %s" , name );
162+ }
163+ return params ;
164+ }
206165 }
207166
208167 @ Override
209168 public final int getKeySize () {
210- return keySize ;
169+ int sz = keySize ;
170+ if (sz < 0 ) {
171+ sz = getCurveSize (getParameters ());
172+ keySize = sz ;
173+ }
174+ return sz ;
211175 }
212176
213177 /**
0 commit comments