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