LCOV - code coverage report
Current view: top level - lib/crypt_ops - crypto_rsa_openssl.c (source / functions) Hit Total Coverage
Test: lcov.info Lines: 238 264 90.2 %
Date: 2021-11-24 03:28:48 Functions: 24 25 96.0 %

          Line data    Source code
       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 OpenSSL implementations of our RSA code.
      10             :  **/
      11             : 
      12             : #include "lib/crypt_ops/compat_openssl.h"
      13             : #include "lib/crypt_ops/crypto_rsa.h"
      14             : #include "lib/crypt_ops/crypto_util.h"
      15             : #include "lib/ctime/di_ops.h"
      16             : #include "lib/log/util_bug.h"
      17             : #include "lib/fs/files.h"
      18             : 
      19             : DISABLE_GCC_WARNING("-Wredundant-decls")
      20             : 
      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>
      29             : 
      30             : ENABLE_GCC_WARNING("-Wredundant-decls")
      31             : 
      32             : #include "lib/log/log.h"
      33             : #include "lib/encoding/binascii.h"
      34             : 
      35             : #include <string.h>
      36             : #include <stdbool.h>
      37             : 
      38             : /** Declaration for crypto_pk_t structure. */
      39             : struct crypto_pk_t
      40             : {
      41             :   int refs; /**< reference count, so we don't have to copy keys */
      42             :   RSA *key; /**< The key itself */
      43             : };
      44             : 
      45             : /** Return true iff <b>key</b> contains the private-key portion of the RSA
      46             :  * key. */
      47             : int
      48       16906 : crypto_pk_key_is_private(const crypto_pk_t *k)
      49             : {
      50             : #ifdef OPENSSL_1_1_API
      51       16906 :   if (!k || !k->key)
      52             :     return 0;
      53             : 
      54       16906 :   const BIGNUM *p, *q;
      55       16906 :   RSA_get0_factors(k->key, &p, &q);
      56       16905 :   return p != NULL; /* XXX/yawning: Should we check q? */
      57             : #else /* !defined(OPENSSL_1_1_API) */
      58             :   return k && k->key && k->key->p;
      59             : #endif /* defined(OPENSSL_1_1_API) */
      60             : }
      61             : 
      62             : /** used by tortls.c: wrap an RSA* in a crypto_pk_t. Takes ownership of
      63             :  * its argument. */
      64             : crypto_pk_t *
      65       85785 : crypto_new_pk_from_openssl_rsa_(RSA *rsa)
      66             : {
      67       85785 :   crypto_pk_t *env;
      68       85785 :   tor_assert(rsa);
      69       85785 :   env = tor_malloc(sizeof(crypto_pk_t));
      70       85785 :   env->refs = 1;
      71       85785 :   env->key = rsa;
      72       85785 :   return env;
      73             : }
      74             : 
      75             : /** Helper, used by tor-gencert.c.  Return a copy of the private RSA from a
      76             :  * crypto_pk_t. */
      77             : RSA *
      78           0 : crypto_pk_get_openssl_rsa_(crypto_pk_t *env)
      79             : {
      80           0 :   return RSAPrivateKey_dup(env->key);
      81             : }
      82             : 
      83             : /** used by tortls.c: get an equivalent EVP_PKEY* for a crypto_pk_t.  Iff
      84             :  * private is set, include the private-key portion of the key. Return a valid
      85             :  * pointer on success, and NULL on failure. */
      86         671 : MOCK_IMPL(EVP_PKEY *,
      87             : crypto_pk_get_openssl_evp_pkey_,(crypto_pk_t *env, int private))
      88             : {
      89         671 :   RSA *key = NULL;
      90         671 :   EVP_PKEY *pkey = NULL;
      91         671 :   tor_assert(env->key);
      92         671 :   if (private) {
      93         384 :     if (!(key = RSAPrivateKey_dup(env->key)))
      94           0 :       goto error;
      95             :   } else {
      96         287 :     if (!(key = RSAPublicKey_dup(env->key)))
      97           0 :       goto error;
      98             :   }
      99         671 :   if (!(pkey = EVP_PKEY_new()))
     100           0 :     goto error;
     101         671 :   if (!(EVP_PKEY_assign_RSA(pkey, key)))
     102           0 :     goto error;
     103             :   return pkey;
     104           0 :  error:
     105           0 :   if (pkey)
     106           0 :     EVP_PKEY_free(pkey);
     107           0 :   if (key)
     108           0 :     RSA_free(key);
     109             :   return NULL;
     110             : }
     111             : 
     112             : /** Allocate and return storage for a public key.  The key itself will not yet
     113             :  * be set.
     114             :  */
     115       41375 : MOCK_IMPL(crypto_pk_t *,
     116             : crypto_pk_new,(void))
     117             : {
     118       41375 :   RSA *rsa;
     119             : 
     120       41375 :   rsa = RSA_new();
     121       41375 :   tor_assert(rsa);
     122       41375 :   return crypto_new_pk_from_openssl_rsa_(rsa);
     123             : }
     124             : 
     125             : /** Release a reference to an asymmetric key; when all the references
     126             :  * are released, free the key.
     127             :  */
     128             : void
     129       68982 : crypto_pk_free_(crypto_pk_t *env)
     130             : {
     131       68982 :   if (!env)
     132             :     return;
     133             : 
     134       65728 :   if (--env->refs > 0)
     135             :     return;
     136       65171 :   tor_assert(env->refs == 0);
     137             : 
     138       65171 :   if (env->key)
     139       65171 :     RSA_free(env->key);
     140             : 
     141       65171 :   tor_free(env);
     142             : }
     143             : 
     144             : /** Generate a <b>bits</b>-bit new public/private keypair in <b>env</b>.
     145             :  * Return 0 on success, -1 on failure.
     146             :  */
     147         123 : MOCK_IMPL(int,
     148             : crypto_pk_generate_key_with_bits,(crypto_pk_t *env, int bits))
     149             : {
     150         123 :   tor_assert(env);
     151             : 
     152         123 :   if (env->key) {
     153         123 :     RSA_free(env->key);
     154         123 :     env->key = NULL;
     155             :   }
     156             : 
     157             :   {
     158         123 :     BIGNUM *e = BN_new();
     159         123 :     RSA *r = NULL;
     160         123 :     if (!e)
     161           0 :       goto done;
     162         123 :     if (! BN_set_word(e, TOR_RSA_EXPONENT))
     163           0 :       goto done;
     164         123 :     r = RSA_new();
     165         123 :     if (!r)
     166           0 :       goto done;
     167         123 :     if (RSA_generate_key_ex(r, bits, e, NULL) == -1)
     168           0 :       goto done;
     169             : 
     170         123 :     env->key = r;
     171         123 :     r = NULL;
     172         123 :   done:
     173         123 :     if (e)
     174         123 :       BN_clear_free(e);
     175         123 :     if (r)
     176           0 :       RSA_free(r);
     177             :   }
     178             : 
     179         123 :   if (!env->key) {
     180           0 :     crypto_openssl_log_errors(LOG_WARN, "generating RSA key");
     181           0 :     return -1;
     182             :   }
     183             : 
     184             :   return 0;
     185             : }
     186             : 
     187             : /** Return true if <b>env</b> has a valid key; false otherwise.
     188             :  */
     189             : int
     190       41063 : crypto_pk_is_valid_private_key(const crypto_pk_t *env)
     191             : {
     192       41063 :   int r;
     193       41063 :   tor_assert(env);
     194             : 
     195       41063 :   r = RSA_check_key(env->key);
     196       41063 :   if (r <= 0) {
     197           1 :     crypto_openssl_log_errors(LOG_WARN,"checking RSA key");
     198           1 :     return 0;
     199             :   } else {
     200             :     return 1;
     201             :   }
     202             : }
     203             : 
     204             : /** Return true iff <b>env</b> contains a public key whose public exponent
     205             :  * equals TOR_RSA_EXPONENT.
     206             :  */
     207             : int
     208         228 : crypto_pk_public_exponent_ok(const crypto_pk_t *env)
     209             : {
     210         228 :   tor_assert(env);
     211         228 :   tor_assert(env->key);
     212             : 
     213         228 :   const BIGNUM *e;
     214             : 
     215             : #ifdef OPENSSL_1_1_API
     216         228 :   const BIGNUM *n, *d;
     217         228 :   RSA_get0_key(env->key, &n, &e, &d);
     218             : #else
     219             :   e = env->key->e;
     220             : #endif /* defined(OPENSSL_1_1_API) */
     221         228 :   return BN_is_word(e, TOR_RSA_EXPONENT);
     222             : }
     223             : 
     224             : /** Compare the public-key components of a and b.  Return less than 0
     225             :  * if a\<b, 0 if a==b, and greater than 0 if a\>b.  A NULL key is
     226             :  * considered to be less than all non-NULL keys, and equal to itself.
     227             :  *
     228             :  * Note that this may leak information about the keys through timing.
     229             :  */
     230             : int
     231          78 : crypto_pk_cmp_keys(const crypto_pk_t *a, const crypto_pk_t *b)
     232             : {
     233          78 :   int result;
     234          78 :   char a_is_non_null = (a != NULL) && (a->key != NULL);
     235          78 :   char b_is_non_null = (b != NULL) && (b->key != NULL);
     236          78 :   char an_argument_is_null = !a_is_non_null | !b_is_non_null;
     237             : 
     238          78 :   result = tor_memcmp(&a_is_non_null, &b_is_non_null, sizeof(a_is_non_null));
     239          78 :   if (an_argument_is_null)
     240             :     return result;
     241             : 
     242          75 :   const BIGNUM *a_n, *a_e;
     243          75 :   const BIGNUM *b_n, *b_e;
     244             : 
     245             : #ifdef OPENSSL_1_1_API
     246          75 :   const BIGNUM *a_d, *b_d;
     247          75 :   RSA_get0_key(a->key, &a_n, &a_e, &a_d);
     248          75 :   RSA_get0_key(b->key, &b_n, &b_e, &b_d);
     249             : #else
     250             :   a_n = a->key->n;
     251             :   a_e = a->key->e;
     252             :   b_n = b->key->n;
     253             :   b_e = b->key->e;
     254             : #endif /* defined(OPENSSL_1_1_API) */
     255             : 
     256          75 :   tor_assert(a_n != NULL && a_e != NULL);
     257          75 :   tor_assert(b_n != NULL && b_e != NULL);
     258             : 
     259          75 :   result = BN_cmp(a_n, b_n);
     260          75 :   if (result)
     261             :     return result;
     262          75 :   return BN_cmp(a_e, b_e);
     263             : }
     264             : 
     265             : /** Return the size of the public key modulus in <b>env</b>, in bytes. */
     266             : size_t
     267       20032 : crypto_pk_keysize(const crypto_pk_t *env)
     268             : {
     269       20032 :   tor_assert(env);
     270       20032 :   tor_assert(env->key);
     271             : 
     272       20032 :   return (size_t) RSA_size((RSA*)env->key);
     273             : }
     274             : 
     275             : /** Return the size of the public key modulus of <b>env</b>, in bits. */
     276             : int
     277         606 : crypto_pk_num_bits(crypto_pk_t *env)
     278             : {
     279         606 :   tor_assert(env);
     280         606 :   tor_assert(env->key);
     281             : 
     282             : #ifdef OPENSSL_1_1_API
     283             :   /* It's so stupid that there's no other way to check that n is valid
     284             :    * before calling RSA_bits().
     285             :    */
     286         606 :   const BIGNUM *n, *e, *d;
     287         606 :   RSA_get0_key(env->key, &n, &e, &d);
     288         606 :   tor_assert(n != NULL);
     289             : 
     290         606 :   return RSA_bits(env->key);
     291             : #else /* !defined(OPENSSL_1_1_API) */
     292             :   tor_assert(env->key->n);
     293             :   return BN_num_bits(env->key->n);
     294             : #endif /* defined(OPENSSL_1_1_API) */
     295             : }
     296             : 
     297             : /** Increase the reference count of <b>env</b>, and return it.
     298             :  */
     299             : crypto_pk_t *
     300         558 : crypto_pk_dup_key(crypto_pk_t *env)
     301             : {
     302         558 :   tor_assert(env);
     303         558 :   tor_assert(env->key);
     304             : 
     305         558 :   env->refs++;
     306         558 :   return env;
     307             : }
     308             : 
     309             : /** Replace dest with src (private key only).  (Dest must have a refcount
     310             :  * of 1)
     311             :  */
     312             : void
     313       41231 : crypto_pk_assign_private(crypto_pk_t *dest, const crypto_pk_t *src)
     314             : {
     315       41231 :   tor_assert(dest);
     316       41231 :   tor_assert(dest->refs == 1);
     317       41231 :   tor_assert(src);
     318       41231 :   RSA_free(dest->key);
     319       41231 :   dest->key = RSAPrivateKey_dup(src->key);
     320       41231 : }
     321             : 
     322             : /** Replace dest with src (public key only).  (Dest must have a refcount
     323             :  * of 1)
     324             :  */
     325             : void
     326          18 : crypto_pk_assign_public(crypto_pk_t *dest, const crypto_pk_t *src)
     327             : {
     328          18 :   tor_assert(dest);
     329          18 :   tor_assert(dest->refs == 1);
     330          18 :   tor_assert(src);
     331          18 :   RSA_free(dest->key);
     332          18 :   dest->key = RSAPublicKey_dup(src->key);
     333          18 : }
     334             : 
     335             : /** Make a real honest-to-goodness copy of <b>env</b>, and return it.
     336             :  * Returns NULL on failure. */
     337             : crypto_pk_t *
     338           1 : crypto_pk_copy_full(crypto_pk_t *env)
     339             : {
     340           1 :   RSA *new_key;
     341           1 :   int privatekey = 0;
     342           1 :   tor_assert(env);
     343           1 :   tor_assert(env->key);
     344             : 
     345           1 :   if (crypto_pk_key_is_private(env)) {
     346           1 :     new_key = RSAPrivateKey_dup(env->key);
     347           1 :     privatekey = 1;
     348             :   } else {
     349           0 :     new_key = RSAPublicKey_dup(env->key);
     350             :   }
     351           1 :   if (!new_key) {
     352             :     /* LCOV_EXCL_START
     353             :      *
     354             :      * We can't cause RSA*Key_dup() to fail, so we can't really test this.
     355             :      */
     356             :     log_err(LD_CRYPTO, "Unable to duplicate a %s key: openssl failed.",
     357             :             privatekey?"private":"public");
     358             :     crypto_openssl_log_errors(LOG_ERR,
     359             :                       privatekey ? "Duplicating a private key" :
     360             :                       "Duplicating a public key");
     361             :     tor_fragile_assert();
     362             :     return NULL;
     363             :     /* LCOV_EXCL_STOP */
     364             :   }
     365             : 
     366           1 :   return crypto_new_pk_from_openssl_rsa_(new_key);
     367             : }
     368             : 
     369             : /** Encrypt <b>fromlen</b> bytes from <b>from</b> with the public key
     370             :  * in <b>env</b>, using the padding method <b>padding</b>.  On success,
     371             :  * write the result to <b>to</b>, and return the number of bytes
     372             :  * written.  On failure, return -1.
     373             :  *
     374             :  * <b>tolen</b> is the number of writable bytes in <b>to</b>, and must be
     375             :  * at least the length of the modulus of <b>env</b>.
     376             :  */
     377             : int
     378          61 : crypto_pk_public_encrypt(crypto_pk_t *env, char *to, size_t tolen,
     379             :                          const char *from, size_t fromlen, int padding)
     380             : {
     381          61 :   int r;
     382          61 :   tor_assert(env);
     383          61 :   tor_assert(from);
     384          61 :   tor_assert(to);
     385          61 :   tor_assert(fromlen<INT_MAX);
     386          61 :   tor_assert(tolen >= crypto_pk_keysize(env));
     387             : 
     388          61 :   r = RSA_public_encrypt((int)fromlen,
     389             :                          (unsigned char*)from, (unsigned char*)to,
     390             :                          env->key, crypto_get_rsa_padding(padding));
     391          61 :   if (r<0) {
     392           0 :     crypto_openssl_log_errors(LOG_WARN, "performing RSA encryption");
     393           0 :     return -1;
     394             :   }
     395             :   return r;
     396             : }
     397             : 
     398             : /** Decrypt <b>fromlen</b> bytes from <b>from</b> with the private key
     399             :  * in <b>env</b>, using the padding method <b>padding</b>.  On success,
     400             :  * write the result to <b>to</b>, and return the number of bytes
     401             :  * written.  On failure, return -1.
     402             :  *
     403             :  * <b>tolen</b> is the number of writable bytes in <b>to</b>, and must be
     404             :  * at least the length of the modulus of <b>env</b>.
     405             :  */
     406             : int
     407          69 : crypto_pk_private_decrypt(crypto_pk_t *env, char *to,
     408             :                           size_t tolen,
     409             :                           const char *from, size_t fromlen,
     410             :                           int padding, int warnOnFailure)
     411             : {
     412          69 :   int r;
     413          69 :   tor_assert(env);
     414          69 :   tor_assert(from);
     415          69 :   tor_assert(to);
     416          69 :   tor_assert(env->key);
     417          69 :   tor_assert(fromlen<INT_MAX);
     418          69 :   tor_assert(tolen >= crypto_pk_keysize(env));
     419          69 :   if (!crypto_pk_key_is_private(env))
     420             :     /* Not a private key */
     421             :     return -1;
     422             : 
     423          68 :   r = RSA_private_decrypt((int)fromlen,
     424             :                           (unsigned char*)from, (unsigned char*)to,
     425             :                           env->key, crypto_get_rsa_padding(padding));
     426             : 
     427          68 :   if (r<0) {
     428           4 :     crypto_openssl_log_errors(warnOnFailure?LOG_WARN:LOG_DEBUG,
     429             :                       "performing RSA decryption");
     430           4 :     return -1;
     431             :   }
     432             :   return r;
     433             : }
     434             : 
     435             : /** Check the signature in <b>from</b> (<b>fromlen</b> bytes long) with the
     436             :  * public key in <b>env</b>, using PKCS1 padding.  On success, write the
     437             :  * signed data to <b>to</b>, and return the number of bytes written.
     438             :  * On failure, return -1.
     439             :  *
     440             :  * <b>tolen</b> is the number of writable bytes in <b>to</b>, and must be
     441             :  * at least the length of the modulus of <b>env</b>.
     442             :  */
     443         506 : MOCK_IMPL(int,
     444             : crypto_pk_public_checksig,(const crypto_pk_t *env, char *to,
     445             :                            size_t tolen,
     446             :                            const char *from, size_t fromlen))
     447             : {
     448         506 :   int r;
     449         506 :   tor_assert(env);
     450         506 :   tor_assert(from);
     451         506 :   tor_assert(to);
     452         506 :   tor_assert(fromlen < INT_MAX);
     453         506 :   tor_assert(tolen >= crypto_pk_keysize(env));
     454        1012 :   r = RSA_public_decrypt((int)fromlen,
     455             :                          (unsigned char*)from, (unsigned char*)to,
     456         506 :                          env->key, RSA_PKCS1_PADDING);
     457             : 
     458         506 :   if (r<0) {
     459           6 :     crypto_openssl_log_errors(LOG_INFO, "checking RSA signature");
     460           6 :     return -1;
     461             :   }
     462             :   return r;
     463             : }
     464             : 
     465             : /** Sign <b>fromlen</b> bytes of data from <b>from</b> with the private key in
     466             :  * <b>env</b>, using PKCS1 padding.  On success, write the signature to
     467             :  * <b>to</b>, and return the number of bytes written.  On failure, return
     468             :  * -1.
     469             :  *
     470             :  * <b>tolen</b> is the number of writable bytes in <b>to</b>, and must be
     471             :  * at least the length of the modulus of <b>env</b>.
     472             :  */
     473             : int
     474       14370 : crypto_pk_private_sign(const crypto_pk_t *env, char *to, size_t tolen,
     475             :                        const char *from, size_t fromlen)
     476             : {
     477       14370 :   int r;
     478       14370 :   tor_assert(env);
     479       14370 :   tor_assert(from);
     480       14370 :   tor_assert(to);
     481       14370 :   tor_assert(fromlen < INT_MAX);
     482       14370 :   tor_assert(tolen >= crypto_pk_keysize(env));
     483       14370 :   if (!crypto_pk_key_is_private(env))
     484             :     /* Not a private key */
     485             :     return -1;
     486             : 
     487       28505 :   r = RSA_private_encrypt((int)fromlen,
     488             :                           (unsigned char*)from, (unsigned char*)to,
     489       14369 :                           (RSA*)env->key, RSA_PKCS1_PADDING);
     490       14136 :   if (r<0) {
     491           0 :     crypto_openssl_log_errors(LOG_WARN, "generating RSA signature");
     492           0 :     return -1;
     493             :   }
     494             :   return r;
     495             : }
     496             : 
     497             : /** ASN.1-encode the public portion of <b>pk</b> into <b>dest</b>.
     498             :  * Return -1 on error, or the number of characters used on success.
     499             :  */
     500             : int
     501        2012 : crypto_pk_asn1_encode(const crypto_pk_t *pk, char *dest, size_t dest_len)
     502             : {
     503        2012 :   int len;
     504        2012 :   unsigned char *buf = NULL;
     505             : 
     506        2012 :   len = i2d_RSAPublicKey(pk->key, &buf);
     507        2012 :   if (len < 0 || buf == NULL)
     508             :     return -1;
     509             : 
     510        2012 :   if ((size_t)len > dest_len || dest_len > SIZE_T_CEILING) {
     511           2 :     OPENSSL_free(buf);
     512           2 :     return -1;
     513             :   }
     514             :   /* We don't encode directly into 'dest', because that would be illegal
     515             :    * type-punning.  (C99 is smarter than me, C99 is smarter than me...)
     516             :    */
     517        2010 :   memcpy(dest,buf,len);
     518        2010 :   OPENSSL_free(buf);
     519        2010 :   return len;
     520             : }
     521             : 
     522             : /** Decode an ASN.1-encoded public key from <b>str</b>; return the result on
     523             :  * success and NULL on failure.
     524             :  */
     525             : crypto_pk_t *
     526        2800 : crypto_pk_asn1_decode(const char *str, size_t len)
     527             : {
     528        2800 :   RSA *rsa;
     529        2800 :   unsigned char *buf;
     530        2800 :   const unsigned char *cp;
     531        2800 :   cp = buf = tor_malloc(len);
     532        2800 :   memcpy(buf,str,len);
     533        2800 :   rsa = d2i_RSAPublicKey(NULL, &cp, len);
     534        2800 :   tor_free(buf);
     535        2800 :   if (!rsa) {
     536           8 :     crypto_openssl_log_errors(LOG_WARN,"decoding public key");
     537           8 :     return NULL;
     538             :   }
     539        2792 :   return crypto_new_pk_from_openssl_rsa_(rsa);
     540             : }
     541             : 
     542             : /** ASN.1-encode the private portion of <b>pk</b> into <b>dest</b>.
     543             :  * Return -1 on error, or the number of characters used on success.
     544             :  */
     545             : int
     546          32 : crypto_pk_asn1_encode_private(const crypto_pk_t *pk, char *dest,
     547             :                               size_t dest_len)
     548             : {
     549          32 :   int len;
     550          32 :   unsigned char *buf = NULL;
     551             : 
     552          32 :   len = i2d_RSAPrivateKey(pk->key, &buf);
     553          32 :   if (len < 0 || buf == NULL)
     554             :     return -1;
     555             : 
     556          32 :   if ((size_t)len > dest_len || dest_len > SIZE_T_CEILING) {
     557           0 :     OPENSSL_free(buf);
     558           0 :     return -1;
     559             :   }
     560             :   /* We don't encode directly into 'dest', because that would be illegal
     561             :    * type-punning.  (C99 is smarter than me, C99 is smarter than me...)
     562             :    */
     563          32 :   memcpy(dest,buf,len);
     564          32 :   OPENSSL_free(buf);
     565          32 :   return len;
     566             : }
     567             : 
     568             : /** Check whether any component of a private key is too large in a way that
     569             :  * seems likely to make verification too expensive. Return true if it's too
     570             :  * long, and false otherwise. */
     571             : static bool
     572           5 : rsa_private_key_too_long(RSA *rsa, int max_bits)
     573             : {
     574           5 :   const BIGNUM *n, *e, *p, *q, *d, *dmp1, *dmq1, *iqmp;
     575             : #ifdef OPENSSL_1_1_API
     576             : 
     577             : #if OPENSSL_VERSION_NUMBER >= OPENSSL_V_SERIES(1,1,1)
     578           5 :   n = RSA_get0_n(rsa);
     579           5 :   e = RSA_get0_e(rsa);
     580           5 :   p = RSA_get0_p(rsa);
     581           5 :   q = RSA_get0_q(rsa);
     582           5 :   d = RSA_get0_d(rsa);
     583           5 :   dmp1 = RSA_get0_dmp1(rsa);
     584           5 :   dmq1 = RSA_get0_dmq1(rsa);
     585           5 :   iqmp = RSA_get0_iqmp(rsa);
     586             : #else /* !(OPENSSL_VERSION_NUMBER >= OPENSSL_V_SERIES(1,1,1)) */
     587             :   /* The accessors above did not exist in openssl 1.1.0. */
     588             :   p = q = dmp1 = dmq1 = iqmp = NULL;
     589             :   RSA_get0_key(rsa, &n, &e, &d);
     590             : #endif /* OPENSSL_VERSION_NUMBER >= OPENSSL_V_SERIES(1,1,1) */
     591             : 
     592           5 :   if (RSA_bits(rsa) > max_bits)
     593             :     return true;
     594             : #else /* !defined(OPENSSL_1_1_API) */
     595             :   n = rsa->n;
     596             :   e = rsa->e;
     597             :   p = rsa->p;
     598             :   q = rsa->q;
     599             :   d = rsa->d;
     600             :   dmp1 = rsa->dmp1;
     601             :   dmq1 = rsa->dmq1;
     602             :   iqmp = rsa->iqmp;
     603             : #endif /* defined(OPENSSL_1_1_API) */
     604             : 
     605           3 :   if (n && BN_num_bits(n) > max_bits)
     606             :     return true;
     607           3 :   if (e && BN_num_bits(e) > max_bits)
     608             :     return true;
     609           3 :   if (p && BN_num_bits(p) > max_bits)
     610             :     return true;
     611           3 :   if (q && BN_num_bits(q) > max_bits)
     612             :     return true;
     613           3 :   if (d && BN_num_bits(d) > max_bits)
     614             :     return true;
     615           3 :   if (dmp1 && BN_num_bits(dmp1) > max_bits)
     616             :     return true;
     617           3 :   if (dmq1 && BN_num_bits(dmq1) > max_bits)
     618             :     return true;
     619           3 :   if (iqmp && BN_num_bits(iqmp) > max_bits)
     620           0 :     return true;
     621             : 
     622             :   return false;
     623             : }
     624             : 
     625             : /** Decode an ASN.1-encoded private key from <b>str</b>; return the result on
     626             :  * success and NULL on failure.
     627             :  *
     628             :  * If <b>max_bits</b> is nonnegative, reject any key longer than max_bits
     629             :  * without performing any expensive validation on it.
     630             :  */
     631             : crypto_pk_t *
     632       41037 : crypto_pk_asn1_decode_private(const char *str, size_t len, int max_bits)
     633             : {
     634       41037 :   RSA *rsa;
     635       41037 :   unsigned char *buf;
     636       41037 :   const unsigned char *cp;
     637       41037 :   cp = buf = tor_malloc(len);
     638       41037 :   memcpy(buf,str,len);
     639       41037 :   rsa = d2i_RSAPrivateKey(NULL, &cp, len);
     640       41037 :   tor_free(buf);
     641       41037 :   if (!rsa) {
     642           1 :     crypto_openssl_log_errors(LOG_WARN,"decoding private key");
     643           1 :     return NULL;
     644             :   }
     645       41036 :   if (max_bits >= 0 && rsa_private_key_too_long(rsa, max_bits)) {
     646           2 :     log_info(LD_CRYPTO, "Private key longer than expected.");
     647           2 :     RSA_free(rsa);
     648           2 :     return NULL;
     649             :   }
     650       41034 :   crypto_pk_t *result = crypto_new_pk_from_openssl_rsa_(rsa);
     651       41034 :   if (! crypto_pk_is_valid_private_key(result)) {
     652           1 :     crypto_pk_free(result);
     653           1 :     return NULL;
     654             :   }
     655             :   return result;
     656             : }

Generated by: LCOV version 1.14