2828import com .google .cose .utils .Headers ;
2929import com .google .crypto .tink .subtle .EcdsaSignJce ;
3030import com .google .crypto .tink .subtle .EcdsaVerifyJce ;
31+ import com .google .crypto .tink .subtle .EllipticCurves ;
32+ import com .google .crypto .tink .subtle .EllipticCurves .CurveType ;
3133import com .google .crypto .tink .subtle .EllipticCurves .EcdsaEncoding ;
3234import com .google .crypto .tink .subtle .Enums .HashType ;
35+ import com .google .crypto .tink .subtle .SubtleUtil ;
3336import java .math .BigInteger ;
3437import java .security .GeneralSecurityException ;
35- import java .security .InvalidAlgorithmParameterException ;
3638import java .security .KeyPair ;
37- import java .security .KeyPairGenerator ;
38- import java .security .NoSuchAlgorithmException ;
3939import java .security .PublicKey ;
4040import java .security .interfaces .ECPrivateKey ;
4141import java .security .interfaces .ECPublicKey ;
42- import java .security .spec .ECGenParameterSpec ;
4342import java .security .spec .ECPoint ;
4443
4544/** Implements EC2 COSE_Key spec for signing purposes. */
@@ -119,69 +118,42 @@ public ECPublicKey getPublicKey() {
119118 return (ECPublicKey ) this .keyPair .getPublic ();
120119 }
121120
122- // Big endian: Do not reuse for little endian encodings
123- private static byte [] arrayFromBigNum (BigInteger num , int keySize )
124- throws IllegalArgumentException {
125- // Roundup arithmetic from bits to bytes.
126- byte [] keyBytes = new byte [(keySize + 7 ) / 8 ];
127- byte [] keyBytes2 = num .toByteArray ();
128- if (keyBytes .length == keyBytes2 .length ) {
129- return keyBytes2 ;
130- }
131- if (keyBytes2 .length > keyBytes .length ) {
132- // There should be no more than one padding(0) byte, invalid key otherwise.
133- if (keyBytes2 .length - keyBytes .length > 1 && keyBytes2 [0 ] != 0 ) {
134- throw new IllegalArgumentException ();
135- }
136- System .arraycopy (keyBytes2 , keyBytes2 .length - keyBytes .length , keyBytes , 0 , keyBytes .length );
137- } else {
138- System .arraycopy (
139- keyBytes2 , 0 , keyBytes , keyBytes .length - keyBytes2 .length , keyBytes2 .length );
140- }
141- return keyBytes ;
142- }
143-
144121 /**
145122 * Generates a COSE formatted Ec2 signing key given a specific algorithm. The selected key size is
146123 * chosen based on section 6.2.1 of RFC 5656
147124 */
148125 public static Ec2SigningKey generateKey (Algorithm algorithm ) throws CborException , CoseException {
149- KeyPair keyPair ;
150- int keySize ;
151126 int header ;
152- String curveName ;
153-
127+ CurveType curveType ;
154128 switch (algorithm ) {
155129 case SIGNING_ALGORITHM_ECDSA_SHA_256 :
156- curveName = "secp256r1" ;
157- keySize = 256 ;
130+ curveType = CurveType .NIST_P256 ;
158131 header = Headers .CURVE_EC2_P256 ;
159132 break ;
160133
161134 case SIGNING_ALGORITHM_ECDSA_SHA_384 :
162- curveName = "secp384r1" ;
163- keySize = 384 ;
135+ curveType = CurveType .NIST_P384 ;
164136 header = Headers .CURVE_EC2_P384 ;
165137 break ;
166138
167139 case SIGNING_ALGORITHM_ECDSA_SHA_512 :
168- curveName = "secp521r1" ;
169- keySize = 521 ;
140+ curveType = CurveType .NIST_P521 ;
170141 header = Headers .CURVE_EC2_P521 ;
171142 break ;
172143
173144 default :
174145 throw new CoseException ("Unsupported algorithm curve: " + algorithm .getJavaAlgorithmId ());
175146 }
147+
148+ KeyPair keyPair ;
176149 try {
177- ECGenParameterSpec paramSpec = new ECGenParameterSpec (curveName );
178- KeyPairGenerator gen = KeyPairGenerator .getInstance ("EC" );
179- gen .initialize (paramSpec );
180- keyPair = gen .genKeyPair ();
150+ keyPair = EllipticCurves .generateKeyPair (curveType );
181151
182152 ECPoint pubPoint = ((ECPublicKey ) keyPair .getPublic ()).getW ();
183- byte [] x = arrayFromBigNum (pubPoint .getAffineX (), keySize );
184- byte [] y = arrayFromBigNum (pubPoint .getAffineY (), keySize );
153+ int keySize =
154+ EllipticCurves .fieldSizeInBytes (EllipticCurves .getCurveSpec (curveType ).getCurve ());
155+ byte [] x = SubtleUtil .integer2Bytes (pubPoint .getAffineX (), keySize );
156+ byte [] y = SubtleUtil .integer2Bytes (pubPoint .getAffineY (), keySize );
185157
186158 byte [] privEncodedKey = keyPair .getPrivate ().getEncoded ();
187159
@@ -193,10 +165,8 @@ public static Ec2SigningKey generateKey(Algorithm algorithm) throws CborExceptio
193165 .withCurve (header )
194166 .withAlgorithm (algorithm )
195167 .build ();
196- } catch (NoSuchAlgorithmException e ) {
197- throw new CoseException ("No provider for algorithm: " + algorithm .getJavaAlgorithmId (), e );
198- } catch (InvalidAlgorithmParameterException e ) {
199- throw new CoseException ("The curve is not supported: " + algorithm .getJavaAlgorithmId (), e );
168+ } catch (GeneralSecurityException e ) {
169+ throw new CoseException ("Failed generating key." , e );
200170 } catch (IllegalArgumentException e ) {
201171 throw new CoseException (
202172 "Invalid Coordinates generated for: " + algorithm .getJavaAlgorithmId (), e );
0 commit comments