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: openssl_crypto.c,v 1.22 2010/05/08 00:33:28 agc Exp $"); 61 #endif 62 63 #ifdef HAVE_OPENSSL_DSA_H 64 #include <openssl/dsa.h> 65 #endif 66 67 #ifdef HAVE_OPENSSL_RSA_H 68 #include <openssl/rsa.h> 69 #endif 70 71 #ifdef HAVE_OPENSSL_ERR_H 72 #include <openssl/err.h> 73 #endif 74 75 #include <openssl/pem.h> 76 #include <openssl/evp.h> 77 78 #include <stdlib.h> 79 #include <string.h> 80 /* Hash size for secret key check */ 81 82 #include "crypto.h" 83 #include "keyring.h" 84 #include "readerwriter.h" 85 #include "netpgpdefs.h" 86 #include "netpgpdigest.h" 87 #include "packet.h" 88 89 90 static void 91 test_seckey(const __ops_seckey_t *seckey) 92 { 93 RSA *test = RSA_new(); 94 95 test->n = BN_dup(seckey->pubkey.key.rsa.n); 96 test->e = BN_dup(seckey->pubkey.key.rsa.e); 97 98 test->d = BN_dup(seckey->key.rsa.d); 99 test->p = BN_dup(seckey->key.rsa.p); 100 test->q = BN_dup(seckey->key.rsa.q); 101 102 if (RSA_check_key(test) != 1) { 103 (void) fprintf(stderr, 104 "test_seckey: RSA_check_key failed\n"); 105 } 106 RSA_free(test); 107 } 108 109 static int 110 md5_init(__ops_hash_t *hash) 111 { 112 if (hash->data) { 113 (void) fprintf(stderr, "md5_init: hash data non-null\n"); 114 } 115 if ((hash->data = calloc(1, sizeof(MD5_CTX))) == NULL) { 116 (void) fprintf(stderr, "md5_init: bad alloc\n"); 117 return 0; 118 } 119 MD5_Init(hash->data); 120 return 1; 121 } 122 123 static void 124 md5_add(__ops_hash_t *hash, const uint8_t *data, unsigned length) 125 { 126 MD5_Update(hash->data, data, length); 127 } 128 129 static unsigned 130 md5_finish(__ops_hash_t *hash, uint8_t *out) 131 { 132 MD5_Final(out, hash->data); 133 free(hash->data); 134 hash->data = NULL; 135 return 16; 136 } 137 138 static const __ops_hash_t md5 = { 139 OPS_HASH_MD5, 140 MD5_DIGEST_LENGTH, 141 "MD5", 142 md5_init, 143 md5_add, 144 md5_finish, 145 NULL 146 }; 147 148 /** 149 \ingroup Core_Crypto 150 \brief Initialise to MD5 151 \param hash Hash to initialise 152 */ 153 void 154 __ops_hash_md5(__ops_hash_t *hash) 155 { 156 *hash = md5; 157 } 158 159 static int 160 sha1_init(__ops_hash_t *hash) 161 { 162 if (__ops_get_debug_level(__FILE__)) { 163 fprintf(stderr, "***\n***\nsha1_init\n***\n"); 164 } 165 if (hash->data) { 166 (void) fprintf(stderr, "sha1_init: hash data non-null\n"); 167 } 168 if ((hash->data = calloc(1, sizeof(SHA_CTX))) == NULL) { 169 (void) fprintf(stderr, "sha1_init: bad alloc\n"); 170 return 0; 171 } 172 SHA1_Init(hash->data); 173 return 1; 174 } 175 176 static void 177 sha1_add(__ops_hash_t *hash, const uint8_t *data, unsigned length) 178 { 179 if (__ops_get_debug_level(__FILE__)) { 180 unsigned i; 181 182 (void) fprintf(stderr, "adding %u to hash:\n ", length); 183 for (i = 0; i < length; i++) { 184 (void) fprintf(stderr, "0x%02x ", data[i]); 185 if (!((i + 1) % 16)) { 186 (void) fprintf(stderr, "\n"); 187 } else if (!((i + 1) % 8)) { 188 (void) fprintf(stderr, " "); 189 } 190 } 191 (void) fprintf(stderr, "\n"); 192 } 193 SHA1_Update(hash->data, data, length); 194 } 195 196 static unsigned 197 sha1_finish(__ops_hash_t *hash, uint8_t *out) 198 { 199 SHA1_Final(out, hash->data); 200 if (__ops_get_debug_level(__FILE__)) { 201 unsigned i; 202 203 (void) fprintf(stderr, "***\n***\nsha1_finish\n***\n"); 204 for (i = 0; i < OPS_SHA1_HASH_SIZE; i++) 205 (void) fprintf(stderr, "0x%02x ", out[i]); 206 (void) fprintf(stderr, "\n"); 207 } 208 free(hash->data); 209 hash->data = NULL; 210 return OPS_SHA1_HASH_SIZE; 211 } 212 213 static const __ops_hash_t sha1 = { 214 OPS_HASH_SHA1, 215 OPS_SHA1_HASH_SIZE, 216 "SHA1", 217 sha1_init, 218 sha1_add, 219 sha1_finish, 220 NULL 221 }; 222 223 /** 224 \ingroup Core_Crypto 225 \brief Initialise to SHA1 226 \param hash Hash to initialise 227 */ 228 void 229 __ops_hash_sha1(__ops_hash_t *hash) 230 { 231 *hash = sha1; 232 } 233 234 static int 235 sha256_init(__ops_hash_t *hash) 236 { 237 if (__ops_get_debug_level(__FILE__)) { 238 fprintf(stderr, "***\n***\nsha256_init\n***\n"); 239 } 240 if (hash->data) { 241 (void) fprintf(stderr, "sha256_init: hash data non-null\n"); 242 } 243 if ((hash->data = calloc(1, sizeof(SHA256_CTX))) == NULL) { 244 (void) fprintf(stderr, "sha256_init: bad alloc\n"); 245 return 0; 246 } 247 SHA256_Init(hash->data); 248 return 1; 249 } 250 251 static void 252 sha256_add(__ops_hash_t *hash, const uint8_t *data, unsigned length) 253 { 254 if (__ops_get_debug_level(__FILE__)) { 255 unsigned i; 256 257 (void) fprintf(stderr, "adding %d to hash:\n ", length); 258 for (i = 0; i < length; i++) { 259 (void) fprintf(stderr, "0x%02x ", data[i]); 260 if (!((i + 1) % 16)) 261 (void) fprintf(stderr, "\n"); 262 else if (!((i + 1) % 8)) 263 (void) fprintf(stderr, " "); 264 } 265 (void) fprintf(stderr, "\n"); 266 } 267 SHA256_Update(hash->data, data, length); 268 } 269 270 static unsigned 271 sha256_finish(__ops_hash_t *hash, uint8_t *out) 272 { 273 SHA256_Final(out, hash->data); 274 if (__ops_get_debug_level(__FILE__)) { 275 unsigned i; 276 277 (void) fprintf(stderr, "***\n***\nsha1_finish\n***\n"); 278 for (i = 0; i < SHA256_DIGEST_LENGTH; i++) 279 (void) fprintf(stderr, "0x%02x ", out[i]); 280 (void) fprintf(stderr, "\n"); 281 } 282 free(hash->data); 283 hash->data = NULL; 284 return SHA256_DIGEST_LENGTH; 285 } 286 287 static const __ops_hash_t sha256 = { 288 OPS_HASH_SHA256, 289 SHA256_DIGEST_LENGTH, 290 "SHA256", 291 sha256_init, 292 sha256_add, 293 sha256_finish, 294 NULL 295 }; 296 297 void 298 __ops_hash_sha256(__ops_hash_t *hash) 299 { 300 *hash = sha256; 301 } 302 303 /* 304 * SHA384 305 */ 306 static int 307 sha384_init(__ops_hash_t *hash) 308 { 309 if (__ops_get_debug_level(__FILE__)) { 310 (void) fprintf(stderr, "***\n***\nsha384_init\n***\n"); 311 } 312 if (hash->data) { 313 (void) fprintf(stderr, "sha384_init: hash data non-null\n"); 314 } 315 if ((hash->data = calloc(1, sizeof(SHA512_CTX))) == NULL) { 316 (void) fprintf(stderr, "sha512_init: bad alloc\n"); 317 return 0; 318 } 319 SHA384_Init(hash->data); 320 return 1; 321 } 322 323 static void 324 sha384_add(__ops_hash_t *hash, const uint8_t *data, unsigned length) 325 { 326 if (__ops_get_debug_level(__FILE__)) { 327 unsigned i; 328 329 (void) fprintf(stderr, "adding %u to hash:\n ", length); 330 for (i = 0; i < length; i++) { 331 (void) fprintf(stderr, "0x%02x ", data[i]); 332 if (!((i + 1) % 16)) 333 (void) fprintf(stderr, "\n"); 334 else if (!((i + 1) % 8)) 335 (void) fprintf(stderr, " "); 336 } 337 (void) fprintf(stderr, "\n"); 338 } 339 SHA384_Update(hash->data, data, length); 340 } 341 342 static unsigned 343 sha384_finish(__ops_hash_t *hash, uint8_t *out) 344 { 345 SHA384_Final(out, hash->data); 346 if (__ops_get_debug_level(__FILE__)) { 347 unsigned i; 348 349 (void) fprintf(stderr, "***\n***\nsha1_finish\n***\n"); 350 for (i = 0; i < SHA384_DIGEST_LENGTH; i++) 351 (void) fprintf(stderr, "0x%02x ", out[i]); 352 (void) fprintf(stderr, "\n"); 353 } 354 free(hash->data); 355 hash->data = NULL; 356 return SHA384_DIGEST_LENGTH; 357 } 358 359 static const __ops_hash_t sha384 = { 360 OPS_HASH_SHA384, 361 SHA384_DIGEST_LENGTH, 362 "SHA384", 363 sha384_init, 364 sha384_add, 365 sha384_finish, 366 NULL 367 }; 368 369 void 370 __ops_hash_sha384(__ops_hash_t *hash) 371 { 372 *hash = sha384; 373 } 374 375 /* 376 * SHA512 377 */ 378 static int 379 sha512_init(__ops_hash_t *hash) 380 { 381 if (__ops_get_debug_level(__FILE__)) { 382 (void) fprintf(stderr, "***\n***\nsha512_init\n***\n"); 383 } 384 if (hash->data) { 385 (void) fprintf(stderr, "sha512_init: hash data non-null\n"); 386 } 387 if ((hash->data = calloc(1, sizeof(SHA512_CTX))) == NULL) { 388 (void) fprintf(stderr, "sha512_init: bad alloc\n"); 389 return 0; 390 } 391 SHA512_Init(hash->data); 392 return 1; 393 } 394 395 static void 396 sha512_add(__ops_hash_t *hash, const uint8_t *data, unsigned length) 397 { 398 if (__ops_get_debug_level(__FILE__)) { 399 unsigned i; 400 401 (void) fprintf(stderr, "adding %u to hash:\n ", length); 402 for (i = 0; i < length; i++) { 403 (void) fprintf(stderr, "0x%02x ", data[i]); 404 if (!((i + 1) % 16)) 405 (void) fprintf(stderr, "\n"); 406 else if (!((i + 1) % 8)) 407 (void) fprintf(stderr, " "); 408 } 409 (void) fprintf(stderr, "\n"); 410 } 411 SHA512_Update(hash->data, data, length); 412 } 413 414 static unsigned 415 sha512_finish(__ops_hash_t *hash, uint8_t *out) 416 { 417 SHA512_Final(out, hash->data); 418 if (__ops_get_debug_level(__FILE__)) { 419 unsigned i; 420 421 (void) fprintf(stderr, "***\n***\nsha1_finish\n***\n"); 422 for (i = 0; i < SHA512_DIGEST_LENGTH; i++) 423 (void) fprintf(stderr, "0x%02x ", out[i]); 424 (void) fprintf(stderr, "\n"); 425 } 426 free(hash->data); 427 hash->data = NULL; 428 return SHA512_DIGEST_LENGTH; 429 } 430 431 static const __ops_hash_t sha512 = { 432 OPS_HASH_SHA512, 433 SHA512_DIGEST_LENGTH, 434 "SHA512", 435 sha512_init, 436 sha512_add, 437 sha512_finish, 438 NULL 439 }; 440 441 void 442 __ops_hash_sha512(__ops_hash_t *hash) 443 { 444 *hash = sha512; 445 } 446 447 /* 448 * SHA224 449 */ 450 451 static int 452 sha224_init(__ops_hash_t *hash) 453 { 454 if (__ops_get_debug_level(__FILE__)) { 455 (void) fprintf(stderr, "***\n***\nsha1_init\n***\n"); 456 } 457 if (hash->data) { 458 (void) fprintf(stderr, "sha224_init: hash data non-null\n"); 459 } 460 if ((hash->data = calloc(1, sizeof(SHA256_CTX))) == NULL) { 461 (void) fprintf(stderr, "sha256_init: bad alloc\n"); 462 return 0; 463 } 464 SHA224_Init(hash->data); 465 return 1; 466 } 467 468 static void 469 sha224_add(__ops_hash_t *hash, const uint8_t *data, unsigned length) 470 { 471 if (__ops_get_debug_level(__FILE__)) { 472 unsigned i; 473 474 (void) fprintf(stderr, "adding %u to hash:\n ", length); 475 for (i = 0; i < length; i++) { 476 (void) fprintf(stderr, "0x%02x ", data[i]); 477 if (!((i + 1) % 16)) 478 (void) fprintf(stderr, "\n"); 479 else if (!((i + 1) % 8)) 480 (void) fprintf(stderr, " "); 481 } 482 (void) fprintf(stderr, "\n"); 483 } 484 SHA224_Update(hash->data, data, length); 485 } 486 487 static unsigned 488 sha224_finish(__ops_hash_t *hash, uint8_t *out) 489 { 490 SHA224_Final(out, hash->data); 491 if (__ops_get_debug_level(__FILE__)) { 492 unsigned i; 493 494 (void) fprintf(stderr, "***\n***\nsha1_finish\n***\n"); 495 for (i = 0; i < SHA224_DIGEST_LENGTH; i++) 496 (void) fprintf(stderr, "0x%02x ", out[i]); 497 (void) fprintf(stderr, "\n"); 498 } 499 free(hash->data); 500 hash->data = NULL; 501 return SHA224_DIGEST_LENGTH; 502 } 503 504 static const __ops_hash_t sha224 = { 505 OPS_HASH_SHA224, 506 SHA224_DIGEST_LENGTH, 507 "SHA224", 508 sha224_init, 509 sha224_add, 510 sha224_finish, 511 NULL 512 }; 513 514 void 515 __ops_hash_sha224(__ops_hash_t *hash) 516 { 517 *hash = sha224; 518 } 519 520 unsigned 521 __ops_dsa_verify(const uint8_t *hash, size_t hash_length, 522 const __ops_dsa_sig_t *sig, 523 const __ops_dsa_pubkey_t *dsa) 524 { 525 unsigned qlen; 526 DSA_SIG *osig; 527 DSA *odsa; 528 int ret; 529 530 osig = DSA_SIG_new(); 531 osig->r = sig->r; 532 osig->s = sig->s; 533 534 odsa = DSA_new(); 535 odsa->p = dsa->p; 536 odsa->q = dsa->q; 537 odsa->g = dsa->g; 538 odsa->pub_key = dsa->y; 539 540 if (__ops_get_debug_level(__FILE__)) { 541 (void) fprintf(stderr, "hash passed in:\n"); 542 hexdump(stderr, hash, hash_length, " "); 543 (void) fprintf(stderr, "\nhash_length=%" PRIsize "d\n", hash_length); 544 (void) fprintf(stderr, "Q=%d\n", BN_num_bytes(odsa->q)); 545 } 546 if ((qlen = (unsigned)BN_num_bytes(odsa->q)) < hash_length) { 547 hash_length = qlen; 548 } 549 ret = DSA_do_verify(hash, (int)hash_length, osig, odsa); 550 if (__ops_get_debug_level(__FILE__)) { 551 (void) fprintf(stderr, "ret=%d\n", ret); 552 } 553 if (ret < 0) { 554 (void) fprintf(stderr, "__ops_dsa_verify: DSA verification\n"); 555 return 0; 556 } 557 558 odsa->p = odsa->q = odsa->g = odsa->pub_key = NULL; 559 DSA_free(odsa); 560 561 osig->r = osig->s = NULL; 562 DSA_SIG_free(osig); 563 564 return (unsigned)ret; 565 } 566 567 /** 568 \ingroup Core_Crypto 569 \brief Recovers message digest from the signature 570 \param out Where to write decrypted data to 571 \param in Encrypted data 572 \param length Length of encrypted data 573 \param pubkey RSA public key 574 \return size of recovered message digest 575 */ 576 int 577 __ops_rsa_public_decrypt(uint8_t *out, 578 const uint8_t *in, 579 size_t length, 580 const __ops_rsa_pubkey_t *pubkey) 581 { 582 RSA *orsa; 583 int n; 584 585 orsa = RSA_new(); 586 orsa->n = pubkey->n; 587 orsa->e = pubkey->e; 588 589 n = RSA_public_decrypt((int)length, in, out, orsa, RSA_NO_PADDING); 590 591 orsa->n = orsa->e = NULL; 592 RSA_free(orsa); 593 594 return n; 595 } 596 597 /** 598 \ingroup Core_Crypto 599 \brief Signs data with RSA 600 \param out Where to write signature 601 \param in Data to sign 602 \param length Length of data 603 \param seckey RSA secret key 604 \param pubkey RSA public key 605 \return number of bytes decrypted 606 */ 607 int 608 __ops_rsa_private_encrypt(uint8_t *out, 609 const uint8_t *in, 610 size_t length, 611 const __ops_rsa_seckey_t *seckey, 612 const __ops_rsa_pubkey_t *pubkey) 613 { 614 RSA *orsa; 615 int n; 616 617 orsa = RSA_new(); 618 orsa->n = BN_dup(pubkey->n); 619 orsa->d = seckey->d; 620 orsa->p = seckey->q; 621 orsa->q = seckey->p; 622 623 /* debug */ 624 orsa->e = BN_dup(pubkey->e); 625 /* If this isn't set, it's very likely that the programmer hasn't */ 626 /* decrypted the secret key. RSA_check_key segfaults in that case. */ 627 /* Use __ops_decrypt_seckey() to do that. */ 628 if (orsa->d == NULL) { 629 (void) fprintf(stderr, "orsa is not set\n"); 630 return 0; 631 } 632 if (RSA_check_key(orsa) != 1) { 633 (void) fprintf(stderr, "RSA_check_key is not set\n"); 634 return 0; 635 } 636 /* end debug */ 637 638 n = RSA_private_encrypt((int)length, in, out, orsa, RSA_NO_PADDING); 639 640 orsa->n = orsa->d = orsa->p = orsa->q = NULL; 641 RSA_free(orsa); 642 643 return n; 644 } 645 646 /** 647 \ingroup Core_Crypto 648 \brief Decrypts RSA-encrypted data 649 \param out Where to write the plaintext 650 \param in Encrypted data 651 \param length Length of encrypted data 652 \param seckey RSA secret key 653 \param pubkey RSA public key 654 \return size of recovered plaintext 655 */ 656 int 657 __ops_rsa_private_decrypt(uint8_t *out, 658 const uint8_t *in, 659 size_t length, 660 const __ops_rsa_seckey_t *seckey, 661 const __ops_rsa_pubkey_t *pubkey) 662 { 663 RSA *keypair; 664 int n; 665 char errbuf[1024]; 666 667 keypair = RSA_new(); 668 keypair->n = pubkey->n; /* XXX: do we need n? */ 669 keypair->d = seckey->d; 670 keypair->p = seckey->q; 671 keypair->q = seckey->p; 672 673 /* debug */ 674 keypair->e = pubkey->e; 675 if (RSA_check_key(keypair) != 1) { 676 (void) fprintf(stderr, "RSA_check_key is not set\n"); 677 return 0; 678 } 679 /* end debug */ 680 681 n = RSA_private_decrypt((int)length, in, out, keypair, RSA_NO_PADDING); 682 683 if (__ops_get_debug_level(__FILE__)) { 684 printf("__ops_rsa_private_decrypt: n=%d\n",n); 685 } 686 687 errbuf[0] = '\0'; 688 if (n == -1) { 689 unsigned long err = ERR_get_error(); 690 691 ERR_error_string(err, &errbuf[0]); 692 (void) fprintf(stderr, "openssl error : %s\n", errbuf); 693 } 694 keypair->n = keypair->d = keypair->p = keypair->q = NULL; 695 RSA_free(keypair); 696 697 return n; 698 } 699 700 /** 701 \ingroup Core_Crypto 702 \brief RSA-encrypts data 703 \param out Where to write the encrypted data 704 \param in Plaintext 705 \param length Size of plaintext 706 \param pubkey RSA Public Key 707 */ 708 int 709 __ops_rsa_public_encrypt(uint8_t *out, 710 const uint8_t *in, 711 size_t length, 712 const __ops_rsa_pubkey_t *pubkey) 713 { 714 RSA *orsa; 715 int n; 716 717 /* printf("__ops_rsa_public_encrypt: length=%ld\n", length); */ 718 719 orsa = RSA_new(); 720 orsa->n = pubkey->n; 721 orsa->e = pubkey->e; 722 723 /* printf("len: %ld\n", length); */ 724 /* __ops_print_bn("n: ", orsa->n); */ 725 /* __ops_print_bn("e: ", orsa->e); */ 726 n = RSA_public_encrypt((int)length, in, out, orsa, RSA_NO_PADDING); 727 728 if (n == -1) { 729 BIO *fd_out; 730 731 fd_out = BIO_new_fd(fileno(stderr), BIO_NOCLOSE); 732 ERR_print_errors(fd_out); 733 } 734 orsa->n = orsa->e = NULL; 735 RSA_free(orsa); 736 737 return n; 738 } 739 740 /** 741 \ingroup Core_Crypto 742 \brief Finalise openssl 743 \note Would usually call __ops_finish() instead 744 \sa __ops_finish() 745 */ 746 void 747 __ops_crypto_finish(void) 748 { 749 CRYPTO_cleanup_all_ex_data(); 750 ERR_remove_state((unsigned long)0); 751 } 752 753 /** 754 \ingroup Core_Hashes 755 \brief Get Hash name 756 \param hash Hash struct 757 \return Hash name 758 */ 759 const char * 760 __ops_text_from_hash(__ops_hash_t *hash) 761 { 762 return hash->name; 763 } 764 765 /** 766 \ingroup HighLevel_KeyGenerate 767 \brief Generates an RSA keypair 768 \param numbits Modulus size 769 \param e Public Exponent 770 \param keydata Pointer to keydata struct to hold new key 771 \return 1 if key generated successfully; otherwise 0 772 \note It is the caller's responsibility to call __ops_keydata_free(keydata) 773 */ 774 static unsigned 775 rsa_generate_keypair(__ops_key_t *keydata, 776 const int numbits, 777 const unsigned long e, 778 const char *hashalg) 779 { 780 __ops_seckey_t *seckey; 781 RSA *rsa; 782 BN_CTX *ctx; 783 __ops_output_t *output; 784 __ops_memory_t *mem; 785 786 ctx = BN_CTX_new(); 787 __ops_keydata_init(keydata, OPS_PTAG_CT_SECRET_KEY); 788 seckey = __ops_get_writable_seckey(keydata); 789 790 /* generate the key pair */ 791 792 rsa = RSA_generate_key(numbits, e, NULL, NULL); 793 794 /* populate __ops key from ssl key */ 795 796 seckey->pubkey.version = OPS_V4; 797 seckey->pubkey.birthtime = time(NULL); 798 seckey->pubkey.days_valid = 0; 799 seckey->pubkey.alg = OPS_PKA_RSA; 800 801 seckey->pubkey.key.rsa.n = BN_dup(rsa->n); 802 seckey->pubkey.key.rsa.e = BN_dup(rsa->e); 803 804 seckey->s2k_usage = OPS_S2KU_ENCRYPTED_AND_HASHED; 805 seckey->s2k_specifier = OPS_S2KS_SALTED; 806 /* seckey->s2k_specifier=OPS_S2KS_SIMPLE; */ 807 seckey->alg = OPS_SA_CAST5; /* \todo make param */ 808 if ((seckey->hash_alg = __ops_str_to_hash_alg(hashalg)) == OPS_HASH_UNKNOWN) { 809 seckey->hash_alg = OPS_HASH_SHA1; 810 } 811 seckey->octetc = 0; 812 seckey->checksum = 0; 813 814 seckey->key.rsa.d = BN_dup(rsa->d); 815 seckey->key.rsa.p = BN_dup(rsa->p); 816 seckey->key.rsa.q = BN_dup(rsa->q); 817 seckey->key.rsa.u = BN_mod_inverse(NULL, rsa->p, rsa->q, ctx); 818 if (seckey->key.rsa.u == NULL) { 819 (void) fprintf(stderr, "seckey->key.rsa.u is NULL\n"); 820 return 0; 821 } 822 BN_CTX_free(ctx); 823 824 RSA_free(rsa); 825 826 __ops_keyid(keydata->key_id, OPS_KEY_ID_SIZE, &keydata->key.seckey.pubkey); 827 __ops_fingerprint(&keydata->fingerprint, &keydata->key.seckey.pubkey); 828 829 /* Generate checksum */ 830 831 output = NULL; 832 mem = NULL; 833 834 __ops_setup_memory_write(&output, &mem, 128); 835 836 __ops_push_checksum_writer(output, seckey); 837 838 switch (seckey->pubkey.alg) { 839 /* case OPS_PKA_DSA: */ 840 /* return __ops_write_mpi(output, key->key.dsa.x); */ 841 842 case OPS_PKA_RSA: 843 case OPS_PKA_RSA_ENCRYPT_ONLY: 844 case OPS_PKA_RSA_SIGN_ONLY: 845 if (!__ops_write_mpi(output, seckey->key.rsa.d) || 846 !__ops_write_mpi(output, seckey->key.rsa.p) || 847 !__ops_write_mpi(output, seckey->key.rsa.q) || 848 !__ops_write_mpi(output, seckey->key.rsa.u)) { 849 return 0; 850 } 851 break; 852 853 /* case OPS_PKA_ELGAMAL: */ 854 /* return __ops_write_mpi(output, key->key.elgamal.x); */ 855 856 default: 857 (void) fprintf(stderr, "Bad seckey->pubkey.alg\n"); 858 return 0; 859 } 860 861 /* close rather than pop, since its the only one on the stack */ 862 __ops_writer_close(output); 863 __ops_teardown_memory_write(output, mem); 864 865 /* should now have checksum in seckey struct */ 866 867 /* test */ 868 if (__ops_get_debug_level(__FILE__)) { 869 test_seckey(seckey); 870 } 871 872 return 1; 873 } 874 875 /** 876 \ingroup HighLevel_KeyGenerate 877 \brief Creates a self-signed RSA keypair 878 \param numbits Modulus size 879 \param e Public Exponent 880 \param userid User ID 881 \return The new keypair or NULL 882 883 \note It is the caller's responsibility to call __ops_keydata_free(keydata) 884 \sa rsa_generate_keypair() 885 \sa __ops_keydata_free() 886 */ 887 __ops_key_t * 888 __ops_rsa_new_selfsign_key(const int numbits, 889 const unsigned long e, 890 __ops_userid_t *userid, 891 const char *hashalg) 892 { 893 __ops_key_t *keydata; 894 895 keydata = __ops_keydata_new(); 896 if (!rsa_generate_keypair(keydata, numbits, e, hashalg) || 897 !__ops_add_selfsigned_userid(keydata, userid)) { 898 __ops_keydata_free(keydata); 899 return NULL; 900 } 901 return keydata; 902 } 903 904 DSA_SIG * 905 __ops_dsa_sign(uint8_t *hashbuf, 906 unsigned hashsize, 907 const __ops_dsa_seckey_t *secdsa, 908 const __ops_dsa_pubkey_t *pubdsa) 909 { 910 DSA_SIG *dsasig; 911 DSA *odsa; 912 913 odsa = DSA_new(); 914 odsa->p = pubdsa->p; 915 odsa->q = pubdsa->q; 916 odsa->g = pubdsa->g; 917 odsa->pub_key = pubdsa->y; 918 odsa->priv_key = secdsa->x; 919 920 dsasig = DSA_do_sign(hashbuf, (int)hashsize, odsa); 921 922 odsa->p = odsa->q = odsa->g = odsa->pub_key = odsa->priv_key = NULL; 923 DSA_free(odsa); 924 925 return dsasig; 926 } 927 928 int 929 openssl_read_pem_seckey(const char *f, __ops_key_t *key, const char *type, int verbose) 930 { 931 FILE *fp; 932 DSA *dsa; 933 RSA *rsa; 934 int ok; 935 936 if ((fp = fopen(f, "r")) == NULL) { 937 if (verbose) { 938 (void) fprintf(stderr, "can't open '%s'\n", f); 939 } 940 return 0; 941 } 942 ok = 1; 943 if (strcmp(type, "ssh-rsa") == 0) { 944 if ((rsa = PEM_read_RSAPrivateKey(fp, NULL, NULL, NULL)) == NULL) { 945 ok = 0; 946 } else { 947 key->key.seckey.key.rsa.d = rsa->d; 948 key->key.seckey.key.rsa.p = rsa->p; 949 key->key.seckey.key.rsa.q = rsa->q; 950 key->key.seckey.key.rsa.d = rsa->d; 951 } 952 } else if (strcmp(type, "ssh-dss") == 0) { 953 if ((dsa = PEM_read_DSAPrivateKey(fp, NULL, NULL, NULL)) == NULL) { 954 ok = 0; 955 } else { 956 key->key.seckey.key.dsa.x = dsa->priv_key; 957 } 958 } else { 959 ok = 0; 960 } 961 (void) fclose(fp); 962 return ok; 963 } 964