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