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