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