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 50 /** \file 51 */ 52 #include "config.h" 53 54 #ifdef HAVE_SYS_CDEFS_H 55 #include <sys/cdefs.h> 56 #endif 57 58 #if defined(__NetBSD__) 59 __COPYRIGHT("@(#) Copyright (c) 2009 The NetBSD Foundation, Inc. All rights reserved."); 60 __RCSID("$NetBSD: keyring.c,v 1.26 2009/12/14 23:29:56 agc Exp $"); 61 #endif 62 63 #ifdef HAVE_FCNTL_H 64 #include <fcntl.h> 65 #endif 66 67 #include <regex.h> 68 #include <stdlib.h> 69 #include <string.h> 70 71 #ifdef HAVE_TERMIOS_H 72 #include <termios.h> 73 #endif 74 75 #ifdef HAVE_UNISTD_H 76 #include <unistd.h> 77 #endif 78 79 #include "types.h" 80 #include "keyring.h" 81 #include "packet-parse.h" 82 #include "signature.h" 83 #include "netpgpsdk.h" 84 #include "readerwriter.h" 85 #include "netpgpdefs.h" 86 #include "packet.h" 87 #include "crypto.h" 88 #include "validate.h" 89 #include "netpgpdigest.h" 90 91 92 93 /** 94 \ingroup HighLevel_Keyring 95 96 \brief Creates a new __ops_key_t struct 97 98 \return A new __ops_key_t struct, initialised to zero. 99 100 \note The returned __ops_key_t struct must be freed after use with __ops_keydata_free. 101 */ 102 103 __ops_key_t * 104 __ops_keydata_new(void) 105 { 106 return calloc(1, sizeof(__ops_key_t)); 107 } 108 109 110 /** 111 \ingroup HighLevel_Keyring 112 113 \brief Frees keydata and its memory 114 115 \param keydata Key to be freed. 116 117 \note This frees the keydata itself, as well as any other memory alloc-ed by it. 118 */ 119 void 120 __ops_keydata_free(__ops_key_t *keydata) 121 { 122 unsigned n; 123 124 for (n = 0; n < keydata->uidc; ++n) { 125 __ops_userid_free(&keydata->uids[n]); 126 } 127 free(keydata->uids); 128 keydata->uids = NULL; 129 keydata->uidc = 0; 130 131 for (n = 0; n < keydata->packetc; ++n) { 132 __ops_subpacket_free(&keydata->packets[n]); 133 } 134 free(keydata->packets); 135 keydata->packets = NULL; 136 keydata->packetc = 0; 137 138 if (keydata->type == OPS_PTAG_CT_PUBLIC_KEY) { 139 __ops_pubkey_free(&keydata->key.pubkey); 140 } else { 141 __ops_seckey_free(&keydata->key.seckey); 142 } 143 144 free(keydata); 145 } 146 147 /** 148 \ingroup HighLevel_KeyGeneral 149 150 \brief Returns the public key in the given keydata. 151 \param keydata 152 153 \return Pointer to public key 154 155 \note This is not a copy, do not free it after use. 156 */ 157 158 const __ops_pubkey_t * 159 __ops_get_pubkey(const __ops_key_t *keydata) 160 { 161 return (keydata->type == OPS_PTAG_CT_PUBLIC_KEY) ? 162 &keydata->key.pubkey : 163 &keydata->key.seckey.pubkey; 164 } 165 166 /** 167 \ingroup HighLevel_KeyGeneral 168 169 \brief Check whether this is a secret key or not. 170 */ 171 172 unsigned 173 __ops_is_key_secret(const __ops_key_t *data) 174 { 175 return data->type != OPS_PTAG_CT_PUBLIC_KEY; 176 } 177 178 /** 179 \ingroup HighLevel_KeyGeneral 180 181 \brief Returns the secret key in the given keydata. 182 183 \note This is not a copy, do not free it after use. 184 185 \note This returns a const. If you need to be able to write to this 186 pointer, use __ops_get_writable_seckey 187 */ 188 189 const __ops_seckey_t * 190 __ops_get_seckey(const __ops_key_t *data) 191 { 192 return (data->type == OPS_PTAG_CT_SECRET_KEY) ? 193 &data->key.seckey : NULL; 194 } 195 196 /** 197 \ingroup HighLevel_KeyGeneral 198 199 \brief Returns the secret key in the given keydata. 200 201 \note This is not a copy, do not free it after use. 202 203 \note If you do not need to be able to modify this key, there is an 204 equivalent read-only function __ops_get_seckey. 205 */ 206 207 __ops_seckey_t * 208 __ops_get_writable_seckey(__ops_key_t *data) 209 { 210 return (data->type == OPS_PTAG_CT_SECRET_KEY) ? 211 &data->key.seckey : NULL; 212 } 213 214 /* utility function to zero out memory */ 215 void 216 __ops_forget(void *vp, unsigned size) 217 { 218 (void) memset(vp, 0x0, size); 219 } 220 221 typedef struct { 222 const __ops_key_t *key; 223 char *passphrase; 224 __ops_seckey_t *seckey; 225 } decrypt_t; 226 227 static __ops_cb_ret_t 228 decrypt_cb(const __ops_packet_t *pkt, __ops_cbdata_t *cbinfo) 229 { 230 const __ops_contents_t *content = &pkt->u; 231 decrypt_t *decrypt; 232 char pass[MAX_PASSPHRASE_LENGTH]; 233 234 decrypt = __ops_callback_arg(cbinfo); 235 switch (pkt->tag) { 236 case OPS_PARSER_PTAG: 237 case OPS_PTAG_CT_USER_ID: 238 case OPS_PTAG_CT_SIGNATURE: 239 case OPS_PTAG_CT_SIGNATURE_HEADER: 240 case OPS_PTAG_CT_SIGNATURE_FOOTER: 241 case OPS_PTAG_CT_TRUST: 242 break; 243 244 case OPS_GET_PASSPHRASE: 245 (void) __ops_getpassphrase(NULL, pass, sizeof(pass)); 246 *content->skey_passphrase.passphrase = strdup(pass); 247 return OPS_KEEP_MEMORY; 248 249 case OPS_PARSER_ERRCODE: 250 switch (content->errcode.errcode) { 251 case OPS_E_P_MPI_FORMAT_ERROR: 252 /* Generally this means a bad passphrase */ 253 fprintf(stderr, "Bad passphrase!\n"); 254 return OPS_RELEASE_MEMORY; 255 256 case OPS_E_P_PACKET_CONSUMED: 257 /* And this is because of an error we've accepted */ 258 return OPS_RELEASE_MEMORY; 259 default: 260 break; 261 } 262 (void) fprintf(stderr, "parse error: %s\n", 263 __ops_errcode(content->errcode.errcode)); 264 return OPS_FINISHED; 265 266 case OPS_PARSER_ERROR: 267 fprintf(stderr, "parse error: %s\n", content->error.error); 268 return OPS_FINISHED; 269 270 case OPS_PTAG_CT_SECRET_KEY: 271 if ((decrypt->seckey = calloc(1, sizeof(*decrypt->seckey))) == NULL) { 272 (void) fprintf(stderr, "decrypt_cb: bad alloc\n"); 273 return OPS_FINISHED; 274 } 275 decrypt->seckey->checkhash = calloc(1, OPS_CHECKHASH_SIZE); 276 *decrypt->seckey = content->seckey; 277 return OPS_KEEP_MEMORY; 278 279 case OPS_PARSER_PACKET_END: 280 /* nothing to do */ 281 break; 282 283 default: 284 fprintf(stderr, "Unexpected tag %d (0x%x)\n", pkt->tag, 285 pkt->tag); 286 return OPS_FINISHED; 287 } 288 289 return OPS_RELEASE_MEMORY; 290 } 291 292 /** 293 \ingroup Core_Keys 294 \brief Decrypts secret key from given keydata with given passphrase 295 \param key Key from which to get secret key 296 \param passphrase Passphrase to use to decrypt secret key 297 \return secret key 298 */ 299 __ops_seckey_t * 300 __ops_decrypt_seckey(const __ops_key_t *key) 301 { 302 __ops_stream_t *stream; 303 const int printerrors = 1; 304 decrypt_t decrypt; 305 306 (void) memset(&decrypt, 0x0, sizeof(decrypt)); 307 decrypt.key = key; 308 stream = __ops_new(sizeof(*stream)); 309 __ops_keydata_reader_set(stream, key); 310 __ops_set_callback(stream, decrypt_cb, &decrypt); 311 stream->readinfo.accumulate = 1; 312 __ops_parse(stream, !printerrors); 313 return decrypt.seckey; 314 } 315 316 /** 317 \ingroup Core_Keys 318 \brief Set secret key in content 319 \param content Content to be set 320 \param key Keydata to get secret key from 321 */ 322 void 323 __ops_set_seckey(__ops_contents_t *cont, const __ops_key_t *key) 324 { 325 *cont->get_seckey.seckey = &key->key.seckey; 326 } 327 328 /** 329 \ingroup Core_Keys 330 \brief Get Key ID from keydata 331 \param key Keydata to get Key ID from 332 \return Pointer to Key ID inside keydata 333 */ 334 const unsigned char * 335 __ops_get_key_id(const __ops_key_t *key) 336 { 337 return key->key_id; 338 } 339 340 /** 341 \ingroup Core_Keys 342 \brief How many User IDs in this key? 343 \param key Keydata to check 344 \return Num of user ids 345 */ 346 unsigned 347 __ops_get_userid_count(const __ops_key_t *key) 348 { 349 return key->uidc; 350 } 351 352 /** 353 \ingroup Core_Keys 354 \brief Get indexed user id from key 355 \param key Key to get user id from 356 \param index Which key to get 357 \return Pointer to requested user id 358 */ 359 const unsigned char * 360 __ops_get_userid(const __ops_key_t *key, unsigned subscript) 361 { 362 return key->uids[subscript].userid; 363 } 364 365 /** 366 \ingroup HighLevel_Supported 367 \brief Checks whether key's algorithm and type are supported by OpenPGP::SDK 368 \param keydata Key to be checked 369 \return 1 if key algorithm and type are supported by OpenPGP::SDK; 0 if not 370 */ 371 372 unsigned 373 __ops_is_key_supported(const __ops_key_t *key) 374 { 375 if (key->type == OPS_PTAG_CT_PUBLIC_KEY) { 376 if (key->key.pubkey.alg == OPS_PKA_RSA) { 377 return 1; 378 } 379 } else if (key->type == OPS_PTAG_CT_PUBLIC_KEY) { 380 if (key->key.pubkey.alg == OPS_PKA_DSA) { 381 return 1; 382 } 383 } 384 return 0; 385 } 386 387 /* \todo check where userid pointers are copied */ 388 /** 389 \ingroup Core_Keys 390 \brief Copy user id, including contents 391 \param dst Destination User ID 392 \param src Source User ID 393 \note If dst already has a userid, it will be freed. 394 */ 395 static __ops_userid_t * 396 __ops_copy_userid(__ops_userid_t *dst, const __ops_userid_t *src) 397 { 398 size_t len = strlen((char *) src->userid); 399 400 if (dst->userid) { 401 free(dst->userid); 402 } 403 if ((dst->userid = calloc(1, len + 1)) == NULL) { 404 (void) fprintf(stderr, "__ops_copy_userid: bad alloc\n"); 405 } else { 406 (void) memcpy(dst->userid, src->userid, len); 407 } 408 return dst; 409 } 410 411 /* \todo check where pkt pointers are copied */ 412 /** 413 \ingroup Core_Keys 414 \brief Copy packet, including contents 415 \param dst Destination packet 416 \param src Source packet 417 \note If dst already has a packet, it will be freed. 418 */ 419 static __ops_subpacket_t * 420 __ops_copy_packet(__ops_subpacket_t *dst, const __ops_subpacket_t *src) 421 { 422 if (dst->raw) { 423 free(dst->raw); 424 } 425 if ((dst->raw = calloc(1, src->length)) == NULL) { 426 (void) fprintf(stderr, "__ops_copy_packet: bad alloc\n"); 427 } else { 428 dst->length = src->length; 429 (void) memcpy(dst->raw, src->raw, src->length); 430 } 431 return dst; 432 } 433 434 /** 435 \ingroup Core_Keys 436 \brief Add User ID to key 437 \param key Key to which to add User ID 438 \param userid User ID to add 439 \return Pointer to new User ID 440 */ 441 __ops_userid_t * 442 __ops_add_userid(__ops_key_t *key, const __ops_userid_t *userid) 443 { 444 __ops_userid_t *uidp; 445 446 EXPAND_ARRAY(key, uid); 447 /* initialise new entry in array */ 448 uidp = &key->uids[key->uidc++]; 449 uidp->userid = NULL; 450 /* now copy it */ 451 return __ops_copy_userid(uidp, userid); 452 } 453 454 /** 455 \ingroup Core_Keys 456 \brief Add packet to key 457 \param keydata Key to which to add packet 458 \param packet Packet to add 459 \return Pointer to new packet 460 */ 461 __ops_subpacket_t * 462 __ops_add_subpacket(__ops_key_t *keydata, const __ops_subpacket_t *packet) 463 { 464 __ops_subpacket_t *subpktp; 465 466 EXPAND_ARRAY(keydata, packet); 467 468 /* initialise new entry in array */ 469 subpktp = &keydata->packets[keydata->packetc++]; 470 subpktp->length = 0; 471 subpktp->raw = NULL; 472 /* now copy it */ 473 return __ops_copy_packet(subpktp, packet); 474 } 475 476 /** 477 \ingroup Core_Keys 478 \brief Add signed User ID to key 479 \param keydata Key to which to add signed User ID 480 \param userid User ID to add 481 \param sigpacket Packet to add 482 */ 483 void 484 __ops_add_signed_userid(__ops_key_t *keydata, 485 const __ops_userid_t *userid, 486 const __ops_subpacket_t *sigpacket) 487 { 488 __ops_subpacket_t *pkt; 489 __ops_userid_t *uid; 490 491 uid = __ops_add_userid(keydata, userid); 492 pkt = __ops_add_subpacket(keydata, sigpacket); 493 494 /* 495 * add entry in sigs array to link the userid and sigpacket 496 * and add ptr to it from the sigs array */ 497 EXPAND_ARRAY(keydata, sig); 498 499 /**setup new entry in array */ 500 keydata->sigs[keydata->sigc].userid = uid; 501 keydata->sigs[keydata->sigc].packet = pkt; 502 503 keydata->sigc++; 504 } 505 506 /** 507 \ingroup Core_Keys 508 \brief Add selfsigned User ID to key 509 \param keydata Key to which to add user ID 510 \param userid Self-signed User ID to add 511 \return 1 if OK; else 0 512 */ 513 unsigned 514 __ops_add_selfsigned_userid(__ops_key_t *keydata, __ops_userid_t *userid) 515 { 516 __ops_create_sig_t *sig; 517 __ops_subpacket_t sigpacket; 518 __ops_memory_t *mem_userid = NULL; 519 __ops_output_t *useridoutput = NULL; 520 __ops_memory_t *mem_sig = NULL; 521 __ops_output_t *sigoutput = NULL; 522 523 /* 524 * create signature packet for this userid 525 */ 526 527 /* create userid pkt */ 528 __ops_setup_memory_write(&useridoutput, &mem_userid, 128); 529 __ops_write_struct_userid(useridoutput, userid); 530 531 /* create sig for this pkt */ 532 sig = __ops_create_sig_new(); 533 __ops_sig_start_key_sig(sig, &keydata->key.seckey.pubkey, userid, 534 OPS_CERT_POSITIVE); 535 __ops_add_birthtime(sig, time(NULL)); 536 __ops_add_issuer_keyid(sig, keydata->key_id); 537 __ops_add_primary_userid(sig, 1); 538 __ops_end_hashed_subpkts(sig); 539 540 __ops_setup_memory_write(&sigoutput, &mem_sig, 128); 541 __ops_write_sig(sigoutput, sig, &keydata->key.seckey.pubkey, 542 &keydata->key.seckey); 543 544 /* add this packet to keydata */ 545 sigpacket.length = __ops_mem_len(mem_sig); 546 sigpacket.raw = __ops_mem_data(mem_sig); 547 548 /* add userid to keydata */ 549 __ops_add_signed_userid(keydata, userid, &sigpacket); 550 551 /* cleanup */ 552 __ops_create_sig_delete(sig); 553 __ops_output_delete(useridoutput); 554 __ops_output_delete(sigoutput); 555 __ops_memory_free(mem_userid); 556 __ops_memory_free(mem_sig); 557 558 return 1; 559 } 560 561 /** 562 \ingroup Core_Keys 563 \brief Initialise __ops_key_t 564 \param keydata Keydata to initialise 565 \param type OPS_PTAG_CT_PUBLIC_KEY or OPS_PTAG_CT_SECRET_KEY 566 */ 567 void 568 __ops_keydata_init(__ops_key_t *keydata, const __ops_content_tag_t type) 569 { 570 if (keydata->type != OPS_PTAG_CT_RESERVED) { 571 (void) fprintf(stderr, 572 "__ops_keydata_init: wrong keydata type\n"); 573 } else if (type != OPS_PTAG_CT_PUBLIC_KEY && 574 type != OPS_PTAG_CT_SECRET_KEY) { 575 (void) fprintf(stderr, "__ops_keydata_init: wrong type\n"); 576 } else { 577 keydata->type = type; 578 } 579 } 580 581 582 static __ops_cb_ret_t 583 cb_keyring_read(const __ops_packet_t *pkt, __ops_cbdata_t *cbinfo) 584 { 585 __OPS_USED(cbinfo); 586 587 switch (pkt->tag) { 588 case OPS_PARSER_PTAG: 589 case OPS_PTAG_CT_ENCRYPTED_SECRET_KEY: /* we get these because we 590 * didn't prompt */ 591 case OPS_PTAG_CT_SIGNATURE_HEADER: 592 case OPS_PTAG_CT_SIGNATURE_FOOTER: 593 case OPS_PTAG_CT_SIGNATURE: 594 case OPS_PTAG_CT_TRUST: 595 case OPS_PARSER_ERRCODE: 596 break; 597 598 default: 599 break; 600 } 601 602 return OPS_RELEASE_MEMORY; 603 } 604 605 /** 606 \ingroup HighLevel_KeyringRead 607 608 \brief Reads a keyring from a file 609 610 \param keyring Pointer to an existing __ops_keyring_t struct 611 \param armour 1 if file is armoured; else 0 612 \param filename Filename of keyring to be read 613 614 \return __ops 1 if OK; 0 on error 615 616 \note Keyring struct must already exist. 617 618 \note Can be used with either a public or secret keyring. 619 620 \note You must call __ops_keyring_free() after usage to free alloc-ed memory. 621 622 \note If you call this twice on the same keyring struct, without calling 623 __ops_keyring_free() between these calls, you will introduce a memory leak. 624 625 \sa __ops_keyring_read_from_mem() 626 \sa __ops_keyring_free() 627 628 */ 629 630 unsigned 631 __ops_keyring_fileread(__ops_keyring_t *keyring, 632 const unsigned armour, 633 const char *filename) 634 { 635 __ops_stream_t *stream; 636 unsigned res = 1; 637 int fd; 638 639 stream = __ops_new(sizeof(*stream)); 640 641 /* add this for the moment, */ 642 /* 643 * \todo need to fix the problems with reading signature subpackets 644 * later 645 */ 646 647 /* __ops_parse_options(parse,OPS_PTAG_SS_ALL,OPS_PARSE_RAW); */ 648 __ops_parse_options(stream, OPS_PTAG_SS_ALL, OPS_PARSE_PARSED); 649 650 #ifdef O_BINARY 651 fd = open(filename, O_RDONLY | O_BINARY); 652 #else 653 fd = open(filename, O_RDONLY); 654 #endif 655 if (fd < 0) { 656 __ops_stream_delete(stream); 657 perror(filename); 658 return 0; 659 } 660 #ifdef USE_MMAP_FOR_FILES 661 __ops_reader_set_mmap(stream, fd); 662 #else 663 __ops_reader_set_fd(stream, fd); 664 #endif 665 666 __ops_set_callback(stream, cb_keyring_read, NULL); 667 668 if (armour) { 669 __ops_reader_push_dearmour(stream); 670 } 671 res = __ops_parse_and_accumulate(keyring, stream); 672 __ops_print_errors(__ops_stream_get_errors(stream)); 673 674 if (armour) { 675 __ops_reader_pop_dearmour(stream); 676 } 677 678 (void)close(fd); 679 680 __ops_stream_delete(stream); 681 682 return res; 683 } 684 685 /** 686 \ingroup HighLevel_KeyringRead 687 688 \brief Reads a keyring from memory 689 690 \param keyring Pointer to existing __ops_keyring_t struct 691 \param armour 1 if file is armoured; else 0 692 \param mem Pointer to a __ops_memory_t struct containing keyring to be read 693 694 \return __ops 1 if OK; 0 on error 695 696 \note Keyring struct must already exist. 697 698 \note Can be used with either a public or secret keyring. 699 700 \note You must call __ops_keyring_free() after usage to free alloc-ed memory. 701 702 \note If you call this twice on the same keyring struct, without calling 703 __ops_keyring_free() between these calls, you will introduce a memory leak. 704 705 \sa __ops_keyring_fileread 706 \sa __ops_keyring_free 707 */ 708 unsigned 709 __ops_keyring_read_from_mem(__ops_io_t *io, 710 __ops_keyring_t *keyring, 711 const unsigned armour, 712 __ops_memory_t *mem) 713 { 714 __ops_stream_t *stream; 715 const unsigned noaccum = 0; 716 unsigned res; 717 718 stream = __ops_new(sizeof(*stream)); 719 __ops_parse_options(stream, OPS_PTAG_SS_ALL, OPS_PARSE_PARSED); 720 __ops_setup_memory_read(io, &stream, mem, NULL, cb_keyring_read, 721 noaccum); 722 if (armour) { 723 __ops_reader_push_dearmour(stream); 724 } 725 res = (unsigned)__ops_parse_and_accumulate(keyring, stream); 726 __ops_print_errors(__ops_stream_get_errors(stream)); 727 if (armour) { 728 __ops_reader_pop_dearmour(stream); 729 } 730 /* don't call teardown_memory_read because memory was passed in */ 731 __ops_stream_delete(stream); 732 return res; 733 } 734 735 /** 736 \ingroup HighLevel_KeyringRead 737 738 \brief Frees keyring's contents (but not keyring itself) 739 740 \param keyring Keyring whose data is to be freed 741 742 \note This does not free keyring itself, just the memory alloc-ed in it. 743 */ 744 void 745 __ops_keyring_free(__ops_keyring_t *keyring) 746 { 747 (void)free(keyring->keys); 748 keyring->keys = NULL; 749 keyring->keyc = keyring->keyvsize = 0; 750 } 751 752 /** 753 \ingroup HighLevel_KeyringFind 754 755 \brief Finds key in keyring from its Key ID 756 757 \param keyring Keyring to be searched 758 \param keyid ID of required key 759 760 \return Pointer to key, if found; NULL, if not found 761 762 \note This returns a pointer to the key inside the given keyring, 763 not a copy. Do not free it after use. 764 765 */ 766 const __ops_key_t * 767 __ops_getkeybyid(__ops_io_t *io, const __ops_keyring_t *keyring, 768 const unsigned char *keyid, unsigned *from) 769 { 770 for ( ; keyring && *from < keyring->keyc; *from += 1) { 771 if (__ops_get_debug_level(__FILE__)) { 772 int i; 773 774 (void) fprintf(io->errs, 775 "__ops_getkeybyid: keyring keyid "); 776 for (i = 0 ; i < OPS_KEY_ID_SIZE ; i++) { 777 (void) fprintf(io->errs, "%02x", 778 keyring->keys[*from].key_id[i]); 779 } 780 (void) fprintf(io->errs, ", keyid "); 781 for (i = 0 ; i < OPS_KEY_ID_SIZE ; i++) { 782 (void) fprintf(io->errs, "%02x", keyid[i]); 783 } 784 (void) fprintf(io->errs, "\n"); 785 } 786 if (memcmp(keyring->keys[*from].key_id, keyid, 787 OPS_KEY_ID_SIZE) == 0) { 788 return &keyring->keys[*from]; 789 } 790 if (memcmp(&keyring->keys[*from].key_id[OPS_KEY_ID_SIZE / 2], 791 keyid, OPS_KEY_ID_SIZE / 2) == 0) { 792 return &keyring->keys[*from]; 793 } 794 } 795 return NULL; 796 } 797 798 /* convert a string keyid into a binary keyid */ 799 static void 800 str2keyid(const char *userid, unsigned char *keyid, size_t len) 801 { 802 static const char *uppers = "0123456789ABCDEF"; 803 static const char *lowers = "0123456789abcdef"; 804 unsigned char hichar; 805 unsigned char lochar; 806 size_t j; 807 const char *hi; 808 const char *lo; 809 int i; 810 811 for (i = j = 0 ; j < len && userid[i] && userid[i + 1] ; i += 2, j++) { 812 if ((hi = strchr(uppers, userid[i])) == NULL) { 813 if ((hi = strchr(lowers, userid[i])) == NULL) { 814 break; 815 } 816 hichar = (hi - lowers); 817 } else { 818 hichar = (hi - uppers); 819 } 820 if ((lo = strchr(uppers, userid[i + 1])) == NULL) { 821 if ((lo = strchr(lowers, userid[i + 1])) == NULL) { 822 break; 823 } 824 lochar = (lo - lowers); 825 } else { 826 lochar = (lo - uppers); 827 } 828 keyid[j] = (hichar << 4) | (lochar); 829 } 830 keyid[j] = 0x0; 831 } 832 833 /* return the next key which matches, starting searching at *from */ 834 static const __ops_key_t * 835 getkeybyname(__ops_io_t *io, 836 const __ops_keyring_t *keyring, 837 const char *name, 838 unsigned *from) 839 { 840 const __ops_key_t *kp; 841 __ops_key_t *keyp; 842 __ops_userid_t *uidp; 843 unsigned char keyid[OPS_KEY_ID_SIZE + 1]; 844 unsigned int i = 0; 845 unsigned savedstart; 846 regex_t r; 847 size_t len; 848 849 if (!keyring) { 850 return NULL; 851 } 852 len = strlen(name); 853 if (__ops_get_debug_level(__FILE__)) { 854 (void) fprintf(io->outs, "[%u] name '%s', len %zu\n", 855 *from, name, len); 856 } 857 /* first try name as a keyid */ 858 (void) memset(keyid, 0x0, sizeof(keyid)); 859 str2keyid(name, keyid, sizeof(keyid)); 860 if (__ops_get_debug_level(__FILE__)) { 861 (void) fprintf(io->outs, 862 "name \"%s\", keyid %02x%02x%02x%02x\n", 863 name, 864 keyid[0], keyid[1], keyid[2], keyid[3]); 865 } 866 savedstart = *from; 867 if ((kp = __ops_getkeybyid(io, keyring, keyid, from)) != NULL) { 868 return kp; 869 } 870 *from = savedstart; 871 if (__ops_get_debug_level(__FILE__)) { 872 (void) fprintf(io->outs, "regex match '%s' from %u\n", 873 name, *from); 874 } 875 /* match on full name or email address as a NOSUB, ICASE regexp */ 876 (void) regcomp(&r, name, REG_EXTENDED | REG_ICASE); 877 for (keyp = &keyring->keys[*from]; *from < keyring->keyc; *from += 1, keyp++) { 878 uidp = keyp->uids; 879 for (i = 0 ; i < keyp->uidc; i++, uidp++) { 880 if (__ops_get_debug_level(__FILE__)) { 881 (void) fprintf(io->outs, 882 "keyid \"%s\" len %" 883 PRIsize "u, keyid[len] '%c'\n", 884 (char *) uidp->userid, 885 len, uidp->userid[len]); 886 } 887 if (regexec(&r, (char *)uidp->userid, 0, NULL, 0) == 0) { 888 regfree(&r); 889 return keyp; 890 } 891 } 892 } 893 regfree(&r); 894 return NULL; 895 } 896 897 /** 898 \ingroup HighLevel_KeyringFind 899 900 \brief Finds key from its User ID 901 902 \param keyring Keyring to be searched 903 \param userid User ID of required key 904 905 \return Pointer to Key, if found; NULL, if not found 906 907 \note This returns a pointer to the key inside the keyring, not a 908 copy. Do not free it. 909 910 */ 911 const __ops_key_t * 912 __ops_getkeybyname(__ops_io_t *io, 913 const __ops_keyring_t *keyring, 914 const char *name) 915 { 916 unsigned from; 917 918 from = 0; 919 return getkeybyname(io, keyring, name, &from); 920 } 921 922 const __ops_key_t * 923 __ops_getnextkeybyname(__ops_io_t *io, 924 const __ops_keyring_t *keyring, 925 const char *name, 926 unsigned *n) 927 { 928 return getkeybyname(io, keyring, name, n); 929 } 930 931 /** 932 \ingroup HighLevel_KeyringList 933 934 \brief Prints all keys in keyring to stdout. 935 936 \param keyring Keyring to use 937 938 \return none 939 */ 940 int 941 __ops_keyring_list(__ops_io_t *io, const __ops_keyring_t *keyring) 942 { 943 __ops_key_t *key; 944 unsigned n; 945 946 (void) fprintf(io->res, "%u key%s\n", keyring->keyc, 947 (keyring->keyc == 1) ? "" : "s"); 948 for (n = 0, key = keyring->keys; n < keyring->keyc; ++n, ++key) { 949 if (__ops_is_key_secret(key)) { 950 __ops_print_keydata(io, key, "sec", 951 &key->key.seckey.pubkey); 952 } else { 953 __ops_print_keydata(io, key, "pub", &key->key.pubkey); 954 } 955 (void) fputc('\n', io->res); 956 } 957 return 1; 958 } 959 960 /* this interface isn't right - hook into callback for getting passphrase */ 961 int 962 __ops_export_key(const __ops_key_t *keydata, unsigned char *passphrase) 963 { 964 __ops_output_t *output; 965 __ops_memory_t *mem; 966 967 __ops_setup_memory_write(&output, &mem, 128); 968 if (keydata->type == OPS_PTAG_CT_PUBLIC_KEY) { 969 __ops_write_xfer_pubkey(output, keydata, 1); 970 } else { 971 __ops_write_xfer_seckey(output, keydata, passphrase, 972 strlen((char *)passphrase), 1); 973 } 974 printf("%s", (char *) __ops_mem_data(mem)); 975 __ops_teardown_memory_write(output, mem); 976 return 1; 977 } 978 979 /* add a key to a public keyring */ 980 int 981 __ops_add_to_pubring(__ops_keyring_t *keyring, const __ops_pubkey_t *pubkey) 982 { 983 __ops_key_t *key; 984 985 EXPAND_ARRAY(keyring, key); 986 key = &keyring->keys[keyring->keyc++]; 987 (void) memset(key, 0x0, sizeof(*key)); 988 __ops_keyid(key->key_id, OPS_KEY_ID_SIZE, pubkey); 989 __ops_fingerprint(&key->fingerprint, pubkey); 990 key->type = OPS_PTAG_CT_PUBLIC_KEY; 991 key->key.pubkey = *pubkey; 992 return 1; 993 } 994 995 /* add a key to a secret keyring */ 996 int 997 __ops_add_to_secring(__ops_keyring_t *keyring, const __ops_seckey_t *seckey) 998 { 999 const __ops_pubkey_t *pubkey; 1000 __ops_key_t *key; 1001 1002 EXPAND_ARRAY(keyring, key); 1003 key = &keyring->keys[keyring->keyc++]; 1004 (void) memset(key, 0x0, sizeof(*key)); 1005 pubkey = &seckey->pubkey; 1006 __ops_keyid(key->key_id, OPS_KEY_ID_SIZE, pubkey); 1007 __ops_fingerprint(&key->fingerprint, pubkey); 1008 key->type = OPS_PTAG_CT_SECRET_KEY; 1009 key->key.seckey = *seckey; 1010 return 1; 1011 } 1012