Skip to content
Draft
Show file tree
Hide file tree
Changes from all 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
Expand Up @@ -4,16 +4,22 @@ import Foundation

/// Metadata needed for matching a request to the device passkey before decrypting the secret data.
public struct DeviceAuthKeyMetadata: Codable, Equatable, Sendable {
/// The unique identifier of the cipher associated with this device auth key.
public let cipherId: String
/// The date this credential was created.
public let creationDate: Date

/// The unique identifier for this credential.
public let credentialId: Data

/// The relying party identifier, typically a domain name.
/// The unique identifier of the cipher associated with this device auth key.
public let recordIdentifier: String

/// The relying party identifier, typically the Bitwarden Web Vault domain name.
public let rpId: String

/// The user handle (user ID) as raw data.
/// The display name for the WebAuthn user.
public let userDisplayName: String

/// The WebAuthn user handle (user ID) as raw data.
public let userHandle: Data

/// The user's username or login name.
Expand All @@ -22,21 +28,27 @@ public struct DeviceAuthKeyMetadata: Codable, Equatable, Sendable {
/// Creates new device auth key metadata.
///
/// - Parameters:
/// - cipherId: The unique identifier of the cipher associated with this device auth key.
/// - creationDate:The date this credential was created.
/// - credentialId: The unique identifier for this credential.
/// - recordIdentifier: The unique identifier of this device auth key.
/// - rpId: The relying party identifier, typically a domain name.
/// - userDisplayName:The display name for the WebAuthn user.
/// - userHandle: The user handle (user ID) as raw data.
/// - userName: The user's username or login name.
public init(
cipherId: String,
creationDate: Date,
credentialId: Data,
recordIdentifier: String,
rpId: String,
userDisplayName: String,
userHandle: Data,
userName: String,
) {
self.cipherId = cipherId
self.creationDate = creationDate
self.credentialId = credentialId
self.recordIdentifier = recordIdentifier
self.rpId = rpId
self.userDisplayName = userDisplayName
self.userHandle = userHandle
self.userName = userName
}
Expand Down
83 changes: 21 additions & 62 deletions BitwardenShared/Core/Auth/Models/Domain/DeviceAuthKeyRecord.swift
Original file line number Diff line number Diff line change
Expand Up @@ -5,62 +5,37 @@ import Foundation

/// Stored key material needed to assert the device auth key passkey.
public struct DeviceAuthKeyRecord: Codable, Equatable, Sendable {
/// The unique identifier of the cipher associated with this device auth key.
public let cipherId: EncString

/// The human-readable name of the cipher.
public let cipherName: EncString

/// The signature counter value, used to detect cloned authenticators.
public let counter: EncString

/// The date when this credential was created.
public let creationDate: Date
public let counter: UInt32

/// The unique identifier for this credential, assigned by the authenticator.
public let credentialId: EncString

/// Whether this credential is discoverable (formerly called "resident key").
/// A discoverable credential can be used without providing a credential ID.
public let discoverable: EncString
public let credentialId: Data

/// The HMAC secret, if the credential supports the hmac-secret extension.
public let hmacSecret: EncString?
public let hmacSecret: Data

/// The algorithm used for the key (e.g., "ES256" for ECDSA with SHA-256).
public let keyAlgorithm: EncString
/// The COSE algorithm identifier used for the key (e.g., `-7` for ECDSA with SHA-256).
public let keyAlgorithm: Int64

/// The elliptic curve used for the key (e.g., "P-256").
public let keyCurve: EncString

/// The type of public key credential (typically "public-key").
public let keyType: EncString
/// The COSE elliptic curve identifier used for the key (e.g., `1` for P-256).
public let keyCurve: Int64

/// The actual key material value.
public let keyValue: EncString
public let keyValue: Data

/// The relying party identifier, typically a domain name.
public let rpId: EncString
/// The relying party identifier, typically the domain name of the Bitwarden Web Vault.
public let rpId: String

/// The human-readable name of the relying party.
public let rpName: EncString?

/// The user's human-readable display name.
public let userDisplayName: EncString?
public let rpName: String

/// The user identifier for the relying party.
public let userId: EncString?

/// The user's username or login name.
public let userName: EncString?
public let userId: Data

/// Creates a new device auth key record.
///
/// - Parameters:
/// - cipherId: The unique identifier of the cipher associated with this device auth key.
/// - cipherName: The human-readable name of the cipher.
/// - counter: The signature counter value, used to detect cloned authenticators.
/// - creationDate: The date when this credential was created.
/// - credentialId: The unique identifier for this credential, assigned by the authenticator.
/// - discoverable: Whether this credential is discoverable (formerly called "resident key").
/// - hmacSecret: The HMAC secret, if the credential supports the hmac-secret extension.
Expand All @@ -70,42 +45,26 @@ public struct DeviceAuthKeyRecord: Codable, Equatable, Sendable {
/// - keyValue: The actual key material value.
/// - rpId: The relying party identifier, typically a domain name.
/// - rpName: The human-readable name of the relying party.
/// - userDisplayName: The user's human-readable display name.
/// - userId: The user identifier for the relying party.
/// - userName: The user's username or login name.
public init(
cipherId: EncString,
cipherName: EncString,
counter: EncString,
creationDate: Date,
credentialId: EncString,
discoverable: EncString,
hmacSecret: EncString?,
keyAlgorithm: EncString,
keyCurve: EncString,
keyType: EncString,
keyValue: EncString,
rpId: EncString,
rpName: EncString?,
userDisplayName: EncString?,
userId: EncString?,
userName: EncString?,
counter: UInt32,
credentialId: Data,
hmacSecret: Data,
keyAlgorithm: Int64,
keyCurve: Int64,
keyValue: Data,
rpId: String,
rpName: String,
userId: Data,
) {
self.cipherId = cipherId
self.cipherName = cipherName
self.counter = counter
self.creationDate = creationDate
self.credentialId = credentialId
self.discoverable = discoverable
self.hmacSecret = hmacSecret
self.keyAlgorithm = keyAlgorithm
self.keyCurve = keyCurve
self.keyType = keyType
self.keyValue = keyValue
self.rpId = rpId
self.rpName = rpName
self.userDisplayName = userDisplayName
self.userId = userId
self.userName = userName
}
}
11 changes: 11 additions & 0 deletions BitwardenShared/Core/Auth/Services/ClientFido2Service.swift
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,13 @@ protocol ClientFido2Service: AnyObject {
credentialStore: Fido2CredentialStore,
) -> ClientFido2ClientProtocol


/// Returns the `ClientDeviceAuthKeyAuthenticator` to perform Fido2 authenticator tasks using the device auth key.
/// - Parameters:
/// - credentialStore: `DeviceAuthKeyStore` with necessary platform side logic related to credential storage.
/// - Returns: Returns the `ClientDeviceAuthKeyAuthenticator` to perform Fido2 authenticator tasks with the device auth key.
func deviceAuthKeyAuthenticator(credentialStore: DeviceAuthKeyStore) -> ClientDeviceAuthKeyAuthenticatorProtocol

/// Decrypts the `CipherView` Fido2 credentials but returning an array of `Fido2CredentialAutofillView`
/// - Parameter cipherView: `CipherView` containing the Fido2 credentials to decrypt.
/// - Returns: An array of decrypted Fido2 credentials of type `Fido2CredentialAutofillView`.
Expand All @@ -41,6 +48,10 @@ extension ClientFido2: ClientFido2Service {
client(userInterface: userInterface, credentialStore: credentialStore) as ClientFido2Client
}

func deviceAuthKeyAuthenticator(credentialStore: DeviceAuthKeyStore) -> ClientDeviceAuthKeyAuthenticatorProtocol {
deviceAuthKeyAuthenticator(credentialStore: credentialStore) as ClientDeviceAuthKeyAuthenticator
}

func decryptFido2AutofillCredentials(cipher cipherView: CipherView) throws -> [Fido2CredentialAutofillView] {
try decryptFido2AutofillCredentials(cipherView: cipherView)
}
Expand Down
Loading
Loading