Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/contrib/libfido2/examples/util.c
39536 views
1
/*
2
* Copyright (c) 2018-2022 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 <sys/types.h>
9
#include <sys/stat.h>
10
11
#include <openssl/ec.h>
12
#include <openssl/evp.h>
13
#include <openssl/pem.h>
14
15
#include <fido.h>
16
#include <fido/es256.h>
17
#include <fido/es384.h>
18
#include <fido/rs256.h>
19
#include <fido/eddsa.h>
20
21
#include <errno.h>
22
#include <fcntl.h>
23
#include <limits.h>
24
#include <stdlib.h>
25
#include <string.h>
26
#ifdef HAVE_UNISTD_H
27
#include <unistd.h>
28
#endif
29
#ifdef _MSC_VER
30
#include "../openbsd-compat/posix_win.h"
31
#endif
32
#include "../openbsd-compat/openbsd-compat.h"
33
#include "extern.h"
34
35
int
36
base10(const char *str, long long *ll)
37
{
38
char *ep;
39
40
*ll = strtoll(str, &ep, 10);
41
if (str == ep || *ep != '\0')
42
return (-1);
43
else if (*ll == LLONG_MIN && errno == ERANGE)
44
return (-1);
45
else if (*ll == LLONG_MAX && errno == ERANGE)
46
return (-1);
47
48
return (0);
49
}
50
51
int
52
write_blob(const char *path, const unsigned char *ptr, size_t len)
53
{
54
int fd, ok = -1;
55
ssize_t n;
56
57
if ((fd = open(path, O_WRONLY | O_CREAT, 0600)) < 0) {
58
warn("open %s", path);
59
goto fail;
60
}
61
62
if ((n = write(fd, ptr, len)) < 0) {
63
warn("write");
64
goto fail;
65
}
66
if ((size_t)n != len) {
67
warnx("write");
68
goto fail;
69
}
70
71
ok = 0;
72
fail:
73
if (fd != -1) {
74
close(fd);
75
}
76
77
return (ok);
78
}
79
80
int
81
read_blob(const char *path, unsigned char **ptr, size_t *len)
82
{
83
int fd, ok = -1;
84
struct stat st;
85
ssize_t n;
86
87
*ptr = NULL;
88
*len = 0;
89
90
if ((fd = open(path, O_RDONLY)) < 0) {
91
warn("open %s", path);
92
goto fail;
93
}
94
if (fstat(fd, &st) < 0) {
95
warn("stat %s", path);
96
goto fail;
97
}
98
if (st.st_size < 0) {
99
warnx("stat %s: invalid size", path);
100
goto fail;
101
}
102
*len = (size_t)st.st_size;
103
if ((*ptr = malloc(*len)) == NULL) {
104
warn("malloc");
105
goto fail;
106
}
107
if ((n = read(fd, *ptr, *len)) < 0) {
108
warn("read");
109
goto fail;
110
}
111
if ((size_t)n != *len) {
112
warnx("read");
113
goto fail;
114
}
115
116
ok = 0;
117
fail:
118
if (fd != -1) {
119
close(fd);
120
}
121
if (ok < 0) {
122
free(*ptr);
123
*ptr = NULL;
124
*len = 0;
125
}
126
127
return (ok);
128
}
129
130
EC_KEY *
131
read_ec_pubkey(const char *path)
132
{
133
FILE *fp = NULL;
134
EVP_PKEY *pkey = NULL;
135
EC_KEY *ec = NULL;
136
137
if ((fp = fopen(path, "r")) == NULL) {
138
warn("fopen");
139
goto fail;
140
}
141
142
if ((pkey = PEM_read_PUBKEY(fp, NULL, NULL, NULL)) == NULL) {
143
warnx("PEM_read_PUBKEY");
144
goto fail;
145
}
146
if ((ec = EVP_PKEY_get1_EC_KEY(pkey)) == NULL) {
147
warnx("EVP_PKEY_get1_EC_KEY");
148
goto fail;
149
}
150
151
fail:
152
if (fp != NULL) {
153
fclose(fp);
154
}
155
if (pkey != NULL) {
156
EVP_PKEY_free(pkey);
157
}
158
159
return (ec);
160
}
161
162
int
163
write_es256_pubkey(const char *path, const void *ptr, size_t len)
164
{
165
FILE *fp = NULL;
166
EVP_PKEY *pkey = NULL;
167
es256_pk_t *pk = NULL;
168
int fd = -1;
169
int ok = -1;
170
171
if ((pk = es256_pk_new()) == NULL) {
172
warnx("es256_pk_new");
173
goto fail;
174
}
175
176
if (es256_pk_from_ptr(pk, ptr, len) != FIDO_OK) {
177
warnx("es256_pk_from_ptr");
178
goto fail;
179
}
180
181
if ((fd = open(path, O_WRONLY | O_CREAT, 0644)) < 0) {
182
warn("open %s", path);
183
goto fail;
184
}
185
186
if ((fp = fdopen(fd, "w")) == NULL) {
187
warn("fdopen");
188
goto fail;
189
}
190
fd = -1; /* owned by fp now */
191
192
if ((pkey = es256_pk_to_EVP_PKEY(pk)) == NULL) {
193
warnx("es256_pk_to_EVP_PKEY");
194
goto fail;
195
}
196
197
if (PEM_write_PUBKEY(fp, pkey) == 0) {
198
warnx("PEM_write_PUBKEY");
199
goto fail;
200
}
201
202
ok = 0;
203
fail:
204
es256_pk_free(&pk);
205
206
if (fp != NULL) {
207
fclose(fp);
208
}
209
if (fd != -1) {
210
close(fd);
211
}
212
if (pkey != NULL) {
213
EVP_PKEY_free(pkey);
214
}
215
216
return (ok);
217
}
218
219
int
220
write_es384_pubkey(const char *path, const void *ptr, size_t len)
221
{
222
FILE *fp = NULL;
223
EVP_PKEY *pkey = NULL;
224
es384_pk_t *pk = NULL;
225
int fd = -1;
226
int ok = -1;
227
228
if ((pk = es384_pk_new()) == NULL) {
229
warnx("es384_pk_new");
230
goto fail;
231
}
232
233
if (es384_pk_from_ptr(pk, ptr, len) != FIDO_OK) {
234
warnx("es384_pk_from_ptr");
235
goto fail;
236
}
237
238
if ((fd = open(path, O_WRONLY | O_CREAT, 0644)) < 0) {
239
warn("open %s", path);
240
goto fail;
241
}
242
243
if ((fp = fdopen(fd, "w")) == NULL) {
244
warn("fdopen");
245
goto fail;
246
}
247
fd = -1; /* owned by fp now */
248
249
if ((pkey = es384_pk_to_EVP_PKEY(pk)) == NULL) {
250
warnx("es384_pk_to_EVP_PKEY");
251
goto fail;
252
}
253
254
if (PEM_write_PUBKEY(fp, pkey) == 0) {
255
warnx("PEM_write_PUBKEY");
256
goto fail;
257
}
258
259
ok = 0;
260
fail:
261
es384_pk_free(&pk);
262
263
if (fp != NULL) {
264
fclose(fp);
265
}
266
if (fd != -1) {
267
close(fd);
268
}
269
if (pkey != NULL) {
270
EVP_PKEY_free(pkey);
271
}
272
273
return (ok);
274
}
275
276
RSA *
277
read_rsa_pubkey(const char *path)
278
{
279
FILE *fp = NULL;
280
EVP_PKEY *pkey = NULL;
281
RSA *rsa = NULL;
282
283
if ((fp = fopen(path, "r")) == NULL) {
284
warn("fopen");
285
goto fail;
286
}
287
288
if ((pkey = PEM_read_PUBKEY(fp, NULL, NULL, NULL)) == NULL) {
289
warnx("PEM_read_PUBKEY");
290
goto fail;
291
}
292
if ((rsa = EVP_PKEY_get1_RSA(pkey)) == NULL) {
293
warnx("EVP_PKEY_get1_RSA");
294
goto fail;
295
}
296
297
fail:
298
if (fp != NULL) {
299
fclose(fp);
300
}
301
if (pkey != NULL) {
302
EVP_PKEY_free(pkey);
303
}
304
305
return (rsa);
306
}
307
308
int
309
write_rs256_pubkey(const char *path, const void *ptr, size_t len)
310
{
311
FILE *fp = NULL;
312
EVP_PKEY *pkey = NULL;
313
rs256_pk_t *pk = NULL;
314
int fd = -1;
315
int ok = -1;
316
317
if ((pk = rs256_pk_new()) == NULL) {
318
warnx("rs256_pk_new");
319
goto fail;
320
}
321
322
if (rs256_pk_from_ptr(pk, ptr, len) != FIDO_OK) {
323
warnx("rs256_pk_from_ptr");
324
goto fail;
325
}
326
327
if ((fd = open(path, O_WRONLY | O_CREAT, 0644)) < 0) {
328
warn("open %s", path);
329
goto fail;
330
}
331
332
if ((fp = fdopen(fd, "w")) == NULL) {
333
warn("fdopen");
334
goto fail;
335
}
336
fd = -1; /* owned by fp now */
337
338
if ((pkey = rs256_pk_to_EVP_PKEY(pk)) == NULL) {
339
warnx("rs256_pk_to_EVP_PKEY");
340
goto fail;
341
}
342
343
if (PEM_write_PUBKEY(fp, pkey) == 0) {
344
warnx("PEM_write_PUBKEY");
345
goto fail;
346
}
347
348
ok = 0;
349
fail:
350
rs256_pk_free(&pk);
351
352
if (fp != NULL) {
353
fclose(fp);
354
}
355
if (fd != -1) {
356
close(fd);
357
}
358
if (pkey != NULL) {
359
EVP_PKEY_free(pkey);
360
}
361
362
return (ok);
363
}
364
365
EVP_PKEY *
366
read_eddsa_pubkey(const char *path)
367
{
368
FILE *fp = NULL;
369
EVP_PKEY *pkey = NULL;
370
371
if ((fp = fopen(path, "r")) == NULL) {
372
warn("fopen");
373
goto fail;
374
}
375
376
if ((pkey = PEM_read_PUBKEY(fp, NULL, NULL, NULL)) == NULL) {
377
warnx("PEM_read_PUBKEY");
378
goto fail;
379
}
380
381
fail:
382
if (fp) {
383
fclose(fp);
384
}
385
386
return (pkey);
387
}
388
389
int
390
write_eddsa_pubkey(const char *path, const void *ptr, size_t len)
391
{
392
FILE *fp = NULL;
393
EVP_PKEY *pkey = NULL;
394
eddsa_pk_t *pk = NULL;
395
int fd = -1;
396
int ok = -1;
397
398
if ((pk = eddsa_pk_new()) == NULL) {
399
warnx("eddsa_pk_new");
400
goto fail;
401
}
402
403
if (eddsa_pk_from_ptr(pk, ptr, len) != FIDO_OK) {
404
warnx("eddsa_pk_from_ptr");
405
goto fail;
406
}
407
408
if ((fd = open(path, O_WRONLY | O_CREAT, 0644)) < 0) {
409
warn("open %s", path);
410
goto fail;
411
}
412
413
if ((fp = fdopen(fd, "w")) == NULL) {
414
warn("fdopen");
415
goto fail;
416
}
417
fd = -1; /* owned by fp now */
418
419
if ((pkey = eddsa_pk_to_EVP_PKEY(pk)) == NULL) {
420
warnx("eddsa_pk_to_EVP_PKEY");
421
goto fail;
422
}
423
424
if (PEM_write_PUBKEY(fp, pkey) == 0) {
425
warnx("PEM_write_PUBKEY");
426
goto fail;
427
}
428
429
ok = 0;
430
fail:
431
eddsa_pk_free(&pk);
432
433
if (fp != NULL) {
434
fclose(fp);
435
}
436
if (fd != -1) {
437
close(fd);
438
}
439
if (pkey != NULL) {
440
EVP_PKEY_free(pkey);
441
}
442
443
return (ok);
444
}
445
446