Skip to content
Original file line number Diff line number Diff line change
Expand Up @@ -128,17 +128,11 @@ class ClientIdPrefixBasedAuthorizationRequestHandlerBaseClass {
)
}

var requestUriMethod : RequestUriMethod = try requestUriMethod()
let requestUriMethod : RequestUriMethod = try requestUriMethod()

var body: [String: String]? = nil
var headers: [String: String] = [Header.accept.rawValue: ContentTypes.applicationJwt.rawValue]

if(requestUriMethod == .post && walletConfig.requestUriMethodsSupported.contains(.post) == false){
// If Wallet does not support post consider it as get and proceed
OpenID4VPException.warn("Wallet does not support POST method for request_uri. Proceeding with GET method.", className: className)
requestUriMethod = .get
}

if requestUriMethod == .post {
body = [AuthorizationRequestFieldConstants.walletNonce: walletNonce]
headers[Header.contentType.rawValue] = ContentTypes.applicationFormUrlEncoded.rawValue
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ class PreRegisteredSchemeAuthorizationRequestHandler: ClientIdPrefixBasedAuthor
}

override func validateClientId() throws {
if walletConfig.validatePreRegisteredVerifier {
if walletConfig.validateTrustedVerifier {
guard walletConfig.trustedVerifiers.contains(where: { $0.clientId == authorizationRequestParameters[AuthorizationRequestFieldConstants.clientId] as? String }) else {
throw InvalidVerifier(message: "Verifier is not trusted by the wallet", className: className)
}
Expand All @@ -45,7 +45,7 @@ class PreRegisteredSchemeAuthorizationRequestHandler: ClientIdPrefixBasedAuthor


func isUnsignedRequestSupported() throws -> Bool {
if walletConfig.validatePreRegisteredVerifier {
if walletConfig.validateTrustedVerifier {
let clientId = getStringValue(authorizationRequestParameters[AuthorizationRequestFieldConstants.clientId]) ?? ""
let preRegisteredVerifier = try verifier(clientId: clientId)
return preRegisteredVerifier.allowUnsignedRequest
Expand All @@ -72,7 +72,7 @@ class PreRegisteredSchemeAuthorizationRequestHandler: ClientIdPrefixBasedAuthor
}

override func validateAndParseRequestFields() async throws {
if walletConfig.validatePreRegisteredVerifier {
if walletConfig.validateTrustedVerifier {
let clientId = authorizationRequestParameters[AuthorizationRequestFieldConstants.clientId] as! String
let preRegisteredClient = try verifier(clientId: clientId)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ func getAuthorizationRequestHandler(authorizationRequestParameters: [String:Any]
let clientId = authorizationRequestParameters[AuthorizationRequestFieldConstants.clientId] as? String ?? ""

let clientIdPrefix = try extractClientIdPrefix(authorizationRequestParams: authorizationRequestParameters)
let specVersion = findSpecVersionUsingClientId(clientId: clientId, clientIdPrefix: clientIdPrefix, trustedVerifiers: walletConfig.trustedVerifiers, checkSpecVersionInPreRegisteredList: walletConfig.validatePreRegisteredVerifier)
let specVersion = findSpecVersionUsingClientId(clientId: clientId, clientIdPrefix: clientIdPrefix, trustedVerifiers: walletConfig.trustedVerifiers, checkSpecVersionInPreRegisteredList: walletConfig.validateTrustedVerifier)

switch clientIdPrefix {
case ClientIdPrefix.preRegistered.rawValue:
Expand Down Expand Up @@ -164,7 +164,7 @@ func validateField<T>(_ field: T?, _ fieldPath: [String], _ className: String) t
}
}

func extractClientIdPrefix(authorizationRequestParams: [String:Any]) throws -> String {
func extractClientIdPrefix(authorizationRequestParams: [String:Any]) throws -> String {
try validateAttribute(AuthorizationRequestFieldConstants.clientId, values: authorizationRequestParams)
let clientId = authorizationRequestParams[AuthorizationRequestFieldConstants.clientId] as? String ?? ""

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ public class AuthorizationResponseHandler {
private var formatToCredentialInputDescriptorMapping: [FormatType: [CredentialInputDescriptorMapping]] = [:]
private var credentialToCredentialQueryIdMappingsGroupedByFormat: [FormatType: [CredentialToCredentialQueryIdMapping]] = [:]

private var unsignedVPTokenResults: [FormatType: (vpTokenSigningPayload: Any?, unsignedVPTokens: [UnsignedVPToken])] = [:]
private var unsignedVPTokenResults: [FormatType: (vpTokenSigningPayload: VPTokenSigningPayload, unsignedVPTokens: [UnsignedVPToken])] = [:]
private var specVersion: SpecVersion = .v1
private let walletConfig: WalletConfig

Expand Down Expand Up @@ -285,31 +285,12 @@ public class AuthorizationResponseHandler {
unsignedVPTokenResults: [FormatType: (Any?, [UnsignedVPToken])],
formatToCredentialInputDescriptorMapping: [FormatType: [CredentialInputDescriptorMapping]]
) throws -> (VPTokenType, PresentationSubmission) {

if Set(unsignedVPTokenResults.keys) != Set(vpTokenSigningResults.keys) {
throw InvalidData(
message: "VPTokenSigningResult not provided for the required formats",
className: Self.className
)
}

var finalVpTokens: [VPToken] = []
var finalDescriptorMappings: [DescriptorMap] = []
var rootIndex = 0

for (credentialFormat, credentialInputDescriptorMappings) in formatToCredentialInputDescriptorMapping {
guard let vpTokenSigningResultsForFormat = vpTokenSigningResults[credentialFormat] else {
throw InvalidData(
message: "unable to find the related credential format - \(credentialFormat) in the vpTokenSigningResults map",
className: Self.className
)
}
guard let unsignedVPTokenResult = unsignedVPTokenResults[credentialFormat] else {
throw InvalidData(
message: "unable to find the related credential format - \(credentialFormat) in the unsignedVPTokenResults map",
className: Self.className
)
}
let (vpTokenSigningResultsForFormat, unsignedVPTokenResult) = try getData(vpTokenSigningResults, credentialFormat: credentialFormat)

let vpTokenBuilder = try VPTokenFactory.getVPTokenBuilder(authorizationRequest: authorizationRequest, credentialFormat: credentialFormat)

Expand Down Expand Up @@ -343,29 +324,10 @@ public class AuthorizationResponseHandler {
unsignedVPTokenResults: [FormatType: (Any?, [UnsignedVPToken])],
credentialToCredentialQueryIdMappingsGroupedByFormat: [FormatType: [CredentialToCredentialQueryIdMapping]]
) throws -> [String: [VPToken]] {

if Set(unsignedVPTokenResults.keys) != Set(vpTokenSigningResults.keys) {
throw InvalidData(
message: "VPTokenSigningResult not provided for the required formats",
className: Self.className
)
}

var finalVpTokens: [String: [VPToken]] = [:]

for (credentialFormat, credentialToCredentialQueryIdMappings) in credentialToCredentialQueryIdMappingsGroupedByFormat {
guard let vpTokenSigningResultsForFormat = vpTokenSigningResults[credentialFormat] else {
throw InvalidData(
message: "unable to find the related credential format - \(credentialFormat) in the vpTokenSigningResults map",
className: Self.className
)
}
guard let unsignedVPTokenResult = unsignedVPTokenResults[credentialFormat] else {
throw InvalidData(
message: "unable to find the related credential format - \(credentialFormat) in the unsignedVPTokenResults map",
className: Self.className
)
}
let (vpTokenSigningResultsForFormat, unsignedVPTokenResult) = try getData(vpTokenSigningResults, credentialFormat: credentialFormat)

let vpTokenBuilder = try VPTokenFactory.getVPTokenBuilder(authorizationRequest: authorizationRequest, credentialFormat: credentialFormat)

Expand Down Expand Up @@ -456,6 +418,18 @@ public class AuthorizationResponseHandler {
self.credentialToCredentialQueryIdMappingsGroupedByFormat = credentialToCredentialQueryIdMappings
}

private func getData(_ vpTokenSigningResults: [FormatType: [VPTokenSigningResult]], credentialFormat: FormatType) throws -> (vpTokenSigningResultsForFormat : [VPTokenSigningResult], unsignedVPTokenResult: (vpTokenSigningPayload: VPTokenSigningPayload, unsignedVPTokens: [UnsignedVPToken])) {
let vpTokenSigningResultsForFormat = vpTokenSigningResults[credentialFormat] ?? []
guard let unsignedVPTokenResult = unsignedVPTokenResults[credentialFormat] else {
throw InvalidData(
message: "unable to find the related credential format - \(credentialFormat) in the unsignedVPTokenResults map",
className: Self.className
)
}

return (vpTokenSigningResultsForFormat, unsignedVPTokenResult)
}

private func toVerifierResponse(_ networkResponse: NetworkResponse) -> VerifierResponse {
let redirectUriKey = "redirect_uri"

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,10 @@ internal struct CredentialToCredentialQueryIdMapping {
let credentialQueryId: String
var identifier: String?

init(format: FormatType, credential: AnyCodable, credentialQueryId: String) {
init(format: FormatType, credential: AnyCodable, identifier: String? = nil, credentialQueryId: String) {
self.format = format
self.credential = credential
self.credentialQueryId = credentialQueryId
self.identifier = identifier
}
}
Original file line number Diff line number Diff line change
@@ -1,19 +1,21 @@
import Foundation

public struct UnsignedVPToken: Codable {

public let id: String
public let format: FormatType
public let holderKeyReference: String
public let signatureAlgorithm: String
// Base64 encoded byte array of the actual data to sign
public let dataToSign: Data

public init(
id: String,
format: FormatType,
holderKeyReference: String,
signatureAlgorithm: String,
dataToSign: Data
) {
self.id = id
self.format = format
self.holderKeyReference = holderKeyReference
self.signatureAlgorithm = signatureAlgorithm
Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
import Foundation

typealias VPTokenSigningPayload = Any
typealias VPTokenSigningPayload = [String: Any]

protocol UnsignedVPTokenBuilder {
var specVersion: SpecVersion { get }
var authorizationRequest: AuthorizationRequest { get }
var walletConfig: WalletConfig { get }
func build(credentialInputDescriptorMappings: inout [CredentialInputDescriptorMapping]) async throws -> (vpTokenSigningPayload: VPTokenSigningPayload?, unsignedVPTokens: [UnsignedVPToken])
func build(credentialInputDescriptorMappings: inout [CredentialInputDescriptorMapping]) async throws -> (vpTokenSigningPayload: VPTokenSigningPayload, unsignedVPTokens: [UnsignedVPToken])

func build(credentialToCredentialQueryIdMappings: inout [CredentialToCredentialQueryIdMapping]) async throws -> (vpTokenSigningPayload: VPTokenSigningPayload?, unsignedVPTokens: [UnsignedVPToken])
func build(credentialToCredentialQueryIdMappings: inout [CredentialToCredentialQueryIdMapping]) async throws -> (vpTokenSigningPayload: VPTokenSigningPayload, unsignedVPTokens: [UnsignedVPToken])
}
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ class UnsignedLdpVPTokenBuilder: UnsignedVPTokenBuilder {
self.walletConfig = walletConfig
}

func build(credentialInputDescriptorMappings: inout [CredentialInputDescriptorMapping]) async throws -> (vpTokenSigningPayload: Any?, unsignedVPTokens: [UnsignedVPToken]) {
func build(credentialInputDescriptorMappings: inout [CredentialInputDescriptorMapping]) async throws -> (vpTokenSigningPayload: VPTokenSigningPayload, unsignedVPTokens: [UnsignedVPToken]) {
guard (authorizationRequest as? AuthorizationPresentationExchangeRequest) != nil else {
throw InvalidData(message: "Expected AuthorizationPresentationExchangeRequest for Presentation Exchange flow", className: className)
}
Expand All @@ -32,9 +32,9 @@ class UnsignedLdpVPTokenBuilder: UnsignedVPTokenBuilder {

for index in 0..<credentialInputDescriptorMappings.count {
var credentialInputDescriptorMapping = credentialInputDescriptorMappings[index]
let uuid = UUIDGenerator.generateUUID()
let identifier = UUIDGenerator.generateUUID()

credentialInputDescriptorMapping.identifier = uuid
credentialInputDescriptorMapping.identifier = identifier
credentialInputDescriptorMapping.nestedPath = "$.\(Self.internalPath)[0]"
credentialInputDescriptorMappings[index] = credentialInputDescriptorMapping

Expand All @@ -46,12 +46,13 @@ class UnsignedLdpVPTokenBuilder: UnsignedVPTokenBuilder {
let result = try extractHolderAndSignatureSuite(credential)

let (vpTokenSigningPayload, unsignedVPToken) = try await buildPayloadAndUnsignedVPToken(
identifier: identifier,
with: verifiableCredentials,
signatureSuite: result.signatureSuite,
holder: sanitize(result.holder)
)

vpTokenSigningPayloads[uuid] = vpTokenSigningPayload
vpTokenSigningPayloads[identifier] = vpTokenSigningPayload
if let unsignedVPToken = unsignedVPToken {
unsignedVPTokens.append(unsignedVPToken)
}
Expand All @@ -61,7 +62,7 @@ class UnsignedLdpVPTokenBuilder: UnsignedVPTokenBuilder {
return (vpTokenSigningPayloads, unsignedVPTokens)
}

func build(credentialToCredentialQueryIdMappings: inout [CredentialToCredentialQueryIdMapping]) async throws -> (vpTokenSigningPayload: Any?, unsignedVPTokens: [UnsignedVPToken]) {
func build(credentialToCredentialQueryIdMappings: inout [CredentialToCredentialQueryIdMapping]) async throws -> (vpTokenSigningPayload: VPTokenSigningPayload, unsignedVPTokens: [UnsignedVPToken]) {
guard let authorizationRequest = authorizationRequest as? AuthorizationDcqlRequest else {
throw InvalidData(message: "Expected AuthorizationDcqlRequest for DCQL flow", className: className)
}
Expand All @@ -70,9 +71,9 @@ class UnsignedLdpVPTokenBuilder: UnsignedVPTokenBuilder {

for index in 0..<credentialToCredentialQueryIdMappings.count {
var credentialToCredentialQueryIdMapping = credentialToCredentialQueryIdMappings[index]
let uuid = UUIDGenerator.generateUUID()
let identifier = UUIDGenerator.generateUUID()

credentialToCredentialQueryIdMapping.identifier = uuid
credentialToCredentialQueryIdMapping.identifier = identifier
credentialToCredentialQueryIdMappings[index] = credentialToCredentialQueryIdMapping

let (credential, credentialQueryId) = (credentialToCredentialQueryIdMapping.credential, credentialToCredentialQueryIdMapping.credentialQueryId)
Expand All @@ -84,18 +85,19 @@ class UnsignedLdpVPTokenBuilder: UnsignedVPTokenBuilder {
}()

if(!mappedCredentialQuery.requireCryptographicHolderBinding) {
vpTokenSigningPayloads[uuid] = .vc(LdpVCToken(verifiableCredential: credential))
vpTokenSigningPayloads[identifier] = .vc(LdpVCToken(verifiableCredential: credential))
continue
}

let result = mappedCredentialQuery.requireCryptographicHolderBinding ? try extractHolderAndSignatureSuite(credential) : nil
let result = try extractHolderAndSignatureSuite(credential)
let (vpTokenSigningPayload, unsignedVPToken) = try await buildPayloadAndUnsignedVPToken(
identifier: identifier,
with: verifiableCredentials,
signatureSuite: result?.signatureSuite,
holder: sanitize(result?.holder)
signatureSuite: result.signatureSuite,
holder: sanitize(result.holder)
)

vpTokenSigningPayloads[uuid] = vpTokenSigningPayload
vpTokenSigningPayloads[identifier] = vpTokenSigningPayload
if let unsignedVPToken = unsignedVPToken {
unsignedVPTokens.append(unsignedVPToken)
}
Expand All @@ -105,7 +107,7 @@ class UnsignedLdpVPTokenBuilder: UnsignedVPTokenBuilder {
return (vpTokenSigningPayloads, unsignedVPTokens)
}

private func buildPayloadAndUnsignedVPToken(with credentials: [AnyCodable], signatureSuite: String?, holder: String?) async throws -> (vpTokenSigningPayload: LdpVP, unsignedVPToken: UnsignedVPToken?) {
private func buildPayloadAndUnsignedVPToken(identifier: String, with credentials: [AnyCodable], signatureSuite: String?, holder: String?) async throws -> (vpTokenSigningPayload: LdpVP, unsignedVPToken: UnsignedVPToken?) {
var context: [String] = ["https://www.w3.org/2018/credentials/v1"]
if signatureSuite == SignatureSuite.ed25519Signature2020.rawValue {
context.append("https://w3id.org/security/suites/ed25519-2020/v1")
Expand Down Expand Up @@ -180,6 +182,7 @@ class UnsignedLdpVPTokenBuilder: UnsignedVPTokenBuilder {


let unsignedVPToken = UnsignedVPToken(
id: identifier,
format: .ldp_vc,
holderKeyReference: holder,
signatureAlgorithm: signatureAlgorithm,
Expand Down
Loading
Loading