keyring.c revision 1.45
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.45 2010/09/01 06:20:23 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 "netpgpdefs.h" 90#include "netpgpdigest.h" 91 92 93 94/** 95 \ingroup HighLevel_Keyring 96 97 \brief Creates a new __ops_key_t struct 98 99 \return A new __ops_key_t struct, initialised to zero. 100 101 \note The returned __ops_key_t struct must be freed after use with __ops_keydata_free. 102*/ 103 104__ops_key_t * 105__ops_keydata_new(void) 106{ 107 return calloc(1, sizeof(__ops_key_t)); 108} 109 110 111/** 112 \ingroup HighLevel_Keyring 113 114 \brief Frees keydata and its memory 115 116 \param keydata Key to be freed. 117 118 \note This frees the keydata itself, as well as any other memory alloc-ed by it. 119*/ 120void 121__ops_keydata_free(__ops_key_t *keydata) 122{ 123 unsigned n; 124 125 for (n = 0; n < keydata->uidc; ++n) { 126 __ops_userid_free(&keydata->uids[n]); 127 } 128 free(keydata->uids); 129 keydata->uids = NULL; 130 keydata->uidc = 0; 131 132 for (n = 0; n < keydata->packetc; ++n) { 133 __ops_subpacket_free(&keydata->packets[n]); 134 } 135 free(keydata->packets); 136 keydata->packets = NULL; 137 keydata->packetc = 0; 138 139 if (keydata->type == OPS_PTAG_CT_PUBLIC_KEY) { 140 __ops_pubkey_free(&keydata->key.pubkey); 141 } else { 142 __ops_seckey_free(&keydata->key.seckey); 143 } 144 145 free(keydata); 146} 147 148/** 149 \ingroup HighLevel_KeyGeneral 150 151 \brief Returns the public key in the given keydata. 152 \param keydata 153 154 \return Pointer to public key 155 156 \note This is not a copy, do not free it after use. 157*/ 158 159const __ops_pubkey_t * 160__ops_get_pubkey(const __ops_key_t *keydata) 161{ 162 return (keydata->type == OPS_PTAG_CT_PUBLIC_KEY) ? 163 &keydata->key.pubkey : 164 &keydata->key.seckey.pubkey; 165} 166 167/** 168\ingroup HighLevel_KeyGeneral 169 170\brief Check whether this is a secret key or not. 171*/ 172 173unsigned 174__ops_is_key_secret(const __ops_key_t *data) 175{ 176 return data->type != OPS_PTAG_CT_PUBLIC_KEY; 177} 178 179/** 180 \ingroup HighLevel_KeyGeneral 181 182 \brief Returns the secret key in the given keydata. 183 184 \note This is not a copy, do not free it after use. 185 186 \note This returns a const. If you need to be able to write to this 187 pointer, use __ops_get_writable_seckey 188*/ 189 190const __ops_seckey_t * 191__ops_get_seckey(const __ops_key_t *data) 192{ 193 return (data->type == OPS_PTAG_CT_SECRET_KEY) ? 194 &data->key.seckey : NULL; 195} 196 197/** 198 \ingroup HighLevel_KeyGeneral 199 200 \brief Returns the secret key in the given keydata. 201 202 \note This is not a copy, do not free it after use. 203 204 \note If you do not need to be able to modify this key, there is an 205 equivalent read-only function __ops_get_seckey. 206*/ 207 208__ops_seckey_t * 209__ops_get_writable_seckey(__ops_key_t *data) 210{ 211 return (data->type == OPS_PTAG_CT_SECRET_KEY) ? 212 &data->key.seckey : NULL; 213} 214 215/* utility function to zero out memory */ 216void 217__ops_forget(void *vp, unsigned size) 218{ 219 (void) memset(vp, 0x0, size); 220} 221 222typedef struct { 223 FILE *passfp; 224 const __ops_key_t *key; 225 char *passphrase; 226 __ops_seckey_t *seckey; 227} decrypt_t; 228 229static __ops_cb_ret_t 230decrypt_cb(const __ops_packet_t *pkt, __ops_cbdata_t *cbinfo) 231{ 232 const __ops_contents_t *content = &pkt->u; 233 decrypt_t *decrypt; 234 char pass[MAX_PASSPHRASE_LENGTH]; 235 236 decrypt = __ops_callback_arg(cbinfo); 237 switch (pkt->tag) { 238 case OPS_PARSER_PTAG: 239 case OPS_PTAG_CT_USER_ID: 240 case OPS_PTAG_CT_SIGNATURE: 241 case OPS_PTAG_CT_SIGNATURE_HEADER: 242 case OPS_PTAG_CT_SIGNATURE_FOOTER: 243 case OPS_PTAG_CT_TRUST: 244 break; 245 246 case OPS_GET_PASSPHRASE: 247 (void) __ops_getpassphrase(decrypt->passfp, pass, sizeof(pass)); 248 *content->skey_passphrase.passphrase = netpgp_strdup(pass); 249 __ops_forget(pass, (unsigned)sizeof(pass)); 250 return OPS_KEEP_MEMORY; 251 252 case OPS_PARSER_ERRCODE: 253 switch (content->errcode.errcode) { 254 case OPS_E_P_MPI_FORMAT_ERROR: 255 /* Generally this means a bad passphrase */ 256 fprintf(stderr, "Bad passphrase!\n"); 257 return OPS_RELEASE_MEMORY; 258 259 case OPS_E_P_PACKET_CONSUMED: 260 /* And this is because of an error we've accepted */ 261 return OPS_RELEASE_MEMORY; 262 default: 263 break; 264 } 265 (void) fprintf(stderr, "parse error: %s\n", 266 __ops_errcode(content->errcode.errcode)); 267 return OPS_FINISHED; 268 269 case OPS_PARSER_ERROR: 270 fprintf(stderr, "parse error: %s\n", content->error); 271 return OPS_FINISHED; 272 273 case OPS_PTAG_CT_SECRET_KEY: 274 if ((decrypt->seckey = calloc(1, sizeof(*decrypt->seckey))) == NULL) { 275 (void) fprintf(stderr, "decrypt_cb: bad alloc\n"); 276 return OPS_FINISHED; 277 } 278 decrypt->seckey->checkhash = calloc(1, OPS_CHECKHASH_SIZE); 279 *decrypt->seckey = content->seckey; 280 return OPS_KEEP_MEMORY; 281 282 case OPS_PARSER_PACKET_END: 283 /* nothing to do */ 284 break; 285 286 default: 287 fprintf(stderr, "Unexpected tag %d (0x%x)\n", pkt->tag, 288 pkt->tag); 289 return OPS_FINISHED; 290 } 291 292 return OPS_RELEASE_MEMORY; 293} 294 295/** 296\ingroup Core_Keys 297\brief Decrypts secret key from given keydata with given passphrase 298\param key Key from which to get secret key 299\param passphrase Passphrase to use to decrypt secret key 300\return secret key 301*/ 302__ops_seckey_t * 303__ops_decrypt_seckey(const __ops_key_t *key, void *passfp) 304{ 305 __ops_stream_t *stream; 306 const int printerrors = 1; 307 decrypt_t decrypt; 308 309 (void) memset(&decrypt, 0x0, sizeof(decrypt)); 310 decrypt.key = key; 311 decrypt.passfp = passfp; 312 stream = __ops_new(sizeof(*stream)); 313 __ops_keydata_reader_set(stream, key); 314 __ops_set_callback(stream, decrypt_cb, &decrypt); 315 stream->readinfo.accumulate = 1; 316 __ops_parse(stream, !printerrors); 317 return decrypt.seckey; 318} 319 320/** 321\ingroup Core_Keys 322\brief Set secret key in content 323\param content Content to be set 324\param key Keydata to get secret key from 325*/ 326void 327__ops_set_seckey(__ops_contents_t *cont, const __ops_key_t *key) 328{ 329 *cont->get_seckey.seckey = &key->key.seckey; 330} 331 332/** 333\ingroup Core_Keys 334\brief Get Key ID from keydata 335\param key Keydata to get Key ID from 336\return Pointer to Key ID inside keydata 337*/ 338const uint8_t * 339__ops_get_key_id(const __ops_key_t *key) 340{ 341 return key->sigid; 342} 343 344/** 345\ingroup Core_Keys 346\brief How many User IDs in this key? 347\param key Keydata to check 348\return Num of user ids 349*/ 350unsigned 351__ops_get_userid_count(const __ops_key_t *key) 352{ 353 return key->uidc; 354} 355 356/** 357\ingroup Core_Keys 358\brief Get indexed user id from key 359\param key Key to get user id from 360\param index Which key to get 361\return Pointer to requested user id 362*/ 363const uint8_t * 364__ops_get_userid(const __ops_key_t *key, unsigned subscript) 365{ 366 return key->uids[subscript]; 367} 368 369/** 370 \ingroup HighLevel_Supported 371 \brief Checks whether key's algorithm and type are supported by OpenPGP::SDK 372 \param keydata Key to be checked 373 \return 1 if key algorithm and type are supported by OpenPGP::SDK; 0 if not 374*/ 375 376unsigned 377__ops_is_key_supported(const __ops_key_t *key) 378{ 379 if (key->type == OPS_PTAG_CT_PUBLIC_KEY) { 380 switch(key->key.pubkey.alg) { 381 case OPS_PKA_RSA: 382 case OPS_PKA_DSA: 383 case OPS_PKA_ELGAMAL: 384 return 1; 385 default: 386 break; 387 } 388 } 389 return 0; 390} 391 392/* \todo check where userid pointers are copied */ 393/** 394\ingroup Core_Keys 395\brief Copy user id, including contents 396\param dst Destination User ID 397\param src Source User ID 398\note If dst already has a userid, it will be freed. 399*/ 400static uint8_t * 401__ops_copy_userid(uint8_t **dst, const uint8_t *src) 402{ 403 size_t len; 404 405 len = strlen((const char *) src); 406 if (*dst) { 407 free(*dst); 408 } 409 if ((*dst = calloc(1, len + 1)) == NULL) { 410 (void) fprintf(stderr, "__ops_copy_userid: bad alloc\n"); 411 } else { 412 (void) memcpy(*dst, src, len); 413 } 414 return *dst; 415} 416 417/* \todo check where pkt pointers are copied */ 418/** 419\ingroup Core_Keys 420\brief Copy packet, including contents 421\param dst Destination packet 422\param src Source packet 423\note If dst already has a packet, it will be freed. 424*/ 425static __ops_subpacket_t * 426__ops_copy_packet(__ops_subpacket_t *dst, const __ops_subpacket_t *src) 427{ 428 if (dst->raw) { 429 free(dst->raw); 430 } 431 if ((dst->raw = calloc(1, src->length)) == NULL) { 432 (void) fprintf(stderr, "__ops_copy_packet: bad alloc\n"); 433 } else { 434 dst->length = src->length; 435 (void) memcpy(dst->raw, src->raw, src->length); 436 } 437 return dst; 438} 439 440/** 441\ingroup Core_Keys 442\brief Add User ID to key 443\param key Key to which to add User ID 444\param userid User ID to add 445\return Pointer to new User ID 446*/ 447uint8_t * 448__ops_add_userid(__ops_key_t *key, const uint8_t *userid) 449{ 450 uint8_t **uidp; 451 452 EXPAND_ARRAY(key, uid); 453 /* initialise new entry in array */ 454 uidp = &key->uids[key->uidc++]; 455 *uidp = NULL; 456 /* now copy it */ 457 return __ops_copy_userid(uidp, userid); 458} 459 460void print_packet_hex(const __ops_subpacket_t *pkt); 461 462/** 463\ingroup Core_Keys 464\brief Add packet to key 465\param keydata Key to which to add packet 466\param packet Packet to add 467\return Pointer to new packet 468*/ 469__ops_subpacket_t * 470__ops_add_subpacket(__ops_key_t *keydata, const __ops_subpacket_t *packet) 471{ 472 __ops_subpacket_t *subpktp; 473 474 EXPAND_ARRAY(keydata, packet); 475 /* initialise new entry in array */ 476 subpktp = &keydata->packets[keydata->packetc++]; 477 subpktp->length = 0; 478 subpktp->raw = NULL; 479 /* now copy it */ 480 return __ops_copy_packet(subpktp, packet); 481} 482 483/** 484\ingroup Core_Keys 485\brief Add selfsigned User ID to key 486\param keydata Key to which to add user ID 487\param userid Self-signed User ID to add 488\return 1 if OK; else 0 489*/ 490unsigned 491__ops_add_selfsigned_userid(__ops_key_t *key, uint8_t *userid) 492{ 493 __ops_create_sig_t *sig; 494 __ops_subpacket_t sigpacket; 495 __ops_memory_t *mem_userid = NULL; 496 __ops_output_t *useridoutput = NULL; 497 __ops_memory_t *mem_sig = NULL; 498 __ops_output_t *sigoutput = NULL; 499 500 /* 501 * create signature packet for this userid 502 */ 503 504 /* create userid pkt */ 505 __ops_setup_memory_write(&useridoutput, &mem_userid, 128); 506 __ops_write_struct_userid(useridoutput, userid); 507 508 /* create sig for this pkt */ 509 sig = __ops_create_sig_new(); 510 __ops_sig_start_key_sig(sig, &key->key.seckey.pubkey, userid, OPS_CERT_POSITIVE); 511 __ops_add_time(sig, (int64_t)time(NULL), "birth"); 512 __ops_add_issuer_keyid(sig, key->sigid); 513 __ops_add_primary_userid(sig, 1); 514 __ops_end_hashed_subpkts(sig); 515 516 __ops_setup_memory_write(&sigoutput, &mem_sig, 128); 517 __ops_write_sig(sigoutput, sig, &key->key.seckey.pubkey, &key->key.seckey); 518 519 /* add this packet to key */ 520 sigpacket.length = __ops_mem_len(mem_sig); 521 sigpacket.raw = __ops_mem_data(mem_sig); 522 523 /* add userid to key */ 524 (void) __ops_add_userid(key, userid); 525 (void) __ops_add_subpacket(key, &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_enum 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; 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, 609 sizeof(pkt->u.ss_issuer)); 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; 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; 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/** 807 \ingroup HighLevel_KeyringFind 808 809 \brief Finds key in keyring from its Key ID 810 811 \param keyring Keyring to be searched 812 \param keyid ID of required key 813 814 \return Pointer to key, if found; NULL, if not found 815 816 \note This returns a pointer to the key inside the given keyring, 817 not a copy. Do not free it after use. 818 819*/ 820const __ops_key_t * 821__ops_getkeybyid(__ops_io_t *io, const __ops_keyring_t *keyring, 822 const uint8_t *keyid, unsigned *from, __ops_pubkey_t **pubkey) 823{ 824 for ( ; keyring && *from < keyring->keyc; *from += 1) { 825 if (__ops_get_debug_level(__FILE__)) { 826 hexdump(io->errs, "keyring keyid", keyring->keys[*from].sigid, OPS_KEY_ID_SIZE); 827 hexdump(io->errs, "keyid", keyid, OPS_KEY_ID_SIZE); 828 } 829 if (memcmp(keyring->keys[*from].sigid, keyid, OPS_KEY_ID_SIZE) == 0 || 830 memcmp(&keyring->keys[*from].sigid[OPS_KEY_ID_SIZE / 2], 831 keyid, OPS_KEY_ID_SIZE / 2) == 0) { 832 if (pubkey) { 833 *pubkey = &keyring->keys[*from].key.pubkey; 834 } 835 return &keyring->keys[*from]; 836 } 837 if (memcmp(&keyring->keys[*from].encid, "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0", OPS_KEY_ID_SIZE) == 0) { 838 continue; 839 } 840 if (memcmp(&keyring->keys[*from].encid, keyid, OPS_KEY_ID_SIZE) == 0 || 841 memcmp(&keyring->keys[*from].encid[OPS_KEY_ID_SIZE / 2], keyid, OPS_KEY_ID_SIZE / 2) == 0) { 842 if (pubkey) { 843 *pubkey = &keyring->keys[*from].enckey; 844 } 845 return &keyring->keys[*from]; 846 } 847 } 848 return NULL; 849} 850 851/* convert a string keyid into a binary keyid */ 852static void 853str2keyid(const char *userid, uint8_t *keyid, size_t len) 854{ 855 static const char *uppers = "0123456789ABCDEF"; 856 static const char *lowers = "0123456789abcdef"; 857 const char *hi; 858 const char *lo; 859 uint8_t hichar; 860 uint8_t lochar; 861 size_t j; 862 int i; 863 864 for (i = 0, j = 0 ; j < len && userid[i] && userid[i + 1] ; i += 2, j++) { 865 if ((hi = strchr(uppers, userid[i])) == NULL) { 866 if ((hi = strchr(lowers, userid[i])) == NULL) { 867 break; 868 } 869 hichar = (uint8_t)(hi - lowers); 870 } else { 871 hichar = (uint8_t)(hi - uppers); 872 } 873 if ((lo = strchr(uppers, userid[i + 1])) == NULL) { 874 if ((lo = strchr(lowers, userid[i + 1])) == NULL) { 875 break; 876 } 877 lochar = (uint8_t)(lo - lowers); 878 } else { 879 lochar = (uint8_t)(lo - uppers); 880 } 881 keyid[j] = (hichar << 4) | (lochar); 882 } 883 keyid[j] = 0x0; 884} 885 886/* return the next key which matches, starting searching at *from */ 887static const __ops_key_t * 888getkeybyname(__ops_io_t *io, 889 const __ops_keyring_t *keyring, 890 const char *name, 891 unsigned *from) 892{ 893 const __ops_key_t *kp; 894 uint8_t **uidp; 895 unsigned i = 0; 896 __ops_key_t *keyp; 897 unsigned savedstart; 898 regex_t r; 899 uint8_t keyid[OPS_KEY_ID_SIZE + 1]; 900 size_t len; 901 902 if (!keyring) { 903 return NULL; 904 } 905 len = strlen(name); 906 if (__ops_get_debug_level(__FILE__)) { 907 (void) fprintf(io->outs, "[%u] name '%s', len %zu\n", 908 *from, name, len); 909 } 910 /* first try name as a keyid */ 911 (void) memset(keyid, 0x0, sizeof(keyid)); 912 str2keyid(name, keyid, sizeof(keyid)); 913 if (__ops_get_debug_level(__FILE__)) { 914 hexdump(io->outs, "keyid", keyid, 4); 915 } 916 savedstart = *from; 917 if ((kp = __ops_getkeybyid(io, keyring, keyid, from, NULL)) != NULL) { 918 return kp; 919 } 920 *from = savedstart; 921 if (__ops_get_debug_level(__FILE__)) { 922 (void) fprintf(io->outs, "regex match '%s' from %u\n", 923 name, *from); 924 } 925 /* match on full name or email address as a NOSUB, ICASE regexp */ 926 (void) regcomp(&r, name, REG_EXTENDED | REG_ICASE); 927 for (keyp = &keyring->keys[*from]; *from < keyring->keyc; *from += 1, keyp++) { 928 uidp = keyp->uids; 929 for (i = 0 ; i < keyp->uidc; i++, uidp++) { 930 if (regexec(&r, (char *)*uidp, 0, NULL, 0) == 0) { 931 if (__ops_get_debug_level(__FILE__)) { 932 (void) fprintf(io->outs, 933 "MATCHED keyid \"%s\" len %" PRIsize "u\n", 934 (char *) *uidp, len); 935 } 936 regfree(&r); 937 return keyp; 938 } 939 } 940 } 941 regfree(&r); 942 return NULL; 943} 944 945/** 946 \ingroup HighLevel_KeyringFind 947 948 \brief Finds key from its User ID 949 950 \param keyring Keyring to be searched 951 \param userid User ID of required key 952 953 \return Pointer to Key, if found; NULL, if not found 954 955 \note This returns a pointer to the key inside the keyring, not a 956 copy. Do not free it. 957 958*/ 959const __ops_key_t * 960__ops_getkeybyname(__ops_io_t *io, 961 const __ops_keyring_t *keyring, 962 const char *name) 963{ 964 unsigned from; 965 966 from = 0; 967 return getkeybyname(io, keyring, name, &from); 968} 969 970const __ops_key_t * 971__ops_getnextkeybyname(__ops_io_t *io, 972 const __ops_keyring_t *keyring, 973 const char *name, 974 unsigned *n) 975{ 976 return getkeybyname(io, keyring, name, n); 977} 978 979/** 980 \ingroup HighLevel_KeyringList 981 982 \brief Prints all keys in keyring to stdout. 983 984 \param keyring Keyring to use 985 986 \return none 987*/ 988int 989__ops_keyring_list(__ops_io_t *io, const __ops_keyring_t *keyring, const int psigs) 990{ 991 __ops_key_t *key; 992 unsigned n; 993 994 (void) fprintf(io->res, "%u key%s\n", keyring->keyc, 995 (keyring->keyc == 1) ? "" : "s"); 996 for (n = 0, key = keyring->keys; n < keyring->keyc; ++n, ++key) { 997 if (__ops_is_key_secret(key)) { 998 __ops_print_keydata(io, keyring, key, "sec", 999 &key->key.seckey.pubkey, 0); 1000 } else { 1001 __ops_print_keydata(io, keyring, key, "signature ", &key->key.pubkey, psigs); 1002 } 1003 (void) fputc('\n', io->res); 1004 } 1005 return 1; 1006} 1007 1008int 1009__ops_keyring_json(__ops_io_t *io, const __ops_keyring_t *keyring, mj_t *obj, const int psigs) 1010{ 1011 __ops_key_t *key; 1012 unsigned n; 1013 1014 (void) memset(obj, 0x0, sizeof(*obj)); 1015 mj_create(obj, "array"); 1016 obj->size = keyring->keyvsize; 1017 if (__ops_get_debug_level(__FILE__)) { 1018 (void) fprintf(io->errs, "__ops_keyring_json: vsize %u\n", obj->size); 1019 } 1020 if ((obj->value.v = calloc(sizeof(*obj->value.v), obj->size)) == NULL) { 1021 (void) fprintf(io->errs, "calloc failure\n"); 1022 return 0; 1023 } 1024 for (n = 0, key = keyring->keys; n < keyring->keyc; ++n, ++key) { 1025 if (__ops_is_key_secret(key)) { 1026 __ops_sprint_mj(io, keyring, key, &obj->value.v[obj->c], 1027 "sec", &key->key.seckey.pubkey, psigs); 1028 } else { 1029 __ops_sprint_mj(io, keyring, key, &obj->value.v[obj->c], 1030 "signature ", &key->key.pubkey, psigs); 1031 } 1032 if (obj->value.v[obj->c].type != 0) { 1033 obj->c += 1; 1034 } 1035 } 1036 if (__ops_get_debug_level(__FILE__)) { 1037 char *s; 1038 1039 mj_asprint(&s, obj); 1040 (void) fprintf(stderr, "__ops_keyring_json: '%s'\n", s); 1041 free(s); 1042 } 1043 return 1; 1044} 1045 1046 1047/* this interface isn't right - hook into callback for getting passphrase */ 1048char * 1049__ops_export_key(__ops_io_t *io, const __ops_key_t *keydata, uint8_t *passphrase) 1050{ 1051 __ops_output_t *output; 1052 __ops_memory_t *mem; 1053 char *cp; 1054 1055 __OPS_USED(io); 1056 __ops_setup_memory_write(&output, &mem, 128); 1057 if (keydata->type == OPS_PTAG_CT_PUBLIC_KEY) { 1058 __ops_write_xfer_pubkey(output, keydata, 1); 1059 } else { 1060 __ops_write_xfer_seckey(output, keydata, passphrase, 1061 strlen((char *)passphrase), 1); 1062 } 1063 cp = netpgp_strdup(__ops_mem_data(mem)); 1064 __ops_teardown_memory_write(output, mem); 1065 return cp; 1066} 1067 1068/* add a key to a public keyring */ 1069int 1070__ops_add_to_pubring(__ops_keyring_t *keyring, const __ops_pubkey_t *pubkey, __ops_content_enum tag) 1071{ 1072 __ops_key_t *key; 1073 time_t duration; 1074 1075 if (__ops_get_debug_level(__FILE__)) { 1076 fprintf(stderr, "__ops_add_to_pubring (type %u)\n", tag); 1077 } 1078 switch(tag) { 1079 case OPS_PTAG_CT_PUBLIC_KEY: 1080 EXPAND_ARRAY(keyring, key); 1081 key = &keyring->keys[keyring->keyc++]; 1082 duration = key->key.pubkey.duration; 1083 (void) memset(key, 0x0, sizeof(*key)); 1084 key->type = tag; 1085 __ops_keyid(key->sigid, OPS_KEY_ID_SIZE, pubkey, keyring->hashtype); 1086 __ops_fingerprint(&key->sigfingerprint, pubkey, keyring->hashtype); 1087 key->key.pubkey = *pubkey; 1088 key->key.pubkey.duration = duration; 1089 return 1; 1090 case OPS_PTAG_CT_PUBLIC_SUBKEY: 1091 /* subkey is not the first */ 1092 key = &keyring->keys[keyring->keyc - 1]; 1093 __ops_keyid(key->encid, OPS_KEY_ID_SIZE, pubkey, keyring->hashtype); 1094 duration = key->key.pubkey.duration; 1095 (void) memcpy(&key->enckey, pubkey, sizeof(key->enckey)); 1096 key->enckey.duration = duration; 1097 return 1; 1098 default: 1099 return 0; 1100 } 1101} 1102 1103/* add a key to a secret keyring */ 1104int 1105__ops_add_to_secring(__ops_keyring_t *keyring, const __ops_seckey_t *seckey) 1106{ 1107 const __ops_pubkey_t *pubkey; 1108 __ops_key_t *key; 1109 1110 if (__ops_get_debug_level(__FILE__)) { 1111 fprintf(stderr, "__ops_add_to_secring\n"); 1112 } 1113 if (keyring->keyc > 0) { 1114 key = &keyring->keys[keyring->keyc - 1]; 1115 if (__ops_get_debug_level(__FILE__) && 1116 key->key.pubkey.alg == OPS_PKA_DSA && 1117 seckey->pubkey.alg == OPS_PKA_ELGAMAL) { 1118 fprintf(stderr, "__ops_add_to_secring: found elgamal seckey\n"); 1119 } 1120 } 1121 EXPAND_ARRAY(keyring, key); 1122 key = &keyring->keys[keyring->keyc++]; 1123 (void) memset(key, 0x0, sizeof(*key)); 1124 pubkey = &seckey->pubkey; 1125 __ops_keyid(key->sigid, OPS_KEY_ID_SIZE, pubkey, keyring->hashtype); 1126 __ops_fingerprint(&key->sigfingerprint, pubkey, keyring->hashtype); 1127 key->type = OPS_PTAG_CT_SECRET_KEY; 1128 key->key.seckey = *seckey; 1129 if (__ops_get_debug_level(__FILE__)) { 1130 fprintf(stderr, "__ops_add_to_secring: keyc %u\n", keyring->keyc); 1131 } 1132 return 1; 1133} 1134 1135/* append one keyring to another */ 1136int 1137__ops_append_keyring(__ops_keyring_t *keyring, __ops_keyring_t *newring) 1138{ 1139 unsigned i; 1140 1141 for (i = 0 ; i < newring->keyc ; i++) { 1142 EXPAND_ARRAY(keyring, key); 1143 (void) memcpy(&keyring->keys[keyring->keyc], &newring->keys[i], 1144 sizeof(newring->keys[i])); 1145 keyring->keyc += 1; 1146 } 1147 return 1; 1148} 1149