xref: /openbsd-src/lib/libfido2/src/blob.c (revision 99fd087599a8791921855f21bd7e36130f39aadc)
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 <string.h>
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 int
17 fido_blob_set(fido_blob_t *b, const unsigned char *ptr, size_t len)
18 {
19 	if (b->ptr != NULL) {
20 		explicit_bzero(b->ptr, b->len);
21 		free(b->ptr);
22 		b->ptr = NULL;
23 	}
24 
25 	b->len = 0;
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 void
45 fido_blob_free(fido_blob_t **bp)
46 {
47 	fido_blob_t *b;
48 
49 	if (bp == NULL || (b = *bp) == NULL)
50 		return;
51 
52 	if (b->ptr) {
53 		explicit_bzero(b->ptr, b->len);
54 		free(b->ptr);
55 	}
56 
57 	explicit_bzero(b, sizeof(*b));
58 	free(b);
59 
60 	*bp = NULL;
61 }
62 
63 void
64 fido_free_blob_array(fido_blob_array_t *array)
65 {
66 	if (array->ptr == NULL)
67 		return;
68 
69 	for (size_t i = 0; i < array->len; i++) {
70 		fido_blob_t *b = &array->ptr[i];
71 		if (b->ptr != NULL) {
72 			explicit_bzero(b->ptr, b->len);
73 			free(b->ptr);
74 			b->ptr = NULL;
75 		}
76 	}
77 
78 	free(array->ptr);
79 	array->ptr = NULL;
80 	array->len = 0;
81 }
82 
83 cbor_item_t *
84 fido_blob_encode(const fido_blob_t *b)
85 {
86 	if (b == NULL || b->ptr == NULL)
87 		return (NULL);
88 
89 	return (cbor_build_bytestring(b->ptr, b->len));
90 }
91 
92 int
93 fido_blob_decode(const cbor_item_t *item, fido_blob_t *b)
94 {
95 	return (cbor_bytestring_copy(item, &b->ptr, &b->len));
96 }
97 
98 int
99 fido_blob_is_empty(const fido_blob_t *b)
100 {
101 	return (b->ptr == NULL || b->len == 0);
102 }
103