1 /*-
2 * Copyright (c) 2018, Juniper Networks, Inc.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
6 * are met:
7 * 1. Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * 2. Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 *
13 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
14 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
15 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
16 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
17 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
18 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
19 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
20 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
21 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24 */
25
26 #include <sys/cdefs.h>
27 #include "../libsecureboot-priv.h"
28
29 #include "decode.h"
30 #include "packet.h"
31
32 /**
33 * @brief decode user-id packet
34 *
35 * This is trivial
36 *
37 * @sa rfc4880:5.11
38 */
39 ssize_t
decode_user(int tag,unsigned char ** pptr,size_t len,OpenPGP_user * user)40 decode_user(int tag, unsigned char **pptr, size_t len, OpenPGP_user *user)
41 {
42 char *cp;
43
44 if (tag == 13) {
45 user->id = malloc(len + 1);
46 strncpy(user->id, (char *)*pptr, len);
47 user->id[len] = '\0';
48 user->name = user->id;
49 cp = strchr(user->id, '<');
50 if (cp > user->id) {
51 user->id = strdup(user->id);
52 cp[-1] = '\0';
53 }
54 }
55 *pptr += len;
56 return ((ssize_t)len);
57 }
58
59 /**
60 * @brief decode a key packet
61 *
62 * We only really support v4 and RSA
63 *
64 * @sa rfc4880:5.5.1.1
65 */
66 ssize_t
decode_key(int tag,unsigned char ** pptr,size_t len,OpenPGP_key * key)67 decode_key(int tag, unsigned char **pptr, size_t len, OpenPGP_key *key)
68 {
69 unsigned char *ptr;
70 int version;
71 #ifdef USE_BEARSSL
72 br_sha1_context mctx;
73 unsigned char mdata[br_sha512_SIZE];
74 size_t mlen;
75 #else
76 RSA *rsa = NULL;
77 const EVP_MD *md = NULL;
78 EVP_MD_CTX mctx;
79 unsigned char mdata[EVP_MAX_MD_SIZE];
80 unsigned int mlen;
81 #endif
82
83 if (tag != 6)
84 return (-1);
85
86 key->key = NULL;
87 ptr = *pptr;
88 version = *ptr;
89 if (version == 4) { /* all we support really */
90 /* comput key fingerprint and id @sa rfc4880:12.2 */
91 mdata[0] = 0x99; /* rfc4880: 12.2.a.1 */
92 mdata[1] = (len >> 8) & 0xff;
93 mdata[2] = len & 0xff;
94
95 #ifdef USE_BEARSSL
96 br_sha1_init(&mctx);
97 br_sha1_update(&mctx, mdata, 3);
98 br_sha1_update(&mctx, ptr, len);
99 br_sha1_out(&mctx, mdata);
100 mlen = br_sha1_SIZE;
101 #else
102 md = EVP_get_digestbyname("sha1");
103 EVP_DigestInit(&mctx, md);
104 EVP_DigestUpdate(&mctx, mdata, 3);
105 EVP_DigestUpdate(&mctx, ptr, len);
106 mlen = (unsigned int)sizeof(mdata);
107 EVP_DigestFinal(&mctx, mdata, &mlen);
108 #endif
109 key->id = octets2hex(&mdata[mlen - 8], 8);
110 }
111 ptr += 1; /* done with version */
112 ptr += 4; /* skip ctime */
113 if (version == 3)
114 ptr += 2; /* valid days */
115 key->sig_alg = *ptr++;
116 if (key->sig_alg == 1) { /* RSA */
117 #ifdef USE_BEARSSL
118 key->key = NEW(br_rsa_public_key);
119 if (!key->key)
120 goto oops;
121 key->key->n = mpi2bn(&ptr, &key->key->nlen);
122 key->key->e = mpi2bn(&ptr, &key->key->elen);
123 #else
124 rsa = RSA_new();
125 if (!rsa)
126 goto oops;
127 rsa->n = mpi2bn(&ptr);
128 rsa->e = mpi2bn(&ptr);
129 key->key = EVP_PKEY_new();
130 if (!key->key || !rsa->n || !rsa->e) {
131 goto oops;
132 }
133 if (!EVP_PKEY_set1_RSA(key->key, rsa))
134 goto oops;
135 #endif
136 }
137 /* we are done */
138 return ((ssize_t)len);
139 oops:
140 #ifdef USE_BEARSSL
141 free(key->key);
142 key->key = NULL;
143 #else
144 if (rsa)
145 RSA_free(rsa);
146 if (key->key) {
147 EVP_PKEY_free(key->key);
148 key->key = NULL;
149 }
150 #endif
151 return (-1);
152 }
153
154 static OpenPGP_key *
load_key_buf(unsigned char * buf,size_t nbytes)155 load_key_buf(unsigned char *buf, size_t nbytes)
156 {
157 unsigned char *data = NULL;
158 unsigned char *ptr;
159 ssize_t rc;
160 int tag;
161 OpenPGP_key *key;
162
163 if (!buf)
164 return (NULL);
165
166 initialize();
167
168 if (!(buf[0] & OPENPGP_TAG_ISTAG)) {
169 /* Note: we do *not* free data */
170 data = dearmor((char *)buf, nbytes, &nbytes);
171 ptr = data;
172 } else
173 ptr = buf;
174 key = NEW(OpenPGP_key);
175 if (key) {
176 rc = decode_packet(0, &ptr, nbytes, (decoder_t)decode_key,
177 key);
178 if (rc < 0) {
179 free(key);
180 key = NULL;
181 } else if (rc > 8) {
182 int isnew, ltype;
183
184 tag = decode_tag(ptr, &isnew, <ype);
185 if (tag == 13) {
186 key->user = NEW(OpenPGP_user);
187 rc = decode_packet(0, &ptr, (size_t)rc,
188 (decoder_t)decode_user, key->user);
189 }
190 }
191 }
192 return (key);
193 }
194
195 static LIST_HEAD(, OpenPGP_key_) trust_list;
196
197 /**
198 * @brief add a key to our list
199 */
200 void
openpgp_trust_add(OpenPGP_key * key)201 openpgp_trust_add(OpenPGP_key *key)
202 {
203 static int once = 0;
204
205 if (!once) {
206 once = 1;
207
208 LIST_INIT(&trust_list);
209 }
210 if (key && openpgp_trust_get(key->id) == NULL) {
211 if (ve_anchor_verbose_get())
212 printf("openpgp_trust_add(%s)\n", key->id);
213 LIST_INSERT_HEAD(&trust_list, key, entries);
214 }
215 }
216
217 /**
218 * @brief add trust anchor from buf
219 */
220 int
openpgp_trust_add_buf(unsigned char * buf,size_t nbytes)221 openpgp_trust_add_buf(unsigned char *buf, size_t nbytes)
222 {
223 OpenPGP_key *key;
224
225 if ((key = load_key_buf(buf, nbytes))) {
226 openpgp_trust_add(key);
227 }
228 return (key != NULL);
229 }
230
231
232 /**
233 * @brief if keyID is in our list clobber it
234 *
235 * @return true if keyID removed
236 */
237 int
openpgp_trust_revoke(const char * keyID)238 openpgp_trust_revoke(const char *keyID)
239 {
240 OpenPGP_key *key, *tkey;
241
242 openpgp_trust_add(NULL); /* initialize if needed */
243
244 LIST_FOREACH(key, &trust_list, entries) {
245 if (strcmp(key->id, keyID) == 0) {
246 tkey = key;
247 LIST_REMOVE(tkey, entries);
248 printf("openpgp_trust_revoke(%s)\n", key->id);
249 memset(key, 0, sizeof(OpenPGP_key));
250 free(key);
251 return (1);
252 }
253 }
254 return (0);
255 }
256
257 /**
258 * @brief if keyID is in our list return the key
259 *
260 * @return key or NULL
261 */
262 OpenPGP_key *
openpgp_trust_get(const char * keyID)263 openpgp_trust_get(const char *keyID)
264 {
265 OpenPGP_key *key;
266
267 openpgp_trust_add(NULL); /* initialize if needed */
268
269 LIST_FOREACH(key, &trust_list, entries) {
270 if (strcmp(key->id, keyID) == 0)
271 return (key);
272 }
273 return (NULL);
274 }
275
276 /**
277 * @brief load a key from file
278 */
279 OpenPGP_key *
load_key_file(const char * kfile)280 load_key_file(const char *kfile)
281 {
282 unsigned char *data = NULL;
283 size_t n;
284 OpenPGP_key *key;
285
286 data = read_file(kfile, &n);
287 key = load_key_buf(data, n);
288 free(data);
289 openpgp_trust_add(key);
290 return (key);
291 }
292
293 #ifdef HAVE_TA_ASC_H
294 #include <ta_asc.h>
295 #endif
296
297 #ifndef _STANDALONE
298 /* we can lookup keyID in filesystem */
299
300 static const char *trust_store[] = {
301 "/var/db/trust",
302 "/etc/db/trust",
303 NULL,
304 };
305
306 /**
307 * @brief lookup key id in trust store
308 *
309 */
310 static OpenPGP_key *
load_trusted_key_id(const char * keyID)311 load_trusted_key_id(const char *keyID)
312 {
313 char kfile[MAXPATHLEN];
314 const char **tp;
315 size_t n;
316
317 for (tp = trust_store; *tp; tp++) {
318 n = (size_t)snprintf(kfile, sizeof(kfile), "%s/%s", *tp, keyID);
319 if (n >= sizeof(kfile))
320 return (NULL);
321 if (access(kfile, R_OK) == 0) {
322 return (load_key_file(kfile));
323 }
324 }
325 return (NULL);
326 }
327 #endif
328
329 /**
330 * @brief return key if trusted
331 */
332 OpenPGP_key *
load_key_id(const char * keyID)333 load_key_id(const char *keyID)
334 {
335 OpenPGP_key *key;
336
337 key = openpgp_trust_get(keyID);
338 #ifndef _STANDALONE
339 if (!key)
340 key = load_trusted_key_id(keyID);
341 #endif
342 DEBUG_PRINTF(2, ("load_key_id(%s): %s\n", keyID, key ? "found" : "nope"));
343 return (key);
344 }
345
346 /**
347 * @brief initialize our internal trust store if any
348 */
349 int
openpgp_trust_init(void)350 openpgp_trust_init(void)
351 {
352 static int once = -1;
353 #ifdef HAVE_TA_ASC
354 OpenPGP_key *key;
355 const char **tp;
356 char *cp;
357 size_t n;
358 #endif
359
360 if (once < 0) {
361 once = 0;
362 #ifdef HAVE_TA_ASC
363 for (tp = ta_ASC; *tp; tp++) {
364 if ((cp = strdup(*tp))) {
365 n = strlen(cp);
366 key = load_key_buf((unsigned char *)cp, n);
367 free(cp);
368 if (key) {
369 openpgp_trust_add(key);
370 once++;
371 }
372 }
373 }
374 #endif
375 }
376 return (once);
377 }
378
379 /**
380 * @brief test that we can verify a signature
381 *
382 * Unlike X.509 certificates, we only support RSA keys
383 * so we stop after first successful signature verification
384 * (which should also be the first attempt ;-)
385 */
386 int
openpgp_self_tests(void)387 openpgp_self_tests(void)
388 {
389 static int rc = -1; /* remember result */
390 #ifdef HAVE_VC_ASC
391 const char **vp, **tp;
392 char *fdata, *sdata = NULL;
393 size_t fbytes, sbytes;
394
395 if (openpgp_trust_init() > 0) {
396 for (tp = ta_ASC, vp = vc_ASC; *tp && *vp && rc; tp++, vp++) {
397 if ((fdata = strdup(*tp)) &&
398 (sdata = strdup(*vp))) {
399 fbytes = strlen(fdata);
400 sbytes = strlen(sdata);
401 rc = openpgp_verify("ta_ASC",
402 (unsigned char *)fdata, fbytes,
403 (unsigned char *)sdata, sbytes, 0);
404 printf("Testing verify OpenPGP signature:\t\t%s\n",
405 rc ? "Failed" : "Passed");
406 }
407 free(fdata);
408 free(sdata);
409 }
410 }
411 #endif
412 return (rc);
413 }
414