|
12 | 12 | //
|
13 | 13 | //===----------------------------------------------------------------------===//
|
14 | 14 |
|
| 15 | +import Crypto |
| 16 | +import SwiftCBOR |
| 17 | + |
15 | 18 | public protocol AuthenticatorProtocol<CredentialSource> {
|
16 | 19 | associatedtype CredentialSource: AuthenticatorCredentialSourceProtocol
|
| 20 | + |
| 21 | + var attestationGloballyUniqueID: AAGUID { get } |
| 22 | + var attachmentModality: AuthenticatorAttachment { get } |
| 23 | + var supportedPublicKeyCredentialParameters: Set<PublicKeyCredentialParameters> { get } |
| 24 | + var canPerformUserVerification: Bool { get } |
| 25 | + var canStoreCredentialSourceClientSide: Bool { get } |
| 26 | + |
| 27 | + /// Generate a credential source for this authenticator. |
| 28 | + /// - Parameters: |
| 29 | + /// - requiresClientSideKeyStorage: `true` if the relying party requires that the credential ID is stored client size, as it won't be provided during authentication requests. |
| 30 | + /// - credentialParameters: The chosen credential parameters. |
| 31 | + /// - relyingPartyID: The ID of the relying party the credential is being generated for. |
| 32 | + /// - userHandle: The user handle the credential is being generated for. |
| 33 | + /// - Returns: A new credential source to be returned to the caller upon successful registration. |
| 34 | + func generateCredentialSource( |
| 35 | + requiresClientSideKeyStorage: Bool, |
| 36 | + credentialParameters: PublicKeyCredentialParameters, |
| 37 | + relyingPartyID: PublicKeyCredentialRelyingPartyEntity.ID, |
| 38 | + userHandle: PublicKeyCredentialUserEntity.ID |
| 39 | + ) async throws -> CredentialSource |
| 40 | + |
| 41 | + /// The preferred attestation format for the authenticator, optionally taking into account the provided list of formats the relying party prefers. |
| 42 | + /// |
| 43 | + /// The default implementation returns ``AttestationFormat/none``. |
| 44 | + /// |
| 45 | + /// - Parameter attestationFormats: A list of attestation formats the relying party prefers. |
| 46 | + /// - Returns: The attestation format that will be used to sign an attestation statement. |
| 47 | + func preferredAttestationFormat(from attestationFormats: [AttestationFormat]) -> AttestationFormat |
| 48 | + |
| 49 | + /// Sign an attestation statement for the provided authenticator data and client data using the specified format. |
| 50 | + /// - Parameters: |
| 51 | + /// - attestationFormat: The attestation format to sign with. |
| 52 | + /// - authenticatorData: The authenticator data to be signed. |
| 53 | + /// - clientDataHash: The client data to be signed. |
| 54 | + /// - Returns: A signiture in the specified format. |
| 55 | + func signAttestationStatement( |
| 56 | + attestationFormat: AttestationFormat, |
| 57 | + authenticatorData: [UInt8], |
| 58 | + clientDataHash: SHA256.Digest |
| 59 | + ) async throws -> CBOR |
| 60 | + |
| 61 | + /// Filter the provided credential descriptors to determine which, if any, should be handled by this authenticator. |
| 62 | + /// |
| 63 | + /// This method should execute a client platform-specific procedure to determine which, if any, public key credentials described by `pkOptions.allowCredentials` are bound to this authenticator, by matching with `rpId`, `pkOptions.allowCredentials.id`, and `pkOptions.allowCredentials.type` |
| 64 | + /// |
| 65 | + /// The default implementation returns the list as is. |
| 66 | + /// - Parameters: |
| 67 | + /// - credentialDescriptors: A list of credentials that will be used assert authorization against. |
| 68 | + /// - relyingPartyID: The relying party ID the credentials belong to. |
| 69 | + /// - Returns: A filtered list of credentials that are suitable for this authenticator. |
| 70 | + func filteredCredentialDescriptors( |
| 71 | + credentialDescriptors: [PublicKeyCredentialDescriptor], |
| 72 | + relyingPartyID: PublicKeyCredentialRelyingPartyEntity.ID |
| 73 | + ) -> [PublicKeyCredentialDescriptor] |
| 74 | + |
| 75 | + /// Collect an authorization gesture from the user for one of the specified credential sources, making sure to increment the counter for the credential source if relevant. |
| 76 | + /// - Parameters: |
| 77 | + /// - requiresUserVerification: The user is required to verify that the credential should be used to assert authorization. If the user cannot perform this task, this method should throw an error. |
| 78 | + /// - requiresUserPresence: The user is required to be present in order for authorization to be attempted. ie. authorization should not be done in the background without the user's knowledge while they are away from this device. |
| 79 | + /// - credentialOptions: A list of available credentials to verify against. |
| 80 | + /// - Returns: The chosen credential to use for authorization. |
| 81 | + func collectAuthorizationGesture( |
| 82 | + requiresUserVerification: Bool, |
| 83 | + requiresUserPresence: Bool, |
| 84 | + credentialOptions: [CredentialSource] |
| 85 | + ) async throws -> CredentialSource |
| 86 | +} |
| 87 | + |
| 88 | +// MARK: - Default Implementations |
| 89 | + |
| 90 | +extension AuthenticatorProtocol { |
| 91 | + public func preferredAttestationFormat( |
| 92 | + from attestationFormats: [AttestationFormat] |
| 93 | + ) -> AttestationFormat { |
| 94 | + .none |
| 95 | + } |
| 96 | + |
| 97 | + public func signAttestationStatement( |
| 98 | + attestationFormat: AttestationFormat, |
| 99 | + authenticatorData: [UInt8], |
| 100 | + clientDataHash: SHA256.Digest |
| 101 | + ) async throws -> CBOR { |
| 102 | + guard attestationFormat == .none |
| 103 | + else { throw WebAuthnError.attestationFormatNotSupported } |
| 104 | + |
| 105 | + return [:] |
| 106 | + } |
| 107 | + |
| 108 | + public func filteredCredentialDescriptors( |
| 109 | + credentialDescriptors: [PublicKeyCredentialDescriptor], |
| 110 | + relyingPartyID: PublicKeyCredentialRelyingPartyEntity.ID |
| 111 | + ) -> [PublicKeyCredentialDescriptor] { |
| 112 | + return credentialDescriptors |
| 113 | + } |
17 | 114 | }
|
0 commit comments