1 /*- 2 * Copyright (c) 2009 The NetBSD Foundation, Inc. 3 * All rights reserved. 4 * 5 * This code is derived from software contributed to The NetBSD Foundation 6 * by Alistair Crooks (agc@NetBSD.org) 7 * 8 * Redistribution and use in source and binary forms, with or without 9 * modification, are permitted provided that the following conditions 10 * are met: 11 * 1. Redistributions of source code must retain the above copyright 12 * notice, this list of conditions and the following disclaimer. 13 * 2. Redistributions in binary form must reproduce the above copyright 14 * notice, this list of conditions and the following disclaimer in the 15 * documentation and/or other materials provided with the distribution. 16 * 17 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 18 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 19 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 20 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 21 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 22 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 23 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 24 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 25 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 26 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 27 * POSSIBILITY OF SUCH DAMAGE. 28 */ 29 /* 30 * Copyright (c) 2005-2008 Nominet UK (www.nic.uk) 31 * All rights reserved. 32 * Contributors: Ben Laurie, Rachel Willmer. The Contributors have asserted 33 * their moral rights under the UK Copyright Design and Patents Act 1988 to 34 * be recorded as the authors of this copyright work. 35 * 36 * Licensed under the Apache License, Version 2.0 (the "License"); you may not 37 * use this file except in compliance with the License. 38 * 39 * You may obtain a copy of the License at 40 * http://www.apache.org/licenses/LICENSE-2.0 41 * 42 * Unless required by applicable law or agreed to in writing, software 43 * distributed under the License is distributed on an "AS IS" BASIS, 44 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 45 * 46 * See the License for the specific language governing permissions and 47 * limitations under the License. 48 */ 49 #include "config.h" 50 51 #ifdef HAVE_SYS_CDEFS_H 52 #include <sys/cdefs.h> 53 #endif 54 55 #if defined(__NetBSD__) 56 __COPYRIGHT("@(#) Copyright (c) 2009 The NetBSD Foundation, Inc. All rights reserved."); 57 __RCSID("$NetBSD: validate.c,v 1.44 2012/03/05 02:20:18 christos Exp $"); 58 #endif 59 60 #include <sys/types.h> 61 #include <sys/param.h> 62 #include <sys/stat.h> 63 64 #include <string.h> 65 #include <stdio.h> 66 67 #ifdef HAVE_UNISTD_H 68 #include <unistd.h> 69 #endif 70 71 #ifdef HAVE_FCNTL_H 72 #include <fcntl.h> 73 #endif 74 75 #include "packet-parse.h" 76 #include "packet-show.h" 77 #include "keyring.h" 78 #include "signature.h" 79 #include "netpgpsdk.h" 80 #include "readerwriter.h" 81 #include "netpgpdefs.h" 82 #include "memory.h" 83 #include "packet.h" 84 #include "crypto.h" 85 #include "validate.h" 86 87 #ifdef HAVE_FCNTL_H 88 #include <fcntl.h> 89 #endif 90 91 92 static int 93 keydata_reader(pgp_stream_t *stream, void *dest, size_t length, pgp_error_t **errors, 94 pgp_reader_t *readinfo, 95 pgp_cbdata_t *cbinfo) 96 { 97 validate_reader_t *reader = pgp_reader_get_arg(readinfo); 98 99 __PGP_USED(stream); 100 __PGP_USED(errors); 101 __PGP_USED(cbinfo); 102 if (reader->offset == reader->key->packets[reader->packet].length) { 103 reader->packet += 1; 104 reader->offset = 0; 105 } 106 if (reader->packet == reader->key->packetc) { 107 return 0; 108 } 109 110 /* 111 * we should never be asked to cross a packet boundary in a single 112 * read 113 */ 114 if (reader->key->packets[reader->packet].length < 115 reader->offset + length) { 116 (void) fprintf(stderr, "keydata_reader: weird length\n"); 117 return 0; 118 } 119 120 (void) memcpy(dest, 121 &reader->key->packets[reader->packet].raw[reader->offset], 122 length); 123 reader->offset += (unsigned)length; 124 125 return (int)length; 126 } 127 128 static void 129 free_sig_info(pgp_sig_info_t *sig) 130 { 131 free(sig->v4_hashed); 132 free(sig); 133 } 134 135 static void 136 copy_sig_info(pgp_sig_info_t *dst, const pgp_sig_info_t *src) 137 { 138 (void) memcpy(dst, src, sizeof(*src)); 139 if ((dst->v4_hashed = calloc(1, src->v4_hashlen)) == NULL) { 140 (void) fprintf(stderr, "copy_sig_info: bad alloc\n"); 141 } else { 142 (void) memcpy(dst->v4_hashed, src->v4_hashed, src->v4_hashlen); 143 } 144 } 145 146 static int 147 add_sig_to_list(const pgp_sig_info_t *sig, pgp_sig_info_t **sigs, 148 unsigned *count) 149 { 150 pgp_sig_info_t *newsigs; 151 152 if (*count == 0) { 153 newsigs = calloc(*count + 1, sizeof(pgp_sig_info_t)); 154 } else { 155 newsigs = realloc(*sigs, 156 (*count + 1) * sizeof(pgp_sig_info_t)); 157 } 158 if (newsigs == NULL) { 159 (void) fprintf(stderr, "add_sig_to_list: alloc failure\n"); 160 return 0; 161 } 162 *sigs = newsigs; 163 copy_sig_info(&(*sigs)[*count], sig); 164 *count += 1; 165 return 1; 166 } 167 168 /* 169 The hash value is calculated by the following method: 170 + hash the data using the given digest algorithm 171 + hash the hash value onto the end 172 + hash the trailer - 6 bytes 173 [PGP_V4][0xff][len >> 24][len >> 16][len >> 8][len & 0xff] 174 to give the final hash value that is checked against the one in the signature 175 */ 176 177 /* Does the signed hash match the given hash? */ 178 unsigned 179 check_binary_sig(const uint8_t *data, 180 const unsigned len, 181 const pgp_sig_t *sig, 182 const pgp_pubkey_t *signer) 183 { 184 unsigned hashedlen; 185 pgp_hash_t hash; 186 unsigned n; 187 uint8_t hashout[PGP_MAX_HASH_SIZE]; 188 uint8_t trailer[6]; 189 190 pgp_hash_any(&hash, sig->info.hash_alg); 191 if (!hash.init(&hash)) { 192 (void) fprintf(stderr, "check_binary_sig: bad hash init\n"); 193 return 0; 194 } 195 hash.add(&hash, data, len); 196 switch (sig->info.version) { 197 case PGP_V3: 198 trailer[0] = sig->info.type; 199 trailer[1] = (unsigned)(sig->info.birthtime) >> 24; 200 trailer[2] = (unsigned)(sig->info.birthtime) >> 16; 201 trailer[3] = (unsigned)(sig->info.birthtime) >> 8; 202 trailer[4] = (uint8_t)(sig->info.birthtime); 203 hash.add(&hash, trailer, 5); 204 break; 205 206 case PGP_V4: 207 if (pgp_get_debug_level(__FILE__)) { 208 hexdump(stderr, "v4 hash", sig->info.v4_hashed, 209 sig->info.v4_hashlen); 210 } 211 hash.add(&hash, sig->info.v4_hashed, (unsigned)sig->info.v4_hashlen); 212 trailer[0] = 0x04; /* version */ 213 trailer[1] = 0xFF; 214 hashedlen = (unsigned)sig->info.v4_hashlen; 215 trailer[2] = (uint8_t)(hashedlen >> 24); 216 trailer[3] = (uint8_t)(hashedlen >> 16); 217 trailer[4] = (uint8_t)(hashedlen >> 8); 218 trailer[5] = (uint8_t)(hashedlen); 219 hash.add(&hash, trailer, 6); 220 break; 221 222 default: 223 (void) fprintf(stderr, "Invalid signature version %d\n", 224 sig->info.version); 225 return 0; 226 } 227 228 n = hash.finish(&hash, hashout); 229 if (pgp_get_debug_level(__FILE__)) { 230 hexdump(stdout, "hash out", hashout, n); 231 } 232 return pgp_check_sig(hashout, n, sig, signer); 233 } 234 235 pgp_cb_ret_t 236 pgp_validate_key_cb(const pgp_packet_t *pkt, pgp_cbdata_t *cbinfo) 237 { 238 const pgp_contents_t *content = &pkt->u; 239 const pgp_key_t *signer; 240 validate_key_cb_t *key; 241 pgp_pubkey_t *sigkey; 242 pgp_error_t **errors; 243 pgp_io_t *io; 244 unsigned from; 245 unsigned valid = 0; 246 247 io = cbinfo->io; 248 if (pgp_get_debug_level(__FILE__)) { 249 (void) fprintf(io->errs, "%s\n", 250 pgp_show_packet_tag(pkt->tag)); 251 } 252 key = pgp_callback_arg(cbinfo); 253 errors = pgp_callback_errors(cbinfo); 254 switch (pkt->tag) { 255 case PGP_PTAG_CT_PUBLIC_KEY: 256 if (key->pubkey.version != 0) { 257 (void) fprintf(io->errs, 258 "pgp_validate_key_cb: version bad\n"); 259 return PGP_FINISHED; 260 } 261 key->pubkey = content->pubkey; 262 return PGP_KEEP_MEMORY; 263 264 case PGP_PTAG_CT_PUBLIC_SUBKEY: 265 if (key->subkey.version) { 266 pgp_pubkey_free(&key->subkey); 267 } 268 key->subkey = content->pubkey; 269 return PGP_KEEP_MEMORY; 270 271 case PGP_PTAG_CT_SECRET_KEY: 272 key->seckey = content->seckey; 273 key->pubkey = key->seckey.pubkey; 274 return PGP_KEEP_MEMORY; 275 276 case PGP_PTAG_CT_USER_ID: 277 if (key->userid) { 278 pgp_userid_free(&key->userid); 279 } 280 key->userid = content->userid; 281 key->last_seen = ID; 282 return PGP_KEEP_MEMORY; 283 284 case PGP_PTAG_CT_USER_ATTR: 285 if (content->userattr.len == 0) { 286 (void) fprintf(io->errs, 287 "pgp_validate_key_cb: user attribute length 0"); 288 return PGP_FINISHED; 289 } 290 (void) fprintf(io->outs, "user attribute, length=%d\n", 291 (int) content->userattr.len); 292 if (key->userattr.len) { 293 pgp_data_free(&key->userattr); 294 } 295 key->userattr = content->userattr; 296 key->last_seen = ATTRIBUTE; 297 return PGP_KEEP_MEMORY; 298 299 case PGP_PTAG_CT_SIGNATURE: /* V3 sigs */ 300 case PGP_PTAG_CT_SIGNATURE_FOOTER: /* V4 sigs */ 301 from = 0; 302 signer = pgp_getkeybyid(io, key->keyring, 303 content->sig.info.signer_id, 304 &from, &sigkey); 305 if (!signer) { 306 if (!add_sig_to_list(&content->sig.info, 307 &key->result->unknown_sigs, 308 &key->result->unknownc)) { 309 (void) fprintf(io->errs, 310 "pgp_validate_key_cb: user attribute length 0"); 311 return PGP_FINISHED; 312 } 313 break; 314 } 315 if (sigkey == &signer->enckey) { 316 (void) fprintf(io->errs, 317 "WARNING: signature made with encryption key\n"); 318 } 319 switch (content->sig.info.type) { 320 case PGP_CERT_GENERIC: 321 case PGP_CERT_PERSONA: 322 case PGP_CERT_CASUAL: 323 case PGP_CERT_POSITIVE: 324 case PGP_SIG_REV_CERT: 325 valid = (key->last_seen == ID) ? 326 pgp_check_useridcert_sig(&key->pubkey, 327 key->userid, 328 &content->sig, 329 pgp_get_pubkey(signer), 330 key->reader->key->packets[ 331 key->reader->packet].raw) : 332 pgp_check_userattrcert_sig(&key->pubkey, 333 &key->userattr, 334 &content->sig, 335 pgp_get_pubkey(signer), 336 key->reader->key->packets[ 337 key->reader->packet].raw); 338 break; 339 340 case PGP_SIG_SUBKEY: 341 /* 342 * XXX: we should also check that the signer is the 343 * key we are validating, I think. 344 */ 345 valid = pgp_check_subkey_sig(&key->pubkey, 346 &key->subkey, 347 &content->sig, 348 pgp_get_pubkey(signer), 349 key->reader->key->packets[ 350 key->reader->packet].raw); 351 break; 352 353 case PGP_SIG_DIRECT: 354 valid = pgp_check_direct_sig(&key->pubkey, 355 &content->sig, 356 pgp_get_pubkey(signer), 357 key->reader->key->packets[ 358 key->reader->packet].raw); 359 break; 360 361 case PGP_SIG_STANDALONE: 362 case PGP_SIG_PRIMARY: 363 case PGP_SIG_REV_KEY: 364 case PGP_SIG_REV_SUBKEY: 365 case PGP_SIG_TIMESTAMP: 366 case PGP_SIG_3RD_PARTY: 367 PGP_ERROR_1(errors, PGP_E_UNIMPLEMENTED, 368 "Sig Verification type 0x%02x not done yet\n", 369 content->sig.info.type); 370 break; 371 372 default: 373 PGP_ERROR_1(errors, PGP_E_UNIMPLEMENTED, 374 "Unexpected signature type 0x%02x\n", 375 content->sig.info.type); 376 } 377 378 if (valid) { 379 if (!add_sig_to_list(&content->sig.info, 380 &key->result->valid_sigs, 381 &key->result->validc)) { 382 PGP_ERROR_1(errors, PGP_E_UNIMPLEMENTED, "%s", 383 "Can't add good sig to list\n"); 384 } 385 } else { 386 PGP_ERROR_1(errors, PGP_E_V_BAD_SIGNATURE, "%s", 387 "Bad Sig"); 388 if (!add_sig_to_list(&content->sig.info, 389 &key->result->invalid_sigs, 390 &key->result->invalidc)) { 391 PGP_ERROR_1(errors, PGP_E_UNIMPLEMENTED, "%s", 392 "Can't add good sig to list\n"); 393 } 394 } 395 break; 396 397 /* ignore these */ 398 case PGP_PARSER_PTAG: 399 case PGP_PTAG_CT_SIGNATURE_HEADER: 400 case PGP_PARSER_PACKET_END: 401 break; 402 403 case PGP_GET_PASSPHRASE: 404 if (key->getpassphrase) { 405 return key->getpassphrase(pkt, cbinfo); 406 } 407 break; 408 409 case PGP_PTAG_CT_TRUST: 410 /* 1 byte for level (depth), 1 byte for trust amount */ 411 printf("trust dump\n"); 412 printf("Got trust\n"); 413 //hexdump(stdout, (const uint8_t *)content->trust.data, 10, " "); 414 //hexdump(stdout, (const uint8_t *)&content->ss_trust, 2, " "); 415 //printf("Trust level %d, amount %d\n", key->trust.level, key->trust.amount); 416 break; 417 418 default: 419 (void) fprintf(stderr, "unexpected tag=0x%x\n", pkt->tag); 420 return PGP_FINISHED; 421 } 422 return PGP_RELEASE_MEMORY; 423 } 424 425 pgp_cb_ret_t 426 validate_data_cb(const pgp_packet_t *pkt, pgp_cbdata_t *cbinfo) 427 { 428 const pgp_contents_t *content = &pkt->u; 429 const pgp_key_t *signer; 430 validate_data_cb_t *data; 431 pgp_pubkey_t *sigkey; 432 pgp_error_t **errors; 433 pgp_io_t *io; 434 unsigned from; 435 unsigned valid = 0; 436 437 io = cbinfo->io; 438 if (pgp_get_debug_level(__FILE__)) { 439 (void) fprintf(io->errs, "validate_data_cb: %s\n", 440 pgp_show_packet_tag(pkt->tag)); 441 } 442 data = pgp_callback_arg(cbinfo); 443 errors = pgp_callback_errors(cbinfo); 444 switch (pkt->tag) { 445 case PGP_PTAG_CT_SIGNED_CLEARTEXT_HEADER: 446 /* 447 * ignore - this gives us the "Armor Header" line "Hash: 448 * SHA1" or similar 449 */ 450 break; 451 452 case PGP_PTAG_CT_LITDATA_HEADER: 453 /* ignore */ 454 break; 455 456 case PGP_PTAG_CT_LITDATA_BODY: 457 data->data.litdata_body = content->litdata_body; 458 data->type = LITDATA; 459 pgp_memory_add(data->mem, data->data.litdata_body.data, 460 data->data.litdata_body.length); 461 return PGP_KEEP_MEMORY; 462 463 case PGP_PTAG_CT_SIGNED_CLEARTEXT_BODY: 464 data->data.cleartext_body = content->cleartext_body; 465 data->type = SIGNED_CLEARTEXT; 466 pgp_memory_add(data->mem, data->data.cleartext_body.data, 467 data->data.cleartext_body.length); 468 return PGP_KEEP_MEMORY; 469 470 case PGP_PTAG_CT_SIGNED_CLEARTEXT_TRAILER: 471 /* this gives us an pgp_hash_t struct */ 472 break; 473 474 case PGP_PTAG_CT_SIGNATURE: /* V3 sigs */ 475 case PGP_PTAG_CT_SIGNATURE_FOOTER: /* V4 sigs */ 476 if (pgp_get_debug_level(__FILE__)) { 477 hexdump(io->outs, "hashed data", content->sig.info.v4_hashed, 478 content->sig.info.v4_hashlen); 479 hexdump(io->outs, "signer id", content->sig.info.signer_id, 480 sizeof(content->sig.info.signer_id)); 481 } 482 from = 0; 483 signer = pgp_getkeybyid(io, data->keyring, 484 content->sig.info.signer_id, &from, &sigkey); 485 if (!signer) { 486 PGP_ERROR_1(errors, PGP_E_V_UNKNOWN_SIGNER, 487 "%s", "Unknown Signer"); 488 if (!add_sig_to_list(&content->sig.info, 489 &data->result->unknown_sigs, 490 &data->result->unknownc)) { 491 PGP_ERROR_1(errors, PGP_E_V_UNKNOWN_SIGNER, 492 "%s", "Can't add unknown sig to list"); 493 } 494 break; 495 } 496 if (sigkey == &signer->enckey) { 497 (void) fprintf(io->errs, 498 "WARNING: signature made with encryption key\n"); 499 } 500 if (content->sig.info.birthtime_set) { 501 data->result->birthtime = content->sig.info.birthtime; 502 } 503 if (content->sig.info.duration_set) { 504 data->result->duration = content->sig.info.duration; 505 } 506 switch (content->sig.info.type) { 507 case PGP_SIG_BINARY: 508 case PGP_SIG_TEXT: 509 if (pgp_mem_len(data->mem) == 0 && 510 data->detachname) { 511 /* check we have seen some data */ 512 /* if not, need to read from detached name */ 513 (void) fprintf(io->errs, 514 "netpgp: assuming signed data in \"%s\"\n", 515 data->detachname); 516 data->mem = pgp_memory_new(); 517 pgp_mem_readfile(data->mem, data->detachname); 518 } 519 if (pgp_get_debug_level(__FILE__)) { 520 hexdump(stderr, "sig dump", (const uint8_t *)(const void *)&content->sig, 521 sizeof(content->sig)); 522 } 523 valid = check_binary_sig(pgp_mem_data(data->mem), 524 (const unsigned)pgp_mem_len(data->mem), 525 &content->sig, 526 pgp_get_pubkey(signer)); 527 break; 528 529 default: 530 PGP_ERROR_1(errors, PGP_E_UNIMPLEMENTED, 531 "No Sig Verification type 0x%02x yet\n", 532 content->sig.info.type); 533 break; 534 535 } 536 537 if (valid) { 538 if (!add_sig_to_list(&content->sig.info, 539 &data->result->valid_sigs, 540 &data->result->validc)) { 541 PGP_ERROR_1(errors, PGP_E_V_BAD_SIGNATURE, 542 "%s", "Can't add good sig to list"); 543 } 544 } else { 545 PGP_ERROR_1(errors, PGP_E_V_BAD_SIGNATURE, 546 "%s", "Bad Signature"); 547 if (!add_sig_to_list(&content->sig.info, 548 &data->result->invalid_sigs, 549 &data->result->invalidc)) { 550 PGP_ERROR_1(errors, PGP_E_V_BAD_SIGNATURE, "%s", 551 "Can't add good sig to list"); 552 } 553 } 554 break; 555 556 /* ignore these */ 557 case PGP_PARSER_PTAG: 558 case PGP_PTAG_CT_SIGNATURE_HEADER: 559 case PGP_PTAG_CT_ARMOUR_HEADER: 560 case PGP_PTAG_CT_ARMOUR_TRAILER: 561 case PGP_PTAG_CT_1_PASS_SIG: 562 break; 563 564 case PGP_PARSER_PACKET_END: 565 break; 566 567 default: 568 PGP_ERROR_1(errors, PGP_E_V_NO_SIGNATURE, "%s", "No signature"); 569 break; 570 } 571 return PGP_RELEASE_MEMORY; 572 } 573 574 static void 575 keydata_destroyer(pgp_reader_t *readinfo) 576 { 577 free(pgp_reader_get_arg(readinfo)); 578 } 579 580 void 581 pgp_keydata_reader_set(pgp_stream_t *stream, const pgp_key_t *key) 582 { 583 validate_reader_t *data; 584 585 if ((data = calloc(1, sizeof(*data))) == NULL) { 586 (void) fprintf(stderr, "pgp_keydata_reader_set: bad alloc\n"); 587 } else { 588 data->key = key; 589 data->packet = 0; 590 data->offset = 0; 591 pgp_reader_set(stream, keydata_reader, keydata_destroyer, data); 592 } 593 } 594 595 static char * 596 fmtsecs(int64_t n, char *buf, size_t size) 597 { 598 if (n > 365 * 24 * 60 * 60) { 599 n /= (365 * 24 * 60 * 60); 600 (void) snprintf(buf, size, "%" PRId64 " year%s", n, (n == 1) ? "" : "s"); 601 return buf; 602 } 603 if (n > 30 * 24 * 60 * 60) { 604 n /= (30 * 24 * 60 * 60); 605 (void) snprintf(buf, size, "%" PRId64 " month%s", n, (n == 1) ? "" : "s"); 606 return buf; 607 } 608 if (n > 24 * 60 * 60) { 609 n /= (24 * 60 * 60); 610 (void) snprintf(buf, size, "%" PRId64 " day%s", n, (n == 1) ? "" : "s"); 611 return buf; 612 } 613 if (n > 60 * 60) { 614 n /= (60 * 60); 615 (void) snprintf(buf, size, "%" PRId64 " hour%s", n, (n == 1) ? "" : "s"); 616 return buf; 617 } 618 if (n > 60) { 619 n /= 60; 620 (void) snprintf(buf, size, "%" PRId64 " minute%s", n, (n == 1) ? "" : "s"); 621 return buf; 622 } 623 (void) snprintf(buf, size, "%" PRId64 " second%s", n, (n == 1) ? "" : "s"); 624 return buf; 625 } 626 627 /** 628 * \ingroup HighLevel_Verify 629 * \brief Indicicates whether any errors were found 630 * \param result Validation result to check 631 * \return 0 if any invalid signatures or unknown signers 632 or no valid signatures; else 1 633 */ 634 static unsigned 635 validate_result_status(FILE *errs, const char *f, pgp_validation_t *val) 636 { 637 time_t now; 638 time_t t; 639 char buf[128]; 640 641 now = time(NULL); 642 if (now < val->birthtime) { 643 /* signature is not valid yet! */ 644 if (f) { 645 (void) fprintf(errs, "\"%s\": ", f); 646 } else { 647 (void) fprintf(errs, "memory "); 648 } 649 (void) fprintf(errs, 650 "signature not valid until %.24s (%s)\n", 651 ctime(&val->birthtime), 652 fmtsecs((int64_t)(val->birthtime - now), buf, sizeof(buf))); 653 return 0; 654 } 655 if (val->duration != 0 && now > val->birthtime + val->duration) { 656 /* signature has expired */ 657 t = val->duration + val->birthtime; 658 if (f) { 659 (void) fprintf(errs, "\"%s\": ", f); 660 } else { 661 (void) fprintf(errs, "memory "); 662 } 663 (void) fprintf(errs, 664 "signature not valid after %.24s (%s ago)\n", 665 ctime(&t), 666 fmtsecs((int64_t)(now - t), buf, sizeof(buf))); 667 return 0; 668 } 669 return val->validc && !val->invalidc && !val->unknownc; 670 } 671 672 /** 673 * \ingroup HighLevel_Verify 674 * \brief Validate all signatures on a single key against the given keyring 675 * \param result Where to put the result 676 * \param key Key to validate 677 * \param keyring Keyring to use for validation 678 * \param cb_get_passphrase Callback to use to get passphrase 679 * \return 1 if all signatures OK; else 0 680 * \note It is the caller's responsiblity to free result after use. 681 * \sa pgp_validate_result_free() 682 */ 683 unsigned 684 pgp_validate_key_sigs(pgp_validation_t *result, 685 const pgp_key_t *key, 686 const pgp_keyring_t *keyring, 687 pgp_cb_ret_t cb_get_passphrase(const pgp_packet_t *, 688 pgp_cbdata_t *)) 689 { 690 pgp_stream_t *stream; 691 validate_key_cb_t keysigs; 692 const int printerrors = 1; 693 694 (void) memset(&keysigs, 0x0, sizeof(keysigs)); 695 keysigs.result = result; 696 keysigs.getpassphrase = cb_get_passphrase; 697 698 stream = pgp_new(sizeof(*stream)); 699 /* pgp_parse_options(&opt,PGP_PTAG_CT_SIGNATURE,PGP_PARSE_PARSED); */ 700 701 keysigs.keyring = keyring; 702 703 pgp_set_callback(stream, pgp_validate_key_cb, &keysigs); 704 stream->readinfo.accumulate = 1; 705 pgp_keydata_reader_set(stream, key); 706 707 /* Note: Coverity incorrectly reports an error that keysigs.reader */ 708 /* is never used. */ 709 keysigs.reader = stream->readinfo.arg; 710 711 pgp_parse(stream, !printerrors); 712 713 pgp_pubkey_free(&keysigs.pubkey); 714 if (keysigs.subkey.version) { 715 pgp_pubkey_free(&keysigs.subkey); 716 } 717 pgp_userid_free(&keysigs.userid); 718 pgp_data_free(&keysigs.userattr); 719 720 pgp_stream_delete(stream); 721 722 return (!result->invalidc && !result->unknownc && result->validc); 723 } 724 725 /** 726 \ingroup HighLevel_Verify 727 \param result Where to put the result 728 \param ring Keyring to use 729 \param cb_get_passphrase Callback to use to get passphrase 730 \note It is the caller's responsibility to free result after use. 731 \sa pgp_validate_result_free() 732 */ 733 unsigned 734 pgp_validate_all_sigs(pgp_validation_t *result, 735 const pgp_keyring_t *ring, 736 pgp_cb_ret_t cb_get_passphrase(const pgp_packet_t *, 737 pgp_cbdata_t *)) 738 { 739 unsigned n; 740 741 (void) memset(result, 0x0, sizeof(*result)); 742 for (n = 0; n < ring->keyc; ++n) { 743 pgp_validate_key_sigs(result, &ring->keys[n], ring, 744 cb_get_passphrase); 745 } 746 return validate_result_status(stderr, "keyring", result); 747 } 748 749 /** 750 \ingroup HighLevel_Verify 751 \brief Frees validation result and associated memory 752 \param result Struct to be freed 753 \note Must be called after validation functions 754 */ 755 void 756 pgp_validate_result_free(pgp_validation_t *result) 757 { 758 if (result != NULL) { 759 if (result->valid_sigs) { 760 free_sig_info(result->valid_sigs); 761 } 762 if (result->invalid_sigs) { 763 free_sig_info(result->invalid_sigs); 764 } 765 if (result->unknown_sigs) { 766 free_sig_info(result->unknown_sigs); 767 } 768 free(result); 769 /* result = NULL; - XXX unnecessary */ 770 } 771 } 772 773 /** 774 \ingroup HighLevel_Verify 775 \brief Verifies the signatures in a signed file 776 \param result Where to put the result 777 \param filename Name of file to be validated 778 \param armoured Treat file as armoured, if set 779 \param keyring Keyring to use 780 \return 1 if signatures validate successfully; 781 0 if signatures fail or there are no signatures 782 \note After verification, result holds the details of all keys which 783 have passed, failed and not been recognised. 784 \note It is the caller's responsiblity to call 785 pgp_validate_result_free(result) after use. 786 */ 787 unsigned 788 pgp_validate_file(pgp_io_t *io, 789 pgp_validation_t *result, 790 const char *infile, 791 const char *outfile, 792 const int user_says_armoured, 793 const pgp_keyring_t *keyring) 794 { 795 validate_data_cb_t validation; 796 pgp_stream_t *parse = NULL; 797 struct stat st; 798 const char *signame; 799 const int printerrors = 1; 800 unsigned ret; 801 char f[MAXPATHLEN]; 802 char *dataname; 803 int realarmour; 804 int outfd = 0; 805 int infd; 806 int cc; 807 808 if (stat(infile, &st) < 0) { 809 (void) fprintf(io->errs, 810 "pgp_validate_file: can't open '%s'\n", infile); 811 return 0; 812 } 813 realarmour = user_says_armoured; 814 dataname = NULL; 815 signame = NULL; 816 cc = snprintf(f, sizeof(f), "%s", infile); 817 if (strcmp(&f[cc - 4], ".sig") == 0) { 818 /* we've been given a sigfile as infile */ 819 f[cc - 4] = 0x0; 820 /* set dataname to name of file which was signed */ 821 dataname = f; 822 signame = infile; 823 } else if (strcmp(&f[cc - 4], ".asc") == 0) { 824 /* we've been given an armored sigfile as infile */ 825 f[cc - 4] = 0x0; 826 /* set dataname to name of file which was signed */ 827 dataname = f; 828 signame = infile; 829 realarmour = 1; 830 } else { 831 signame = infile; 832 } 833 (void) memset(&validation, 0x0, sizeof(validation)); 834 infd = pgp_setup_file_read(io, &parse, signame, &validation, 835 validate_data_cb, 1); 836 if (infd < 0) { 837 return 0; 838 } 839 840 if (dataname) { 841 validation.detachname = netpgp_strdup(dataname); 842 } 843 844 /* Set verification reader and handling options */ 845 validation.result = result; 846 validation.keyring = keyring; 847 validation.mem = pgp_memory_new(); 848 pgp_memory_init(validation.mem, 128); 849 /* Note: Coverity incorrectly reports an error that validation.reader */ 850 /* is never used. */ 851 validation.reader = parse->readinfo.arg; 852 853 if (realarmour) { 854 pgp_reader_push_dearmour(parse); 855 } 856 857 /* Do the verification */ 858 pgp_parse(parse, !printerrors); 859 860 /* Tidy up */ 861 if (realarmour) { 862 pgp_reader_pop_dearmour(parse); 863 } 864 pgp_teardown_file_read(parse, infd); 865 866 ret = validate_result_status(io->errs, infile, result); 867 868 /* this is triggered only for --cat output */ 869 if (outfile) { 870 /* need to send validated output somewhere */ 871 if (strcmp(outfile, "-") == 0) { 872 outfd = STDOUT_FILENO; 873 } else { 874 outfd = open(outfile, O_WRONLY | O_CREAT, 0666); 875 } 876 if (outfd < 0) { 877 /* even if the signature was good, we can't 878 * write the file, so send back a bad return 879 * code */ 880 ret = 0; 881 } else if (validate_result_status(io->errs, infile, result)) { 882 unsigned len; 883 char *cp; 884 int i; 885 886 len = (unsigned)pgp_mem_len(validation.mem); 887 cp = pgp_mem_data(validation.mem); 888 for (i = 0 ; i < (int)len ; i += cc) { 889 cc = (int)write(outfd, &cp[i], (unsigned)(len - i)); 890 if (cc < 0) { 891 (void) fprintf(io->errs, 892 "netpgp: short write\n"); 893 ret = 0; 894 break; 895 } 896 } 897 if (strcmp(outfile, "-") != 0) { 898 (void) close(outfd); 899 } 900 } 901 } 902 pgp_memory_free(validation.mem); 903 return ret; 904 } 905 906 /** 907 \ingroup HighLevel_Verify 908 \brief Verifies the signatures in a pgp_memory_t struct 909 \param result Where to put the result 910 \param mem Memory to be validated 911 \param user_says_armoured Treat data as armoured, if set 912 \param keyring Keyring to use 913 \return 1 if signature validates successfully; 0 if not 914 \note After verification, result holds the details of all keys which 915 have passed, failed and not been recognised. 916 \note It is the caller's responsiblity to call 917 pgp_validate_result_free(result) after use. 918 */ 919 920 unsigned 921 pgp_validate_mem(pgp_io_t *io, 922 pgp_validation_t *result, 923 pgp_memory_t *mem, 924 pgp_memory_t **cat, 925 const int user_says_armoured, 926 const pgp_keyring_t *keyring) 927 { 928 validate_data_cb_t validation; 929 pgp_stream_t *stream = NULL; 930 const int printerrors = 1; 931 int realarmour; 932 933 pgp_setup_memory_read(io, &stream, mem, &validation, validate_data_cb, 1); 934 /* Set verification reader and handling options */ 935 (void) memset(&validation, 0x0, sizeof(validation)); 936 validation.result = result; 937 validation.keyring = keyring; 938 validation.mem = pgp_memory_new(); 939 pgp_memory_init(validation.mem, 128); 940 /* Note: Coverity incorrectly reports an error that validation.reader */ 941 /* is never used. */ 942 validation.reader = stream->readinfo.arg; 943 944 if ((realarmour = user_says_armoured) != 0 || 945 strncmp(pgp_mem_data(mem), 946 "-----BEGIN PGP MESSAGE-----", 27) == 0) { 947 realarmour = 1; 948 } 949 if (realarmour) { 950 pgp_reader_push_dearmour(stream); 951 } 952 953 /* Do the verification */ 954 pgp_parse(stream, !printerrors); 955 956 /* Tidy up */ 957 if (realarmour) { 958 pgp_reader_pop_dearmour(stream); 959 } 960 pgp_teardown_memory_read(stream, mem); 961 962 /* this is triggered only for --cat output */ 963 if (cat) { 964 /* need to send validated output somewhere */ 965 *cat = validation.mem; 966 } else { 967 pgp_memory_free(validation.mem); 968 } 969 970 return validate_result_status(io->errs, NULL, result); 971 } 972