diff options
Diffstat (limited to 'tools/cred_verify.c')
-rw-r--r-- | tools/cred_verify.c | 177 |
1 files changed, 177 insertions, 0 deletions
diff --git a/tools/cred_verify.c b/tools/cred_verify.c new file mode 100644 index 0000000..3f7a400 --- /dev/null +++ b/tools/cred_verify.c | |||
@@ -0,0 +1,177 @@ | |||
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 <fido.h> | ||
8 | #include <stdio.h> | ||
9 | #include <stdlib.h> | ||
10 | #include <string.h> | ||
11 | #ifdef HAVE_UNISTD_H | ||
12 | #include <unistd.h> | ||
13 | #endif | ||
14 | |||
15 | #include "../openbsd-compat/openbsd-compat.h" | ||
16 | #include "extern.h" | ||
17 | |||
18 | static fido_cred_t * | ||
19 | prepare_cred(FILE *in_f, int type, int flags) | ||
20 | { | ||
21 | fido_cred_t *cred = NULL; | ||
22 | struct blob cdh; | ||
23 | struct blob authdata; | ||
24 | struct blob id; | ||
25 | struct blob sig; | ||
26 | struct blob x5c; | ||
27 | char *rpid = NULL; | ||
28 | char *fmt = NULL; | ||
29 | int r; | ||
30 | |||
31 | memset(&cdh, 0, sizeof(cdh)); | ||
32 | memset(&authdata, 0, sizeof(authdata)); | ||
33 | memset(&id, 0, sizeof(id)); | ||
34 | memset(&sig, 0, sizeof(sig)); | ||
35 | memset(&x5c, 0, sizeof(x5c)); | ||
36 | |||
37 | r = base64_read(in_f, &cdh); | ||
38 | r |= string_read(in_f, &rpid); | ||
39 | r |= string_read(in_f, &fmt); | ||
40 | r |= base64_read(in_f, &authdata); | ||
41 | r |= base64_read(in_f, &id); | ||
42 | r |= base64_read(in_f, &sig); | ||
43 | if (r < 0) | ||
44 | errx(1, "input error"); | ||
45 | |||
46 | (void)base64_read(in_f, &x5c); | ||
47 | |||
48 | if (flags & FLAG_DEBUG) { | ||
49 | fprintf(stderr, "client data hash:\n"); | ||
50 | xxd(cdh.ptr, cdh.len); | ||
51 | fprintf(stderr, "relying party id: %s\n", rpid); | ||
52 | fprintf(stderr, "format: %s\n", fmt); | ||
53 | fprintf(stderr, "authenticator data:\n"); | ||
54 | xxd(authdata.ptr, authdata.len); | ||
55 | fprintf(stderr, "credential id:\n"); | ||
56 | xxd(id.ptr, id.len); | ||
57 | fprintf(stderr, "signature:\n"); | ||
58 | xxd(sig.ptr, sig.len); | ||
59 | fprintf(stderr, "x509:\n"); | ||
60 | xxd(x5c.ptr, x5c.len); | ||
61 | } | ||
62 | |||
63 | if ((cred = fido_cred_new()) == NULL) | ||
64 | errx(1, "fido_cred_new"); | ||
65 | |||
66 | if ((r = fido_cred_set_type(cred, type)) != FIDO_OK || | ||
67 | (r = fido_cred_set_clientdata_hash(cred, cdh.ptr, | ||
68 | cdh.len)) != FIDO_OK || | ||
69 | (r = fido_cred_set_rp(cred, rpid, NULL)) != FIDO_OK || | ||
70 | (r = fido_cred_set_authdata(cred, authdata.ptr, | ||
71 | authdata.len)) != FIDO_OK || | ||
72 | (r = fido_cred_set_sig(cred, sig.ptr, sig.len)) != FIDO_OK || | ||
73 | (r = fido_cred_set_fmt(cred, fmt)) != FIDO_OK) | ||
74 | errx(1, "fido_cred_set: %s", fido_strerr(r)); | ||
75 | |||
76 | if (x5c.ptr != NULL) { | ||
77 | if ((r = fido_cred_set_x509(cred, x5c.ptr, x5c.len)) != FIDO_OK) | ||
78 | errx(1, "fido_cred_set_x509: %s", fido_strerr(r)); | ||
79 | } | ||
80 | |||
81 | if (flags & FLAG_UV) { | ||
82 | if ((r = fido_cred_set_uv(cred, FIDO_OPT_TRUE)) != FIDO_OK) | ||
83 | errx(1, "fido_cred_set_uv: %s", fido_strerr(r)); | ||
84 | } | ||
85 | if (flags & FLAG_HMAC) { | ||
86 | if ((r = fido_cred_set_extensions(cred, | ||
87 | FIDO_EXT_HMAC_SECRET)) != FIDO_OK) | ||
88 | errx(1, "fido_cred_set_extensions: %s", fido_strerr(r)); | ||
89 | } | ||
90 | |||
91 | free(cdh.ptr); | ||
92 | free(authdata.ptr); | ||
93 | free(id.ptr); | ||
94 | free(sig.ptr); | ||
95 | free(x5c.ptr); | ||
96 | free(rpid); | ||
97 | free(fmt); | ||
98 | |||
99 | return (cred); | ||
100 | } | ||
101 | |||
102 | int | ||
103 | cred_verify(int argc, char **argv) | ||
104 | { | ||
105 | fido_cred_t *cred = NULL; | ||
106 | char *in_path = NULL; | ||
107 | char *out_path = NULL; | ||
108 | FILE *in_f = NULL; | ||
109 | FILE *out_f = NULL; | ||
110 | int type = COSE_ES256; | ||
111 | int flags = 0; | ||
112 | int ch; | ||
113 | int r; | ||
114 | |||
115 | while ((ch = getopt(argc, argv, "dhi:o:v")) != -1) { | ||
116 | switch (ch) { | ||
117 | case 'd': | ||
118 | flags |= FLAG_DEBUG; | ||
119 | break; | ||
120 | case 'h': | ||
121 | flags |= FLAG_HMAC; | ||
122 | break; | ||
123 | case 'i': | ||
124 | in_path = optarg; | ||
125 | break; | ||
126 | case 'o': | ||
127 | out_path = optarg; | ||
128 | break; | ||
129 | case 'v': | ||
130 | flags |= FLAG_UV; | ||
131 | break; | ||
132 | default: | ||
133 | usage(); | ||
134 | } | ||
135 | } | ||
136 | |||
137 | argc -= optind; | ||
138 | argv += optind; | ||
139 | |||
140 | if (argc > 1) | ||
141 | usage(); | ||
142 | |||
143 | in_f = open_read(in_path); | ||
144 | out_f = open_write(out_path); | ||
145 | |||
146 | if (argc > 0) { | ||
147 | if (strcmp(argv[0], "es256") == 0) | ||
148 | type = COSE_ES256; | ||
149 | else if (strcmp(argv[0], "rs256") == 0) | ||
150 | type = COSE_RS256; | ||
151 | else if (strcmp(argv[0], "eddsa") == 0) | ||
152 | type = COSE_EDDSA; | ||
153 | else | ||
154 | errx(1, "unknown type %s", argv[0]); | ||
155 | } | ||
156 | |||
157 | fido_init((flags & FLAG_DEBUG) ? FIDO_DEBUG : 0); | ||
158 | cred = prepare_cred(in_f, type, flags); | ||
159 | |||
160 | if (fido_cred_x5c_ptr(cred) == NULL) { | ||
161 | if ((r = fido_cred_verify_self(cred)) != FIDO_OK) | ||
162 | errx(1, "fido_cred_verify_self: %s", fido_strerr(r)); | ||
163 | } else { | ||
164 | if ((r = fido_cred_verify(cred)) != FIDO_OK) | ||
165 | errx(1, "fido_cred_verify: %s", fido_strerr(r)); | ||
166 | } | ||
167 | |||
168 | print_cred(out_f, type, cred); | ||
169 | fido_cred_free(&cred); | ||
170 | |||
171 | fclose(in_f); | ||
172 | fclose(out_f); | ||
173 | in_f = NULL; | ||
174 | out_f = NULL; | ||
175 | |||
176 | exit(0); | ||
177 | } | ||