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