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 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 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 * 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 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 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 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 * 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 * 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 * 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 * 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 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 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