From d7b0ef711875c0f1a1a7c933f27c95d4d90d7f00 Mon Sep 17 00:00:00 2001 From: Filippos Sakellaropoulos Date: Mon, 25 Nov 2024 22:53:18 +0200 Subject: [PATCH] Refactor RQESService to make defaultSigningAlgorithmOID optional and get it from the rssp metadata. --- README.md | 3 +-- Sources/RqesKit/RQESService.swift | 6 +++--- Sources/RqesKit/RQESServiceAuthorized.swift | 4 ++-- .../RqesKit/RQESServiceCredentialAuthorized.swift | 7 ++++--- Sources/RqesKit/RqesProtocols.swift | 3 +-- Tests/RqesKitTests/RqesKitTests.swift | 14 ++++++++++++++ 6 files changed, 25 insertions(+), 12 deletions(-) diff --git a/README.md b/README.md index 47cbd03..a7f6a8e 100644 --- a/README.md +++ b/README.md @@ -65,8 +65,7 @@ let cscClientConfig = CSCClientConfig( ) var rqesService = RQESService( clientConfig: cscClientConfig, - defaultHashAlgorithmOID: .SHA256, - defaultSigningAlgorithmOID: .RSA + defaultHashAlgorithmOID: .SHA256 ) ``` diff --git a/Sources/RqesKit/RQESService.swift b/Sources/RqesKit/RQESService.swift index 2df4ea8..f562e43 100644 --- a/Sources/RqesKit/RQESService.swift +++ b/Sources/RqesKit/RQESService.swift @@ -32,7 +32,7 @@ public class RQESService: RQESServiceProtocol, @unchecked Sendable { var state: String? var rqes: RQES! var defaultHashAlgorithmOID: HashAlgorithmOID - var defaultSigningAlgorithmOID: SigningAlgorithmOID + var defaultSigningAlgorithmOID: SigningAlgorithmOID? var fileExtension: String /// Initialize the RQES service @@ -40,10 +40,9 @@ public class RQESService: RQESServiceProtocol, @unchecked Sendable { /// - Parameter defaultHashAlgorithmOID: The default hash algorithm OID /// - Parameter defaultSigningAlgorithmOID: The default signing algorithm OID /// - Parameter fileExtension: The file extension to be used for the signed documents - required public init(clientConfig: CSCClientConfig, defaultHashAlgorithmOID: HashAlgorithmOID = .SHA256, defaultSigningAlgorithmOID: SigningAlgorithmOID = .RSA, fileExtension: String = ".pdf") { + required public init(clientConfig: CSCClientConfig, defaultHashAlgorithmOID: HashAlgorithmOID = .SHA256, fileExtension: String = ".pdf") { self.clientConfig = clientConfig self.defaultHashAlgorithmOID = defaultHashAlgorithmOID - self.defaultSigningAlgorithmOID = defaultSigningAlgorithmOID self.fileExtension = fileExtension } @@ -55,6 +54,7 @@ public class RQESService: RQESServiceProtocol, @unchecked Sendable { // STEP 2: Retrieve service information using the InfoService let request = InfoServiceRequest(lang: "en-US") let response = try await rqes.getInfo(request: request) + if let algo = response.signAlgorithms.algos.first { defaultSigningAlgorithmOID = SigningAlgorithmOID(rawValue: algo) } return response } diff --git a/Sources/RqesKit/RQESServiceAuthorized.swift b/Sources/RqesKit/RQESServiceAuthorized.swift index baec1dc..2902be1 100644 --- a/Sources/RqesKit/RQESServiceAuthorized.swift +++ b/Sources/RqesKit/RQESServiceAuthorized.swift @@ -33,10 +33,10 @@ public class RQESServiceAuthorized: RQESServiceAuthorizedProtocol, @unchecked Se var authorizationDetailsJsonString: String? var hashAlgorithmOID: HashAlgorithmOID? var defaultHashAlgorithmOID: HashAlgorithmOID - var defaultSigningAlgorithmOID: SigningAlgorithmOID + var defaultSigningAlgorithmOID: SigningAlgorithmOID? var fileExtension: String - public init(_ rqes: RQES, clientConfig: CSCClientConfig, defaultHashAlgorithmOID: HashAlgorithmOID, defaultSigningAlgorithmOID: SigningAlgorithmOID, fileExtension: String, state: String, accessToken: String) { + public init(_ rqes: RQES, clientConfig: CSCClientConfig, defaultHashAlgorithmOID: HashAlgorithmOID, defaultSigningAlgorithmOID: SigningAlgorithmOID?, fileExtension: String, state: String, accessToken: String) { self.rqes = rqes self.clientConfig = clientConfig self.defaultHashAlgorithmOID = defaultHashAlgorithmOID diff --git a/Sources/RqesKit/RQESServiceCredentialAuthorized.swift b/Sources/RqesKit/RQESServiceCredentialAuthorized.swift index cb3e5e1..89c3300 100644 --- a/Sources/RqesKit/RQESServiceCredentialAuthorized.swift +++ b/Sources/RqesKit/RQESServiceCredentialAuthorized.swift @@ -31,10 +31,10 @@ public class RQESServiceCredentialAuthorized: RQESServiceCredentialAuthorizedPro var documents: [Document] var calculateHashResponse: CalculateHashResponse var hashAlgorithmOID: HashAlgorithmOID - var defaultSigningAlgorithmOID: SigningAlgorithmOID + var defaultSigningAlgorithmOID: SigningAlgorithmOID? var fileExtension: String - public init(rqes: RQES, clientConfig: CSCClientConfig, credentialInfo: CredentialInfo, credentialAccessToken: String, documents: [Document], calculateHashResponse: CalculateHashResponse, hashAlgorithmOID: HashAlgorithmOID, defaultSigningAlgorithmOID: SigningAlgorithmOID, fileExtension: String) { + public init(rqes: RQES, clientConfig: CSCClientConfig, credentialInfo: CredentialInfo, credentialAccessToken: String, documents: [Document], calculateHashResponse: CalculateHashResponse, hashAlgorithmOID: HashAlgorithmOID, defaultSigningAlgorithmOID: SigningAlgorithmOID?, fileExtension: String) { self.rqes = rqes self.clientConfig = clientConfig self.credentialInfo = credentialInfo @@ -58,7 +58,8 @@ public class RQESServiceCredentialAuthorized: RQESServiceCredentialAuthorizedPro /// that were passed to the ``RQESServiceAuthorizedProtocol.getCredentialAuthorizationUrl`` method. public func signDocuments(signAlgorithmOID: SigningAlgorithmOID? = nil, certificates: [X509.Certificate]? = nil) async throws -> [Document] { // STEP 12: Sign the calculated hash with the credential - let signHashRequest = SignHashRequest(credentialID: credentialInfo.credentialID, hashes: calculateHashResponse.hashes, hashAlgorithmOID: hashAlgorithmOID, signAlgo: signAlgorithmOID ?? defaultSigningAlgorithmOID, operationMode: "S") + guard let signAlgo = signAlgorithmOID ?? defaultSigningAlgorithmOID else { throw NSError(domain: "RQES", code: 0, userInfo: [NSLocalizedDescriptionKey: "No signing algorithm provided"]) } + let signHashRequest = SignHashRequest(credentialID: credentialInfo.credentialID, hashes: calculateHashResponse.hashes, hashAlgorithmOID: hashAlgorithmOID, signAlgo: signAlgo, operationMode: "S") let signHashResponse = try await rqes.signHash(request: signHashRequest, accessToken: credentialAccessToken) let certs = certificates?.map(\.base64String) ?? credentialInfo.cert.certificates // STEP 13: Obtain the signed document diff --git a/Sources/RqesKit/RqesProtocols.swift b/Sources/RqesKit/RqesProtocols.swift index 8228bd0..217c0a8 100644 --- a/Sources/RqesKit/RqesProtocols.swift +++ b/Sources/RqesKit/RqesProtocols.swift @@ -26,9 +26,8 @@ public protocol RQESServiceProtocol { /// Initialize the RQES service /// - Parameter clientConfig: CSC client configuration /// - Parameter defaultHashAlgorithmOID: The default hash algorithm OID - /// - Parameter defaultSigningAlgorithmOID: The default signing algorithm OID /// - Parameter fileExtension: The file extension to be used for the signed documents - init(clientConfig: CSCClientConfig, defaultHashAlgorithmOID: HashAlgorithmOID, defaultSigningAlgorithmOID: SigningAlgorithmOID, fileExtension: String) + init(clientConfig: CSCClientConfig, defaultHashAlgorithmOID: HashAlgorithmOID, fileExtension: String) /// Retrieve the RSSP metadata func getRSSPMetadata() async throws -> RSSPMetadata /// Retrieve the service authorization URL diff --git a/Tests/RqesKitTests/RqesKitTests.swift b/Tests/RqesKitTests/RqesKitTests.swift index a79793e..93a3e40 100644 --- a/Tests/RqesKitTests/RqesKitTests.swift +++ b/Tests/RqesKitTests/RqesKitTests.swift @@ -13,3 +13,17 @@ import SwiftASN1 #expect(ser.serializedBytes == certData) #expect(Data(ser.serializedBytes).base64EncodedString() == certBase64) } + +@Test func ensureDefaultSignAlgorithmExists() async throws { + let cscClientConfig = CSCClientConfig( + OAuth2Client: CSCClientConfig.OAuth2Client(clientId: "wallet-client", clientSecret: "somesecret2"), + authFlowRedirectionURI: "https://oauthdebugger.com/debug", + scaBaseURL: "https://walletcentric.signer.eudiw.dev" +) + let rqesService = RQESService(clientConfig: cscClientConfig, defaultHashAlgorithmOID: .SHA256) + let rsspMetadata = try await rqesService.getRSSPMetadata() + #expect(rsspMetadata.signAlgorithms.algos.count > 0) + #expect(rqesService.defaultSigningAlgorithmOID != nil) + print("Default signing algorithm: \(rsspMetadata.signAlgorithms.algos.first ?? "")") + +}