tortls.c (11603B)
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 tortls.c 8 * @brief Shared functionality for our TLS backends. 9 **/ 10 11 #define TORTLS_PRIVATE 12 #define TOR_X509_PRIVATE 13 #include "lib/tls/x509.h" 14 #include "lib/tls/x509_internal.h" 15 #include "lib/tls/tortls_sys.h" 16 #include "lib/tls/tortls.h" 17 #include "lib/tls/tortls_st.h" 18 #include "lib/tls/tortls_internal.h" 19 #include "lib/log/util_bug.h" 20 #include "lib/intmath/cmp.h" 21 #include "lib/crypt_ops/crypto_rsa.h" 22 #include "lib/crypt_ops/crypto_rand.h" 23 #include "lib/net/socket.h" 24 #include "lib/subsys/subsys.h" 25 26 #ifdef _WIN32 27 #include <winsock2.h> 28 #include <ws2tcpip.h> 29 #endif 30 31 #include <time.h> 32 33 /** Global TLS contexts. We keep them here because nobody else needs 34 * to touch them. 35 * 36 * @{ */ 37 STATIC tor_tls_context_t *server_tls_context = NULL; 38 STATIC tor_tls_context_t *client_tls_context = NULL; 39 /**@}*/ 40 41 /** 42 * Return the appropriate TLS context. 43 */ 44 tor_tls_context_t * 45 tor_tls_context_get(int is_server) 46 { 47 return is_server ? server_tls_context : client_tls_context; 48 } 49 50 /** Convert an errno (or a WSAerrno on windows) into a TOR_TLS_* error 51 * code. */ 52 int 53 tor_errno_to_tls_error(int e) 54 { 55 switch (e) { 56 case SOCK_ERRNO(ECONNRESET): // most common 57 return TOR_TLS_ERROR_CONNRESET; 58 case SOCK_ERRNO(ETIMEDOUT): 59 return TOR_TLS_ERROR_TIMEOUT; 60 case SOCK_ERRNO(EHOSTUNREACH): 61 case SOCK_ERRNO(ENETUNREACH): 62 return TOR_TLS_ERROR_NO_ROUTE; 63 case SOCK_ERRNO(ECONNREFUSED): 64 return TOR_TLS_ERROR_CONNREFUSED; // least common 65 default: 66 return TOR_TLS_ERROR_MISC; 67 } 68 } 69 70 /** Set *<b>link_cert_out</b> and *<b>id_cert_out</b> to the link certificate 71 * and ID certificate that we're currently using for our V3 in-protocol 72 * handshake's certificate chain. If <b>server</b> is true, provide the certs 73 * that we use in server mode (auth, ID); otherwise, provide the certs that we 74 * use in client mode. (link, ID) */ 75 int 76 tor_tls_get_my_certs(int server, 77 const tor_x509_cert_t **link_cert_out, 78 const tor_x509_cert_t **id_cert_out) 79 { 80 tor_tls_context_t *ctx = tor_tls_context_get(server); 81 int rv = -1; 82 const tor_x509_cert_t *link_cert = NULL; 83 const tor_x509_cert_t *id_cert = NULL; 84 if (ctx) { 85 rv = 0; 86 link_cert = server ? ctx->my_link_cert : ctx->my_auth_cert; 87 id_cert = ctx->my_id_cert; 88 } 89 if (link_cert_out) 90 *link_cert_out = link_cert; 91 if (id_cert_out) 92 *id_cert_out = id_cert; 93 return rv; 94 } 95 96 /** Increase the reference count of <b>ctx</b>. */ 97 void 98 tor_tls_context_incref(tor_tls_context_t *ctx) 99 { 100 ++ctx->refcnt; 101 } 102 103 /** Remove a reference to <b>ctx</b>, and free it if it has no more 104 * references. */ 105 void 106 tor_tls_context_decref(tor_tls_context_t *ctx) 107 { 108 tor_assert(ctx); 109 if (--ctx->refcnt == 0) { 110 tor_tls_context_impl_free(ctx->ctx); 111 tor_x509_cert_free(ctx->my_link_cert); 112 tor_x509_cert_free(ctx->my_id_cert); 113 tor_x509_cert_free(ctx->my_auth_cert); 114 crypto_pk_free(ctx->link_key); 115 crypto_pk_free(ctx->auth_key); 116 /* LCOV_EXCL_BR_START since ctx will never be NULL here */ 117 tor_free(ctx); 118 /* LCOV_EXCL_BR_STOP */ 119 } 120 } 121 122 /** Free all global TLS structures. */ 123 void 124 tor_tls_free_all(void) 125 { 126 check_no_tls_errors(); 127 128 if (server_tls_context) { 129 tor_tls_context_t *ctx = server_tls_context; 130 server_tls_context = NULL; 131 tor_tls_context_decref(ctx); 132 } 133 if (client_tls_context) { 134 tor_tls_context_t *ctx = client_tls_context; 135 client_tls_context = NULL; 136 tor_tls_context_decref(ctx); 137 } 138 } 139 140 /** Given a TOR_TLS_* error code, return a string equivalent. */ 141 const char * 142 tor_tls_err_to_string(int err) 143 { 144 if (err >= 0) 145 return "[Not an error.]"; 146 switch (err) { 147 case TOR_TLS_ERROR_MISC: return "misc error"; 148 case TOR_TLS_ERROR_IO: return "unexpected close"; 149 case TOR_TLS_ERROR_CONNREFUSED: return "connection refused"; 150 case TOR_TLS_ERROR_CONNRESET: return "connection reset"; 151 case TOR_TLS_ERROR_NO_ROUTE: return "host unreachable"; 152 case TOR_TLS_ERROR_TIMEOUT: return "connection timed out"; 153 case TOR_TLS_CLOSE: return "closed"; 154 case TOR_TLS_WANTREAD: return "want to read"; 155 case TOR_TLS_WANTWRITE: return "want to write"; 156 default: return "(unknown error code)"; 157 } 158 } 159 160 /** Create new global client and server TLS contexts. 161 * 162 * If <b>server_identity</b> is NULL, this will not generate a server 163 * TLS context. If TOR_TLS_CTX_IS_PUBLIC_SERVER is set in <b>flags</b>, use 164 * the same TLS context for incoming and outgoing connections, and 165 * ignore <b>client_identity</b>. 166 */ 167 int 168 tor_tls_context_init(unsigned flags, 169 crypto_pk_t *client_identity, 170 crypto_pk_t *server_identity, 171 unsigned int key_lifetime) 172 { 173 int rv1 = 0; 174 int rv2 = 0; 175 const int is_public_server = flags & TOR_TLS_CTX_IS_PUBLIC_SERVER; 176 check_no_tls_errors(); 177 178 if (is_public_server) { 179 tor_tls_context_t *new_ctx; 180 tor_tls_context_t *old_ctx; 181 182 tor_assert(server_identity != NULL); 183 184 rv1 = tor_tls_context_init_one(&server_tls_context, 185 server_identity, 186 key_lifetime, flags, 0); 187 188 if (rv1 >= 0) { 189 new_ctx = server_tls_context; 190 tor_tls_context_incref(new_ctx); 191 old_ctx = client_tls_context; 192 client_tls_context = new_ctx; 193 194 if (old_ctx != NULL) { 195 tor_tls_context_decref(old_ctx); 196 } 197 } else { 198 tls_log_errors(NULL, LOG_WARN, LD_CRYPTO, 199 "constructing a TLS context"); 200 } 201 } else { 202 if (server_identity != NULL) { 203 rv1 = tor_tls_context_init_one(&server_tls_context, 204 server_identity, 205 key_lifetime, 206 flags, 207 0); 208 if (rv1 < 0) 209 tls_log_errors(NULL, LOG_WARN, LD_CRYPTO, 210 "constructing a server TLS context"); 211 } else { 212 tor_tls_context_t *old_ctx = server_tls_context; 213 server_tls_context = NULL; 214 215 if (old_ctx != NULL) { 216 tor_tls_context_decref(old_ctx); 217 } 218 } 219 220 rv2 = tor_tls_context_init_one(&client_tls_context, 221 client_identity, 222 key_lifetime, 223 flags, 224 1); 225 if (rv2 < 0) 226 tls_log_errors(NULL, LOG_WARN, LD_CRYPTO, 227 "constructing a client TLS context"); 228 } 229 230 return MIN(rv1, rv2); 231 } 232 233 /** Create a new global TLS context. 234 * 235 * You can call this function multiple times. Each time you call it, 236 * it generates new certificates; all new connections will use 237 * the new SSL context. 238 */ 239 int 240 tor_tls_context_init_one(tor_tls_context_t **ppcontext, 241 crypto_pk_t *identity, 242 unsigned int key_lifetime, 243 unsigned int flags, 244 int is_client) 245 { 246 tor_tls_context_t *new_ctx = tor_tls_context_new(identity, 247 key_lifetime, 248 flags, 249 is_client); 250 tor_tls_context_t *old_ctx = *ppcontext; 251 252 if (new_ctx != NULL) { 253 *ppcontext = new_ctx; 254 255 /* Free the old context if one existed. */ 256 if (old_ctx != NULL) { 257 /* This is safe even if there are open connections: we reference- 258 * count tor_tls_context_t objects. */ 259 tor_tls_context_decref(old_ctx); 260 } 261 } 262 263 return ((new_ctx != NULL) ? 0 : -1); 264 } 265 266 /** Size of the RSA key to use for our TLS link keys */ 267 #define RSA_LINK_KEY_BITS 2048 268 269 /** How long do identity certificates live? (sec) */ 270 #define IDENTITY_CERT_LIFETIME (365*24*60*60) 271 272 /** 273 * Initialize the certificates and keys for a TLS context <b>result</b> 274 * 275 * Other arguments as for tor_tls_context_new(). 276 */ 277 int 278 tor_tls_context_init_certificates(tor_tls_context_t *result, 279 crypto_pk_t *identity, 280 unsigned key_lifetime, 281 unsigned flags) 282 { 283 (void)flags; 284 int rv = -1; 285 char *nickname = NULL, *nn2 = NULL; 286 crypto_pk_t *rsa = NULL, *rsa_auth = NULL; 287 tor_x509_cert_impl_t *cert = NULL, *idcert = NULL, *authcert = NULL; 288 289 nickname = crypto_random_hostname(8, 20, "www.", ".net"); 290 291 #ifdef DISABLE_V3_LINKPROTO_SERVERSIDE 292 nn2 = crypto_random_hostname(8, 20, "www.", ".net"); 293 #else 294 nn2 = crypto_random_hostname(8, 20, "www.", ".com"); 295 #endif 296 297 /* Generate short-term RSA key for use with TLS. */ 298 if (!(rsa = crypto_pk_new())) 299 goto error; 300 if (crypto_pk_generate_key_with_bits(rsa, RSA_LINK_KEY_BITS)<0) 301 goto error; 302 303 /* Generate short-term RSA key for use in the in-protocol ("v3") 304 * authentication handshake. */ 305 if (!(rsa_auth = crypto_pk_new())) 306 goto error; 307 if (crypto_pk_generate_key(rsa_auth)<0) 308 goto error; 309 310 /* Create a link certificate signed by identity key. */ 311 cert = tor_tls_create_certificate(rsa, identity, nickname, nn2, 312 key_lifetime); 313 /* Create self-signed certificate for identity key. */ 314 idcert = tor_tls_create_certificate(identity, identity, nn2, nn2, 315 IDENTITY_CERT_LIFETIME); 316 /* Create an authentication certificate signed by identity key. */ 317 authcert = tor_tls_create_certificate(rsa_auth, identity, nickname, nn2, 318 key_lifetime); 319 if (!cert || !idcert || !authcert) { 320 log_warn(LD_CRYPTO, "Error creating certificate"); 321 goto error; 322 } 323 324 result->my_link_cert = tor_x509_cert_new(cert); 325 cert = NULL; 326 result->my_id_cert = tor_x509_cert_new(idcert); 327 idcert = NULL; 328 result->my_auth_cert = tor_x509_cert_new(authcert); 329 authcert = NULL; 330 if (!result->my_link_cert || !result->my_id_cert || !result->my_auth_cert) 331 goto error; 332 result->link_key = rsa; 333 rsa = NULL; 334 result->auth_key = rsa_auth; 335 rsa_auth = NULL; 336 337 rv = 0; 338 error: 339 340 tor_free(nickname); 341 tor_free(nn2); 342 343 tor_x509_cert_impl_free(cert); 344 tor_x509_cert_impl_free(idcert); 345 tor_x509_cert_impl_free(authcert); 346 crypto_pk_free(rsa); 347 crypto_pk_free(rsa_auth); 348 349 return rv; 350 } 351 /** Make future log messages about <b>tls</b> display the address 352 * <b>address</b>. 353 */ 354 void 355 tor_tls_set_logged_address(tor_tls_t *tls, const char *address) 356 { 357 tor_assert(tls); 358 tor_free(tls->address); 359 tls->address = tor_strdup(address); 360 } 361 362 /** Return whether this tls initiated the connect (client) or 363 * received it (server). */ 364 int 365 tor_tls_is_server(tor_tls_t *tls) 366 { 367 tor_assert(tls); 368 return tls->isServer; 369 } 370 371 /** Release resources associated with a TLS object. Does not close the 372 * underlying file descriptor. 373 */ 374 void 375 tor_tls_free_(tor_tls_t *tls) 376 { 377 if (!tls) 378 return; 379 tor_assert(tls->ssl); 380 { 381 size_t r,w; 382 tor_tls_get_n_raw_bytes(tls,&r,&w); /* ensure written_by_tls is updated */ 383 } 384 tor_tls_impl_free(tls->ssl); 385 tls->ssl = NULL; 386 #ifdef ENABLE_OPENSSL 387 tls->negotiated_callback = NULL; 388 #endif 389 if (tls->context) 390 tor_tls_context_decref(tls->context); 391 tor_free(tls->address); 392 tls->magic = 0x99999999; 393 tor_free(tls); 394 } 395 396 static void 397 subsys_tortls_shutdown(void) 398 { 399 tor_tls_free_all(); 400 } 401 402 const subsys_fns_t sys_tortls = { 403 .name = "tortls", 404 SUBSYS_DECLARE_LOCATION(), 405 .level = -50, 406 .shutdown = subsys_tortls_shutdown 407 };