blob.c revision 1.3
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 9fido_blob_t * 10fido_blob_new(void) 11{ 12 return calloc(1, sizeof(fido_blob_t)); 13} 14 15void 16fido_blob_reset(fido_blob_t *b) 17{ 18 freezero(b->ptr, b->len); 19 explicit_bzero(b, sizeof(*b)); 20} 21 22int 23fido_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 44int 45fido_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 69void 70fido_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 82void 83fido_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 99cbor_item_t * 100fido_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 108int 109fido_blob_decode(const cbor_item_t *item, fido_blob_t *b) 110{ 111 return cbor_bytestring_copy(item, &b->ptr, &b->len); 112} 113 114int 115fido_blob_is_empty(const fido_blob_t *b) 116{ 117 return b->ptr == NULL || b->len == 0; 118} 119 120int 121fido_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