/** * ssl_setup - Set up SSL on the Connection * @param conn Connection * @retval 0 Success * @retval -1 Failure */ static int ssl_setup(struct Connection *conn) { struct SslSockData *ssldata = NULL; int maxbits; ssldata = mutt_mem_calloc(1, sizeof(struct SslSockData)); conn->sockdata = ssldata; ssldata->sctx = SSL_CTX_new(SSLv23_client_method()); if (!ssldata->sctx) { /* L10N: an SSL context is a data structure returned by the OpenSSL function SSL_CTX_new(). In this case it returned NULL: an error condition. */ mutt_error(_("Unable to create SSL context")); ssl_dprint_err_stack(); goto free_sasldata; } /* disable SSL protocols as needed */ #ifdef SSL_OP_NO_TLSv1_2 if (!C_SslUseTlsv12) SSL_CTX_set_options(ssldata->sctx, SSL_OP_NO_TLSv1_2); #endif #ifdef SSL_OP_NO_TLSv1_1 if (!C_SslUseTlsv11) SSL_CTX_set_options(ssldata->sctx, SSL_OP_NO_TLSv1_1); #endif #ifdef SSL_OP_NO_TLSv1 if (!C_SslUseTlsv1) SSL_CTX_set_options(ssldata->sctx, SSL_OP_NO_TLSv1); #endif if (!C_SslUseSslv3) SSL_CTX_set_options(ssldata->sctx, SSL_OP_NO_SSLv3); if (!C_SslUseSslv2) SSL_CTX_set_options(ssldata->sctx, SSL_OP_NO_SSLv2); if (C_SslUsesystemcerts) { if (!SSL_CTX_set_default_verify_paths(ssldata->sctx)) { mutt_debug(LL_DEBUG1, "Error setting default verify paths\n"); goto free_ctx; } } if (C_CertificateFile && !ssl_load_certificates(ssldata->sctx)) mutt_debug(LL_DEBUG1, "Error loading trusted certificates\n"); ssl_get_client_cert(ssldata, conn); if (C_SslCiphers) { SSL_CTX_set_cipher_list(ssldata->sctx, C_SslCiphers); } if (ssl_set_verify_partial(ssldata->sctx)) { mutt_error(_("Warning: error enabling ssl_verify_partial_chains")); } ssldata->ssl = SSL_new(ssldata->sctx); SSL_set_fd(ssldata->ssl, conn->fd); if (ssl_negotiate(conn, ssldata)) goto free_ssl; ssldata->isopen = 1; conn->ssf = SSL_CIPHER_get_bits(SSL_get_current_cipher(ssldata->ssl), &maxbits); return 0; free_ssl: SSL_free(ssldata->ssl); ssldata->ssl = 0; free_ctx: SSL_CTX_free(ssldata->sctx); ssldata->sctx = 0; free_sasldata: FREE(&ssldata); return -1; }
static int ssl_socket_open (CONNECTION * conn) { sslsockdata *data; int maxbits; if (raw_socket_open (conn) < 0) return -1; data = (sslsockdata *) safe_calloc (1, sizeof (sslsockdata)); conn->sockdata = data; if (! (data->ctx = SSL_CTX_new (SSLv23_client_method ()))) { /* L10N: an SSL context is a data structure returned by the OpenSSL * function SSL_CTX_new(). In this case it returned NULL: an * error condition. */ mutt_error (_("Unable to create SSL context")); ssl_dprint_err_stack (); mutt_socket_close (conn); return -1; } /* disable SSL protocols as needed */ if (!option(OPTTLSV1)) { SSL_CTX_set_options(data->ctx, SSL_OP_NO_TLSv1); } /* TLSv1.1/1.2 support was added in OpenSSL 1.0.1, but some OS distros such * as Fedora 17 are on OpenSSL 1.0.0. */ #ifdef SSL_OP_NO_TLSv1_1 if (!option(OPTTLSV1_1)) { SSL_CTX_set_options(data->ctx, SSL_OP_NO_TLSv1_1); } #endif #ifdef SSL_OP_NO_TLSv1_2 if (!option(OPTTLSV1_2)) { SSL_CTX_set_options(data->ctx, SSL_OP_NO_TLSv1_2); } #endif if (!option(OPTSSLV2)) { SSL_CTX_set_options(data->ctx, SSL_OP_NO_SSLv2); } if (!option(OPTSSLV3)) { SSL_CTX_set_options(data->ctx, SSL_OP_NO_SSLv3); } ssl_get_client_cert(data, conn); if (SslCiphers) { SSL_CTX_set_cipher_list (data->ctx, SslCiphers); } data->ssl = SSL_new (data->ctx); SSL_set_fd (data->ssl, conn->fd); if (ssl_negotiate(conn, data)) { mutt_socket_close (conn); return -1; } data->isopen = 1; conn->ssf = SSL_CIPHER_get_bits (SSL_get_current_cipher (data->ssl), &maxbits); return 0; }