crypto_rsa.c (20104B)
1 /* Copyright (c) 2001, Matej Pfajfar. 2 * Copyright (c) 2001-2004, Roger Dingledine. 3 * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. 4 * Copyright (c) 2007-2021, The Tor Project, Inc. */ 5 /* See LICENSE for licensing information */ 6 7 /** 8 * \file crypto_rsa.c 9 * \brief Block of functions related with RSA utilities and operations. 10 **/ 11 12 #include "lib/crypt_ops/crypto_cipher.h" 13 #include "lib/crypt_ops/crypto_curve25519.h" 14 #include "lib/crypt_ops/crypto_digest.h" 15 #include "lib/crypt_ops/crypto_format.h" 16 #include "lib/crypt_ops/compat_openssl.h" 17 #include "lib/crypt_ops/crypto_rand.h" 18 #include "lib/crypt_ops/crypto_rsa.h" 19 #include "lib/crypt_ops/crypto_util.h" 20 #include "lib/ctime/di_ops.h" 21 #include "lib/log/util_bug.h" 22 #include "lib/fs/files.h" 23 24 #include "lib/log/escape.h" 25 #include "lib/log/log.h" 26 #include "lib/encoding/binascii.h" 27 #include "lib/encoding/pem.h" 28 29 #include <string.h> 30 #ifdef HAVE_SYS_STAT_H 31 #include <sys/stat.h> 32 #endif 33 34 #ifdef ENABLE_OPENSSL 35 #include <openssl/rsa.h> 36 #endif 37 38 /** Return the number of bytes added by padding method <b>padding</b>. 39 */ 40 int 41 crypto_get_rsa_padding_overhead(int padding) 42 { 43 switch (padding) 44 { 45 case PK_PKCS1_OAEP_PADDING: return PKCS1_OAEP_PADDING_OVERHEAD; 46 default: tor_assert(0); return -1; // LCOV_EXCL_LINE 47 } 48 } 49 50 #ifdef ENABLE_OPENSSL 51 /** Given a padding method <b>padding</b>, return the correct OpenSSL constant. 52 */ 53 int 54 crypto_get_rsa_padding(int padding) 55 { 56 switch (padding) 57 { 58 case PK_PKCS1_OAEP_PADDING: return RSA_PKCS1_OAEP_PADDING; 59 default: tor_assert(0); return -1; // LCOV_EXCL_LINE 60 } 61 } 62 #endif /* defined(ENABLE_OPENSSL) */ 63 64 /** Compare the public-key components of a and b. Return non-zero iff 65 * a==b. A NULL key is considered to be distinct from all non-NULL 66 * keys, and equal to itself. 67 * 68 * Note that this may leak information about the keys through timing. 69 */ 70 int 71 crypto_pk_eq_keys(const crypto_pk_t *a, const crypto_pk_t *b) 72 { 73 return (crypto_pk_cmp_keys(a, b) == 0); 74 } 75 76 /** Perform a hybrid (public/secret) encryption on <b>fromlen</b> 77 * bytes of data from <b>from</b>, with padding type 'padding', 78 * storing the results on <b>to</b>. 79 * 80 * Returns the number of bytes written on success, -1 on failure. 81 * 82 * The encrypted data consists of: 83 * - The source data, padded and encrypted with the public key, if the 84 * padded source data is no longer than the public key, and <b>force</b> 85 * is false, OR 86 * - The beginning of the source data prefixed with a 16-byte symmetric key, 87 * padded and encrypted with the public key; followed by the rest of 88 * the source data encrypted in AES-CTR mode with the symmetric key. 89 * 90 * NOTE that this format does not authenticate the symmetrically encrypted 91 * part of the data, and SHOULD NOT BE USED for new protocols. 92 */ 93 int 94 crypto_pk_obsolete_public_hybrid_encrypt(crypto_pk_t *env, 95 char *to, size_t tolen, 96 const char *from, 97 size_t fromlen, 98 int padding, int force) 99 { 100 int overhead, outlen, r; 101 size_t pkeylen, symlen; 102 crypto_cipher_t *cipher = NULL; 103 char *buf = NULL; 104 105 tor_assert(env); 106 tor_assert(from); 107 tor_assert(to); 108 tor_assert(fromlen < SIZE_T_CEILING); 109 110 overhead = crypto_get_rsa_padding_overhead(padding); 111 pkeylen = crypto_pk_keysize(env); 112 113 if (!force && fromlen+overhead <= pkeylen) { 114 /* It all fits in a single encrypt. */ 115 return crypto_pk_public_encrypt(env,to, 116 tolen, 117 from,fromlen,padding); 118 } 119 tor_assert(tolen >= fromlen + overhead + CIPHER_KEY_LEN); 120 tor_assert(tolen >= pkeylen); 121 122 char key[CIPHER_KEY_LEN]; 123 crypto_rand(key, sizeof(key)); /* generate a new key. */ 124 cipher = crypto_cipher_new(key); 125 126 buf = tor_malloc(pkeylen+1); 127 memcpy(buf, key, CIPHER_KEY_LEN); 128 memcpy(buf+CIPHER_KEY_LEN, from, pkeylen-overhead-CIPHER_KEY_LEN); 129 130 /* Length of symmetrically encrypted data. */ 131 symlen = fromlen-(pkeylen-overhead-CIPHER_KEY_LEN); 132 133 outlen = crypto_pk_public_encrypt(env,to,tolen,buf,pkeylen-overhead,padding); 134 if (outlen!=(int)pkeylen) { 135 goto err; 136 } 137 r = crypto_cipher_encrypt(cipher, to+outlen, 138 from+pkeylen-overhead-CIPHER_KEY_LEN, symlen); 139 140 if (r<0) goto err; 141 memwipe(buf, 0, pkeylen); 142 memwipe(key, 0, sizeof(key)); 143 tor_free(buf); 144 crypto_cipher_free(cipher); 145 tor_assert(outlen+symlen < INT_MAX); 146 return (int)(outlen + symlen); 147 err: 148 149 memwipe(buf, 0, pkeylen); 150 memwipe(key, 0, sizeof(key)); 151 tor_free(buf); 152 crypto_cipher_free(cipher); 153 return -1; 154 } 155 156 /** Invert crypto_pk_obsolete_public_hybrid_encrypt. Returns the number of 157 * bytes written on success, -1 on failure. 158 * 159 * NOTE that this format does not authenticate the symmetrically encrypted 160 * part of the data, and SHOULD NOT BE USED for new protocols. 161 */ 162 int 163 crypto_pk_obsolete_private_hybrid_decrypt(crypto_pk_t *env, 164 char *to, 165 size_t tolen, 166 const char *from, 167 size_t fromlen, 168 int padding, int warnOnFailure) 169 { 170 int outlen, r; 171 size_t pkeylen; 172 crypto_cipher_t *cipher = NULL; 173 char *buf = NULL; 174 175 tor_assert(fromlen < SIZE_T_CEILING); 176 pkeylen = crypto_pk_keysize(env); 177 178 if (fromlen <= pkeylen) { 179 return crypto_pk_private_decrypt(env,to,tolen,from,fromlen,padding, 180 warnOnFailure); 181 } 182 183 buf = tor_malloc(pkeylen); 184 outlen = crypto_pk_private_decrypt(env,buf,pkeylen,from,pkeylen,padding, 185 warnOnFailure); 186 if (outlen<0) { 187 log_fn(warnOnFailure?LOG_WARN:LOG_DEBUG, LD_CRYPTO, 188 "Error decrypting public-key data"); 189 goto err; 190 } 191 if (outlen < CIPHER_KEY_LEN) { 192 log_fn(warnOnFailure?LOG_WARN:LOG_INFO, LD_CRYPTO, 193 "No room for a symmetric key"); 194 goto err; 195 } 196 cipher = crypto_cipher_new(buf); 197 if (!cipher) { 198 goto err; 199 } 200 memcpy(to,buf+CIPHER_KEY_LEN,outlen-CIPHER_KEY_LEN); 201 outlen -= CIPHER_KEY_LEN; 202 tor_assert(tolen - outlen >= fromlen - pkeylen); 203 r = crypto_cipher_decrypt(cipher, to+outlen, from+pkeylen, fromlen-pkeylen); 204 if (r<0) 205 goto err; 206 memwipe(buf,0,pkeylen); 207 tor_free(buf); 208 crypto_cipher_free(cipher); 209 tor_assert(outlen + fromlen < INT_MAX); 210 return (int)(outlen + (fromlen-pkeylen)); 211 err: 212 memwipe(buf,0,pkeylen); 213 tor_free(buf); 214 crypto_cipher_free(cipher); 215 return -1; 216 } 217 218 /** Given a private or public key <b>pk</b>, put a fingerprint of the 219 * public key into <b>fp_out</b> (must have at least FINGERPRINT_LEN+1 bytes of 220 * space). Return 0 on success, -1 on failure. 221 * 222 * Fingerprints are computed as the SHA1 digest of the ASN.1 encoding 223 * of the public key, converted to hexadecimal, in upper case, with a 224 * space after every four digits. 225 * 226 * If <b>add_space</b> is false, omit the spaces. 227 */ 228 int 229 crypto_pk_get_fingerprint(crypto_pk_t *pk, char *fp_out, int add_space) 230 { 231 char digest[DIGEST_LEN]; 232 char hexdigest[HEX_DIGEST_LEN+1]; 233 if (crypto_pk_get_digest(pk, digest)) { 234 return -1; 235 } 236 base16_encode(hexdigest,sizeof(hexdigest),digest,DIGEST_LEN); 237 if (add_space) { 238 crypto_add_spaces_to_fp(fp_out, FINGERPRINT_LEN+1, hexdigest); 239 } else { 240 strncpy(fp_out, hexdigest, HEX_DIGEST_LEN+1); 241 } 242 return 0; 243 } 244 245 /** Given a private or public key <b>pk</b>, put a hashed fingerprint of 246 * the public key into <b>fp_out</b> (must have at least FINGERPRINT_LEN+1 247 * bytes of space). Return 0 on success, -1 on failure. 248 * 249 * Hashed fingerprints are computed as the SHA1 digest of the SHA1 digest 250 * of the ASN.1 encoding of the public key, converted to hexadecimal, in 251 * upper case. 252 */ 253 int 254 crypto_pk_get_hashed_fingerprint(crypto_pk_t *pk, char *fp_out) 255 { 256 char digest[DIGEST_LEN], hashed_digest[DIGEST_LEN]; 257 if (crypto_pk_get_digest(pk, digest)) { 258 return -1; 259 } 260 if (crypto_digest(hashed_digest, digest, DIGEST_LEN) < 0) { 261 return -1; 262 } 263 base16_encode(fp_out, FINGERPRINT_LEN + 1, hashed_digest, DIGEST_LEN); 264 return 0; 265 } 266 267 /** Copy <b>in</b> to the <b>outlen</b>-byte buffer <b>out</b>, adding spaces 268 * every four characters. */ 269 void 270 crypto_add_spaces_to_fp(char *out, size_t outlen, const char *in) 271 { 272 int n = 0; 273 char *end = out+outlen; 274 tor_assert(outlen < SIZE_T_CEILING); 275 276 while (*in && out<end) { 277 *out++ = *in++; 278 if (++n == 4 && *in && out<end) { 279 n = 0; 280 *out++ = ' '; 281 } 282 } 283 tor_assert(out<end); 284 *out = '\0'; 285 } 286 287 /** Check a siglen-byte long signature at <b>sig</b> against 288 * <b>datalen</b> bytes of data at <b>data</b>, using the public key 289 * in <b>env</b>. Return 0 if <b>sig</b> is a correct signature for 290 * SHA1(data). Else return -1. 291 */ 292 MOCK_IMPL(int, 293 crypto_pk_public_checksig_digest,(crypto_pk_t *env, const char *data, 294 size_t datalen, const char *sig, 295 size_t siglen)) 296 { 297 char digest[DIGEST_LEN]; 298 char *buf; 299 size_t buflen; 300 int r; 301 302 tor_assert(env); 303 tor_assert(data); 304 tor_assert(sig); 305 tor_assert(datalen < SIZE_T_CEILING); 306 tor_assert(siglen < SIZE_T_CEILING); 307 308 if (crypto_digest(digest,data,datalen)<0) { 309 log_warn(LD_BUG, "couldn't compute digest"); 310 return -1; 311 } 312 buflen = crypto_pk_keysize(env); 313 buf = tor_malloc(buflen); 314 r = crypto_pk_public_checksig(env,buf,buflen,sig,siglen); 315 if (r != DIGEST_LEN) { 316 log_warn(LD_CRYPTO, "Invalid signature"); 317 tor_free(buf); 318 return -1; 319 } 320 if (tor_memneq(buf, digest, DIGEST_LEN)) { 321 log_warn(LD_CRYPTO, "Signature mismatched with digest."); 322 tor_free(buf); 323 return -1; 324 } 325 tor_free(buf); 326 327 return 0; 328 } 329 330 /** Compute a SHA1 digest of <b>fromlen</b> bytes of data stored at 331 * <b>from</b>; sign the data with the private key in <b>env</b>, and 332 * store it in <b>to</b>. Return the number of bytes written on 333 * success, and -1 on failure. 334 * 335 * <b>tolen</b> is the number of writable bytes in <b>to</b>, and must be 336 * at least the length of the modulus of <b>env</b>. 337 */ 338 int 339 crypto_pk_private_sign_digest(crypto_pk_t *env, char *to, size_t tolen, 340 const char *from, size_t fromlen) 341 { 342 int r; 343 char digest[DIGEST_LEN]; 344 if (crypto_digest(digest,from,fromlen)<0) 345 return -1; 346 r = crypto_pk_private_sign(env,to,tolen,digest,DIGEST_LEN); 347 memwipe(digest, 0, sizeof(digest)); 348 return r; 349 } 350 351 /** Given a private or public key <b>pk</b>, put a SHA1 hash of the 352 * public key into <b>digest_out</b> (must have DIGEST_LEN bytes of space). 353 * Return 0 on success, -1 on failure. 354 */ 355 int 356 crypto_pk_get_digest(const crypto_pk_t *pk, char *digest_out) 357 { 358 char *buf; 359 size_t buflen; 360 int len; 361 int rv = -1; 362 363 buflen = crypto_pk_keysize(pk)*2; 364 buf = tor_malloc(buflen); 365 len = crypto_pk_asn1_encode(pk, buf, buflen); 366 if (len < 0) 367 goto done; 368 369 if (crypto_digest(digest_out, buf, len) < 0) 370 goto done; 371 372 rv = 0; 373 done: 374 tor_free(buf); 375 return rv; 376 } 377 378 /** Compute all digests of the DER encoding of <b>pk</b>, and store them 379 * in <b>digests_out</b>. Return 0 on success, -1 on failure. */ 380 int 381 crypto_pk_get_common_digests(crypto_pk_t *pk, common_digests_t *digests_out) 382 { 383 char *buf; 384 size_t buflen; 385 int len; 386 int rv = -1; 387 388 buflen = crypto_pk_keysize(pk)*2; 389 buf = tor_malloc(buflen); 390 len = crypto_pk_asn1_encode(pk, buf, buflen); 391 if (len < 0) 392 goto done; 393 394 if (crypto_common_digests(digests_out, (char*)buf, len) < 0) 395 goto done; 396 397 rv = 0; 398 done: 399 tor_free(buf); 400 return rv; 401 } 402 403 static const char RSA_PUBLIC_TAG[] = "RSA PUBLIC KEY"; 404 static const char RSA_PRIVATE_TAG[] = "RSA PRIVATE KEY"; 405 406 /* These are overestimates for how many extra bytes we might need to encode 407 * a key in DER */ 408 #define PRIVATE_ASN_MAX_OVERHEAD_FACTOR 16 409 #define PUBLIC_ASN_MAX_OVERHEAD_FACTOR 3 410 411 /** Helper: PEM-encode <b>env</b> and write it to a newly allocated string. 412 * If <b>private_key</b>, write the private part of <b>env</b>; otherwise 413 * write only the public portion. On success, set *<b>dest</b> to the new 414 * string, *<b>len</b> to the string's length, and return 0. On failure, 415 * return -1. 416 */ 417 static int 418 crypto_pk_write_to_string_generic(crypto_pk_t *env, 419 char **dest, size_t *len, 420 bool private_key) 421 { 422 const int factor = 423 private_key ? PRIVATE_ASN_MAX_OVERHEAD_FACTOR 424 : PUBLIC_ASN_MAX_OVERHEAD_FACTOR; 425 size_t buflen = crypto_pk_keysize(env) * factor; 426 const char *tag = 427 private_key ? RSA_PRIVATE_TAG : RSA_PUBLIC_TAG; 428 char *buf = tor_malloc(buflen); 429 char *result = NULL; 430 size_t resultlen = 0; 431 int rv = -1; 432 433 int n = private_key 434 ? crypto_pk_asn1_encode_private(env, buf, buflen) 435 : crypto_pk_asn1_encode(env, buf, buflen); 436 if (n < 0) 437 goto done; 438 439 resultlen = pem_encoded_size(n, tag); 440 result = tor_malloc(resultlen); 441 if (pem_encode(result, resultlen, 442 (const unsigned char *)buf, n, tag) < 0) { 443 goto done; 444 } 445 446 *dest = result; 447 *len = resultlen; 448 rv = 0; 449 450 done: 451 if (rv < 0 && result) { 452 memwipe(result, 0, resultlen); 453 tor_free(result); 454 } 455 memwipe(buf, 0, buflen); 456 tor_free(buf); 457 return rv; 458 } 459 460 /** PEM-encode the public key portion of <b>env</b> and write it to a 461 * newly allocated string. On success, set *<b>dest</b> to the new 462 * string, *<b>len</b> to the string's length, and return 0. On 463 * failure, return -1. 464 */ 465 int 466 crypto_pk_write_public_key_to_string(crypto_pk_t *env, 467 char **dest, size_t *len) 468 { 469 return crypto_pk_write_to_string_generic(env, dest, len, false); 470 } 471 472 /** PEM-encode the private key portion of <b>env</b> and write it to a 473 * newly allocated string. On success, set *<b>dest</b> to the new 474 * string, *<b>len</b> to the string's length, and return 0. On 475 * failure, return -1. 476 */ 477 int 478 crypto_pk_write_private_key_to_string(crypto_pk_t *env, 479 char **dest, size_t *len) 480 { 481 return crypto_pk_write_to_string_generic(env, dest, len, true); 482 } 483 484 /** 485 * Helper. Read a PEM-encoded RSA from the first <b>len</b> characters of 486 * <b>src</b>, and store the result in <b>env</b>. If <b>private_key</b>, 487 * expect a private key; otherwise expect a public key. Return 0 on success, 488 * -1 on failure. If len is -1, the string is nul-terminated. 489 */ 490 static int 491 crypto_pk_read_from_string_generic(crypto_pk_t *env, const char *src, 492 size_t len, int severity, 493 bool private_key, int max_bits) 494 { 495 if (len == (size_t)-1) // "-1" indicates "use the length of the string." 496 len = strlen(src); 497 498 const char *ktype = private_key ? "private key" : "public key"; 499 const char *tag = 500 private_key ? RSA_PRIVATE_TAG : RSA_PUBLIC_TAG; 501 size_t buflen = len; 502 uint8_t *buf = tor_malloc(buflen); 503 int rv = -1; 504 505 int n = pem_decode(buf, buflen, src, len, tag); 506 if (n < 0) { 507 log_fn(severity, LD_CRYPTO, 508 "Error decoding PEM wrapper while reading %s", ktype); 509 goto done; 510 } 511 512 crypto_pk_t *pk = private_key 513 ? crypto_pk_asn1_decode_private((const char*)buf, n, max_bits) 514 : crypto_pk_asn1_decode((const char*)buf, n); 515 if (! pk) { 516 log_fn(severity, LD_CRYPTO, 517 "Error decoding ASN.1 while reading %s", ktype); 518 goto done; 519 } 520 521 if (private_key) 522 crypto_pk_assign_private(env, pk); 523 else 524 crypto_pk_assign_public(env, pk); 525 crypto_pk_free(pk); 526 rv = 0; 527 528 done: 529 memwipe(buf, 0, buflen); 530 tor_free(buf); 531 return rv; 532 } 533 534 /** Read a PEM-encoded public key from the first <b>len</b> characters of 535 * <b>src</b>, and store the result in <b>env</b>. Return 0 on success, -1 on 536 * failure. If len is -1, the string is nul-terminated. 537 */ 538 int 539 crypto_pk_read_public_key_from_string(crypto_pk_t *env, 540 const char *src, size_t len) 541 { 542 return crypto_pk_read_from_string_generic(env, src, len, LOG_INFO, false, 543 -1); 544 } 545 546 /** Read a PEM-encoded private key from the <b>len</b>-byte string <b>src</b> 547 * into <b>env</b>. Return 0 on success, -1 on failure. If len is -1, 548 * the string is nul-terminated. 549 */ 550 int 551 crypto_pk_read_private_key_from_string(crypto_pk_t *env, 552 const char *src, ssize_t len) 553 { 554 return crypto_pk_read_from_string_generic(env, src, len, LOG_INFO, true, 555 -1); 556 } 557 558 /** 559 * As crypto_pk_read_private_key_from_string(), but reject any key 560 * with a modulus longer than 1024 bits before doing any expensive 561 * validation on it. 562 */ 563 int 564 crypto_pk_read_private_key1024_from_string(crypto_pk_t *env, 565 const char *src, ssize_t len) 566 { 567 return crypto_pk_read_from_string_generic(env, src, len, LOG_INFO, true, 568 1024); 569 } 570 571 /** If a file is longer than this, we won't try to decode its private key */ 572 #define MAX_PRIVKEY_FILE_LEN (16*1024*1024) 573 574 /** Read a PEM-encoded private key from the file named by 575 * <b>keyfile</b> into <b>env</b>. Return 0 on success, -1 on failure. 576 */ 577 int 578 crypto_pk_read_private_key_from_filename(crypto_pk_t *env, 579 const char *keyfile) 580 { 581 struct stat st; 582 char *buf = read_file_to_str(keyfile, 0, &st); 583 if (!buf) { 584 log_warn(LD_CRYPTO, "Unable to read file for private key in %s", 585 escaped(keyfile)); 586 return -1; 587 } 588 if (st.st_size > MAX_PRIVKEY_FILE_LEN) { 589 log_warn(LD_CRYPTO, "Private key file %s was far too large.", 590 escaped(keyfile)); 591 tor_free(buf); 592 return -1; 593 } 594 595 int rv = crypto_pk_read_from_string_generic(env, buf, (ssize_t)st.st_size, 596 LOG_WARN, true, -1); 597 if (rv < 0) { 598 log_warn(LD_CRYPTO, "Unable to decode private key from file %s", 599 escaped(keyfile)); 600 } 601 memwipe(buf, 0, (size_t)st.st_size); 602 tor_free(buf); 603 return rv; 604 } 605 606 /** Write the private key from <b>env</b> into the file named by <b>fname</b>, 607 * PEM-encoded. Return 0 on success, -1 on failure. 608 */ 609 int 610 crypto_pk_write_private_key_to_filename(crypto_pk_t *env, 611 const char *fname) 612 { 613 char *s = NULL; 614 size_t n = 0; 615 616 if (crypto_pk_write_private_key_to_string(env, &s, &n) < 0) 617 return -1; 618 619 int rv = write_bytes_to_file(fname, s, n, 0); 620 memwipe(s, 0, n); 621 tor_free(s); 622 return rv; 623 } 624 625 /** Given a crypto_pk_t <b>pk</b>, allocate a new buffer containing the 626 * Base64 encoding of the DER representation of the private key as a NUL 627 * terminated string, and return it via <b>priv_out</b>. Return 0 on 628 * success, -1 on failure. 629 * 630 * It is the caller's responsibility to sanitize and free the resulting buffer. 631 */ 632 int 633 crypto_pk_base64_encode_private(const crypto_pk_t *pk, char **priv_out) 634 { 635 size_t buflen = crypto_pk_keysize(pk)*16; 636 char *buf = tor_malloc(buflen); 637 char *result = NULL; 638 size_t reslen = 0; 639 bool ok = false; 640 641 int n = crypto_pk_asn1_encode_private(pk, buf, buflen); 642 643 if (n < 0) 644 goto done; 645 646 reslen = base64_encode_size(n, 0)+1; 647 result = tor_malloc(reslen); 648 if (base64_encode(result, reslen, buf, n, 0) < 0) 649 goto done; 650 651 ok = true; 652 653 done: 654 memwipe(buf, 0, buflen); 655 tor_free(buf); 656 if (result && ! ok) { 657 memwipe(result, 0, reslen); 658 tor_free(result); 659 } 660 *priv_out = result; 661 return ok ? 0 : -1; 662 } 663 664 /** Given a string containing the Base64 encoded DER representation of the 665 * private key <b>str</b>, decode and return the result on success, or NULL 666 * on failure. 667 */ 668 crypto_pk_t * 669 crypto_pk_base64_decode_private(const char *str, size_t len) 670 { 671 crypto_pk_t *pk = NULL; 672 673 char *der = tor_malloc_zero(len + 1); 674 int der_len = base64_decode(der, len, str, len); 675 if (der_len <= 0) { 676 log_warn(LD_CRYPTO, "Stored RSA private key seems corrupted (base64)."); 677 goto out; 678 } 679 680 pk = crypto_pk_asn1_decode_private(der, der_len, -1); 681 682 out: 683 memwipe(der, 0, len+1); 684 tor_free(der); 685 686 return pk; 687 }