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