Skip to content

Commit 30eab5a

Browse files
authored
Make BoringSSL wrapper match CryptoKit behaviour when working with x9.63 (#128)
* Make BoringSSL wrapper match CryptoKit behaviour when working with x963 representation * Revert Package.swift changes * Fix Signing tests and add test cases for invalid key lengths
1 parent 5fdc8c4 commit 30eab5a

File tree

3 files changed

+57
-18
lines changed

3 files changed

+57
-18
lines changed

Sources/Crypto/Keys/EC/BoringSSL/NISTCurvesKeys_boring.swift

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -370,6 +370,16 @@ class BoringSSLECPublicKeyWrapper<Curve: OpenSSLSupportedNISTCurve> {
370370
self.key = try group.makeUnsafeOwnedECKey()
371371
try self.setPublicKey(x: &x, y: &y)
372372

373+
default:
374+
throw CryptoKitError.incorrectParameterSize
375+
}
376+
}
377+
378+
init<Bytes: ContiguousBytes>(compressedRepresentation bytes: Bytes) throws {
379+
let group = Curve.group
380+
let length = bytes.withUnsafeBytes { $0.count }
381+
382+
switch length {
373383
case group.coordinateByteCount + 1:
374384
var (x, yBit) = try bytes.readx963CompressedPublicNumbers()
375385
self.key = try group.makeUnsafeOwnedECKey()
@@ -380,12 +390,6 @@ class BoringSSLECPublicKeyWrapper<Curve: OpenSSLSupportedNISTCurve> {
380390
}
381391
}
382392

383-
convenience init<Bytes: ContiguousBytes>(compressedRepresentation bytes: Bytes) throws {
384-
// CryptoKit accepts the exact same data through init(x963Representation:) as it does through
385-
// init(compressedRepresentation:), so we do the same.
386-
try self.init(x963Representation: bytes)
387-
}
388-
389393
init<Bytes: ContiguousBytes>(rawRepresentation bytes: Bytes) throws {
390394
let group = Curve.group
391395

Tests/CryptoTests/ECDH/X25519-Runner.swift

Lines changed: 23 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -66,42 +66,42 @@ class X25519Tests: XCTestCase {
6666

6767
func testCompressedKeys() throws {
6868
let x963Positive = Data(base64Encoded: "A+QHCXtGd5WWSQgp37FBPXMy+nnSwFK79QQD0ZeNMv7L")!
69-
let key = try P256.KeyAgreement.PublicKey(x963Representation: x963Positive)
69+
let key = try P256.KeyAgreement.PublicKey(compressedRepresentation: x963Positive)
7070
XCTAssertEqual(
7171
key.x963Representation.base64EncodedString(),
7272
"BOQHCXtGd5WWSQgp37FBPXMy+nnSwFK79QQD0ZeNMv7LE6xvfFkB4Y3VXoOpB/Kp6ngpf3Lce9hDMl7fqaDUfYE="
7373
)
7474

7575
let x963Negative = Data(base64Encoded: "AuQHCXtGd5WWSQgp37FBPXMy+nnSwFK79QQD0ZeNMv7L")!
76-
let negativeKey = try P256.KeyAgreement.PublicKey(x963Representation: x963Negative)
76+
let negativeKey = try P256.KeyAgreement.PublicKey(compressedRepresentation: x963Negative)
7777
XCTAssertEqual(
7878
negativeKey.x963Representation.base64EncodedString(),
7979
"BOQHCXtGd5WWSQgp37FBPXMy+nnSwFK79QQD0ZeNMv7L7FOQgqb+HnMqoXxW+A1WFYfWgI4jhCe8zaEgVl8rgn4="
8080
)
8181

8282
let p384Positive = Data(base64Encoded: "AyEfGE5ySReJyfSruLRdsjvCB5RNWGLk8JYrzIrans3MprXf5Q4nh69bQ2rI4+DNpw==")!
83-
let p384Key = try P384.KeyAgreement.PublicKey(x963Representation: p384Positive)
83+
let p384Key = try P384.KeyAgreement.PublicKey(compressedRepresentation: p384Positive)
8484
XCTAssertEqual(
8585
p384Key.x963Representation.base64EncodedString(),
8686
"BCEfGE5ySReJyfSruLRdsjvCB5RNWGLk8JYrzIrans3MprXf5Q4nh69bQ2rI4+DNp22k0ZcxSL1Ljf19pe25Y6UgedrZf1sOLBVVDZxO36mxwUgPUqFp5/0nNmGMDdQeTQ=="
8787
)
8888

8989
let p384Negative = Data(base64Encoded: "AiEfGE5ySReJyfSruLRdsjvCB5RNWGLk8JYrzIrans3MprXf5Q4nh69bQ2rI4+DNpw==")!
90-
let p384NegativeKey = try P384.KeyAgreement.PublicKey(x963Representation: p384Negative)
90+
let p384NegativeKey = try P384.KeyAgreement.PublicKey(compressedRepresentation: p384Negative)
9191
XCTAssertEqual(
9292
p384NegativeKey.x963Representation.base64EncodedString(),
9393
"BCEfGE5ySReJyfSruLRdsjvCB5RNWGLk8JYrzIrans3MprXf5Q4nh69bQ2rI4+DNp5JbLmjOt0K0cgKCWhJGnFrfhiUmgKTx0+qq8mOxIFZNPrfwrF6WGALYyZ508ivhsg=="
9494
)
9595

9696
let p521Positive = Data(base64Encoded: "AwGUsatNKbCi6jeO1oFHpvhxesJnRxeZ45/sqCvaEZgwnpyj+/SsXjgBViEjvlJUdqentCaUFCwjuYZJM9HpdVq4Iw==")!
97-
let p521Key = try P521.KeyAgreement.PublicKey(x963Representation: p521Positive)
97+
let p521Key = try P521.KeyAgreement.PublicKey(compressedRepresentation: p521Positive)
9898
XCTAssertEqual(
9999
p521Key.x963Representation.base64EncodedString(),
100100
"BAGUsatNKbCi6jeO1oFHpvhxesJnRxeZ45/sqCvaEZgwnpyj+/SsXjgBViEjvlJUdqentCaUFCwjuYZJM9HpdVq4IwE8xEGqskayEkbPkQCGqSKfVYPZTkBdEs1ham1IXcqT4HSfoGGw98UwjQRiDPfIv0+vU6ocPbxURTdvwUSWPm72WQ=="
101101
)
102102

103103
let p521Negative = Data(base64Encoded: "AgGUsatNKbCi6jeO1oFHpvhxesJnRxeZ45/sqCvaEZgwnpyj+/SsXjgBViEjvlJUdqentCaUFCwjuYZJM9HpdVq4Iw==")!
104-
let p521NegativeKey = try P521.KeyAgreement.PublicKey(x963Representation: p521Negative)
104+
let p521NegativeKey = try P521.KeyAgreement.PublicKey(compressedRepresentation: p521Negative)
105105
XCTAssertEqual(
106106
p521NegativeKey.x963Representation.base64EncodedString(),
107107
"BAGUsatNKbCi6jeO1oFHpvhxesJnRxeZ45/sqCvaEZgwnpyj+/SsXjgBViEjvlJUdqentCaUFCwjuYZJM9HpdVq4IwDDO75VTblN7bkwbv95Vt1gqnwmsb+i7TKelZK3ojVsH4tgX55PCDrPcvud8wg3QLBQrFXjwkOrusiQPrtpwZEJpg=="
@@ -150,6 +150,23 @@ class X25519Tests: XCTestCase {
150150
p521NegativeKey.compressedRepresentation,
151151
p521Negative
152152
)
153+
154+
// Check that the uncompressed key gets rejected
155+
let uncompressedX963 = Data(base64Encoded: "BOQHCXtGd5WWSQgp37FBPXMy+nnSwFK79QQD0ZeNMv7LE6xvfFkB4Y3VXoOpB/Kp6ngpf3Lce9hDMl7fqaDUfYE=")!
156+
157+
XCTAssertThrowsError(try P256.KeyAgreement.PublicKey(compressedRepresentation: uncompressedX963))
158+
}
159+
160+
func testUncompressedKeys() throws {
161+
let uncompressedX963 = Data(base64Encoded: "BOQHCXtGd5WWSQgp37FBPXMy+nnSwFK79QQD0ZeNMv7LE6xvfFkB4Y3VXoOpB/Kp6ngpf3Lce9hDMl7fqaDUfYE=")!
162+
let key = try P256.KeyAgreement.PublicKey(x963Representation: uncompressedX963)
163+
XCTAssertEqual(
164+
key.x963Representation.base64EncodedString(),
165+
"BOQHCXtGd5WWSQgp37FBPXMy+nnSwFK79QQD0ZeNMv7LE6xvfFkB4Y3VXoOpB/Kp6ngpf3Lce9hDMl7fqaDUfYE="
166+
)
167+
168+
let compressedX963Positive = Data(base64Encoded: "A+QHCXtGd5WWSQgp37FBPXMy+nnSwFK79QQD0ZeNMv7L")!
169+
XCTAssertThrowsError(try P256.KeyAgreement.PublicKey(x963Representation: compressedX963Positive))
153170
}
154171

155172
func testWycheproof() throws {

Tests/CryptoTests/Signatures/ECDSA/ECDSASignatureTests.swift

Lines changed: 24 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -344,46 +344,64 @@ class SignatureTests: XCTestCase {
344344

345345
func testCompressedKeys() throws {
346346
let x963Positive = Data(base64Encoded: "A+QHCXtGd5WWSQgp37FBPXMy+nnSwFK79QQD0ZeNMv7L")!
347-
let key = try P256.Signing.PublicKey(x963Representation: x963Positive)
347+
let key = try P256.Signing.PublicKey(compressedRepresentation: x963Positive)
348348
XCTAssertEqual(
349349
key.x963Representation.base64EncodedString(),
350350
"BOQHCXtGd5WWSQgp37FBPXMy+nnSwFK79QQD0ZeNMv7LE6xvfFkB4Y3VXoOpB/Kp6ngpf3Lce9hDMl7fqaDUfYE="
351351
)
352352

353353
let x963Negative = Data(base64Encoded: "AuQHCXtGd5WWSQgp37FBPXMy+nnSwFK79QQD0ZeNMv7L")!
354-
let negativeKey = try P256.Signing.PublicKey(x963Representation: x963Negative)
354+
let negativeKey = try P256.Signing.PublicKey(compressedRepresentation: x963Negative)
355355
XCTAssertEqual(
356356
negativeKey.x963Representation.base64EncodedString(),
357357
"BOQHCXtGd5WWSQgp37FBPXMy+nnSwFK79QQD0ZeNMv7L7FOQgqb+HnMqoXxW+A1WFYfWgI4jhCe8zaEgVl8rgn4="
358358
)
359359

360360
let p384Positive = Data(base64Encoded: "AyEfGE5ySReJyfSruLRdsjvCB5RNWGLk8JYrzIrans3MprXf5Q4nh69bQ2rI4+DNpw==")!
361-
let p384Key = try P384.Signing.PublicKey(x963Representation: p384Positive)
361+
let p384Key = try P384.Signing.PublicKey(compressedRepresentation: p384Positive)
362362
XCTAssertEqual(
363363
p384Key.x963Representation.base64EncodedString(),
364364
"BCEfGE5ySReJyfSruLRdsjvCB5RNWGLk8JYrzIrans3MprXf5Q4nh69bQ2rI4+DNp22k0ZcxSL1Ljf19pe25Y6UgedrZf1sOLBVVDZxO36mxwUgPUqFp5/0nNmGMDdQeTQ=="
365365
)
366366

367367
let p384Negative = Data(base64Encoded: "AiEfGE5ySReJyfSruLRdsjvCB5RNWGLk8JYrzIrans3MprXf5Q4nh69bQ2rI4+DNpw==")!
368-
let p384NegativeKey = try P384.Signing.PublicKey(x963Representation: p384Negative)
368+
let p384NegativeKey = try P384.Signing.PublicKey(compressedRepresentation: p384Negative)
369369
XCTAssertEqual(
370370
p384NegativeKey.x963Representation.base64EncodedString(),
371371
"BCEfGE5ySReJyfSruLRdsjvCB5RNWGLk8JYrzIrans3MprXf5Q4nh69bQ2rI4+DNp5JbLmjOt0K0cgKCWhJGnFrfhiUmgKTx0+qq8mOxIFZNPrfwrF6WGALYyZ508ivhsg=="
372372
)
373373

374374
let p521Positive = Data(base64Encoded: "AwGUsatNKbCi6jeO1oFHpvhxesJnRxeZ45/sqCvaEZgwnpyj+/SsXjgBViEjvlJUdqentCaUFCwjuYZJM9HpdVq4Iw==")!
375-
let p521Key = try P521.Signing.PublicKey(x963Representation: p521Positive)
375+
let p521Key = try P521.Signing.PublicKey(compressedRepresentation: p521Positive)
376376
XCTAssertEqual(
377377
p521Key.x963Representation.base64EncodedString(),
378378
"BAGUsatNKbCi6jeO1oFHpvhxesJnRxeZ45/sqCvaEZgwnpyj+/SsXjgBViEjvlJUdqentCaUFCwjuYZJM9HpdVq4IwE8xEGqskayEkbPkQCGqSKfVYPZTkBdEs1ham1IXcqT4HSfoGGw98UwjQRiDPfIv0+vU6ocPbxURTdvwUSWPm72WQ=="
379379
)
380380

381381
let p521Negative = Data(base64Encoded: "AgGUsatNKbCi6jeO1oFHpvhxesJnRxeZ45/sqCvaEZgwnpyj+/SsXjgBViEjvlJUdqentCaUFCwjuYZJM9HpdVq4Iw==")!
382-
let p521NegativeKey = try P521.Signing.PublicKey(x963Representation: p521Negative)
382+
let p521NegativeKey = try P521.Signing.PublicKey(compressedRepresentation: p521Negative)
383383
XCTAssertEqual(
384384
p521NegativeKey.x963Representation.base64EncodedString(),
385385
"BAGUsatNKbCi6jeO1oFHpvhxesJnRxeZ45/sqCvaEZgwnpyj+/SsXjgBViEjvlJUdqentCaUFCwjuYZJM9HpdVq4IwDDO75VTblN7bkwbv95Vt1gqnwmsb+i7TKelZK3ojVsH4tgX55PCDrPcvud8wg3QLBQrFXjwkOrusiQPrtpwZEJpg=="
386386
)
387+
388+
// Check that the uncompressed key gets rejected
389+
let uncompressedX963 = Data(base64Encoded: "BOQHCXtGd5WWSQgp37FBPXMy+nnSwFK79QQD0ZeNMv7LE6xvfFkB4Y3VXoOpB/Kp6ngpf3Lce9hDMl7fqaDUfYE=")!
390+
391+
XCTAssertThrowsError(try P256.Signing.PublicKey(compressedRepresentation: uncompressedX963))
392+
}
393+
394+
func testUncompressedKeys() throws {
395+
let uncompressedX963 = Data(base64Encoded: "BOQHCXtGd5WWSQgp37FBPXMy+nnSwFK79QQD0ZeNMv7LE6xvfFkB4Y3VXoOpB/Kp6ngpf3Lce9hDMl7fqaDUfYE=")!
396+
let key = try P256.Signing.PublicKey(x963Representation: uncompressedX963)
397+
XCTAssertEqual(
398+
key.x963Representation.base64EncodedString(),
399+
"BOQHCXtGd5WWSQgp37FBPXMy+nnSwFK79QQD0ZeNMv7LE6xvfFkB4Y3VXoOpB/Kp6ngpf3Lce9hDMl7fqaDUfYE="
400+
)
401+
402+
let compressedX963Positive = Data(base64Encoded: "A+QHCXtGd5WWSQgp37FBPXMy+nnSwFK79QQD0ZeNMv7L")!
403+
XCTAssertThrowsError(try P256.Signing.PublicKey(x963Representation: compressedX963Positive))
387404
}
405+
388406
}
389407
#endif // (os(macOS) || os(iOS) || os(watchOS) || os(tvOS)) && CRYPTO_IN_SWIFTPM

0 commit comments

Comments
 (0)