]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/libfido2/src/blob.c
zfs: merge openzfs/zfs@9198de8f1
[FreeBSD/FreeBSD.git] / contrib / libfido2 / src / blob.c
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 }