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