Skip to content

Commit

Permalink
Add curve and parameters properties to ECDSAKey protocol (vapor#143)
Browse files Browse the repository at this point in the history
* add curve and parameters properties to ECDSAKey protocol

* move tests around since tests no longer internal

---------

Co-authored-by: Jaap Wijnen <[email protected]>
  • Loading branch information
JaapWijnen and Jaap Wijnen authored Mar 15, 2024
1 parent f97e96f commit 295a5e5
Show file tree
Hide file tree
Showing 6 changed files with 238 additions and 259 deletions.
11 changes: 7 additions & 4 deletions Sources/JWTKit/ECDSA/ECDSA.swift
Original file line number Diff line number Diff line change
Expand Up @@ -7,16 +7,19 @@ public enum ECDSA: Sendable {}

public protocol ECDSAKey: Sendable {
associatedtype Curve: ECDSACurveType

var curve: ECDSACurve { get }
var parameters: ECDSAParameters? { get }
}

public extension ECDSA {
struct PublicKey<Curve>: ECDSAKey where Curve: ECDSACurveType {
typealias Signature = Curve.Signature
typealias PublicKey = Curve.PrivateKey.PublicKey

var curve: ECDSACurve = Curve.curve
public private(set) var curve: ECDSACurve = Curve.curve

var parameters: ECDSAParameters? {
public var parameters: ECDSAParameters? {
// 0x04 || x || y
let x = backing.x963Representation[Curve.byteRanges.x].base64EncodedString()
let y = backing.x963Representation[Curve.byteRanges.y].base64EncodedString()
Expand Down Expand Up @@ -112,9 +115,9 @@ public extension ECDSA {
typealias PrivateKey = Curve.PrivateKey
typealias Signature = PrivateKey.Signature

var curve: ECDSACurve = Curve.curve
public private(set) var curve: ECDSACurve = Curve.curve

var parameters: ECDSAParameters? {
public var parameters: ECDSAParameters? {
publicKey.parameters
}

Expand Down
15 changes: 15 additions & 0 deletions Tests/JWTKitTests/ClaimTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -68,4 +68,19 @@ final class ClaimTests: XCTestCase {
XCTAssertEqual((jwtError.failedClaim as? AudienceClaim)?.value, [id1.uuidString, id2.uuidString])
}
}

func testExpirationEncoding() async throws {
let exp = ExpirationClaim(value: Date(timeIntervalSince1970: 2_000_000_000))
let parser = DefaultJWTParser()
let keyCollection = await JWTKeyCollection().addHS256(key: "secret".bytes, parser: parser)
let jwt = try await keyCollection.sign(ExpirationPayload(exp: exp))
let parsed = try parser.parse(jwt.bytes, as: ExpirationPayload.self)
let header = parsed.header
let typ = try XCTUnwrap(header.typ)
XCTAssertEqual(typ, "JWT")
let alg = try XCTUnwrap(header.alg)
XCTAssertEqual(alg, "HS256")
XCTAssertEqual(parsed.payload.exp, exp)
_ = try await keyCollection.verify(jwt, as: ExpirationPayload.self)
}
}
54 changes: 54 additions & 0 deletions Tests/JWTKitTests/ECDSATests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -231,6 +231,60 @@ final class ECDSATests: XCTestCase {
let key2 = try ES256PrivateKey(pem: key.pemRepresentation)
XCTAssertEqual(key, key2)
}

func testGetECParametersES256() async throws {
let message = "test".bytes

let ec = ES256PrivateKey()
let keys = await JWTKeyCollection().addES256(key: ec, kid: "initial")

let signature = try await keys.getKey(for: "initial").sign(message)

let params = ec.parameters!
try await keys.addES256(key: ES256PublicKey(parameters: params), kid: "params")
try await XCTAssertTrueAsync(try await keys.getKey(for: "params").verify(signature, signs: message))
XCTAssertEqual(ec.curve, .p256)
}

func testGetECParametersES384() async throws {
let message = "test".bytes

let ec = ES384PrivateKey()
let keys = await JWTKeyCollection().addES384(key: ec, kid: "initial")

let signature = try await keys.getKey(for: "initial").sign(message)

let params = ec.parameters!
try await keys.addES384(key: ES384PublicKey(parameters: params), kid: "params")
try await XCTAssertTrueAsync(try await keys.getKey(for: "params").verify(signature, signs: message))
XCTAssertEqual(ec.curve, .p384)
}

func testGetECParametersES512() async throws {
let message = "test".bytes

let ec = ES512PrivateKey()
let keys = await JWTKeyCollection().addES512(key: ec, kid: "initial")

let signature = try await keys.getKey(for: "initial").sign(message)

let params = ec.parameters!
try await keys.addES512(key: ES512PublicKey(parameters: params), kid: "params")
try await XCTAssertTrueAsync(try await keys.getKey(for: "params").verify(signature, signs: message))
XCTAssertEqual(ec.curve, .p521)
}
}

extension ECDSA.PublicKey: Equatable {
public static func == (lhs: Self, rhs: Self) -> Bool {
lhs.parameters?.x == rhs.parameters?.x && lhs.parameters?.y == rhs.parameters?.y
}
}

extension ECDSA.PrivateKey: Equatable {
public static func == (lhs: Self, rhs: Self) -> Bool {
lhs.parameters?.x == rhs.parameters?.x && lhs.parameters?.y == rhs.parameters?.y
}
}

let ecdsaPrivateKey = """
Expand Down
252 changes: 0 additions & 252 deletions Tests/JWTKitTests/InternalTests.swift

This file was deleted.

Loading

0 comments on commit 295a5e5

Please sign in to comment.