Skip to content

Commit 511f6f7

Browse files
committed
Use Tink utility to turn BigInteger to bytes.
Replace the custom implementation of positive BigInteger conversion to a padded byte array with the utility provided by Tink.
1 parent ea26416 commit 511f6f7

File tree

1 file changed

+16
-46
lines changed

1 file changed

+16
-46
lines changed

src/com/google/cose/Ec2SigningKey.java

Lines changed: 16 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -28,18 +28,17 @@
2828
import com.google.cose.utils.Headers;
2929
import com.google.crypto.tink.subtle.EcdsaSignJce;
3030
import com.google.crypto.tink.subtle.EcdsaVerifyJce;
31+
import com.google.crypto.tink.subtle.EllipticCurves;
32+
import com.google.crypto.tink.subtle.EllipticCurves.CurveType;
3133
import com.google.crypto.tink.subtle.EllipticCurves.EcdsaEncoding;
3234
import com.google.crypto.tink.subtle.Enums.HashType;
35+
import com.google.crypto.tink.subtle.SubtleUtil;
3336
import java.math.BigInteger;
3437
import java.security.GeneralSecurityException;
35-
import java.security.InvalidAlgorithmParameterException;
3638
import java.security.KeyPair;
37-
import java.security.KeyPairGenerator;
38-
import java.security.NoSuchAlgorithmException;
3939
import java.security.PublicKey;
4040
import java.security.interfaces.ECPrivateKey;
4141
import java.security.interfaces.ECPublicKey;
42-
import java.security.spec.ECGenParameterSpec;
4342
import 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

Comments
 (0)