Skip to content

Nonce,DPoP and getIssuer() #225

@craigaps

Description

@craigaps

Hi

The method getIssuer is not providing a networking instance for the nonce poster and DPoP has no bearing on the dpopConstructor.

Here is the existing code in OpenId4VciService.swift:

func getIssuer(offer: CredentialOffer) throws -> Issuer {
   try Issuer(authorizationServerMetadata: offer.authorizationServerMetadata,
      issuerMetadata: offer.credentialIssuerMetadata, 
      config: config, 
      parPoster: Poster(session: networking), 
      tokenPoster: Poster(session: networking),
      requesterPoster: Poster(session: networking),
      deferredRequesterPoster: Poster(session: networking),
      notificationPoster: Poster(session: networking),
      dpopConstructor: try OpenId4VCIConfiguration.makeDPoPConstructor(algorithms: offer.authorizationServerMetadata.dpopSigningAlgValuesSupported))
}

Here is what it should be:

func getIssuer(offer: CredentialOffer) throws -> Issuer {
   try Issuer(authorizationServerMetadata: offer.authorizationServerMetadata,
      issuerMetadata: offer.credentialIssuerMetadata, 
      config: config, 
      parPoster: Poster(session: networking), 
      tokenPoster: Poster(session: networking),
      requesterPoster: Poster(session: networking),
      deferredRequesterPoster: Poster(session: networking),
      notificationPoster: Poster(session: networking),
      noncePoster: Poster(session: networking), 
      dpopConstructor: try OpenId4VCIConfiguration.makeDPoPConstructor(algorithms: offer.authorizationServerMetadata.dpopSigningAlgValuesSupported))
}

In addition, the useDPoP is ignored which should be checked before assigning the dpopConstructor. Perhaps something like this:

func getIssuer(offer: CredentialOffer) throws -> Issuer {
  var dpopConstructor: DPoPConstructorType? = nil
  if config.useDPoP {
    dpopConstructor = try OpenId4VCIConfiguration.makeDPoPConstructor(algorithms: offer.authorizationServerMetadata.dpopSigningAlgValuesSupported)
  }
		
  try Issuer(authorizationServerMetadata: offer.authorizationServerMetadata,
     issuerMetadata: offer.credentialIssuerMetadata,
     config: config,
     parPoster: Poster(session: networking),
     tokenPoster: Poster(session: networking),
     requesterPoster: Poster(session: networking),
     deferredRequesterPoster: Poster(session: networking),
     notificationPoster: Poster(session: networking),
     noncePoster: Poster(session: networking),
     dpopConstructor: dpopConstructor)
}

The useDPoP provided in OpenId4VCIConfiguration.swift init(...) needs to be assigned to a instance variable and carried through to the function toOpenId4VCIConfig(... useDPoP: useDPoP) -> Open4VCIConfig so that the above suggestion will compile. That will require a change in eudi-lib-ios-openid4vci-swift/Sources/Entities/Wallet/Config.swift the OpenId4VCIConfig. Something like this:

/// Configuration for OpenID4VCI.
public struct OpenId4VCIConfig: Sendable {
  
  /// The client used for OpenID4VCI operations.
  public let client: Client
  
  /// The URI to which the authentication flow should redirect.
  public let authFlowRedirectionURI: URL
  
  /// Configuration specifying how issuance authorization should be handled.
  public let authorizeIssuanceConfig: AuthorizeIssuanceConfig
  
  /// Whether to use PAR.
  public let usePAR: Bool

  /// Whether to use DPoP.
  public let useDPoP: Bool
  
  /// An optional builder for client attestation proof-of-possession tokens.
  public let clientAttestationPoPBuilder: ClientAttestationPoPBuilder?
  
  /// Policy defining how issuer metadata should be handled.
  public let issuerMetadataPolicy: IssuerMetadataPolicy
  
  /// Initializes an `OpenId4VCIConfig` instance with the given parameters.
  /// - Parameters:
  ///   - client: The client used for OpenID4VCI operations.
  ///   - authFlowRedirectionURI: The URI to which the authentication flow should redirect.
  ///   - authorizeIssuanceConfig: Specifies how issuance authorization should be handled (default: `.favorScopes`).
  ///   - usePAR: Whether to use Pushed Authorization Requests (default: `true`).
  ///   - useDPoP: Whether to use Device Proof of Possession. (default: `false`).
  ///   - clientAttestationPoPBuilder: An optional client attestation PoP builder (default: `nil`).
  ///   - issuerMetadataPolicy: Policy defining how issuer metadata should be handled (default: `.ignoreSigned`).
  public init(
    client: Client,
    authFlowRedirectionURI: URL,
    authorizeIssuanceConfig: AuthorizeIssuanceConfig = .favorScopes,
    usePAR: Bool = true,
    useDPoP: Bool = false,
    clientAttestationPoPBuilder: ClientAttestationPoPBuilder? = nil,
    issuerMetadataPolicy: IssuerMetadataPolicy = .ignoreSigned
  ) {
    self.client = client
    self.authFlowRedirectionURI = authFlowRedirectionURI
    self.authorizeIssuanceConfig = authorizeIssuanceConfig
    self.usePAR = usePAR
    self.useDPoP = useDPoP
    self.clientAttestationPoPBuilder = clientAttestationPoPBuilder
    self.issuerMetadataPolicy = issuerMetadataPolicy
  }
}

The DPoP suggestion is referred in this issue.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions