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