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