1 /* 2 * Copyright (c) 2018 Yubico AB. All rights reserved. 3 * Use of this source code is governed by a BSD-style 4 * license that can be found in the LICENSE file. 5 */ 6 7 #include "fido.h" 8 9 fido_blob_t * 10 fido_blob_new(void) 11 { 12 return calloc(1, sizeof(fido_blob_t)); 13 } 14 15 void 16 fido_blob_reset(fido_blob_t *b) 17 { 18 freezero(b->ptr, b->len); 19 explicit_bzero(b, sizeof(*b)); 20 } 21 22 int 23 fido_blob_set(fido_blob_t *b, const u_char *ptr, size_t len) 24 { 25 fido_blob_reset(b); 26 27 if (ptr == NULL || len == 0) { 28 fido_log_debug("%s: ptr=%p, len=%zu", __func__, 29 (const void *)ptr, len); 30 return -1; 31 } 32 33 if ((b->ptr = malloc(len)) == NULL) { 34 fido_log_debug("%s: malloc", __func__); 35 return -1; 36 } 37 38 memcpy(b->ptr, ptr, len); 39 b->len = len; 40 41 return 0; 42 } 43 44 int 45 fido_blob_append(fido_blob_t *b, const u_char *ptr, size_t len) 46 { 47 u_char *tmp; 48 49 if (ptr == NULL || len == 0) { 50 fido_log_debug("%s: ptr=%p, len=%zu", __func__, 51 (const void *)ptr, len); 52 return -1; 53 } 54 if (SIZE_MAX - b->len < len) { 55 fido_log_debug("%s: overflow", __func__); 56 return -1; 57 } 58 if ((tmp = realloc(b->ptr, b->len + len)) == NULL) { 59 fido_log_debug("%s: realloc", __func__); 60 return -1; 61 } 62 b->ptr = tmp; 63 memcpy(&b->ptr[b->len], ptr, len); 64 b->len += len; 65 66 return 0; 67 } 68 69 void 70 fido_blob_free(fido_blob_t **bp) 71 { 72 fido_blob_t *b; 73 74 if (bp == NULL || (b = *bp) == NULL) 75 return; 76 77 fido_blob_reset(b); 78 free(b); 79 *bp = NULL; 80 } 81 82 void 83 fido_free_blob_array(fido_blob_array_t *array) 84 { 85 if (array->ptr == NULL) 86 return; 87 88 for (size_t i = 0; i < array->len; i++) { 89 fido_blob_t *b = &array->ptr[i]; 90 freezero(b->ptr, b->len); 91 b->ptr = NULL; 92 } 93 94 free(array->ptr); 95 array->ptr = NULL; 96 array->len = 0; 97 } 98 99 cbor_item_t * 100 fido_blob_encode(const fido_blob_t *b) 101 { 102 if (b == NULL || b->ptr == NULL) 103 return NULL; 104 105 return cbor_build_bytestring(b->ptr, b->len); 106 } 107 108 int 109 fido_blob_decode(const cbor_item_t *item, fido_blob_t *b) 110 { 111 return cbor_bytestring_copy(item, &b->ptr, &b->len); 112 } 113 114 int 115 fido_blob_is_empty(const fido_blob_t *b) 116 { 117 return b->ptr == NULL || b->len == 0; 118 } 119 120 int 121 fido_blob_serialise(fido_blob_t *b, const cbor_item_t *item) 122 { 123 size_t alloc; 124 125 if (!fido_blob_is_empty(b)) 126 return -1; 127 if ((b->len = cbor_serialize_alloc(item, &b->ptr, &alloc)) == 0) { 128 b->ptr = NULL; 129 return -1; 130 } 131 132 return 0; 133 } 134