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