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 * RCSid: 27 * from: signer.c,v 1.10 2018/03/23 01:14:30 sjg 28 * 29 * @(#) Copyright (c) 2012 Simon J. Gerraty 30 * 31 * This file is provided in the hope that it will 32 * be of use. There is absolutely NO WARRANTY. 33 * Permission to copy, redistribute or otherwise 34 * use this file is hereby granted provided that 35 * the above copyright notice and this notice are 36 * left intact. 37 * 38 * Please send copies of changes and bug-fixes to: 39 * sjg@crufty.net 40 */ 41 42 #include <sys/cdefs.h> 43 __FBSDID("$FreeBSD$"); 44 45 #include "../libsecureboot-priv.h" 46 #ifdef _STANDALONE 47 #define warnx printf 48 #else 49 50 #include <sys/param.h> 51 #include <sys/stat.h> 52 #include <unistd.h> 53 #include <stdio.h> 54 #include <fcntl.h> 55 #include <stdlib.h> 56 #include <string.h> 57 #include <err.h> 58 #endif 59 60 #include "decode.h" 61 #include "packet.h" 62 63 #ifdef USE_BEARSSL 64 65 #define get_error_string ve_error_get 66 67 void 68 initialize (void) 69 { 70 openpgp_trust_init(); 71 } 72 73 #else 74 75 #include <openssl/err.h> 76 77 /** 78 * @brief intialize OpenSSL 79 */ 80 void 81 initialize(void) 82 { 83 static int once; 84 85 if (once) 86 return); 87 once = 1; 88 //CRYPTO_malloc_init(); 89 ERR_load_crypto_strings(); 90 OpenSSL_add_all_algorithms(); 91 } 92 93 /** 94 * @brief 95 * last error from OpenSSL as a string 96 */ 97 char * 98 get_error_string(void) 99 { 100 initialize(); 101 return (ERR_error_string(ERR_get_error(), NULL)); 102 } 103 #endif 104 105 /** 106 * @brief decode a signature packet 107 * 108 * We only support RSA 109 * 110 * @sa rfc4880:5.2 111 */ 112 ssize_t 113 decode_sig(int tag, unsigned char **pptr, size_t len, OpenPGP_sig *sig) 114 { 115 unsigned char *ptr; 116 unsigned char *pgpbytes; 117 unsigned char *sp; 118 int version; 119 int hcount = 0; 120 int ucount = 0; 121 int stag = 0; 122 int n; 123 124 n = tag; /* avoid unused */ 125 126 /* 127 * We need to keep a reference to the packet bytes 128 * as these form part of the signature data. 129 * 130 * @sa rfc4880:5.2.4 131 */ 132 pgpbytes = ptr = *pptr; 133 version = *ptr++; 134 if (version == 3) { 135 ptr++; 136 sig->pgpbytes = malloc(5); 137 if (!sig->pgpbytes) 138 return (-1); 139 memcpy(sig->pgpbytes, ptr, 5); 140 sig->pgpbytes_len = 5; 141 sig->sig_type = *ptr++; 142 ptr += 4; 143 sig->key_id = octets2hex(ptr, 8); 144 ptr += 8; 145 sig->sig_alg = *ptr++; 146 sig->hash_alg = *ptr++; 147 } else if (version == 4) { 148 sig->sig_type = *ptr++; 149 sig->sig_alg = *ptr++; 150 sig->hash_alg = *ptr++; 151 hcount = octets2i(ptr, 2); 152 ptr += 2; 153 sig->pgpbytes_len = (size_t)hcount + 6; 154 sig->pgpbytes = malloc(sig->pgpbytes_len + 6); 155 if (!sig->pgpbytes) 156 return (-1); 157 memcpy(sig->pgpbytes, pgpbytes, sig->pgpbytes_len); 158 sp = &sig->pgpbytes[sig->pgpbytes_len]; 159 *sp++ = 4; 160 *sp++ = 255; 161 memcpy(sp, i2octets(4, (int)sig->pgpbytes_len), 4); 162 sig->pgpbytes_len += 6; 163 164 while (hcount > 0) { 165 sp = decode_subpacket(&ptr, &stag, &n); 166 hcount -= n; 167 /* can check stag to see if we care */ 168 } 169 ucount = octets2i(ptr, 2); 170 ptr += 2; 171 while (ucount > 0) { 172 sp = decode_subpacket(&ptr, &stag, &n); 173 ucount -= n; 174 /* can check stag to see if we care */ 175 if (stag == 16) { 176 free(sig->key_id); 177 sig->key_id = octets2hex(sp, 8); 178 } 179 } 180 } else 181 return (-1); 182 ptr += 2; /* skip hash16 */ 183 if (sig->sig_alg == 1) { /* RSA */ 184 sig->sig = decode_mpi(&ptr, &sig->sig_len); 185 } 186 /* we are done */ 187 return ((ssize_t)len); 188 } 189 190 /** 191 * @brief map OpenPGP hash algorithm id's to name 192 * 193 * @sa rfc4880:9.4 194 */ 195 static struct hash_alg_map { 196 int halg; 197 const char *hname; 198 } hash_algs[] = { 199 {1, "md5"}, 200 {2, "sha1"}, 201 {8, "sha256"}, 202 {9, "sha384"}, 203 {10, "sha512"}, 204 {11, "sha224"}, 205 {0, NULL}, 206 }; 207 208 static const char * 209 get_hname(int hash_alg) 210 { 211 struct hash_alg_map *hmp; 212 213 for (hmp = hash_algs; hmp->halg > 0; hmp++) { 214 if (hmp->halg == hash_alg) 215 return (hmp->hname); 216 } 217 return (NULL); 218 } 219 220 /* lifted from signer.c */ 221 /** 222 * @brief verify a digest 223 * 224 * The public key, digest name, file and signature data. 225 * 226 * @return 1 on success 0 on failure, -1 on error 227 */ 228 #ifndef USE_BEARSSL 229 static int 230 verify_digest (EVP_PKEY *pkey, 231 const char *digest, 232 unsigned char *mdata, size_t mlen, 233 unsigned char *sdata, size_t slen) 234 { 235 EVP_MD_CTX ctx; 236 const EVP_MD *md = NULL; 237 EVP_PKEY_CTX *pctx = NULL; 238 int rc = 0; 239 int i = -1; 240 241 initialize(); 242 md = EVP_get_digestbyname(digest); 243 EVP_DigestInit(&ctx, md); 244 245 pctx = EVP_PKEY_CTX_new(pkey, NULL); 246 if (!pctx) 247 goto fail; 248 if (EVP_PKEY_verify_init(pctx) <= 0) 249 goto fail; 250 if (EVP_PKEY_CTX_set_signature_md(pctx, ctx.digest) <= 0) 251 goto fail; 252 i = EVP_PKEY_verify(pctx, sdata, slen, mdata, mlen); 253 if (i >= 0) 254 rc = i; 255 fail: 256 EVP_PKEY_CTX_free(pctx); 257 return (rc); 258 } 259 #endif 260 261 262 /** 263 * @brief verify OpenPGP signed file 264 * 265 * 266 * @param[in] filename 267 * used to determine the signature name 268 * 269 * @param[in] fdata 270 * content of filename 271 * 272 * @param[in] fbytes 273 * of fdata 274 * 275 * @param[in] sdata 276 * content of signature 277 * 278 * @param[in] sbytes 279 * of sdata 280 * 281 * @param[in] flags 282 * 283 * @return 0 on success 284 */ 285 int 286 openpgp_verify(const char *filename, 287 unsigned char *fdata, size_t fbytes, 288 unsigned char *sdata, size_t sbytes, 289 int flags) 290 { 291 OpenPGP_key *key; 292 OpenPGP_sig *sig; 293 #ifdef USE_BEARSSL 294 const br_hash_class *md; 295 br_hash_compat_context mctx; 296 const unsigned char *hash_oid; 297 #else 298 const EVP_MD *md = NULL; 299 EVP_MD_CTX mctx; 300 #endif 301 unsigned char mdata[64]; 302 unsigned char *ptr; 303 unsigned char *ddata = NULL; 304 const char *hname; 305 size_t mlen; 306 int rc = -1; 307 308 initialize(); 309 310 sig = NEW(OpenPGP_sig); 311 if (!sdata || !sig) { 312 warnx("cannot verify %s", filename); 313 goto oops; 314 } 315 if (!(sdata[0] & OPENPGP_TAG_ISTAG)) 316 sdata = ddata = dearmor((char *)sdata, sbytes, &sbytes); 317 ptr = sdata; 318 rc = decode_packet(2, &ptr, sbytes, (decoder_t)decode_sig, sig); 319 DEBUG_PRINTF(2, ("rc=%d keyID=%s\n", rc, sig->key_id ? sig->key_id : "?")); 320 if (rc == 0 && sig->key_id) { 321 key = load_key_id(sig->key_id); 322 if (!key) { 323 warnx("cannot find key-id: %s", sig->key_id); 324 rc = -1; 325 } else if (!(hname = get_hname(sig->hash_alg))) { 326 warnx("unsupported hash algorithm: %d", sig->hash_alg); 327 rc = -1; 328 } else { 329 /* 330 * Hash fdata according to the OpenPGP recipe 331 * 332 * @sa rfc4880:5.2.4 333 */ 334 #ifdef USE_BEARSSL 335 switch (sig->hash_alg) { /* see hash_algs above */ 336 case 2: /* sha1 */ 337 md = &br_sha1_vtable; 338 mlen = br_sha1_SIZE; 339 hash_oid = BR_HASH_OID_SHA1; 340 break; 341 case 8: /* sha256 */ 342 md = &br_sha256_vtable; 343 mlen = br_sha256_SIZE; 344 hash_oid = BR_HASH_OID_SHA256; 345 break; 346 default: 347 warnx("unsupported hash algorithm: %s", hname); 348 goto oops; 349 } 350 md->init(&mctx.vtable); 351 md->update(&mctx.vtable, fdata, fbytes); 352 md->update(&mctx.vtable, sig->pgpbytes, 353 sig->pgpbytes_len); 354 md->out(&mctx.vtable, mdata); 355 356 rc = verify_rsa_digest(key->key, hash_oid, 357 mdata, mlen, sig->sig, sig->sig_len); 358 #else 359 md = EVP_get_digestbyname(hname); 360 EVP_DigestInit(&mctx, md); 361 EVP_DigestUpdate(&mctx, fdata, fbytes); 362 EVP_DigestUpdate(&mctx, sig->pgpbytes, 363 sig->pgpbytes_len); 364 mlen = sizeof(mdata); 365 EVP_DigestFinal(&mctx,mdata,(unsigned int *)&mlen); 366 367 rc = verify_digest(key->key, hname, mdata, mlen, 368 sig->sig, sig->sig_len); 369 #endif 370 371 if (rc > 0) { 372 if ((flags & VEF_VERBOSE)) 373 printf("Verified %s signed by %s\n", 374 filename, 375 key->user ? key->user->name : "someone"); 376 rc = 0; /* success */ 377 } else if (rc == 0) { 378 printf("Unverified %s: %s\n", 379 filename, get_error_string()); 380 rc = 1; 381 } else { 382 printf("Unverified %s\n", filename); 383 } 384 } 385 } else { 386 warnx("cannot decode signature for %s", filename); 387 rc = -1; 388 } 389 oops: 390 free(ddata); 391 free(sig); 392 return (rc); 393 } 394 395 #ifndef _STANDALONE 396 /** 397 * @brief list of extensions we handle 398 * 399 * ".asc" is preferred as it works seamlessly with openpgp 400 */ 401 static const char *sig_exts[] = { 402 ".asc", 403 ".pgp", 404 ".psig", 405 NULL, 406 }; 407 408 /** 409 * @brief verify OpenPGP signed file 410 * 411 * 412 * @param[in] filename 413 * used to determine the signature name 414 * 415 * @param[in] fdata 416 * content of filename 417 * 418 * @param[in] nbytes 419 * of fdata 420 * 421 * @return 422 */ 423 424 int 425 openpgp_verify_file(const char *filename, unsigned char *fdata, size_t nbytes) 426 { 427 char pbuf[MAXPATHLEN]; 428 unsigned char *sdata; 429 const char *sname = NULL; 430 const char **ep; 431 size_t sz; 432 int n; 433 434 for (ep = sig_exts; *ep; ep++) { 435 n = snprintf(pbuf, sizeof(pbuf), "%s%s", filename, *ep); 436 if (n >= (int)sizeof(pbuf)) { 437 warnx("cannot form signature name for %s", filename); 438 return (-1); 439 } 440 if (access(pbuf, R_OK) == 0) { 441 sname = pbuf; 442 break; 443 } 444 } 445 if (!sname) { 446 warnx("cannot find signature for %s", filename); 447 return (-1); 448 } 449 sdata = read_file(sname, &sz); 450 return (openpgp_verify(filename, fdata, nbytes, sdata, sz, VerifyFlags)); 451 } 452 #endif 453 454 /** 455 * @brief verify OpenPGP signature 456 * 457 * @return content of signed file 458 */ 459 unsigned char * 460 verify_asc(const char *sigfile, int flags) 461 { 462 char pbuf[MAXPATHLEN]; 463 char *cp; 464 size_t n; 465 unsigned char *fdata, *sdata; 466 size_t fbytes, sbytes; 467 468 if ((sdata = read_file(sigfile, &sbytes))) { 469 n = strlcpy(pbuf, sigfile, sizeof(pbuf)); 470 if ((cp = strrchr(pbuf, '.'))) 471 *cp = '\0'; 472 if ((fdata = read_file(pbuf, &fbytes))) { 473 if (openpgp_verify(pbuf, fdata, fbytes, sdata, 474 sbytes, flags)) { 475 free(fdata); 476 fdata = NULL; 477 } 478 } 479 } else 480 fdata = NULL; 481 free(sdata); 482 return (fdata); 483 } 484