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.32 2010/03/12 01:22:01 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 FILE *passfp; 223 const __ops_key_t *key; 224 char *passphrase; 225 __ops_seckey_t *seckey; 226 } decrypt_t; 227 228 static __ops_cb_ret_t 229 decrypt_cb(const __ops_packet_t *pkt, __ops_cbdata_t *cbinfo) 230 { 231 const __ops_contents_t *content = &pkt->u; 232 decrypt_t *decrypt; 233 char pass[MAX_PASSPHRASE_LENGTH]; 234 235 decrypt = __ops_callback_arg(cbinfo); 236 switch (pkt->tag) { 237 case OPS_PARSER_PTAG: 238 case OPS_PTAG_CT_USER_ID: 239 case OPS_PTAG_CT_SIGNATURE: 240 case OPS_PTAG_CT_SIGNATURE_HEADER: 241 case OPS_PTAG_CT_SIGNATURE_FOOTER: 242 case OPS_PTAG_CT_TRUST: 243 break; 244 245 case OPS_GET_PASSPHRASE: 246 (void) __ops_getpassphrase(decrypt->passfp, pass, sizeof(pass)); 247 *content->skey_passphrase.passphrase = netpgp_strdup(pass); 248 __ops_forget(pass, sizeof(pass)); 249 return OPS_KEEP_MEMORY; 250 251 case OPS_PARSER_ERRCODE: 252 switch (content->errcode.errcode) { 253 case OPS_E_P_MPI_FORMAT_ERROR: 254 /* Generally this means a bad passphrase */ 255 fprintf(stderr, "Bad passphrase!\n"); 256 return OPS_RELEASE_MEMORY; 257 258 case OPS_E_P_PACKET_CONSUMED: 259 /* And this is because of an error we've accepted */ 260 return OPS_RELEASE_MEMORY; 261 default: 262 break; 263 } 264 (void) fprintf(stderr, "parse error: %s\n", 265 __ops_errcode(content->errcode.errcode)); 266 return OPS_FINISHED; 267 268 case OPS_PARSER_ERROR: 269 fprintf(stderr, "parse error: %s\n", content->error.error); 270 return OPS_FINISHED; 271 272 case OPS_PTAG_CT_SECRET_KEY: 273 if ((decrypt->seckey = calloc(1, sizeof(*decrypt->seckey))) == NULL) { 274 (void) fprintf(stderr, "decrypt_cb: bad alloc\n"); 275 return OPS_FINISHED; 276 } 277 decrypt->seckey->checkhash = calloc(1, OPS_CHECKHASH_SIZE); 278 *decrypt->seckey = content->seckey; 279 return OPS_KEEP_MEMORY; 280 281 case OPS_PARSER_PACKET_END: 282 /* nothing to do */ 283 break; 284 285 default: 286 fprintf(stderr, "Unexpected tag %d (0x%x)\n", pkt->tag, 287 pkt->tag); 288 return OPS_FINISHED; 289 } 290 291 return OPS_RELEASE_MEMORY; 292 } 293 294 /** 295 \ingroup Core_Keys 296 \brief Decrypts secret key from given keydata with given passphrase 297 \param key Key from which to get secret key 298 \param passphrase Passphrase to use to decrypt secret key 299 \return secret key 300 */ 301 __ops_seckey_t * 302 __ops_decrypt_seckey(const __ops_key_t *key, void *passfp) 303 { 304 __ops_stream_t *stream; 305 const int printerrors = 1; 306 decrypt_t decrypt; 307 308 (void) memset(&decrypt, 0x0, sizeof(decrypt)); 309 decrypt.key = key; 310 decrypt.passfp = passfp; 311 stream = __ops_new(sizeof(*stream)); 312 __ops_keydata_reader_set(stream, key); 313 __ops_set_callback(stream, decrypt_cb, &decrypt); 314 stream->readinfo.accumulate = 1; 315 __ops_parse(stream, !printerrors); 316 return decrypt.seckey; 317 } 318 319 /** 320 \ingroup Core_Keys 321 \brief Set secret key in content 322 \param content Content to be set 323 \param key Keydata to get secret key from 324 */ 325 void 326 __ops_set_seckey(__ops_contents_t *cont, const __ops_key_t *key) 327 { 328 *cont->get_seckey.seckey = &key->key.seckey; 329 } 330 331 /** 332 \ingroup Core_Keys 333 \brief Get Key ID from keydata 334 \param key Keydata to get Key ID from 335 \return Pointer to Key ID inside keydata 336 */ 337 const uint8_t * 338 __ops_get_key_id(const __ops_key_t *key) 339 { 340 return key->key_id; 341 } 342 343 /** 344 \ingroup Core_Keys 345 \brief How many User IDs in this key? 346 \param key Keydata to check 347 \return Num of user ids 348 */ 349 unsigned 350 __ops_get_userid_count(const __ops_key_t *key) 351 { 352 return key->uidc; 353 } 354 355 /** 356 \ingroup Core_Keys 357 \brief Get indexed user id from key 358 \param key Key to get user id from 359 \param index Which key to get 360 \return Pointer to requested user id 361 */ 362 const uint8_t * 363 __ops_get_userid(const __ops_key_t *key, unsigned subscript) 364 { 365 return key->uids[subscript].userid; 366 } 367 368 /** 369 \ingroup HighLevel_Supported 370 \brief Checks whether key's algorithm and type are supported by OpenPGP::SDK 371 \param keydata Key to be checked 372 \return 1 if key algorithm and type are supported by OpenPGP::SDK; 0 if not 373 */ 374 375 unsigned 376 __ops_is_key_supported(const __ops_key_t *key) 377 { 378 if (key->type == OPS_PTAG_CT_PUBLIC_KEY) { 379 if (key->key.pubkey.alg == OPS_PKA_RSA) { 380 return 1; 381 } 382 } else if (key->type == OPS_PTAG_CT_PUBLIC_KEY) { 383 if (key->key.pubkey.alg == OPS_PKA_DSA) { 384 return 1; 385 } 386 } 387 return 0; 388 } 389 390 /* \todo check where userid pointers are copied */ 391 /** 392 \ingroup Core_Keys 393 \brief Copy user id, including contents 394 \param dst Destination User ID 395 \param src Source User ID 396 \note If dst already has a userid, it will be freed. 397 */ 398 static __ops_userid_t * 399 __ops_copy_userid(__ops_userid_t *dst, const __ops_userid_t *src) 400 { 401 size_t len; 402 403 len = strlen((char *) src->userid); 404 if (dst->userid) { 405 free(dst->userid); 406 } 407 if ((dst->userid = calloc(1, len + 1)) == NULL) { 408 (void) fprintf(stderr, "__ops_copy_userid: bad alloc\n"); 409 } else { 410 (void) memcpy(dst->userid, src->userid, len); 411 } 412 return dst; 413 } 414 415 /* \todo check where pkt pointers are copied */ 416 /** 417 \ingroup Core_Keys 418 \brief Copy packet, including contents 419 \param dst Destination packet 420 \param src Source packet 421 \note If dst already has a packet, it will be freed. 422 */ 423 static __ops_subpacket_t * 424 __ops_copy_packet(__ops_subpacket_t *dst, const __ops_subpacket_t *src) 425 { 426 if (dst->raw) { 427 free(dst->raw); 428 } 429 if ((dst->raw = calloc(1, src->length)) == NULL) { 430 (void) fprintf(stderr, "__ops_copy_packet: bad alloc\n"); 431 } else { 432 dst->length = src->length; 433 (void) memcpy(dst->raw, src->raw, src->length); 434 } 435 return dst; 436 } 437 438 /** 439 \ingroup Core_Keys 440 \brief Add User ID to key 441 \param key Key to which to add User ID 442 \param userid User ID to add 443 \return Pointer to new User ID 444 */ 445 __ops_userid_t * 446 __ops_add_userid(__ops_key_t *key, const __ops_userid_t *userid) 447 { 448 __ops_userid_t *uidp; 449 450 EXPAND_ARRAY(key, uid); 451 /* initialise new entry in array */ 452 uidp = &key->uids[key->uidc++]; 453 uidp->userid = NULL; 454 /* now copy it */ 455 return __ops_copy_userid(uidp, userid); 456 } 457 458 void print_packet_hex(const __ops_subpacket_t *pkt); 459 460 /** 461 \ingroup Core_Keys 462 \brief Add packet to key 463 \param keydata Key to which to add packet 464 \param packet Packet to add 465 \return Pointer to new packet 466 */ 467 __ops_subpacket_t * 468 __ops_add_subpacket(__ops_key_t *keydata, const __ops_subpacket_t *packet) 469 { 470 __ops_subpacket_t *subpktp; 471 472 EXPAND_ARRAY(keydata, packet); 473 /* initialise new entry in array */ 474 subpktp = &keydata->packets[keydata->packetc++]; 475 subpktp->length = 0; 476 subpktp->raw = NULL; 477 /* now copy it */ 478 return __ops_copy_packet(subpktp, packet); 479 } 480 481 /** 482 \ingroup Core_Keys 483 \brief Add signed User ID to key 484 \param keydata Key to which to add signed User ID 485 \param userid User ID to add 486 \param sigpacket Packet to add 487 */ 488 void 489 __ops_add_signed_userid(__ops_key_t *keydata, 490 const __ops_userid_t *userid, 491 const __ops_subpacket_t *sigpacket) 492 { 493 __ops_subpacket_t *pkt; 494 __ops_userid_t *uid; 495 496 uid = __ops_add_userid(keydata, userid); 497 pkt = __ops_add_subpacket(keydata, sigpacket); 498 499 /* 500 * add entry in sigs array to link the userid and sigpacket 501 * and add ptr to it from the sigs array */ 502 EXPAND_ARRAY(keydata, sig); 503 504 /**setup new entry in array */ 505 keydata->sigs[keydata->sigc].userid = uid; 506 keydata->sigs[keydata->sigc].packet = pkt; 507 508 keydata->sigc++; 509 } 510 511 /** 512 \ingroup Core_Keys 513 \brief Add selfsigned User ID to key 514 \param keydata Key to which to add user ID 515 \param userid Self-signed User ID to add 516 \return 1 if OK; else 0 517 */ 518 unsigned 519 __ops_add_selfsigned_userid(__ops_key_t *keydata, __ops_userid_t *userid) 520 { 521 __ops_create_sig_t *sig; 522 __ops_subpacket_t sigpacket; 523 __ops_memory_t *mem_userid = NULL; 524 __ops_output_t *useridoutput = NULL; 525 __ops_memory_t *mem_sig = NULL; 526 __ops_output_t *sigoutput = NULL; 527 528 /* 529 * create signature packet for this userid 530 */ 531 532 /* create userid pkt */ 533 __ops_setup_memory_write(&useridoutput, &mem_userid, 128); 534 __ops_write_struct_userid(useridoutput, userid); 535 536 /* create sig for this pkt */ 537 sig = __ops_create_sig_new(); 538 __ops_sig_start_key_sig(sig, &keydata->key.seckey.pubkey, userid, 539 OPS_CERT_POSITIVE); 540 __ops_add_birthtime(sig, time(NULL)); 541 __ops_add_issuer_keyid(sig, keydata->key_id); 542 __ops_add_primary_userid(sig, 1); 543 __ops_end_hashed_subpkts(sig); 544 545 __ops_setup_memory_write(&sigoutput, &mem_sig, 128); 546 __ops_write_sig(sigoutput, sig, &keydata->key.seckey.pubkey, 547 &keydata->key.seckey); 548 549 /* add this packet to keydata */ 550 sigpacket.length = __ops_mem_len(mem_sig); 551 sigpacket.raw = __ops_mem_data(mem_sig); 552 553 /* add userid to keydata */ 554 __ops_add_signed_userid(keydata, userid, &sigpacket); 555 556 /* cleanup */ 557 __ops_create_sig_delete(sig); 558 __ops_output_delete(useridoutput); 559 __ops_output_delete(sigoutput); 560 __ops_memory_free(mem_userid); 561 __ops_memory_free(mem_sig); 562 563 return 1; 564 } 565 566 /** 567 \ingroup Core_Keys 568 \brief Initialise __ops_key_t 569 \param keydata Keydata to initialise 570 \param type OPS_PTAG_CT_PUBLIC_KEY or OPS_PTAG_CT_SECRET_KEY 571 */ 572 void 573 __ops_keydata_init(__ops_key_t *keydata, const __ops_content_tag_t type) 574 { 575 if (keydata->type != OPS_PTAG_CT_RESERVED) { 576 (void) fprintf(stderr, 577 "__ops_keydata_init: wrong keydata type\n"); 578 } else if (type != OPS_PTAG_CT_PUBLIC_KEY && 579 type != OPS_PTAG_CT_SECRET_KEY) { 580 (void) fprintf(stderr, "__ops_keydata_init: wrong type\n"); 581 } else { 582 keydata->type = type; 583 } 584 } 585 586 587 /* used to point to data during keyring read */ 588 typedef struct keyringcb_t { 589 __ops_keyring_t *keyring; /* the keyring we're reading */ 590 } keyringcb_t; 591 592 593 static __ops_cb_ret_t 594 cb_keyring_read(const __ops_packet_t *pkt, __ops_cbdata_t *cbinfo) 595 { 596 __ops_keyring_t *keyring; 597 keyringcb_t *cb; 598 599 cb = __ops_callback_arg(cbinfo); 600 keyring = cb->keyring; 601 switch (pkt->tag) { 602 case OPS_PARSER_PTAG: 603 case OPS_PTAG_CT_ENCRYPTED_SECRET_KEY: 604 /* we get these because we didn't prompt */ 605 case OPS_PTAG_CT_SIGNATURE_HEADER: 606 case OPS_PTAG_CT_SIGNATURE_FOOTER: 607 case OPS_PTAG_CT_SIGNATURE: 608 case OPS_PTAG_CT_TRUST: 609 case OPS_PARSER_ERRCODE: 610 break; 611 case OPS_PTAG_SS_KEY_EXPIRY: 612 EXPAND_ARRAY(keyring, key); 613 if (keyring->keyc > 0) { 614 keyring->keys[keyring->keyc - 1].key.pubkey.duration = pkt->u.ss_time.time; 615 } 616 break; 617 default: 618 break; 619 } 620 621 return OPS_RELEASE_MEMORY; 622 } 623 624 /** 625 \ingroup HighLevel_KeyringRead 626 627 \brief Reads a keyring from a file 628 629 \param keyring Pointer to an existing __ops_keyring_t struct 630 \param armour 1 if file is armoured; else 0 631 \param filename Filename of keyring to be read 632 633 \return __ops 1 if OK; 0 on error 634 635 \note Keyring struct must already exist. 636 637 \note Can be used with either a public or secret keyring. 638 639 \note You must call __ops_keyring_free() after usage to free alloc-ed memory. 640 641 \note If you call this twice on the same keyring struct, without calling 642 __ops_keyring_free() between these calls, you will introduce a memory leak. 643 644 \sa __ops_keyring_read_from_mem() 645 \sa __ops_keyring_free() 646 647 */ 648 649 unsigned 650 __ops_keyring_fileread(__ops_keyring_t *keyring, 651 const unsigned armour, 652 const char *filename) 653 { 654 __ops_stream_t *stream; 655 keyringcb_t cb; 656 unsigned res = 1; 657 int fd; 658 659 (void) memset(&cb, 0x0, sizeof(cb)); 660 cb.keyring = keyring; 661 stream = __ops_new(sizeof(*stream)); 662 663 /* add this for the moment, */ 664 /* 665 * \todo need to fix the problems with reading signature subpackets 666 * later 667 */ 668 669 /* __ops_parse_options(parse,OPS_PTAG_SS_ALL,OPS_PARSE_RAW); */ 670 __ops_parse_options(stream, OPS_PTAG_SS_ALL, OPS_PARSE_PARSED); 671 672 #ifdef O_BINARY 673 fd = open(filename, O_RDONLY | O_BINARY); 674 #else 675 fd = open(filename, O_RDONLY); 676 #endif 677 if (fd < 0) { 678 __ops_stream_delete(stream); 679 perror(filename); 680 return 0; 681 } 682 #ifdef USE_MMAP_FOR_FILES 683 __ops_reader_set_mmap(stream, fd); 684 #else 685 __ops_reader_set_fd(stream, fd); 686 #endif 687 688 __ops_set_callback(stream, cb_keyring_read, &cb); 689 690 if (armour) { 691 __ops_reader_push_dearmour(stream); 692 } 693 res = __ops_parse_and_accumulate(keyring, stream); 694 __ops_print_errors(__ops_stream_get_errors(stream)); 695 696 if (armour) { 697 __ops_reader_pop_dearmour(stream); 698 } 699 700 (void)close(fd); 701 702 __ops_stream_delete(stream); 703 704 return res; 705 } 706 707 /** 708 \ingroup HighLevel_KeyringRead 709 710 \brief Reads a keyring from memory 711 712 \param keyring Pointer to existing __ops_keyring_t struct 713 \param armour 1 if file is armoured; else 0 714 \param mem Pointer to a __ops_memory_t struct containing keyring to be read 715 716 \return __ops 1 if OK; 0 on error 717 718 \note Keyring struct must already exist. 719 720 \note Can be used with either a public or secret keyring. 721 722 \note You must call __ops_keyring_free() after usage to free alloc-ed memory. 723 724 \note If you call this twice on the same keyring struct, without calling 725 __ops_keyring_free() between these calls, you will introduce a memory leak. 726 727 \sa __ops_keyring_fileread 728 \sa __ops_keyring_free 729 */ 730 unsigned 731 __ops_keyring_read_from_mem(__ops_io_t *io, 732 __ops_keyring_t *keyring, 733 const unsigned armour, 734 __ops_memory_t *mem) 735 { 736 __ops_stream_t *stream; 737 const unsigned noaccum = 0; 738 keyringcb_t cb; 739 unsigned res; 740 741 (void) memset(&cb, 0x0, sizeof(cb)); 742 cb.keyring = keyring; 743 stream = __ops_new(sizeof(*stream)); 744 __ops_parse_options(stream, OPS_PTAG_SS_ALL, OPS_PARSE_PARSED); 745 __ops_setup_memory_read(io, &stream, mem, &cb, cb_keyring_read, 746 noaccum); 747 if (armour) { 748 __ops_reader_push_dearmour(stream); 749 } 750 res = (unsigned)__ops_parse_and_accumulate(keyring, stream); 751 __ops_print_errors(__ops_stream_get_errors(stream)); 752 if (armour) { 753 __ops_reader_pop_dearmour(stream); 754 } 755 /* don't call teardown_memory_read because memory was passed in */ 756 __ops_stream_delete(stream); 757 return res; 758 } 759 760 /** 761 \ingroup HighLevel_KeyringRead 762 763 \brief Frees keyring's contents (but not keyring itself) 764 765 \param keyring Keyring whose data is to be freed 766 767 \note This does not free keyring itself, just the memory alloc-ed in it. 768 */ 769 void 770 __ops_keyring_free(__ops_keyring_t *keyring) 771 { 772 (void)free(keyring->keys); 773 keyring->keys = NULL; 774 keyring->keyc = keyring->keyvsize = 0; 775 } 776 777 /* simple function to print out a binary keyid */ 778 void 779 __ops_pkeyid(FILE *fp, const uint8_t *keyid, size_t size) 780 { 781 size_t i; 782 783 for (i = 0 ; i < size ; i++) { 784 (void) fprintf(fp, "%02x", keyid[i]); 785 } 786 } 787 788 /** 789 \ingroup HighLevel_KeyringFind 790 791 \brief Finds key in keyring from its Key ID 792 793 \param keyring Keyring to be searched 794 \param keyid ID of required key 795 796 \return Pointer to key, if found; NULL, if not found 797 798 \note This returns a pointer to the key inside the given keyring, 799 not a copy. Do not free it after use. 800 801 */ 802 const __ops_key_t * 803 __ops_getkeybyid(__ops_io_t *io, const __ops_keyring_t *keyring, 804 const uint8_t *keyid, unsigned *from) 805 { 806 for ( ; keyring && *from < keyring->keyc; *from += 1) { 807 if (__ops_get_debug_level(__FILE__)) { 808 (void) fprintf(io->errs, 809 "__ops_getkeybyid: keyring keyid "); 810 __ops_pkeyid(io->errs, keyring->keys[*from].key_id, 811 OPS_KEY_ID_SIZE); 812 (void) fprintf(io->errs, ", keyid "); 813 __ops_pkeyid(io->errs, keyid, OPS_KEY_ID_SIZE); 814 (void) fprintf(io->errs, "\n"); 815 } 816 if (memcmp(keyring->keys[*from].key_id, keyid, 817 OPS_KEY_ID_SIZE) == 0) { 818 return &keyring->keys[*from]; 819 } 820 if (memcmp(&keyring->keys[*from].key_id[OPS_KEY_ID_SIZE / 2], 821 keyid, OPS_KEY_ID_SIZE / 2) == 0) { 822 return &keyring->keys[*from]; 823 } 824 } 825 return NULL; 826 } 827 828 /* convert a string keyid into a binary keyid */ 829 static void 830 str2keyid(const char *userid, uint8_t *keyid, size_t len) 831 { 832 static const char *uppers = "0123456789ABCDEF"; 833 static const char *lowers = "0123456789abcdef"; 834 const char *hi; 835 const char *lo; 836 uint8_t hichar; 837 uint8_t lochar; 838 size_t j; 839 int i; 840 841 for (i = j = 0 ; j < len && userid[i] && userid[i + 1] ; i += 2, j++) { 842 if ((hi = strchr(uppers, userid[i])) == NULL) { 843 if ((hi = strchr(lowers, userid[i])) == NULL) { 844 break; 845 } 846 hichar = (hi - lowers); 847 } else { 848 hichar = (hi - uppers); 849 } 850 if ((lo = strchr(uppers, userid[i + 1])) == NULL) { 851 if ((lo = strchr(lowers, userid[i + 1])) == NULL) { 852 break; 853 } 854 lochar = (lo - lowers); 855 } else { 856 lochar = (lo - uppers); 857 } 858 keyid[j] = (hichar << 4) | (lochar); 859 } 860 keyid[j] = 0x0; 861 } 862 863 /* return the next key which matches, starting searching at *from */ 864 static const __ops_key_t * 865 getkeybyname(__ops_io_t *io, 866 const __ops_keyring_t *keyring, 867 const char *name, 868 unsigned *from) 869 { 870 const __ops_key_t *kp; 871 __ops_userid_t *uidp; 872 unsigned i = 0; 873 __ops_key_t *keyp; 874 unsigned savedstart; 875 regex_t r; 876 uint8_t keyid[OPS_KEY_ID_SIZE + 1]; 877 size_t len; 878 879 if (!keyring) { 880 return NULL; 881 } 882 len = strlen(name); 883 if (__ops_get_debug_level(__FILE__)) { 884 (void) fprintf(io->outs, "[%u] name '%s', len %zu\n", 885 *from, name, len); 886 } 887 /* first try name as a keyid */ 888 (void) memset(keyid, 0x0, sizeof(keyid)); 889 str2keyid(name, keyid, sizeof(keyid)); 890 if (__ops_get_debug_level(__FILE__)) { 891 (void) fprintf(io->outs, 892 "name \"%s\", keyid %02x%02x%02x%02x\n", 893 name, 894 keyid[0], keyid[1], keyid[2], keyid[3]); 895 } 896 savedstart = *from; 897 if ((kp = __ops_getkeybyid(io, keyring, keyid, from)) != NULL) { 898 return kp; 899 } 900 *from = savedstart; 901 if (__ops_get_debug_level(__FILE__)) { 902 (void) fprintf(io->outs, "regex match '%s' from %u\n", 903 name, *from); 904 } 905 /* match on full name or email address as a NOSUB, ICASE regexp */ 906 (void) regcomp(&r, name, REG_EXTENDED | REG_ICASE); 907 for (keyp = &keyring->keys[*from]; *from < keyring->keyc; *from += 1, keyp++) { 908 uidp = keyp->uids; 909 for (i = 0 ; i < keyp->uidc; i++, uidp++) { 910 if (__ops_get_debug_level(__FILE__)) { 911 (void) fprintf(io->outs, 912 "keyid \"%s\" len %" 913 PRIsize "u, keyid[len] '%c'\n", 914 (char *) uidp->userid, 915 len, uidp->userid[len]); 916 } 917 if (regexec(&r, (char *)uidp->userid, 0, NULL, 0) == 0) { 918 regfree(&r); 919 return keyp; 920 } 921 } 922 } 923 regfree(&r); 924 return NULL; 925 } 926 927 /** 928 \ingroup HighLevel_KeyringFind 929 930 \brief Finds key from its User ID 931 932 \param keyring Keyring to be searched 933 \param userid User ID of required key 934 935 \return Pointer to Key, if found; NULL, if not found 936 937 \note This returns a pointer to the key inside the keyring, not a 938 copy. Do not free it. 939 940 */ 941 const __ops_key_t * 942 __ops_getkeybyname(__ops_io_t *io, 943 const __ops_keyring_t *keyring, 944 const char *name) 945 { 946 unsigned from; 947 948 from = 0; 949 return getkeybyname(io, keyring, name, &from); 950 } 951 952 const __ops_key_t * 953 __ops_getnextkeybyname(__ops_io_t *io, 954 const __ops_keyring_t *keyring, 955 const char *name, 956 unsigned *n) 957 { 958 return getkeybyname(io, keyring, name, n); 959 } 960 961 /** 962 \ingroup HighLevel_KeyringList 963 964 \brief Prints all keys in keyring to stdout. 965 966 \param keyring Keyring to use 967 968 \return none 969 */ 970 int 971 __ops_keyring_list(__ops_io_t *io, const __ops_keyring_t *keyring) 972 { 973 __ops_key_t *key; 974 unsigned n; 975 976 (void) fprintf(io->res, "%u key%s\n", keyring->keyc, 977 (keyring->keyc == 1) ? "" : "s"); 978 for (n = 0, key = keyring->keys; n < keyring->keyc; ++n, ++key) { 979 if (__ops_is_key_secret(key)) { 980 __ops_print_keydata(io, key, "sec", 981 &key->key.seckey.pubkey); 982 } else { 983 __ops_print_keydata(io, key, "pub", &key->key.pubkey); 984 } 985 (void) fputc('\n', io->res); 986 } 987 return 1; 988 } 989 990 /* this interface isn't right - hook into callback for getting passphrase */ 991 char * 992 __ops_export_key(__ops_io_t *io, const __ops_key_t *keydata, uint8_t *passphrase) 993 { 994 __ops_output_t *output; 995 __ops_memory_t *mem; 996 char *cp; 997 998 __OPS_USED(io); 999 __ops_setup_memory_write(&output, &mem, 128); 1000 if (keydata->type == OPS_PTAG_CT_PUBLIC_KEY) { 1001 __ops_write_xfer_pubkey(output, keydata, 1); 1002 } else { 1003 __ops_write_xfer_seckey(output, keydata, passphrase, 1004 strlen((char *)passphrase), 1); 1005 } 1006 cp = netpgp_strdup(__ops_mem_data(mem)); 1007 __ops_teardown_memory_write(output, mem); 1008 return cp; 1009 } 1010 1011 /* add a key to a public keyring */ 1012 int 1013 __ops_add_to_pubring(__ops_keyring_t *keyring, const __ops_pubkey_t *pubkey) 1014 { 1015 __ops_key_t *key; 1016 time_t duration; 1017 1018 EXPAND_ARRAY(keyring, key); 1019 key = &keyring->keys[keyring->keyc++]; 1020 duration = key->key.pubkey.duration; 1021 (void) memset(key, 0x0, sizeof(*key)); 1022 __ops_keyid(key->key_id, OPS_KEY_ID_SIZE, pubkey); 1023 __ops_fingerprint(&key->fingerprint, pubkey); 1024 key->type = OPS_PTAG_CT_PUBLIC_KEY; 1025 key->key.pubkey = *pubkey; 1026 key->key.pubkey.duration = duration; 1027 return 1; 1028 } 1029 1030 /* add a key to a secret keyring */ 1031 int 1032 __ops_add_to_secring(__ops_keyring_t *keyring, const __ops_seckey_t *seckey) 1033 { 1034 const __ops_pubkey_t *pubkey; 1035 __ops_key_t *key; 1036 1037 EXPAND_ARRAY(keyring, key); 1038 key = &keyring->keys[keyring->keyc++]; 1039 (void) memset(key, 0x0, sizeof(*key)); 1040 pubkey = &seckey->pubkey; 1041 __ops_keyid(key->key_id, OPS_KEY_ID_SIZE, pubkey); 1042 __ops_fingerprint(&key->fingerprint, pubkey); 1043 key->type = OPS_PTAG_CT_SECRET_KEY; 1044 key->key.seckey = *seckey; 1045 return 1; 1046 } 1047 1048 /* append one keyring to another */ 1049 int 1050 __ops_append_keyring(__ops_keyring_t *keyring, __ops_keyring_t *newring) 1051 { 1052 unsigned i; 1053 1054 for (i = 0 ; i < newring->keyc ; i++) { 1055 EXPAND_ARRAY(keyring, key); 1056 (void) memcpy(&keyring->keys[keyring->keyc], &newring->keys[i], 1057 sizeof(newring->keys[i])); 1058 keyring->keyc += 1; 1059 } 1060 return 1; 1061 } 1062