Home | History | Annotate | Line # | Download | only in src
      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