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