Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
//===----------------------------------------------------------------------===//
//
// This source file is part of the Swift WebAuthn open source project
//
// Copyright (c) 2022 the Swift WebAuthn project authors
// Licensed under Apache License v2.0
//
// See LICENSE.txt for license information
//
// SPDX-License-Identifier: Apache-2.0
//
//===----------------------------------------------------------------------===//

import Foundation

/// A dictionary describing the Relying Party's requirements regarding authenticator attributes.
///
/// - SeeAlso: https://www.w3.org/TR/webauthn-2/#dictdef-authenticatorselectioncriteria
public struct AuthenticatorSelection: Codable, Sendable {
/// If present, indicates the Relying Party's preference for authenticator attachment.
public var authenticatorAttachment: AuthenticatorAttachment?

/// Describes the Relying Party's requirements regarding whether the authenticator should create a client-side-resident public key credential source.
public var residentKey: ResidentKeyRequirement?

/// Describes the Relying Party's requirements regarding user verification.
public var userVerification: UserVerificationRequirement?

public init(
authenticatorAttachment: AuthenticatorAttachment? = nil,
residentKey: ResidentKeyRequirement? = nil,
userVerification: UserVerificationRequirement? = nil
) {
self.authenticatorAttachment = authenticatorAttachment
self.residentKey = residentKey
self.userVerification = userVerification
}
}

Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,9 @@ public struct PublicKeyCredentialCreationOptions: Sendable {
/// Sets the Relying Party's preference for attestation conveyance. At the time of writing only ``AttestationConveyancePreference/none`` is supported.
public var attestation: AttestationConveyancePreference

/// A dictionary describing the Relying Party's requirements regarding authenticator attributes.
public var authenticatorSelection: AuthenticatorSelection?

/// Initialize a credential creation options dictionary directly.
///
/// - Warning: Manually initializing options dictionaries can easily lead to insecure implementations of the WebAuthn protocol. Whenever possible, create an options dictionary using ``WebAuthnManager/beginRegistration(user:timeout:attestation:publicKeyCredentialParameters:)`` instead.
Expand All @@ -64,20 +67,23 @@ public struct PublicKeyCredentialCreationOptions: Sendable {
/// - publicKeyCredentialParameters: A list of key types and signature algorithms the Relying Party supports. Ordered from most preferred to least preferred.
/// - timeout: A time, in seconds, that the caller is willing to wait for the call to complete. This is treated as a hint, and may be overridden by the client.
/// - attestation: Sets the Relying Party's preference for attestation conveyance. At the time of writing only `none` is supported.
/// - authenticatorSelection: A dictionary describing the Relying Party's requirements regarding authenticator attributes.
public init(
challenge: [UInt8],
user: PublicKeyCredentialUserEntity,
relyingParty: PublicKeyCredentialRelyingPartyEntity,
publicKeyCredentialParameters: [PublicKeyCredentialParameters],
timeout: Duration?,
attestation: AttestationConveyancePreference
attestation: AttestationConveyancePreference,
authenticatorSelection: AuthenticatorSelection? = nil
) {
self.challenge = challenge
self.user = user
self.relyingParty = relyingParty
self.publicKeyCredentialParameters = publicKeyCredentialParameters
self.timeout = timeout
self.attestation = attestation
self.authenticatorSelection = authenticatorSelection
}
}

Expand All @@ -93,6 +99,8 @@ extension PublicKeyCredentialCreationOptions: Codable {
self.timeout = .milliseconds(timeout)
}
self.attestation = try values.decode(AttestationConveyancePreference.self, forKey: .attestation)
self.authenticatorSelection = try values.decodeIfPresent(
AuthenticatorSelection.self, forKey: .authenticatorSelection)
}

public func encode(to encoder: any Encoder) throws {
Expand All @@ -104,6 +112,7 @@ extension PublicKeyCredentialCreationOptions: Codable {
try container.encode(publicKeyCredentialParameters, forKey: .publicKeyCredentialParameters)
try container.encodeIfPresent(timeout?.milliseconds, forKey: .timeout)
try container.encode(attestation, forKey: .attestation)
try container.encodeIfPresent(authenticatorSelection, forKey: .authenticatorSelection)
}

private enum CodingKeys: String, CodingKey {
Expand All @@ -113,6 +122,7 @@ extension PublicKeyCredentialCreationOptions: Codable {
case publicKeyCredentialParameters = "pubKeyCredParams"
case timeout
case attestation
case authenticatorSelection
}
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
//===----------------------------------------------------------------------===//
//
// This source file is part of the Swift WebAuthn open source project
//
// Copyright (c) 2022 the Swift WebAuthn project authors
// Licensed under Apache License v2.0
//
// See LICENSE.txt for license information
//
// SPDX-License-Identifier: Apache-2.0
//
//===----------------------------------------------------------------------===//

import Foundation

/// The Relying Party's requirements regarding whether the authenticator should create a client-side-resident public key credential source.
///
/// - SeeAlso: https://www.w3.org/TR/webauthn-2/#enumdef-residentkeyrequirement
public struct ResidentKeyRequirement: UnreferencedStringEnumeration, Sendable {
public var rawValue: String

public init(_ rawValue: String) {
self.rawValue = rawValue
}

/// This value indicates the Relying Party requires a client-side-resident credential (i.e., a discoverable credential).
/// If the authenticator cannot create a client-side-resident credential, it will return an error.
public static let required: Self = "required"

/// This value indicates the Relying Party strongly prefers a client-side-resident credential, but will accept a server-side credential.
public static let preferred: Self = "preferred"

/// This value indicates the Relying Party strongly prefers a server-side credential, but will accept a client-side-resident credential.
public static let discouraged: Self = "discouraged"
}

8 changes: 6 additions & 2 deletions Sources/WebAuthn/WebAuthnManager.swift
Original file line number Diff line number Diff line change
Expand Up @@ -57,12 +57,15 @@ public struct WebAuthnManager: Sendable {
/// - attestation: The Relying Party's preference regarding attestation. Defaults to `.none`.
/// - publicKeyCredentialParameters: A list of public key algorithms the Relying Party chooses to restrict
/// support to. Defaults to all supported algorithms.
/// - authenticatorSelection: A dictionary describing the Relying Party's requirements regarding authenticator attributes.
/// Defaults to `nil` (no requirements).
/// - Returns: Registration options ready for the browser.
public func beginRegistration(
user: PublicKeyCredentialUserEntity,
timeout: Duration? = .seconds(5*60),
attestation: AttestationConveyancePreference = .none,
publicKeyCredentialParameters: [PublicKeyCredentialParameters] = .supported
publicKeyCredentialParameters: [PublicKeyCredentialParameters] = .supported,
authenticatorSelection: AuthenticatorSelection? = nil
) -> PublicKeyCredentialCreationOptions {
let challenge = challengeGenerator.generate()

Expand All @@ -72,7 +75,8 @@ public struct WebAuthnManager: Sendable {
relyingParty: .init(id: configuration.relyingPartyID, name: configuration.relyingPartyName),
publicKeyCredentialParameters: publicKeyCredentialParameters,
timeout: timeout,
attestation: attestation
attestation: attestation,
authenticatorSelection: authenticatorSelection
)
}

Expand Down
Loading
Loading