summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCarlos Martín Nieto <carlosmn@github.com>2016-03-14 15:29:30 +0100
committerCarlos Martín Nieto <carlosmn@github.com>2016-03-14 15:29:30 +0100
commitff5a39678b77d1ccb65119314ee518b019add7aa (patch)
treed91b32ab090bb9cbfc3b230ef951e2d3e8efa20c
parent1ddada422caf8e72ba97dca2568d2bf879fed5f2 (diff)
parentc577efbbb5565d078a08eae211cfb04987199809 (diff)
downloadlibgit2-ff5a39678b77d1ccb65119314ee518b019add7aa.tar.gz
Merge pull request #3683 from dbussink/dbussink/better-openssl-ciphers
Setup better defaults for OpenSSL ciphers
-rw-r--r--include/git2/common.h6
-rw-r--r--src/global.c2
-rw-r--r--src/global.h1
-rw-r--r--src/openssl_stream.c13
-rw-r--r--src/settings.c24
-rw-r--r--tests/online/badssl.c8
6 files changed, 53 insertions, 1 deletions
diff --git a/include/git2/common.h b/include/git2/common.h
index c1efee320..0629abb7f 100644
--- a/include/git2/common.h
+++ b/include/git2/common.h
@@ -149,6 +149,7 @@ typedef enum {
GIT_OPT_SET_SSL_CERT_LOCATIONS,
GIT_OPT_SET_USER_AGENT,
GIT_OPT_ENABLE_STRICT_OBJECT_CREATION,
+ GIT_OPT_SET_SSL_CIPHERS,
} git_libgit2_opt_t;
/**
@@ -260,6 +261,11 @@ typedef enum {
* > example, when this is enabled, the parent(s) and tree inputs
* > will be validated when creating a new commit. This defaults
* > to disabled.
+ * * opts(GIT_OPT_SET_SSL_CIPHERS, const char *ciphers)
+ *
+ * > Set the SSL ciphers use for HTTPS connections.
+ * >
+ * > - `ciphers` is the list of ciphers that are eanbled.
*
* @param option Option key
* @param ... value to set the option
diff --git a/src/global.c b/src/global.c
index 0bfde1e04..c725b5184 100644
--- a/src/global.c
+++ b/src/global.c
@@ -27,6 +27,7 @@ static git_global_shutdown_fn git__shutdown_callbacks[MAX_SHUTDOWN_CB];
static git_atomic git__n_shutdown_callbacks;
static git_atomic git__n_inits;
char *git__user_agent;
+char *git__ssl_ciphers;
void git__on_shutdown(git_global_shutdown_fn callback)
{
@@ -83,6 +84,7 @@ static void shutdown_common(void)
}
git__free(git__user_agent);
+ git__free(git__ssl_ciphers);
#if defined(GIT_MSVC_CRTDBG)
git_win32__crtdbg_stacktrace_cleanup();
diff --git a/src/global.h b/src/global.h
index 9fdcee573..219951525 100644
--- a/src/global.h
+++ b/src/global.h
@@ -36,5 +36,6 @@ extern void git__on_shutdown(git_global_shutdown_fn callback);
extern void git__free_tls_data(void);
extern const char *git_libgit2__user_agent(void);
+extern const char *git_libgit2__ssl_ciphers(void);
#endif
diff --git a/src/openssl_stream.c b/src/openssl_stream.c
index 97736b714..a65f5586e 100644
--- a/src/openssl_stream.c
+++ b/src/openssl_stream.c
@@ -34,6 +34,8 @@
SSL_CTX *git__ssl_ctx;
+#define GIT_SSL_DEFAULT_CIPHERS "ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-DSS-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:DHE-DSS-AES256-GCM-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA:ECDHE-RSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES256-SHA256:DHE-RSA-AES128-SHA:DHE-RSA-AES256-SHA:DHE-DSS-AES128-SHA256:DHE-DSS-AES256-SHA256:DHE-DSS-AES128-SHA:DHE-DSS-AES256-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA"
+
#ifdef GIT_THREADS
static git_mutex *openssl_locks;
@@ -85,6 +87,7 @@ int git_openssl_stream_global_init(void)
{
#ifdef GIT_OPENSSL
long ssl_opts = SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3;
+ const char *ciphers = git_libgit2__ssl_ciphers();
/* Older OpenSSL and MacOS OpenSSL doesn't have this */
#ifdef SSL_OP_NO_COMPRESSION
@@ -108,6 +111,16 @@ int git_openssl_stream_global_init(void)
git__ssl_ctx = NULL;
return -1;
}
+
+ if (!ciphers) {
+ ciphers = GIT_SSL_DEFAULT_CIPHERS;
+ }
+
+ if(!SSL_CTX_set_cipher_list(git__ssl_ctx, ciphers)) {
+ SSL_CTX_free(git__ssl_ctx);
+ git__ssl_ctx = NULL;
+ return -1;
+ }
#endif
git__on_shutdown(shutdown_ssl);
diff --git a/src/settings.c b/src/settings.c
index 88602bad0..0da19ea03 100644
--- a/src/settings.c
+++ b/src/settings.c
@@ -71,12 +71,18 @@ static int config_level_to_sysdir(int config_level)
}
extern char *git__user_agent;
+extern char *git__ssl_ciphers;
const char *git_libgit2__user_agent()
{
return git__user_agent;
}
+const char *git_libgit2__ssl_ciphers()
+{
+ return git__ssl_ciphers;
+}
+
int git_libgit2_opts(int key, ...)
{
int error = 0;
@@ -169,7 +175,7 @@ int git_libgit2_opts(int key, ...)
}
}
#else
- giterr_set(GITERR_NET, "Cannot set certificate locations: OpenSSL is not enabled");
+ giterr_set(GITERR_NET, "cannot set certificate locations: OpenSSL is not enabled");
error = -1;
#endif
break;
@@ -187,6 +193,22 @@ int git_libgit2_opts(int key, ...)
git_object__strict_input_validation = (va_arg(ap, int) != 0);
break;
+ case GIT_OPT_SET_SSL_CIPHERS:
+#ifdef GIT_OPENSSL
+ {
+ git__free(git__ssl_ciphers);
+ git__ssl_ciphers = git__strdup(va_arg(ap, const char *));
+ if (!git__ssl_ciphers) {
+ giterr_set_oom();
+ error = -1;
+ }
+ }
+#else
+ giterr_set(GITERR_NET, "cannot set custom ciphers: OpenSSL is not enabled");
+ error = -1;
+#endif
+ break;
+
default:
giterr_set(GITERR_INVALID, "invalid option key");
error = -1;
diff --git a/tests/online/badssl.c b/tests/online/badssl.c
index 12badbda3..66b090df4 100644
--- a/tests/online/badssl.c
+++ b/tests/online/badssl.c
@@ -36,3 +36,11 @@ void test_online_badssl__self_signed(void)
cl_git_fail_with(GIT_ECERTIFICATE,
git_clone(&g_repo, "https://self-signed.badssl.com/fake.git", "./fake", NULL));
}
+
+void test_online_badssl__old_cipher(void)
+{
+ if (!g_has_ssl)
+ cl_skip();
+
+ cl_git_fail(git_clone(&g_repo, "https://rc4.badssl.com/fake.git", "./fake", NULL));
+}