12 #include "lib/crypt_ops/compat_openssl.h"
19 DISABLE_GCC_WARNING(
"-Wredundant-decls")
21 #include <openssl/err.h>
22 #include <openssl/rsa.h>
23 #include <openssl/pem.h>
24 #include <openssl/evp.h>
25 #include <openssl/engine.h>
26 #include <openssl/rand.h>
27 #include <openssl/bn.h>
28 #include <openssl/conf.h>
30 ENABLE_GCC_WARNING(
"-Wredundant-decls")
32 #include "lib/log/log.h"
50 #ifdef OPENSSL_1_1_API
55 RSA_get0_factors(k->key, &p, &q);
58 return k && k->key && k->key->p;
65 crypto_new_pk_from_openssl_rsa_(RSA *rsa)
80 return RSAPrivateKey_dup(env->
key);
87 crypto_pk_get_openssl_evp_pkey_,(
crypto_pk_t *env,
int private))
90 EVP_PKEY *pkey = NULL;
93 if (!(key = RSAPrivateKey_dup(env->
key)))
96 if (!(key = RSAPublicKey_dup(env->
key)))
99 if (!(pkey = EVP_PKEY_new()))
101 if (!(EVP_PKEY_assign_RSA(pkey, key)))
122 return crypto_new_pk_from_openssl_rsa_(rsa);
158 BIGNUM *e = BN_new();
167 if (RSA_generate_key_ex(r, bits, e, NULL) == -1)
195 r = RSA_check_key(env->
key);
215 #ifdef OPENSSL_1_1_API
217 RSA_get0_key(env->
key, &n, &e, &d);
234 char a_is_non_null = (a != NULL) && (a->
key != NULL);
235 char b_is_non_null = (b != NULL) && (b->
key != NULL);
236 char an_argument_is_null = !a_is_non_null | !b_is_non_null;
238 result =
tor_memcmp(&a_is_non_null, &b_is_non_null,
sizeof(a_is_non_null));
239 if (an_argument_is_null)
242 const BIGNUM *a_n, *a_e;
243 const BIGNUM *b_n, *b_e;
245 #ifdef OPENSSL_1_1_API
246 const BIGNUM *a_d, *b_d;
247 RSA_get0_key(a->
key, &a_n, &a_e, &a_d);
248 RSA_get0_key(b->
key, &b_n, &b_e, &b_d);
259 result = BN_cmp(a_n, b_n);
262 return BN_cmp(a_e, b_e);
272 return (
size_t) RSA_size((RSA*)env->
key);
282 #ifdef OPENSSL_1_1_API
286 const BIGNUM *n, *e, *d;
287 RSA_get0_key(env->
key, &n, &e, &d);
290 return RSA_bits(env->
key);
293 return BN_num_bits(env->
key->n);
319 dest->
key = RSAPrivateKey_dup(src->
key);
332 dest->
key = RSAPublicKey_dup(src->
key);
346 new_key = RSAPrivateKey_dup(env->
key);
349 new_key = RSAPublicKey_dup(env->
key);
356 log_err(
LD_CRYPTO,
"Unable to duplicate a %s key: openssl failed.",
357 privatekey?
"private":
"public");
359 privatekey ?
"Duplicating a private key" :
360 "Duplicating a public key");
366 return crypto_new_pk_from_openssl_rsa_(new_key);
379 const char *from,
size_t fromlen,
int padding)
388 r = RSA_public_encrypt((
int)fromlen,
389 (
unsigned char*)from, (
unsigned char*)to,
390 env->
key, crypto_get_rsa_padding(padding));
409 const char *from,
size_t fromlen,
410 int padding,
int warnOnFailure)
423 r = RSA_private_decrypt((
int)fromlen,
424 (
unsigned char*)from, (
unsigned char*)to,
425 env->
key, crypto_get_rsa_padding(padding));
429 "performing RSA decryption");
446 const char *from,
size_t fromlen))
454 r = RSA_public_decrypt((
int)fromlen,
455 (
unsigned char*)from, (
unsigned char*)to,
456 env->
key, RSA_PKCS1_PADDING);
475 const char *from,
size_t fromlen)
487 r = RSA_private_encrypt((
int)fromlen,
488 (
unsigned char*)from, (
unsigned char*)to,
489 (RSA*)env->
key, RSA_PKCS1_PADDING);
504 unsigned char *buf = NULL;
506 len = i2d_RSAPublicKey(pk->
key, &buf);
507 if (len < 0 || buf == NULL)
517 memcpy(dest,buf,len);
530 const unsigned char *cp;
531 cp = buf = tor_malloc(len);
533 rsa = d2i_RSAPublicKey(NULL, &cp, len);
539 return crypto_new_pk_from_openssl_rsa_(rsa);
550 unsigned char *buf = NULL;
552 len = i2d_RSAPrivateKey(pk->
key, &buf);
553 if (len < 0 || buf == NULL)
563 memcpy(dest,buf,len);
572 rsa_private_key_too_long(RSA *rsa,
int max_bits)
574 const BIGNUM *n, *e, *p, *q, *d, *dmp1, *dmq1, *iqmp;
575 #ifdef OPENSSL_1_1_API
577 #if OPENSSL_VERSION_NUMBER >= OPENSSL_V_SERIES(1,1,1)
583 dmp1 = RSA_get0_dmp1(rsa);
584 dmq1 = RSA_get0_dmq1(rsa);
585 iqmp = RSA_get0_iqmp(rsa);
588 p = q = dmp1 = dmq1 = iqmp = NULL;
589 RSA_get0_key(rsa, &n, &e, &d);
592 if (RSA_bits(rsa) > max_bits)
605 if (n && BN_num_bits(n) > max_bits)
607 if (e && BN_num_bits(e) > max_bits)
609 if (p && BN_num_bits(p) > max_bits)
611 if (q && BN_num_bits(q) > max_bits)
613 if (d && BN_num_bits(d) > max_bits)
615 if (dmp1 && BN_num_bits(dmp1) > max_bits)
617 if (dmq1 && BN_num_bits(dmq1) > max_bits)
619 if (iqmp && BN_num_bits(iqmp) > max_bits)
636 const unsigned char *cp;
637 cp = buf = tor_malloc(len);
639 rsa = d2i_RSAPrivateKey(NULL, &cp, len);
645 if (max_bits >= 0 && rsa_private_key_too_long(rsa, max_bits)) {
646 log_info(
LD_CRYPTO,
"Private key longer than expected.");
650 crypto_pk_t *result = crypto_new_pk_from_openssl_rsa_(rsa);
652 crypto_pk_free(result);
void crypto_openssl_log_errors(int severity, const char *doing)
Headers for crypto_rsa.c.
crypto_pk_t * crypto_pk_dup_key(crypto_pk_t *orig)
void crypto_pk_assign_private(crypto_pk_t *dest, const crypto_pk_t *src)
crypto_pk_t * crypto_pk_asn1_decode_private(const char *str, size_t len, int max_bits)
int crypto_pk_cmp_keys(const crypto_pk_t *a, const crypto_pk_t *b)
int crypto_pk_generate_key_with_bits(crypto_pk_t *env, int bits)
size_t crypto_pk_keysize(const crypto_pk_t *env)
crypto_pk_t * crypto_pk_new(void)
int crypto_pk_private_sign(const crypto_pk_t *env, char *to, size_t tolen, const char *from, size_t fromlen)
int crypto_pk_is_valid_private_key(const crypto_pk_t *env)
crypto_pk_t * crypto_pk_asn1_decode(const char *str, size_t len)
int crypto_pk_private_decrypt(crypto_pk_t *env, char *to, size_t tolen, const char *from, size_t fromlen, int padding, int warnOnFailure)
int crypto_pk_asn1_encode(const crypto_pk_t *pk, char *dest, size_t dest_len)
int crypto_pk_public_encrypt(crypto_pk_t *env, char *to, size_t tolen, const char *from, size_t fromlen, int padding)
void crypto_pk_assign_public(crypto_pk_t *dest, const crypto_pk_t *src)
int crypto_pk_num_bits(crypto_pk_t *env)
int crypto_pk_key_is_private(const crypto_pk_t *key)
int crypto_pk_asn1_encode_private(const crypto_pk_t *pk, char *dest, size_t dest_len)
crypto_pk_t * crypto_pk_copy_full(crypto_pk_t *orig)
int crypto_pk_public_checksig(const crypto_pk_t *env, char *to, size_t tolen, const char *from, size_t fromlen)
int crypto_pk_public_exponent_ok(const crypto_pk_t *env)
void crypto_pk_free_(crypto_pk_t *env)
Common functions for cryptographic routines.
int tor_memcmp(const void *a, const void *b, size_t len)
Wrappers for reading and writing data to files on disk.
#define MOCK_IMPL(rv, funcname, arglist)
Macros to manage assertions, fatal and non-fatal.
#define tor_fragile_assert()