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: create.c,v 1.28 2010/05/25 01:05:10 agc Exp $"); 61 #endif 62 63 #include <sys/types.h> 64 #include <sys/param.h> 65 #include <sys/stat.h> 66 67 #ifdef HAVE_FCNTL_H 68 #include <fcntl.h> 69 #endif 70 71 #include <string.h> 72 73 #ifdef HAVE_UNISTD_H 74 #include <unistd.h> 75 #endif 76 77 #ifdef HAVE_OPENSSL_CAST_H 78 #include <openssl/cast.h> 79 #endif 80 81 #include "create.h" 82 #include "keyring.h" 83 #include "packet.h" 84 #include "signature.h" 85 #include "writer.h" 86 #include "readerwriter.h" 87 #include "memory.h" 88 #include "netpgpdefs.h" 89 #include "netpgpdigest.h" 90 91 /** 92 * \ingroup Core_Create 93 * \param length 94 * \param type 95 * \param output 96 * \return 1 if OK, otherwise 0 97 */ 98 99 unsigned 100 __ops_write_ss_header(__ops_output_t *output, 101 unsigned length, 102 __ops_content_enum type) 103 { 104 return __ops_write_length(output, length) && 105 __ops_write_scalar(output, (unsigned)(type - 106 (unsigned)OPS_PTAG_SIG_SUBPKT_BASE), 1); 107 } 108 109 /* 110 * XXX: the general idea of _fast_ is that it doesn't copy stuff the safe 111 * (i.e. non _fast_) version will, and so will also need to be freed. 112 */ 113 114 /** 115 * \ingroup Core_Create 116 * 117 * __ops_fast_create_userid() sets id->userid to the given userid. 118 * This is fast because it is only copying a char*. However, if userid 119 * is changed or freed in the future, this could have injurious results. 120 * \param id 121 * \param userid 122 */ 123 124 void 125 __ops_fast_create_userid(uint8_t **id, uint8_t *userid) 126 { 127 *id = userid; 128 } 129 130 /** 131 * \ingroup Core_WritePackets 132 * \brief Writes a User Id packet 133 * \param id 134 * \param output 135 * \return 1 if OK, otherwise 0 136 */ 137 unsigned 138 __ops_write_struct_userid(__ops_output_t *output, const uint8_t *id) 139 { 140 return __ops_write_ptag(output, OPS_PTAG_CT_USER_ID) && 141 __ops_write_length(output, strlen((const char *) id)) && 142 __ops_write(output, id, strlen((const char *) id)); 143 } 144 145 /** 146 * \ingroup Core_WritePackets 147 * \brief Write a User Id packet. 148 * \param userid 149 * \param output 150 * 151 * \return return value from __ops_write_struct_userid() 152 */ 153 unsigned 154 __ops_write_userid(const uint8_t *userid, __ops_output_t *output) 155 { 156 return __ops_write_struct_userid(output, userid); 157 } 158 159 /** 160 \ingroup Core_MPI 161 */ 162 static unsigned 163 mpi_length(const BIGNUM *bn) 164 { 165 return (unsigned)(2 + (BN_num_bits(bn) + 7) / 8); 166 } 167 168 static unsigned 169 pubkey_length(const __ops_pubkey_t *key) 170 { 171 switch (key->alg) { 172 case OPS_PKA_RSA: 173 return mpi_length(key->key.rsa.n) + mpi_length(key->key.rsa.e); 174 175 default: 176 (void) fprintf(stderr, 177 "pubkey_length: unknown key algorithm\n"); 178 } 179 return 0; 180 } 181 182 static unsigned 183 seckey_length(const __ops_seckey_t *key) 184 { 185 int len; 186 187 len = 0; 188 switch (key->pubkey.alg) { 189 case OPS_PKA_RSA: 190 len = mpi_length(key->key.rsa.d) + mpi_length(key->key.rsa.p) + 191 mpi_length(key->key.rsa.q) + mpi_length(key->key.rsa.u); 192 193 return (unsigned)(len + pubkey_length(&key->pubkey)); 194 default: 195 (void) fprintf(stderr, 196 "seckey_length: unknown key algorithm\n"); 197 } 198 return 0; 199 } 200 201 /** 202 * \ingroup Core_Create 203 * \param key 204 * \param t 205 * \param n 206 * \param e 207 */ 208 void 209 __ops_fast_create_rsa_pubkey(__ops_pubkey_t *key, time_t t, 210 BIGNUM *n, BIGNUM *e) 211 { 212 key->version = OPS_V4; 213 key->birthtime = t; 214 key->alg = OPS_PKA_RSA; 215 key->key.rsa.n = n; 216 key->key.rsa.e = e; 217 } 218 219 /* 220 * Note that we support v3 keys here because they're needed for for 221 * verification - the writer doesn't allow them, though 222 */ 223 static unsigned 224 write_pubkey_body(const __ops_pubkey_t *key, __ops_output_t *output) 225 { 226 if (!(__ops_write_scalar(output, (unsigned)key->version, 1) && 227 __ops_write_scalar(output, (unsigned)key->birthtime, 4))) { 228 return 0; 229 } 230 231 if (key->version != 4 && 232 !__ops_write_scalar(output, key->days_valid, 2)) { 233 return 0; 234 } 235 236 if (!__ops_write_scalar(output, (unsigned)key->alg, 1)) { 237 return 0; 238 } 239 240 switch (key->alg) { 241 case OPS_PKA_DSA: 242 return __ops_write_mpi(output, key->key.dsa.p) && 243 __ops_write_mpi(output, key->key.dsa.q) && 244 __ops_write_mpi(output, key->key.dsa.g) && 245 __ops_write_mpi(output, key->key.dsa.y); 246 247 case OPS_PKA_RSA: 248 case OPS_PKA_RSA_ENCRYPT_ONLY: 249 case OPS_PKA_RSA_SIGN_ONLY: 250 return __ops_write_mpi(output, key->key.rsa.n) && 251 __ops_write_mpi(output, key->key.rsa.e); 252 253 case OPS_PKA_ELGAMAL: 254 return __ops_write_mpi(output, key->key.elgamal.p) && 255 __ops_write_mpi(output, key->key.elgamal.g) && 256 __ops_write_mpi(output, key->key.elgamal.y); 257 258 default: 259 (void) fprintf(stderr, 260 "write_pubkey_body: bad algorithm\n"); 261 break; 262 } 263 return 0; 264 } 265 266 /* 267 * Note that we support v3 keys here because they're needed for 268 * verification - the writer doesn't allow them, though 269 */ 270 static unsigned 271 write_seckey_body(const __ops_seckey_t *key, 272 const uint8_t *passphrase, 273 const size_t pplen, 274 __ops_output_t *output) 275 { 276 /* RFC4880 Section 5.5.3 Secret-Key Packet Formats */ 277 278 __ops_crypt_t crypted; 279 __ops_hash_t hash; 280 unsigned done = 0; 281 unsigned i = 0; 282 uint8_t hashed[OPS_SHA1_HASH_SIZE]; 283 uint8_t sesskey[CAST_KEY_LENGTH]; 284 285 if (!write_pubkey_body(&key->pubkey, output)) { 286 return 0; 287 } 288 if (key->s2k_usage != OPS_S2KU_ENCRYPTED_AND_HASHED) { 289 (void) fprintf(stderr, "write_seckey_body: s2k usage\n"); 290 return 0; 291 } 292 if (!__ops_write_scalar(output, (unsigned)key->s2k_usage, 1)) { 293 return 0; 294 } 295 296 if (key->alg != OPS_SA_CAST5) { 297 (void) fprintf(stderr, "write_seckey_body: algorithm\n"); 298 return 0; 299 } 300 if (!__ops_write_scalar(output, (unsigned)key->alg, 1)) { 301 return 0; 302 } 303 304 if (key->s2k_specifier != OPS_S2KS_SIMPLE && 305 key->s2k_specifier != OPS_S2KS_SALTED) { 306 /* = 1 \todo could also be iterated-and-salted */ 307 (void) fprintf(stderr, "write_seckey_body: s2k spec\n"); 308 return 0; 309 } 310 if (!__ops_write_scalar(output, (unsigned)key->s2k_specifier, 1)) { 311 return 0; 312 } 313 if (!__ops_write_scalar(output, (unsigned)key->hash_alg, 1)) { 314 return 0; 315 } 316 317 switch (key->s2k_specifier) { 318 case OPS_S2KS_SIMPLE: 319 /* nothing more to do */ 320 break; 321 322 case OPS_S2KS_SALTED: 323 /* 8-octet salt value */ 324 __ops_random(__UNCONST(&key->salt[0]), OPS_SALT_SIZE); 325 if (!__ops_write(output, key->salt, OPS_SALT_SIZE)) { 326 return 0; 327 } 328 break; 329 330 /* 331 * \todo case OPS_S2KS_ITERATED_AND_SALTED: // 8-octet salt 332 * value // 1-octet count break; 333 */ 334 335 default: 336 (void) fprintf(stderr, 337 "invalid/unsupported s2k specifier %d\n", 338 key->s2k_specifier); 339 return 0; 340 } 341 342 if (!__ops_write(output, &key->iv[0], __ops_block_size(key->alg))) { 343 return 0; 344 } 345 346 /* 347 * create the session key for encrypting the algorithm-specific 348 * fields 349 */ 350 351 switch (key->s2k_specifier) { 352 case OPS_S2KS_SIMPLE: 353 case OPS_S2KS_SALTED: 354 /* RFC4880: section 3.7.1.1 and 3.7.1.2 */ 355 356 for (done = 0, i = 0; done < CAST_KEY_LENGTH; i++) { 357 unsigned j; 358 uint8_t zero = 0; 359 int needed; 360 int size; 361 362 needed = CAST_KEY_LENGTH - done; 363 size = MIN(needed, OPS_SHA1_HASH_SIZE); 364 365 __ops_hash_any(&hash, key->hash_alg); 366 if (!hash.init(&hash)) { 367 (void) fprintf(stderr, "write_seckey_body: bad alloc\n"); 368 return 0; 369 } 370 371 /* preload if iterating */ 372 for (j = 0; j < i; j++) { 373 /* 374 * Coverity shows a DEADCODE error on this 375 * line. This is expected since the hardcoded 376 * use of SHA1 and CAST5 means that it will 377 * not used. This will change however when 378 * other algorithms are supported. 379 */ 380 hash.add(&hash, &zero, 1); 381 } 382 383 if (key->s2k_specifier == OPS_S2KS_SALTED) { 384 hash.add(&hash, key->salt, OPS_SALT_SIZE); 385 } 386 hash.add(&hash, passphrase, pplen); 387 hash.finish(&hash, hashed); 388 389 /* 390 * if more in hash than is needed by session key, use 391 * the leftmost octets 392 */ 393 (void) memcpy(&sesskey[i * OPS_SHA1_HASH_SIZE], 394 hashed, (unsigned)size); 395 done += (unsigned)size; 396 if (done > CAST_KEY_LENGTH) { 397 (void) fprintf(stderr, 398 "write_seckey_body: short add\n"); 399 return 0; 400 } 401 } 402 403 break; 404 405 /* 406 * \todo case OPS_S2KS_ITERATED_AND_SALTED: * 8-octet salt 407 * value * 1-octet count break; 408 */ 409 410 default: 411 (void) fprintf(stderr, 412 "invalid/unsupported s2k specifier %d\n", 413 key->s2k_specifier); 414 return 0; 415 } 416 417 /* use this session key to encrypt */ 418 419 __ops_crypt_any(&crypted, key->alg); 420 crypted.set_iv(&crypted, key->iv); 421 crypted.set_crypt_key(&crypted, sesskey); 422 __ops_encrypt_init(&crypted); 423 424 if (__ops_get_debug_level(__FILE__)) { 425 (void) fprintf(stderr, "\nWRITING:\niv="); 426 hexdump(stderr, key->iv, __ops_block_size(key->alg), " "); 427 (void) fprintf(stderr, "\nkey="); 428 hexdump(stderr, sesskey, CAST_KEY_LENGTH, " "); 429 (void) fprintf(stderr, "\nturning encryption on...\n"); 430 } 431 __ops_push_enc_crypt(output, &crypted); 432 433 switch (key->pubkey.alg) { 434 /* case OPS_PKA_DSA: */ 435 /* return __ops_write_mpi(output, key->key.dsa.x); */ 436 437 case OPS_PKA_RSA: 438 case OPS_PKA_RSA_ENCRYPT_ONLY: 439 case OPS_PKA_RSA_SIGN_ONLY: 440 441 if (!__ops_write_mpi(output, key->key.rsa.d) || 442 !__ops_write_mpi(output, key->key.rsa.p) || 443 !__ops_write_mpi(output, key->key.rsa.q) || 444 !__ops_write_mpi(output, key->key.rsa.u)) { 445 if (__ops_get_debug_level(__FILE__)) { 446 (void) fprintf(stderr, 447 "4 x mpi not written - problem\n"); 448 } 449 return 0; 450 } 451 break; 452 453 /* case OPS_PKA_ELGAMAL: */ 454 /* return __ops_write_mpi(output, key->key.elgamal.x); */ 455 456 default: 457 return 0; 458 } 459 460 if (!__ops_write(output, key->checkhash, OPS_CHECKHASH_SIZE)) { 461 return 0; 462 } 463 464 __ops_writer_pop(output); 465 466 return 1; 467 } 468 469 /** 470 * \ingroup Core_WritePackets 471 * \brief Writes a Public Key packet 472 * \param key 473 * \param output 474 * \return 1 if OK, otherwise 0 475 */ 476 static unsigned 477 write_struct_pubkey(__ops_output_t *output, const __ops_pubkey_t *key) 478 { 479 if (key->version != 4) { 480 (void) fprintf(stderr, 481 "write_struct_pubkey: wrong key version\n"); 482 return 0; 483 } 484 return __ops_write_ptag(output, OPS_PTAG_CT_PUBLIC_KEY) && 485 __ops_write_length(output, 1 + 4 + 1 + pubkey_length(key)) && 486 write_pubkey_body(key, output); 487 } 488 489 490 /** 491 \ingroup HighLevel_KeyWrite 492 493 \brief Writes a transferable PGP public key to the given output stream. 494 495 \param keydata Key to be written 496 \param armoured Flag is set for armoured output 497 \param output Output stream 498 499 */ 500 501 unsigned 502 __ops_write_xfer_pubkey(__ops_output_t *output, 503 const __ops_key_t *key, 504 const unsigned armoured) 505 { 506 unsigned i, j; 507 508 if (armoured) { 509 __ops_writer_push_armoured(output, OPS_PGP_PUBLIC_KEY_BLOCK); 510 } 511 /* public key */ 512 if (!write_struct_pubkey(output, &key->key.seckey.pubkey)) { 513 return 0; 514 } 515 516 /* TODO: revocation signatures go here */ 517 518 /* user ids and corresponding signatures */ 519 for (i = 0; i < key->uidc; i++) { 520 if (!__ops_write_struct_userid(output, key->uids[i])) { 521 return 0; 522 } 523 for (j = 0; j < key->packetc; j++) { 524 if (!__ops_write(output, key->packets[j].raw, key->packets[j].length)) { 525 return 0; 526 } 527 } 528 } 529 530 /* TODO: user attributes and corresponding signatures */ 531 532 /* 533 * subkey packets and corresponding signatures and optional 534 * revocation 535 */ 536 537 if (armoured) { 538 __ops_writer_info_finalise(&output->errors, &output->writer); 539 __ops_writer_pop(output); 540 } 541 return 1; 542 } 543 544 /** 545 \ingroup HighLevel_KeyWrite 546 547 \brief Writes a transferable PGP secret key to the given output stream. 548 549 \param keydata Key to be written 550 \param passphrase 551 \param pplen 552 \param armoured Flag is set for armoured output 553 \param output Output stream 554 555 */ 556 557 unsigned 558 __ops_write_xfer_seckey(__ops_output_t *output, 559 const __ops_key_t *key, 560 const uint8_t *passphrase, 561 const size_t pplen, 562 unsigned armoured) 563 { 564 unsigned i, j; 565 566 if (armoured) { 567 __ops_writer_push_armoured(output, OPS_PGP_PRIVATE_KEY_BLOCK); 568 } 569 /* public key */ 570 if (!__ops_write_struct_seckey(&key->key.seckey, passphrase, 571 pplen, output)) { 572 return 0; 573 } 574 575 /* TODO: revocation signatures go here */ 576 577 /* user ids and corresponding signatures */ 578 for (i = 0; i < key->uidc; i++) { 579 if (!__ops_write_struct_userid(output, key->uids[i])) { 580 return 0; 581 } 582 for (j = 0; j < key->packetc; j++) { 583 if (!__ops_write(output, key->packets[j].raw, key->packets[j].length)) { 584 return 0; 585 } 586 } 587 } 588 589 /* TODO: user attributes and corresponding signatures */ 590 591 /* 592 * subkey packets and corresponding signatures and optional 593 * revocation 594 */ 595 596 if (armoured) { 597 __ops_writer_info_finalise(&output->errors, &output->writer); 598 __ops_writer_pop(output); 599 } 600 return 1; 601 } 602 603 /** 604 * \ingroup Core_WritePackets 605 * \brief Writes one RSA public key packet. 606 * \param t Creation time 607 * \param n RSA public modulus 608 * \param e RSA public encryption exponent 609 * \param output Writer settings 610 * 611 * \return 1 if OK, otherwise 0 612 */ 613 614 unsigned 615 __ops_write_rsa_pubkey(time_t t, const BIGNUM *n, 616 const BIGNUM *e, 617 __ops_output_t *output) 618 { 619 __ops_pubkey_t key; 620 621 __ops_fast_create_rsa_pubkey(&key, t, __UNCONST(n), __UNCONST(e)); 622 return write_struct_pubkey(output, &key); 623 } 624 625 /** 626 * \ingroup Core_Create 627 * \param out 628 * \param key 629 * \param make_packet 630 */ 631 632 void 633 __ops_build_pubkey(__ops_memory_t *out, const __ops_pubkey_t *key, 634 unsigned make_packet) 635 { 636 __ops_output_t *output; 637 638 output = __ops_output_new(); 639 __ops_memory_init(out, 128); 640 __ops_writer_set_memory(output, out); 641 write_pubkey_body(key, output); 642 if (make_packet) { 643 __ops_memory_make_packet(out, OPS_PTAG_CT_PUBLIC_KEY); 644 } 645 __ops_output_delete(output); 646 } 647 648 /** 649 * \ingroup Core_Create 650 * 651 * Create an RSA secret key structure. If a parameter is marked as 652 * [OPTIONAL], then it can be omitted and will be calculated from 653 * other params - or, in the case of e, will default to 0x10001. 654 * 655 * Parameters are _not_ copied, so will be freed if the structure is 656 * freed. 657 * 658 * \param key The key structure to be initialised. 659 * \param t 660 * \param d The RSA parameter d (=e^-1 mod (p-1)(q-1)) [OPTIONAL] 661 * \param p The RSA parameter p 662 * \param q The RSA parameter q (q > p) 663 * \param u The RSA parameter u (=p^-1 mod q) [OPTIONAL] 664 * \param n The RSA public parameter n (=p*q) [OPTIONAL] 665 * \param e The RSA public parameter e */ 666 667 void 668 __ops_fast_create_rsa_seckey(__ops_seckey_t *key, time_t t, 669 BIGNUM *d, BIGNUM *p, BIGNUM *q, BIGNUM *u, 670 BIGNUM *n, BIGNUM *e) 671 { 672 __ops_fast_create_rsa_pubkey(&key->pubkey, t, n, e); 673 674 /* XXX: calculate optionals */ 675 key->key.rsa.d = d; 676 key->key.rsa.p = p; 677 key->key.rsa.q = q; 678 key->key.rsa.u = u; 679 680 key->s2k_usage = OPS_S2KU_NONE; 681 682 /* XXX: sanity check and add errors... */ 683 } 684 685 /** 686 * \ingroup Core_WritePackets 687 * \brief Writes a Secret Key packet. 688 * \param key The secret key 689 * \param passphrase The passphrase 690 * \param pplen Length of passphrase 691 * \param output 692 * \return 1 if OK; else 0 693 */ 694 unsigned 695 __ops_write_struct_seckey(const __ops_seckey_t *key, 696 const uint8_t *passphrase, 697 const size_t pplen, 698 __ops_output_t *output) 699 { 700 int length = 0; 701 702 if (key->pubkey.version != 4) { 703 (void) fprintf(stderr, 704 "__ops_write_struct_seckey: public key version\n"); 705 return 0; 706 } 707 708 /* Ref: RFC4880 Section 5.5.3 */ 709 710 /* pubkey, excluding MPIs */ 711 length += 1 + 4 + 1 + 1; 712 713 /* s2k usage */ 714 length += 1; 715 716 switch (key->s2k_usage) { 717 case OPS_S2KU_NONE: 718 /* nothing to add */ 719 break; 720 721 case OPS_S2KU_ENCRYPTED_AND_HASHED: /* 254 */ 722 case OPS_S2KU_ENCRYPTED: /* 255 */ 723 724 /* Ref: RFC4880 Section 3.7 */ 725 length += 1; /* s2k_specifier */ 726 727 switch (key->s2k_specifier) { 728 case OPS_S2KS_SIMPLE: 729 length += 1; /* hash algorithm */ 730 break; 731 732 case OPS_S2KS_SALTED: 733 length += 1 + 8; /* hash algorithm + salt */ 734 break; 735 736 case OPS_S2KS_ITERATED_AND_SALTED: 737 length += 1 + 8 + 1; /* hash algorithm, salt + 738 * count */ 739 break; 740 741 default: 742 (void) fprintf(stderr, 743 "__ops_write_struct_seckey: s2k spec\n"); 744 return 0; 745 } 746 break; 747 748 default: 749 (void) fprintf(stderr, 750 "__ops_write_struct_seckey: s2k usage\n"); 751 return 0; 752 } 753 754 /* IV */ 755 if (key->s2k_usage) { 756 length += __ops_block_size(key->alg); 757 } 758 /* checksum or hash */ 759 switch (key->s2k_usage) { 760 case OPS_S2KU_NONE: 761 case OPS_S2KU_ENCRYPTED: 762 length += 2; 763 break; 764 765 case OPS_S2KU_ENCRYPTED_AND_HASHED: 766 length += OPS_CHECKHASH_SIZE; 767 break; 768 769 default: 770 (void) fprintf(stderr, 771 "__ops_write_struct_seckey: s2k cksum usage\n"); 772 return 0; 773 } 774 775 /* secret key and public key MPIs */ 776 length += (unsigned)seckey_length(key); 777 778 return __ops_write_ptag(output, OPS_PTAG_CT_SECRET_KEY) && 779 /* __ops_write_length(output,1+4+1+1+seckey_length(key)+2) && */ 780 __ops_write_length(output, (unsigned)length) && 781 write_seckey_body(key, passphrase, pplen, output); 782 } 783 784 /** 785 * \ingroup Core_Create 786 * 787 * \brief Create a new __ops_output_t structure. 788 * 789 * \return the new structure. 790 * \note It is the responsiblity of the caller to call __ops_output_delete(). 791 * \sa __ops_output_delete() 792 */ 793 __ops_output_t * 794 __ops_output_new(void) 795 { 796 return calloc(1, sizeof(__ops_output_t)); 797 } 798 799 /** 800 * \ingroup Core_Create 801 * \brief Delete an __ops_output_t strucut and associated resources. 802 * 803 * Delete an __ops_output_t structure. If a writer is active, then 804 * that is also deleted. 805 * 806 * \param info the structure to be deleted. 807 */ 808 void 809 __ops_output_delete(__ops_output_t *output) 810 { 811 __ops_writer_info_delete(&output->writer); 812 free(output); 813 } 814 815 /** 816 \ingroup Core_Create 817 \brief Calculate the checksum for a session key 818 \param sesskey Session Key to use 819 \param cs Checksum to be written 820 \return 1 if OK; else 0 821 */ 822 unsigned 823 __ops_calc_sesskey_checksum(__ops_pk_sesskey_t *sesskey, uint8_t cs[2]) 824 { 825 uint32_t checksum = 0; 826 unsigned i; 827 828 if (!__ops_is_sa_supported(sesskey->symm_alg)) { 829 return 0; 830 } 831 832 for (i = 0; i < __ops_key_size(sesskey->symm_alg); i++) { 833 checksum += sesskey->key[i]; 834 } 835 checksum = checksum % 65536; 836 837 cs[0] = (uint8_t)((checksum >> 8) & 0xff); 838 cs[1] = (uint8_t)(checksum & 0xff); 839 840 if (__ops_get_debug_level(__FILE__)) { 841 (void) fprintf(stderr,"\nm buf checksum: "); 842 hexdump(stderr, cs, 2, " "); 843 (void) fprintf(stderr,"\n"); 844 } 845 return 1; 846 } 847 848 static unsigned 849 create_unencoded_m_buf(__ops_pk_sesskey_t *sesskey, uint8_t *m_buf) 850 { 851 int i; 852 853 /* m_buf is the buffer which will be encoded in PKCS#1 block */ 854 /* encoding to form the "m" value used in the */ 855 /* Public Key Encrypted Session Key Packet */ 856 /* 857 * as defined in RFC Section 5.1 "Public-Key Encrypted Session Key 858 * Packet" 859 */ 860 861 m_buf[0] = sesskey->symm_alg; 862 863 if (sesskey->symm_alg != OPS_SA_CAST5) { 864 (void) fprintf(stderr, "create_unencoded_m_buf: symm alg\n"); 865 return 0; 866 } 867 for (i = 0; i < CAST_KEY_LENGTH; i++) { 868 /* XXX - Flexelint - Warning 679: Suspicious Truncation in arithmetic expression combining with pointer */ 869 m_buf[1 + i] = sesskey->key[i]; 870 } 871 872 return (__ops_calc_sesskey_checksum(sesskey, 873 m_buf + 1 + CAST_KEY_LENGTH)); 874 } 875 876 /** 877 \ingroup Core_Create 878 \brief implementation of EME-PKCS1-v1_5-ENCODE, as defined in OpenPGP RFC 879 \param M 880 \param mLen 881 \param pubkey 882 \param EM 883 \return 1 if OK; else 0 884 */ 885 unsigned 886 encode_m_buf(const uint8_t *M, size_t mLen, const __ops_pubkey_t * pubkey, 887 uint8_t *EM) 888 { 889 unsigned k; 890 unsigned i; 891 892 /* implementation of EME-PKCS1-v1_5-ENCODE, as defined in OpenPGP RFC */ 893 894 if (pubkey->alg != OPS_PKA_RSA) { 895 (void) fprintf(stderr, "encode_m_buf: pubkey algorithm\n"); 896 return 0; 897 } 898 899 k = (unsigned)BN_num_bytes(pubkey->key.rsa.n); 900 if (mLen > k - 11) { 901 (void) fprintf(stderr, "encode_m_buf: message too long\n"); 902 return 0; 903 } 904 /* these two bytes defined by RFC */ 905 EM[0] = 0x00; 906 EM[1] = 0x02; 907 908 /* add non-zero random bytes of length k - mLen -3 */ 909 for (i = 2; i < (k - mLen) - 1; ++i) { 910 do { 911 __ops_random(EM + i, 1); 912 } while (EM[i] == 0); 913 } 914 915 if (i < 8 + 2) { 916 (void) fprintf(stderr, "encode_m_buf: bad i len\n"); 917 return 0; 918 } 919 920 EM[i++] = 0; 921 922 (void) memcpy(EM + i, M, mLen); 923 924 if (__ops_get_debug_level(__FILE__)) { 925 (void) fprintf(stderr, "Encoded Message: \n"); 926 hexdump(stderr, EM, mLen, " "); 927 (void) fprintf(stderr, "\n"); 928 } 929 return 1; 930 } 931 932 /** 933 \ingroup Core_Create 934 \brief Creates an __ops_pk_sesskey_t struct from keydata 935 \param key Keydata to use 936 \return __ops_pk_sesskey_t struct 937 \note It is the caller's responsiblity to free the returned pointer 938 \note Currently hard-coded to use CAST5 939 \note Currently hard-coded to use RSA 940 */ 941 __ops_pk_sesskey_t * 942 __ops_create_pk_sesskey(const __ops_key_t *key) 943 { 944 /* 945 * Creates a random session key and encrypts it for the given key 946 * 947 * Session Key is for use with a SK algo, 948 * can be any, we're hardcoding CAST5 for now 949 * 950 * Encryption used is PK, 951 * can be any, we're hardcoding RSA for now 952 */ 953 954 #define SZ_UNENCODED_M_BUF (CAST_KEY_LENGTH + 1 + 2) 955 956 const __ops_pubkey_t *pubkey; 957 __ops_pk_sesskey_t *sesskey; 958 uint8_t unencoded_m_buf[SZ_UNENCODED_M_BUF]; 959 uint8_t *encoded_m_buf; 960 size_t sz_encoded_m_buf; 961 962 pubkey = __ops_get_pubkey(key); 963 sz_encoded_m_buf = BN_num_bytes(pubkey->key.rsa.n); 964 if ((encoded_m_buf = calloc(1, sz_encoded_m_buf)) == NULL) { 965 (void) fprintf(stderr, 966 "__ops_create_pk_sesskey: can't allocate\n"); 967 return NULL; 968 } 969 if ((sesskey = calloc(1, sizeof(*sesskey))) == NULL) { 970 (void) fprintf(stderr, 971 "__ops_create_pk_sesskey: can't allocate\n"); 972 free(encoded_m_buf); 973 return NULL; 974 } 975 if (key->type != OPS_PTAG_CT_PUBLIC_KEY) { 976 (void) fprintf(stderr, 977 "__ops_create_pk_sesskey: bad type\n"); 978 free(encoded_m_buf); 979 free(sesskey); 980 return NULL; 981 } 982 sesskey->version = OPS_PKSK_V3; 983 (void) memcpy(sesskey->key_id, key->key_id, 984 sizeof(sesskey->key_id)); 985 986 if (__ops_get_debug_level(__FILE__)) { 987 (void) fprintf(stderr, "Encrypting for RSA key id : "); 988 hexdump(stderr, key->key_id, sizeof(sesskey->key_id), " "); 989 (void) fprintf(stderr, "\n"); 990 } 991 if (key->key.pubkey.alg != OPS_PKA_RSA) { 992 (void) fprintf(stderr, 993 "__ops_create_pk_sesskey: bad pubkey algorithm\n"); 994 free(encoded_m_buf); 995 free(sesskey); 996 return NULL; 997 } 998 sesskey->alg = key->key.pubkey.alg; 999 1000 /* \todo allow user to specify other algorithm */ 1001 sesskey->symm_alg = OPS_SA_CAST5; 1002 __ops_random(sesskey->key, CAST_KEY_LENGTH); 1003 1004 if (__ops_get_debug_level(__FILE__)) { 1005 (void) fprintf(stderr, 1006 "CAST5 session key created (len=%d):\n ", 1007 CAST_KEY_LENGTH); 1008 hexdump(stderr, sesskey->key, CAST_KEY_LENGTH, " "); 1009 (void) fprintf(stderr, "\n"); 1010 } 1011 if (create_unencoded_m_buf(sesskey, &unencoded_m_buf[0]) == 0) { 1012 free(encoded_m_buf); 1013 free(sesskey); 1014 return NULL; 1015 } 1016 if (__ops_get_debug_level(__FILE__)) { 1017 fprintf(stderr, "unencoded m buf:\n"); 1018 hexdump(stderr, unencoded_m_buf, SZ_UNENCODED_M_BUF, " "); 1019 fprintf(stderr, "\n"); 1020 } 1021 encode_m_buf(unencoded_m_buf, SZ_UNENCODED_M_BUF, pubkey, encoded_m_buf); 1022 1023 /* and encrypt it */ 1024 if (!__ops_rsa_encrypt_mpi(encoded_m_buf, sz_encoded_m_buf, pubkey, 1025 &sesskey->params)) { 1026 free(encoded_m_buf); 1027 free(sesskey); 1028 return NULL; 1029 } 1030 free(encoded_m_buf); 1031 return sesskey; 1032 } 1033 1034 /** 1035 \ingroup Core_WritePackets 1036 \brief Writes Public Key Session Key packet 1037 \param info Write settings 1038 \param pksk Public Key Session Key to write out 1039 \return 1 if OK; else 0 1040 */ 1041 unsigned 1042 __ops_write_pk_sesskey(__ops_output_t *output, __ops_pk_sesskey_t *pksk) 1043 { 1044 /* XXX - Flexelint - Pointer parameter 'pksk' (line 1076) could be declared as pointing to const */ 1045 if (pksk == NULL) { 1046 (void) fprintf(stderr, 1047 "__ops_write_pk_sesskey: NULL pksk\n"); 1048 return 0; 1049 } 1050 if (pksk->alg != OPS_PKA_RSA) { 1051 (void) fprintf(stderr, 1052 "__ops_write_pk_sesskey: bad algorithm\n"); 1053 return 0; 1054 } 1055 return __ops_write_ptag(output, OPS_PTAG_CT_PK_SESSION_KEY) && 1056 __ops_write_length(output, (unsigned)(1 + 8 + 1 + 1057 BN_num_bytes(pksk->params.rsa.encrypted_m) + 2)) && 1058 __ops_write_scalar(output, (unsigned)pksk->version, 1) && 1059 __ops_write(output, pksk->key_id, 8) && 1060 __ops_write_scalar(output, (unsigned)pksk->alg, 1) && 1061 __ops_write_mpi(output, pksk->params.rsa.encrypted_m) 1062 /* ?? && __ops_write_scalar(output, 0, 2); */ 1063 ; 1064 } 1065 1066 /** 1067 \ingroup Core_WritePackets 1068 \brief Writes MDC packet 1069 \param hashed Hash for MDC 1070 \param output Write settings 1071 \return 1 if OK; else 0 1072 */ 1073 1074 unsigned 1075 __ops_write_mdc(__ops_output_t *output, const uint8_t *hashed) 1076 { 1077 /* write it out */ 1078 return __ops_write_ptag(output, OPS_PTAG_CT_MDC) && 1079 __ops_write_length(output, OPS_SHA1_HASH_SIZE) && 1080 __ops_write(output, hashed, OPS_SHA1_HASH_SIZE); 1081 } 1082 1083 /** 1084 \ingroup Core_WritePackets 1085 \brief Writes Literal Data packet from buffer 1086 \param data Buffer to write out 1087 \param maxlen Max length of buffer 1088 \param type Literal Data Type 1089 \param output Write settings 1090 \return 1 if OK; else 0 1091 */ 1092 unsigned 1093 __ops_write_litdata(__ops_output_t *output, 1094 const uint8_t *data, 1095 const int maxlen, 1096 const __ops_litdata_enum type) 1097 { 1098 /* 1099 * RFC4880 does not specify a meaning for filename or date. 1100 * It is implementation-dependent. 1101 * We will not implement them. 1102 */ 1103 /* \todo do we need to check text data for <cr><lf> line endings ? */ 1104 return __ops_write_ptag(output, OPS_PTAG_CT_LITDATA) && 1105 __ops_write_length(output, (unsigned)(1 + 1 + 4 + maxlen)) && 1106 __ops_write_scalar(output, (unsigned)type, 1) && 1107 __ops_write_scalar(output, 0, 1) && 1108 __ops_write_scalar(output, 0, 4) && 1109 __ops_write(output, data, (unsigned)maxlen); 1110 } 1111 1112 /** 1113 \ingroup Core_WritePackets 1114 \brief Writes Literal Data packet from contents of file 1115 \param filename Name of file to read from 1116 \param type Literal Data Type 1117 \param output Write settings 1118 \return 1 if OK; else 0 1119 */ 1120 1121 unsigned 1122 __ops_fileread_litdata(const char *filename, 1123 const __ops_litdata_enum type, 1124 __ops_output_t *output) 1125 { 1126 __ops_memory_t *mem; 1127 unsigned ret; 1128 int len; 1129 1130 mem = __ops_memory_new(); 1131 if (!__ops_mem_readfile(mem, filename)) { 1132 (void) fprintf(stderr, "__ops_mem_readfile of '%s' failed\n", filename); 1133 return 0; 1134 } 1135 len = (size_t)__ops_mem_len(mem); 1136 ret = __ops_write_litdata(output, __ops_mem_data(mem), len, type); 1137 __ops_memory_free(mem); 1138 return ret; 1139 } 1140 1141 /** 1142 \ingroup HighLevel_General 1143 1144 \brief Writes contents of buffer into file 1145 1146 \param filename Filename to write to 1147 \param buf Buffer to write to file 1148 \param len Size of buffer 1149 \param overwrite Flag to set whether to overwrite an existing file 1150 \return 1 if OK; 0 if error 1151 */ 1152 1153 int 1154 __ops_filewrite(const char *filename, const char *buf, 1155 const size_t len, const unsigned overwrite) 1156 { 1157 int flags; 1158 int fd; 1159 1160 flags = O_WRONLY | O_CREAT; 1161 if (overwrite) { 1162 flags |= O_TRUNC; 1163 } else { 1164 flags |= O_EXCL; 1165 } 1166 #ifdef O_BINARY 1167 flags |= O_BINARY; 1168 #endif 1169 fd = open(filename, flags, 0600); 1170 if (fd < 0) { 1171 (void) fprintf(stderr, "can't open '%s'\n", filename); 1172 return 0; 1173 } 1174 if (write(fd, buf, len) != (int)len) { 1175 (void) close(fd); 1176 return 0; 1177 } 1178 1179 return (close(fd) == 0); 1180 } 1181 1182 /** 1183 \ingroup Core_WritePackets 1184 \brief Write Symmetrically Encrypted packet 1185 \param data Data to encrypt 1186 \param len Length of data 1187 \param output Write settings 1188 \return 1 if OK; else 0 1189 \note Hard-coded to use AES256 1190 */ 1191 unsigned 1192 __ops_write_symm_enc_data(const uint8_t *data, 1193 const int len, 1194 __ops_output_t * output) 1195 { 1196 __ops_crypt_t crypt_info; 1197 uint8_t *encrypted = (uint8_t *) NULL; 1198 size_t encrypted_sz; 1199 int done = 0; 1200 1201 /* \todo assume AES256 for now */ 1202 __ops_crypt_any(&crypt_info, OPS_SA_AES_256); 1203 __ops_encrypt_init(&crypt_info); 1204 1205 encrypted_sz = (size_t)(len + crypt_info.blocksize + 2); 1206 if ((encrypted = calloc(1, encrypted_sz)) == NULL) { 1207 (void) fprintf(stderr, "can't allocate %" PRIsize "d\n", 1208 encrypted_sz); 1209 return 0; 1210 } 1211 1212 done = __ops_encrypt_se(&crypt_info, encrypted, data, (unsigned)len); 1213 if (done != len) { 1214 (void) fprintf(stderr, 1215 "__ops_write_symm_enc_data: done != len\n"); 1216 return 0; 1217 } 1218 1219 return __ops_write_ptag(output, OPS_PTAG_CT_SE_DATA) && 1220 __ops_write_length(output, 1 + encrypted_sz) && 1221 __ops_write(output, data, (unsigned)len); 1222 } 1223 1224 /** 1225 \ingroup Core_WritePackets 1226 \brief Write a One Pass Signature packet 1227 \param seckey Secret Key to use 1228 \param hash_alg Hash Algorithm to use 1229 \param sig_type Signature type 1230 \param output Write settings 1231 \return 1 if OK; else 0 1232 */ 1233 unsigned 1234 __ops_write_one_pass_sig(__ops_output_t *output, 1235 const __ops_seckey_t *seckey, 1236 const __ops_hash_alg_t hash_alg, 1237 const __ops_sig_type_t sig_type) 1238 { 1239 uint8_t keyid[OPS_KEY_ID_SIZE]; 1240 1241 __ops_keyid(keyid, OPS_KEY_ID_SIZE, &seckey->pubkey); 1242 return __ops_write_ptag(output, OPS_PTAG_CT_1_PASS_SIG) && 1243 __ops_write_length(output, 1 + 1 + 1 + 1 + 8 + 1) && 1244 __ops_write_scalar(output, 3, 1) /* version */ && 1245 __ops_write_scalar(output, (unsigned)sig_type, 1) && 1246 __ops_write_scalar(output, (unsigned)hash_alg, 1) && 1247 __ops_write_scalar(output, (unsigned)seckey->pubkey.alg, 1) && 1248 __ops_write(output, keyid, 8) && 1249 __ops_write_scalar(output, 1, 1); 1250 } 1251