I’m hitting a wall with the Authorize App (Smart Lock 1 - 4th Generation) example (check out 9. Command usage examples). Steps 19 and 20 are throwing me off. How am I supposed to verify the authenticator, exactly?
Here’s my test code (Swift):
@Test("Verify Authenticator")
func verifyStep20() {
print("\n=== STEP 20 ===")
// Authorization-ID command (Step 19)
let rxData = Data(hex: "07006156B043406A20B4FCEF7E0684F4BDF4950420DD87FE855DB76306819A5B0CBAE05C34000177383DA0D13BD22354671DE3C7DF4FD3E6BD6162D21E61A313FF043AAD58C68652E338A4BF9FC7D99857B0DB85A3A9EA4C")
// Shared Secret (Step 8a)
let sharedSecretHex = "915561587D86815B709EDD5819D8C6F2E883DA3C86F461F13B84228B84533E04"
// rxData.subdata(in: 2..<34)
let expectedAuthenticator = "6156B043406A20B4FCEF7E0684F4BDF4950420DD87FE855DB76306819A5B0CBA" // ???
let key = SymmetricKey(data: Data(hex: sharedSecretHex))
let authenticator = rxData.subdata(in: 2..<34)
let authorizationData = rxData.subdata(in: 34..<38)
let authorizationID = authorizationData.withUnsafeBytes { $0.load(as: UInt32.self) }
let uuid = rxData.subdata(in: 38..<54)
let nonce = rxData.subdata(in: 54..<86)
print("authenticator: \(authenticator.hexString.uppercased())")
print("authorizationID: \(authorizationID) - \(authorizationData.hexString.uppercased())")
print("uuid: \(uuid.hexString.uppercased())")
print("nonce: \(nonce.hexString.uppercased())")
// ???
var verifyData = Data()
verifyData.append(authenticator)
verifyData.append(authorizationData)
verifyData.append(uuid)
verifyData.append(nonce)
let calculatedHmac = HMAC<SHA256>.authenticationCode(for: verifyData, using: key)
print("Calculated: \(Data(calculatedHmac).hexString.uppercased())")
print("Expected: \(expectedAuthenticator.uppercased())")
#expect(Data(calculatedHmac).hexString.lowercased().starts(with: expectedAuthenticator.lowercased()), "Step 20 Logic Mismatch!")
if Data(calculatedHmac).hexString.uppercased().starts(with: expectedAuthenticator.uppercased()) {
print("✅ SUCCESS!")
}
}
I think I misread the docs. The pairing part works like a charm (meaning without verifying the received authenticator), but I really want to nail down how to verify it in my app. Any clues?