LCOV - code coverage report
Current view: top level - lib/tls - x509_openssl.c (source / functions) Hit Total Coverage
Test: lcov.info Lines: 187 211 88.6 %
Date: 2021-11-24 03:28:48 Functions: 12 12 100.0 %

          Line data    Source code
       1             : /* Copyright (c) 2003, Roger Dingledine.
       2             :  * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
       3             :  * Copyright (c) 2007-2021, The Tor Project, Inc. */
       4             : /* See LICENSE for licensing information */
       5             : 
       6             : /**
       7             :  * \file x509_openssl.c
       8             :  * \brief Wrapper functions to present a consistent interface to
       9             :  * X.509 functions from OpenSSL.
      10             :  **/
      11             : 
      12             : #define TOR_X509_PRIVATE
      13             : #include "lib/tls/x509.h"
      14             : #include "lib/tls/x509_internal.h"
      15             : #include "lib/tls/tortls.h"
      16             : #include "lib/crypt_ops/crypto_rand.h"
      17             : #include "lib/crypt_ops/crypto_util.h"
      18             : #include "lib/crypt_ops/compat_openssl.h"
      19             : 
      20             : /* Some versions of OpenSSL declare SSL_get_selected_srtp_profile twice in
      21             :  * srtp.h. Suppress the GCC warning so we can build with -Wredundant-decl. */
      22             : DISABLE_GCC_WARNING("-Wredundant-decls")
      23             : 
      24             : #include <openssl/opensslv.h>
      25             : 
      26             : #ifdef OPENSSL_NO_EC
      27             : #error "We require OpenSSL with ECC support"
      28             : #endif
      29             : 
      30             : #include <openssl/err.h>
      31             : #include <openssl/asn1.h>
      32             : #include <openssl/bio.h>
      33             : #include <openssl/bn.h>
      34             : #include <openssl/evp.h>
      35             : #include <openssl/objects.h>
      36             : #include <openssl/rsa.h>
      37             : #include <openssl/x509.h>
      38             : 
      39             : ENABLE_GCC_WARNING("-Wredundant-decls")
      40             : 
      41             : #include "lib/log/log.h"
      42             : #include "lib/log/util_bug.h"
      43             : #include "lib/ctime/di_ops.h"
      44             : #include "lib/encoding/time_fmt.h"
      45             : 
      46             : #include <stdlib.h>
      47             : #include <string.h>
      48             : 
      49             : #ifdef OPENSSL_1_1_API
      50             : #define X509_get_notBefore_const(cert) \
      51             :     X509_get0_notBefore(cert)
      52             : #define X509_get_notAfter_const(cert) \
      53             :     X509_get0_notAfter(cert)
      54             : #ifndef X509_get_notBefore
      55             : #define X509_get_notBefore(cert) \
      56             :     X509_getm_notBefore(cert)
      57             : #endif
      58             : #ifndef X509_get_notAfter
      59             : #define X509_get_notAfter(cert) \
      60             :     X509_getm_notAfter(cert)
      61             : #endif
      62             : #else /* !defined(OPENSSL_1_1_API) */
      63             : #define X509_get_notBefore_const(cert) \
      64             :   ((const ASN1_TIME*) X509_get_notBefore((X509 *)cert))
      65             : #define X509_get_notAfter_const(cert) \
      66             :   ((const ASN1_TIME*) X509_get_notAfter((X509 *)cert))
      67             : #endif /* defined(OPENSSL_1_1_API) */
      68             : 
      69             : /** Return a newly allocated X509 name with commonName <b>cname</b>. */
      70             : static X509_NAME *
      71         576 : tor_x509_name_new(const char *cname)
      72             : {
      73         576 :   int nid;
      74         576 :   X509_NAME *name;
      75             :   /* LCOV_EXCL_BR_START : these branches will only fail on OOM errors */
      76         576 :   if (!(name = X509_NAME_new()))
      77             :     return NULL;
      78         576 :   if ((nid = OBJ_txt2nid("commonName")) == NID_undef) goto error;
      79         576 :   if (!(X509_NAME_add_entry_by_NID(name, nid, MBSTRING_ASC,
      80             :                                    (unsigned char*)cname, -1, -1, 0)))
      81           0 :     goto error;
      82             :   /* LCOV_EXCL_BR_STOP */
      83             :   return name;
      84             : 
      85             :   /* LCOV_EXCL_START : these lines will only execute on out of memory errors*/
      86             :  error:
      87             :   X509_NAME_free(name);
      88             :   return NULL;
      89             :   /* LCOV_EXCL_STOP */
      90             : }
      91             : 
      92             : /** Generate and sign an X509 certificate with the public key <b>rsa</b>,
      93             :  * signed by the private key <b>rsa_sign</b>.  The commonName of the
      94             :  * certificate will be <b>cname</b>; the commonName of the issuer will be
      95             :  * <b>cname_sign</b>. The cert will be valid for <b>cert_lifetime</b>
      96             :  * seconds, starting from some time in the past.
      97             :  *
      98             :  * Return a certificate on success, NULL on failure.
      99             :  */
     100         290 : MOCK_IMPL(X509 *,
     101             : tor_tls_create_certificate,(crypto_pk_t *rsa,
     102             :                             crypto_pk_t *rsa_sign,
     103             :                             const char *cname,
     104             :                             const char *cname_sign,
     105             :                             unsigned int cert_lifetime))
     106             : {
     107             :   /* OpenSSL generates self-signed certificates with random 64-bit serial
     108             :    * numbers, so let's do that too. */
     109             : #define SERIAL_NUMBER_SIZE 8
     110             : 
     111         290 :   time_t start_time, end_time;
     112         290 :   BIGNUM *serial_number = NULL;
     113         290 :   unsigned char serial_tmp[SERIAL_NUMBER_SIZE];
     114         290 :   EVP_PKEY *sign_pkey = NULL, *pkey=NULL;
     115         290 :   X509 *x509 = NULL;
     116         290 :   X509_NAME *name = NULL, *name_issuer=NULL;
     117             : 
     118         290 :   tor_tls_init();
     119             : 
     120         290 :   time_t now = time(NULL);
     121             : 
     122         290 :   tor_tls_pick_certificate_lifetime(now, cert_lifetime,
     123             :                                     &start_time, &end_time);
     124             : 
     125         290 :   tor_assert(rsa);
     126         290 :   tor_assert(cname);
     127         290 :   tor_assert(rsa_sign);
     128         290 :   tor_assert(cname_sign);
     129         290 :   if (!(sign_pkey = crypto_pk_get_openssl_evp_pkey_(rsa_sign,1)))
     130           1 :     goto error;
     131         289 :   if (!(pkey = crypto_pk_get_openssl_evp_pkey_(rsa,0)))
     132           1 :     goto error;
     133         288 :   if (!(x509 = X509_new()))
     134           0 :     goto error;
     135         288 :   if (!(X509_set_version(x509, 2)))
     136           0 :     goto error;
     137             : 
     138             :   { /* our serial number is 8 random bytes. */
     139         288 :     crypto_rand((char *)serial_tmp, sizeof(serial_tmp));
     140         288 :     if (!(serial_number = BN_bin2bn(serial_tmp, sizeof(serial_tmp), NULL)))
     141           0 :       goto error;
     142         288 :     if (!(BN_to_ASN1_INTEGER(serial_number, X509_get_serialNumber(x509))))
     143           0 :       goto error;
     144             :   }
     145             : 
     146         288 :   if (!(name = tor_x509_name_new(cname)))
     147           0 :     goto error;
     148         288 :   if (!(X509_set_subject_name(x509, name)))
     149           0 :     goto error;
     150         288 :   if (!(name_issuer = tor_x509_name_new(cname_sign)))
     151           0 :     goto error;
     152         288 :   if (!(X509_set_issuer_name(x509, name_issuer)))
     153           0 :     goto error;
     154             : 
     155         288 :   if (!X509_time_adj(X509_get_notBefore(x509),0,&start_time))
     156           0 :     goto error;
     157         288 :   if (!X509_time_adj(X509_get_notAfter(x509),0,&end_time))
     158           0 :     goto error;
     159         288 :   if (!X509_set_pubkey(x509, pkey))
     160           1 :     goto error;
     161             : 
     162         287 :   if (!X509_sign(x509, sign_pkey, EVP_sha256()))
     163           0 :     goto error;
     164             : 
     165         287 :   goto done;
     166           3 :  error:
     167           3 :   if (x509) {
     168           1 :     X509_free(x509);
     169           1 :     x509 = NULL;
     170             :   }
     171           2 :  done:
     172         290 :   tls_log_errors(NULL, LOG_WARN, LD_NET, "generating certificate");
     173         290 :   if (sign_pkey)
     174         289 :     EVP_PKEY_free(sign_pkey);
     175         290 :   if (pkey)
     176         288 :     EVP_PKEY_free(pkey);
     177         290 :   if (serial_number)
     178         288 :     BN_clear_free(serial_number);
     179         290 :   if (name)
     180         288 :     X509_NAME_free(name);
     181         290 :   if (name_issuer)
     182         288 :     X509_NAME_free(name_issuer);
     183         290 :   return x509;
     184             : 
     185             : #undef SERIAL_NUMBER_SIZE
     186             : }
     187             : 
     188             : /** Set the 'encoded' and 'encoded_len' fields of "cert" from cert->cert. */
     189             : int
     190         565 : tor_x509_cert_set_cached_der_encoding(tor_x509_cert_t *cert)
     191             : {
     192         565 :   unsigned char *buf = NULL;
     193         565 :   int length = i2d_X509(cert->cert, &buf);
     194             : 
     195         565 :   if (length <= 0 || buf == NULL) {
     196             :     return -1;
     197             :   }
     198         565 :   cert->encoded_len = (size_t) length;
     199         565 :   cert->encoded = tor_malloc(length);
     200         565 :   memcpy(cert->encoded, buf, length);
     201         565 :   OPENSSL_free(buf);
     202         565 :   return 0;
     203             : }
     204             : 
     205             : void
     206         546 : tor_x509_cert_impl_free_(tor_x509_cert_impl_t *cert)
     207             : {
     208         546 :   if (cert)
     209         251 :     X509_free(cert);
     210         546 : }
     211             : 
     212             : tor_x509_cert_impl_t *
     213         105 : tor_x509_cert_impl_dup_(tor_x509_cert_impl_t *cert)
     214             : {
     215         105 :   if (cert)
     216         101 :     return X509_dup(cert);
     217             :   else
     218             :     return NULL;
     219             : }
     220             : 
     221             : /** Set *<b>encoded_out</b> and *<b>size_out</b> to <b>cert</b>'s encoded DER
     222             :  * representation and length, respectively. */
     223             : void
     224         721 : tor_x509_cert_get_der(const tor_x509_cert_t *cert,
     225             :                  const uint8_t **encoded_out, size_t *size_out)
     226             : {
     227         721 :   tor_assert(cert);
     228         721 :   tor_assert(encoded_out);
     229         721 :   tor_assert(size_out);
     230         721 :   *encoded_out = cert->encoded;
     231         721 :   *size_out = cert->encoded_len;
     232         721 : }
     233             : 
     234             : /** Read a DER-encoded X509 cert, of length exactly <b>certificate_len</b>,
     235             :  * from a <b>certificate</b>.  Return a newly allocated tor_x509_cert_t on
     236             :  * success and NULL on failure. */
     237             : tor_x509_cert_t *
     238         179 : tor_x509_cert_decode(const uint8_t *certificate, size_t certificate_len)
     239             : {
     240         179 :   X509 *x509;
     241         179 :   const unsigned char *cp = (const unsigned char *)certificate;
     242         179 :   tor_x509_cert_t *newcert;
     243         179 :   tor_assert(certificate);
     244         179 :   check_no_tls_errors();
     245             : 
     246         179 :   if (certificate_len > INT_MAX)
     247           0 :     goto err;
     248             : 
     249         179 :   x509 = d2i_X509(NULL, &cp, (int)certificate_len);
     250             : 
     251         179 :   if (!x509)
     252           2 :     goto err; /* Couldn't decode */
     253         177 :   if (cp - certificate != (int)certificate_len) {
     254           0 :     X509_free(x509);
     255           0 :     goto err; /* Didn't use all the bytes */
     256             :   }
     257         177 :   newcert = tor_x509_cert_new(x509);
     258         177 :   if (!newcert) {
     259           0 :     goto err;
     260             :   }
     261         177 :   if (newcert->encoded_len != certificate_len ||
     262         177 :       fast_memneq(newcert->encoded, certificate, certificate_len)) {
     263             :     /* Cert wasn't in DER */
     264           0 :     tor_x509_cert_free(newcert);
     265           0 :     goto err;
     266             :   }
     267             :   return newcert;
     268           2 :  err:
     269           2 :   tls_log_errors(NULL, LOG_INFO, LD_CRYPTO, "decoding a certificate");
     270           2 :   return NULL;
     271             : }
     272             : 
     273             : /**
     274             :  * Return a newly allocated copy of the public key that a certificate
     275             :  * certifies. Watch out! This returns NULL if the cert's key is not RSA.
     276             :  */
     277             : crypto_pk_t *
     278         585 : tor_tls_cert_get_key(tor_x509_cert_t *cert)
     279             : {
     280         585 :   crypto_pk_t *result = NULL;
     281         585 :   EVP_PKEY *pkey = X509_get_pubkey(cert->cert);
     282         585 :   RSA *rsa;
     283         585 :   if (!pkey)
     284             :     return NULL;
     285         584 :   rsa = EVP_PKEY_get1_RSA(pkey);
     286         584 :   if (!rsa) {
     287           2 :     EVP_PKEY_free(pkey);
     288           2 :     return NULL;
     289             :   }
     290         582 :   result = crypto_new_pk_from_openssl_rsa_(rsa);
     291         582 :   EVP_PKEY_free(pkey);
     292         582 :   return result;
     293             : }
     294             : 
     295             : /** Check whether <b>cert</b> is well-formed, currently live, and correctly
     296             :  * signed by the public key in <b>signing_cert</b>.  If <b>check_rsa_1024</b>,
     297             :  * make sure that it has an RSA key with 1024 bits; otherwise, just check that
     298             :  * the key is long enough. Return 1 if the cert is good, and 0 if it's bad or
     299             :  * we couldn't check it. */
     300             : int
     301          39 : tor_tls_cert_is_valid(int severity,
     302             :                       const tor_x509_cert_t *cert,
     303             :                       const tor_x509_cert_t *signing_cert,
     304             :                       time_t now,
     305             :                       int check_rsa_1024)
     306             : {
     307          39 :   check_no_tls_errors();
     308          39 :   EVP_PKEY *cert_key;
     309          39 :   int r, key_ok = 0;
     310             : 
     311          39 :   if (!signing_cert || !cert)
     312           1 :     goto bad;
     313             : 
     314          38 :   EVP_PKEY *signing_key = X509_get_pubkey(signing_cert->cert);
     315          38 :   if (!signing_key)
     316           2 :     goto bad;
     317          36 :   r = X509_verify(cert->cert, signing_key);
     318          36 :   EVP_PKEY_free(signing_key);
     319          36 :   if (r <= 0)
     320           5 :     goto bad;
     321             : 
     322             :   /* okay, the signature checked out right.  Now let's check the check the
     323             :    * lifetime. */
     324          31 :   if (tor_x509_check_cert_lifetime_internal(severity, cert->cert, now,
     325             :                                             TOR_X509_PAST_SLOP,
     326             :                                             TOR_X509_FUTURE_SLOP) < 0)
     327           4 :     goto bad;
     328             : 
     329          27 :   cert_key = X509_get_pubkey(cert->cert);
     330          27 :   if (check_rsa_1024 && cert_key) {
     331          17 :     RSA *rsa = EVP_PKEY_get1_RSA(cert_key);
     332             : #ifdef OPENSSL_1_1_API
     333          17 :     if (rsa && RSA_bits(rsa) == 1024) {
     334             : #else
     335             :     if (rsa && BN_num_bits(rsa->n) == 1024) {
     336             : #endif
     337             :       key_ok = 1;
     338             :     } else {
     339           1 :       log_fn(severity, LD_CRYPTO, "Invalid certificate: Key is not RSA1024.");
     340             :     }
     341             : 
     342          17 :     if (rsa)
     343          16 :       RSA_free(rsa);
     344          10 :   } else if (cert_key) {
     345          10 :     int min_bits = 1024;
     346             : #ifdef EVP_PKEY_EC
     347          10 :     if (EVP_PKEY_base_id(cert_key) == EVP_PKEY_EC)
     348           1 :       min_bits = 128;
     349             : #endif
     350          10 :     if (EVP_PKEY_bits(cert_key) >= min_bits)
     351          10 :       key_ok = 1;
     352             :   }
     353          27 :   EVP_PKEY_free(cert_key);
     354          27 :   if (!key_ok)
     355           1 :     goto bad;
     356             : 
     357             :   /* XXXX compare DNs or anything? */
     358             : 
     359             :   return 1;
     360          13 :  bad:
     361          13 :   tls_log_errors(NULL, LOG_INFO, LD_CRYPTO, "checking a certificate");
     362          13 :   return 0;
     363             : }
     364             : 
     365             : /** Warn that a certificate lifetime extends through a certain range. */
     366             : static void
     367           4 : log_cert_lifetime(int severity, const X509 *cert, const char *problem,
     368             :                   time_t now)
     369             : {
     370           4 :   BIO *bio = NULL;
     371           4 :   BUF_MEM *buf;
     372           4 :   char *s1=NULL, *s2=NULL;
     373           4 :   char mytime[33];
     374           4 :   struct tm tm;
     375           4 :   size_t n;
     376             : 
     377           4 :   if (problem)
     378           4 :     tor_log(severity, LD_GENERAL,
     379             :         "Certificate %s. Either their clock is set wrong, or your clock "
     380             :         "is wrong.",
     381             :            problem);
     382             : 
     383           4 :   if (!(bio = BIO_new(BIO_s_mem()))) {
     384           0 :     log_warn(LD_GENERAL, "Couldn't allocate BIO!"); goto end;
     385             :   }
     386           4 :   if (!(ASN1_TIME_print(bio, X509_get_notBefore_const(cert)))) {
     387           0 :     tls_log_errors(NULL, LOG_WARN, LD_NET, "printing certificate lifetime");
     388           0 :     goto end;
     389             :   }
     390           4 :   BIO_get_mem_ptr(bio, &buf);
     391           4 :   s1 = tor_strndup(buf->data, buf->length);
     392             : 
     393           4 :   (void)BIO_reset(bio);
     394           4 :   if (!(ASN1_TIME_print(bio, X509_get_notAfter_const(cert)))) {
     395           0 :     tls_log_errors(NULL, LOG_WARN, LD_NET, "printing certificate lifetime");
     396           0 :     goto end;
     397             :   }
     398           4 :   BIO_get_mem_ptr(bio, &buf);
     399           4 :   s2 = tor_strndup(buf->data, buf->length);
     400             : 
     401           4 :   n = strftime(mytime, 32, "%b %d %H:%M:%S %Y UTC", tor_gmtime_r(&now, &tm));
     402           4 :   if (n > 0) {
     403           4 :     tor_log(severity, LD_GENERAL,
     404             :         "(certificate lifetime runs from %s through %s. Your time is %s.)",
     405             :         s1,s2,mytime);
     406             :   } else {
     407           0 :     tor_log(severity, LD_GENERAL,
     408             :         "(certificate lifetime runs from %s through %s. "
     409             :         "Couldn't get your time.)",
     410             :         s1, s2);
     411             :   }
     412             : 
     413           4 :  end:
     414             :   /* Not expected to get invoked */
     415           4 :   tls_log_errors(NULL, LOG_WARN, LD_NET, "getting certificate lifetime");
     416           4 :   if (bio)
     417           4 :     BIO_free(bio);
     418           4 :   tor_free(s1);
     419           4 :   tor_free(s2);
     420           4 : }
     421             : 
     422             : /** Helper: check whether <b>cert</b> is expired give or take
     423             :  * <b>past_tolerance</b> seconds, or not-yet-valid give or take
     424             :  * <b>future_tolerance</b> seconds.  (Relative to the current time
     425             :  * <b>now</b>.)  If it is live, return 0.  If it is not live, log a message
     426             :  * and return -1. */
     427             : int
     428          31 : tor_x509_check_cert_lifetime_internal(int severity, const X509 *cert,
     429             :                                       time_t now,
     430             :                                       int past_tolerance, int future_tolerance)
     431             : {
     432          31 :   time_t t;
     433             : 
     434          31 :   t = now + future_tolerance;
     435          31 :   if (X509_cmp_time(X509_get_notBefore_const(cert), &t) > 0) {
     436           1 :     log_cert_lifetime(severity, cert, "not yet valid", now);
     437           1 :     return -1;
     438             :   }
     439          30 :   t = now - past_tolerance;
     440          30 :   if (X509_cmp_time(X509_get_notAfter_const(cert), &t) < 0) {
     441           3 :     log_cert_lifetime(severity, cert, "already expired", now);
     442           3 :     return -1;
     443             :   }
     444             : 
     445             :   return 0;
     446             : }
     447             : 
     448             : #ifdef TOR_UNIT_TESTS
     449             : /* Testing only: return a new x509 cert with the same contents as <b>inp</b>,
     450             :    but with the expiration time <b>new_expiration_time</b>, signed with
     451             :    <b>signing_key</b>. */
     452             : STATIC tor_x509_cert_t *
     453           3 : tor_x509_cert_replace_expiration(const tor_x509_cert_t *inp,
     454             :                                  time_t new_expiration_time,
     455             :                                  crypto_pk_t *signing_key)
     456             : {
     457           3 :   X509 *newc = X509_dup(inp->cert);
     458           3 :   X509_time_adj(X509_get_notAfter(newc), 0, &new_expiration_time);
     459           3 :   EVP_PKEY *pk = crypto_pk_get_openssl_evp_pkey_(signing_key, 1);
     460           3 :   tor_assert(X509_sign(newc, pk, EVP_sha256()));
     461           3 :   EVP_PKEY_free(pk);
     462           3 :   return tor_x509_cert_new(newc);
     463             : }
     464             : #endif /* defined(TOR_UNIT_TESTS) */

Generated by: LCOV version 1.14