keyring.c revision 1.33
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.33 2010/03/13 23:30:41 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*/ 119void 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 158const __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 172unsigned 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 189const __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 */ 215void 216__ops_forget(void *vp, unsigned size) 217{ 218 (void) memset(vp, 0x0, size); 219} 220 221typedef struct { 222 FILE *passfp; 223 const __ops_key_t *key; 224 char *passphrase; 225 __ops_seckey_t *seckey; 226} decrypt_t; 227 228static __ops_cb_ret_t 229decrypt_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*/ 325void 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*/ 337const 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*/ 349unsigned 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*/ 362const 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 375unsigned 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*/ 398static __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*/ 423static __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 458void 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 selfsigned User ID to key 484\param keydata Key to which to add user ID 485\param userid Self-signed User ID to add 486\return 1 if OK; else 0 487*/ 488unsigned 489__ops_add_selfsigned_userid(__ops_key_t *keydata, __ops_userid_t *userid) 490{ 491 __ops_create_sig_t *sig; 492 __ops_subpacket_t sigpacket; 493 __ops_memory_t *mem_userid = NULL; 494 __ops_output_t *useridoutput = NULL; 495 __ops_memory_t *mem_sig = NULL; 496 __ops_output_t *sigoutput = NULL; 497 498 /* 499 * create signature packet for this userid 500 */ 501 502 /* create userid pkt */ 503 __ops_setup_memory_write(&useridoutput, &mem_userid, 128); 504 __ops_write_struct_userid(useridoutput, userid); 505 506 /* create sig for this pkt */ 507 sig = __ops_create_sig_new(); 508 __ops_sig_start_key_sig(sig, &keydata->key.seckey.pubkey, userid, 509 OPS_CERT_POSITIVE); 510 __ops_add_birthtime(sig, time(NULL)); 511 __ops_add_issuer_keyid(sig, keydata->key_id); 512 __ops_add_primary_userid(sig, 1); 513 __ops_end_hashed_subpkts(sig); 514 515 __ops_setup_memory_write(&sigoutput, &mem_sig, 128); 516 __ops_write_sig(sigoutput, sig, &keydata->key.seckey.pubkey, 517 &keydata->key.seckey); 518 519 /* add this packet to keydata */ 520 sigpacket.length = __ops_mem_len(mem_sig); 521 sigpacket.raw = __ops_mem_data(mem_sig); 522 523 /* add userid to keydata */ 524 (void) __ops_add_userid(keydata, userid); 525 (void) __ops_add_subpacket(keydata, &sigpacket); 526 527 /* cleanup */ 528 __ops_create_sig_delete(sig); 529 __ops_output_delete(useridoutput); 530 __ops_output_delete(sigoutput); 531 __ops_memory_free(mem_userid); 532 __ops_memory_free(mem_sig); 533 534 return 1; 535} 536 537/** 538\ingroup Core_Keys 539\brief Initialise __ops_key_t 540\param keydata Keydata to initialise 541\param type OPS_PTAG_CT_PUBLIC_KEY or OPS_PTAG_CT_SECRET_KEY 542*/ 543void 544__ops_keydata_init(__ops_key_t *keydata, const __ops_content_tag_t type) 545{ 546 if (keydata->type != OPS_PTAG_CT_RESERVED) { 547 (void) fprintf(stderr, 548 "__ops_keydata_init: wrong keydata type\n"); 549 } else if (type != OPS_PTAG_CT_PUBLIC_KEY && 550 type != OPS_PTAG_CT_SECRET_KEY) { 551 (void) fprintf(stderr, "__ops_keydata_init: wrong type\n"); 552 } else { 553 keydata->type = type; 554 } 555} 556 557/* used to point to data during keyring read */ 558typedef struct keyringcb_t { 559 __ops_keyring_t *keyring; /* the keyring we're reading */ 560} keyringcb_t; 561 562 563static __ops_cb_ret_t 564cb_keyring_read(const __ops_packet_t *pkt, __ops_cbdata_t *cbinfo) 565{ 566 __ops_keyring_t *keyring; 567 __ops_revoke_t *revocation; 568 __ops_key_t *key; 569 keyringcb_t *cb; 570 571 cb = __ops_callback_arg(cbinfo); 572 keyring = cb->keyring; 573 switch (pkt->tag) { 574 case OPS_PARSER_PTAG: 575 case OPS_PTAG_CT_ENCRYPTED_SECRET_KEY: 576 /* we get these because we didn't prompt */ 577 break; 578 case OPS_PTAG_CT_SIGNATURE_HEADER: 579 key = &keyring->keys[keyring->keyc - 1]; 580 EXPAND_ARRAY(key, subsig); 581 key->subsigs[key->subsigc].uid = key->uidc - 1; 582 (void) memcpy(&key->subsigs[key->subsigc].sig, &pkt->u.sig, 583 sizeof(pkt->u.sig)); 584 key->subsigc += 1; 585 break; 586 case OPS_PTAG_CT_SIGNATURE: 587 key = &keyring->keys[keyring->keyc - 1]; 588 EXPAND_ARRAY(key, subsig); 589 key->subsigs[key->subsigc].uid = key->uidc - 1; 590 (void) memcpy(&key->subsigs[key->subsigc].sig, &pkt->u.sig, 591 sizeof(pkt->u.sig)); 592 key->subsigc += 1; 593 break; 594 case OPS_PTAG_CT_TRUST: 595 key = &keyring->keys[keyring->keyc - 1]; 596 key->subsigs[key->subsigc - 1].trustlevel = pkt->u.ss_trust.level; 597 key->subsigs[key->subsigc - 1].trustamount = pkt->u.ss_trust.amount; 598 break; 599 case OPS_PTAG_SS_KEY_EXPIRY: 600 EXPAND_ARRAY(keyring, key); 601 if (keyring->keyc > 0) { 602 keyring->keys[keyring->keyc - 1].key.pubkey.duration = pkt->u.ss_time.time; 603 } 604 break; 605 case OPS_PTAG_SS_ISSUER_KEY_ID: 606 key = &keyring->keys[keyring->keyc - 1]; 607 (void) memcpy(&key->subsigs[key->subsigc - 1].sig.info.signer_id, 608 pkt->u.ss_issuer.key_id, 609 sizeof(pkt->u.ss_issuer.key_id)); 610 key->subsigs[key->subsigc - 1].sig.info.signer_id_set = 1; 611 break; 612 case OPS_PTAG_SS_CREATION_TIME: 613 key = &keyring->keys[keyring->keyc - 1]; 614 key->subsigs[key->subsigc - 1].sig.info.birthtime = pkt->u.ss_time.time; 615 key->subsigs[key->subsigc - 1].sig.info.birthtime_set = 1; 616 break; 617 case OPS_PTAG_SS_EXPIRATION_TIME: 618 key = &keyring->keys[keyring->keyc - 1]; 619 key->subsigs[key->subsigc - 1].sig.info.duration = pkt->u.ss_time.time; 620 key->subsigs[key->subsigc - 1].sig.info.duration_set = 1; 621 break; 622 case OPS_PTAG_SS_PRIMARY_USER_ID: 623 key = &keyring->keys[keyring->keyc - 1]; 624 key->uid0 = key->uidc - 1; 625 break; 626 case OPS_PTAG_SS_REVOCATION_REASON: 627 key = &keyring->keys[keyring->keyc - 1]; 628 if (key->uidc == 0) { 629 /* revoke whole key */ 630 key->revoked = 1; 631 revocation = &key->revocation; 632 } else { 633 /* revoke the user id */ 634 EXPAND_ARRAY(key, revoke); 635 revocation = &key->revokes[key->revokec]; 636 key->revokes[key->revokec].uid = key->uidc - 1; 637 key->revokec += 1; 638 } 639 revocation->code = pkt->u.ss_revocation.code; 640 revocation->reason = netpgp_strdup(__ops_show_ss_rr_code(pkt->u.ss_revocation.code)); 641 break; 642 case OPS_PTAG_CT_SIGNATURE_FOOTER: 643 case OPS_PARSER_ERRCODE: 644 break; 645 646 default: 647 break; 648 } 649 650 return OPS_RELEASE_MEMORY; 651} 652 653/** 654 \ingroup HighLevel_KeyringRead 655 656 \brief Reads a keyring from a file 657 658 \param keyring Pointer to an existing __ops_keyring_t struct 659 \param armour 1 if file is armoured; else 0 660 \param filename Filename of keyring to be read 661 662 \return __ops 1 if OK; 0 on error 663 664 \note Keyring struct must already exist. 665 666 \note Can be used with either a public or secret keyring. 667 668 \note You must call __ops_keyring_free() after usage to free alloc-ed memory. 669 670 \note If you call this twice on the same keyring struct, without calling 671 __ops_keyring_free() between these calls, you will introduce a memory leak. 672 673 \sa __ops_keyring_read_from_mem() 674 \sa __ops_keyring_free() 675 676*/ 677 678unsigned 679__ops_keyring_fileread(__ops_keyring_t *keyring, 680 const unsigned armour, 681 const char *filename) 682{ 683 __ops_stream_t *stream; 684 keyringcb_t cb; 685 unsigned res = 1; 686 int fd; 687 688 (void) memset(&cb, 0x0, sizeof(cb)); 689 cb.keyring = keyring; 690 stream = __ops_new(sizeof(*stream)); 691 692 /* add this for the moment, */ 693 /* 694 * \todo need to fix the problems with reading signature subpackets 695 * later 696 */ 697 698 /* __ops_parse_options(parse,OPS_PTAG_SS_ALL,OPS_PARSE_RAW); */ 699 __ops_parse_options(stream, OPS_PTAG_SS_ALL, OPS_PARSE_PARSED); 700 701#ifdef O_BINARY 702 fd = open(filename, O_RDONLY | O_BINARY); 703#else 704 fd = open(filename, O_RDONLY); 705#endif 706 if (fd < 0) { 707 __ops_stream_delete(stream); 708 perror(filename); 709 return 0; 710 } 711#ifdef USE_MMAP_FOR_FILES 712 __ops_reader_set_mmap(stream, fd); 713#else 714 __ops_reader_set_fd(stream, fd); 715#endif 716 717 __ops_set_callback(stream, cb_keyring_read, &cb); 718 719 if (armour) { 720 __ops_reader_push_dearmour(stream); 721 } 722 res = __ops_parse_and_accumulate(keyring, stream); 723 __ops_print_errors(__ops_stream_get_errors(stream)); 724 725 if (armour) { 726 __ops_reader_pop_dearmour(stream); 727 } 728 729 (void)close(fd); 730 731 __ops_stream_delete(stream); 732 733 return res; 734} 735 736/** 737 \ingroup HighLevel_KeyringRead 738 739 \brief Reads a keyring from memory 740 741 \param keyring Pointer to existing __ops_keyring_t struct 742 \param armour 1 if file is armoured; else 0 743 \param mem Pointer to a __ops_memory_t struct containing keyring to be read 744 745 \return __ops 1 if OK; 0 on error 746 747 \note Keyring struct must already exist. 748 749 \note Can be used with either a public or secret keyring. 750 751 \note You must call __ops_keyring_free() after usage to free alloc-ed memory. 752 753 \note If you call this twice on the same keyring struct, without calling 754 __ops_keyring_free() between these calls, you will introduce a memory leak. 755 756 \sa __ops_keyring_fileread 757 \sa __ops_keyring_free 758*/ 759unsigned 760__ops_keyring_read_from_mem(__ops_io_t *io, 761 __ops_keyring_t *keyring, 762 const unsigned armour, 763 __ops_memory_t *mem) 764{ 765 __ops_stream_t *stream; 766 const unsigned noaccum = 0; 767 keyringcb_t cb; 768 unsigned res; 769 770 (void) memset(&cb, 0x0, sizeof(cb)); 771 cb.keyring = keyring; 772 stream = __ops_new(sizeof(*stream)); 773 __ops_parse_options(stream, OPS_PTAG_SS_ALL, OPS_PARSE_PARSED); 774 __ops_setup_memory_read(io, &stream, mem, &cb, cb_keyring_read, 775 noaccum); 776 if (armour) { 777 __ops_reader_push_dearmour(stream); 778 } 779 res = (unsigned)__ops_parse_and_accumulate(keyring, stream); 780 __ops_print_errors(__ops_stream_get_errors(stream)); 781 if (armour) { 782 __ops_reader_pop_dearmour(stream); 783 } 784 /* don't call teardown_memory_read because memory was passed in */ 785 __ops_stream_delete(stream); 786 return res; 787} 788 789/** 790 \ingroup HighLevel_KeyringRead 791 792 \brief Frees keyring's contents (but not keyring itself) 793 794 \param keyring Keyring whose data is to be freed 795 796 \note This does not free keyring itself, just the memory alloc-ed in it. 797 */ 798void 799__ops_keyring_free(__ops_keyring_t *keyring) 800{ 801 (void)free(keyring->keys); 802 keyring->keys = NULL; 803 keyring->keyc = keyring->keyvsize = 0; 804} 805 806/* simple function to print out a binary keyid */ 807void 808__ops_pkeyid(FILE *fp, const uint8_t *keyid, size_t size) 809{ 810 size_t i; 811 812 for (i = 0 ; i < size ; i++) { 813 (void) fprintf(fp, "%02x", keyid[i]); 814 } 815} 816 817/** 818 \ingroup HighLevel_KeyringFind 819 820 \brief Finds key in keyring from its Key ID 821 822 \param keyring Keyring to be searched 823 \param keyid ID of required key 824 825 \return Pointer to key, if found; NULL, if not found 826 827 \note This returns a pointer to the key inside the given keyring, 828 not a copy. Do not free it after use. 829 830*/ 831const __ops_key_t * 832__ops_getkeybyid(__ops_io_t *io, const __ops_keyring_t *keyring, 833 const uint8_t *keyid, unsigned *from) 834{ 835 for ( ; keyring && *from < keyring->keyc; *from += 1) { 836 if (__ops_get_debug_level(__FILE__)) { 837 (void) fprintf(io->errs, 838 "__ops_getkeybyid: keyring keyid "); 839 __ops_pkeyid(io->errs, keyring->keys[*from].key_id, 840 OPS_KEY_ID_SIZE); 841 (void) fprintf(io->errs, ", keyid "); 842 __ops_pkeyid(io->errs, keyid, OPS_KEY_ID_SIZE); 843 (void) fprintf(io->errs, "\n"); 844 } 845 if (memcmp(keyring->keys[*from].key_id, keyid, 846 OPS_KEY_ID_SIZE) == 0) { 847 return &keyring->keys[*from]; 848 } 849 if (memcmp(&keyring->keys[*from].key_id[OPS_KEY_ID_SIZE / 2], 850 keyid, OPS_KEY_ID_SIZE / 2) == 0) { 851 return &keyring->keys[*from]; 852 } 853 } 854 return NULL; 855} 856 857/* convert a string keyid into a binary keyid */ 858static void 859str2keyid(const char *userid, uint8_t *keyid, size_t len) 860{ 861 static const char *uppers = "0123456789ABCDEF"; 862 static const char *lowers = "0123456789abcdef"; 863 const char *hi; 864 const char *lo; 865 uint8_t hichar; 866 uint8_t lochar; 867 size_t j; 868 int i; 869 870 for (i = j = 0 ; j < len && userid[i] && userid[i + 1] ; i += 2, j++) { 871 if ((hi = strchr(uppers, userid[i])) == NULL) { 872 if ((hi = strchr(lowers, userid[i])) == NULL) { 873 break; 874 } 875 hichar = (hi - lowers); 876 } else { 877 hichar = (hi - uppers); 878 } 879 if ((lo = strchr(uppers, userid[i + 1])) == NULL) { 880 if ((lo = strchr(lowers, userid[i + 1])) == NULL) { 881 break; 882 } 883 lochar = (lo - lowers); 884 } else { 885 lochar = (lo - uppers); 886 } 887 keyid[j] = (hichar << 4) | (lochar); 888 } 889 keyid[j] = 0x0; 890} 891 892/* return the next key which matches, starting searching at *from */ 893static const __ops_key_t * 894getkeybyname(__ops_io_t *io, 895 const __ops_keyring_t *keyring, 896 const char *name, 897 unsigned *from) 898{ 899 const __ops_key_t *kp; 900 __ops_userid_t *uidp; 901 unsigned i = 0; 902 __ops_key_t *keyp; 903 unsigned savedstart; 904 regex_t r; 905 uint8_t keyid[OPS_KEY_ID_SIZE + 1]; 906 size_t len; 907 908 if (!keyring) { 909 return NULL; 910 } 911 len = strlen(name); 912 if (__ops_get_debug_level(__FILE__)) { 913 (void) fprintf(io->outs, "[%u] name '%s', len %zu\n", 914 *from, name, len); 915 } 916 /* first try name as a keyid */ 917 (void) memset(keyid, 0x0, sizeof(keyid)); 918 str2keyid(name, keyid, sizeof(keyid)); 919 if (__ops_get_debug_level(__FILE__)) { 920 (void) fprintf(io->outs, 921 "name \"%s\", keyid %02x%02x%02x%02x\n", 922 name, 923 keyid[0], keyid[1], keyid[2], keyid[3]); 924 } 925 savedstart = *from; 926 if ((kp = __ops_getkeybyid(io, keyring, keyid, from)) != NULL) { 927 return kp; 928 } 929 *from = savedstart; 930 if (__ops_get_debug_level(__FILE__)) { 931 (void) fprintf(io->outs, "regex match '%s' from %u\n", 932 name, *from); 933 } 934 /* match on full name or email address as a NOSUB, ICASE regexp */ 935 (void) regcomp(&r, name, REG_EXTENDED | REG_ICASE); 936 for (keyp = &keyring->keys[*from]; *from < keyring->keyc; *from += 1, keyp++) { 937 uidp = keyp->uids; 938 for (i = 0 ; i < keyp->uidc; i++, uidp++) { 939 if (__ops_get_debug_level(__FILE__)) { 940 (void) fprintf(io->outs, 941 "keyid \"%s\" len %" 942 PRIsize "u, keyid[len] '%c'\n", 943 (char *) uidp->userid, 944 len, uidp->userid[len]); 945 } 946 if (regexec(&r, (char *)uidp->userid, 0, NULL, 0) == 0) { 947 regfree(&r); 948 return keyp; 949 } 950 } 951 } 952 regfree(&r); 953 return NULL; 954} 955 956/** 957 \ingroup HighLevel_KeyringFind 958 959 \brief Finds key from its User ID 960 961 \param keyring Keyring to be searched 962 \param userid User ID of required key 963 964 \return Pointer to Key, if found; NULL, if not found 965 966 \note This returns a pointer to the key inside the keyring, not a 967 copy. Do not free it. 968 969*/ 970const __ops_key_t * 971__ops_getkeybyname(__ops_io_t *io, 972 const __ops_keyring_t *keyring, 973 const char *name) 974{ 975 unsigned from; 976 977 from = 0; 978 return getkeybyname(io, keyring, name, &from); 979} 980 981const __ops_key_t * 982__ops_getnextkeybyname(__ops_io_t *io, 983 const __ops_keyring_t *keyring, 984 const char *name, 985 unsigned *n) 986{ 987 return getkeybyname(io, keyring, name, n); 988} 989 990/** 991 \ingroup HighLevel_KeyringList 992 993 \brief Prints all keys in keyring to stdout. 994 995 \param keyring Keyring to use 996 997 \return none 998*/ 999int 1000__ops_keyring_list(__ops_io_t *io, const __ops_keyring_t *keyring, const int psigs) 1001{ 1002 __ops_key_t *key; 1003 unsigned n; 1004 1005 (void) fprintf(io->res, "%u key%s\n", keyring->keyc, 1006 (keyring->keyc == 1) ? "" : "s"); 1007 for (n = 0, key = keyring->keys; n < keyring->keyc; ++n, ++key) { 1008 if (__ops_is_key_secret(key)) { 1009 __ops_print_keydata(io, keyring, key, "sec", 1010 &key->key.seckey.pubkey, 0); 1011 } else { 1012 __ops_print_keydata(io, keyring, key, "pub", &key->key.pubkey, psigs); 1013 } 1014 (void) fputc('\n', io->res); 1015 } 1016 return 1; 1017} 1018 1019 1020/* this interface isn't right - hook into callback for getting passphrase */ 1021char * 1022__ops_export_key(__ops_io_t *io, const __ops_key_t *keydata, uint8_t *passphrase) 1023{ 1024 __ops_output_t *output; 1025 __ops_memory_t *mem; 1026 char *cp; 1027 1028 __OPS_USED(io); 1029 __ops_setup_memory_write(&output, &mem, 128); 1030 if (keydata->type == OPS_PTAG_CT_PUBLIC_KEY) { 1031 __ops_write_xfer_pubkey(output, keydata, 1); 1032 } else { 1033 __ops_write_xfer_seckey(output, keydata, passphrase, 1034 strlen((char *)passphrase), 1); 1035 } 1036 cp = netpgp_strdup(__ops_mem_data(mem)); 1037 __ops_teardown_memory_write(output, mem); 1038 return cp; 1039} 1040 1041/* add a key to a public keyring */ 1042int 1043__ops_add_to_pubring(__ops_keyring_t *keyring, const __ops_pubkey_t *pubkey) 1044{ 1045 __ops_key_t *key; 1046 time_t duration; 1047 1048 EXPAND_ARRAY(keyring, key); 1049 key = &keyring->keys[keyring->keyc++]; 1050 duration = key->key.pubkey.duration; 1051 (void) memset(key, 0x0, sizeof(*key)); 1052 __ops_keyid(key->key_id, OPS_KEY_ID_SIZE, pubkey); 1053 __ops_fingerprint(&key->fingerprint, pubkey); 1054 key->type = OPS_PTAG_CT_PUBLIC_KEY; 1055 key->key.pubkey = *pubkey; 1056 key->key.pubkey.duration = duration; 1057 return 1; 1058} 1059 1060/* add a key to a secret keyring */ 1061int 1062__ops_add_to_secring(__ops_keyring_t *keyring, const __ops_seckey_t *seckey) 1063{ 1064 const __ops_pubkey_t *pubkey; 1065 __ops_key_t *key; 1066 1067 EXPAND_ARRAY(keyring, key); 1068 key = &keyring->keys[keyring->keyc++]; 1069 (void) memset(key, 0x0, sizeof(*key)); 1070 pubkey = &seckey->pubkey; 1071 __ops_keyid(key->key_id, OPS_KEY_ID_SIZE, pubkey); 1072 __ops_fingerprint(&key->fingerprint, pubkey); 1073 key->type = OPS_PTAG_CT_SECRET_KEY; 1074 key->key.seckey = *seckey; 1075 return 1; 1076} 1077 1078/* append one keyring to another */ 1079int 1080__ops_append_keyring(__ops_keyring_t *keyring, __ops_keyring_t *newring) 1081{ 1082 unsigned i; 1083 1084 for (i = 0 ; i < newring->keyc ; i++) { 1085 EXPAND_ARRAY(keyring, key); 1086 (void) memcpy(&keyring->keys[keyring->keyc], &newring->keys[i], 1087 sizeof(newring->keys[i])); 1088 keyring->keyc += 1; 1089 } 1090 return 1; 1091} 1092