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