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