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.25 2010/07/09 05:35:34 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 hexdump(stderr, "input hash", hash, hash_length); 542 (void) fprintf(stderr, "Q=%d\n", BN_num_bytes(odsa->q)); 543 } 544 if ((qlen = (unsigned)BN_num_bytes(odsa->q)) < hash_length) { 545 hash_length = qlen; 546 } 547 ret = DSA_do_verify(hash, (int)hash_length, osig, odsa); 548 if (__ops_get_debug_level(__FILE__)) { 549 (void) fprintf(stderr, "ret=%d\n", ret); 550 } 551 if (ret < 0) { 552 (void) fprintf(stderr, "__ops_dsa_verify: DSA verification\n"); 553 return 0; 554 } 555 556 odsa->p = odsa->q = odsa->g = odsa->pub_key = NULL; 557 DSA_free(odsa); 558 559 osig->r = osig->s = NULL; 560 DSA_SIG_free(osig); 561 562 return (unsigned)ret; 563 } 564 565 /** 566 \ingroup Core_Crypto 567 \brief Recovers message digest from the signature 568 \param out Where to write decrypted data to 569 \param in Encrypted data 570 \param length Length of encrypted data 571 \param pubkey RSA public key 572 \return size of recovered message digest 573 */ 574 int 575 __ops_rsa_public_decrypt(uint8_t *out, 576 const uint8_t *in, 577 size_t length, 578 const __ops_rsa_pubkey_t *pubkey) 579 { 580 RSA *orsa; 581 int n; 582 583 orsa = RSA_new(); 584 orsa->n = pubkey->n; 585 orsa->e = pubkey->e; 586 587 n = RSA_public_decrypt((int)length, in, out, orsa, RSA_NO_PADDING); 588 589 orsa->n = orsa->e = NULL; 590 RSA_free(orsa); 591 592 return n; 593 } 594 595 /** 596 \ingroup Core_Crypto 597 \brief Signs data with RSA 598 \param out Where to write signature 599 \param in Data to sign 600 \param length Length of data 601 \param seckey RSA secret key 602 \param pubkey RSA public key 603 \return number of bytes decrypted 604 */ 605 int 606 __ops_rsa_private_encrypt(uint8_t *out, 607 const uint8_t *in, 608 size_t length, 609 const __ops_rsa_seckey_t *seckey, 610 const __ops_rsa_pubkey_t *pubkey) 611 { 612 RSA *orsa; 613 int n; 614 615 orsa = RSA_new(); 616 orsa->n = BN_dup(pubkey->n); 617 orsa->d = seckey->d; 618 orsa->p = seckey->q; 619 orsa->q = seckey->p; 620 621 /* debug */ 622 orsa->e = BN_dup(pubkey->e); 623 /* If this isn't set, it's very likely that the programmer hasn't */ 624 /* decrypted the secret key. RSA_check_key segfaults in that case. */ 625 /* Use __ops_decrypt_seckey() to do that. */ 626 if (orsa->d == NULL) { 627 (void) fprintf(stderr, "orsa is not set\n"); 628 return 0; 629 } 630 if (RSA_check_key(orsa) != 1) { 631 (void) fprintf(stderr, "RSA_check_key is not set\n"); 632 return 0; 633 } 634 /* end debug */ 635 636 n = RSA_private_encrypt((int)length, in, out, orsa, RSA_NO_PADDING); 637 638 orsa->n = orsa->d = orsa->p = orsa->q = NULL; 639 RSA_free(orsa); 640 641 return n; 642 } 643 644 /** 645 \ingroup Core_Crypto 646 \brief Decrypts RSA-encrypted data 647 \param out Where to write the plaintext 648 \param in Encrypted data 649 \param length Length of encrypted data 650 \param seckey RSA secret key 651 \param pubkey RSA public key 652 \return size of recovered plaintext 653 */ 654 int 655 __ops_rsa_private_decrypt(uint8_t *out, 656 const uint8_t *in, 657 size_t length, 658 const __ops_rsa_seckey_t *seckey, 659 const __ops_rsa_pubkey_t *pubkey) 660 { 661 RSA *keypair; 662 int n; 663 char errbuf[1024]; 664 665 keypair = RSA_new(); 666 keypair->n = pubkey->n; /* XXX: do we need n? */ 667 keypair->d = seckey->d; 668 keypair->p = seckey->q; 669 keypair->q = seckey->p; 670 671 /* debug */ 672 keypair->e = pubkey->e; 673 if (RSA_check_key(keypair) != 1) { 674 (void) fprintf(stderr, "RSA_check_key is not set\n"); 675 return 0; 676 } 677 /* end debug */ 678 679 n = RSA_private_decrypt((int)length, in, out, keypair, RSA_NO_PADDING); 680 681 if (__ops_get_debug_level(__FILE__)) { 682 printf("__ops_rsa_private_decrypt: n=%d\n",n); 683 } 684 685 errbuf[0] = '\0'; 686 if (n == -1) { 687 unsigned long err = ERR_get_error(); 688 689 ERR_error_string(err, &errbuf[0]); 690 (void) fprintf(stderr, "openssl error : %s\n", errbuf); 691 } 692 keypair->n = keypair->d = keypair->p = keypair->q = NULL; 693 RSA_free(keypair); 694 695 return n; 696 } 697 698 /** 699 \ingroup Core_Crypto 700 \brief RSA-encrypts data 701 \param out Where to write the encrypted data 702 \param in Plaintext 703 \param length Size of plaintext 704 \param pubkey RSA Public Key 705 */ 706 int 707 __ops_rsa_public_encrypt(uint8_t *out, 708 const uint8_t *in, 709 size_t length, 710 const __ops_rsa_pubkey_t *pubkey) 711 { 712 RSA *orsa; 713 int n; 714 715 /* printf("__ops_rsa_public_encrypt: length=%ld\n", length); */ 716 717 orsa = RSA_new(); 718 orsa->n = pubkey->n; 719 orsa->e = pubkey->e; 720 721 /* printf("len: %ld\n", length); */ 722 /* __ops_print_bn("n: ", orsa->n); */ 723 /* __ops_print_bn("e: ", orsa->e); */ 724 n = RSA_public_encrypt((int)length, in, out, orsa, RSA_NO_PADDING); 725 726 if (n == -1) { 727 BIO *fd_out; 728 729 fd_out = BIO_new_fd(fileno(stderr), BIO_NOCLOSE); 730 ERR_print_errors(fd_out); 731 } 732 orsa->n = orsa->e = NULL; 733 RSA_free(orsa); 734 735 return n; 736 } 737 738 /** 739 \ingroup Core_Crypto 740 \brief Finalise openssl 741 \note Would usually call __ops_finish() instead 742 \sa __ops_finish() 743 */ 744 void 745 __ops_crypto_finish(void) 746 { 747 CRYPTO_cleanup_all_ex_data(); 748 ERR_remove_state((unsigned long)0); 749 } 750 751 /** 752 \ingroup Core_Hashes 753 \brief Get Hash name 754 \param hash Hash struct 755 \return Hash name 756 */ 757 const char * 758 __ops_text_from_hash(__ops_hash_t *hash) 759 { 760 return hash->name; 761 } 762 763 /** 764 \ingroup HighLevel_KeyGenerate 765 \brief Generates an RSA keypair 766 \param numbits Modulus size 767 \param e Public Exponent 768 \param keydata Pointer to keydata struct to hold new key 769 \return 1 if key generated successfully; otherwise 0 770 \note It is the caller's responsibility to call __ops_keydata_free(keydata) 771 */ 772 static unsigned 773 rsa_generate_keypair(__ops_key_t *keydata, 774 const int numbits, 775 const unsigned long e, 776 const char *hashalg) 777 { 778 __ops_seckey_t *seckey; 779 RSA *rsa; 780 BN_CTX *ctx; 781 __ops_output_t *output; 782 __ops_memory_t *mem; 783 784 ctx = BN_CTX_new(); 785 __ops_keydata_init(keydata, OPS_PTAG_CT_SECRET_KEY); 786 seckey = __ops_get_writable_seckey(keydata); 787 788 /* generate the key pair */ 789 790 rsa = RSA_generate_key(numbits, e, NULL, NULL); 791 792 /* populate __ops key from ssl key */ 793 794 seckey->pubkey.version = OPS_V4; 795 seckey->pubkey.birthtime = time(NULL); 796 seckey->pubkey.days_valid = 0; 797 seckey->pubkey.alg = OPS_PKA_RSA; 798 799 seckey->pubkey.key.rsa.n = BN_dup(rsa->n); 800 seckey->pubkey.key.rsa.e = BN_dup(rsa->e); 801 802 seckey->s2k_usage = OPS_S2KU_ENCRYPTED_AND_HASHED; 803 seckey->s2k_specifier = OPS_S2KS_SALTED; 804 /* seckey->s2k_specifier=OPS_S2KS_SIMPLE; */ 805 seckey->alg = OPS_SA_CAST5; /* \todo make param */ 806 if ((seckey->hash_alg = __ops_str_to_hash_alg(hashalg)) == OPS_HASH_UNKNOWN) { 807 seckey->hash_alg = OPS_HASH_SHA1; 808 } 809 seckey->octetc = 0; 810 seckey->checksum = 0; 811 812 seckey->key.rsa.d = BN_dup(rsa->d); 813 seckey->key.rsa.p = BN_dup(rsa->p); 814 seckey->key.rsa.q = BN_dup(rsa->q); 815 seckey->key.rsa.u = BN_mod_inverse(NULL, rsa->p, rsa->q, ctx); 816 if (seckey->key.rsa.u == NULL) { 817 (void) fprintf(stderr, "seckey->key.rsa.u is NULL\n"); 818 return 0; 819 } 820 BN_CTX_free(ctx); 821 822 RSA_free(rsa); 823 824 __ops_keyid(keydata->key_id, OPS_KEY_ID_SIZE, &keydata->key.seckey.pubkey, seckey->hash_alg); 825 __ops_fingerprint(&keydata->fingerprint, &keydata->key.seckey.pubkey, seckey->hash_alg); 826 827 /* Generate checksum */ 828 829 output = NULL; 830 mem = NULL; 831 832 __ops_setup_memory_write(&output, &mem, 128); 833 834 __ops_push_checksum_writer(output, seckey); 835 836 switch (seckey->pubkey.alg) { 837 case OPS_PKA_DSA: 838 return __ops_write_mpi(output, seckey->key.dsa.x); 839 case OPS_PKA_RSA: 840 case OPS_PKA_RSA_ENCRYPT_ONLY: 841 case OPS_PKA_RSA_SIGN_ONLY: 842 if (!__ops_write_mpi(output, seckey->key.rsa.d) || 843 !__ops_write_mpi(output, seckey->key.rsa.p) || 844 !__ops_write_mpi(output, seckey->key.rsa.q) || 845 !__ops_write_mpi(output, seckey->key.rsa.u)) { 846 return 0; 847 } 848 break; 849 case OPS_PKA_ELGAMAL: 850 return __ops_write_mpi(output, seckey->key.elgamal.x); 851 852 default: 853 (void) fprintf(stderr, "Bad seckey->pubkey.alg\n"); 854 return 0; 855 } 856 857 /* close rather than pop, since its the only one on the stack */ 858 __ops_writer_close(output); 859 __ops_teardown_memory_write(output, mem); 860 861 /* should now have checksum in seckey struct */ 862 863 /* test */ 864 if (__ops_get_debug_level(__FILE__)) { 865 test_seckey(seckey); 866 } 867 868 return 1; 869 } 870 871 /** 872 \ingroup HighLevel_KeyGenerate 873 \brief Creates a self-signed RSA keypair 874 \param numbits Modulus size 875 \param e Public Exponent 876 \param userid User ID 877 \return The new keypair or NULL 878 879 \note It is the caller's responsibility to call __ops_keydata_free(keydata) 880 \sa rsa_generate_keypair() 881 \sa __ops_keydata_free() 882 */ 883 __ops_key_t * 884 __ops_rsa_new_selfsign_key(const int numbits, 885 const unsigned long e, 886 uint8_t *userid, 887 const char *hashalg) 888 { 889 __ops_key_t *keydata; 890 891 keydata = __ops_keydata_new(); 892 if (!rsa_generate_keypair(keydata, numbits, e, hashalg) || 893 !__ops_add_selfsigned_userid(keydata, userid)) { 894 __ops_keydata_free(keydata); 895 return NULL; 896 } 897 return keydata; 898 } 899 900 DSA_SIG * 901 __ops_dsa_sign(uint8_t *hashbuf, 902 unsigned hashsize, 903 const __ops_dsa_seckey_t *secdsa, 904 const __ops_dsa_pubkey_t *pubdsa) 905 { 906 DSA_SIG *dsasig; 907 DSA *odsa; 908 909 odsa = DSA_new(); 910 odsa->p = pubdsa->p; 911 odsa->q = pubdsa->q; 912 odsa->g = pubdsa->g; 913 odsa->pub_key = pubdsa->y; 914 odsa->priv_key = secdsa->x; 915 916 dsasig = DSA_do_sign(hashbuf, (int)hashsize, odsa); 917 918 odsa->p = odsa->q = odsa->g = odsa->pub_key = odsa->priv_key = NULL; 919 DSA_free(odsa); 920 921 return dsasig; 922 } 923 924 int 925 openssl_read_pem_seckey(const char *f, __ops_key_t *key, const char *type, int verbose) 926 { 927 FILE *fp; 928 DSA *dsa; 929 RSA *rsa; 930 int ok; 931 932 if ((fp = fopen(f, "r")) == NULL) { 933 if (verbose) { 934 (void) fprintf(stderr, "can't open '%s'\n", f); 935 } 936 return 0; 937 } 938 ok = 1; 939 if (strcmp(type, "ssh-rsa") == 0) { 940 if ((rsa = PEM_read_RSAPrivateKey(fp, NULL, NULL, NULL)) == NULL) { 941 ok = 0; 942 } else { 943 key->key.seckey.key.rsa.d = rsa->d; 944 key->key.seckey.key.rsa.p = rsa->p; 945 key->key.seckey.key.rsa.q = rsa->q; 946 key->key.seckey.key.rsa.d = rsa->d; 947 } 948 } else if (strcmp(type, "ssh-dss") == 0) { 949 if ((dsa = PEM_read_DSAPrivateKey(fp, NULL, NULL, NULL)) == NULL) { 950 ok = 0; 951 } else { 952 key->key.seckey.key.dsa.x = dsa->priv_key; 953 } 954 } else { 955 ok = 0; 956 } 957 (void) fclose(fp); 958 return ok; 959 } 960