Skip to content

Commit

Permalink
[fix] updated compact parser interface
Browse files Browse the repository at this point in the history
  • Loading branch information
dtsiflit committed Oct 3, 2024
1 parent 869f944 commit 4998e78
Show file tree
Hide file tree
Showing 12 changed files with 104 additions and 72 deletions.
21 changes: 10 additions & 11 deletions Sources/Parser/CompactParser.swift
Original file line number Diff line number Diff line change
Expand Up @@ -27,23 +27,22 @@ public class CompactParser: ParserProtocol {

private static let TILDE = "~"

var serialisedString: String
var serialisationFormat: SerialisationFormat = .serialised

// MARK: - Lifecycle

public required init(serialiserProtocol: SerialiserProtocol) {
self.serialisedString = serialiserProtocol.serialised
}

public init(serialisedString: String) {
self.serialisedString = serialisedString
public init() {
}

// MARK: - Methods

public func getSignedSdJwt() throws -> SignedSDJWT {
let (serialisedJWT, disclosuresInBase64, serialisedKBJWT) = try self.parseCombined()
public func getSignedSdJwt(using serialiserProtocol: SerialiserProtocol) throws -> SignedSDJWT {
let serialisedString = serialiserProtocol.serialised
return try getSignedSdJwt(serialisedString: serialisedString)
}

public func getSignedSdJwt(serialisedString: String) throws -> SignedSDJWT {
let (serialisedJWT, disclosuresInBase64, serialisedKBJWT) = try self.parseCombined(serialisedString)
return try SignedSDJWT(serializedJwt: serialisedJWT, disclosures: disclosuresInBase64, serializedKbJwt: serialisedKBJWT)
}

Expand Down Expand Up @@ -88,8 +87,8 @@ public class CompactParser: ParserProtocol {

}

private func parseCombined() throws -> (String, [Disclosure], String?) {
let parts = self.serialisedString
private func parseCombined(_ serialisedString: String) throws -> (String, [Disclosure], String?) {
let parts = serialisedString
.split(separator: "~")
.map {String($0)}

Expand Down
35 changes: 18 additions & 17 deletions Sources/Parser/EnvelopedParser.swift
Original file line number Diff line number Diff line change
Expand Up @@ -18,31 +18,32 @@ import Foundation
public class EnvelopedParser: ParserProtocol {

// MARK: - Properties

let compactParser: ParserProtocol

// MARK: - Lifecycle

var sdJwt: SignedSDJWT
public init(
compactParser: ParserProtocol = CompactParser()
) {
self.compactParser = compactParser
}

// MARK: - Lifecycle
// MARK: - Methods

public init(serialiserProtocol: SerialiserProtocol) throws {
public func getSignedSdJwt(using serialiserProtocol: any SerialiserProtocol) throws -> SignedSDJWT {
let jsonDecoder = JSONDecoder()
let envelopedJwt = try jsonDecoder.decode(EnvelopedJwt.self, from: serialiserProtocol.data)
let compactParser = CompactParser(serialisedString: envelopedJwt.sdJwt)
self.sdJwt = try compactParser.getSignedSdJwt()
return try compactParser.getSignedSdJwt(serialisedString: envelopedJwt.sdJwt)
}

public init(data: Data) throws {
public func getSignedSdJwt(serialisedString: String) throws -> SignedSDJWT {
let jsonDecoder = JSONDecoder()
let envelopedJwt = try jsonDecoder.decode(EnvelopedJwt.self, from: data)
let compactParser = CompactParser(serialisedString: envelopedJwt.sdJwt)
self.sdJwt = try compactParser.getSignedSdJwt()
let envelopedJwt = try jsonDecoder.decode(
EnvelopedJwt.self, from: serialisedString.data(using: .utf8) ?? Data()
)
return try compactParser.getSignedSdJwt(serialisedString: envelopedJwt.sdJwt)
}

// MARK: - Methods

public func getSignedSdJwt() throws -> SignedSDJWT {
return sdJwt
}

}

public struct EnvelopedJwt: Codable {
Expand Down
17 changes: 12 additions & 5 deletions Sources/Parser/ParserProtocol.swift
Original file line number Diff line number Diff line change
Expand Up @@ -16,15 +16,22 @@
import Foundation

public protocol ParserProtocol {

func getSignedSdJwt() throws -> SignedSDJWT

// Existing method to support SerialiserProtocol
func getSignedSdJwt(using serialiserProtocol: SerialiserProtocol) throws -> SignedSDJWT

// New method to support String input
func getSignedSdJwt(serialisedString: String) throws -> SignedSDJWT
}

struct NoParser: ParserProtocol {

var sdJWT: SignedSDJWT

func getSignedSdJwt() throws -> SignedSDJWT {

func getSignedSdJwt(using serialiserProtocol: any SerialiserProtocol) throws -> SignedSDJWT {
return self.sdJWT
}

func getSignedSdJwt(serialisedString: String) throws -> SignedSDJWT {
return self.sdJWT
}
}
4 changes: 2 additions & 2 deletions Sources/Verifier/DisclosuresVerifier.swift
Original file line number Diff line number Diff line change
Expand Up @@ -62,8 +62,8 @@ public class DisclosuresVerifier: VerifierProtocol {
recreatedClaims = claimExtractor.recreatedClaims
}

convenience init(parser: ParserProtocol) throws {
try self.init(signedSDJWT: try parser.getSignedSdJwt())
convenience init(parser: ParserProtocol, serialisedString: String) throws {
try self.init(signedSDJWT: try parser.getSignedSdJwt(serialisedString: serialisedString))
}

// MARK: - Methods
Expand Down
14 changes: 9 additions & 5 deletions Sources/Verifier/SDJWTVCVerifier.swift
Original file line number Diff line number Diff line change
Expand Up @@ -81,21 +81,27 @@ public class SDJWTVCVerifier: SdJwtVcVerifierType {
/// Service for fetching issuer metadata such as public keys.
private let fetcher: any SdJwtVcIssuerMetaDataFetching

/// A parser conforming to `ParserProtocol`, responsible for parsing SD-JWTs.
private let parser: ParserProtocol

/**
* Initializes the `SDJWTVCVerifier` with dependencies for metadata fetching, certificate trust, and public key lookup.
*
* - Parameters:
* - parser: A parser responsible for parsing SD-JWTs.
* - fetcher: A service responsible for fetching issuer metadata.
* - trust: The X.509 trust configuration.
* - lookup: Optional service for looking up public keys from DIDs or DID URLs.
*/
public init(
parser: ParserProtocol = CompactParser(),
fetcher: SdJwtVcIssuerMetaDataFetching = SdJwtVcIssuerMetaDataFetcher(
session: URLSession.shared
),
trust: X509CertificateTrust = X509CertificateTrustFactory.none,
lookup: LookupPublicKeysFromDIDDocument? = nil
) {
self.parser = parser
self.fetcher = fetcher
self.trust = trust
self.lookup = lookup
Expand All @@ -110,8 +116,7 @@ public class SDJWTVCVerifier: SdJwtVcVerifierType {
func verifyIssuance(
unverifiedSdJwt: String
) async throws -> Result<SignedSDJWT, any Error> {
let parser = CompactParser(serialisedString: unverifiedSdJwt)
let jws = try parser.getSignedSdJwt().jwt
let jws = try parser.getSignedSdJwt(serialisedString: unverifiedSdJwt).jwt
let jwk = try await issuerJwsKeySelector(
jws: jws,
trust: trust,
Expand All @@ -121,9 +126,8 @@ public class SDJWTVCVerifier: SdJwtVcVerifierType {
switch jwk {
case .success(let jwk):
return try SDJWTVerifier(
parser: CompactParser(
serialisedString: unverifiedSdJwt
)
parser: parser,
serialisedString: unverifiedSdJwt
).verifyIssuance { jws in
try SignatureVerifier(
signedJWT: jws,
Expand Down
7 changes: 5 additions & 2 deletions Sources/Verifier/SDJWTVerifier.swift
Original file line number Diff line number Diff line change
Expand Up @@ -41,8 +41,11 @@ public class SDJWTVerifier {
/// - parser: A parser conforming to `ParserProtocol`.
/// - Throws: An error if the SDJWT cannot be obtained.
///
public init(parser: ParserProtocol) throws {
self.sdJwt = try parser.getSignedSdJwt()
public init(
parser: ParserProtocol = CompactParser(),
serialisedString: String
) throws {
self.sdJwt = try parser.getSignedSdJwt(serialisedString: serialisedString)
}

/// Initializes the verifier with a pre-existing SDJWT.
Expand Down
4 changes: 3 additions & 1 deletion Tests/Issuance/SignedJwtTest.swift
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,9 @@ final class SignedJwtTest: XCTestCase {
CompactSerialiser(signedSDJWT: jwt)
}

let verifier = try SDJWTVerifier(parser: CompactParser(serialisedString: serialised)).verifyIssuance { jws in
let verifier = try SDJWTVerifier(
serialisedString: serialised
).verifyIssuance { jws in
try SignatureVerifier(signedJWT: jws, publicKey: keyPair.public)
} claimVerifier: { _, _ in
ClaimsVerifier()
Expand Down
8 changes: 4 additions & 4 deletions Tests/JSONSerialization/JSONSerializationTest.swift
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,8 @@ final class JSONSerializationTest: XCTestCase {
func testSdJWTGeneralSerialization() async throws {

// Given
let parser = CompactParser(serialisedString: SDJWTConstants.compactSdJwt)
let sdJwt = try! parser.getSignedSdJwt()
let parser = CompactParser()
let sdJwt = try! parser.getSignedSdJwt(serialisedString: SDJWTConstants.compactSdJwt)

// When
let json = try sdJwt.asJwsJsonObject(
Expand Down Expand Up @@ -69,8 +69,8 @@ final class JSONSerializationTest: XCTestCase {
func testSdJWTFlattendedSerializationtest() async throws {

// Given
let parser = CompactParser(serialisedString: SDJWTConstants.compactSdJwt)
let sdJwt = try! parser.getSignedSdJwt()
let parser = CompactParser()
let sdJwt = try! parser.getSignedSdJwt(serialisedString: SDJWTConstants.compactSdJwt)

// When
let json = try sdJwt.asJwsJsonObject(
Expand Down
5 changes: 4 additions & 1 deletion Tests/SpecExamples.swift
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,10 @@ final class SpecExamples: XCTestCase {

let string = CompactSerialiser(signedSDJWT: sdjwt).serialised

let disclosureVerifierOut = try DisclosuresVerifier(parser: CompactParser(serialisedString: string)).verify()
let disclosureVerifierOut = try DisclosuresVerifier(
parser: CompactParser(),
serialisedString: string
).verify()

validateObjectResults(factoryResult: output,
expectedDigests: disclosureVerifierOut.digestsFoundOnPayload.count,
Expand Down
19 changes: 11 additions & 8 deletions Tests/Verification/SerializerTest.swift
Original file line number Diff line number Diff line change
Expand Up @@ -34,21 +34,24 @@ final class SerialiserTest: XCTestCase {

func testPareserWhenReceivingASerialisedFormatJWT_ThenConstructUnsignedSDJWT() throws {
let serialisedString = try testSerializerWhenSerializedFormatIsSelected_ThenExpectSerialisedFormattedSignedSDJWT()
let parser = CompactParser(serialisedString: serialisedString)
let jwt = try parser.getSignedSdJwt().toSDJWT()
let parser = CompactParser()
let jwt = try parser.getSignedSdJwt(serialisedString: serialisedString).toSDJWT()
print(jwt.disclosures)
}

func testSerialiseWhenChosingEnvelopeFormat_AppylingNoKeyBinding_ThenExpectACorrectJWT() throws {
let compactParser = try CompactParser(serialisedString: testSerializerWhenSerializedFormatIsSelected_ThenExpectSerialisedFormattedSignedSDJWT())

let compactParser = CompactParser()
let envelopeSerializer = try EnvelopedSerialiser(
SDJWT: compactParser.getSignedSdJwt(),
SDJWT: compactParser.getSignedSdJwt(
serialisedString: testSerializerWhenSerializedFormatIsSelected_ThenExpectSerialisedFormattedSignedSDJWT()
),
jwTpayload: JWTBody(nonce: "", aud: "sub", iat: 1234).toJSONData())

let parser = try EnvelopedParser(serialiserProtocol: envelopeSerializer)

let verifier = try SDJWTVerifier(parser: parser).verifyIssuance { jws in
let parser = EnvelopedParser()
let verifier = try SDJWTVerifier(
parser: parser,
serialisedString: envelopeSerializer.serialised
).verifyIssuance { jws in
try SignatureVerifier(signedJWT: jws, publicKey: issuersKeyPair.public)
} claimVerifier: { _, _ in
ClaimsVerifier()
Expand Down
12 changes: 6 additions & 6 deletions Tests/Verification/VcVerifierTest.swift
Original file line number Diff line number Diff line change
Expand Up @@ -91,8 +91,8 @@ final class VcVerifierTest: XCTestCase {

// Given
let sdJwtString = SDJWTConstants.x509_sd_jwt.clean()
let parser = CompactParser(serialisedString: sdJwtString)
let sdJwt = try! parser.getSignedSdJwt()
let parser = CompactParser()
let sdJwt = try! parser.getSignedSdJwt(serialisedString: sdJwtString)

// When
let json = try sdJwt.asJwsJsonObject(
Expand All @@ -116,8 +116,8 @@ final class VcVerifierTest: XCTestCase {

// Given
let sdJwtString = SDJWTConstants.x509_sd_jwt.clean()
let parser = CompactParser(serialisedString: sdJwtString)
let sdJwt = try! parser.getSignedSdJwt()
let parser = CompactParser()
let sdJwt = try! parser.getSignedSdJwt(serialisedString: sdJwtString)

// When
let json = try sdJwt.asJwsJsonObject(
Expand All @@ -141,8 +141,8 @@ final class VcVerifierTest: XCTestCase {

// Given
let sdJwtString = SDJWTConstants.issuer_metadata_sd_jwt.clean()
let parser = CompactParser(serialisedString: sdJwtString)
let sdJwt = try! parser.getSignedSdJwt()
let parser = CompactParser()
let sdJwt = try! parser.getSignedSdJwt(serialisedString: sdJwtString)

// When
let json = try sdJwt.asJwsJsonObject(
Expand Down
30 changes: 20 additions & 10 deletions Tests/Verification/VerifierTest.swift
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,10 @@ final class VerifierTest: XCTestCase {
AiV2VpZGVuc3RyYVx1MDBkZmUgMjIifV0~
""".clean()

let result = try SDJWTVerifier(parser: CompactParser(serialisedString: complexStructureSDJWTString))
let result = try SDJWTVerifier(
parser: CompactParser(),
serialisedString: complexStructureSDJWTString
)
.verifyIssuance { jws in
try SignatureVerifier(signedJWT: jws, publicKey: pk)
} claimVerifier: { _, _ in
Expand All @@ -70,8 +73,8 @@ final class VerifierTest: XCTestCase {

XCTAssertNoThrow(try result.get())

let recreatedClaimsResult = try CompactParser(serialisedString: complexStructureSDJWTString)
.getSignedSdJwt()
let recreatedClaimsResult = try CompactParser()
.getSignedSdJwt(serialisedString: complexStructureSDJWTString)
.recreateClaims()

XCTAssertTrue(recreatedClaimsResult.recreatedClaims.exists())
Expand Down Expand Up @@ -138,10 +141,12 @@ final class VerifierTest: XCTestCase {
"""
.clean()

let result = try SDJWTVerifier(parser: CompactParser(serialisedString: ComplexStructureSDJWTString))
.unsingedVerify { signedSDJWT in
try DisclosuresVerifier(signedSDJWT: signedSDJWT)
}
let result = try SDJWTVerifier(
parser: CompactParser(),
serialisedString: ComplexStructureSDJWTString
).unsingedVerify { signedSDJWT in
try DisclosuresVerifier(signedSDJWT: signedSDJWT)
}

XCTAssertNoThrow(try result.get())
}
Expand Down Expand Up @@ -337,10 +342,12 @@ final class VerifierTest: XCTestCase {
func testSerialiseWhenChosingEnvelopeFormat_AppylingEnvelopeBinding_ThenExpectACorrectJWT() throws {
let serializerTest = SerialiserTest()

let compactParser = try CompactParser(serialisedString: serializerTest.testSerializerWhenSerializedFormatIsSelected_ThenExpectSerialisedFormattedSignedSDJWT())
let compactParser = CompactParser()

let envelopeSerializer = try EnvelopedSerialiser(
SDJWT: compactParser.getSignedSdJwt(),
SDJWT: compactParser.getSignedSdJwt(
serialisedString: serializerTest.testSerializerWhenSerializedFormatIsSelected_ThenExpectSerialisedFormattedSignedSDJWT()
),
jwTpayload: JWTBody(nonce: "", aud: "sub", iat: 1234
).toJSONData())

Expand All @@ -361,7 +368,10 @@ final class VerifierTest: XCTestCase {
let envelopedJws = try JWS(jwsString: jwt.compactSerialization)

let verifyEnvelope =
try SDJWTVerifier(parser: EnvelopedParser(data: envelopeSerializer.data))
try SDJWTVerifier(
parser: EnvelopedParser(),
serialisedString: envelopeSerializer.serialised
)
.verifyEnvelope(envelope: envelopedJws) { jws in

try SignatureVerifier(signedJWT: jws, publicKey: issuersKeyPair.public)
Expand Down

0 comments on commit 4998e78

Please sign in to comment.