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