-
Notifications
You must be signed in to change notification settings - Fork 232
/
Copy pathHAPMFiTokenAuth.c
151 lines (133 loc) · 5.54 KB
/
HAPMFiTokenAuth.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
// Copyright (c) 2015-2019 The HomeKit ADK Contributors
//
// Licensed under the Apache License, Version 2.0 (the “License”);
// you may not use this file except in compliance with the License.
// See [CONTRIBUTORS.md] for the list of HomeKit ADK project authors.
#include "HAP+Internal.h"
static const HAPLogObject logObject = { .subsystem = kHAP_LogSubsystem, .category = "MFiTokenAuth" };
/**
* TLV types used in HAP-Token-Response and HAP-Update-Token-Request.
*
* @see HomeKit Accessory Protocol Specification R14
* Table 5-4 Software Authentication TLV types
*/
HAP_ENUM_BEGIN(uint8_t, HAPMFiTokenAuthTLVType) { /**
* UUID (The matching UUID for the initial token provisioned on the
* accessory). 16 bytes.
*/
kHAPMFiTokenAuthTLVType_UUID = 0x01,
/**
* Software Token.
* Opaque blob, up to kHAPPlatformMFiTokenAuth_MaxMFiTokenBytes bytes.
*/
kHAPMFiTokenAuthTLVType_SoftwareToken = 0x02
} HAP_ENUM_END(uint8_t, HAPMFiTokenAuthTLVType);
HAP_RESULT_USE_CHECK
HAPError HAPMFiTokenAuthGetTokenResponse(
HAPAccessoryServerRef* server_,
HAPSessionRef* session,
const HAPAccessory* accessory,
HAPTLVWriterRef* responseWriter) {
HAPPrecondition(server_);
HAPAccessoryServer* server = (HAPAccessoryServer*) server_;
HAPPrecondition(session);
HAPPrecondition(accessory);
HAPPrecondition(responseWriter);
HAPError err;
// See HomeKit Accessory Protocol Specification R14
// Section 5.15.2 HAP-Token-Response
// Load Software Token.
HAPPlatformMFiTokenAuthUUID mfiTokenUUID;
void* mfiTokenBytes;
size_t maxMFiTokenBytes;
size_t numMFiTokenBytes = 0;
HAPTLVWriterGetScratchBytes(responseWriter, &mfiTokenBytes, &maxMFiTokenBytes);
bool hasMFiToken = false;
if (server->platform.authentication.mfiTokenAuth) {
err = HAPPlatformMFiTokenAuthLoad(
HAPNonnull(server->platform.authentication.mfiTokenAuth),
&hasMFiToken,
&mfiTokenUUID,
mfiTokenBytes,
maxMFiTokenBytes,
&numMFiTokenBytes);
if (err) {
HAPAssert(err == kHAPError_Unknown);
return err;
}
}
if (!hasMFiToken) {
HAPLog(&logObject, "Software Token requested but no token is provisioned.");
return kHAPError_InvalidState;
}
// Software Token.
// Do this first because scratch buffer gets invalidated on TLV append.
err = HAPTLVWriterAppend(
responseWriter,
&(const HAPTLV) { .type = kHAPMFiTokenAuthTLVType_SoftwareToken,
.value = { .bytes = mfiTokenBytes, .numBytes = numMFiTokenBytes } });
if (err) {
HAPAssert(err == kHAPError_OutOfResources);
return err;
}
// UUID.
err = HAPTLVWriterAppend(
responseWriter,
&(const HAPTLV) { .type = kHAPMFiTokenAuthTLVType_UUID,
.value = { .bytes = mfiTokenUUID.bytes, .numBytes = sizeof mfiTokenUUID.bytes } });
if (err) {
HAPAssert(err == kHAPError_OutOfResources);
return err;
}
return kHAPError_None;
}
HAP_RESULT_USE_CHECK
HAPError HAPMFiTokenAuthHandleTokenUpdateRequest(
HAPAccessoryServerRef* server_,
HAPSessionRef* session,
const HAPAccessory* accessory,
HAPTLVReaderRef* requestReader) {
HAPPrecondition(server_);
HAPAccessoryServer* server = (HAPAccessoryServer*) server_;
HAPPrecondition(session);
HAPPrecondition(accessory);
HAPPrecondition(requestReader);
HAPError err;
// See HomeKit Accessory Protocol Specification R14
// Section 5.15.3 HAP-Token-Update-Request
HAPTLV softwareTokenTLV;
softwareTokenTLV.type = kHAPMFiTokenAuthTLVType_SoftwareToken;
err = HAPTLVReaderGetAll(requestReader, (HAPTLV* const[]) { &softwareTokenTLV, NULL });
if (err) {
HAPAssert(err == kHAPError_InvalidData);
return err;
}
// Validate Software Token.
if (!softwareTokenTLV.value.bytes) {
HAPLog(&logObject, "Software Token missing.");
return kHAPError_InvalidData;
}
if (softwareTokenTLV.value.numBytes > kHAPPlatformMFiTokenAuth_MaxMFiTokenBytes) {
HAPLog(&logObject, "Software Token has invalid length (%lu).", (unsigned long) softwareTokenTLV.value.numBytes);
return kHAPError_InvalidData;
}
HAPLogSensitiveBuffer(&logObject, softwareTokenTLV.value.bytes, softwareTokenTLV.value.numBytes, "Software Token");
// Update Token.
HAPLogInfo(
&logObject,
"Updating Software Token (length = %lu bytes).",
(unsigned long) softwareTokenTLV.value.numBytes);
if (!server->platform.authentication.mfiTokenAuth) {
HAPLog(&logObject, "Software Authentication not supported.");
return kHAPError_Unknown;
}
err = HAPPlatformMFiTokenAuthUpdate(
HAPNonnull(server->platform.authentication.mfiTokenAuth),
HAPNonnullVoid(softwareTokenTLV.value.bytes),
softwareTokenTLV.value.numBytes);
if (err) {
HAPAssert(err == kHAPError_Unknown);
return err;
}
return kHAPError_None;
}