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 default: 343 warnx("unsupported hash algorithm: %s", hname); 344 goto oops; 345 } 346 md->init(&mctx.vtable); 347 md->update(&mctx.vtable, fdata, fbytes); 348 md->update(&mctx.vtable, sig->pgpbytes, 349 sig->pgpbytes_len); 350 md->out(&mctx.vtable, mdata); 351 352 rc = verify_rsa_digest(key->key, hash_oid, 353 mdata, mlen, sig->sig, sig->sig_len); 354 #else 355 md = EVP_get_digestbyname(hname); 356 EVP_DigestInit(&mctx, md); 357 EVP_DigestUpdate(&mctx, fdata, fbytes); 358 EVP_DigestUpdate(&mctx, sig->pgpbytes, 359 sig->pgpbytes_len); 360 mlen = sizeof(mdata); 361 EVP_DigestFinal(&mctx,mdata,(unsigned int *)&mlen); 362 363 rc = verify_digest(key->key, hname, mdata, mlen, 364 sig->sig, sig->sig_len); 365 #endif 366 367 if (rc > 0) { 368 if ((flags & VEF_VERBOSE)) 369 printf("Verified %s signed by %s\n", 370 filename, 371 key->user ? key->user->name : "someone"); 372 rc = 0; /* success */ 373 } else if (rc == 0) { 374 printf("Unverified %s: %s\n", 375 filename, get_error_string()); 376 rc = 1; 377 } else { 378 printf("Unverified %s\n", filename); 379 } 380 } 381 } else { 382 warnx("cannot decode signature for %s", filename); 383 rc = -1; 384 } 385 oops: 386 free(ddata); 387 free(sig); 388 return (rc); 389 } 390 391 #ifndef _STANDALONE 392 /** 393 * @brief list of extensions we handle 394 * 395 * ".asc" is preferred as it works seamlessly with openpgp 396 */ 397 static const char *sig_exts[] = { 398 ".asc", 399 ".pgp", 400 ".psig", 401 NULL, 402 }; 403 404 /** 405 * @brief verify OpenPGP signed file 406 * 407 * 408 * @param[in] filename 409 * used to determine the signature name 410 * 411 * @param[in] fdata 412 * content of filename 413 * 414 * @param[in] nbytes 415 * of fdata 416 * 417 * @return 418 */ 419 420 int 421 openpgp_verify_file(const char *filename, unsigned char *fdata, size_t nbytes) 422 { 423 char pbuf[MAXPATHLEN]; 424 unsigned char *sdata; 425 const char *sname = NULL; 426 const char **ep; 427 size_t sz; 428 int n; 429 430 for (ep = sig_exts; *ep; ep++) { 431 n = snprintf(pbuf, sizeof(pbuf), "%s%s", filename, *ep); 432 if (n >= (int)sizeof(pbuf)) { 433 warnx("cannot form signature name for %s", filename); 434 return (-1); 435 } 436 if (access(pbuf, R_OK) == 0) { 437 sname = pbuf; 438 break; 439 } 440 } 441 if (!sname) { 442 warnx("cannot find signature for %s", filename); 443 return (-1); 444 } 445 sdata = read_file(sname, &sz); 446 return (openpgp_verify(filename, fdata, nbytes, sdata, sz, VerifyFlags)); 447 } 448 #endif 449 450 /** 451 * @brief verify OpenPGP signature 452 * 453 * @return content of signed file 454 */ 455 unsigned char * 456 verify_asc(const char *sigfile, int flags) 457 { 458 char pbuf[MAXPATHLEN]; 459 char *cp; 460 size_t n; 461 unsigned char *fdata, *sdata; 462 size_t fbytes, sbytes; 463 464 fdata = NULL; 465 if ((sdata = read_file(sigfile, &sbytes))) { 466 n = strlcpy(pbuf, sigfile, sizeof(pbuf)); 467 if (n < sizeof(pbuf)) { 468 if ((cp = strrchr(pbuf, '.'))) 469 *cp = '\0'; 470 if ((fdata = read_file(pbuf, &fbytes))) { 471 if (openpgp_verify(pbuf, fdata, fbytes, sdata, 472 sbytes, flags)) { 473 free(fdata); 474 fdata = NULL; 475 } 476 } 477 } 478 } 479 free(sdata); 480 return (fdata); 481 } 482