pkg_signature.c revision 1.3
1/* $NetBSD: pkg_signature.c,v 1.3 2017/04/20 13:18:23 joerg Exp $ */ 2 3#if HAVE_CONFIG_H 4#include "config.h" 5#endif 6#include <nbcompat.h> 7#if HAVE_SYS_CDEFS_H 8#include <sys/cdefs.h> 9#endif 10__RCSID("$NetBSD: pkg_signature.c,v 1.3 2017/04/20 13:18:23 joerg Exp $"); 11 12/*- 13 * Copyright (c) 2008 Joerg Sonnenberger <joerg@NetBSD.org>. 14 * All rights reserved. 15 * 16 * Redistribution and use in source and binary forms, with or without 17 * modification, are permitted provided that the following conditions 18 * are met: 19 * 20 * 1. Redistributions of source code must retain the above copyright 21 * notice, this list of conditions and the following disclaimer. 22 * 2. Redistributions in binary form must reproduce the above copyright 23 * notice, this list of conditions and the following disclaimer in 24 * the documentation and/or other materials provided with the 25 * distribution. 26 * 27 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 28 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 29 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 30 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 31 * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 32 * INCIDENTAL, SPECIAL, EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING, 33 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 34 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED 35 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 36 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT 37 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 38 * SUCH DAMAGE. 39 */ 40 41#if HAVE_SYS_WAIT_H 42#include <sys/wait.h> 43#endif 44#include <ctype.h> 45#if HAVE_ERR_H 46#include <err.h> 47#endif 48#include <errno.h> 49#include <fcntl.h> 50#include <limits.h> 51#include <stdlib.h> 52#ifndef NETBSD 53#include <nbcompat/sha2.h> 54#else 55#include <sha2.h> 56#endif 57#include <signal.h> 58#ifdef NETBSD 59#include <unistd.h> 60#else 61#include <nbcompat/unistd.h> 62#endif 63 64#include <archive.h> 65#include <archive_entry.h> 66 67#include "lib.h" 68 69#define HASH_FNAME "+PKG_HASH" 70#define SIGNATURE_FNAME "+PKG_SIGNATURE" 71#define GPG_SIGNATURE_FNAME "+PKG_GPG_SIGNATURE" 72 73struct signature_archive { 74 struct archive *archive; 75 off_t pkg_size; 76 size_t sign_block_len, sign_block_number, sign_cur_block; 77 char **sign_blocks; 78 unsigned char *sign_buf; 79}; 80 81static void 82hash_block(unsigned char *buf, size_t buf_len, 83 char hash[SHA512_DIGEST_STRING_LENGTH]) 84{ 85 unsigned char digest[SHA512_DIGEST_LENGTH]; 86 SHA512_CTX hash_ctx; 87 int i; 88 89 SHA512_Init(&hash_ctx); 90 SHA512_Update(&hash_ctx, buf, buf_len); 91 SHA512_Final(digest, &hash_ctx); 92 for (i = 0; i < SHA512_DIGEST_LENGTH; ++i) { 93 unsigned char c; 94 95 c = digest[i] / 16; 96 if (c < 10) 97 hash[2 * i] = '0' + c; 98 else 99 hash[2 * i] = 'a' - 10 + c; 100 101 c = digest[i] % 16; 102 if (c < 10) 103 hash[2 * i + 1] = '0' + c; 104 else 105 hash[2 * i + 1] = 'a' - 10 + c; 106 } 107 hash[2 * i] = '\0'; 108} 109 110static ssize_t 111verify_signature_read_cb(struct archive *archive, void *cookie, const void **buf) 112{ 113 struct signature_archive *state = cookie; 114 char hash[SHA512_DIGEST_STRING_LENGTH]; 115 ssize_t len, expected; 116 117 if (state->sign_cur_block >= state->sign_block_number) 118 return 0; 119 120 /* The following works for sign_block_len > 1 */ 121 if (state->sign_cur_block + 1 == state->sign_block_number) 122 expected = state->pkg_size % state->sign_block_len; 123 else 124 expected = state->sign_block_len; 125 126 len = archive_read_data(state->archive, state->sign_buf, expected); 127 if (len != expected) { 128 warnx("Short read from package"); 129 return -1; 130 } 131 132 hash_block(state->sign_buf, len, hash); 133 134 if (strcmp(hash, state->sign_blocks[state->sign_cur_block]) != 0) { 135 warnx("Invalid signature of block %llu", 136 (unsigned long long)state->sign_cur_block); 137 return -1; 138 } 139 ++state->sign_cur_block; 140 *buf = state->sign_buf; 141 return len; 142} 143 144static void 145free_signature_int(struct signature_archive *state) 146{ 147 size_t i; 148 149 if (state->sign_blocks != NULL) { 150 for (i = 0; i < state->sign_block_number; ++i) 151 free(state->sign_blocks[i]); 152 } 153 free(state->sign_blocks); 154 free(state->sign_buf); 155 free(state); 156} 157 158static int 159verify_signature_close_cb(struct archive *archive, void *cookie) 160{ 161 struct signature_archive *state = cookie; 162 163 archive_read_free(state->archive); 164 free_signature_int(state); 165 return 0; 166} 167 168static int 169read_file_from_archive(const char *archive_name, struct archive *archive, 170 struct archive_entry **entry, 171 const char *fname, char **content, size_t *len) 172{ 173 int r; 174 175 *content = NULL; 176 *len = 0; 177 178retry: 179 if (*entry == NULL && 180 (r = archive_read_next_header(archive, entry)) != ARCHIVE_OK) { 181 if (r == ARCHIVE_FATAL) { 182 warnx("Cannot read from archive `%s': %s", 183 archive_name, archive_error_string(archive)); 184 } else { 185 warnx("Premature end of archive `%s'", archive_name); 186 } 187 *entry = NULL; 188 return -1; 189 } 190 if (strcmp(archive_entry_pathname(*entry), "//") == 0) { 191 archive_read_data_skip(archive); 192 *entry = NULL; 193 goto retry; 194 } 195 196 if (strcmp(fname, archive_entry_pathname(*entry)) != 0) 197 return 1; 198 199 if (archive_entry_size(*entry) > SSIZE_MAX - 1) { 200 warnx("Signature of archive `%s' too large to process", 201 archive_name); 202 return 1; 203 } 204 *len = archive_entry_size(*entry); 205 *content = xmalloc(*len + 1); 206 207 if (archive_read_data(archive, *content, *len) != (ssize_t)*len) { 208 warnx("Cannot read complete %s from archive `%s'", fname, 209 archive_name); 210 free(*content); 211 *len = 0; 212 *content = NULL; 213 return 1; 214 } 215 (*content)[*len] = '\0'; 216 *entry = NULL; 217 218 return 0; 219} 220 221static int 222parse_hash_file(const char *hash_file, char **pkgname, 223 struct signature_archive *state) 224{ 225 static const char block1[] = "pkgsrc signature\n\nversion: 1\npkgname: "; 226 static const char block2[] = "algorithm: SHA512\nblock size: "; 227 static const char block3[] = "file size: "; 228 static const char block4[] = "end pkgsrc signature\n"; 229 char *next; 230 size_t i, len; 231 232 *pkgname = NULL; 233 234 if (strncmp(hash_file, block1, strlen(block1)) != 0) 235 goto cleanup; 236 hash_file += strlen(block1); 237 238 len = strcspn(hash_file, "\n"); 239 *pkgname = xmalloc(len + 1); 240 memcpy(*pkgname, hash_file, len); 241 (*pkgname)[len] = '\0'; 242 for (i = 0; i < len; ++i) { 243 if (!isgraph((unsigned char)(*pkgname)[i])) 244 goto cleanup; 245 } 246 hash_file += len + 1; 247 248 if (strncmp(hash_file, block2, strlen(block2)) != 0) 249 goto cleanup; 250 hash_file += strlen(block2); 251 252 errno = 0; 253 if (!isdigit((unsigned char)*hash_file)) 254 goto cleanup; 255 state->sign_block_len = strtoul(hash_file, &next, 10); 256 hash_file = next; 257 258 /* Assert sane minimum block size of 1KB */ 259 if (*hash_file++ != '\n' || errno == ERANGE || state->sign_block_len < 1024) 260 goto cleanup; 261 262 if (strncmp(hash_file, block3, strlen(block3)) != 0) 263 goto cleanup; 264 hash_file += strlen(block3); 265 266 errno = 0; 267 if (!isdigit((unsigned char)*hash_file)) 268 goto cleanup; 269 if (/* CONSTCOND */sizeof(off_t) >= sizeof(long long)) 270 state->pkg_size = strtoll(hash_file, &next, 10); 271 else 272 state->pkg_size = strtol(hash_file, &next, 10); 273 hash_file = next; 274 if (*hash_file++ != '\n' || errno == ERANGE || state->pkg_size < 1) 275 goto cleanup; 276 277 if (*hash_file++ != '\n') 278 goto cleanup; 279 280 if (state->pkg_size / state->sign_block_len > SSIZE_MAX) 281 goto cleanup; 282 state->sign_block_number = (state->pkg_size + 283 state->sign_block_len - 1) / state->sign_block_len; 284 285 state->sign_buf = xmalloc(state->sign_block_len); 286 state->sign_blocks = xcalloc(state->sign_block_number, sizeof(char *)); 287 288 for (i = 0; i < state->sign_block_number; ++i) { 289 len = strspn(hash_file, "01234567889abcdef"); 290 if (len != SHA512_DIGEST_LENGTH * 2 || hash_file[len] != '\n') 291 goto cleanup_hashes; 292 state->sign_blocks[i] = xmalloc(len + 1); 293 memcpy(state->sign_blocks[i], hash_file, len); 294 state->sign_blocks[i][len] = '\0'; 295 hash_file += len + 1; 296 } 297 298 if (strcmp(hash_file, block4) != 0) 299 goto cleanup_hashes; 300 301 return 0; 302 303cleanup_hashes: 304 for (i = 0; i < state->sign_block_number; ++i) 305 free(state->sign_blocks[i]); 306 free(state->sign_blocks); 307 state->sign_blocks = NULL; 308 309cleanup: 310 warnx("Unknown format of hash file"); 311 free(*pkgname); 312 *pkgname = NULL; 313 return -1; 314} 315 316int 317pkg_verify_signature(const char *archive_name, struct archive **archive, 318 struct archive_entry **entry, char **pkgname) 319{ 320 struct signature_archive *state; 321 struct archive_entry *my_entry; 322 struct archive *a; 323 char *hash_file, *signature_file; 324 size_t hash_len, signature_len; 325 int r, has_sig; 326 327 *pkgname = NULL; 328 329 state = xcalloc(sizeof(*state), 1); 330 331 r = read_file_from_archive(archive_name, *archive, entry, HASH_FNAME, 332 &hash_file, &hash_len); 333 if (r == -1) { 334 archive_read_free(*archive); 335 *archive = NULL; 336 free(state); 337 goto no_valid_signature; 338 } else if (r == 1) { 339 free(state); 340 goto no_valid_signature; 341 } 342 343 if (parse_hash_file(hash_file, pkgname, state)) 344 goto no_valid_signature; 345 346 r = read_file_from_archive(archive_name, *archive, entry, SIGNATURE_FNAME, 347 &signature_file, &signature_len); 348 if (r == -1) { 349 archive_read_free(*archive); 350 *archive = NULL; 351 free(state); 352 free(hash_file); 353 goto no_valid_signature; 354 } else if (r != 0) { 355 if (*entry != NULL) 356 r = read_file_from_archive(archive_name, *archive, 357 entry, GPG_SIGNATURE_FNAME, 358 &signature_file, &signature_len); 359 if (r == -1) { 360 archive_read_free(*archive); 361 *archive = NULL; 362 free(state); 363 free(hash_file); 364 goto no_valid_signature; 365 } else if (r != 0) { 366 free(hash_file); 367 free(state); 368 goto no_valid_signature; 369 } 370 has_sig = !gpg_verify(hash_file, hash_len, gpg_keyring_verify, 371 signature_file, signature_len); 372 373 free(signature_file); 374 } else { 375#ifdef HAVE_SSL 376 has_sig = !easy_pkcs7_verify(hash_file, hash_len, signature_file, 377 signature_len, certs_packages, 1); 378 379 free(signature_file); 380#else 381 warnx("No OpenSSL support compiled in, skipping signature"); 382 has_sig = 0; 383 free(signature_file); 384#endif 385 } 386 387 r = archive_read_next_header(*archive, &my_entry); 388 if (r != ARCHIVE_OK) { 389 warnx("Cannot read inner package: %s", 390 archive_error_string(*archive)); 391 free_signature_int(state); 392 goto no_valid_signature; 393 } 394 395 if (archive_entry_size(my_entry) != state->pkg_size) { 396 warnx("Package size doesn't match signature"); 397 free_signature_int(state); 398 goto no_valid_signature; 399 } 400 401 state->archive = *archive; 402 403 a = prepare_archive(); 404 if (archive_read_open(a, state, NULL, verify_signature_read_cb, 405 verify_signature_close_cb)) { 406 warnx("Can't open signed package file"); 407 archive_read_free(a); 408 goto no_valid_signature; 409 } 410 *archive = a; 411 *entry = NULL; 412 413 return has_sig ? 0 : -1; 414 415no_valid_signature: 416 return -1; 417} 418 419int 420pkg_full_signature_check(const char *archive_name, struct archive **archive) 421{ 422 struct archive_entry *entry = NULL; 423 char *pkgname; 424 int r; 425 426 if (pkg_verify_signature(archive_name, archive, &entry, &pkgname)) 427 return -1; 428 if (pkgname == NULL) 429 return 0; 430 431 /* XXX read PLIST and compare pkgname */ 432 while ((r = archive_read_next_header(*archive, &entry)) == ARCHIVE_OK) 433 archive_read_data_skip(*archive); 434 435 free(pkgname); 436 return r == ARCHIVE_EOF ? 0 : -1; 437} 438 439static char * 440extract_pkgname(int fd) 441{ 442 package_t plist; 443 plist_t *p; 444 struct archive *a; 445 struct archive_entry *entry; 446 char *buf; 447 ssize_t len; 448 int r; 449 450 a = prepare_archive(); 451 if (archive_read_open_fd(a, fd, 1024)) { 452 warnx("Cannot open binary package: %s", 453 archive_error_string(a)); 454 archive_read_free(a); 455 return NULL; 456 } 457 458 r = archive_read_next_header(a, &entry); 459 if (r != ARCHIVE_OK) { 460 warnx("Cannot extract package name: %s", 461 r == ARCHIVE_EOF ? "EOF" : archive_error_string(a)); 462 archive_read_free(a); 463 return NULL; 464 } 465 if (strcmp(archive_entry_pathname(entry), "+CONTENTS") != 0) { 466 warnx("Invalid binary package, doesn't start with +CONTENTS"); 467 archive_read_free(a); 468 return NULL; 469 } 470 if (archive_entry_size(entry) > SSIZE_MAX - 1) { 471 warnx("+CONTENTS too large to process"); 472 archive_read_free(a); 473 return NULL; 474 } 475 476 len = archive_entry_size(entry); 477 buf = xmalloc(len + 1); 478 479 if (archive_read_data(a, buf, len) != len) { 480 warnx("Short read when extracing +CONTENTS"); 481 free(buf); 482 archive_read_free(a); 483 return NULL; 484 } 485 buf[len] = '\0'; 486 487 archive_read_free(a); 488 489 parse_plist(&plist, buf); 490 free(buf); 491 p = find_plist(&plist, PLIST_NAME); 492 if (p != NULL) { 493 buf = xstrdup(p->name); 494 } else { 495 warnx("Invalid PLIST: missing @name"); 496 buf = NULL; 497 } 498 free_plist(&plist); 499 500 if (lseek(fd, 0, SEEK_SET) != 0) { 501 warn("Cannot seek in archive"); 502 free(buf); 503 return NULL; 504 } 505 506 return buf; 507} 508 509static const char hash_template[] = 510"pkgsrc signature\n" 511"\n" 512"version: 1\n" 513"pkgname: %s\n" 514"algorithm: SHA512\n" 515"block size: 65536\n" 516"file size: %lld\n" 517"\n"; 518 519static const char hash_trailer[] = "end pkgsrc signature\n"; 520 521#ifdef HAVE_SSL 522void 523pkg_sign_x509(const char *name, const char *output, const char *key_file, const char *cert_file) 524{ 525 struct archive *pkg; 526 struct archive_entry *entry, *hash_entry, *sign_entry; 527 int fd; 528 struct stat sb; 529 char *hash_file, *signature_file, *tmp, *pkgname, hash[SHA512_DIGEST_STRING_LENGTH]; 530 unsigned char block[65536]; 531 off_t i, size; 532 size_t block_len, signature_len; 533 534 if ((fd = open(name, O_RDONLY)) == -1) 535 err(EXIT_FAILURE, "Cannot open binary package %s", name); 536 if (fstat(fd, &sb) == -1) 537 err(EXIT_FAILURE, "Cannot stat %s", name); 538 539 entry = archive_entry_new(); 540 archive_entry_copy_stat(entry, &sb); 541 542 pkgname = extract_pkgname(fd); 543 hash_file = xasprintf(hash_template, pkgname, 544 (long long)archive_entry_size(entry)); 545 free(pkgname); 546 547 for (i = 0; i < archive_entry_size(entry); i += block_len) { 548 if (i + (off_t)sizeof(block) < archive_entry_size(entry)) 549 block_len = sizeof(block); 550 else 551 block_len = archive_entry_size(entry) % sizeof(block); 552 if (read(fd, block, block_len) != (ssize_t)block_len) 553 err(2, "short read"); 554 hash_block(block, block_len, hash); 555 tmp = xasprintf("%s%s\n", hash_file, hash); 556 free(hash_file); 557 hash_file = tmp; 558 } 559 tmp = xasprintf("%s%s", hash_file, hash_trailer); 560 free(hash_file); 561 hash_file = tmp; 562 563 if (easy_pkcs7_sign(hash_file, strlen(hash_file), &signature_file, 564 &signature_len, key_file, cert_file)) 565 err(EXIT_FAILURE, "Cannot sign hash file"); 566 567 lseek(fd, 0, SEEK_SET); 568 569 sign_entry = archive_entry_clone(entry); 570 hash_entry = archive_entry_clone(entry); 571 pkgname = strrchr(name, '/'); 572 archive_entry_set_pathname(entry, pkgname != NULL ? pkgname + 1 : name); 573 archive_entry_set_pathname(hash_entry, HASH_FNAME); 574 archive_entry_set_pathname(sign_entry, SIGNATURE_FNAME); 575 archive_entry_set_size(hash_entry, strlen(hash_file)); 576 archive_entry_set_size(sign_entry, signature_len); 577 578 pkg = archive_write_new(); 579 archive_write_set_format_ar_bsd(pkg); 580 archive_write_open_filename(pkg, output); 581 582 archive_write_header(pkg, hash_entry); 583 archive_write_data(pkg, hash_file, strlen(hash_file)); 584 archive_write_finish_entry(pkg); 585 archive_entry_free(hash_entry); 586 587 archive_write_header(pkg, sign_entry); 588 archive_write_data(pkg, signature_file, signature_len); 589 archive_write_finish_entry(pkg); 590 archive_entry_free(sign_entry); 591 592 size = archive_entry_size(entry); 593 archive_write_header(pkg, entry); 594 595 for (i = 0; i < size; i += block_len) { 596 if (i + (off_t)sizeof(block) < size) 597 block_len = sizeof(block); 598 else 599 block_len = size % sizeof(block); 600 if (read(fd, block, block_len) != (ssize_t)block_len) 601 err(2, "short read"); 602 archive_write_data(pkg, block, block_len); 603 } 604 archive_write_finish_entry(pkg); 605 archive_entry_free(entry); 606 607 archive_write_free(pkg); 608 609 close(fd); 610 611 exit(0); 612} 613#endif 614 615void 616pkg_sign_gpg(const char *name, const char *output) 617{ 618 struct archive *pkg; 619 struct archive_entry *entry, *hash_entry, *sign_entry; 620 int fd; 621 struct stat sb; 622 char *hash_file, *signature_file, *tmp, *pkgname, hash[SHA512_DIGEST_STRING_LENGTH]; 623 unsigned char block[65536]; 624 off_t i, size; 625 size_t block_len, signature_len; 626 627 if ((fd = open(name, O_RDONLY)) == -1) 628 err(EXIT_FAILURE, "Cannot open binary package %s", name); 629 if (fstat(fd, &sb) == -1) 630 err(EXIT_FAILURE, "Cannot stat %s", name); 631 632 entry = archive_entry_new(); 633 archive_entry_copy_stat(entry, &sb); 634 635 pkgname = extract_pkgname(fd); 636 hash_file = xasprintf(hash_template, pkgname, 637 (long long)archive_entry_size(entry)); 638 free(pkgname); 639 640 for (i = 0; i < archive_entry_size(entry); i += block_len) { 641 if (i + (off_t)sizeof(block) < archive_entry_size(entry)) 642 block_len = sizeof(block); 643 else 644 block_len = archive_entry_size(entry) % sizeof(block); 645 if (read(fd, block, block_len) != (ssize_t)block_len) 646 err(2, "short read"); 647 hash_block(block, block_len, hash); 648 tmp = xasprintf("%s%s\n", hash_file, hash); 649 free(hash_file); 650 hash_file = tmp; 651 } 652 tmp = xasprintf("%s%s", hash_file, hash_trailer); 653 free(hash_file); 654 hash_file = tmp; 655 656 if (detached_gpg_sign(hash_file, strlen(hash_file), &signature_file, 657 &signature_len, gpg_keyring_sign, gpg_sign_as)) 658 err(EXIT_FAILURE, "Cannot sign hash file"); 659 660 lseek(fd, 0, SEEK_SET); 661 662 sign_entry = archive_entry_clone(entry); 663 hash_entry = archive_entry_clone(entry); 664 pkgname = strrchr(name, '/'); 665 archive_entry_set_pathname(entry, pkgname != NULL ? pkgname + 1 : name); 666 archive_entry_set_pathname(hash_entry, HASH_FNAME); 667 archive_entry_set_pathname(sign_entry, GPG_SIGNATURE_FNAME); 668 archive_entry_set_size(hash_entry, strlen(hash_file)); 669 archive_entry_set_size(sign_entry, signature_len); 670 671 pkg = archive_write_new(); 672 archive_write_set_format_ar_bsd(pkg); 673 archive_write_open_filename(pkg, output); 674 675 archive_write_header(pkg, hash_entry); 676 archive_write_data(pkg, hash_file, strlen(hash_file)); 677 archive_write_finish_entry(pkg); 678 archive_entry_free(hash_entry); 679 680 archive_write_header(pkg, sign_entry); 681 archive_write_data(pkg, signature_file, signature_len); 682 archive_write_finish_entry(pkg); 683 archive_entry_free(sign_entry); 684 685 size = archive_entry_size(entry); 686 archive_write_header(pkg, entry); 687 688 for (i = 0; i < size; i += block_len) { 689 if (i + (off_t)sizeof(block) < size) 690 block_len = sizeof(block); 691 else 692 block_len = size % sizeof(block); 693 if (read(fd, block, block_len) != (ssize_t)block_len) 694 err(2, "short read"); 695 archive_write_data(pkg, block, block_len); 696 } 697 archive_write_finish_entry(pkg); 698 archive_entry_free(entry); 699 700 archive_write_free(pkg); 701 702 close(fd); 703 704 exit(0); 705} 706