Commit 737b445a1866706f271e163427823471bee8fb95

William Swanson 2014-09-26T20:31:33

Add support for setting the SSL CA location This allows users to specify self-signed certificates, or to provide their own certificate stores on limited platforms such as mobile phones.

diff --git a/include/git2/common.h b/include/git2/common.h
index 32237ef..1363316 100644
--- a/include/git2/common.h
+++ b/include/git2/common.h
@@ -136,7 +136,8 @@ typedef enum {
 	GIT_OPT_ENABLE_CACHING,
 	GIT_OPT_GET_CACHED_MEMORY,
 	GIT_OPT_GET_TEMPLATE_PATH,
-	GIT_OPT_SET_TEMPLATE_PATH
+	GIT_OPT_SET_TEMPLATE_PATH,
+	GIT_OPT_SET_SSL_CERT_LOCATIONS,
 } git_libgit2_opt_t;
 
 /**
@@ -221,6 +222,17 @@ typedef enum {
  *		>
  *		> - `path` directory of template.
  *
+ *	* opts(GIT_OPT_SET_SSL_CERT_LOCATIONS, const char *file, const char *path)
+ *
+ *		> Set the SSL certificate-authority locations.
+ *		>
+ *		> - `file` is the location of a file containing several
+ *		>   certificates concatenated together.
+ *		> - `path` is the location of a directory holding several
+ *		>   certificates, one per file.
+ *		>
+ * 		> Either parameter may be `NULL`, but not both.
+ *
  * @param option Option key
  * @param ... value to set the option
  * @return 0 on success, <0 on failure
diff --git a/src/settings.c b/src/settings.c
index 1a21ea0..971b509 100644
--- a/src/settings.c
+++ b/src/settings.c
@@ -5,10 +5,15 @@
  * a Linking Exception. For full terms see the included COPYING file.
  */
 
+#ifdef GIT_SSL
+# include <openssl/err.h>
+#endif
+
 #include <git2.h>
 #include "common.h"
 #include "sysdir.h"
 #include "cache.h"
+#include "global.h"
 
 void git_libgit2_version(int *major, int *minor, int *rev)
 {
@@ -131,6 +136,23 @@ int git_libgit2_opts(int key, ...)
 	case GIT_OPT_SET_TEMPLATE_PATH:
 		error = git_sysdir_set(GIT_SYSDIR_TEMPLATE, va_arg(ap, const char *));
 		break;
+
+	case GIT_OPT_SET_SSL_CERT_LOCATIONS:
+#ifdef GIT_SSL
+		{
+			const char *file = va_arg(ap, const char *);
+			const char *path = va_arg(ap, const char *);
+			if (!SSL_CTX_load_verify_locations(git__ssl_ctx, file, path)) {
+				giterr_set(GITERR_NET, "SSL error: %s",
+					ERR_error_string(ERR_get_error(), NULL));
+				error = -1;
+			}
+		}
+#else
+		giterr_set(GITERR_NET, "Cannot set certificate locations: OpenSSL is not enabled");
+		error = -1;
+#endif
+		break;
 	}
 
 	va_end(ap);