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) { 213 DEBUG_PRINTF(2, ("openpgp_trust_add(%s)\n", key->id)); 214 LIST_INSERT_HEAD(&trust_list, key, entries); 215 } 216 } 217 218 /** 219 * @brief if keyID is in our list return the key 220 * 221 * @return key or NULL 222 */ 223 OpenPGP_key * 224 openpgp_trust_get(const char *keyID) 225 { 226 OpenPGP_key *key; 227 228 openpgp_trust_add(NULL); /* initialize if needed */ 229 230 LIST_FOREACH(key, &trust_list, entries) { 231 if (strcmp(key->id, keyID) == 0) 232 return (key); 233 } 234 return (NULL); 235 } 236 237 /** 238 * @brief load a key from file 239 */ 240 OpenPGP_key * 241 load_key_file(const char *kfile) 242 { 243 unsigned char *data = NULL; 244 size_t n; 245 OpenPGP_key *key; 246 247 data = read_file(kfile, &n); 248 key = load_key_buf(data, n); 249 free(data); 250 openpgp_trust_add(key); 251 return (key); 252 } 253 254 #include <ta_asc.h> 255 256 #ifndef _STANDALONE 257 /* we can lookup keyID in filesystem */ 258 259 static const char *trust_store[] = { 260 "/var/db/trust", 261 "/etc/db/trust", 262 NULL, 263 }; 264 265 /** 266 * @brief lookup key id in trust store 267 * 268 */ 269 static OpenPGP_key * 270 load_trusted_key_id(const char *keyID) 271 { 272 char kfile[MAXPATHLEN]; 273 const char **tp; 274 size_t n; 275 276 for (tp = trust_store; *tp; tp++) { 277 n = (size_t)snprintf(kfile, sizeof(kfile), "%s/%s", *tp, keyID); 278 if (n >= sizeof(kfile)) 279 return (NULL); 280 if (access(kfile, R_OK) == 0) { 281 return (load_key_file(kfile)); 282 } 283 } 284 return (NULL); 285 } 286 #endif 287 288 /** 289 * @brief return key if trusted 290 */ 291 OpenPGP_key * 292 load_key_id(const char *keyID) 293 { 294 OpenPGP_key *key; 295 296 key = openpgp_trust_get(keyID); 297 #ifndef _STANDALONE 298 if (!key) 299 key = load_trusted_key_id(keyID); 300 #endif 301 DEBUG_PRINTF(2, ("load_key_id(%s): %s\n", keyID, key ? "found" : "nope")); 302 return (key); 303 } 304 305 /** 306 * @brief initialize our internal trust store if any 307 */ 308 int 309 openpgp_trust_init(void) 310 { 311 static int once = -1; 312 #ifdef HAVE_TA_ASC 313 OpenPGP_key *key; 314 const char **tp; 315 char *cp; 316 size_t n; 317 #endif 318 319 if (once < 0) { 320 once = 0; 321 #ifdef HAVE_TA_ASC 322 for (tp = ta_ASC; *tp; tp++) { 323 if ((cp = strdup(*tp))) { 324 n = strlen(cp); 325 key = load_key_buf((unsigned char *)cp, n); 326 free(cp); 327 if (key) { 328 openpgp_trust_add(key); 329 once++; 330 } 331 } 332 } 333 } 334 #endif 335 return (once); 336 } 337 338 /** 339 * @brief test that we can verify a signature 340 * 341 * Unlike X.509 certificates, we only support RSA keys 342 * so we stop after first successful signature verification 343 * (which should also be the first attempt ;-) 344 */ 345 int 346 openpgp_self_tests(void) 347 { 348 static int rc = -1; /* remember result */ 349 #ifdef HAVE_VC_ASC 350 const char **vp, **tp; 351 char *fdata, *sdata = NULL; 352 size_t fbytes, sbytes; 353 354 if (openpgp_trust_init() > 0) { 355 for (tp = ta_ASC, vp = vc_ASC; *tp && *vp && rc; tp++, vp++) { 356 if ((fdata = strdup(*tp)) && 357 (sdata = strdup(*vp))) { 358 fbytes = strlen(fdata); 359 sbytes = strlen(sdata); 360 rc = openpgp_verify("ta_ASC", 361 (unsigned char *)fdata, fbytes, 362 (unsigned char *)sdata, sbytes, 0); 363 printf("Testing verify OpenPGP signature:\t\t%s\n", 364 rc ? "Failed" : "Passed"); 365 } 366 free(fdata); 367 free(sdata); 368 } 369 } 370 #endif 371 return (rc); 372 } 373