Skip to content

Commit

Permalink
feat(jwe): normalize compactSerialization make it a computed var like…
Browse files Browse the repository at this point in the history
… JWS instead of a func
  • Loading branch information
beatt83 committed Dec 7, 2024
1 parent 9a78a8a commit e7bd1ec
Show file tree
Hide file tree
Showing 6 changed files with 27 additions and 58 deletions.
26 changes: 13 additions & 13 deletions Sources/JSONWebEncryption/JWE.swift
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,19 @@ public struct JWE: Sendable {
/// `additionalAuthenticatedData` is optional extra data that can be authenticated along with the payload but is not encrypted.
public let additionalAuthenticatedData: Data?

/// Generates a compact serialization of the `JWE` object.
/// This serialization is a string representation consisting of base64url-encoded values separated by periods.
/// - Returns: A compact serialized string representation of the JWE object.
public var compactSerialization: String {
return [
Base64URL.encode(protectedHeaderData),
Base64URL.encode(encryptedKey ?? .init()),
Base64URL.encode(initializationVector ?? .init()),
Base64URL.encode(cipher),
Base64URL.encode(authenticationTag ?? .init())
].joined(separator: ".")
}

/// Initializes a new `JWE` object with the specified parameters.
/// - Parameters:
/// - protectedHeader: The protected header with registered fields.
Expand Down Expand Up @@ -107,17 +120,4 @@ public struct JWE: Sendable {
additionalAuthenticatedData: nil
)
}

/// Generates a compact serialization of the `JWE` object.
/// This serialization is a string representation consisting of base64url-encoded values separated by periods.
/// - Returns: A compact serialized string representation of the JWE object.
public func compactSerialization() -> String {
return [
Base64URL.encode(protectedHeaderData),
Base64URL.encode(encryptedKey ?? .init()),
Base64URL.encode(initializationVector ?? .init()),
Base64URL.encode(cipher),
Base64URL.encode(authenticationTag ?? .init())
].joined(separator: ".")
}
}
2 changes: 1 addition & 1 deletion Sources/JSONWebToken/JWT.swift
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ public struct JWT {
public var jwtString: String {
switch format {
case .jwe(let jwe):
return jwe.compactSerialization()
return jwe.compactSerialization
case .jws(let jws):
return jws.compactSerialization
}
Expand Down
2 changes: 1 addition & 1 deletion Tests/JWETests/PBES2Tests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -157,7 +157,7 @@ final class PBES2Tests: XCTestCase {
password: password,
saltLength: 16,
iterationCount: 8192
).compactSerialization()
).compactSerialization

let decrypted = try JWE.decrypt(
compactString: jweString,
Expand Down
4 changes: 2 additions & 2 deletions Tests/JWETests/RFC7516Tests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ final class RFC7516Tests: XCTestCase {
additionalAuthenticationData: nil
)

let compact = serialization.compactSerialization()
let compact = serialization.compactSerialization

let jweCompact = try JWE(compactString: compact)
let decrypted = try jweCompact.decrypt(recipientKey: recipientJWK)
Expand Down Expand Up @@ -183,7 +183,7 @@ final class RFC7516Tests: XCTestCase {
)

XCTAssertEqual(
serialization.compactSerialization(),
serialization.compactSerialization,
"""
eyJhbGciOiJBMTI4S1ciLCJlbmMiOiJBMTI4Q0JDLUhTMjU2In0.
6KB707dM9YTIgHtLvtgWQ8mKwboJW3of9locizkDTHzBC2IlrT1oOQ.
Expand Down
20 changes: 10 additions & 10 deletions Tests/JWETests/RFC7520Tests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,7 @@ final class RFC7520Tests: XCTestCase {
cek: Base64URL.decode("3qyTVhIWt5juqZUCpfRqpvauwB956MEJL2Rt-8qXKSo"),
initializationVector: Base64URL.decode("bbd5sTkYwhAIqfHsx8DayA"),
additionalAuthenticationData: nil
).compactSerialization()
).compactSerialization

let decrypted = try JWE.decrypt(
compactString: serialization,
Expand Down Expand Up @@ -226,7 +226,7 @@ final class RFC7520Tests: XCTestCase {
cek: Base64URL.decode("mYMfsggkTAm0TbvtlFh2hyoXnbEzJQjMxmgLN3d8xXA"),
initializationVector: Base64URL.decode("-nBoKLH0YkLZPSI9"),
additionalAuthenticationData: nil
).compactSerialization()
).compactSerialization

let decrypted = try JWE.decrypt(
compactString: serialization,
Expand Down Expand Up @@ -303,7 +303,7 @@ final class RFC7520Tests: XCTestCase {
cek: Base64URL.decode("Nou2ueKlP70ZXDbq9UrRwg"),
initializationVector: Base64URL.decode("mH-G2zVqgztUtnW_"),
additionalAuthenticationData: nil
).compactSerialization()
).compactSerialization

let decrypted = try JWE.decrypt(
compactString: serialization,
Expand Down Expand Up @@ -385,7 +385,7 @@ final class RFC7520Tests: XCTestCase {
cek: nil,
initializationVector: Base64URL.decode("yc9N8v5sYyv3iGQT926IUg"),
additionalAuthenticationData: nil
).compactSerialization()
).compactSerialization

let decrypted = try JWE.decrypt(
compactString: serialization,
Expand Down Expand Up @@ -465,7 +465,7 @@ final class RFC7520Tests: XCTestCase {
cek: sharedSymmetricKey.key!,
initializationVector: Base64URL.decode("refa467QzzKx6QAB"),
additionalAuthenticationData: nil
).compactSerialization()
).compactSerialization

let decrypted = try JWE.decrypt(
compactString: serialization,
Expand Down Expand Up @@ -534,7 +534,7 @@ final class RFC7520Tests: XCTestCase {
)

let decrypted = try JWE.decrypt(
compactString: serialization.compactSerialization(),
compactString: serialization.compactSerialization,
recipientKey: recipientJWK
)

Expand Down Expand Up @@ -598,7 +598,7 @@ final class RFC7520Tests: XCTestCase {
cek: Base64URL.decode("aY5_Ghmk9KxWPBLu_glx1w"),
initializationVector: Base64URL.decode("Qx0pmsDa8KnJc9Jo"),
additionalAuthenticationData: nil
).compactSerialization()
).compactSerialization

let decrypted = try JWE.decrypt(
compactString: serialization,
Expand Down Expand Up @@ -663,7 +663,7 @@ final class RFC7520Tests: XCTestCase {
cek: Base64URL.decode("hC-MpLZSuwWv8sexS6ydfw"),
initializationVector: Base64URL.decode("p9pUq6XHY0jfEZIl"),
additionalAuthenticationData: nil
).compactSerialization()
).compactSerialization

let decrypted = try JWE.decrypt(
compactString: serialization,
Expand Down Expand Up @@ -805,7 +805,7 @@ final class RFC7520Tests: XCTestCase {
recipientKey: recipientJWK,
cek: Base64URL.decode("WDgEptBmQs9ouUvArz6x6g"),
initializationVector: Base64URL.decode("WgEJsDS9bkoXQ3nR")
).compactSerialization()
).compactSerialization

let expectedSerializationTestVector = """
{
Expand Down Expand Up @@ -868,7 +868,7 @@ final class RFC7520Tests: XCTestCase {
recipientKey: recipientJWK,
cek: Base64URL.decode("WDgEptBmQs9ouUvArz6x6g"),
initializationVector: Base64URL.decode("WgEJsDS9bkoXQ3nR")
).compactSerialization()
).compactSerialization

let expectedSerializationTestVector = """
{
Expand Down
31 changes: 0 additions & 31 deletions Tests/JWTTests/JWTTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -280,37 +280,6 @@ final class JWTTests: XCTestCase {
XCTAssertTrue(areJSONStringsEqual(jsonString, expectedJSON))
}

func testJWE() throws {
let expiredAt = Date().addingTimeInterval(60)

let header = DefaultJWEHeaderImpl(
keyManagementAlgorithm: .direct,
encodingAlgorithm: .a256GCM
)

let kekData = Data(count: 256 / 8)

let jwt = try JWT.encrypt(
claims: {
ObjectClaim(key: "body") {
StringClaim(key: "foo", value: "bar")
}
IssuerClaim(value: "DLTA Studio")
ExpirationTimeClaim(value: expiredAt)
},
protectedHeader: header,
senderKey: nil,
recipientKey: nil,
sharedKey: nil,
cek: kekData
)

let jwtString = jwt.jwtString

let verifiedJWT = try JWT.verify(jwtString: jwtString, sharedKey: JWK(keyType: .octetSequence, key: kekData))
let verifiedPayload = verifiedJWT.payload
}

private func areJSONStringsEqual(_ lhs: String, _ rhs: String) -> Bool {
guard
let lhsData = lhs.data(using: .utf8),
Expand Down

0 comments on commit e7bd1ec

Please sign in to comment.