aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVitaly Buka <vitalybuka@google.com>2016-01-27 14:21:37 -0800
committerVitaly Buka <vitalybuka@google.com>2016-01-27 23:25:49 +0000
commit7d29a5a5402badd1c24a8542539306a521c14cc1 (patch)
tree851b32b9ed20076c2fe54c880ab5eec63e460dc3
parent1c83377af2869fa3e641fa332fe2180aa6a21c2d (diff)
downloadlibweave-7d29a5a5402badd1c24a8542539306a521c14cc1.tar.gz
Update macaroon lib
Change-Id: I71f2aacbc094b3e4cbd10898d037719ac59c4015 Reviewed-on: https://weave-review.googlesource.com/2359 Reviewed-by: Vitaly Buka <vitalybuka@google.com>
-rw-r--r--third_party/libuweave/src/crypto_hmac.h30
-rw-r--r--third_party/libuweave/src/crypto_utils.c7
-rw-r--r--third_party/libuweave/src/macaroon.c286
-rw-r--r--third_party/libuweave/src/macaroon.h89
-rw-r--r--third_party/libuweave/src/macaroon_caveat.c591
-rw-r--r--third_party/libuweave/src/macaroon_caveat.h105
-rw-r--r--third_party/libuweave/src/macaroon_caveat_internal.h41
-rw-r--r--third_party/libuweave/src/macaroon_context.c24
-rw-r--r--third_party/libuweave/src/macaroon_context.h18
-rw-r--r--third_party/libuweave/src/macaroon_encoding.c103
-rw-r--r--third_party/libuweave/src/macaroon_encoding.h47
11 files changed, 974 insertions, 367 deletions
diff --git a/third_party/libuweave/src/crypto_hmac.h b/third_party/libuweave/src/crypto_hmac.h
index bac634a..6f76ed0 100644
--- a/third_party/libuweave/src/crypto_hmac.h
+++ b/third_party/libuweave/src/crypto_hmac.h
@@ -9,21 +9,21 @@
#include <stddef.h>
#include <stdint.h>
-// Return the minimum required number of bytes for the state_buffer used in the
-// init, update and final functions.
-size_t uw_crypto_hmac_required_buffer_size_();
+typedef struct {
+ const uint8_t* bytes;
+ size_t num_bytes;
+} UwCryptoHmacMsg;
-bool uw_crypto_hmac_init_(uint8_t* state_buffer,
- size_t state_buffer_len,
- const uint8_t* key,
- size_t key_len);
-bool uw_crypto_hmac_update_(uint8_t* state_buffer,
- size_t state_buffer_len,
- const uint8_t* data,
- size_t data_len);
-bool uw_crypto_hmac_final_(uint8_t* state_buffer,
- size_t state_buffer_len,
- uint8_t* truncated_digest,
- size_t truncated_digest_len);
+/**
+ * Compute HMAC over a list of messages, which is equivalent to computing HMAC
+ * over the concatenation of all the messages. The HMAC output will be truncated
+ * to the desired length truncated_digest_len, and written into trucated_digest.
+ */
+bool uw_crypto_hmac_(const uint8_t* key,
+ size_t key_len,
+ const UwCryptoHmacMsg messages[],
+ size_t num_messages,
+ uint8_t* truncated_digest,
+ size_t truncated_digest_len);
#endif // LIBUWEAVE_SRC_CRYPTO_HMAC_H_
diff --git a/third_party/libuweave/src/crypto_utils.c b/third_party/libuweave/src/crypto_utils.c
index 76b8068..7a6e38f 100644
--- a/third_party/libuweave/src/crypto_utils.c
+++ b/third_party/libuweave/src/crypto_utils.c
@@ -7,13 +7,6 @@
bool uw_crypto_utils_equal_(const uint8_t* arr1,
const uint8_t* arr2,
size_t len) {
- if (arr1 == NULL || arr2 == NULL) {
- if (arr1 == NULL && arr2 == NULL && len == 0) {
- return true;
- }
- return false;
- }
-
uint8_t diff = 0;
for (size_t i = 0; i < len; i++) {
diff |= arr1[i] ^ arr2[i];
diff --git a/third_party/libuweave/src/macaroon.c b/third_party/libuweave/src/macaroon.c
index 70afda1..50b2d00 100644
--- a/third_party/libuweave/src/macaroon.c
+++ b/third_party/libuweave/src/macaroon.c
@@ -8,13 +8,17 @@
#include "src/crypto_utils.h"
#include "src/macaroon_caveat.h"
+#include "src/macaroon_caveat_internal.h"
#include "src/macaroon_encoding.h"
-static bool create_mac_tag_(const uint8_t* key, size_t key_len,
- const UwMacaroonCaveat* caveats, size_t num_caveats,
+static bool create_mac_tag_(const uint8_t* key,
+ size_t key_len,
+ const UwMacaroonContext* context,
+ const UwMacaroonCaveat* const caveats[],
+ size_t num_caveats,
uint8_t mac_tag[UW_MACAROON_MAC_LEN]) {
- if (key == NULL || key_len == 0 || caveats == NULL || num_caveats == 0 ||
- mac_tag == NULL) {
+ if (key == NULL || key_len == 0 || context == NULL || caveats == NULL ||
+ num_caveats == 0 || mac_tag == NULL) {
return false;
}
@@ -26,15 +30,15 @@ static bool create_mac_tag_(const uint8_t* key, size_t key_len,
uint8_t mac_tag_buff[UW_MACAROON_MAC_LEN];
// Compute the first tag by using the key
- if (!uw_macaroon_caveat_sign_(key, key_len, &(caveats[0]), mac_tag_buff,
+ if (!uw_macaroon_caveat_sign_(key, key_len, context, caveats[0], mac_tag_buff,
UW_MACAROON_MAC_LEN)) {
return false;
}
// Compute the rest of the tags by using the tag as the key
for (size_t i = 1; i < num_caveats; i++) {
- if (!uw_macaroon_caveat_sign_(mac_tag_buff, UW_MACAROON_MAC_LEN,
- &(caveats[i]), mac_tag_buff,
+ if (!uw_macaroon_caveat_sign_(mac_tag_buff, UW_MACAROON_MAC_LEN, context,
+ caveats[i], mac_tag_buff,
UW_MACAROON_MAC_LEN)) {
return false;
}
@@ -44,33 +48,38 @@ static bool create_mac_tag_(const uint8_t* key, size_t key_len,
return true;
}
-bool uw_macaroon_new_from_mac_tag_(UwMacaroon* new_macaroon,
- const uint8_t mac_tag[UW_MACAROON_MAC_LEN],
- const UwMacaroonCaveat* caveats,
- size_t num_caveats) {
- if (new_macaroon == NULL || mac_tag == NULL || caveats == NULL ||
- num_caveats == 0) {
+static bool verify_mac_tag_(const uint8_t* root_key,
+ size_t root_key_len,
+ const UwMacaroonContext* context,
+ const UwMacaroonCaveat* const caveats[],
+ size_t num_caveats,
+ const uint8_t mac_tag[UW_MACAROON_MAC_LEN]) {
+ if (root_key == NULL || root_key_len == 0 || context == NULL ||
+ caveats == NULL || num_caveats == 0 || mac_tag == 0) {
return false;
}
- memcpy(new_macaroon->mac_tag, mac_tag, UW_MACAROON_MAC_LEN);
- new_macaroon->num_caveats = num_caveats;
- new_macaroon->caveats = caveats;
+ uint8_t computed_mac_tag[UW_MACAROON_MAC_LEN] = {0};
+ if (!create_mac_tag_(root_key, root_key_len, context, caveats, num_caveats,
+ computed_mac_tag)) {
+ return false;
+ }
- return true;
+ return uw_crypto_utils_equal_(mac_tag, computed_mac_tag, UW_MACAROON_MAC_LEN);
}
-bool uw_macaroon_new_from_root_key_(UwMacaroon* new_macaroon,
- const uint8_t* root_key,
- size_t root_key_len,
- const UwMacaroonCaveat* caveats,
- size_t num_caveats) {
- if (new_macaroon == NULL || root_key == NULL || root_key_len == 0 ||
- caveats == NULL || num_caveats == 0) {
+bool uw_macaroon_create_from_root_key_(UwMacaroon* new_macaroon,
+ const uint8_t* root_key,
+ size_t root_key_len,
+ const UwMacaroonContext* context,
+ const UwMacaroonCaveat* const caveats[],
+ size_t num_caveats) {
+ if (new_macaroon == NULL || root_key == NULL || context == NULL ||
+ root_key_len == 0 || caveats == NULL || num_caveats == 0) {
return false;
}
- if (!create_mac_tag_(root_key, root_key_len, caveats, num_caveats,
+ if (!create_mac_tag_(root_key, root_key_len, context, caveats, num_caveats,
new_macaroon->mac_tag)) {
return false;
}
@@ -81,139 +90,228 @@ bool uw_macaroon_new_from_root_key_(UwMacaroon* new_macaroon,
return true;
}
-bool uw_macaroon_verify_(const UwMacaroon* macaroon,
- const uint8_t* root_key,
- size_t root_key_len) {
- if (macaroon == NULL || root_key == NULL) {
- return false;
- }
-
- uint8_t mac_tag[UW_MACAROON_MAC_LEN] = {0};
- if (!create_mac_tag_(root_key, root_key_len, macaroon->caveats,
- macaroon->num_caveats, mac_tag)) {
- return false;
- }
-
- return uw_crypto_utils_equal_(mac_tag, macaroon->mac_tag,
- UW_MACAROON_MAC_LEN);
-}
-
bool uw_macaroon_extend_(const UwMacaroon* old_macaroon,
UwMacaroon* new_macaroon,
+ const UwMacaroonContext* context,
const UwMacaroonCaveat* additional_caveat,
- uint8_t* buffer, size_t buffer_size) {
- if (old_macaroon == NULL || new_macaroon == NULL ||
+ uint8_t* buffer,
+ size_t buffer_size) {
+ if (old_macaroon == NULL || new_macaroon == NULL || context == NULL ||
additional_caveat == NULL || buffer == NULL || buffer_size == 0) {
return false;
}
new_macaroon->num_caveats = old_macaroon->num_caveats + 1;
- // Extend the caveat list
- if ((new_macaroon->num_caveats) * sizeof(UwMacaroonCaveat) > buffer_size) {
- // Not enough memory to store the extended caveat list
+ // Extend the caveat pointer list
+ if ((new_macaroon->num_caveats) * sizeof(UwMacaroonCaveat*) > buffer_size) {
+ // Not enough memory to store the extended caveat pointer list
return false;
}
- UwMacaroonCaveat* extended_list = (UwMacaroonCaveat*)buffer;
- if (old_macaroon->caveats != NULL && extended_list != old_macaroon->caveats) {
+ const UwMacaroonCaveat** extended_list = (const UwMacaroonCaveat**)buffer;
+ if (new_macaroon->caveats != old_macaroon->caveats) {
memcpy(extended_list, old_macaroon->caveats,
- (old_macaroon->num_caveats) * sizeof(UwMacaroonCaveat));
+ old_macaroon->num_caveats * sizeof(old_macaroon->caveats[0]));
}
- extended_list[old_macaroon->num_caveats] = *additional_caveat;
- new_macaroon->caveats = extended_list;
+ extended_list[old_macaroon->num_caveats] = additional_caveat;
+ new_macaroon->caveats = (const UwMacaroonCaveat* const*)extended_list;
// Compute the new MAC tag
- return create_mac_tag_(old_macaroon->mac_tag, UW_MACAROON_MAC_LEN,
- additional_caveat, 1, new_macaroon->mac_tag);
+ return create_mac_tag_(old_macaroon->mac_tag, UW_MACAROON_MAC_LEN, context,
+ new_macaroon->caveats + old_macaroon->num_caveats, 1,
+ new_macaroon->mac_tag);
}
-// Encode a Macaroon to a byte string
-bool uw_macaroon_dump_(const UwMacaroon* macaroon,
- uint8_t* out,
- size_t out_len,
- size_t* resulting_str_len) {
- if (macaroon == NULL || out == NULL || out_len == 0 ||
- resulting_str_len == NULL) {
+static void init_validation_result(UwMacaroonValidationResult* result) {
+ // Start from the largest scope
+ result->granted_scope = kUwMacaroonCaveatScopeTypeOwner;
+ result->expiration_time = UINT32_MAX;
+ result->weave_app_restricted = false;
+ result->lan_session_id = NULL;
+ result->lan_session_id_len = 0;
+ result->num_delegatees = 0;
+}
+
+/** Reset the result object to the lowest scope when encountering errors */
+static void reset_validation_result(UwMacaroonValidationResult* result) {
+ // Start from the largest scope or highest privilege
+ result->granted_scope =
+ (UwMacaroonCaveatScopeType)UW_MACAROON_CAVEAT_SCOPE_LOWEST_POSSIBLE;
+ result->expiration_time = 0;
+ result->weave_app_restricted = true;
+ result->lan_session_id = NULL;
+ result->lan_session_id_len = 0;
+
+ result->num_delegatees = 0;
+ for (size_t i = 0; i < MAX_NUM_DELEGATEES; i++) {
+ result->delegatees[i].id = NULL;
+ result->delegatees[i].id_len = 0;
+ result->delegatees[i].is_app = true;
+ }
+}
+
+bool uw_macaroon_validate_(const UwMacaroon* macaroon,
+ const uint8_t* root_key,
+ size_t root_key_len,
+ const UwMacaroonContext* context,
+ UwMacaroonValidationResult* result) {
+ if (result == NULL) {
return false;
}
+ init_validation_result(result);
- size_t offset = 0, item_len;
+ if (root_key == NULL || root_key_len == 0 || macaroon == NULL ||
+ context == NULL || result == NULL ||
+ !verify_mac_tag_(root_key, root_key_len, context, macaroon->caveats,
+ macaroon->num_caveats, macaroon->mac_tag)) {
+ return false;
+ }
- if (!uw_macaroon_encoding_encode_byte_str_(
- macaroon->mac_tag, UW_MACAROON_MAC_LEN, out, out_len, &item_len)) {
+ UwMacaroonValidationState state;
+ if (!uw_macaroon_caveat_init_validation_state_(&state)) {
return false;
}
- offset += item_len;
+ for (size_t i = 0; i < macaroon->num_caveats; i++) {
+ if (!uw_macaroon_caveat_validate_(macaroon->caveats[i], context, &state,
+ result)) {
+ reset_validation_result(result); // Reset the result object
+ return false;
+ }
+ }
+
+ return true;
+}
- if (!uw_macaroon_encoding_encode_array_len_(
- (uint32_t)(macaroon->num_caveats), out + offset, out_len - offset, &item_len)) {
+// Encode a Macaroon to a byte string
+bool uw_macaroon_serialize_(const UwMacaroon* macaroon,
+ uint8_t* out,
+ size_t out_len,
+ size_t* resulting_str_len) {
+ if (macaroon == NULL || out == NULL ||
+ out_len < UW_MACAROON_ENCODING_MAX_UINT_CBOR_LEN ||
+ resulting_str_len == NULL) {
+ return false;
+ }
+
+ // Need to encode the whole Macaroon again into a byte string.
+
+ // First encode the part without the overall byte string header to the buffer
+ // to get the total length.
+ size_t item_len = 0;
+ // Start with an offset
+ size_t offset = UW_MACAROON_ENCODING_MAX_UINT_CBOR_LEN;
+ if (!uw_macaroon_encoding_encode_array_len_((uint32_t)(macaroon->num_caveats),
+ out + offset, out_len - offset,
+ &item_len)) {
return false;
}
offset += item_len;
for (size_t i = 0; i < macaroon->num_caveats; i++) {
if (!uw_macaroon_encoding_encode_byte_str_(
- macaroon->caveats[i].bytes, macaroon->caveats[i].num_bytes,
+ macaroon->caveats[i]->bytes, macaroon->caveats[i]->num_bytes,
out + offset, out_len - offset, &item_len)) {
return false;
}
offset += item_len;
}
- *resulting_str_len = offset;
+ if (!uw_macaroon_encoding_encode_byte_str_(macaroon->mac_tag,
+ UW_MACAROON_MAC_LEN, out + offset,
+ out_len - offset, &item_len)) {
+ return false;
+ }
+ offset += item_len;
+
+ // Encode the length of the body at the beginning of the buffer
+ size_t bstr_len = offset - UW_MACAROON_ENCODING_MAX_UINT_CBOR_LEN;
+ if (!uw_macaroon_encoding_encode_byte_str_len_(
+ bstr_len, out, UW_MACAROON_ENCODING_MAX_UINT_CBOR_LEN, &item_len)) {
+ return false;
+ }
+
+ // Move the body part to be adjacent to the byte string header part
+ memmove(out + item_len, out + UW_MACAROON_ENCODING_MAX_UINT_CBOR_LEN,
+ bstr_len);
+
+ *resulting_str_len = item_len + bstr_len;
return true;
}
// Decode a byte string to a Macaroon
-bool uw_macaroon_load_(const uint8_t* in,
- size_t in_len,
- uint8_t* caveats_buffer,
- size_t caveats_buffer_size,
- UwMacaroon* macaroon) {
- if (in == NULL || in_len == 0 || caveats_buffer == NULL ||
- caveats_buffer_size == 0 || macaroon == NULL) {
+bool uw_macaroon_deserialize_(const uint8_t* in,
+ size_t in_len,
+ uint8_t* buffer,
+ size_t buffer_size,
+ UwMacaroon* macaroon) {
+ if (in == NULL || in_len == 0 || buffer == NULL || buffer_size == 0 ||
+ macaroon == NULL) {
return false;
}
- const uint8_t* tag;
- size_t tag_len;
- if (!uw_macaroon_encoding_decode_byte_str_(in, in_len, &tag, &tag_len) ||
- tag_len != UW_MACAROON_MAC_LEN) {
+ size_t offset = 0;
+ size_t item_len = 0;
+
+ const uint8_t* bstr = NULL;
+ size_t bstr_len = 0;
+ if (!uw_macaroon_encoding_decode_byte_str_(in + offset, in_len - offset,
+ &bstr, &bstr_len)) {
return false;
}
- memcpy(macaroon->mac_tag, tag, UW_MACAROON_MAC_LEN);
+ item_len = bstr - in; // The length of the first byte string header
+ offset += item_len;
- size_t offset = 0, cbor_item_len;
- if (!uw_macaroon_encoding_get_item_len_(in, in_len, &cbor_item_len)) {
+ if (item_len + bstr_len != in_len) {
+ // The string length doesn't match
return false;
}
- offset += cbor_item_len;
- uint32_t array_len;
+ uint32_t array_len = 0;
if (!uw_macaroon_encoding_decode_array_len_(in + offset, in_len - offset,
&array_len)) {
return false;
}
macaroon->num_caveats = (size_t)array_len;
- if (caveats_buffer_size < array_len * sizeof(UwMacaroonCaveat)) {
+ if (buffer_size <
+ (array_len * (sizeof(UwMacaroonCaveat) + sizeof(UwMacaroonCaveat*)))) {
+ // Need two levels of abstraction, one for structs and one for pointers
+ return false;
+ }
+
+ if (!uw_macaroon_encoding_get_item_len_(in + offset, in_len - offset,
+ &item_len)) {
return false;
}
+ offset += item_len;
- UwMacaroonCaveat* caveats = (UwMacaroonCaveat*)caveats_buffer;
+ const UwMacaroonCaveat** caveat_pointers = (const UwMacaroonCaveat**)buffer;
+ buffer += array_len * sizeof(UwMacaroonCaveat*);
+ UwMacaroonCaveat* caveat_structs = (UwMacaroonCaveat*)buffer;
for (size_t i = 0; i < array_len; i++) {
- if (!uw_macaroon_encoding_get_item_len_(in + offset, in_len - offset,
- &cbor_item_len)) {
+ caveat_pointers[i] = &(caveat_structs[i]);
+
+ if (!uw_macaroon_encoding_decode_byte_str_(
+ in + offset, in_len - offset, &(caveat_structs[i].bytes),
+ &(caveat_structs[i].num_bytes))) {
return false;
}
- offset += cbor_item_len;
- if (!uw_macaroon_encoding_decode_byte_str_(in + offset, in_len - offset,
- &(caveats[i].bytes),
- &(caveats[i].num_bytes))) {
+ if (!uw_macaroon_encoding_get_item_len_(in + offset, in_len - offset,
+ &item_len)) {
return false;
}
+ offset += item_len;
+ }
+ macaroon->caveats = caveat_pointers;
+
+ const uint8_t* tag;
+ size_t tag_len;
+ if (!uw_macaroon_encoding_decode_byte_str_(in + offset, in_len - offset, &tag,
+ &tag_len) ||
+ tag_len != UW_MACAROON_MAC_LEN) {
+ return false;
}
- macaroon->caveats = caveats;
+ memcpy(macaroon->mac_tag, tag, UW_MACAROON_MAC_LEN);
return true;
}
diff --git a/third_party/libuweave/src/macaroon.h b/third_party/libuweave/src/macaroon.h
index 61242f7..dfaaba7 100644
--- a/third_party/libuweave/src/macaroon.h
+++ b/third_party/libuweave/src/macaroon.h
@@ -9,7 +9,8 @@
#include <stddef.h>
#include <stdint.h>
-#include "macaroon_caveat.h"
+#include "src/macaroon_caveat.h"
+#include "src/macaroon_context.h"
#define UW_MACAROON_MAC_LEN 16
@@ -20,45 +21,71 @@
typedef struct {
uint8_t mac_tag[UW_MACAROON_MAC_LEN];
size_t num_caveats;
- const UwMacaroonCaveat* caveats;
+ const UwMacaroonCaveat* const* caveats;
} UwMacaroon;
-bool uw_macaroon_new_from_mac_tag_(UwMacaroon* new_macaroon,
- const uint8_t mac_tag[UW_MACAROON_MAC_LEN],
- const UwMacaroonCaveat* caveats,
- size_t num_caveats);
+// For the delegatee list in the validation result object
+typedef struct {
+ const uint8_t* id;
+ size_t id_len;
+ bool is_app;
+} UwMacaroonDelegateeInfo;
+
+#define MAX_NUM_DELEGATEES 10
-bool uw_macaroon_new_from_root_key_(UwMacaroon* new_macaroon,
- const uint8_t* root_key,
- size_t root_key_len,
- const UwMacaroonCaveat* caveats,
- size_t num_caveats);
+typedef struct {
+ UwMacaroonCaveatScopeType granted_scope;
+ uint32_t expiration_time;
+ bool weave_app_restricted;
+ const uint8_t* lan_session_id;
+ size_t lan_session_id_len;
+ UwMacaroonDelegateeInfo delegatees[MAX_NUM_DELEGATEES];
+ size_t num_delegatees;
+} UwMacaroonValidationResult;
-bool uw_macaroon_verify_(const UwMacaroon* macaroon,
- const uint8_t* root_key,
- size_t root_key_len);
+bool uw_macaroon_create_from_root_key_(UwMacaroon* new_macaroon,
+ const uint8_t* root_key,
+ size_t root_key_len,
+ const UwMacaroonContext* context,
+ const UwMacaroonCaveat* const caveats[],
+ size_t num_caveats);
-// Create a new macaroon with a new caveat
+/** Creates a new macaroon with a new caveat. */
bool uw_macaroon_extend_(const UwMacaroon* old_macaroon,
UwMacaroon* new_macaroon,
+ const UwMacaroonContext* context,
const UwMacaroonCaveat* additional_caveat,
- uint8_t* buffer, size_t buffer_size);
+ uint8_t* buffer,
+ size_t buffer_size);
+
+/**
+ * Verify and validate the Macaroon, and put relevant information into the
+ * result object.
+ */
+bool uw_macaroon_validate_(
+ const UwMacaroon* macaroon,
+ const uint8_t* root_key,
+ size_t root_key_len,
+ const UwMacaroonContext* context,
+ UwMacaroonValidationResult* result);
-// Encode a Macaroon to a byte string
-bool uw_macaroon_dump_(const UwMacaroon* macaroon,
- uint8_t* out,
- size_t out_len,
- size_t* resulting_str_len);
+/** Encode a Macaroon to a byte string. */
+bool uw_macaroon_serialize_(const UwMacaroon* macaroon,
+ uint8_t* out,
+ size_t out_len,
+ size_t* resulting_str_len);
-// Decode a byte string to a Macaroon (the caveats_buffer here is used only for
-// the caveat pointer list *caveats in the UwMacaroon *macaroon). One note is
-// that the function doesn't copy string values to new buffers, so the caller
-// may maintain the input string around to make caveats with string values to
-// be usuable.
-bool uw_macaroon_load_(const uint8_t* in,
- size_t in_len,
- uint8_t* caveats_buffer,
- size_t caveats_buffer_size,
- UwMacaroon* macaroon);
+/**
+ * Decodes a byte string to a Macaroon.
+ *
+ * One note is that the function doesn't copy string values to new buffers, so
+ * the caller must maintain the input string around to make caveats with string
+ * values to be usable.
+ */
+bool uw_macaroon_deserialize_(const uint8_t* in,
+ size_t in_len,
+ uint8_t* buffer,
+ size_t buffer_size,
+ UwMacaroon* new_macaroon);
#endif // LIBUWEAVE_SRC_MACAROON_H_
diff --git a/third_party/libuweave/src/macaroon_caveat.c b/third_party/libuweave/src/macaroon_caveat.c
index 594f9de..b8b2183 100644
--- a/third_party/libuweave/src/macaroon_caveat.c
+++ b/third_party/libuweave/src/macaroon_caveat.c
@@ -3,125 +3,287 @@
// found in the LICENSE file.
#include "src/macaroon_caveat.h"
+#include "src/macaroon_caveat_internal.h"
#include <string.h>
#include "src/crypto_hmac.h"
+#include "src/macaroon.h"
#include "src/macaroon_context.h"
#include "src/macaroon_encoding.h"
-// TODO(bozhu): Find a better way to pre-allocate memory for HMACc computations?
-// Are C99 variable-length arrays allowed on embedded devices?
-#define HMAC_STATE_BUFFER_SIZE 1024
+#define MAX_CBOR_STR_LEN_FOR_UINT 5
-static bool create_caveat_(UwMacaroonCaveatType type, const void* value,
- size_t value_len, uint8_t* buffer,
- size_t buffer_size, UwMacaroonCaveat* caveat) {
- if (buffer == NULL || buffer_size == 0 || caveat == NULL) {
- // Here value can be NULL, and value_len can be 0
- return false;
+static bool is_valid_caveat_type_(UwMacaroonCaveatType type) {
+ switch (type) {
+ case kUwMacaroonCaveatTypeNonce:
+ case kUwMacaroonCaveatTypeScope:
+ case kUwMacaroonCaveatTypeExpirationAbsolute:
+ case kUwMacaroonCaveatTypeTTL1Hour:
+ case kUwMacaroonCaveatTypeTTL24Hour:
+ case kUwMacaroonCaveatTypeDelegationTimestamp:
+ case kUwMacaroonCaveatTypeDelegateeUser:
+ case kUwMacaroonCaveatTypeDelegateeApp:
+ case kUwMacaroonCaveatTypeAppCommandsOnly:
+ case kUwMacaroonCaveatTypeBleSessionID:
+ case kUwMacaroonCaveatTypeLanSessionID:
+ case kUwMacaroonCaveatTypeClientAuthorizationTokenV1:
+ case kUwMacaroonCaveatTypeServerAuthenticationTokenV1:
+ return true;
}
+ return false;
+}
- caveat->bytes = buffer;
- size_t encoded_str_len, total_str_len;
+static bool is_valid_scope_type_(UwMacaroonCaveatScopeType type) {
+ switch (type) {
+ case kUwMacaroonCaveatScopeTypeOwner:
+ case kUwMacaroonCaveatScopeTypeManager:
+ case kUwMacaroonCaveatScopeTypeUser:
+ case kUwMacaroonCaveatScopeTypeViewer:
+ return true;
+ }
+ return false;
+}
- uint32_t unsigned_int = (uint32_t)type;
- if (!uw_macaroon_encoding_encode_uint_(unsigned_int, buffer, buffer_size,
- &encoded_str_len)) {
+static bool create_caveat_no_value_(UwMacaroonCaveatType type,
+ uint8_t* buffer,
+ size_t buffer_size,
+ UwMacaroonCaveat* new_caveat) {
+ // (buffer_size == 0 || get_buffer_size_() > buffer_size) will conver the case
+ // that get_buffer_size_() returns 0 (for errors), so there is no need to
+ // check get_buffer_size_() == 0 again.
+ if (buffer == NULL || buffer_size == 0 || new_caveat == NULL ||
+ uw_macaroon_caveat_creation_get_buffsize_(type, 0) > buffer_size) {
return false;
}
- total_str_len = encoded_str_len;
- buffer += encoded_str_len;
- buffer_size -= encoded_str_len;
-
- switch (type) {
- case kUwMacaroonCaveatTypeStop:
- case kUwMacaroonCaveatTypeSessionIdentifier:
- // No value
- encoded_str_len = 0;
- break;
-
- case kUwMacaroonCaveatTypeScope:
- case kUwMacaroonCaveatTypeIssued:
- case kUwMacaroonCaveatTypeTTL:
- case kUwMacaroonCaveatTypeExpiration:
- // Integer
- if (value_len != sizeof(uint32_t)) {
- // Wrong size for integers
- return false;
- }
- unsigned_int = *((uint32_t*)value);
- if (!uw_macaroon_encoding_encode_uint_(unsigned_int, buffer, buffer_size,
- &encoded_str_len)) {
- return false;
- }
- break;
- case kUwMacaroonCaveatTypeIdentifier:
- // Text string
- if (!uw_macaroon_encoding_encode_text_str_((uint8_t*)value, value_len,
- buffer, buffer_size,
- &encoded_str_len)) {
- return false;
- }
- break;
-
- default:
- // Should never reach here
- return false;
+ size_t encoded_str_len = 0, total_str_len = 0;
+ if (!uw_macaroon_encoding_encode_uint_((uint32_t)type, buffer, buffer_size,
+ &encoded_str_len)) {
+ return false;
}
-
total_str_len += encoded_str_len;
- caveat->num_bytes = total_str_len;
+
+ new_caveat->bytes = buffer;
+ new_caveat->num_bytes = total_str_len;
return true;
}
-bool uw_macaroon_caveat_create_without_value_(UwMacaroonCaveatType type,
- uint8_t* buffer,
- size_t buffer_size,
- UwMacaroonCaveat* caveat) {
- if (buffer == NULL || buffer_size == 0 || caveat == NULL) {
+static bool create_caveat_uint_value_(UwMacaroonCaveatType type,
+ uint32_t unsigned_int,
+ uint8_t* buffer,
+ size_t buffer_size,
+ UwMacaroonCaveat* new_caveat) {
+ if (buffer == NULL || buffer_size == 0 || new_caveat == NULL ||
+ uw_macaroon_caveat_creation_get_buffsize_(type, 0) > buffer_size) {
return false;
}
- if (type != kUwMacaroonCaveatTypeStop &&
- type != kUwMacaroonCaveatTypeSessionIdentifier) {
+
+ size_t encoded_str_len = 0, total_str_len = 0;
+ if (!uw_macaroon_encoding_encode_uint_((uint32_t)type, buffer, buffer_size,
+ &encoded_str_len)) {
+ return false;
+ }
+ total_str_len += encoded_str_len;
+ if (!uw_macaroon_encoding_encode_uint_(unsigned_int, buffer + total_str_len,
+ buffer_size - total_str_len,
+ &encoded_str_len)) {
return false;
}
+ total_str_len += encoded_str_len;
- return create_caveat_(type, NULL, 0, buffer, buffer_size, caveat);
+ new_caveat->bytes = buffer;
+ new_caveat->num_bytes = total_str_len;
+ return true;
}
-bool uw_macaroon_caveat_create_with_uint_(UwMacaroonCaveatType type,
- uint32_t value, uint8_t* buffer,
- size_t buffer_size,
- UwMacaroonCaveat* caveat) {
- if (buffer == NULL || buffer_size == 0 || caveat == NULL) {
+static bool create_caveat_bstr_value_(UwMacaroonCaveatType type,
+ const uint8_t* str,
+ size_t str_len,
+ uint8_t* buffer,
+ size_t buffer_size,
+ UwMacaroonCaveat* new_caveat) {
+ if ((str == NULL && str_len != 0) || buffer == NULL || buffer_size == 0 ||
+ new_caveat == NULL ||
+ uw_macaroon_caveat_creation_get_buffsize_(type, str_len) > buffer_size) {
return false;
}
- if (type != kUwMacaroonCaveatTypeScope &&
- type != kUwMacaroonCaveatTypeIssued &&
- type != kUwMacaroonCaveatTypeTTL &&
- type != kUwMacaroonCaveatTypeExpiration) {
+
+ size_t encoded_str_len = 0, total_str_len = 0;
+ if (!uw_macaroon_encoding_encode_uint_((uint32_t)type, buffer, buffer_size,
+ &encoded_str_len)) {
return false;
}
+ total_str_len += encoded_str_len;
+ if (!uw_macaroon_encoding_encode_byte_str_(
+ str, str_len, buffer + total_str_len, buffer_size - total_str_len,
+ &encoded_str_len)) {
+ return false;
+ }
+ total_str_len += encoded_str_len;
- return create_caveat_(type, &value, sizeof(uint32_t), buffer, buffer_size,
- caveat);
+ new_caveat->bytes = buffer;
+ new_caveat->num_bytes = total_str_len;
+ return true;
}
-bool uw_macaroon_caveat_create_with_str_(UwMacaroonCaveatType type,
- const uint8_t* str, size_t str_len,
- uint8_t* buffer, size_t buffer_size,
- UwMacaroonCaveat* caveat) {
- if (buffer == NULL || buffer_size == 0 || caveat == NULL ||
- (str == NULL && str_len != 0)) {
- return false;
+size_t uw_macaroon_caveat_creation_get_buffsize_(UwMacaroonCaveatType type,
+ size_t str_len) {
+ switch (type) {
+ // No values
+ case kUwMacaroonCaveatTypeTTL1Hour:
+ case kUwMacaroonCaveatTypeTTL24Hour:
+ case kUwMacaroonCaveatTypeAppCommandsOnly:
+ case kUwMacaroonCaveatTypeBleSessionID:
+ return UW_MACAROON_ENCODING_MAX_UINT_CBOR_LEN;
+
+ // Unsigned integers
+ case kUwMacaroonCaveatTypeScope:
+ case kUwMacaroonCaveatTypeExpirationAbsolute:
+ case kUwMacaroonCaveatTypeDelegationTimestamp:
+ return 2 * UW_MACAROON_ENCODING_MAX_UINT_CBOR_LEN;
+
+ // Byte strings
+ case kUwMacaroonCaveatTypeNonce:
+ case kUwMacaroonCaveatTypeDelegateeUser:
+ case kUwMacaroonCaveatTypeDelegateeApp:
+ case kUwMacaroonCaveatTypeLanSessionID:
+ case kUwMacaroonCaveatTypeClientAuthorizationTokenV1:
+ case kUwMacaroonCaveatTypeServerAuthenticationTokenV1:
+ return str_len + UW_MACAROON_ENCODING_MAX_UINT_CBOR_LEN;
+
+ default:
+ return 0; // For errors
}
- if (type != kUwMacaroonCaveatTypeIdentifier) {
+}
+
+bool uw_macaroon_caveat_create_nonce_(const uint8_t* nonce,
+ size_t nonce_size,
+ uint8_t* buffer,
+ size_t buffer_size,
+ UwMacaroonCaveat* new_caveat) {
+ return create_caveat_bstr_value_(kUwMacaroonCaveatTypeNonce, nonce,
+ nonce_size, buffer, buffer_size, new_caveat);
+}
+
+bool uw_macaroon_caveat_create_scope_(UwMacaroonCaveatScopeType scope,
+ uint8_t* buffer,
+ size_t buffer_size,
+ UwMacaroonCaveat* new_caveat) {
+ if (!is_valid_scope_type_(scope)) {
return false;
}
- return create_caveat_(type, str, str_len, buffer, buffer_size, caveat);
+ return create_caveat_uint_value_(kUwMacaroonCaveatTypeScope, scope, buffer,
+ buffer_size, new_caveat);
+}
+
+bool uw_macaroon_caveat_create_expiration_absolute_(
+ uint32_t expiration_time,
+ uint8_t* buffer,
+ size_t buffer_size,
+ UwMacaroonCaveat* new_caveat) {
+ return create_caveat_uint_value_(kUwMacaroonCaveatTypeExpirationAbsolute,
+ expiration_time, buffer, buffer_size,
+ new_caveat);
+}
+
+bool uw_macaroon_caveat_create_ttl_1_hour_(uint8_t* buffer,
+ size_t buffer_size,
+ UwMacaroonCaveat* new_caveat) {
+ return create_caveat_no_value_(kUwMacaroonCaveatTypeTTL1Hour, buffer,
+ buffer_size, new_caveat);
+}
+
+bool uw_macaroon_caveat_create_ttl_24_hour_(uint8_t* buffer,
+ size_t buffer_size,
+ UwMacaroonCaveat* new_caveat) {
+ return create_caveat_no_value_(kUwMacaroonCaveatTypeTTL24Hour, buffer,
+ buffer_size, new_caveat);
+}
+
+bool uw_macaroon_caveat_create_delegation_timestamp_(
+ uint32_t timestamp,
+ uint8_t* buffer,
+ size_t buffer_size,
+ UwMacaroonCaveat* new_caveat) {
+ return create_caveat_uint_value_(kUwMacaroonCaveatTypeDelegationTimestamp,
+ timestamp, buffer, buffer_size, new_caveat);
+}
+
+bool 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) {
+ return create_caveat_bstr_value_(kUwMacaroonCaveatTypeDelegateeUser, id_str,
+ id_str_len, buffer, buffer_size, new_caveat);
+}
+
+bool 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) {
+ return create_caveat_bstr_value_(kUwMacaroonCaveatTypeDelegateeApp, id_str,
+ id_str_len, buffer, buffer_size, new_caveat);
+}
+
+bool uw_macaroon_caveat_create_app_commands_only_(
+ uint8_t* buffer,
+ size_t buffer_size,
+ UwMacaroonCaveat* new_caveat) {
+ return create_caveat_no_value_(kUwMacaroonCaveatTypeAppCommandsOnly, buffer,
+ buffer_size, new_caveat);
+}
+
+bool uw_macaroon_caveat_create_ble_session_id_(uint8_t* buffer,
+ size_t buffer_size,
+ UwMacaroonCaveat* new_caveat) {
+ return create_caveat_no_value_(kUwMacaroonCaveatTypeBleSessionID, buffer,
+ buffer_size, new_caveat);
+}
+
+bool 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) {
+ return create_caveat_bstr_value_(kUwMacaroonCaveatTypeLanSessionID,
+ session_id, session_id_len, buffer,
+ buffer_size, new_caveat);
+}
+
+bool 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) {
+ if (str_len == 0) {
+ return create_caveat_no_value_(
+ kUwMacaroonCaveatTypeClientAuthorizationTokenV1, buffer, buffer_size,
+ new_caveat);
+ }
+ return create_caveat_bstr_value_(
+ kUwMacaroonCaveatTypeClientAuthorizationTokenV1, str, str_len, buffer,
+ buffer_size, new_caveat);
+}
+
+bool 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) {
+ if (str_len == 0) {
+ return create_caveat_no_value_(
+ kUwMacaroonCaveatTypeServerAuthenticationTokenV1, buffer, buffer_size,
+ new_caveat);
+ }
+ return create_caveat_bstr_value_(
+ kUwMacaroonCaveatTypeServerAuthenticationTokenV1, str, str_len, buffer,
+ buffer_size, new_caveat);
}
bool uw_macaroon_caveat_get_type_(const UwMacaroonCaveat* caveat,
@@ -137,20 +299,208 @@ bool uw_macaroon_caveat_get_type_(const UwMacaroonCaveat* caveat,
}
*type = (UwMacaroonCaveatType)unsigned_int;
+ return is_valid_caveat_type_(*type);
+}
+
+/* === Some internal functions defined in macaroon_caveat_internal.h === */
- if (*type != kUwMacaroonCaveatTypeStop &&
- *type != kUwMacaroonCaveatTypeScope &&
- *type != kUwMacaroonCaveatTypeIdentifier &&
- *type != kUwMacaroonCaveatTypeIssued &&
- *type != kUwMacaroonCaveatTypeTTL &&
- *type != kUwMacaroonCaveatTypeExpiration &&
- *type != kUwMacaroonCaveatTypeSessionIdentifier) {
+bool 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) {
+ if (key == NULL || key_len == 0 || context == NULL || caveat == NULL ||
+ mac_tag == NULL || mac_tag_size == 0) {
+ return false;
+ }
+
+ UwMacaroonCaveatType caveat_type;
+ if (!uw_macaroon_caveat_get_type_(caveat, &caveat_type) ||
+ !is_valid_caveat_type_(caveat_type)) {
return false;
}
+ // Need to encode the whole caveat as a byte string and then sign it
+
+ // If there is no additional value from the context, just compute the HMAC on
+ // the current byte string.
+ uint8_t bstr_cbor_prefix[UW_MACAROON_ENCODING_MAX_UINT_CBOR_LEN] = {0};
+ size_t bstr_cbor_prefix_len = 0;
+ if (caveat_type != kUwMacaroonCaveatTypeBleSessionID) {
+ if (!uw_macaroon_encoding_encode_byte_str_len_(
+ (uint32_t)(caveat->num_bytes), bstr_cbor_prefix,
+ sizeof(bstr_cbor_prefix), &bstr_cbor_prefix_len)) {
+ return false;
+ }
+
+ UwCryptoHmacMsg messages[] = {
+ {bstr_cbor_prefix, bstr_cbor_prefix_len},
+ {caveat->bytes, caveat->num_bytes},
+ };
+
+ return uw_crypto_hmac_(key, key_len, messages,
+ sizeof(messages) / sizeof(messages[0]), mac_tag,
+ mac_tag_size);
+ }
+
+ // If there is additional value from the context.
+ if (context->ble_session_id == NULL || context->ble_session_id_len == 0) {
+ return false;
+ }
+
+ // The length here includes the length of the BLE session ID string.
+ if (!uw_macaroon_encoding_encode_byte_str_len_(
+ (uint32_t)(context->ble_session_id_len + caveat->num_bytes),
+ bstr_cbor_prefix, sizeof(bstr_cbor_prefix), &bstr_cbor_prefix_len)) {
+ return false;
+ }
+
+ uint8_t value_cbor_prefix[UW_MACAROON_ENCODING_MAX_UINT_CBOR_LEN] = {0};
+ size_t value_cbor_prefix_len = 0;
+ if (!uw_macaroon_encoding_encode_byte_str_len_(
+ (uint32_t)(context->ble_session_id_len), value_cbor_prefix,
+ sizeof(value_cbor_prefix), &value_cbor_prefix_len)) {
+ return false;
+ }
+
+ UwCryptoHmacMsg messages[] = {
+ {bstr_cbor_prefix, bstr_cbor_prefix_len},
+ {caveat->bytes, caveat->num_bytes},
+ {value_cbor_prefix, value_cbor_prefix_len},
+ {context->ble_session_id, context->ble_session_id_len},
+ };
+
+ return uw_crypto_hmac_(key, key_len, messages,
+ sizeof(messages) / sizeof(messages[0]), mac_tag,
+ mac_tag_size);
+}
+
+static bool update_and_check_expiration_time(
+ uint32_t current_time,
+ uint32_t new_expiration_time,
+ UwMacaroonValidationResult* result) {
+ if (result->expiration_time > new_expiration_time) {
+ result->expiration_time = new_expiration_time;
+ }
+
+ return current_time <= result->expiration_time;
+}
+
+static bool update_delegatee_list(UwMacaroonCaveatType caveat_type,
+ const UwMacaroonCaveat* caveat,
+ UwMacaroonValidationResult* result) {
+ if (result->num_delegatees >= MAX_NUM_DELEGATEES) {
+ return false;
+ }
+ bool is_app = (caveat_type == kUwMacaroonCaveatTypeDelegateeApp);
+
+ if (is_app) {
+ for (size_t i = 0; i < result->num_delegatees; i++) {
+ // There must have at most one DelegateeApp
+ if (result->delegatees[i].is_app) {
+ return false;
+ }
+ }
+ }
+
+ if (!uw_macaroon_caveat_get_value_bstr_(
+ caveat, &(result->delegatees[result->num_delegatees].id),
+ &(result->delegatees[result->num_delegatees].id_len))) {
+ return false;
+ }
+ result->delegatees[result->num_delegatees].is_app = is_app;
+ result->num_delegatees++;
return true;
}
+bool uw_macaroon_caveat_validate_(const UwMacaroonCaveat* caveat,
+ const UwMacaroonContext* context,
+ UwMacaroonValidationState* state,
+ UwMacaroonValidationResult* result) {
+ if (caveat == NULL || context == NULL || state == NULL || result == NULL) {
+ return false;
+ }
+
+ uint32_t expiration_time = 0;
+ uint32_t issued_time = 0;
+ uint32_t scope = UW_MACAROON_CAVEAT_SCOPE_LOWEST_POSSIBLE;
+
+ UwMacaroonCaveatType caveat_type;
+ if (!uw_macaroon_caveat_get_type_(caveat, &caveat_type)) {
+ return false;
+ }
+
+ switch (caveat_type) {
+ // The types that always validate
+ case kUwMacaroonCaveatTypeClientAuthorizationTokenV1:
+ case kUwMacaroonCaveatTypeServerAuthenticationTokenV1:
+ case kUwMacaroonCaveatTypeNonce:
+ case kUwMacaroonCaveatTypeBleSessionID:
+ return true;
+
+ case kUwMacaroonCaveatTypeDelegationTimestamp:
+ state->has_issued_time = true;
+ if (!uw_macaroon_caveat_get_value_uint_(caveat, &issued_time)) {
+ return false;
+ }
+ state->issued_time = issued_time;
+ return true;
+
+ case kUwMacaroonCaveatTypeTTL1Hour:
+ if (!(state->has_issued_time)) {
+ return false;
+ }
+ return update_and_check_expiration_time(
+ context->current_time, state->issued_time + 60 * 60, result);
+
+ case kUwMacaroonCaveatTypeTTL24Hour:
+ if (!(state->has_issued_time)) {
+ return false;
+ }
+ return update_and_check_expiration_time(
+ context->current_time, state->issued_time + 24 * 60 * 60, result);
+
+ // Need to create a list of delegatees
+ case kUwMacaroonCaveatTypeDelegateeUser:
+ return update_delegatee_list(caveat_type, caveat, result);
+
+ case kUwMacaroonCaveatTypeDelegateeApp:
+ return update_delegatee_list(caveat_type, caveat, result);
+
+ // Time related caveats
+ case kUwMacaroonCaveatTypeExpirationAbsolute:
+ if (!uw_macaroon_caveat_get_value_uint_(caveat, &expiration_time)) {
+ return false;
+ }
+ return update_and_check_expiration_time(context->current_time,
+ expiration_time, result);
+
+ // The caveats that update the values of the result object
+ case kUwMacaroonCaveatTypeScope:
+ if (!uw_macaroon_caveat_get_value_uint_(caveat, &scope) ||
+ // Larger value means less priviledge
+ scope < UW_MACAROON_CAVEAT_SCOPE_HIGHEST_POSSIBLE ||
+ scope > UW_MACAROON_CAVEAT_SCOPE_LOWEST_POSSIBLE) {
+ return false;
+ }
+ if (scope > (uint32_t)(result->granted_scope)) {
+ result->granted_scope = (UwMacaroonCaveatScopeType)scope;
+ }
+ return true;
+
+ case kUwMacaroonCaveatTypeAppCommandsOnly:
+ result->weave_app_restricted = true;
+ return true;
+
+ case kUwMacaroonCaveatTypeLanSessionID:
+ return uw_macaroon_caveat_get_value_bstr_(
+ caveat, &(result->lan_session_id), &(result->lan_session_id_len));
+ }
+
+ return false;
+}
+
bool uw_macaroon_caveat_get_value_uint_(const UwMacaroonCaveat* caveat,
uint32_t* unsigned_int) {
if (caveat == NULL || unsigned_int == NULL) {
@@ -162,13 +512,13 @@ bool uw_macaroon_caveat_get_value_uint_(const UwMacaroonCaveat* caveat,
return false;
}
if (type != kUwMacaroonCaveatTypeScope &&
- type != kUwMacaroonCaveatTypeIssued &&
- type != kUwMacaroonCaveatTypeTTL &&
- type != kUwMacaroonCaveatTypeExpiration) {
+ type != kUwMacaroonCaveatTypeExpirationAbsolute &&
+ type != kUwMacaroonCaveatTypeDelegationTimestamp) {
// Wrong type
return false;
}
+ // Skip the portion for CBOR type
size_t offset;
if (!uw_macaroon_encoding_get_item_len_(caveat->bytes, caveat->num_bytes,
&offset)) {
@@ -179,8 +529,9 @@ bool uw_macaroon_caveat_get_value_uint_(const UwMacaroonCaveat* caveat,
caveat->bytes + offset, caveat->num_bytes - offset, unsigned_int);
}
-bool uw_macaroon_caveat_get_value_str_(const UwMacaroonCaveat* caveat,
- const uint8_t** str, size_t* str_len) {
+bool uw_macaroon_caveat_get_value_bstr_(const UwMacaroonCaveat* caveat,
+ const uint8_t** str,
+ size_t* str_len) {
if (caveat == NULL || str == NULL || str_len == NULL) {
return false;
}
@@ -189,7 +540,12 @@ bool uw_macaroon_caveat_get_value_str_(const UwMacaroonCaveat* caveat,
if (!uw_macaroon_caveat_get_type_(caveat, &type)) {
return false;
}
- if (type != kUwMacaroonCaveatTypeIdentifier) {
+ if (type != kUwMacaroonCaveatTypeNonce &&
+ type != kUwMacaroonCaveatTypeDelegateeUser &&
+ type != kUwMacaroonCaveatTypeDelegateeApp &&
+ type != kUwMacaroonCaveatTypeLanSessionID &&
+ type != kUwMacaroonCaveatTypeClientAuthorizationTokenV1 &&
+ type != kUwMacaroonCaveatTypeServerAuthenticationTokenV1) {
// Wrong type
return false;
}
@@ -200,48 +556,17 @@ bool uw_macaroon_caveat_get_value_str_(const UwMacaroonCaveat* caveat,
return false;
}
- return uw_macaroon_encoding_decode_text_str_(
+ return uw_macaroon_encoding_decode_byte_str_(
caveat->bytes + offset, caveat->num_bytes - offset, str, str_len);
}
-bool uw_macaroon_caveat_sign_(const uint8_t* key, size_t key_len,
- const UwMacaroonCaveat* caveat, uint8_t* mac_tag,
- size_t mac_tag_size) {
- if (key == NULL || key_len == 0 || caveat == NULL || mac_tag == NULL ||
- mac_tag_size == 0) {
- return false;
- }
-
- uint8_t hmac_state_buffer[HMAC_STATE_BUFFER_SIZE];
- if (HMAC_STATE_BUFFER_SIZE < uw_crypto_hmac_required_buffer_size_()) {
+bool uw_macaroon_caveat_init_validation_state_(
+ UwMacaroonValidationState* state) {
+ if (state == NULL) {
return false;
}
- if (!uw_crypto_hmac_init_(hmac_state_buffer, HMAC_STATE_BUFFER_SIZE, key,
- key_len)) {
- return false;
- }
-
- if (!uw_crypto_hmac_update_(hmac_state_buffer, HMAC_STATE_BUFFER_SIZE,
- caveat->bytes, caveat->num_bytes)) {
- return false;
- }
-
- const uint8_t* context;
- size_t context_len;
- UwMacaroonCaveatType caveat_type;
-
- if ((!uw_macaroon_caveat_get_type_(caveat, &caveat_type)) ||
- (!uw_macaroon_context_get_(caveat_type, &context, &context_len))) {
- return false;
- }
- if (context != NULL && context_len != 0) {
- if (!uw_crypto_hmac_update_(hmac_state_buffer, HMAC_STATE_BUFFER_SIZE,
- context, context_len)) {
- return false;
- }
- }
-
- return uw_crypto_hmac_final_(hmac_state_buffer, HMAC_STATE_BUFFER_SIZE,
- mac_tag, mac_tag_size);
+ state->has_issued_time = false;
+ state->issued_time = 0;
+ return true;
}
diff --git a/third_party/libuweave/src/macaroon_caveat.h b/third_party/libuweave/src/macaroon_caveat.h
index 2e01742..9baf70d 100644
--- a/third_party/libuweave/src/macaroon_caveat.h
+++ b/third_party/libuweave/src/macaroon_caveat.h
@@ -15,15 +15,25 @@ typedef struct {
} UwMacaroonCaveat;
typedef enum {
- kUwMacaroonCaveatTypeStop = 0,
- kUwMacaroonCaveatTypeScope = 1,
- kUwMacaroonCaveatTypeIdentifier = 2,
- kUwMacaroonCaveatTypeIssued = 3,
- kUwMacaroonCaveatTypeTTL = 4,
- kUwMacaroonCaveatTypeExpiration = 5,
- kUwMacaroonCaveatTypeSessionIdentifier = 16,
+ kUwMacaroonCaveatTypeNonce = 0, // bstr
+ kUwMacaroonCaveatTypeScope = 1, // uint
+ kUwMacaroonCaveatTypeExpirationAbsolute = 5, // uint
+ kUwMacaroonCaveatTypeTTL1Hour = 6, // no value
+ kUwMacaroonCaveatTypeTTL24Hour = 7, // no value
+ kUwMacaroonCaveatTypeDelegationTimestamp = 8, // uint
+ kUwMacaroonCaveatTypeDelegateeUser = 9, // bstr
+ kUwMacaroonCaveatTypeDelegateeApp = 10, // bstr
+ kUwMacaroonCaveatTypeAppCommandsOnly = 11, // no value
+ kUwMacaroonCaveatTypeBleSessionID = 16, // no value
+ kUwMacaroonCaveatTypeLanSessionID = 17, // bstr
+ kUwMacaroonCaveatTypeClientAuthorizationTokenV1 = 8193, // bstr (0x2001)
+ kUwMacaroonCaveatTypeServerAuthenticationTokenV1 = 12289, // bstr (0x3001)
} UwMacaroonCaveatType;
+// For security sanity checks
+#define UW_MACAROON_CAVEAT_SCOPE_HIGHEST_POSSIBLE 0
+#define UW_MACAROON_CAVEAT_SCOPE_LOWEST_POSSIBLE 127
+
typedef enum {
kUwMacaroonCaveatScopeTypeOwner = 2,
kUwMacaroonCaveatScopeTypeManager = 8,
@@ -31,28 +41,75 @@ typedef enum {
kUwMacaroonCaveatScopeTypeViewer = 20,
} UwMacaroonCaveatScopeType;
-bool uw_macaroon_caveat_create_without_value_(UwMacaroonCaveatType type,
+/** Compute the buffer sizes that are enough for caveat creation functions. */
+size_t uw_macaroon_caveat_creation_get_buffsize_(UwMacaroonCaveatType type,
+ size_t str_len);
+
+// Caveat creation functions
+bool uw_macaroon_caveat_create_nonce_(const uint8_t* nonce,
+ size_t nonce_size,
+ uint8_t* buffer,
+ size_t buffer_size,
+ UwMacaroonCaveat* new_caveat);
+bool uw_macaroon_caveat_create_scope_(UwMacaroonCaveatScopeType scope,
+ uint8_t* buffer,
+ size_t buffer_size,
+ UwMacaroonCaveat* new_caveat);
+bool uw_macaroon_caveat_create_expiration_absolute_(
+ uint32_t expiration_time,
+ uint8_t* buffer,
+ size_t buffer_size,
+ UwMacaroonCaveat* new_caveat);
+bool uw_macaroon_caveat_create_ttl_1_hour_(uint8_t* buffer,
+ size_t buffer_size,
+ UwMacaroonCaveat* new_caveat);
+bool uw_macaroon_caveat_create_ttl_24_hour_(uint8_t* buffer,
+ size_t buffer_size,
+ UwMacaroonCaveat* new_caveat);
+bool uw_macaroon_caveat_create_delegation_timestamp_(
+ uint32_t timestamp,
+ uint8_t* buffer,
+ size_t buffer_size,
+ UwMacaroonCaveat* new_caveat);
+bool 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);
+bool 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);
-bool uw_macaroon_caveat_create_with_uint_(UwMacaroonCaveatType type,
- uint32_t value, uint8_t* buffer,
- size_t buffer_size,
- UwMacaroonCaveat* new_caveat);
-bool uw_macaroon_caveat_create_with_str_(UwMacaroonCaveatType type,
- const uint8_t* str, size_t str_len,
- uint8_t* buffer, size_t buffer_size,
- UwMacaroonCaveat* new_caveat);
+bool uw_macaroon_caveat_create_app_commands_only_(uint8_t* buffer,
+ size_t buffer_size,
+ UwMacaroonCaveat* new_caveat);
+bool uw_macaroon_caveat_create_ble_session_id_(uint8_t* buffer,
+ size_t buffer_size,
+ UwMacaroonCaveat* new_caveat);
+bool 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);
+
+// The string values for these two token types are optional.
+// Use str_len = 0 to indicate creating the caveats without string values.
+bool 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);
+bool 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);
+/** Get the type for the given caveat. */
bool uw_macaroon_caveat_get_type_(const UwMacaroonCaveat* caveat,
UwMacaroonCaveatType* type);
-bool uw_macaroon_caveat_get_value_uint_(const UwMacaroonCaveat* caveat,
- uint32_t* unsigned_int);
-bool uw_macaroon_caveat_get_value_str_(const UwMacaroonCaveat* caveat,
- const uint8_t** str, size_t* str_len);
-
-bool uw_macaroon_caveat_sign_(const uint8_t* key, size_t key_len,
- const UwMacaroonCaveat* caveat, uint8_t* mac_tag,
- size_t mac_tag_size);
#endif // LIBUWEAVE_SRC_MACAROON_CAVEAT_H_
diff --git a/third_party/libuweave/src/macaroon_caveat_internal.h b/third_party/libuweave/src/macaroon_caveat_internal.h
new file mode 100644
index 0000000..46a72fb
--- /dev/null
+++ b/third_party/libuweave/src/macaroon_caveat_internal.h
@@ -0,0 +1,41 @@
+// Copyright 2015 The Weave Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef LIBUWEAVE_SRC_MACAROON_CAVEAT_INTERNAL_H_
+#define LIBUWEAVE_SRC_MACAROON_CAVEAT_INTERNAL_H_
+
+#include <stdbool.h>
+#include <stddef.h>
+#include <stdint.h>
+
+#include "src/macaroon.h"
+#include "src/macaroon_caveat.h"
+
+bool 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);
+
+typedef struct {
+ bool has_issued_time;
+ uint32_t issued_time;
+} UwMacaroonValidationState;
+
+bool uw_macaroon_caveat_init_validation_state_(
+ UwMacaroonValidationState* state);
+
+bool uw_macaroon_caveat_validate_(const UwMacaroonCaveat* caveat,
+ const UwMacaroonContext* context,
+ UwMacaroonValidationState* state,
+ UwMacaroonValidationResult* result);
+
+bool uw_macaroon_caveat_get_value_uint_(const UwMacaroonCaveat* caveat,
+ uint32_t* unsigned_int);
+bool uw_macaroon_caveat_get_value_bstr_(const UwMacaroonCaveat* caveat,
+ const uint8_t** str,
+ size_t* str_len);
+
+#endif // LIBUWEAVE_SRC_MACAROON_CAVEAT_INTERNAL_H_
diff --git a/third_party/libuweave/src/macaroon_context.c b/third_party/libuweave/src/macaroon_context.c
index 7477784..2f1685d 100644
--- a/third_party/libuweave/src/macaroon_context.c
+++ b/third_party/libuweave/src/macaroon_context.c
@@ -4,19 +4,19 @@
#include "src/macaroon_context.h"
-#include "src/macaroon_caveat.h"
-
-bool uw_macaroon_context_get_(UwMacaroonCaveatType type,
- const uint8_t** context, size_t* context_len) {
- if (type != kUwMacaroonCaveatTypeSessionIdentifier) {
- *context = NULL;
- *context_len = 0;
+bool uw_macaroon_context_create_(uint32_t current_time,
+ const uint8_t* ble_session_id,
+ size_t ble_session_id_len,
+ UwMacaroonContext* new_context) {
+ if (ble_session_id == NULL && ble_session_id_len != 0) {
+ return false;
+ }
+ if (new_context == NULL) {
+ return false;
}
- // TODO(bozhu): Waiting for a proper way to obtain the session identifier.
- // Have we already implemented something related to session identifiers?
- *context = NULL;
- *context_len = 0;
-
+ new_context->current_time = current_time;
+ new_context->ble_session_id = ble_session_id;
+ new_context->ble_session_id_len = ble_session_id_len;
return true;
}
diff --git a/third_party/libuweave/src/macaroon_context.h b/third_party/libuweave/src/macaroon_context.h
index 8522b69..c230eb7 100644
--- a/third_party/libuweave/src/macaroon_context.h
+++ b/third_party/libuweave/src/macaroon_context.h
@@ -2,8 +2,8 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#ifndef UW_LIBUWEAVE_SRC_MACAROON_CONTEXT_
-#define UW_LIBUWEAVE_SRC_MACAROON_CONTEXT_
+#ifndef LIBUWEAVE_SRC_MACAROON_CONTEXT_
+#define LIBUWEAVE_SRC_MACAROON_CONTEXT_
#include <stdbool.h>
#include <stddef.h>
@@ -11,7 +11,15 @@
#include "src/macaroon_caveat.h"
-bool uw_macaroon_context_get_(UwMacaroonCaveatType type,
- const uint8_t** context, size_t* context_len);
+typedef struct {
+ uint32_t current_time; // In number of seconds since Jan 1st 2000 00:00:00
+ const uint8_t* ble_session_id; // Only for BLE
+ size_t ble_session_id_len;
+} UwMacaroonContext;
-#endif // UW_LIBUWEAVE_SRC_MACAROON_CONTEXT_
+bool uw_macaroon_context_create_(uint32_t current_time,
+ const uint8_t* ble_session_id,
+ size_t ble_session_id_len,
+ UwMacaroonContext* new_context);
+
+#endif // LIBUWEAVE_SRC_MACAROON_CONTEXT_
diff --git a/third_party/libuweave/src/macaroon_encoding.c b/third_party/libuweave/src/macaroon_encoding.c
index 3fb5323..29adc52 100644
--- a/third_party/libuweave/src/macaroon_encoding.c
+++ b/third_party/libuweave/src/macaroon_encoding.c
@@ -21,28 +21,34 @@ typedef enum {
kCborMajorTypeArray = 4 << 5, // type 4 -- arrays
} CborMajorType;
-// -- Prototypes begin --
static inline CborMajorType get_type_(const uint8_t* cbor);
static inline uint8_t get_addtl_data_(const uint8_t* cbor);
static inline void set_type_(CborMajorType type, uint8_t* cbor);
static inline void set_addtl_data_(uint8_t addtl_data, uint8_t* cbor);
-// Compute the minimum number of bytes to store the unsigned integer.
+/** Computes the minimum number of bytes to store the unsigned integer. */
static inline size_t uint_min_len_(uint32_t unsigned_int);
-// Encoding or decoding without checking types
-static bool blindly_encode_uint_(uint32_t unsigned_int, uint8_t* buffer,
- size_t buffer_size, size_t* result_len);
-static bool blindly_encode_str_(const uint8_t* str, size_t str_len,
- uint8_t* buffer, size_t buffer_size,
+/** Encoding or decoding without checking types */
+static bool blindly_encode_uint_(uint32_t unsigned_int,
+ uint8_t* buffer,
+ size_t buffer_size,
+ size_t* result_len);
+static bool blindly_encode_str_(const uint8_t* str,
+ size_t str_len,
+ uint8_t* buffer,
+ size_t buffer_size,
size_t* result_len);
-static bool blindly_decode_uint_(const uint8_t* cbor, size_t cbor_len,
+static bool blindly_decode_uint_(const uint8_t* cbor,
+ size_t cbor_len,
uint32_t* unsigned_int);
-static bool blindly_decode_str_(const uint8_t* cbor, size_t cbor_len,
- const uint8_t** out_str, size_t* out_str_len);
-// -- Prototypes end --
+static bool blindly_decode_str_(const uint8_t* cbor,
+ size_t cbor_len,
+ const uint8_t** out_str,
+ size_t* out_str_len);
-bool uw_macaroon_encoding_get_item_len_(const uint8_t* cbor, size_t cbor_len,
+bool uw_macaroon_encoding_get_item_len_(const uint8_t* cbor,
+ size_t cbor_len,
size_t* first_item_len) {
if (cbor == NULL || cbor_len == 0 || first_item_len == NULL) {
return false;
@@ -76,7 +82,8 @@ bool uw_macaroon_encoding_get_item_len_(const uint8_t* cbor, size_t cbor_len,
}
bool uw_macaroon_encoding_encode_uint_(const uint32_t unsigned_int,
- uint8_t* buffer, size_t buffer_size,
+ uint8_t* buffer,
+ size_t buffer_size,
size_t* resulting_cbor_len) {
if (buffer == NULL || buffer_size == 0 || resulting_cbor_len == NULL) {
return false;
@@ -88,7 +95,8 @@ bool uw_macaroon_encoding_encode_uint_(const uint32_t unsigned_int,
}
bool uw_macaroon_encoding_encode_array_len_(const uint32_t array_len,
- uint8_t* buffer, size_t buffer_size,
+ uint8_t* buffer,
+ size_t buffer_size,
size_t* resulting_cbor_len) {
if (buffer == NULL || buffer_size == 0 || resulting_cbor_len == NULL) {
return false;
@@ -99,8 +107,10 @@ bool uw_macaroon_encoding_encode_array_len_(const uint32_t array_len,
resulting_cbor_len);
}
-bool uw_macaroon_encoding_encode_byte_str_(const uint8_t* str, size_t str_len,
- uint8_t* buffer, size_t buffer_size,
+bool uw_macaroon_encoding_encode_byte_str_(const uint8_t* str,
+ size_t str_len,
+ uint8_t* buffer,
+ size_t buffer_size,
size_t* resulting_cbor_len) {
if (buffer == NULL || buffer_size == 0 || resulting_cbor_len == NULL) {
return false;
@@ -111,8 +121,10 @@ bool uw_macaroon_encoding_encode_byte_str_(const uint8_t* str, size_t str_len,
resulting_cbor_len);
}
-bool uw_macaroon_encoding_encode_text_str_(const uint8_t* str, size_t str_len,
- uint8_t* buffer, size_t buffer_size,
+bool uw_macaroon_encoding_encode_text_str_(const uint8_t* str,
+ size_t str_len,
+ uint8_t* buffer,
+ size_t buffer_size,
size_t* resulting_cbor_len) {
if (buffer == NULL || buffer_size == 0 || resulting_cbor_len == NULL) {
return false;
@@ -123,7 +135,19 @@ bool uw_macaroon_encoding_encode_text_str_(const uint8_t* str, size_t str_len,
resulting_cbor_len);
}
-bool uw_macaroon_encoding_decode_uint_(const uint8_t* cbor, size_t cbor_len,
+bool uw_macaroon_encoding_encode_byte_str_len_(size_t str_len,
+ uint8_t* buffer,
+ size_t buffer_size,
+ size_t* resulting_cbor_len) {
+ if (buffer == NULL || buffer_size == 0 || resulting_cbor_len == NULL) {
+ return false;
+ }
+ set_type_(kCborMajorTypeByteStr, buffer);
+ return blindly_encode_uint_(str_len, buffer, buffer_size, resulting_cbor_len);
+}
+
+bool uw_macaroon_encoding_decode_uint_(const uint8_t* cbor,
+ size_t cbor_len,
uint32_t* unsigned_int) {
if (cbor == NULL || cbor_len == 0 || unsigned_int == NULL ||
get_type_(cbor) != kCborMajorTypeUint) {
@@ -144,7 +168,8 @@ bool uw_macaroon_encoding_decode_array_len_(const uint8_t* cbor,
return blindly_decode_uint_(cbor, cbor_len, array_len);
}
-bool uw_macaroon_encoding_decode_byte_str_(const uint8_t* cbor, size_t cbor_len,
+bool uw_macaroon_encoding_decode_byte_str_(const uint8_t* cbor,
+ size_t cbor_len,
const uint8_t** out_str,
size_t* out_str_len) {
if (cbor == NULL || cbor_len == 0 || out_str == NULL || out_str_len == NULL ||
@@ -155,7 +180,8 @@ bool uw_macaroon_encoding_decode_byte_str_(const uint8_t* cbor, size_t cbor_len,
return blindly_decode_str_(cbor, cbor_len, out_str, out_str_len);
}
-bool uw_macaroon_encoding_decode_text_str_(const uint8_t* cbor, size_t cbor_len,
+bool uw_macaroon_encoding_decode_text_str_(const uint8_t* cbor,
+ size_t cbor_len,
const uint8_t** out_str,
size_t* out_str_len) {
if (cbor == NULL || cbor_len == 0 || out_str == NULL || out_str_len == NULL ||
@@ -193,9 +219,12 @@ static inline size_t uint_min_len_(uint32_t unsigned_int) {
return 4;
}
-// Write the unsigned int in the big-endian fashion by using the minimum number
-// of bytes in CBOR
-static inline bool write_uint_big_endian_(uint32_t unsigned_int, uint8_t* buff,
+/**
+ * Writes the unsigned int in the big-endian fashion by using the minimum number
+ * of bytes in CBOR
+ */
+static inline bool write_uint_big_endian_(uint32_t unsigned_int,
+ uint8_t* buff,
size_t buff_len) {
if (buff == NULL || buff_len == 0) {
return false;
@@ -225,8 +254,9 @@ static inline bool write_uint_big_endian_(uint32_t unsigned_int, uint8_t* buff,
return true;
}
-// Read the unsigned int written in big-endian
-static inline bool read_uint_big_endian_(const uint8_t* bytes, size_t num_bytes,
+/** Reads the unsigned int written in big-endian. */
+static inline bool read_uint_big_endian_(const uint8_t* bytes,
+ size_t num_bytes,
uint32_t* unsigned_int) {
if (bytes == NULL || num_bytes == 0 || num_bytes > 4 ||
unsigned_int == NULL) {
@@ -252,8 +282,10 @@ static inline bool read_uint_big_endian_(const uint8_t* bytes, size_t num_bytes,
return true;
}
-static bool blindly_encode_uint_(uint32_t unsigned_int, uint8_t* buffer,
- size_t buffer_size, size_t* result_len) {
+static bool blindly_encode_uint_(uint32_t unsigned_int,
+ uint8_t* buffer,
+ size_t buffer_size,
+ size_t* result_len) {
if (buffer == NULL || buffer_size == 0 || result_len == NULL) {
return false;
}
@@ -288,8 +320,10 @@ static bool blindly_encode_uint_(uint32_t unsigned_int, uint8_t* buffer,
return write_uint_big_endian_(unsigned_int, buffer + 1, buffer_size - 1);
}
-static bool blindly_encode_str_(const uint8_t* str, size_t str_len,
- uint8_t* buffer, size_t buffer_size,
+static bool blindly_encode_str_(const uint8_t* str,
+ size_t str_len,
+ uint8_t* buffer,
+ size_t buffer_size,
size_t* result_len) {
if (buffer == NULL || buffer_size == 0) {
return false;
@@ -320,7 +354,8 @@ static bool blindly_encode_str_(const uint8_t* str, size_t str_len,
return true;
}
-static bool blindly_decode_uint_(const uint8_t* cbor, size_t cbor_len,
+static bool blindly_decode_uint_(const uint8_t* cbor,
+ size_t cbor_len,
uint32_t* unsigned_int) {
if (cbor == NULL || cbor_len == 0 || unsigned_int == NULL) {
return false;
@@ -344,8 +379,10 @@ static bool blindly_decode_uint_(const uint8_t* cbor, size_t cbor_len,
return read_uint_big_endian_(cbor + 1, uint_num_bytes, unsigned_int);
}
-static bool blindly_decode_str_(const uint8_t* cbor, size_t cbor_len,
- const uint8_t** out_str, size_t* out_str_len) {
+static bool blindly_decode_str_(const uint8_t* cbor,
+ size_t cbor_len,
+ const uint8_t** out_str,
+ size_t* out_str_len) {
if (cbor == NULL || cbor_len == 0 || out_str == NULL || out_str == NULL) {
return false;
}
diff --git a/third_party/libuweave/src/macaroon_encoding.h b/third_party/libuweave/src/macaroon_encoding.h
index edddfc1..60f80a6 100644
--- a/third_party/libuweave/src/macaroon_encoding.h
+++ b/third_party/libuweave/src/macaroon_encoding.h
@@ -17,32 +17,53 @@
#include <stddef.h>
#include <stdint.h>
-// Get the number of bytes that is occupied by the first data item in the give
-// CBOR string.
-bool uw_macaroon_encoding_get_item_len_(const uint8_t* cbor, size_t cbor_len,
+#define UW_MACAROON_ENCODING_MAX_UINT_CBOR_LEN 5
+
+/**
+ * Gets the number of bytes that is occupied by the first data item in the give
+ * CBOR string.
+ */
+bool uw_macaroon_encoding_get_item_len_(const uint8_t* cbor,
+ size_t cbor_len,
size_t* first_item_len);
bool uw_macaroon_encoding_encode_uint_(const uint32_t unsigned_int,
- uint8_t* buffer, size_t buffer_size,
+ uint8_t* buffer,
+ size_t buffer_size,
size_t* resulting_cbor_len);
bool uw_macaroon_encoding_encode_array_len_(const uint32_t array_len,
- uint8_t* buffer, size_t buffer_size,
+ uint8_t* buffer,
+ size_t buffer_size,
size_t* resulting_cbor_len);
-bool uw_macaroon_encoding_encode_byte_str_(const uint8_t* str, size_t str_len,
- uint8_t* buffer, size_t buffer_size,
+bool uw_macaroon_encoding_encode_byte_str_(const uint8_t* str,
+ size_t str_len,
+ uint8_t* buffer,
+ size_t buffer_size,
size_t* resulting_cbor_len);
-bool uw_macaroon_encoding_encode_text_str_(const uint8_t* str, size_t str_len,
- uint8_t* buffer, size_t buffer_size,
+bool uw_macaroon_encoding_encode_text_str_(const uint8_t* str,
+ size_t str_len,
+ uint8_t* buffer,
+ size_t buffer_size,
size_t* resulting_cbor_len);
-bool uw_macaroon_encoding_decode_uint_(const uint8_t* cbor, size_t cbor_len,
+/** Only encode the header (major type and length) of the byte string */
+bool uw_macaroon_encoding_encode_byte_str_len_(size_t str_len,
+ uint8_t* buffer,
+ size_t buffer_size,
+ size_t* resulting_cbor_len);
+
+bool uw_macaroon_encoding_decode_uint_(const uint8_t* cbor,
+ size_t cbor_len,
uint32_t* unsigned_int);
bool uw_macaroon_encoding_decode_array_len_(const uint8_t* cbor,
- size_t cbor_len, uint32_t* array_len);
-bool uw_macaroon_encoding_decode_byte_str_(const uint8_t* cbor, size_t cbor_len,
+ size_t cbor_len,
+ uint32_t* array_len);
+bool uw_macaroon_encoding_decode_byte_str_(const uint8_t* cbor,
+ size_t cbor_len,
const uint8_t** str,
size_t* str_len);
-bool uw_macaroon_encoding_decode_text_str_(const uint8_t* cbor, size_t cbor_len,
+bool uw_macaroon_encoding_decode_text_str_(const uint8_t* cbor,
+ size_t cbor_len,
const uint8_t** str,
size_t* str_len);