tor

The Tor anonymity network
git clone https://git.dasho.dev/tor.git
Log | Files | Refs | README | LICENSE

crypto_nss_mgt.c (3078B)


      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_nss_mgt.c
      9 *
     10 * \brief Manage the NSS library (if used)
     11 **/
     12 
     13 #include "lib/crypt_ops/crypto_nss_mgt.h"
     14 
     15 #include "lib/log/log.h"
     16 #include "lib/log/util_bug.h"
     17 #include "lib/string/printf.h"
     18 
     19 DISABLE_GCC_WARNING("-Wredundant-decls")
     20 DISABLE_GCC_WARNING("-Wstrict-prototypes")
     21 #include <nss.h>
     22 #include <pk11func.h>
     23 #include <ssl.h>
     24 
     25 #include <prerror.h>
     26 #include <prtypes.h>
     27 #include <prinit.h>
     28 ENABLE_GCC_WARNING("-Wstrict-prototypes")
     29 ENABLE_GCC_WARNING("-Wredundant-decls")
     30 
     31 const char *
     32 crypto_nss_get_version_str(void)
     33 {
     34  return NSS_GetVersion();
     35 }
     36 const char *
     37 crypto_nss_get_header_version_str(void)
     38 {
     39  return NSS_VERSION;
     40 }
     41 
     42 /** A password function that always returns NULL. */
     43 static char *
     44 nss_password_func_always_fail(PK11SlotInfo *slot,
     45                              PRBool retry,
     46                              void *arg)
     47 {
     48  (void) slot;
     49  (void) retry;
     50  (void) arg;
     51  return NULL;
     52 }
     53 
     54 void
     55 crypto_nss_early_init(int nss_only)
     56 {
     57  if (! nss_only) {
     58    PR_Init(PR_USER_THREAD, PR_PRIORITY_NORMAL, 0);
     59    PK11_SetPasswordFunc(nss_password_func_always_fail);
     60  }
     61 
     62  /* Eventually we should use NSS_Init() instead -- but that wants a
     63     directory. The documentation says that we can't use this if we want
     64     to use OpenSSL. */
     65  if (NSS_NoDB_Init(NULL) == SECFailure) {
     66    log_err(LD_CRYPTO, "Unable to initialize NSS.");
     67    crypto_nss_log_errors(LOG_ERR, "initializing NSS");
     68    tor_assert_unreached();
     69  }
     70 
     71  if (NSS_SetDomesticPolicy() == SECFailure) {
     72    log_err(LD_CRYPTO, "Unable to set NSS cipher policy.");
     73    crypto_nss_log_errors(LOG_ERR, "setting cipher policy");
     74    tor_assert_unreached();
     75  }
     76 
     77  /* We need to override the default here, or NSS will reject all the
     78   * legacy Tor certificates. */
     79  SECStatus rv = NSS_OptionSet(NSS_RSA_MIN_KEY_SIZE, 1024);
     80  if (rv != SECSuccess) {
     81    log_err(LD_CRYPTO, "Unable to set NSS min RSA key size");
     82    crypto_nss_log_errors(LOG_ERR, "setting cipher option.");
     83    tor_assert_unreached();
     84  }
     85 }
     86 
     87 void
     88 crypto_nss_log_errors(int severity, const char *doing)
     89 {
     90  PRErrorCode code = PR_GetError();
     91  const char *string = PORT_ErrorToString(code);
     92  const char *name = PORT_ErrorToName(code);
     93  char buf[16];
     94  if (!string)
     95    string = "<unrecognized>";
     96  if (!name) {
     97    tor_snprintf(buf, sizeof(buf), "%d", code);
     98    name = buf;
     99  }
    100  if (doing) {
    101    tor_log(severity, LD_CRYPTO, "NSS error %s while %s: %s",
    102            name, doing, string);
    103  } else {
    104    tor_log(severity, LD_CRYPTO, "NSS error %s: %s", name, string);
    105  }
    106 }
    107 
    108 int
    109 crypto_nss_late_init(void)
    110 {
    111  /* Possibly, SSL_OptionSetDefault? */
    112 
    113  return 0;
    114 }
    115 
    116 void
    117 crypto_nss_global_cleanup(void)
    118 {
    119  NSS_Shutdown();
    120  PL_ArenaFinish();
    121  PR_Cleanup();
    122 }
    123 
    124 void
    125 crypto_nss_prefork(void)
    126 {
    127  NSS_Shutdown();
    128 }
    129 
    130 void
    131 crypto_nss_postfork(void)
    132 {
    133  crypto_nss_early_init(1);
    134 }