Skip to content

Commit 8d7b74f

Browse files
Updated AuthenticatorData and related objects to be byte encodable
1 parent 2b1fe1a commit 8d7b74f

File tree

3 files changed

+58
-1
lines changed

3 files changed

+58
-1
lines changed

Sources/WebAuthn/Ceremonies/Registration/AttestationObject.swift

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,29 @@ public struct AttestationObject: Sendable {
2222
let rawAuthenticatorData: [UInt8]
2323
let format: AttestationFormat
2424
let attestationStatement: CBOR
25+
26+
init(
27+
authenticatorData: AuthenticatorData,
28+
rawAuthenticatorData: [UInt8],
29+
format: AttestationFormat,
30+
attestationStatement: CBOR
31+
) {
32+
self.authenticatorData = authenticatorData
33+
self.rawAuthenticatorData = rawAuthenticatorData
34+
self.format = format
35+
self.attestationStatement = attestationStatement
36+
}
37+
38+
init(
39+
authenticatorData: AuthenticatorData,
40+
format: AttestationFormat,
41+
attestationStatement: CBOR
42+
) {
43+
self.authenticatorData = authenticatorData
44+
self.rawAuthenticatorData = authenticatorData.bytes
45+
self.format = format
46+
self.attestationStatement = attestationStatement
47+
}
2548

2649
func verify(
2750
relyingPartyID: String,

Sources/WebAuthn/Ceremonies/Shared/AuthenticatorData.swift

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -120,6 +120,29 @@ extension AuthenticatorData {
120120

121121
return (data, length)
122122
}
123+
124+
public var bytes: [UInt8] {
125+
assert(relyingPartyIDHash.count == 32, "AuthenticatorData contains relyingPartyIDHash of length \(relyingPartyIDHash.count), which will likely not be decodable.")
126+
var bytes: [UInt8] = []
127+
128+
bytes += relyingPartyIDHash
129+
bytes += flags.bytes
130+
bytes += withUnsafeBytes(of: UInt32(counter).bigEndian) { Array($0) }
131+
132+
assert((!flags.attestedCredentialData && attestedData == nil) || (flags.attestedCredentialData && attestedData != nil), "AuthenticatorData contains mismatch between attestedCredentialData flag and attestedData, which will likely not be decodable.")
133+
if flags.attestedCredentialData, let attestedData {
134+
bytes += attestedData.authenticatorAttestationGUID.bytes
135+
bytes += withUnsafeBytes(of: UInt16(attestedData.credentialID.count).bigEndian) { Array($0) }
136+
bytes += attestedData.credentialID
137+
bytes += attestedData.publicKey
138+
}
139+
140+
assert((!flags.extensionDataIncluded && extData == nil) || (flags.extensionDataIncluded && extData != nil), "AuthenticatorData contains mismatch between extensionDataIncluded flag and extData, which will likely not be decodable.")
141+
if flags.extensionDataIncluded, let extData {
142+
bytes += extData
143+
}
144+
return bytes
145+
}
123146
}
124147

125148
/// A helper type to determine how many bytes were consumed when decoding CBOR items.

Sources/WebAuthn/Ceremonies/Shared/AuthenticatorFlags.swift

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
//
1313
//===----------------------------------------------------------------------===//
1414

15-
struct AuthenticatorFlags: Equatable, Sendable {
15+
public struct AuthenticatorFlags: Equatable, Sendable {
1616

1717
/**
1818
Taken from https://w3c.github.io/webauthn/#sctn-authenticator-data
@@ -58,4 +58,15 @@ extension AuthenticatorFlags {
5858
attestedCredentialData = Self.isFlagSet(on: byte, at: .attestedCredentialDataIncluded)
5959
extensionDataIncluded = Self.isFlagSet(on: byte, at: .extensionDataIncluded)
6060
}
61+
62+
public var bytes: [UInt8] {
63+
var byte: UInt8 = 0
64+
byte |= userPresent ? 1 << Bit.userPresent.rawValue : 0
65+
byte |= userVerified ? 1 << Bit.userVerified.rawValue : 0
66+
byte |= isBackupEligible ? 1 << Bit.backupEligible.rawValue : 0
67+
byte |= isCurrentlyBackedUp ? 1 << Bit.backupState.rawValue : 0
68+
byte |= attestedCredentialData ? 1 << Bit.attestedCredentialDataIncluded.rawValue : 0
69+
byte |= extensionDataIncluded ? 1 << Bit.extensionDataIncluded.rawValue : 0
70+
return [byte]
71+
}
6172
}

0 commit comments

Comments
 (0)