void tls_init(void) { ONCE_INIT(tls_init_once); }
static int tls_init_context(tls_t *tls, tls_issues_t const *ti) { int verify; static int random_loaded; ONCE_INIT(tls_init_once); if (!random_loaded) { random_loaded = 1; if (ti->randFile && !RAND_load_file(ti->randFile, 1024 * 1024)) { if (ti->configured > 1) { SU_DEBUG_3(("%s: cannot open randFile %s\n", "tls_init_context", ti->randFile)); tls_log_errors(3, "tls_init_context", 0); } /* errno = EIO; */ /* return -1; */ } } #if HAVE_SIGPIPE /* Avoid possible SIGPIPE when sending close_notify */ signal(SIGPIPE, SIG_IGN); #endif if (tls->ctx == NULL) if (!(tls->ctx = SSL_CTX_new((SSL_METHOD*)SSLv23_method()))) { tls_log_errors(1, "SSL_CTX_new() failed", 0); errno = EIO; return -1; } if (!(ti->version & TPTLS_VERSION_SSLv2)) SSL_CTX_set_options(tls->ctx, SSL_OP_NO_SSLv2); if (!(ti->version & TPTLS_VERSION_SSLv3)) SSL_CTX_set_options(tls->ctx, SSL_OP_NO_SSLv3); if (!(ti->version & TPTLS_VERSION_TLSv1)) SSL_CTX_set_options(tls->ctx, SSL_OP_NO_TLSv1); if (!(ti->version & TPTLS_VERSION_TLSv1_1)) SSL_CTX_set_options(tls->ctx, SSL_OP_NO_TLSv1_1); if (!(ti->version & TPTLS_VERSION_TLSv1_2)) SSL_CTX_set_options(tls->ctx, SSL_OP_NO_TLSv1_2); SSL_CTX_sess_set_remove_cb(tls->ctx, NULL); SSL_CTX_set_timeout(tls->ctx, ti->timeout); /* Set callback if we have a passphrase */ if (ti->passphrase != NULL) { SSL_CTX_set_default_passwd_cb(tls->ctx, passwd_cb); SSL_CTX_set_default_passwd_cb_userdata(tls->ctx, (void *)ti); } if (!SSL_CTX_use_certificate_file(tls->ctx, ti->cert, SSL_FILETYPE_PEM)) { if (ti->configured > 0) { SU_DEBUG_1(("%s: invalid local certificate: %s\n", "tls_init_context", ti->cert)); tls_log_errors(3, "tls_init_context", 0); #if require_client_certificate errno = EIO; return -1; #endif } } if (!SSL_CTX_use_PrivateKey_file(tls->ctx, ti->key, SSL_FILETYPE_PEM)) { if (ti->configured > 0) { SU_DEBUG_1(("%s: invalid private key: %s\n", "tls_init_context", ti->key)); tls_log_errors(3, "tls_init_context(key)", 0); #if require_client_certificate errno = EIO; return -1; #endif } } if (!SSL_CTX_check_private_key(tls->ctx)) { if (ti->configured > 0) { SU_DEBUG_1(("%s: private key does not match the certificate public key\n", "tls_init_context")); } #if require_client_certificate errno = EIO; return -1; #endif } if (!SSL_CTX_load_verify_locations(tls->ctx, ti->CAfile, ti->CApath)) { SU_DEBUG_1(("%s: error loading CA list: %s\n", "tls_init_context", ti->CAfile)); if (ti->configured > 0) tls_log_errors(3, "tls_init_context(CA)", 0); errno = EIO; return -1; } /* corresponds to (enum tport_tls_verify_policy) */ tls->verify_incoming = (ti->policy & 0x1) ? 1 : 0; tls->verify_outgoing = (ti->policy & 0x2) ? 1 : 0; tls->verify_subj_in = (ti->policy & 0x4) ? tls->verify_incoming : 0; tls->verify_subj_out = (ti->policy & 0x8) ? tls->verify_outgoing : 0; tls->verify_date = (ti->verify_date) ? 1 : 0; if (tls->verify_incoming) verify = SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT; else verify = SSL_VERIFY_NONE; SSL_CTX_set_verify_depth(tls->ctx, ti->verify_depth); SSL_CTX_set_verify(tls->ctx, verify, tls_verify_cb); if (tls_init_ecdh_curve(tls) == 0) { SU_DEBUG_3(("%s\n", "tls: initialized ECDH")); } else { SU_DEBUG_3(("%s\n", "tls: failed to initialize ECDH")); } if (!SSL_CTX_set_cipher_list(tls->ctx, ti->ciphers)) { SU_DEBUG_1(("%s: error setting cipher list\n", "tls_init_context")); tls_log_errors(3, "tls_init_context", 0); errno = EIO; return -1; } return 0; }
static int tls_init_context(tls_t *tls, tls_issues_t const *ti) { int verify; static int random_loaded; ONCE_INIT(tls_init_once); if (!random_loaded) { random_loaded = 1; if (ti->randFile && !RAND_load_file(ti->randFile, 1024 * 1024)) { if (ti->configured > 1) { SU_DEBUG_3(("%s: cannot open randFile %s\n", "tls_init_context", ti->randFile)); tls_log_errors(3, "tls_init_context", 0); } /* errno = EIO; */ /* return -1; */ } } #if HAVE_SIGPIPE /* Avoid possible SIGPIPE when sending close_notify */ signal(SIGPIPE, SIG_IGN); #endif if (tls->ctx == NULL) { const SSL_METHOD *meth; /* meth = SSLv3_method(); */ /* meth = SSLv23_method(); */ if (ti->version) meth = TLSv1_method(); else meth = SSLv23_method(); tls->ctx = SSL_CTX_new((SSL_METHOD*)meth); } if (tls->ctx == NULL) { tls_log_errors(1, "tls_init_context", 0); errno = EIO; return -1; } if (!SSL_CTX_use_certificate_file(tls->ctx, ti->cert, SSL_FILETYPE_PEM)) { if (ti->configured > 0) { SU_DEBUG_1(("%s: invalid local certificate: %s\n", "tls_init_context", ti->cert)); tls_log_errors(3, "tls_init_context", 0); #if require_client_certificate errno = EIO; return -1; #endif } } if (!SSL_CTX_use_PrivateKey_file(tls->ctx, ti->key, SSL_FILETYPE_PEM)) { if (ti->configured > 0) { SU_DEBUG_1(("%s: invalid private key: %s\n", "tls_init_context", ti->key)); tls_log_errors(3, "tls_init_context(key)", 0); #if require_client_certificate errno = EIO; return -1; #endif } } if (!SSL_CTX_check_private_key(tls->ctx)) { if (ti->configured > 0) { SU_DEBUG_1(("%s: private key does not match the certificate public key\n", "tls_init_context")); } #if require_client_certificate errno = EIO; return -1; #endif } if (!SSL_CTX_load_verify_locations(tls->ctx, ti->CAfile, ti->CApath)) { SU_DEBUG_1(("%s: error loading CA list: %s\n", "tls_init_context", ti->CAfile)); if (ti->configured > 0) tls_log_errors(3, "tls_init_context(CA)", 0); errno = EIO; return -1; } /* corresponds to (enum tport_tls_verify_policy) */ tls->verify_incoming = (ti->policy & 0x1) ? 1 : 0; tls->verify_outgoing = (ti->policy & 0x2) ? 1 : 0; tls->verify_subj_in = (ti->policy & 0x4) ? tls->verify_incoming : 0; tls->verify_subj_out = (ti->policy & 0x8) ? tls->verify_outgoing : 0; tls->verify_date = (ti->verify_date) ? 1 : 0; if (tls->verify_incoming) verify = SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT; else verify = SSL_VERIFY_NONE; SSL_CTX_set_verify_depth(tls->ctx, ti->verify_depth); SSL_CTX_set_verify(tls->ctx, verify, tls_verify_cb); if (!SSL_CTX_set_cipher_list(tls->ctx, ti->cipher)) { SU_DEBUG_1(("%s: error setting cipher list\n", "tls_init_context")); tls_log_errors(3, "tls_init_context", 0); errno = EIO; return -1; } return 0; }