1 // Copyright 2015 The Weave Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "src/macaroon_caveat.h"
6 #include "src/macaroon_caveat_internal.h"
7
8 #include <string.h>
9
10 #include "src/crypto_hmac.h"
11 #include "src/macaroon.h"
12 #include "src/macaroon_context.h"
13 #include "src/macaroon_encoding.h"
14
is_valid_caveat_type_(UwMacaroonCaveatType type)15 static bool is_valid_caveat_type_(UwMacaroonCaveatType type) {
16 switch (type) {
17 case kUwMacaroonCaveatTypeNonce:
18 case kUwMacaroonCaveatTypeScope:
19 case kUwMacaroonCaveatTypeExpirationAbsolute:
20 case kUwMacaroonCaveatTypeTTL1Hour:
21 case kUwMacaroonCaveatTypeTTL24Hour:
22 case kUwMacaroonCaveatTypeDelegationTimestamp:
23 case kUwMacaroonCaveatTypeDelegateeUser:
24 case kUwMacaroonCaveatTypeDelegateeApp:
25 case kUwMacaroonCaveatTypeAppCommandsOnly:
26 case kUwMacaroonCaveatTypeDelegateeService:
27 case kUwMacaroonCaveatTypeBleSessionID:
28 case kUwMacaroonCaveatTypeLanSessionID:
29 case kUwMacaroonCaveatTypeClientAuthorizationTokenV1:
30 case kUwMacaroonCaveatTypeServerAuthenticationTokenV1:
31 return true;
32 }
33 return false;
34 }
35
is_valid_scope_type_(UwMacaroonCaveatScopeType type)36 static bool is_valid_scope_type_(UwMacaroonCaveatScopeType type) {
37 switch (type) {
38 case kUwMacaroonCaveatScopeTypeOwner:
39 case kUwMacaroonCaveatScopeTypeManager:
40 case kUwMacaroonCaveatScopeTypeUser:
41 case kUwMacaroonCaveatScopeTypeViewer:
42 return true;
43 }
44 return false;
45 }
46
create_caveat_no_value_(UwMacaroonCaveatType type,uint8_t * buffer,size_t buffer_size,UwMacaroonCaveat * new_caveat)47 static bool create_caveat_no_value_(UwMacaroonCaveatType type,
48 uint8_t* buffer,
49 size_t buffer_size,
50 UwMacaroonCaveat* new_caveat) {
51 // (buffer_size == 0 || get_buffer_size_() > buffer_size) will conver the case
52 // that get_buffer_size_() returns 0 (for errors), so there is no need to
53 // check get_buffer_size_() == 0 again.
54 if (buffer == NULL || buffer_size == 0 || new_caveat == NULL ||
55 uw_macaroon_caveat_creation_get_buffsize_(type, 0) > buffer_size) {
56 return false;
57 }
58
59 size_t encoded_str_len = 0, total_str_len = 0;
60 if (!uw_macaroon_encoding_encode_uint_((uint32_t)type, buffer, buffer_size,
61 &encoded_str_len)) {
62 return false;
63 }
64 total_str_len += encoded_str_len;
65
66 new_caveat->bytes = buffer;
67 new_caveat->num_bytes = total_str_len;
68 return true;
69 }
70
create_caveat_uint_value_(UwMacaroonCaveatType type,uint32_t unsigned_int,uint8_t * buffer,size_t buffer_size,UwMacaroonCaveat * new_caveat)71 static bool create_caveat_uint_value_(UwMacaroonCaveatType type,
72 uint32_t unsigned_int,
73 uint8_t* buffer,
74 size_t buffer_size,
75 UwMacaroonCaveat* new_caveat) {
76 if (buffer == NULL || buffer_size == 0 || new_caveat == NULL ||
77 uw_macaroon_caveat_creation_get_buffsize_(type, 0) > buffer_size) {
78 return false;
79 }
80
81 size_t encoded_str_len = 0, total_str_len = 0;
82 if (!uw_macaroon_encoding_encode_uint_((uint32_t)type, buffer, buffer_size,
83 &encoded_str_len)) {
84 return false;
85 }
86 total_str_len += encoded_str_len;
87 if (!uw_macaroon_encoding_encode_uint_(unsigned_int, buffer + total_str_len,
88 buffer_size - total_str_len,
89 &encoded_str_len)) {
90 return false;
91 }
92 total_str_len += encoded_str_len;
93
94 new_caveat->bytes = buffer;
95 new_caveat->num_bytes = total_str_len;
96 return true;
97 }
98
create_caveat_bstr_value_(UwMacaroonCaveatType type,const uint8_t * str,size_t str_len,uint8_t * buffer,size_t buffer_size,UwMacaroonCaveat * new_caveat)99 static bool create_caveat_bstr_value_(UwMacaroonCaveatType type,
100 const uint8_t* str,
101 size_t str_len,
102 uint8_t* buffer,
103 size_t buffer_size,
104 UwMacaroonCaveat* new_caveat) {
105 if ((str == NULL && str_len != 0) || buffer == NULL || buffer_size == 0 ||
106 new_caveat == NULL ||
107 uw_macaroon_caveat_creation_get_buffsize_(type, str_len) > buffer_size) {
108 return false;
109 }
110
111 size_t encoded_str_len = 0, total_str_len = 0;
112 if (!uw_macaroon_encoding_encode_uint_((uint32_t)type, buffer, buffer_size,
113 &encoded_str_len)) {
114 return false;
115 }
116 total_str_len += encoded_str_len;
117 if (!uw_macaroon_encoding_encode_byte_str_(
118 str, str_len, buffer + total_str_len, buffer_size - total_str_len,
119 &encoded_str_len)) {
120 return false;
121 }
122 total_str_len += encoded_str_len;
123
124 new_caveat->bytes = buffer;
125 new_caveat->num_bytes = total_str_len;
126 return true;
127 }
128
uw_macaroon_caveat_creation_get_buffsize_(UwMacaroonCaveatType type,size_t str_len)129 size_t uw_macaroon_caveat_creation_get_buffsize_(UwMacaroonCaveatType type,
130 size_t str_len) {
131 switch (type) {
132 // No values
133 case kUwMacaroonCaveatTypeTTL1Hour:
134 case kUwMacaroonCaveatTypeTTL24Hour:
135 case kUwMacaroonCaveatTypeAppCommandsOnly:
136 case kUwMacaroonCaveatTypeBleSessionID:
137 return UW_MACAROON_ENCODING_MAX_UINT_CBOR_LEN;
138
139 // Unsigned integers
140 case kUwMacaroonCaveatTypeScope:
141 case kUwMacaroonCaveatTypeExpirationAbsolute:
142 case kUwMacaroonCaveatTypeDelegationTimestamp:
143 return 2 * UW_MACAROON_ENCODING_MAX_UINT_CBOR_LEN;
144
145 // Byte strings
146 case kUwMacaroonCaveatTypeNonce:
147 case kUwMacaroonCaveatTypeDelegateeUser:
148 case kUwMacaroonCaveatTypeDelegateeApp:
149 case kUwMacaroonCaveatTypeDelegateeService:
150 case kUwMacaroonCaveatTypeLanSessionID:
151 case kUwMacaroonCaveatTypeClientAuthorizationTokenV1:
152 case kUwMacaroonCaveatTypeServerAuthenticationTokenV1:
153 return str_len + UW_MACAROON_ENCODING_MAX_UINT_CBOR_LEN;
154
155 default:
156 return 0; // For errors
157 }
158 }
159
uw_macaroon_caveat_create_nonce_(const uint8_t * nonce,size_t nonce_size,uint8_t * buffer,size_t buffer_size,UwMacaroonCaveat * new_caveat)160 bool uw_macaroon_caveat_create_nonce_(const uint8_t* nonce,
161 size_t nonce_size,
162 uint8_t* buffer,
163 size_t buffer_size,
164 UwMacaroonCaveat* new_caveat) {
165 return create_caveat_bstr_value_(kUwMacaroonCaveatTypeNonce, nonce,
166 nonce_size, buffer, buffer_size, new_caveat);
167 }
168
uw_macaroon_caveat_create_scope_(UwMacaroonCaveatScopeType scope,uint8_t * buffer,size_t buffer_size,UwMacaroonCaveat * new_caveat)169 bool uw_macaroon_caveat_create_scope_(UwMacaroonCaveatScopeType scope,
170 uint8_t* buffer,
171 size_t buffer_size,
172 UwMacaroonCaveat* new_caveat) {
173 if (!is_valid_scope_type_(scope)) {
174 return false;
175 }
176
177 return create_caveat_uint_value_(kUwMacaroonCaveatTypeScope, scope, buffer,
178 buffer_size, new_caveat);
179 }
180
uw_macaroon_caveat_create_expiration_absolute_(uint32_t expiration_time,uint8_t * buffer,size_t buffer_size,UwMacaroonCaveat * new_caveat)181 bool uw_macaroon_caveat_create_expiration_absolute_(
182 uint32_t expiration_time,
183 uint8_t* buffer,
184 size_t buffer_size,
185 UwMacaroonCaveat* new_caveat) {
186 return create_caveat_uint_value_(kUwMacaroonCaveatTypeExpirationAbsolute,
187 expiration_time, buffer, buffer_size,
188 new_caveat);
189 }
190
uw_macaroon_caveat_create_ttl_1_hour_(uint8_t * buffer,size_t buffer_size,UwMacaroonCaveat * new_caveat)191 bool uw_macaroon_caveat_create_ttl_1_hour_(uint8_t* buffer,
192 size_t buffer_size,
193 UwMacaroonCaveat* new_caveat) {
194 return create_caveat_no_value_(kUwMacaroonCaveatTypeTTL1Hour, buffer,
195 buffer_size, new_caveat);
196 }
197
uw_macaroon_caveat_create_ttl_24_hour_(uint8_t * buffer,size_t buffer_size,UwMacaroonCaveat * new_caveat)198 bool uw_macaroon_caveat_create_ttl_24_hour_(uint8_t* buffer,
199 size_t buffer_size,
200 UwMacaroonCaveat* new_caveat) {
201 return create_caveat_no_value_(kUwMacaroonCaveatTypeTTL24Hour, buffer,
202 buffer_size, new_caveat);
203 }
204
uw_macaroon_caveat_create_delegation_timestamp_(uint32_t timestamp,uint8_t * buffer,size_t buffer_size,UwMacaroonCaveat * new_caveat)205 bool uw_macaroon_caveat_create_delegation_timestamp_(
206 uint32_t timestamp,
207 uint8_t* buffer,
208 size_t buffer_size,
209 UwMacaroonCaveat* new_caveat) {
210 return create_caveat_uint_value_(kUwMacaroonCaveatTypeDelegationTimestamp,
211 timestamp, buffer, buffer_size, new_caveat);
212 }
213
uw_macaroon_caveat_create_delegatee_user_(const uint8_t * id_str,size_t id_str_len,uint8_t * buffer,size_t buffer_size,UwMacaroonCaveat * new_caveat)214 bool uw_macaroon_caveat_create_delegatee_user_(const uint8_t* id_str,
215 size_t id_str_len,
216 uint8_t* buffer,
217 size_t buffer_size,
218 UwMacaroonCaveat* new_caveat) {
219 return create_caveat_bstr_value_(kUwMacaroonCaveatTypeDelegateeUser, id_str,
220 id_str_len, buffer, buffer_size, new_caveat);
221 }
222
uw_macaroon_caveat_create_delegatee_app_(const uint8_t * id_str,size_t id_str_len,uint8_t * buffer,size_t buffer_size,UwMacaroonCaveat * new_caveat)223 bool uw_macaroon_caveat_create_delegatee_app_(const uint8_t* id_str,
224 size_t id_str_len,
225 uint8_t* buffer,
226 size_t buffer_size,
227 UwMacaroonCaveat* new_caveat) {
228 return create_caveat_bstr_value_(kUwMacaroonCaveatTypeDelegateeApp, id_str,
229 id_str_len, buffer, buffer_size, new_caveat);
230 }
231
uw_macaroon_caveat_create_app_commands_only_(uint8_t * buffer,size_t buffer_size,UwMacaroonCaveat * new_caveat)232 bool uw_macaroon_caveat_create_app_commands_only_(
233 uint8_t* buffer,
234 size_t buffer_size,
235 UwMacaroonCaveat* new_caveat) {
236 return create_caveat_no_value_(kUwMacaroonCaveatTypeAppCommandsOnly, buffer,
237 buffer_size, new_caveat);
238 }
239
uw_macaroon_caveat_create_delegatee_service_(const uint8_t * id_str,size_t id_str_len,uint8_t * buffer,size_t buffer_size,UwMacaroonCaveat * new_caveat)240 bool uw_macaroon_caveat_create_delegatee_service_(
241 const uint8_t* id_str,
242 size_t id_str_len,
243 uint8_t* buffer,
244 size_t buffer_size,
245 UwMacaroonCaveat* new_caveat) {
246 return create_caveat_bstr_value_(kUwMacaroonCaveatTypeDelegateeService,
247 id_str, id_str_len, buffer, buffer_size,
248 new_caveat);
249 }
250
uw_macaroon_caveat_create_ble_session_id_(uint8_t * buffer,size_t buffer_size,UwMacaroonCaveat * new_caveat)251 bool uw_macaroon_caveat_create_ble_session_id_(uint8_t* buffer,
252 size_t buffer_size,
253 UwMacaroonCaveat* new_caveat) {
254 return create_caveat_no_value_(kUwMacaroonCaveatTypeBleSessionID, buffer,
255 buffer_size, new_caveat);
256 }
257
uw_macaroon_caveat_create_lan_session_id_(const uint8_t * session_id,size_t session_id_len,uint8_t * buffer,size_t buffer_size,UwMacaroonCaveat * new_caveat)258 bool uw_macaroon_caveat_create_lan_session_id_(const uint8_t* session_id,
259 size_t session_id_len,
260 uint8_t* buffer,
261 size_t buffer_size,
262 UwMacaroonCaveat* new_caveat) {
263 return create_caveat_bstr_value_(kUwMacaroonCaveatTypeLanSessionID,
264 session_id, session_id_len, buffer,
265 buffer_size, new_caveat);
266 }
267
uw_macaroon_caveat_create_client_authorization_token_(const uint8_t * str,size_t str_len,uint8_t * buffer,size_t buffer_size,UwMacaroonCaveat * new_caveat)268 bool uw_macaroon_caveat_create_client_authorization_token_(
269 const uint8_t* str,
270 size_t str_len,
271 uint8_t* buffer,
272 size_t buffer_size,
273 UwMacaroonCaveat* new_caveat) {
274 if (str_len == 0) {
275 return create_caveat_no_value_(
276 kUwMacaroonCaveatTypeClientAuthorizationTokenV1, buffer, buffer_size,
277 new_caveat);
278 }
279 return create_caveat_bstr_value_(
280 kUwMacaroonCaveatTypeClientAuthorizationTokenV1, str, str_len, buffer,
281 buffer_size, new_caveat);
282 }
283
uw_macaroon_caveat_create_server_authentication_token_(const uint8_t * str,size_t str_len,uint8_t * buffer,size_t buffer_size,UwMacaroonCaveat * new_caveat)284 bool uw_macaroon_caveat_create_server_authentication_token_(
285 const uint8_t* str,
286 size_t str_len,
287 uint8_t* buffer,
288 size_t buffer_size,
289 UwMacaroonCaveat* new_caveat) {
290 if (str_len == 0) {
291 return create_caveat_no_value_(
292 kUwMacaroonCaveatTypeServerAuthenticationTokenV1, buffer, buffer_size,
293 new_caveat);
294 }
295 return create_caveat_bstr_value_(
296 kUwMacaroonCaveatTypeServerAuthenticationTokenV1, str, str_len, buffer,
297 buffer_size, new_caveat);
298 }
299
uw_macaroon_caveat_get_type_(const UwMacaroonCaveat * caveat,UwMacaroonCaveatType * type)300 bool uw_macaroon_caveat_get_type_(const UwMacaroonCaveat* caveat,
301 UwMacaroonCaveatType* type) {
302 if (caveat == NULL || type == NULL) {
303 return false;
304 }
305
306 uint32_t unsigned_int;
307 if (!uw_macaroon_encoding_decode_uint_(caveat->bytes, caveat->num_bytes,
308 &unsigned_int)) {
309 return false;
310 }
311
312 *type = (UwMacaroonCaveatType)unsigned_int;
313 return is_valid_caveat_type_(*type);
314 }
315
316 /* === Some internal functions defined in macaroon_caveat_internal.h === */
317
uw_macaroon_caveat_sign_(const uint8_t * key,size_t key_len,const UwMacaroonContext * context,const UwMacaroonCaveat * caveat,uint8_t * mac_tag,size_t mac_tag_size)318 bool uw_macaroon_caveat_sign_(const uint8_t* key,
319 size_t key_len,
320 const UwMacaroonContext* context,
321 const UwMacaroonCaveat* caveat,
322 uint8_t* mac_tag,
323 size_t mac_tag_size) {
324 if (key == NULL || key_len == 0 || context == NULL || caveat == NULL ||
325 mac_tag == NULL || mac_tag_size == 0) {
326 return false;
327 }
328
329 UwMacaroonCaveatType caveat_type;
330 if (!uw_macaroon_caveat_get_type_(caveat, &caveat_type) ||
331 !is_valid_caveat_type_(caveat_type)) {
332 return false;
333 }
334
335 // Need to encode the whole caveat as a byte string and then sign it
336
337 // If there is no additional value from the context, just compute the HMAC on
338 // the current byte string.
339 uint8_t bstr_cbor_prefix[UW_MACAROON_ENCODING_MAX_UINT_CBOR_LEN] = {0};
340 size_t bstr_cbor_prefix_len = 0;
341 if (caveat_type != kUwMacaroonCaveatTypeBleSessionID) {
342 if (!uw_macaroon_encoding_encode_byte_str_len_(
343 (uint32_t)(caveat->num_bytes), bstr_cbor_prefix,
344 sizeof(bstr_cbor_prefix), &bstr_cbor_prefix_len)) {
345 return false;
346 }
347
348 UwCryptoHmacMsg messages[] = {
349 {bstr_cbor_prefix, bstr_cbor_prefix_len},
350 {caveat->bytes, caveat->num_bytes},
351 };
352
353 return uw_crypto_hmac_(key, key_len, messages,
354 sizeof(messages) / sizeof(messages[0]), mac_tag,
355 mac_tag_size);
356 }
357
358 // If there is additional value from the context.
359 if (context->ble_session_id == NULL || context->ble_session_id_len == 0) {
360 return false;
361 }
362
363 // The length here includes the length of the BLE session ID string.
364 if (!uw_macaroon_encoding_encode_byte_str_len_(
365 (uint32_t)(context->ble_session_id_len + caveat->num_bytes),
366 bstr_cbor_prefix, sizeof(bstr_cbor_prefix), &bstr_cbor_prefix_len)) {
367 return false;
368 }
369
370 uint8_t value_cbor_prefix[UW_MACAROON_ENCODING_MAX_UINT_CBOR_LEN] = {0};
371 size_t value_cbor_prefix_len = 0;
372 if (!uw_macaroon_encoding_encode_byte_str_len_(
373 (uint32_t)(context->ble_session_id_len), value_cbor_prefix,
374 sizeof(value_cbor_prefix), &value_cbor_prefix_len)) {
375 return false;
376 }
377
378 UwCryptoHmacMsg messages[] = {
379 {bstr_cbor_prefix, bstr_cbor_prefix_len},
380 {caveat->bytes, caveat->num_bytes},
381 {value_cbor_prefix, value_cbor_prefix_len},
382 {context->ble_session_id, context->ble_session_id_len},
383 };
384
385 return uw_crypto_hmac_(key, key_len, messages,
386 sizeof(messages) / sizeof(messages[0]), mac_tag,
387 mac_tag_size);
388 }
389
update_and_check_expiration_time(uint32_t current_time,uint32_t new_expiration_time,UwMacaroonValidationResult * result)390 static bool update_and_check_expiration_time(
391 uint32_t current_time,
392 uint32_t new_expiration_time,
393 UwMacaroonValidationResult* result) {
394 if (result->expiration_time > new_expiration_time) {
395 result->expiration_time = new_expiration_time;
396 }
397
398 return current_time <= result->expiration_time;
399 }
400
update_delegatee_list(UwMacaroonCaveatType caveat_type,const UwMacaroonCaveat * caveat,uint32_t issued_time,UwMacaroonValidationResult * result)401 static bool update_delegatee_list(UwMacaroonCaveatType caveat_type,
402 const UwMacaroonCaveat* caveat,
403 uint32_t issued_time,
404 UwMacaroonValidationResult* result) {
405 if (result->num_delegatees >= MAX_NUM_DELEGATEES || issued_time == 0) {
406 return false;
407 }
408
409 UwMacaroonDelegateeType delegatee_type = kUwMacaroonDelegateeTypeNone;
410 switch (caveat_type) {
411 case kUwMacaroonCaveatTypeDelegateeUser:
412 delegatee_type = kUwMacaroonDelegateeTypeUser;
413 break;
414
415 case kUwMacaroonCaveatTypeDelegateeApp:
416 delegatee_type = kUwMacaroonDelegateeTypeApp;
417 break;
418
419 case kUwMacaroonCaveatTypeDelegateeService:
420 delegatee_type = kUwMacaroonDelegateeTypeService;
421 break;
422
423 default:
424 return false;
425 }
426
427 if (caveat_type != kUwMacaroonCaveatTypeDelegateeUser) {
428 for (size_t i = 0; i < result->num_delegatees; i++) {
429 // There must have at most one DelegateeApp or DelegateeService
430 if (result->delegatees[i].type == delegatee_type) {
431 return false;
432 }
433 }
434 }
435
436 if (!uw_macaroon_caveat_get_value_bstr_(
437 caveat, &(result->delegatees[result->num_delegatees].id),
438 &(result->delegatees[result->num_delegatees].id_len))) {
439 return false;
440 }
441 result->delegatees[result->num_delegatees].type = delegatee_type;
442 result->delegatees[result->num_delegatees].timestamp = issued_time;
443 result->num_delegatees++;
444 return true;
445 }
446
uw_macaroon_caveat_validate_(const UwMacaroonCaveat * caveat,const UwMacaroonContext * context,UwMacaroonValidationState * state,UwMacaroonValidationResult * result)447 bool uw_macaroon_caveat_validate_(const UwMacaroonCaveat* caveat,
448 const UwMacaroonContext* context,
449 UwMacaroonValidationState* state,
450 UwMacaroonValidationResult* result) {
451 if (caveat == NULL || context == NULL || state == NULL || result == NULL) {
452 return false;
453 }
454
455 uint32_t expiration_time = 0;
456 uint32_t issued_time = 0;
457 uint32_t scope = UW_MACAROON_CAVEAT_SCOPE_LOWEST_POSSIBLE;
458
459 UwMacaroonCaveatType caveat_type;
460 if (!uw_macaroon_caveat_get_type_(caveat, &caveat_type)) {
461 return false;
462 }
463
464 switch (caveat_type) {
465 // The types that always validate
466 case kUwMacaroonCaveatTypeClientAuthorizationTokenV1:
467 case kUwMacaroonCaveatTypeServerAuthenticationTokenV1:
468 case kUwMacaroonCaveatTypeNonce:
469 case kUwMacaroonCaveatTypeBleSessionID:
470 return true;
471
472 case kUwMacaroonCaveatTypeDelegationTimestamp:
473 if (!uw_macaroon_caveat_get_value_uint_(caveat, &issued_time) ||
474 issued_time < state->issued_time) {
475 return false;
476 }
477 state->issued_time = issued_time;
478 return true;
479
480 case kUwMacaroonCaveatTypeTTL1Hour:
481 if (state->issued_time == 0) {
482 return false;
483 }
484 return update_and_check_expiration_time(
485 context->current_time, state->issued_time + 60 * 60, result);
486
487 case kUwMacaroonCaveatTypeTTL24Hour:
488 if (state->issued_time == 0) {
489 return false;
490 }
491 return update_and_check_expiration_time(
492 context->current_time, state->issued_time + 24 * 60 * 60, result);
493
494 // Need to create a list of delegatees
495 case kUwMacaroonCaveatTypeDelegateeUser:
496 case kUwMacaroonCaveatTypeDelegateeApp:
497 case kUwMacaroonCaveatTypeDelegateeService:
498 return update_delegatee_list(caveat_type, caveat, state->issued_time,
499 result);
500
501 // Time related caveats
502 case kUwMacaroonCaveatTypeExpirationAbsolute:
503 if (!uw_macaroon_caveat_get_value_uint_(caveat, &expiration_time)) {
504 return false;
505 }
506 return update_and_check_expiration_time(context->current_time,
507 expiration_time, result);
508
509 // The caveats that update the values of the result object
510 case kUwMacaroonCaveatTypeScope:
511 if (!uw_macaroon_caveat_get_value_uint_(caveat, &scope) ||
512 // Larger value means less priviledge
513 scope > UW_MACAROON_CAVEAT_SCOPE_LOWEST_POSSIBLE) {
514 return false;
515 }
516 if (scope > (uint32_t)(result->granted_scope)) {
517 result->granted_scope = (UwMacaroonCaveatScopeType)scope;
518 }
519 return true;
520
521 case kUwMacaroonCaveatTypeAppCommandsOnly:
522 result->weave_app_restricted = true;
523 return true;
524
525 case kUwMacaroonCaveatTypeLanSessionID:
526 return uw_macaroon_caveat_get_value_bstr_(
527 caveat, &(result->lan_session_id), &(result->lan_session_id_len));
528 }
529
530 return false;
531 }
532
uw_macaroon_caveat_get_value_uint_(const UwMacaroonCaveat * caveat,uint32_t * unsigned_int)533 bool uw_macaroon_caveat_get_value_uint_(const UwMacaroonCaveat* caveat,
534 uint32_t* unsigned_int) {
535 if (caveat == NULL || unsigned_int == NULL) {
536 return false;
537 }
538
539 UwMacaroonCaveatType type;
540 if (!uw_macaroon_caveat_get_type_(caveat, &type)) {
541 return false;
542 }
543 if (type != kUwMacaroonCaveatTypeScope &&
544 type != kUwMacaroonCaveatTypeExpirationAbsolute &&
545 type != kUwMacaroonCaveatTypeDelegationTimestamp) {
546 // Wrong type
547 return false;
548 }
549
550 // Skip the portion for CBOR type
551 size_t offset;
552 if (!uw_macaroon_encoding_get_item_len_(caveat->bytes, caveat->num_bytes,
553 &offset)) {
554 return false;
555 }
556
557 return uw_macaroon_encoding_decode_uint_(
558 caveat->bytes + offset, caveat->num_bytes - offset, unsigned_int);
559 }
560
uw_macaroon_caveat_get_value_bstr_(const UwMacaroonCaveat * caveat,const uint8_t ** str,size_t * str_len)561 bool uw_macaroon_caveat_get_value_bstr_(const UwMacaroonCaveat* caveat,
562 const uint8_t** str,
563 size_t* str_len) {
564 if (caveat == NULL || str == NULL || str_len == NULL) {
565 return false;
566 }
567
568 UwMacaroonCaveatType type;
569 if (!uw_macaroon_caveat_get_type_(caveat, &type)) {
570 return false;
571 }
572 if (type != kUwMacaroonCaveatTypeNonce &&
573 type != kUwMacaroonCaveatTypeDelegateeUser &&
574 type != kUwMacaroonCaveatTypeDelegateeApp &&
575 type != kUwMacaroonCaveatTypeDelegateeService &&
576 type != kUwMacaroonCaveatTypeLanSessionID &&
577 type != kUwMacaroonCaveatTypeClientAuthorizationTokenV1 &&
578 type != kUwMacaroonCaveatTypeServerAuthenticationTokenV1) {
579 // Wrong type
580 return false;
581 }
582
583 size_t offset;
584 if (!uw_macaroon_encoding_get_item_len_(caveat->bytes, caveat->num_bytes,
585 &offset)) {
586 return false;
587 }
588
589 return uw_macaroon_encoding_decode_byte_str_(
590 caveat->bytes + offset, caveat->num_bytes - offset, str, str_len);
591 }
592
uw_macaroon_caveat_init_validation_state_(UwMacaroonValidationState * state)593 bool uw_macaroon_caveat_init_validation_state_(
594 UwMacaroonValidationState* state) {
595 if (state == NULL) {
596 return false;
597 }
598
599 state->issued_time = 0;
600 return true;
601 }
602