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