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 }