keyring.c revision 1.3
11638Srgrimes/* 21638Srgrimes * Copyright (c) 2005-2008 Nominet UK (www.nic.uk) 31638Srgrimes * All rights reserved. 41638Srgrimes * Contributors: Ben Laurie, Rachel Willmer. The Contributors have asserted 51638Srgrimes * their moral rights under the UK Copyright Design and Patents Act 1988 to 61638Srgrimes * be recorded as the authors of this copyright work. 71638Srgrimes * 81638Srgrimes * Licensed under the Apache License, Version 2.0 (the "License"); you may not 91638Srgrimes * use this file except in compliance with the License. 101638Srgrimes * 111638Srgrimes * You may obtain a copy of the License at 121638Srgrimes * http://www.apache.org/licenses/LICENSE-2.0 131638Srgrimes * 141638Srgrimes * Unless required by applicable law or agreed to in writing, software 151638Srgrimes * distributed under the License is distributed on an "AS IS" BASIS, 161638Srgrimes * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 171638Srgrimes * 181638Srgrimes * See the License for the specific language governing permissions and 191638Srgrimes * limitations under the License. 201638Srgrimes */ 211638Srgrimes 221638Srgrimes/** \file 231638Srgrimes */ 241638Srgrimes#include "config.h" 251638Srgrimes 261638Srgrimes#include "keyring.h" 271638Srgrimes#include "packet-parse.h" 281638Srgrimes#include "signature.h" 291638Srgrimes#include "netpgpsdk.h" 301638Srgrimes 311638Srgrimes#include "readerwriter.h" 321638Srgrimes#include "netpgpdefs.h" 331638Srgrimes#include "keyring_local.h" 341638Srgrimes#include "parse_local.h" 351638Srgrimes#include "validate.h" 361638Srgrimes 371638Srgrimes#include <stdlib.h> 381638Srgrimes#include <string.h> 391638Srgrimes 401638Srgrimes#ifdef HAVE_UNISTD_H 411638Srgrimes#include <unistd.h> 421638Srgrimes#endif 431638Srgrimes 441638Srgrimes#ifdef HAVE_TERMIOS_H 451638Srgrimes#include <termios.h> 461638Srgrimes#endif 471638Srgrimes 481638Srgrimes#include <fcntl.h> 491638Srgrimes 501638Srgrimes#ifdef HAVE_ASSERT_H 511638Srgrimes#include <assert.h> 521638Srgrimes#endif 531638Srgrimes 541638Srgrimes 551638Srgrimes/** 561638Srgrimes \ingroup HighLevel_Keyring 571638Srgrimes 581638Srgrimes \brief Creates a new __ops_keydata_t struct 591638Srgrimes 601638Srgrimes \return A new __ops_keydata_t struct, initialised to zero. 611638Srgrimes 621638Srgrimes \note The returned __ops_keydata_t struct must be freed after use with __ops_keydata_free. 631638Srgrimes*/ 641638Srgrimes 651638Srgrimes__ops_keydata_t * 661638Srgrimes__ops_keydata_new(void) 671638Srgrimes{ 681638Srgrimes return calloc(1, sizeof(__ops_keydata_t)); 691638Srgrimes} 701638Srgrimes 711638Srgrimes 721638Srgrimes/** 731638Srgrimes \ingroup HighLevel_Keyring 741638Srgrimes 751638Srgrimes \brief Frees keydata and its memory 761638Srgrimes 771638Srgrimes \param keydata Key to be freed. 781638Srgrimes 791638Srgrimes \note This frees the keydata itself, as well as any other memory alloc-ed by it. 801638Srgrimes*/ 811638Srgrimesvoid 821638Srgrimes__ops_keydata_free(__ops_keydata_t * keydata) 831638Srgrimes{ 841638Srgrimes unsigned n; 851638Srgrimes 861638Srgrimes for (n = 0; n < keydata->nuids; ++n) 871638Srgrimes __ops_user_id_free(&keydata->uids[n]); 881638Srgrimes free(keydata->uids); 891638Srgrimes keydata->uids = NULL; 901638Srgrimes keydata->nuids = 0; 911638Srgrimes 921638Srgrimes for (n = 0; n < keydata->npackets; ++n) 931638Srgrimes __ops_packet_free(&keydata->packets[n]); 941638Srgrimes free(keydata->packets); 951638Srgrimes keydata->packets = NULL; 961638Srgrimes keydata->npackets = 0; 971638Srgrimes 981638Srgrimes if (keydata->type == OPS_PTAG_CT_PUBLIC_KEY) 991638Srgrimes __ops_public_key_free(&keydata->key.pkey); 1001638Srgrimes else 1011638Srgrimes __ops_secret_key_free(&keydata->key.skey); 1021638Srgrimes 1031638Srgrimes free(keydata); 1041638Srgrimes} 1051638Srgrimes 1061638Srgrimes/** 1071638Srgrimes \ingroup HighLevel_KeyGeneral 1081638Srgrimes 1091638Srgrimes \brief Returns the public key in the given keydata. 1101638Srgrimes \param keydata 1111638Srgrimes 1121638Srgrimes \return Pointer to public key 1131638Srgrimes 1141638Srgrimes \note This is not a copy, do not free it after use. 1151638Srgrimes*/ 1161638Srgrimes 1171638Srgrimesconst __ops_public_key_t * 1181638Srgrimes__ops_get_public_key_from_data(const __ops_keydata_t * keydata) 1191638Srgrimes{ 1201638Srgrimes if (keydata->type == OPS_PTAG_CT_PUBLIC_KEY) 1211638Srgrimes return &keydata->key.pkey; 1221638Srgrimes return &keydata->key.skey.public_key; 1231638Srgrimes} 1241638Srgrimes 125/** 126\ingroup HighLevel_KeyGeneral 127 128\brief Check whether this is a secret key or not. 129*/ 130 131bool 132__ops_is_key_secret(const __ops_keydata_t * data) 133{ 134 return data->type != OPS_PTAG_CT_PUBLIC_KEY; 135} 136 137/** 138 \ingroup HighLevel_KeyGeneral 139 140 \brief Returns the secret key in the given keydata. 141 142 \note This is not a copy, do not free it after use. 143 144 \note This returns a const. If you need to be able to write to this pointer, use __ops_get_writable_secret_key_from_data 145*/ 146 147const __ops_secret_key_t * 148__ops_get_secret_key_from_data(const __ops_keydata_t * data) 149{ 150 if (data->type != OPS_PTAG_CT_SECRET_KEY) 151 return NULL; 152 153 return &data->key.skey; 154} 155 156/** 157 \ingroup HighLevel_KeyGeneral 158 159 \brief Returns the secret key in the given keydata. 160 161 \note This is not a copy, do not free it after use. 162 163 \note If you do not need to be able to modify this key, there is an equivalent read-only function __ops_get_secret_key_from_data. 164*/ 165 166__ops_secret_key_t * 167__ops_get_writable_secret_key_from_data(__ops_keydata_t * data) 168{ 169 if (data->type != OPS_PTAG_CT_SECRET_KEY) 170 return NULL; 171 172 return &data->key.skey; 173} 174 175typedef struct { 176 const __ops_keydata_t *key; 177 char *pphrase; 178 __ops_secret_key_t *skey; 179} decrypt_t; 180 181static __ops_parse_cb_return_t 182decrypt_cb(const __ops_parser_content_t * contents, 183 __ops_parse_cb_info_t * cbinfo) 184{ 185 const __ops_parser_content_union_t *content = &contents->u; 186 decrypt_t *decrypt = __ops_parse_cb_get_arg(cbinfo); 187 188 OPS_USED(cbinfo); 189 190 switch (contents->tag) { 191 case OPS_PARSER_PTAG: 192 case OPS_PTAG_CT_USER_ID: 193 case OPS_PTAG_CT_SIGNATURE: 194 case OPS_PTAG_CT_SIGNATURE_HEADER: 195 case OPS_PTAG_CT_SIGNATURE_FOOTER: 196 case OPS_PTAG_CT_TRUST: 197 break; 198 199 case OPS_PARSER_CMD_GET_SK_PASSPHRASE: 200 *content->secret_key_passphrase.passphrase = decrypt->pphrase; 201 return OPS_KEEP_MEMORY; 202 203 case OPS_PARSER_ERRCODE: 204 switch (content->errcode.errcode) { 205 case OPS_E_P_MPI_FORMAT_ERROR: 206 /* Generally this means a bad passphrase */ 207 fprintf(stderr, "Bad passphrase!\n"); 208 goto done; 209 210 case OPS_E_P_PACKET_CONSUMED: 211 /* And this is because of an error we've accepted */ 212 goto done; 213 214 default: 215 fprintf(stderr, "parse error: %s\n", 216 __ops_errcode(content->errcode.errcode)); 217 assert( /* CONSTCOND */ 0); 218 break; 219 } 220 221 break; 222 223 case OPS_PARSER_ERROR: 224 fprintf(stderr, "parse error: %s\n", content->error.error); 225 assert( /* CONSTCOND */ 0); 226 break; 227 228 case OPS_PTAG_CT_SECRET_KEY: 229 decrypt->skey = calloc(1, sizeof(*decrypt->skey)); 230 *decrypt->skey = content->secret_key; 231 return OPS_KEEP_MEMORY; 232 233 case OPS_PARSER_PACKET_END: 234 /* nothing to do */ 235 break; 236 237 default: 238 fprintf(stderr, "Unexpected tag %d (0x%x)\n", contents->tag, 239 contents->tag); 240 assert( /* CONSTCOND */ 0); 241 } 242 243done: 244 return OPS_RELEASE_MEMORY; 245} 246 247/** 248\ingroup Core_Keys 249\brief Decrypts secret key from given keydata with given passphrase 250\param key Key from which to get secret key 251\param pphrase Passphrase to use to decrypt secret key 252\return secret key 253*/ 254__ops_secret_key_t * 255__ops_decrypt_secret_key_from_data(const __ops_keydata_t * key, 256 const char *pphrase) 257{ 258 __ops_parse_info_t *pinfo; 259 decrypt_t decrypt; 260 261 (void) memset(&decrypt, 0x0, sizeof(decrypt)); 262 decrypt.key = key; 263 decrypt.pphrase = strdup(pphrase); 264 265 pinfo = __ops_parse_info_new(); 266 267 __ops_keydata_reader_set(pinfo, key); 268 __ops_parse_cb_set(pinfo, decrypt_cb, &decrypt); 269 pinfo->rinfo.accumulate = true; 270 271 __ops_parse(pinfo); 272 273 return decrypt.skey; 274} 275 276/** 277\ingroup Core_Keys 278\brief Set secret key in content 279\param content Content to be set 280\param key Keydata to get secret key from 281*/ 282void 283__ops_set_secret_key(__ops_parser_content_union_t * content, const __ops_keydata_t * key) 284{ 285 *content->get_secret_key.secret_key = &key->key.skey; 286} 287 288/** 289\ingroup Core_Keys 290\brief Get Key ID from keydata 291\param key Keydata to get Key ID from 292\return Pointer to Key ID inside keydata 293*/ 294const unsigned char * 295__ops_get_key_id(const __ops_keydata_t * key) 296{ 297 return key->key_id; 298} 299 300/** 301\ingroup Core_Keys 302\brief How many User IDs in this key? 303\param key Keydata to check 304\return Num of user ids 305*/ 306unsigned 307__ops_get_user_id_count(const __ops_keydata_t * key) 308{ 309 return key->nuids; 310} 311 312/** 313\ingroup Core_Keys 314\brief Get indexed user id from key 315\param key Key to get user id from 316\param index Which key to get 317\return Pointer to requested user id 318*/ 319const unsigned char * 320__ops_get_user_id(const __ops_keydata_t * key, unsigned subscript) 321{ 322 return key->uids[subscript].user_id; 323} 324 325/** 326 \ingroup HighLevel_Supported 327 \brief Checks whether key's algorithm and type are supported by OpenPGP::SDK 328 \param keydata Key to be checked 329 \return true if key algorithm and type are supported by OpenPGP::SDK; false if not 330*/ 331 332bool 333__ops_is_key_supported(const __ops_keydata_t *keydata) 334{ 335 if (keydata->type == OPS_PTAG_CT_PUBLIC_KEY) { 336 if (keydata->key.pkey.algorithm == OPS_PKA_RSA) { 337 return true; 338 } 339 } else if (keydata->type == OPS_PTAG_CT_PUBLIC_KEY) { 340 if (keydata->key.pkey.algorithm == OPS_PKA_DSA) { 341 return true; 342 } 343 } 344 return false; 345} 346 347 348/** 349 \ingroup HighLevel_KeyringFind 350 351 \brief Returns key inside a keyring, chosen by index 352 353 \param keyring Pointer to existing keyring 354 \param index Index of required key 355 356 \note Index starts at 0 357 358 \note This returns a pointer to the original key, not a copy. You do not need to free the key after use. 359 360 \return Pointer to the required key; or NULL if index too large. 361 362 Example code: 363 \code 364 void example(const __ops_keyring_t* keyring) 365 { 366 __ops_keydata_t* keydata=NULL; 367 keydata=__ops_keyring_get_key_by_index(keyring, 0); 368 ... 369 } 370 \endcode 371*/ 372 373const __ops_keydata_t * 374__ops_keyring_get_key_by_index(const __ops_keyring_t * keyring, int subscript) 375{ 376 if (subscript >= keyring->nkeys) 377 return NULL; 378 return &keyring->keys[subscript]; 379} 380 381/* \todo check where userid pointers are copied */ 382/** 383\ingroup Core_Keys 384\brief Copy user id, including contents 385\param dst Destination User ID 386\param src Source User ID 387\note If dst already has a user_id, it will be freed. 388*/ 389void 390__ops_copy_userid(__ops_user_id_t * dst, const __ops_user_id_t * src) 391{ 392 size_t len = strlen((char *) src->user_id); 393 if (dst->user_id) 394 free(dst->user_id); 395 dst->user_id = calloc(1, len + 1); 396 397 (void) memcpy(dst->user_id, src->user_id, len); 398} 399 400/* \todo check where pkt pointers are copied */ 401/** 402\ingroup Core_Keys 403\brief Copy packet, including contents 404\param dst Destination packet 405\param src Source packet 406\note If dst already has a packet, it will be freed. 407*/ 408void 409__ops_copy_packet(__ops_packet_t * dst, const __ops_packet_t * src) 410{ 411 if (dst->raw) 412 free(dst->raw); 413 dst->raw = calloc(1, src->length); 414 415 dst->length = src->length; 416 (void) memcpy(dst->raw, src->raw, src->length); 417} 418 419/** 420\ingroup Core_Keys 421\brief Add User ID to keydata 422\param keydata Key to which to add User ID 423\param userid User ID to add 424\return Pointer to new User ID 425*/ 426__ops_user_id_t * 427__ops_add_userid_to_keydata(__ops_keydata_t * keydata, const __ops_user_id_t * userid) 428{ 429 __ops_user_id_t *new_uid = NULL; 430 431 EXPAND_ARRAY(keydata, uids); 432 433 /* initialise new entry in array */ 434 new_uid = &keydata->uids[keydata->nuids]; 435 436 new_uid->user_id = NULL; 437 438 /* now copy it */ 439 __ops_copy_userid(new_uid, userid); 440 keydata->nuids++; 441 442 return new_uid; 443} 444 445/** 446\ingroup Core_Keys 447\brief Add packet to key 448\param keydata Key to which to add packet 449\param packet Packet to add 450\return Pointer to new packet 451*/ 452__ops_packet_t * 453__ops_add_packet_to_keydata(__ops_keydata_t * keydata, const __ops_packet_t * packet) 454{ 455 __ops_packet_t *new_pkt = NULL; 456 457 EXPAND_ARRAY(keydata, packets); 458 459 /* initialise new entry in array */ 460 new_pkt = &keydata->packets[keydata->npackets]; 461 new_pkt->length = 0; 462 new_pkt->raw = NULL; 463 464 /* now copy it */ 465 __ops_copy_packet(new_pkt, packet); 466 keydata->npackets++; 467 468 return new_pkt; 469} 470 471/** 472\ingroup Core_Keys 473\brief Add signed User ID to key 474\param keydata Key to which to add signed User ID 475\param user_id User ID to add 476\param sigpacket Packet to add 477*/ 478void 479__ops_add_signed_userid_to_keydata(__ops_keydata_t * keydata, const __ops_user_id_t * user_id, const __ops_packet_t * sigpacket) 480{ 481 /* int i=0; */ 482 __ops_user_id_t *uid = NULL; 483 __ops_packet_t *pkt = NULL; 484 485 uid = __ops_add_userid_to_keydata(keydata, user_id); 486 pkt = __ops_add_packet_to_keydata(keydata, sigpacket); 487 488 /* 489 * add entry in sigs array to link the userid and sigpacket 490 */ 491 492 /* and add ptr to it from the sigs array */ 493 EXPAND_ARRAY(keydata, sigs); 494 495 /**setup new entry in array */ 496 497 keydata->sigs[keydata->nsigs].userid = uid; 498 keydata->sigs[keydata->nsigs].packet = pkt; 499 500 keydata->nsigs++; 501} 502 503/** 504\ingroup Core_Keys 505\brief Add selfsigned User ID to key 506\param keydata Key to which to add user ID 507\param userid Self-signed User ID to add 508\return true if OK; else false 509*/ 510bool 511__ops_add_selfsigned_userid_to_keydata(__ops_keydata_t * keydata, __ops_user_id_t * userid) 512{ 513 __ops_packet_t sigpacket; 514 515 __ops_memory_t *mem_userid = NULL; 516 __ops_create_info_t *cinfo_userid = NULL; 517 518 __ops_memory_t *mem_sig = NULL; 519 __ops_create_info_t *cinfo_sig = NULL; 520 521 __ops_create_signature_t *sig = NULL; 522 523 /* 524 * create signature packet for this userid 525 */ 526 527 /* create userid pkt */ 528 __ops_setup_memory_write(&cinfo_userid, &mem_userid, 128); 529 __ops_write_struct_user_id(userid, cinfo_userid); 530 531 /* create sig for this pkt */ 532 533 sig = __ops_create_signature_new(); 534 __ops_signature_start_key_signature(sig, &keydata->key.skey.public_key, userid, OPS_CERT_POSITIVE); 535 __ops_signature_add_creation_time(sig, time(NULL)); 536 __ops_signature_add_issuer_key_id(sig, keydata->key_id); 537 __ops_signature_add_primary_user_id(sig, true); 538 __ops_signature_hashed_subpackets_end(sig); 539 540 __ops_setup_memory_write(&cinfo_sig, &mem_sig, 128); 541 __ops_write_signature(sig, &keydata->key.skey.public_key, &keydata->key.skey, cinfo_sig); 542 543 /* add this packet to keydata */ 544 545 sigpacket.length = __ops_memory_get_length(mem_sig); 546 sigpacket.raw = __ops_memory_get_data(mem_sig); 547 548 /* add userid to keydata */ 549 __ops_add_signed_userid_to_keydata(keydata, userid, &sigpacket); 550 551 /* cleanup */ 552 __ops_create_signature_delete(sig); 553 __ops_create_info_delete(cinfo_userid); 554 __ops_create_info_delete(cinfo_sig); 555 __ops_memory_free(mem_userid); 556 __ops_memory_free(mem_sig); 557 558 return true; 559} 560 561/** 562\ingroup Core_Keys 563\brief Initialise __ops_keydata_t 564\param keydata Keydata to initialise 565\param type OPS_PTAG_CT_PUBLIC_KEY or OPS_PTAG_CT_SECRET_KEY 566*/ 567void 568__ops_keydata_init(__ops_keydata_t * keydata, const __ops_content_tag_t type) 569{ 570 assert(keydata->type == OPS_PTAG_CT_RESERVED); 571 assert(type == OPS_PTAG_CT_PUBLIC_KEY || type == OPS_PTAG_CT_SECRET_KEY); 572 573 keydata->type = type; 574} 575 576/** 577 Example Usage: 578 \code 579 580 // definition of variables 581 __ops_keyring_t keyring; 582 char* filename="~/.gnupg/pubring.gpg"; 583 584 // Read keyring from file 585 __ops_keyring_read_from_file(&keyring,filename); 586 587 // do actions using keyring 588 ... 589 590 // Free memory alloc-ed in __ops_keyring_read_from_file() 591 __ops_keyring_free(keyring); 592 \endcode 593*/ 594 595 596static __ops_parse_cb_return_t 597cb_keyring_read(const __ops_parser_content_t * contents, 598 __ops_parse_cb_info_t * cbinfo) 599{ 600 OPS_USED(cbinfo); 601 602 switch (contents->tag) { 603 case OPS_PARSER_PTAG: 604 case OPS_PTAG_CT_ENCRYPTED_SECRET_KEY: /* we get these because we 605 * didn't prompt */ 606 case OPS_PTAG_CT_SIGNATURE_HEADER: 607 case OPS_PTAG_CT_SIGNATURE_FOOTER: 608 case OPS_PTAG_CT_SIGNATURE: 609 case OPS_PTAG_CT_TRUST: 610 case OPS_PARSER_ERRCODE: 611 break; 612 613 default: 614 ; 615 } 616 617 return OPS_RELEASE_MEMORY; 618} 619 620/** 621 \ingroup HighLevel_KeyringRead 622 623 \brief Reads a keyring from a file 624 625 \param keyring Pointer to an existing __ops_keyring_t struct 626 \param armour true if file is armoured; else false 627 \param filename Filename of keyring to be read 628 629 \return __ops true if OK; false on error 630 631 \note Keyring struct must already exist. 632 633 \note Can be used with either a public or secret keyring. 634 635 \note You must call __ops_keyring_free() after usage to free alloc-ed memory. 636 637 \note If you call this twice on the same keyring struct, without calling 638 __ops_keyring_free() between these calls, you will introduce a memory leak. 639 640 \sa __ops_keyring_read_from_mem() 641 \sa __ops_keyring_free() 642 643 Example code: 644 \code 645 __ops_keyring_t* keyring=calloc(1, sizeof(*keyring)); 646 bool armoured=false; 647 __ops_keyring_read_from_file(keyring, armoured, "~/.gnupg/pubring.gpg"); 648 ... 649 __ops_keyring_free(keyring); 650 free (keyring); 651 652 \endcode 653*/ 654 655bool 656__ops_keyring_read_from_file(__ops_keyring_t * keyring, const bool armour, const char *filename) 657{ 658 __ops_parse_info_t *pinfo; 659 int fd; 660 bool res = true; 661 662 pinfo = __ops_parse_info_new(); 663 664 /* add this for the moment, */ 665 /* 666 * \todo need to fix the problems with reading signature subpackets 667 * later 668 */ 669 670 /* __ops_parse_options(pinfo,OPS_PTAG_SS_ALL,OPS_PARSE_RAW); */ 671 __ops_parse_options(pinfo, OPS_PTAG_SS_ALL, OPS_PARSE_PARSED); 672 673#ifdef O_BINARY 674 fd = open(filename, O_RDONLY | O_BINARY); 675#else 676 fd = open(filename, O_RDONLY); 677#endif 678 if (fd < 0) { 679 __ops_parse_info_delete(pinfo); 680 perror(filename); 681 return false; 682 } 683#ifdef USE_MMAP_FOR_FILES 684 __ops_reader_set_mmap(pinfo, fd); 685#else 686 __ops_reader_set_fd(pinfo, fd); 687#endif 688 689 __ops_parse_cb_set(pinfo, cb_keyring_read, NULL); 690 691 if (armour) { 692 __ops_reader_push_dearmour(pinfo); 693 } 694 if (__ops_parse_and_accumulate(keyring, pinfo) == 0) { 695 res = false; 696 } else { 697 res = true; 698 } 699 __ops_print_errors(__ops_parse_info_get_errors(pinfo)); 700 701 if (armour) 702 __ops_reader_pop_dearmour(pinfo); 703 704 close(fd); 705 706 __ops_parse_info_delete(pinfo); 707 708 return res; 709} 710 711#if 0 712/** 713 \ingroup HighLevel_KeyringRead 714 715 \brief Reads a keyring from memory 716 717 \param keyring Pointer to existing __ops_keyring_t struct 718 \param armour true if file is armoured; else false 719 \param mem Pointer to a __ops_memory_t struct containing keyring to be read 720 721 \return __ops true if OK; false on error 722 723 \note Keyring struct must already exist. 724 725 \note Can be used with either a public or secret keyring. 726 727 \note You must call __ops_keyring_free() after usage to free alloc-ed memory. 728 729 \note If you call this twice on the same keyring struct, without calling 730 __ops_keyring_free() between these calls, you will introduce a memory leak. 731 732 \sa __ops_keyring_read_from_file 733 \sa __ops_keyring_free 734 735 Example code: 736 \code 737 __ops_memory_t* mem; // Filled with keyring packets 738 __ops_keyring_t* keyring=calloc(1, sizeof(*keyring)); 739 bool armoured=false; 740 __ops_keyring_read_from_mem(keyring, armoured, mem); 741 ... 742 __ops_keyring_free(keyring); 743 free (keyring); 744 \endcode 745*/ 746static bool 747__ops_keyring_read_from_mem(__ops_keyring_t * keyring, const bool armour, __ops_memory_t * mem) 748{ 749 __ops_parse_info_t *pinfo = NULL; 750 bool res = true; 751 752 pinfo = __ops_parse_info_new(); 753 __ops_parse_options(pinfo, OPS_PTAG_SS_ALL, OPS_PARSE_PARSED); 754 755 __ops_setup_memory_read(&pinfo, mem, NULL, cb_keyring_read, false); 756 757 if (armour) { 758 __ops_reader_push_dearmour(pinfo); 759 } 760 res = (__ops_parse_and_accumulate(keyring, pinfo) != 0); 761 __ops_print_errors(__ops_parse_info_get_errors(pinfo)); 762 763 if (armour) 764 __ops_reader_pop_dearmour(pinfo); 765 766 /* don't call teardown_memory_read because memory was passed in */ 767 __ops_parse_info_delete(pinfo); 768 769 return res; 770} 771#endif 772 773/** 774 \ingroup HighLevel_KeyringRead 775 776 \brief Frees keyring's contents (but not keyring itself) 777 778 \param keyring Keyring whose data is to be freed 779 780 \note This does not free keyring itself, just the memory alloc-ed in it. 781 */ 782void 783__ops_keyring_free(__ops_keyring_t * keyring) 784{ 785 free(keyring->keys); 786 keyring->keys = NULL; 787 keyring->nkeys = 0; 788 keyring->nkeys_allocated = 0; 789} 790 791/** 792 \ingroup HighLevel_KeyringFind 793 794 \brief Finds key in keyring from its Key ID 795 796 \param keyring Keyring to be searched 797 \param keyid ID of required key 798 799 \return Pointer to key, if found; NULL, if not found 800 801 \note This returns a pointer to the key inside the given keyring, not a copy. Do not free it after use. 802 803 Example code: 804 \code 805 void example(__ops_keyring_t* keyring) 806 { 807 __ops_keydata_t* keydata=NULL; 808 unsigned char keyid[OPS_KEY_ID_SIZE]; // value set elsewhere 809 keydata=__ops_keyring_find_key_by_id(keyring,keyid); 810 ... 811 } 812 \endcode 813*/ 814const __ops_keydata_t * 815__ops_keyring_find_key_by_id(const __ops_keyring_t * keyring, 816 const unsigned char keyid[OPS_KEY_ID_SIZE]) 817{ 818 int n; 819 820 for (n = 0; keyring && n < keyring->nkeys; n++) { 821 if (__ops_get_debug_level(__FILE__)) { 822 int i; 823 824 printf("__ops_keyring_find_key_by_id: keyring keyid "); 825 for (i = 0 ; i < OPS_KEY_ID_SIZE ; i++) { 826 printf("%02x", keyring->keys[n].key_id[i]); 827 } 828 printf(", keyid "); 829 for (i = 0 ; i < OPS_KEY_ID_SIZE ; i++) { 830 printf("%02x", keyid[i]); 831 } 832 printf("\n"); 833 } 834 if (memcmp(keyring->keys[n].key_id, keyid, OPS_KEY_ID_SIZE) == 0) { 835 return &keyring->keys[n]; 836 } 837 if (memcmp(&keyring->keys[n].key_id[OPS_KEY_ID_SIZE / 2], 838 keyid, OPS_KEY_ID_SIZE / 2) == 0) { 839 return &keyring->keys[n]; 840 } 841 } 842 return NULL; 843} 844 845/* convert a string keyid into a binary keyid */ 846static void 847str2keyid(const char *userid, unsigned char *keyid, size_t len) 848{ 849 static const char *uppers = "0123456789ABCDEF"; 850 static const char *lowers = "0123456789abcdef"; 851 unsigned char hichar; 852 unsigned char lochar; 853 size_t j; 854 const char *hi; 855 const char *lo; 856 int i; 857 858 for (i = j = 0 ; j < len && userid[i] && userid[i + 1] ; i += 2, j++) { 859 if ((hi = strchr(uppers, userid[i])) == NULL) { 860 if ((hi = strchr(lowers, userid[i])) == NULL) { 861 break; 862 } 863 hichar = (hi - lowers); 864 } else { 865 hichar = (hi - uppers); 866 } 867 if ((lo = strchr(uppers, userid[i + 1])) == NULL) { 868 if ((lo = strchr(lowers, userid[i + 1])) == NULL) { 869 break; 870 } 871 lochar = (lo - lowers); 872 } else { 873 lochar = (lo - uppers); 874 } 875 keyid[j] = (hichar << 4) | (lochar); 876 } 877 keyid[j] = 0x0; 878} 879 880/** 881 \ingroup HighLevel_KeyringFind 882 883 \brief Finds key from its User ID 884 885 \param keyring Keyring to be searched 886 \param userid User ID of required key 887 888 \return Pointer to Key, if found; NULL, if not found 889 890 \note This returns a pointer to the key inside the keyring, not a copy. Do not free it. 891 892 Example code: 893 \code 894 void example(__ops_keyring_t* keyring) 895 { 896 __ops_keydata_t* keydata=NULL; 897 keydata=__ops_keyring_find_key_by_userid(keyring,"user@domain.com"); 898 ... 899 } 900 \endcode 901*/ 902const __ops_keydata_t * 903__ops_keyring_find_key_by_userid(const __ops_keyring_t *keyring, 904 const char *userid) 905{ 906 const __ops_keydata_t *kp; 907 unsigned char keyid[OPS_KEY_ID_SIZE + 1]; 908 unsigned int i = 0; 909 size_t len; 910 char *cp; 911 int n = 0; 912 913 if (!keyring) 914 return NULL; 915 916 len = strlen(userid); 917 for (n = 0; n < keyring->nkeys; ++n) { 918 for (i = 0; i < keyring->keys[n].nuids; i++) { 919 if (__ops_get_debug_level(__FILE__)) { 920 printf("[%d][%d] userid %s, last '%d'\n", 921 n, i, keyring->keys[n].uids[i].user_id, 922 keyring->keys[n].uids[i].user_id[len]); 923 } 924 if (strncmp((char *) keyring->keys[n].uids[i].user_id, userid, len) == 0 && 925 keyring->keys[n].uids[i].user_id[len] == ' ') { 926 return &keyring->keys[n]; 927 } 928 } 929 } 930 931 if (strchr(userid, '@') == NULL) { 932 /* no '@' sign */ 933 /* first try userid as a keyid */ 934 (void) memset(keyid, 0x0, sizeof(keyid)); 935 str2keyid(userid, keyid, sizeof(keyid)); 936 if (__ops_get_debug_level(__FILE__)) { 937 printf("userid \"%s\", keyid %02x%02x%02x%02x\n", 938 userid, 939 keyid[0], keyid[1], keyid[2], keyid[3]); 940 } 941 if ((kp = __ops_keyring_find_key_by_id(keyring, keyid)) != NULL) { 942 return kp; 943 } 944 /* match on full name */ 945 for (n = 0; n < keyring->nkeys; n++) { 946 for (i = 0; i < keyring->keys[n].nuids; i++) { 947 if (__ops_get_debug_level(__FILE__)) { 948 printf("keyid \"%s\" len %" PRIsize "u, keyid[len] '%c'\n", 949 (char *) keyring->keys[n].uids[i].user_id, 950 len, keyring->keys[n].uids[i].user_id[len]); 951 } 952 if (strncasecmp((char *) keyring->keys[n].uids[i].user_id, userid, len) == 0 && 953 keyring->keys[n].uids[i].user_id[len] == ' ') { 954 return &keyring->keys[n]; 955 } 956 } 957 } 958 } 959 /* match on <email@address> */ 960 for (n = 0; n < keyring->nkeys; n++) { 961 for (i = 0; i < keyring->keys[n].nuids; i++) { 962 /* 963 * look for the rightmost '<', in case there is one 964 * in the comment field 965 */ 966 if ((cp = strrchr((char *) keyring->keys[n].uids[i].user_id, '<')) != NULL) { 967 if (__ops_get_debug_level(__FILE__)) { 968 printf("cp ,%s, userid ,%s, len %" PRIsize "u ,%c,\n", 969 cp + 1, userid, len, *(cp + len + 1)); 970 } 971 if (strncasecmp(cp + 1, userid, len) == 0 && 972 *(cp + len + 1) == '>') { 973 return &keyring->keys[n]; 974 } 975 } 976 } 977 } 978 979 /* printf("end: n=%d,i=%d\n",n,i); */ 980 return NULL; 981} 982 983/** 984 \ingroup HighLevel_KeyringList 985 986 \brief Prints all keys in keyring to stdout. 987 988 \param keyring Keyring to use 989 990 \return none 991 992 Example code: 993 \code 994 void example() 995 { 996 __ops_keyring_t* keyring=calloc(1, sizeof(*keyring)); 997 bool armoured=false; 998 __ops_keyring_read_from_file(keyring, armoured, "~/.gnupg/pubring.gpg"); 999 1000 __ops_keyring_list(keyring); 1001 1002 __ops_keyring_free(keyring); 1003 free (keyring); 1004 } 1005 \endcode 1006*/ 1007 1008void 1009__ops_keyring_list(const __ops_keyring_t * keyring) 1010{ 1011 int n; 1012 __ops_keydata_t *key; 1013 1014 printf("%d keys\n", keyring->nkeys); 1015 for (n = 0, key = &keyring->keys[n]; n < keyring->nkeys; ++n, ++key) { 1016 if (__ops_is_key_secret(key)) 1017 __ops_print_secret_keydata(key); 1018 else 1019 __ops_print_public_keydata(key); 1020 (void) fputc('\n', stdout); 1021 } 1022} 1023 1024unsigned 1025__ops_get_keydata_content_type(const __ops_keydata_t * keydata) 1026{ 1027 return keydata->type; 1028} 1029 1030/* this interface isn't right - hook into callback for getting passphrase */ 1031int 1032__ops_export_key(const __ops_keydata_t *keydata, unsigned char *passphrase) 1033{ 1034 __ops_create_info_t *cinfo; 1035 __ops_memory_t *mem; 1036 1037 __ops_setup_memory_write(&cinfo, &mem, 128); 1038 if (__ops_get_keydata_content_type(keydata) == OPS_PTAG_CT_PUBLIC_KEY) { 1039 __ops_write_transferable_public_key(keydata, true, cinfo); 1040 } else { 1041 __ops_write_transferable_secret_key(keydata, 1042 passphrase, 1043 strlen((char *)passphrase), true, cinfo); 1044 } 1045 printf("%s", (char *) __ops_memory_get_data(mem)); 1046 __ops_teardown_memory_write(cinfo, mem); 1047 return 1; 1048} 1049