1 /* 2 * Copyright (c) 2005-2008 Nominet UK (www.nic.uk) 3 * All rights reserved. 4 * Contributors: Ben Laurie, Rachel Willmer. The Contributors have asserted 5 * their moral rights under the UK Copyright Design and Patents Act 1988 to 6 * be recorded as the authors of this copyright work. 7 * 8 * Licensed under the Apache License, Version 2.0 (the "License"); you may not 9 * use this file except in compliance with the License. 10 * 11 * You may obtain a copy of the License at 12 * http://www.apache.org/licenses/LICENSE-2.0 13 * 14 * Unless required by applicable law or agreed to in writing, software 15 * distributed under the License is distributed on an "AS IS" BASIS, 16 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 17 * 18 * See the License for the specific language governing permissions and 19 * limitations under the License. 20 */ 21 22 /** \file 23 */ 24 #include "config.h" 25 26 #ifdef HAVE_OPENSSL_MD5_H 27 #include <openssl/md5.h> 28 #endif 29 30 #ifdef HAVE_OPENSSL_SHA_H 31 #include <openssl/sha.h> 32 #endif 33 34 #ifdef HAVE_OPENSSL_DSA_H 35 #include <openssl/dsa.h> 36 #endif 37 38 #ifdef HAVE_OPENSSL_RSA_H 39 #include <openssl/rsa.h> 40 #endif 41 42 #ifdef HAVE_OPENSSL_ERR_H 43 #include <openssl/err.h> 44 #endif 45 46 47 #ifdef HAVE_ASSERT_H 48 #include <assert.h> 49 #endif 50 51 #include <stdlib.h> 52 53 /* Apple */ 54 #ifdef HAVE_COMMONCRYPTO_COMMONDIGEST_H 55 #undef MD5_DIGEST_LENGTH 56 #undef SHA_DIGEST_LENGTH 57 #define COMMON_DIGEST_FOR_OPENSSL 1 58 #include <CommonCrypto/CommonDigest.h> 59 #endif 60 61 #include "crypto.h" 62 #include "keyring.h" 63 64 #include "readerwriter.h" 65 #include "netpgpdefs.h" 66 #include "keyring_local.h" 67 68 69 static void 70 test_secret_key(const __ops_secret_key_t * skey) 71 { 72 RSA *test = RSA_new(); 73 74 test->n = BN_dup(skey->public_key.key.rsa.n); 75 test->e = BN_dup(skey->public_key.key.rsa.e); 76 77 test->d = BN_dup(skey->key.rsa.d); 78 test->p = BN_dup(skey->key.rsa.p); 79 test->q = BN_dup(skey->key.rsa.q); 80 81 assert(RSA_check_key(test) == 1); 82 RSA_free(test); 83 } 84 85 static void 86 md5_init(__ops_hash_t * hash) 87 { 88 assert(!hash->data); 89 hash->data = calloc(1, sizeof(MD5_CTX)); 90 MD5_Init(hash->data); 91 } 92 93 static void 94 md5_add(__ops_hash_t * hash, const unsigned char *data, unsigned length) 95 { 96 MD5_Update(hash->data, data, length); 97 } 98 99 static unsigned 100 md5_finish(__ops_hash_t * hash, unsigned char *out) 101 { 102 MD5_Final(out, hash->data); 103 free(hash->data); 104 hash->data = NULL; 105 return 16; 106 } 107 108 static __ops_hash_t md5 = {OPS_HASH_MD5, MD5_DIGEST_LENGTH, "MD5", md5_init, md5_add, 109 md5_finish, NULL}; 110 111 /** 112 \ingroup Core_Crypto 113 \brief Initialise to MD5 114 \param hash Hash to initialise 115 */ 116 void 117 __ops_hash_md5(__ops_hash_t * hash) 118 { 119 *hash = md5; 120 } 121 122 static void 123 sha1_init(__ops_hash_t * hash) 124 { 125 if (__ops_get_debug_level(__FILE__)) { 126 fprintf(stderr, "***\n***\nsha1_init\n***\n"); 127 } 128 assert(!hash->data); 129 hash->data = calloc(1, sizeof(SHA_CTX)); 130 SHA1_Init(hash->data); 131 } 132 133 static void 134 sha1_add(__ops_hash_t * hash, const unsigned char *data, 135 unsigned length) 136 { 137 if (__ops_get_debug_level(__FILE__)) { 138 unsigned int i = 0; 139 fprintf(stderr, "adding %d to hash:\n ", length); 140 for (i = 0; i < length; i++) { 141 fprintf(stderr, "0x%02x ", data[i]); 142 if (!((i + 1) % 16)) 143 fprintf(stderr, "\n"); 144 else if (!((i + 1) % 8)) 145 fprintf(stderr, " "); 146 } 147 fprintf(stderr, "\n"); 148 } 149 SHA1_Update(hash->data, data, length); 150 } 151 152 static unsigned 153 sha1_finish(__ops_hash_t * hash, unsigned char *out) 154 { 155 SHA1_Final(out, hash->data); 156 if (__ops_get_debug_level(__FILE__)) { 157 unsigned i = 0; 158 fprintf(stderr, "***\n***\nsha1_finish\n***\n"); 159 for (i = 0; i < SHA_DIGEST_LENGTH; i++) 160 fprintf(stderr, "0x%02x ", out[i]); 161 fprintf(stderr, "\n"); 162 } 163 free(hash->data); 164 hash->data = NULL; 165 return SHA_DIGEST_LENGTH; 166 } 167 168 static __ops_hash_t sha1 = {OPS_HASH_SHA1, SHA_DIGEST_LENGTH, "SHA1", sha1_init, 169 sha1_add, sha1_finish, NULL}; 170 171 /** 172 \ingroup Core_Crypto 173 \brief Initialise to SHA1 174 \param hash Hash to initialise 175 */ 176 void 177 __ops_hash_sha1(__ops_hash_t * hash) 178 { 179 *hash = sha1; 180 } 181 182 static void 183 sha256_init(__ops_hash_t * hash) 184 { 185 if (__ops_get_debug_level(__FILE__)) { 186 fprintf(stderr, "***\n***\nsha256_init\n***\n"); 187 } 188 assert(!hash->data); 189 hash->data = calloc(1, sizeof(SHA256_CTX)); 190 SHA256_Init(hash->data); 191 } 192 193 static void 194 sha256_add(__ops_hash_t * hash, const unsigned char *data, 195 unsigned length) 196 { 197 if (__ops_get_debug_level(__FILE__)) { 198 unsigned int i = 0; 199 fprintf(stderr, "adding %d to hash:\n ", length); 200 for (i = 0; i < length; i++) { 201 fprintf(stderr, "0x%02x ", data[i]); 202 if (!((i + 1) % 16)) 203 fprintf(stderr, "\n"); 204 else if (!((i + 1) % 8)) 205 fprintf(stderr, " "); 206 } 207 fprintf(stderr, "\n"); 208 } 209 SHA256_Update(hash->data, data, length); 210 } 211 212 static unsigned 213 sha256_finish(__ops_hash_t * hash, unsigned char *out) 214 { 215 SHA256_Final(out, hash->data); 216 if (__ops_get_debug_level(__FILE__)) { 217 unsigned i = 0; 218 fprintf(stderr, "***\n***\nsha1_finish\n***\n"); 219 for (i = 0; i < SHA256_DIGEST_LENGTH; i++) 220 fprintf(stderr, "0x%02x ", out[i]); 221 fprintf(stderr, "\n"); 222 } 223 free(hash->data); 224 hash->data = NULL; 225 return SHA256_DIGEST_LENGTH; 226 } 227 228 static __ops_hash_t sha256 = {OPS_HASH_SHA256, SHA256_DIGEST_LENGTH, "SHA256", sha256_init, 229 sha256_add, sha256_finish, NULL}; 230 231 void 232 __ops_hash_sha256(__ops_hash_t * hash) 233 { 234 *hash = sha256; 235 } 236 237 /* 238 * SHA384 239 */ 240 241 static void 242 sha384_init(__ops_hash_t * hash) 243 { 244 if (__ops_get_debug_level(__FILE__)) { 245 fprintf(stderr, "***\n***\nsha384_init\n***\n"); 246 } 247 assert(!hash->data); 248 hash->data = calloc(1, sizeof(SHA512_CTX)); 249 SHA384_Init(hash->data); 250 } 251 252 static void 253 sha384_add(__ops_hash_t * hash, const unsigned char *data, 254 unsigned length) 255 { 256 if (__ops_get_debug_level(__FILE__)) { 257 unsigned int i = 0; 258 fprintf(stderr, "adding %d to hash:\n ", length); 259 for (i = 0; i < length; i++) { 260 fprintf(stderr, "0x%02x ", data[i]); 261 if (!((i + 1) % 16)) 262 fprintf(stderr, "\n"); 263 else if (!((i + 1) % 8)) 264 fprintf(stderr, " "); 265 } 266 fprintf(stderr, "\n"); 267 } 268 SHA384_Update(hash->data, data, length); 269 } 270 271 static unsigned 272 sha384_finish(__ops_hash_t * hash, unsigned char *out) 273 { 274 SHA384_Final(out, hash->data); 275 if (__ops_get_debug_level(__FILE__)) { 276 unsigned i = 0; 277 fprintf(stderr, "***\n***\nsha1_finish\n***\n"); 278 for (i = 0; i < SHA384_DIGEST_LENGTH; i++) 279 fprintf(stderr, "0x%02x ", out[i]); 280 fprintf(stderr, "\n"); 281 } 282 free(hash->data); 283 hash->data = NULL; 284 return SHA384_DIGEST_LENGTH; 285 } 286 287 static __ops_hash_t sha384 = {OPS_HASH_SHA384, SHA384_DIGEST_LENGTH, "SHA384", sha384_init, 288 sha384_add, sha384_finish, NULL}; 289 290 void 291 __ops_hash_sha384(__ops_hash_t * hash) 292 { 293 *hash = sha384; 294 } 295 296 /* 297 * SHA512 298 */ 299 300 static void 301 sha512_init(__ops_hash_t * hash) 302 { 303 if (__ops_get_debug_level(__FILE__)) { 304 fprintf(stderr, "***\n***\nsha512_init\n***\n"); 305 } 306 assert(!hash->data); 307 hash->data = calloc(1, sizeof(SHA512_CTX)); 308 SHA512_Init(hash->data); 309 } 310 311 static void 312 sha512_add(__ops_hash_t * hash, const unsigned char *data, 313 unsigned length) 314 { 315 if (__ops_get_debug_level(__FILE__)) { 316 unsigned int i = 0; 317 fprintf(stderr, "adding %d to hash:\n ", length); 318 for (i = 0; i < length; i++) { 319 fprintf(stderr, "0x%02x ", data[i]); 320 if (!((i + 1) % 16)) 321 fprintf(stderr, "\n"); 322 else if (!((i + 1) % 8)) 323 fprintf(stderr, " "); 324 } 325 fprintf(stderr, "\n"); 326 } 327 SHA512_Update(hash->data, data, length); 328 } 329 330 static unsigned 331 sha512_finish(__ops_hash_t * hash, unsigned char *out) 332 { 333 SHA512_Final(out, hash->data); 334 if (__ops_get_debug_level(__FILE__)) { 335 unsigned i = 0; 336 fprintf(stderr, "***\n***\nsha1_finish\n***\n"); 337 for (i = 0; i < SHA512_DIGEST_LENGTH; i++) 338 fprintf(stderr, "0x%02x ", out[i]); 339 fprintf(stderr, "\n"); 340 } 341 free(hash->data); 342 hash->data = NULL; 343 return SHA512_DIGEST_LENGTH; 344 } 345 346 static __ops_hash_t sha512 = {OPS_HASH_SHA512, SHA512_DIGEST_LENGTH, "SHA512", sha512_init, 347 sha512_add, sha512_finish, NULL}; 348 349 void 350 __ops_hash_sha512(__ops_hash_t * hash) 351 { 352 *hash = sha512; 353 } 354 355 /* 356 * SHA224 357 */ 358 359 static void 360 sha224_init(__ops_hash_t * hash) 361 { 362 if (__ops_get_debug_level(__FILE__)) { 363 fprintf(stderr, "***\n***\nsha1_init\n***\n"); 364 } 365 assert(!hash->data); 366 hash->data = calloc(1, sizeof(SHA256_CTX)); 367 SHA224_Init(hash->data); 368 } 369 370 static void 371 sha224_add(__ops_hash_t * hash, const unsigned char *data, 372 unsigned length) 373 { 374 if (__ops_get_debug_level(__FILE__)) { 375 unsigned int i = 0; 376 fprintf(stderr, "adding %d to hash:\n ", length); 377 for (i = 0; i < length; i++) { 378 fprintf(stderr, "0x%02x ", data[i]); 379 if (!((i + 1) % 16)) 380 fprintf(stderr, "\n"); 381 else if (!((i + 1) % 8)) 382 fprintf(stderr, " "); 383 } 384 fprintf(stderr, "\n"); 385 } 386 SHA224_Update(hash->data, data, length); 387 } 388 389 static unsigned 390 sha224_finish(__ops_hash_t * hash, unsigned char *out) 391 { 392 SHA224_Final(out, hash->data); 393 if (__ops_get_debug_level(__FILE__)) { 394 unsigned i = 0; 395 fprintf(stderr, "***\n***\nsha1_finish\n***\n"); 396 for (i = 0; i < SHA224_DIGEST_LENGTH; i++) 397 fprintf(stderr, "0x%02x ", out[i]); 398 fprintf(stderr, "\n"); 399 } 400 free(hash->data); 401 hash->data = NULL; 402 return SHA224_DIGEST_LENGTH; 403 } 404 405 static __ops_hash_t sha224 = {OPS_HASH_SHA224, SHA224_DIGEST_LENGTH, "SHA224", sha224_init, 406 sha224_add, sha224_finish, NULL}; 407 408 void 409 __ops_hash_sha224(__ops_hash_t * hash) 410 { 411 *hash = sha224; 412 } 413 414 bool 415 __ops_dsa_verify(const unsigned char *hash, size_t hash_length, 416 const __ops_dsa_signature_t * sig, 417 const __ops_dsa_public_key_t * dsa) 418 { 419 DSA_SIG *osig; 420 DSA *odsa; 421 int ret; 422 unsigned int qlen; 423 424 osig = DSA_SIG_new(); 425 osig->r = sig->r; 426 osig->s = sig->s; 427 428 odsa = DSA_new(); 429 odsa->p = dsa->p; 430 odsa->q = dsa->q; 431 odsa->g = dsa->g; 432 odsa->pub_key = dsa->y; 433 434 if (__ops_get_debug_level(__FILE__)) { 435 unsigned i; 436 fprintf(stderr, "hash passed in:\n"); 437 for (i = 0; i < hash_length; i++) { 438 fprintf(stderr, "%02x ", hash[i]); 439 } 440 fprintf(stderr, "\n"); 441 } 442 /* printf("hash_length=%ld\n", hash_length); */ 443 /* printf("Q=%d\n", BN_num_bytes(odsa->q)); */ 444 qlen = BN_num_bytes(odsa->q); 445 if (qlen < hash_length) 446 hash_length = qlen; 447 /* ret=DSA_do_verify(hash,hash_length,osig,odsa); */ 448 ret = DSA_do_verify(hash, (int)hash_length, osig, odsa); 449 if (__ops_get_debug_level(__FILE__)) { 450 fprintf(stderr, "ret=%d\n", ret); 451 } 452 assert(ret >= 0); 453 454 odsa->p = odsa->q = odsa->g = odsa->pub_key = NULL; 455 DSA_free(odsa); 456 457 osig->r = osig->s = NULL; 458 DSA_SIG_free(osig); 459 460 return ret != 0; 461 } 462 463 /** 464 \ingroup Core_Crypto 465 \brief Recovers message digest from the signature 466 \param out Where to write decrypted data to 467 \param in Encrypted data 468 \param length Length of encrypted data 469 \param rsa RSA public key 470 \return size of recovered message digest 471 */ 472 int 473 __ops_rsa_public_decrypt(unsigned char *out, const unsigned char *in, 474 size_t length, const __ops_rsa_public_key_t * rsa) 475 { 476 RSA *orsa; 477 int n; 478 479 orsa = RSA_new(); 480 orsa->n = rsa->n; 481 orsa->e = rsa->e; 482 483 n = RSA_public_decrypt((int)length, in, out, orsa, RSA_NO_PADDING); 484 485 orsa->n = orsa->e = NULL; 486 RSA_free(orsa); 487 488 return n; 489 } 490 491 /** 492 \ingroup Core_Crypto 493 \brief Signs data with RSA 494 \param out Where to write signature 495 \param in Data to sign 496 \param length Length of data 497 \param srsa RSA secret key 498 \param rsa RSA public key 499 \return number of bytes decrypted 500 */ 501 int 502 __ops_rsa_private_encrypt(unsigned char *out, const unsigned char *in, 503 size_t length, const __ops_rsa_secret_key_t *srsa, 504 const __ops_rsa_public_key_t *rsa) 505 { 506 RSA *orsa; 507 int n; 508 509 orsa = RSA_new(); 510 orsa->n = rsa->n; /* XXX: do we need n? */ 511 orsa->d = srsa->d; 512 orsa->p = srsa->q; 513 orsa->q = srsa->p; 514 515 /* debug */ 516 orsa->e = rsa->e; 517 /* If this isn't set, it's very likely that the programmer hasn't */ 518 /* decrypted the secret key. RSA_check_key segfaults in that case. */ 519 /* Use __ops_decrypt_secret_key_from_data() to do that. */ 520 assert(orsa->d); 521 assert(RSA_check_key(orsa) == 1); 522 /* end debug */ 523 524 n = RSA_private_encrypt((int)length, in, out, orsa, RSA_NO_PADDING); 525 526 orsa->n = orsa->d = orsa->p = orsa->q = NULL; 527 RSA_free(orsa); 528 529 return n; 530 } 531 532 /** 533 \ingroup Core_Crypto 534 \brief Decrypts RSA-encrypted data 535 \param out Where to write the plaintext 536 \param in Encrypted data 537 \param length Length of encrypted data 538 \param srsa RSA secret key 539 \param rsa RSA public key 540 \return size of recovered plaintext 541 */ 542 int 543 __ops_rsa_private_decrypt(unsigned char *out, const unsigned char *in, 544 size_t length, const __ops_rsa_secret_key_t * srsa, 545 const __ops_rsa_public_key_t * rsa) 546 { 547 RSA *orsa; 548 int n; 549 char errbuf[1024]; 550 551 orsa = RSA_new(); 552 orsa->n = rsa->n; /* XXX: do we need n? */ 553 orsa->d = srsa->d; 554 orsa->p = srsa->q; 555 orsa->q = srsa->p; 556 557 /* debug */ 558 orsa->e = rsa->e; 559 assert(RSA_check_key(orsa) == 1); 560 /* end debug */ 561 562 n = RSA_private_decrypt((int)length, in, out, orsa, RSA_NO_PADDING); 563 564 if (__ops_get_debug_level(__FILE__)) { 565 printf("__ops_rsa_private_decrypt: n=%d\n",n); 566 } 567 568 errbuf[0] = '\0'; 569 if (n == -1) { 570 unsigned long err = ERR_get_error(); 571 ERR_error_string(err, &errbuf[0]); 572 fprintf(stderr, "openssl error : %s\n", errbuf); 573 } 574 orsa->n = orsa->d = orsa->p = orsa->q = NULL; 575 RSA_free(orsa); 576 577 return n; 578 } 579 580 /** 581 \ingroup Core_Crypto 582 \brief RSA-encrypts data 583 \param out Where to write the encrypted data 584 \param in Plaintext 585 \param length Size of plaintext 586 \param rsa RSA Public Key 587 */ 588 int 589 __ops_rsa_public_encrypt(unsigned char *out, const unsigned char *in, 590 size_t length, const __ops_rsa_public_key_t * rsa) 591 { 592 RSA *orsa; 593 int n; 594 595 /* printf("__ops_rsa_public_encrypt: length=%ld\n", length); */ 596 597 orsa = RSA_new(); 598 orsa->n = rsa->n; 599 orsa->e = rsa->e; 600 601 /* printf("len: %ld\n", length); */ 602 /* __ops_print_bn("n: ", orsa->n); */ 603 /* __ops_print_bn("e: ", orsa->e); */ 604 n = RSA_public_encrypt((int)length, in, out, orsa, RSA_NO_PADDING); 605 606 if (n == -1) { 607 BIO *fd_out; 608 fd_out = BIO_new_fd(fileno(stderr), BIO_NOCLOSE); 609 ERR_print_errors(fd_out); 610 } 611 orsa->n = orsa->e = NULL; 612 RSA_free(orsa); 613 614 return n; 615 } 616 617 /** 618 \ingroup Core_Crypto 619 \brief initialises openssl 620 \note Would usually call __ops_init() instead 621 \sa __ops_init() 622 */ 623 void 624 __ops_crypto_init() 625 { 626 #ifdef DMALLOC 627 CRYPTO_malloc_debug_init(); 628 CRYPTO_dbg_set_options(V_CRYPTO_MDEBUG_ALL); 629 CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_ON); 630 #endif 631 } 632 633 /** 634 \ingroup Core_Crypto 635 \brief Finalise openssl 636 \note Would usually call __ops_finish() instead 637 \sa __ops_finish() 638 */ 639 void 640 __ops_crypto_finish() 641 { 642 CRYPTO_cleanup_all_ex_data(); 643 ERR_remove_state((unsigned long)0); 644 #ifdef DMALLOC 645 CRYPTO_mem_leaks_fp(stderr); 646 #endif 647 } 648 649 /** 650 \ingroup Core_Hashes 651 \brief Get Hash name 652 \param hash Hash struct 653 \return Hash name 654 */ 655 const char * 656 __ops_text_from_hash(__ops_hash_t * hash) 657 { 658 return hash->name; 659 } 660 661 /** 662 \ingroup HighLevel_KeyGenerate 663 \brief Generates an RSA keypair 664 \param numbits Modulus size 665 \param e Public Exponent 666 \param keydata Pointer to keydata struct to hold new key 667 \return true if key generated successfully; otherwise false 668 \note It is the caller's responsibility to call __ops_keydata_free(keydata) 669 */ 670 bool 671 __ops_rsa_generate_keypair(const int numbits, const unsigned long e, __ops_keydata_t * keydata) 672 { 673 __ops_secret_key_t *skey = NULL; 674 RSA *rsa = NULL; 675 BN_CTX *ctx = BN_CTX_new(); 676 __ops_create_info_t *cinfo; 677 __ops_memory_t *mem; 678 679 __ops_keydata_init(keydata, OPS_PTAG_CT_SECRET_KEY); 680 skey = __ops_get_writable_secret_key_from_data(keydata); 681 682 /* generate the key pair */ 683 684 rsa = RSA_generate_key(numbits, e, NULL, NULL); 685 686 /* populate __ops key from ssl key */ 687 688 skey->public_key.version = 4; 689 skey->public_key.creation_time = time(NULL); 690 skey->public_key.days_valid = 0; 691 skey->public_key.algorithm = OPS_PKA_RSA; 692 693 skey->public_key.key.rsa.n = BN_dup(rsa->n); 694 skey->public_key.key.rsa.e = BN_dup(rsa->e); 695 696 skey->s2k_usage = OPS_S2KU_ENCRYPTED_AND_HASHED; 697 skey->s2k_specifier = OPS_S2KS_SALTED; 698 /* skey->s2k_specifier=OPS_S2KS_SIMPLE; */ 699 skey->algorithm = OPS_SA_CAST5; /* \todo make param */ 700 skey->hash_algorithm = OPS_HASH_SHA1; /* \todo make param */ 701 skey->octet_count = 0; 702 skey->checksum = 0; 703 704 skey->key.rsa.d = BN_dup(rsa->d); 705 skey->key.rsa.p = BN_dup(rsa->p); 706 skey->key.rsa.q = BN_dup(rsa->q); 707 skey->key.rsa.u = BN_mod_inverse(NULL, rsa->p, rsa->q, ctx); 708 assert(skey->key.rsa.u); 709 BN_CTX_free(ctx); 710 711 RSA_free(rsa); 712 713 __ops_keyid(keydata->key_id, OPS_KEY_ID_SIZE, OPS_KEY_ID_SIZE, 714 &keydata->key.skey.public_key); 715 __ops_fingerprint(&keydata->fingerprint, &keydata->key.skey.public_key); 716 717 /* Generate checksum */ 718 719 cinfo = NULL; 720 mem = NULL; 721 722 __ops_setup_memory_write(&cinfo, &mem, 128); 723 724 __ops_push_skey_checksum_writer(cinfo, skey); 725 726 switch (skey->public_key.algorithm) { 727 /* case OPS_PKA_DSA: */ 728 /* return __ops_write_mpi(key->key.dsa.x,info); */ 729 730 case OPS_PKA_RSA: 731 case OPS_PKA_RSA_ENCRYPT_ONLY: 732 case OPS_PKA_RSA_SIGN_ONLY: 733 if (!__ops_write_mpi(skey->key.rsa.d, cinfo) 734 || !__ops_write_mpi(skey->key.rsa.p, cinfo) 735 || !__ops_write_mpi(skey->key.rsa.q, cinfo) 736 || !__ops_write_mpi(skey->key.rsa.u, cinfo)) 737 return false; 738 break; 739 740 /* case OPS_PKA_ELGAMAL: */ 741 /* return __ops_write_mpi(key->key.elgamal.x,info); */ 742 743 default: 744 assert( /* CONSTCOND */ 0); 745 break; 746 } 747 748 /* close rather than pop, since its the only one on the stack */ 749 __ops_writer_close(cinfo); 750 __ops_teardown_memory_write(cinfo, mem); 751 752 /* should now have checksum in skey struct */ 753 754 /* test */ 755 if (__ops_get_debug_level(__FILE__)) 756 test_secret_key(skey); 757 758 return true; 759 } 760 761 /** 762 \ingroup HighLevel_KeyGenerate 763 \brief Creates a self-signed RSA keypair 764 \param numbits Modulus size 765 \param e Public Exponent 766 \param userid User ID 767 \return The new keypair or NULL 768 769 \note It is the caller's responsibility to call __ops_keydata_free(keydata) 770 \sa __ops_rsa_generate_keypair() 771 \sa __ops_keydata_free() 772 */ 773 __ops_keydata_t * 774 __ops_rsa_create_selfsigned_keypair(const int numbits, const unsigned long e, __ops_user_id_t * userid) 775 { 776 __ops_keydata_t *keydata = NULL; 777 778 keydata = __ops_keydata_new(); 779 780 if (__ops_rsa_generate_keypair(numbits, e, keydata) != true 781 || __ops_add_selfsigned_userid_to_keydata(keydata, userid) != true) { 782 __ops_keydata_free(keydata); 783 return NULL; 784 } 785 return keydata; 786 } 787 788 /* 789 int __ops_dsa_size(const __ops_dsa_public_key_t *dsa) 790 { 791 int size; 792 DSA *odsa; 793 odsa=DSA_new(); 794 odsa->p=dsa->p; 795 odsa->q=dsa->q; 796 odsa->g=dsa->g; 797 odsa->pub_key=dsa->y; 798 799 DSAparams_print_fp(stderr, odsa); 800 size=DSA_size(odsa); 801 802 odsa->p=odsa->q=odsa->g=odsa->pub_key=odsa->priv_key=NULL; 803 DSA_free(odsa); 804 805 return size; 806 } 807 */ 808 809 DSA_SIG * 810 __ops_dsa_sign(unsigned char *hashbuf, unsigned hashsize, const __ops_dsa_secret_key_t * sdsa, const __ops_dsa_public_key_t * dsa) 811 { 812 DSA *odsa; 813 DSA_SIG *dsasig; 814 815 odsa = DSA_new(); 816 odsa->p = dsa->p; 817 odsa->q = dsa->q; 818 odsa->g = dsa->g; 819 odsa->pub_key = dsa->y; 820 odsa->priv_key = sdsa->x; 821 822 dsasig = DSA_do_sign(hashbuf, (int)hashsize, odsa); 823 824 odsa->p = odsa->q = odsa->g = odsa->pub_key = odsa->priv_key = NULL; 825 DSA_free(odsa); 826 827 return dsasig; 828 } 829