Skip to content

Commit 4e80182

Browse files
authored
Validate coordinates when creating EC2 keys (#25)
Previously, we would simply "trust" the caller was providing legitimate points on the curve. Now, use named curves from bouncy castle to verify that the coordinates are valid.
1 parent 3de97af commit 4e80182

2 files changed

Lines changed: 31 additions & 12 deletions

File tree

src/com/google/cose/utils/CoseUtils.java

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,7 @@
6666
import org.bouncycastle.asn1.ASN1Sequence;
6767
import org.bouncycastle.asn1.DERSequenceGenerator;
6868
import org.bouncycastle.jce.ECNamedCurveTable;
69+
import org.bouncycastle.jce.spec.ECNamedCurveParameterSpec;
6970

7071
public class CoseUtils {
7172
private static final String EC_PARAMETER_SPEC = "EC";
@@ -148,8 +149,15 @@ public static ECPrivateKey getEc2PrivateKeyFromInteger(int curve, BigInteger s)
148149
public static PublicKey getEc2PublicKeyFromCoordinates(int curve, BigInteger x, BigInteger y)
149150
throws CoseException {
150151
try {
152+
final String curveName = getEc2CoseCurveName(curve);
153+
final ECNamedCurveParameterSpec spec = ECNamedCurveTable.getParameterSpec(curveName);
154+
if (spec == null) {
155+
throw new IllegalStateException("Unsupported curve: " + curveName);
156+
}
157+
spec.getCurve().validatePoint(x, y);
158+
151159
final AlgorithmParameters params = AlgorithmParameters.getInstance(EC_PARAMETER_SPEC);
152-
params.init(new ECGenParameterSpec(getEc2CoseCurveName(curve)));
160+
params.init(new ECGenParameterSpec(curveName));
153161
final ECParameterSpec ecParameters = params.getParameterSpec(ECParameterSpec.class);
154162

155163
final ECPoint ecPoint = new ECPoint(x, y);

test/com/google/cose/Ec2SigningKeyTest.java

Lines changed: 22 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -80,17 +80,28 @@ public void testRoundTrip() throws CborException, CoseException {
8080
}
8181

8282
@Test
83-
public void testConversion() throws CborException, CoseException {
84-
final String cborString = "A4010220012158205A88D182BCE5F42EFA59943F33359D2E8A968FF289D93E5FA44"
85-
+ "4B624343167FE225820B16E8CF858DDC7690407BA61D4C338237A8CFCF3DE6AA672FC60A557AA32FC67";
86-
final ByteString x = new ByteString(X_BYTES);
87-
final ByteString y = new ByteString(Y_BYTES);
88-
final Ec2SigningKey sKey = Ec2SigningKey.parse(TestUtilities.hexStringToByteArray(cborString));
89-
Assert.assertEquals(Headers.KEY_TYPE_EC2, sKey.getKeyType());
90-
Assert.assertEquals(new UnsignedInteger(Headers.CURVE_EC2_P256),
91-
sKey.getLabels().get(Headers.KEY_PARAMETER_CURVE));
92-
Assert.assertEquals(x, sKey.getLabels().get(Headers.KEY_PARAMETER_X));
93-
Assert.assertEquals(y, sKey.getLabels().get(Headers.KEY_PARAMETER_Y));
83+
public void testCoordinatesNotOnCurve() {
84+
final int[] allCurves = new int[]{
85+
Headers.CURVE_EC2_P256,
86+
Headers.CURVE_EC2_P384,
87+
Headers.CURVE_EC2_P521
88+
};
89+
90+
for (int curve: allCurves) {
91+
final Map map = new Map();
92+
map.put(new UnsignedInteger(Headers.KEY_PARAMETER_KEY_TYPE),
93+
new UnsignedInteger(Headers.KEY_TYPE_EC2));
94+
map.put(new NegativeInteger(Headers.KEY_PARAMETER_CURVE), new UnsignedInteger(curve));
95+
map.put(new NegativeInteger(Headers.KEY_PARAMETER_X),
96+
new ByteString(
97+
TestUtilities.hexStringToByteArray(
98+
"59cc8d401bbd23517c7b5e948d269190d2a897e9061d1af3bc0398d77edd1400")));
99+
map.put(new NegativeInteger(Headers.KEY_PARAMETER_Y),
100+
new ByteString(
101+
TestUtilities.hexStringToByteArray(
102+
"77550f5dbc8b3fbbb35c099961d51a956c7228c6e36aeccb4c95ac69cf27f7e6")));
103+
assertThrows(IllegalArgumentException.class, () -> new Ec2SigningKey(map));
104+
}
94105
}
95106

96107
@Test

0 commit comments

Comments
 (0)