pkg_checksum.c
1 /* Copyright (c) 2014, Vsevolod Stakhov <vsevolod@FreeBSD.org> 2 * Copyright (c) 2014, Google Inc. 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions are met: 7 * * Redistributions of source code must retain the above copyright 8 * notice, this list of conditions and the following disclaimer. 9 * * 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 ''AS IS'' AND ANY 14 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 15 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 16 * DISCLAIMED. IN NO EVENT SHALL AUTHOR BE LIABLE FOR ANY 17 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 18 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 19 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 20 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 21 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 22 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 23 */ 24 25 #include <assert.h> 26 27 #include <sys/stat.h> 28 29 #include <fcntl.h> 30 #include <errno.h> 31 #include "pkg.h" 32 #include "private/pkg.h" 33 #include "private/event.h" 34 #include "sha256.h" 35 #include "blake2.h" 36 37 /* Separate checksum parts */ 38 #define PKG_CKSUM_SEPARATOR '$' 39 40 /* Hash is in format <version>:<typeid>:<hexhash> */ 41 #define PKG_CHECKSUM_SHA256_LEN (SHA256_BLOCK_SIZE * 2 + 1) 42 #define PKG_CHECKSUM_BLAKE2_LEN (BLAKE2B_OUTBYTES * 8 / 5 + sizeof("100") * 2 + 2) 43 #define PKG_CHECKSUM_BLAKE2S_LEN (BLAKE2S_OUTBYTES * 8 / 5 + sizeof("100") * 2 + 2) 44 #define PKG_CHECKSUM_CUR_VERSION 2 45 46 struct kv { 47 const char *key; 48 const char *value; 49 struct kv *next; 50 }; 51 52 static struct kv * 53 kv_new(const char *k, const char *v) 54 { 55 struct kv *kv = xcalloc(1, sizeof(*kv)); 56 kv->key = k; 57 kv->value = v; 58 return (kv); 59 } 60 61 typedef void (*pkg_checksum_hash_func)(struct kv *entries, 62 unsigned char **out, size_t *outlen); 63 typedef void (*pkg_checksum_hash_bulk_func)(const unsigned char *in, size_t inlen, 64 unsigned char **out, size_t *outlen); 65 typedef void (*pkg_checksum_encode_func)(unsigned char *in, size_t inlen, 66 char *out, size_t outlen); 67 68 typedef void (*pkg_checksum_hash_file_func)(int fd, unsigned char **out, 69 size_t *outlen); 70 71 static void pkg_checksum_hash_sha256(struct kv *entries, 72 unsigned char **out, size_t *outlen); 73 static void pkg_checksum_hash_sha256_bulk(const unsigned char *in, size_t inlen, 74 unsigned char **out, size_t *outlen); 75 static void pkg_checksum_hash_sha256_file(int fd, unsigned char **out, 76 size_t *outlen); 77 static void pkg_checksum_hash_blake2(struct kv *entries, 78 unsigned char **out, size_t *outlen); 79 static void pkg_checksum_hash_blake2_bulk(const unsigned char *in, size_t inlen, 80 unsigned char **out, size_t *outlen); 81 static void pkg_checksum_hash_blake2_file(int fd, unsigned char **out, 82 size_t *outlen); 83 static void pkg_checksum_hash_blake2s(struct kv *entries, 84 unsigned char **out, size_t *outlen); 85 static void pkg_checksum_hash_blake2s_bulk(const unsigned char *in, size_t inlen, 86 unsigned char **out, size_t *outlen); 87 static void pkg_checksum_hash_blake2s_file(int fd, unsigned char **out, 88 size_t *outlen); 89 static void pkg_checksum_encode_base32(unsigned char *in, size_t inlen, 90 char *out, size_t outlen); 91 static void pkg_checksum_encode_hex(unsigned char *in, size_t inlen, 92 char *out, size_t outlen); 93 94 static const struct _pkg_cksum_type { 95 const char *name; 96 size_t hlen; 97 pkg_checksum_hash_func hfunc; 98 pkg_checksum_hash_bulk_func hbulkfunc; 99 pkg_checksum_hash_file_func hfilefunc; 100 pkg_checksum_encode_func encfunc; 101 } checksum_types[] = { 102 [PKG_HASH_TYPE_SHA256_BASE32] = { 103 "sha256_base32", 104 PKG_CHECKSUM_SHA256_LEN, 105 pkg_checksum_hash_sha256, 106 pkg_checksum_hash_sha256_bulk, 107 pkg_checksum_hash_sha256_file, 108 pkg_checksum_encode_base32 109 }, 110 [PKG_HASH_TYPE_SHA256_HEX] = { 111 "sha256_hex", 112 PKG_CHECKSUM_SHA256_LEN, 113 pkg_checksum_hash_sha256, 114 pkg_checksum_hash_sha256_bulk, 115 pkg_checksum_hash_sha256_file, 116 pkg_checksum_encode_hex 117 }, 118 [PKG_HASH_TYPE_BLAKE2_BASE32] = { 119 "blake2_base32", 120 PKG_CHECKSUM_BLAKE2_LEN, 121 pkg_checksum_hash_blake2, 122 pkg_checksum_hash_blake2_bulk, 123 pkg_checksum_hash_blake2_file, 124 pkg_checksum_encode_base32 125 }, 126 [PKG_HASH_TYPE_SHA256_RAW] = { 127 "sha256_raw", 128 SHA256_BLOCK_SIZE, 129 pkg_checksum_hash_sha256, 130 pkg_checksum_hash_sha256_bulk, 131 pkg_checksum_hash_sha256_file, 132 NULL 133 }, 134 [PKG_HASH_TYPE_BLAKE2_RAW] = { 135 "blake2_raw", 136 BLAKE2B_OUTBYTES, 137 pkg_checksum_hash_blake2, 138 pkg_checksum_hash_blake2_bulk, 139 pkg_checksum_hash_blake2_file, 140 NULL 141 }, 142 [PKG_HASH_TYPE_BLAKE2S_BASE32] = { 143 "blake2s_base32", 144 PKG_CHECKSUM_BLAKE2S_LEN, 145 pkg_checksum_hash_blake2s, 146 pkg_checksum_hash_blake2s_bulk, 147 pkg_checksum_hash_blake2s_file, 148 pkg_checksum_encode_base32 149 }, 150 [PKG_HASH_TYPE_BLAKE2S_RAW] = { 151 "blake2s_raw", 152 BLAKE2S_OUTBYTES, 153 pkg_checksum_hash_blake2s, 154 pkg_checksum_hash_blake2s_bulk, 155 pkg_checksum_hash_blake2s_file, 156 NULL 157 }, 158 [PKG_HASH_TYPE_UNKNOWN] = { 159 NULL, 160 -1, 161 NULL, 162 NULL, 163 NULL, 164 NULL 165 } 166 }; 167 168 static int 169 pkg_checksum_entry_cmp(struct kv *e1, 170 struct kv *e2) 171 { 172 int r; 173 174 /* Compare field names first. */ 175 r = strcmp(e1->key, e2->key); 176 if (r != 0) 177 return r; 178 179 /* If field names are the same, compare values. */ 180 return (strcmp(e1->value, e2->value)); 181 } 182 183 /* 184 * At the moment we use the following fields to calculate the unique checksum 185 * of the following fields: 186 * - name 187 * - origin 188 * - version 189 * - arch 190 * - vital flag 191 * - options 192 * - required_shlibs 193 * - provided_shlibs 194 * - users 195 * - groups 196 * - dependencies 197 */ 198 199 int 200 pkg_checksum_generate(struct pkg *pkg, char *dest, size_t destlen, 201 pkg_checksum_type_t type, bool inc_scripts, bool inc_version, bool inc_files __unused) 202 { 203 unsigned char *bdigest; 204 char *olduid; 205 size_t blen; 206 struct kv *entries = NULL; 207 charv_t tofree = vec_init(); 208 struct pkg_option *option = NULL; 209 struct pkg_dep *dep = NULL; 210 struct pkg_file *f = NULL; 211 bool is_group = false; 212 213 if (pkg == NULL || type >= PKG_HASH_TYPE_UNKNOWN || 214 destlen < checksum_types[type].hlen) 215 return (EPKG_FATAL); 216 if (pkg_type(pkg) == PKG_GROUP_REMOTE || pkg_type(pkg) == PKG_GROUP_INSTALLED) 217 is_group = true; 218 219 LL_APPEND(entries, kv_new("name", pkg->name)); 220 if (!is_group) 221 LL_APPEND(entries, kv_new("origin", pkg->origin)); 222 if (inc_version && !is_group) 223 LL_APPEND(entries, kv_new("version", pkg->version)); 224 if (!is_group) 225 LL_APPEND(entries, kv_new("arch", pkg->altabi)); 226 227 LL_APPEND(entries, kv_new("vital", pkg->vital ? "1" : "0")); 228 229 while (pkg_options(pkg, &option) == EPKG_OK) { 230 LL_APPEND(entries, kv_new(option->key, option->value)); 231 } 232 233 vec_foreach(pkg->shlibs_required, i) { 234 LL_APPEND(entries, kv_new("required_shlib", pkg->shlibs_required.d[i])); 235 } 236 237 vec_foreach(pkg->shlibs_provided, i) { 238 LL_APPEND(entries, kv_new("provided_shlib", pkg->shlibs_provided.d[i])); 239 } 240 241 vec_foreach(pkg->users, i) { 242 LL_APPEND(entries, kv_new("user", pkg->users.d[i])); 243 } 244 245 vec_foreach(pkg->groups, i) { 246 LL_APPEND(entries, kv_new("group", pkg->groups.d[i])); 247 } 248 249 while (pkg_deps(pkg, &dep) == EPKG_OK) { 250 if (is_group) { 251 LL_APPEND(entries, kv_new("depend", dep->name)); 252 } else { 253 xasprintf(&olduid, "%s~%s", dep->name, dep->origin); 254 LL_APPEND(entries, kv_new("depend", olduid)); 255 vec_push(&tofree, olduid); 256 } 257 } 258 259 vec_foreach(pkg->provides, i) { 260 LL_APPEND(entries, kv_new("provide", pkg->provides.d[i])); 261 } 262 263 vec_foreach(pkg->requires, i) { 264 LL_APPEND(entries, kv_new("require", pkg->requires.d[i])); 265 } 266 267 if (inc_scripts) { 268 for (int i = 0; i < PKG_NUM_SCRIPTS; i++) { 269 if (pkg->scripts[i] != NULL) { 270 fflush(pkg->scripts[i]->fp); 271 LL_APPEND(entries, kv_new("script", pkg->scripts[i]->buf)); 272 } 273 } 274 for (int i = 0; i < PKG_NUM_LUA_SCRIPTS; i++) { 275 vec_foreach(pkg->lua_scripts[i], j) 276 LL_APPEND(entries, kv_new("lua_script", pkg->lua_scripts[i].d[j])); 277 } 278 } 279 280 while (pkg_files(pkg, &f) == EPKG_OK) { 281 LL_APPEND(entries, kv_new(f->path, f->sum != NULL ? f->sum : "" )); 282 } 283 284 /* Sort before hashing */ 285 LL_SORT(entries, pkg_checksum_entry_cmp); 286 287 checksum_types[type].hfunc(entries, &bdigest, &blen); 288 if (blen == 0 || bdigest == NULL) { 289 LL_FREE(entries, free); 290 vec_free_and_free(&tofree, free); 291 return (EPKG_FATAL); 292 } 293 294 if (checksum_types[type].encfunc) { 295 size_t i = snprintf(dest, destlen, "%d%c%d%c", PKG_CHECKSUM_CUR_VERSION, 296 PKG_CKSUM_SEPARATOR, type, PKG_CKSUM_SEPARATOR); 297 assert(i < destlen); 298 checksum_types[type].encfunc(bdigest, blen, dest + i, destlen - i); 299 } 300 else { 301 /* For raw formats we just output digest */ 302 assert(destlen >= blen); 303 memcpy(dest, bdigest, blen); 304 } 305 306 free(bdigest); 307 LL_FREE(entries, free); 308 vec_free_and_free(&tofree, free); 309 310 return (EPKG_OK); 311 } 312 313 bool 314 pkg_checksum_is_valid(const char *cksum, size_t clen) 315 { 316 const char *sep; 317 unsigned int value; 318 319 if (clen < 4) 320 return (false); 321 322 sep = strchr(cksum, PKG_CKSUM_SEPARATOR); 323 if (sep == NULL || *sep == '\0') 324 return (false); 325 326 /* Test version */ 327 value = strtoul(cksum, NULL, 10); 328 if (value != PKG_CHECKSUM_CUR_VERSION) 329 return (false); 330 331 cksum = sep + 1; 332 sep = strchr(cksum, PKG_CKSUM_SEPARATOR); 333 if (sep == NULL || *sep == '\0') 334 return (false); 335 336 /* Test type */ 337 value = strtoul(cksum, NULL, 10); 338 if (value >= PKG_HASH_TYPE_UNKNOWN) 339 return (false); 340 341 return (true); 342 } 343 344 /* <hashtype>$<hash> */ 345 pkg_checksum_type_t 346 pkg_checksum_file_get_type(const char *cksum, size_t clen __unused) 347 { 348 unsigned int value; 349 350 if (cksum == NULL || strchr(cksum, PKG_CKSUM_SEPARATOR) == NULL) 351 return (PKG_HASH_TYPE_UNKNOWN); 352 353 value = strtoul(cksum, NULL, 10); 354 if (value < PKG_HASH_TYPE_UNKNOWN) 355 return (value); 356 357 return (PKG_HASH_TYPE_UNKNOWN); 358 } 359 360 /* <version>$<hashtype>$<hash> */ 361 pkg_checksum_type_t 362 pkg_checksum_get_type(const char *cksum, size_t clen __unused) 363 { 364 const char *sep; 365 unsigned int value; 366 367 sep = strchr(cksum, PKG_CKSUM_SEPARATOR); 368 if (sep != NULL && *sep != '\0') { 369 value = strtoul(sep + 1, NULL, 10); 370 if (value < PKG_HASH_TYPE_UNKNOWN) 371 return (value); 372 } 373 374 return (PKG_HASH_TYPE_UNKNOWN); 375 } 376 377 static void 378 pkg_checksum_hash_sha256(struct kv *entries, 379 unsigned char **out, size_t *outlen) 380 { 381 SHA256_CTX sign_ctx; 382 struct kv *e; 383 384 sha256_init(&sign_ctx); 385 386 LL_FOREACH(entries, e) { 387 sha256_update(&sign_ctx, e->key, strlen(e->key)); 388 sha256_update(&sign_ctx, e->value, strlen(e->value)); 389 } 390 *out = xmalloc(SHA256_BLOCK_SIZE); 391 sha256_final(&sign_ctx, *out); 392 *outlen = SHA256_BLOCK_SIZE; 393 } 394 395 static void 396 pkg_checksum_hash_sha256_bulk(const unsigned char *in, size_t inlen, 397 unsigned char **out, size_t *outlen) 398 { 399 SHA256_CTX sign_ctx; 400 401 *out = xmalloc(SHA256_BLOCK_SIZE); 402 sha256_init(&sign_ctx); 403 sha256_update(&sign_ctx, in, inlen); 404 sha256_final(&sign_ctx, *out); 405 *outlen = SHA256_BLOCK_SIZE; 406 } 407 408 static void 409 pkg_checksum_hash_sha256_file(int fd, unsigned char **out, size_t *outlen) 410 { 411 char buffer[8192]; 412 ssize_t r; 413 414 SHA256_CTX sign_ctx; 415 *out = xmalloc(SHA256_BLOCK_SIZE); 416 sha256_init(&sign_ctx); 417 while ((r = read(fd, buffer, sizeof(buffer))) > 0) 418 sha256_update(&sign_ctx, buffer, r); 419 if (r < 0) { 420 pkg_emit_errno(__func__, "read failed"); 421 free(*out); 422 *out = NULL; 423 return; 424 } 425 sha256_final(&sign_ctx, *out); 426 *outlen = SHA256_BLOCK_SIZE; 427 } 428 429 static void 430 pkg_checksum_hash_blake2(struct kv *entries, 431 unsigned char **out, size_t *outlen) 432 { 433 blake2b_state st; 434 struct kv *e; 435 436 blake2b_init (&st, BLAKE2B_OUTBYTES); 437 438 LL_FOREACH(entries, e) { 439 blake2b_update (&st, e->key, strlen(e->key)); 440 blake2b_update (&st, e->value, strlen(e->value)); 441 } 442 *out = xmalloc(BLAKE2B_OUTBYTES); 443 blake2b_final (&st, *out, BLAKE2B_OUTBYTES); 444 *outlen = BLAKE2B_OUTBYTES; 445 } 446 447 static void 448 pkg_checksum_hash_blake2_bulk(const unsigned char *in, size_t inlen, 449 unsigned char **out, size_t *outlen) 450 { 451 *out = xmalloc(BLAKE2B_OUTBYTES); 452 blake2b(*out, BLAKE2B_OUTBYTES, in, inlen, NULL, 0); 453 *outlen = BLAKE2B_OUTBYTES; 454 } 455 456 static void 457 pkg_checksum_hash_blake2_file(int fd, unsigned char **out, size_t *outlen) 458 { 459 char buffer[8192]; 460 ssize_t r; 461 462 blake2b_state st; 463 blake2b_init(&st, BLAKE2B_OUTBYTES); 464 465 while ((r = read(fd, buffer, sizeof(buffer))) > 0) 466 blake2b_update(&st, buffer, r); 467 if (r < 0) { 468 pkg_emit_errno(__func__, "read failed"); 469 free(*out); 470 *out = NULL; 471 return; 472 } 473 *out = xmalloc(BLAKE2B_OUTBYTES); 474 blake2b_final(&st, *out, BLAKE2B_OUTBYTES); 475 *outlen = BLAKE2B_OUTBYTES; 476 } 477 478 static void 479 pkg_checksum_hash_blake2s(struct kv *entries, 480 unsigned char **out, size_t *outlen) 481 { 482 blake2s_state st; 483 struct kv *e; 484 485 blake2s_init (&st, BLAKE2S_OUTBYTES); 486 487 LL_FOREACH(entries, e) { 488 blake2s_update (&st, e->key, strlen(e->key)); 489 blake2s_update (&st, e->value, strlen(e->value)); 490 } 491 *out = xmalloc(BLAKE2S_OUTBYTES); 492 blake2s_final (&st, *out, BLAKE2S_OUTBYTES); 493 *outlen = BLAKE2S_OUTBYTES; 494 } 495 496 static void 497 pkg_checksum_hash_blake2s_bulk(const unsigned char *in, size_t inlen, 498 unsigned char **out, size_t *outlen) 499 { 500 *out = xmalloc(BLAKE2S_OUTBYTES); 501 blake2s(*out, BLAKE2S_OUTBYTES, in, inlen, NULL, 0); 502 *outlen = BLAKE2S_OUTBYTES; 503 } 504 505 static void 506 pkg_checksum_hash_blake2s_file(int fd, unsigned char **out, size_t *outlen) 507 { 508 char buffer[8192]; 509 ssize_t r; 510 511 blake2s_state st; 512 blake2s_init(&st, BLAKE2S_OUTBYTES); 513 514 while ((r = read(fd, buffer, sizeof(buffer))) > 0) 515 blake2s_update(&st, buffer, r); 516 if (r < 0) { 517 pkg_emit_errno(__func__, "read failed"); 518 free(*out); 519 *out = NULL; 520 return; 521 } 522 *out = xmalloc(BLAKE2S_OUTBYTES); 523 blake2s_final(&st, *out, BLAKE2S_OUTBYTES); 524 *outlen = BLAKE2S_OUTBYTES; 525 } 526 527 /* 528 * We use here z-base32 encoding described here: 529 * http://philzimmermann.com/docs/human-oriented-base-32-encoding.txt 530 */ 531 static const char b32[]="ybndrfg8ejkmcpqxot1uwisza345h769"; 532 533 534 static void 535 pkg_checksum_encode_base32(unsigned char *in, size_t inlen, 536 char *out, size_t outlen) 537 { 538 size_t i; 539 int remain = -1, r, x; 540 541 if (outlen < inlen * 8 / 5) { 542 pkg_emit_error("cannot encode base32 as outlen is not sufficient"); 543 return; 544 } 545 546 for (i = 0, r = 0; i < inlen; i++) { 547 switch (i % 5) { 548 case 0: 549 /* 8 bits of input and 3 to remain */ 550 x = in[i]; 551 remain = in[i] >> 5; 552 out[r++] = b32[x & 0x1F]; 553 break; 554 case 1: 555 /* 11 bits of input, 1 to remain */ 556 x = remain | in[i] << 3; 557 out[r++] = b32[x & 0x1F]; 558 out[r++] = b32[x >> 5 & 0x1F]; 559 remain = x >> 10; 560 break; 561 case 2: 562 /* 9 bits of input, 4 to remain */ 563 x = remain | in[i] << 1; 564 out[r++] = b32[x & 0x1F]; 565 remain = x >> 5; 566 break; 567 case 3: 568 /* 12 bits of input, 2 to remain */ 569 x = remain | in[i] << 4; 570 out[r++] = b32[x & 0x1F]; 571 out[r++] = b32[x >> 5 & 0x1F]; 572 remain = x >> 10 & 0x3; 573 break; 574 case 4: 575 /* 10 bits of output, nothing to remain */ 576 x = remain | in[i] << 2; 577 out[r++] = b32[x & 0x1F]; 578 out[r++] = b32[x >> 5 & 0x1F]; 579 remain = -1; 580 break; 581 default: 582 /* Not to be happen */ 583 break; 584 } 585 586 } 587 if (remain >= 0) 588 out[r++] = b32[remain]; 589 590 out[r] = 0; 591 } 592 593 static void 594 pkg_checksum_encode_hex(unsigned char *in, size_t inlen, 595 char *out, size_t outlen) 596 { 597 size_t i; 598 599 if (outlen < inlen * 2) { 600 pkg_emit_error("cannot encode hex as outlen is not sufficient"); 601 return; 602 } 603 604 for (i = 0; i < inlen; i++) 605 sprintf(out + (i * 2), "%02x", in[i]); 606 607 out[inlen * 2] = '\0'; 608 } 609 610 pkg_checksum_type_t 611 pkg_checksum_type_from_string(const char *name) 612 { 613 int i; 614 for (i = 0; i < PKG_HASH_TYPE_UNKNOWN; i ++) { 615 if (STRIEQ(name, checksum_types[i].name)) 616 return (i); 617 } 618 619 return (PKG_HASH_TYPE_UNKNOWN); 620 } 621 622 const char* 623 pkg_checksum_type_to_string(pkg_checksum_type_t type) 624 { 625 return (checksum_types[type].name); 626 } 627 628 size_t 629 pkg_checksum_type_size(pkg_checksum_type_t type) 630 { 631 return (checksum_types[type].hlen); 632 } 633 634 int 635 pkg_checksum_calculate(struct pkg *pkg, struct pkgdb *db, bool inc_scripts, 636 bool inc_version, bool inc_files) 637 { 638 char *new_digest; 639 struct pkg_repo *repo; 640 int rc = EPKG_OK; 641 pkg_checksum_type_t type; 642 643 if (sizeof(void *) == 8) 644 type = PKG_HASH_TYPE_BLAKE2_BASE32; 645 else 646 type = PKG_HASH_TYPE_BLAKE2S_BASE32; 647 648 if (pkg->reponame != NULL) { 649 repo = pkg_repo_find(pkg->reponame); 650 651 if (repo != NULL) 652 type = repo->meta->digest_format; 653 } 654 655 new_digest = xmalloc(pkg_checksum_type_size(type)); 656 if (pkg_checksum_generate(pkg, new_digest, pkg_checksum_type_size(type), 657 type, inc_scripts, inc_version, inc_files) 658 != EPKG_OK) { 659 free(new_digest); 660 return (EPKG_FATAL); 661 } 662 663 free(pkg->digest); 664 pkg->digest = new_digest; 665 666 if (db != NULL) 667 pkgdb_set_pkg_digest(db, pkg); 668 669 return (rc); 670 } 671 672 673 unsigned char * 674 pkg_checksum_data(const unsigned char *in, size_t inlen, 675 pkg_checksum_type_t type) 676 { 677 const struct _pkg_cksum_type *cksum; 678 unsigned char *out, *res = NULL; 679 size_t outlen; 680 681 if (type >= PKG_HASH_TYPE_UNKNOWN || in == NULL) 682 return (NULL); 683 684 /* Zero terminated string */ 685 if (inlen == 0) { 686 inlen = strlen(in); 687 } 688 689 cksum = &checksum_types[type]; 690 691 cksum->hbulkfunc(in, inlen, &out, &outlen); 692 if (out != NULL) { 693 if (cksum->encfunc != NULL) { 694 res = xmalloc(cksum->hlen); 695 cksum->encfunc(out, outlen, res, cksum->hlen); 696 free(out); 697 } 698 else { 699 res = out; 700 } 701 } 702 703 return (res); 704 } 705 706 unsigned char * 707 pkg_checksum_fileat(int rootfd, const char *path, pkg_checksum_type_t type) 708 { 709 int fd; 710 unsigned char *ret; 711 712 if ((fd = openat(rootfd, path, O_RDONLY)) == -1) { 713 pkg_emit_errno("open", path); 714 return (NULL); 715 } 716 717 ret = pkg_checksum_fd(fd, type); 718 719 close(fd); 720 721 return (ret); 722 } 723 724 unsigned char * 725 pkg_checksum_file(const char *path, pkg_checksum_type_t type) 726 { 727 return pkg_checksum_fileat(AT_FDCWD, path, type); 728 } 729 730 unsigned char * 731 pkg_checksum_fd(int fd, pkg_checksum_type_t type) 732 { 733 const struct _pkg_cksum_type *cksum; 734 unsigned char *out, *res = NULL; 735 size_t outlen; 736 737 if (type >= PKG_HASH_TYPE_UNKNOWN || fd < 0) 738 return (NULL); 739 740 cksum = &checksum_types[type]; 741 cksum->hfilefunc(fd, &out, &outlen); 742 if (out != NULL) { 743 if (cksum->encfunc != NULL) { 744 res = xmalloc(cksum->hlen); 745 cksum->encfunc(out, outlen, res, cksum->hlen); 746 free(out); 747 } else { 748 res = out; 749 } 750 } 751 752 return (res); 753 } 754 755 static unsigned char * 756 pkg_checksum_symlink_readlink(const char *linkbuf, int linklen, 757 pkg_checksum_type_t type) 758 { 759 const char *lnk; 760 761 lnk = linkbuf; 762 763 /* 764 * It is known that \0 is added to the checksum in case the symlink 765 * targets an absolute path but the behaviour is kept for compat 766 */ 767 return (pkg_checksum_data(RELATIVE_PATH(lnk), linklen, type)); 768 } 769 770 unsigned char * 771 pkg_checksum_symlink(const char *path, pkg_checksum_type_t type) 772 { 773 return pkg_checksum_symlinkat(AT_FDCWD, path, type); 774 } 775 776 unsigned char * 777 pkg_checksum_symlinkat(int fd, const char *path, pkg_checksum_type_t type) 778 { 779 char linkbuf[MAXPATHLEN]; 780 int linklen; 781 782 if ((linklen = readlinkat(fd, path, linkbuf, sizeof(linkbuf) - 1)) == -1) { 783 pkg_emit_errno("pkg_checksum_symlinkat", "readlink failed"); 784 return (NULL); 785 } 786 linkbuf[linklen] = '\0'; 787 788 return (pkg_checksum_symlink_readlink(linkbuf, linklen, type)); 789 } 790 791 int 792 pkg_checksum_validate_file(const char *path, const char *sum) 793 { 794 return pkg_checksum_validate_fileat(AT_FDCWD, path, sum); 795 } 796 797 int 798 pkg_checksum_validate_fileat(int rootfd, const char *path, const char *sum) 799 { 800 struct stat st; 801 char *newsum; 802 pkg_checksum_type_t type; 803 804 type = pkg_checksum_file_get_type(sum, strlen(sum)); 805 if (type == PKG_HASH_TYPE_UNKNOWN) { 806 type = PKG_HASH_TYPE_SHA256_HEX; 807 } else { 808 sum = strchr(sum, PKG_CKSUM_SEPARATOR); 809 if (sum != NULL) 810 sum++; 811 } 812 813 if (fstatat(rootfd, path, &st, AT_SYMLINK_NOFOLLOW) == -1) { 814 return (errno); 815 } 816 817 if (S_ISLNK(st.st_mode)) 818 newsum = pkg_checksum_symlinkat(rootfd, path, type); 819 else 820 newsum = pkg_checksum_fileat(rootfd, path, type); 821 822 if (newsum == NULL) 823 return (-1); 824 825 if (!STREQ(sum, newsum)) { 826 free(newsum); 827 return (-1); 828 } 829 830 free(newsum); 831 832 return (0); 833 } 834 835 char * 836 pkg_checksum_generate_file(const char *path, pkg_checksum_type_t type) 837 { 838 return pkg_checksum_generate_fileat(AT_FDCWD, path, type); 839 } 840 841 char * 842 pkg_checksum_generate_fileat(int rootfd, const char *path, 843 pkg_checksum_type_t type) 844 { 845 struct stat st; 846 unsigned char *sum; 847 char *cksum; 848 849 if (fstatat(rootfd, path, &st, AT_SYMLINK_NOFOLLOW) == -1) { 850 pkg_emit_errno("pkg_checksum_generate_file", "lstat"); 851 return (NULL); 852 } 853 854 if (S_ISLNK(st.st_mode)) 855 sum = pkg_checksum_symlinkat(rootfd, path, type); 856 else 857 sum = pkg_checksum_fileat(rootfd, path, type); 858 859 if (sum == NULL) 860 return (NULL); 861 862 xasprintf(&cksum, "%d%c%s", type, PKG_CKSUM_SEPARATOR, sum); 863 free(sum); 864 865 return (cksum); 866 }