Skip to content

Commit

Permalink
Merge pull request #103 from niscy-eudiw/fix/async-signer-fixes
Browse files Browse the repository at this point in the history
Async signer updates
  • Loading branch information
dtsiflit authored Dec 13, 2024
2 parents 16e691a + f6a94ef commit 75baa73
Show file tree
Hide file tree
Showing 3 changed files with 107 additions and 19 deletions.
19 changes: 6 additions & 13 deletions Sources/Entities/Encryption/BindingKey.swift
Original file line number Diff line number Diff line change
Expand Up @@ -185,19 +185,12 @@ extension BindingKey {
return secKeySigner

} else if case let .custom(customAsyncSigner) = privateKey {
let signingInput: Data? = [
header as DataConvertible,
payload as DataConvertible
].map {
$0.data().base64URLEncodedString()
}
.joined(separator: ".").data(using: .ascii)

guard let signingInput = signingInput else {
throw ValidationError.error(reason: "Invalid signing input fopr signing data")
}
let headerData = header as DataConvertible
let signature = try await customAsyncSigner.signAsync(
headerData.data(),
payload.data()
)

let signature = try await customAsyncSigner.signAsync(signingInput)
let customSigner = PrecomputedSigner(
signature: signature,
algorithm: signatureAlgorithm
Expand Down Expand Up @@ -225,5 +218,5 @@ class PrecomputedSigner: JOSESwift.SignerProtocol {
}

public protocol AsyncSignerProtocol {
func signAsync(_ signingInput: Data) async throws -> Data
func signAsync(_ header: Data, _ payload: Data) async throws -> Data
}
56 changes: 51 additions & 5 deletions Tests/Constants/TestsConstants.swift
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@
* limitations under the License.
*/
import Foundation
import JOSESwift

@testable import OpenID4VCI

let CREDENTIAL_ISSUER_PUBLIC_URL = "https://dev.issuer-backend.eudiw.dev"
Expand Down Expand Up @@ -77,7 +79,7 @@ let MDL_CredentialOffer = """

let config: OpenId4VCIConfig = .init(
clientId: "wallet-dev",
authFlowRedirectionURI: URL(string: "urn:ietf:wg:oauth:2.0:oob")!,
authFlowRedirectionURI: URL(string: "urn:ietf:wg:oauth:2.0:oob")!,
authorizeIssuanceConfig: .favorScopes
)

Expand Down Expand Up @@ -146,7 +148,7 @@ struct TestsConstants {
path: "credential_issuer_metadata",
extension: "json"
)
))
))

let authorizationServerMetadataResolver = AuthorizationServerMetadataResolver(
oidcFetcher: Fetcher<OIDCProviderMetadata>(session: NetworkingMock(
Expand Down Expand Up @@ -179,7 +181,7 @@ struct TestsConstants {
path: "openid-credential-issuer_no_encryption",
extension: "json"
)
))
))

let authorizationServerMetadataResolver = AuthorizationServerMetadataResolver(
oidcFetcher: Fetcher<OIDCProviderMetadata>(session: NetworkingMock(
Expand Down Expand Up @@ -212,7 +214,7 @@ struct TestsConstants {
path: "openid-credential-issuer_no_encryption_batch",
extension: "json"
)
))
))

let authorizationServerMetadataResolver = AuthorizationServerMetadataResolver(
oidcFetcher: Fetcher<OIDCProviderMetadata>(session: NetworkingMock(
Expand Down Expand Up @@ -245,7 +247,7 @@ struct TestsConstants {
path: "credential_issuer_metadata",
extension: "json"
)
))
))

let authorizationServerMetadataResolver = AuthorizationServerMetadataResolver(
oidcFetcher: Fetcher<OIDCProviderMetadata>(session: NetworkingMock(
Expand All @@ -272,3 +274,47 @@ struct TestsConstants {
).get()
}
}

class TestSinger: AsyncSignerProtocol {
let privateKey: SecKey

init(privateKey: SecKey) {
self.privateKey = privateKey
}

func signAsync(_ header: Data, _ payload: Data) async throws -> Data {

guard
let jwsHeader = JWSHeader(header),
let algorithm = jwsHeader.algorithm
else {
throw NSError(
domain: "SignerErrorDomain",
code: 1,
userInfo: [NSLocalizedDescriptionKey: "Unable to create signer"]
)
}

/// Create the signer
guard let signer = Signer(
signatureAlgorithm: algorithm,
key: privateKey
) else {
throw NSError(
domain: "SignerErrorDomain",
code: 1,
userInfo: [NSLocalizedDescriptionKey: "Unable to create signer"]
)
}

let jws = try JWS(
header: jwsHeader,
payload: .init(
payload
),
signer: signer
)

return jws.signature
}
}
51 changes: 50 additions & 1 deletion Tests/Wallet/VCIFlowWithOffer.swift
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,55 @@ class VCIFlowWithOffer: XCTestCase {
XCTAssert(true)
}

func testWithOfferSdJWTWithSigner() async throws {

let privateKey = try KeyController.generateECDHPrivateKey()
let publicKey = try KeyController.generateECDHPublicKey(from: privateKey)

let alg = JWSAlgorithm(.ES256)
let publicKeyJWK = try ECPublicKey(
publicKey: publicKey,
additionalParameters: [
"alg": alg.name,
"use": "sig",
"kid": UUID().uuidString
])

let bindingKey: BindingKey = .jwk(
algorithm: alg,
jwk: publicKeyJWK,
privateKey: .custom(
TestSinger(
privateKey: privateKey
)
)
)

let user = ActingUser(
username: "tneal",
password: "password"
)

let wallet = Wallet(
actingUser: user,
bindingKeys: [bindingKey],
dPoPConstructor: nil,
session: Wallet.walletSession
)

do {
try await walletInitiatedIssuanceWithOfferSdJWT(
wallet: wallet
)
} catch {

XCTExpectFailure()
XCTAssert(false, error.localizedDescription)
}

XCTAssert(true)
}

func testWithOfferMdoc() async throws {

let privateKey = try KeyController.generateECDHPrivateKey()
Expand Down Expand Up @@ -315,7 +364,7 @@ private func walletInitiatedIssuanceWithOfferSdJWT(
scope: PID_SdJwtVC_config_id,
claimSet: claimSet
)

print("--> [ISSUANCE] Issued credential: \(credential)")
}

Expand Down

0 comments on commit 75baa73

Please sign in to comment.