Thanks to visit codestin.com
Credit goes to github.com

Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
mbedtls: load default CA certificates
  • Loading branch information
tiennou committed Apr 11, 2018
commit 382ed1e873da51cb411bd8842cc160fe4d67a666
37 changes: 37 additions & 0 deletions src/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -193,6 +193,43 @@ IF (USE_HTTPS)
MESSAGE(FATAL_ERROR "Asked for mbedTLS backend, but it wasn't found")
ENDIF()

IF(NOT CERT_LOCATION)
MESSAGE("Auto-detecting default certificates location")
IF(CMAKE_SYSTEM_NAME MATCHES Darwin)
# Check for an Homebrew installation
SET(OPENSSL_CMD "/usr/local/opt/openssl/bin/openssl")
ELSE()
SET(OPENSSL_CMD "openssl")
ENDIF()
EXECUTE_PROCESS(COMMAND ${OPENSSL_CMD} version -d OUTPUT_VARIABLE OPENSSL_DIR OUTPUT_STRIP_TRAILING_WHITESPACE)
IF(OPENSSL_DIR)
STRING(REGEX REPLACE "^OPENSSLDIR: \"(.*)\"$" "\\1/" OPENSSL_DIR ${OPENSSL_DIR})

SET(OPENSSL_CA_LOCATIONS
"ca-bundle.pem" # OpenSUSE Leap 42.1
"cert.pem" # Ubuntu 14.04, FreeBSD
"certs/ca-certificates.crt" # Ubuntu 16.04
"certs/ca.pem" # Debian 7
)
FOREACH(SUFFIX IN LISTS OPENSSL_CA_LOCATIONS)
SET(LOC "${OPENSSL_DIR}${SUFFIX}")
IF(NOT CERT_LOCATION AND EXISTS "${OPENSSL_DIR}${SUFFIX}")
SET(CERT_LOCATION ${LOC})
ENDIF()
ENDFOREACH()
ELSE()
MESSAGE("Unable to find OpenSSL executable. Please provide default certificate location via CERT_LOCATION")
ENDIF()
ENDIF()

IF(CERT_LOCATION)
IF(NOT EXISTS ${CERT_LOCATION})
MESSAGE(FATAL_ERROR "Cannot use CERT_LOCATION=${CERT_LOCATION} as it doesn't exist")
ENDIF()
ADD_FEATURE_INFO(CERT_LOCATION ON "using certificates from ${CERT_LOCATION}")
ADD_DEFINITIONS(-DGIT_DEFAULT_CERT_LOCATION="${CERT_LOCATION}")
ENDIF()

SET(GIT_MBEDTLS 1)
LIST(APPEND LIBGIT2_INCLUDES ${MBEDTLS_INCLUDE_DIR})
LIST(APPEND LIBGIT2_LIBS ${MBEDTLS_LIBRARIES})
Expand Down
5 changes: 4 additions & 1 deletion src/settings.c
Original file line number Diff line number Diff line change
Expand Up @@ -184,7 +184,10 @@ int git_libgit2_opts(int key, ...)
{
const char *file = va_arg(ap, const char *);
const char *path = va_arg(ap, const char *);
error = git_mbedtls__set_cert_location(file, path);
if (file)
error = git_mbedtls__set_cert_location(file, 0);
if (error && path)
error = git_mbedtls__set_cert_location(path, 1);
}
#else
giterr_set(GITERR_SSL, "TLS backend doesn't support certificate locations");
Expand Down
60 changes: 38 additions & 22 deletions src/streams/mbedtls.c
Original file line number Diff line number Diff line change
Expand Up @@ -22,13 +22,16 @@
# include "streams/curl.h"
#endif

#ifndef GIT_DEFAULT_CERT_LOCATION
#define GIT_DEFAULT_CERT_LOCATION NULL
#endif

#include <mbedtls/config.h>
#include <mbedtls/ssl.h>
#include <mbedtls/error.h>
#include <mbedtls/entropy.h>
#include <mbedtls/ctr_drbg.h>

#define CRT_LOC "/etc/ssl/certs"

mbedtls_ssl_config *git__ssl_conf;
mbedtls_entropy_context *mbedtls_entropy;

Expand Down Expand Up @@ -57,9 +60,13 @@ static void shutdown_ssl(void)
}
}

int git_mbedtls__set_cert_location(const char *path, int is_dir);

int git_mbedtls_stream_global_init(void)
{
int ret;
int loaded = 0;
char *crtpath = GIT_DEFAULT_CERT_LOCATION;
struct stat statbuf;
mbedtls_ctr_drbg_context *ctr_drbg = NULL;

int *ciphers_list = NULL;
Expand Down Expand Up @@ -121,16 +128,11 @@ int git_mbedtls_stream_global_init(void)

mbedtls_ssl_conf_rng(git__ssl_conf, mbedtls_ctr_drbg_random, ctr_drbg);

// set root certificates
cacert = git__malloc(sizeof(mbedtls_x509_crt));
mbedtls_x509_crt_init(cacert);
ret = mbedtls_x509_crt_parse_path(cacert, CRT_LOC);
if (ret) {
giterr_set(GITERR_SSL, "failed to load CA certificates: %d", ret);
goto cleanup;
}

mbedtls_ssl_conf_ca_chain(git__ssl_conf, cacert, NULL);
/* load default certificates */
if (crtpath != NULL && stat(crtpath, &statbuf) == 0 && S_ISREG(statbuf.st_mode))
loaded = (git_mbedtls__set_cert_location(crtpath, 0) == 0);
if (!loaded && crtpath != NULL && stat(crtpath, &statbuf) == 0 && S_ISDIR(statbuf.st_mode))
loaded = (git_mbedtls__set_cert_location(crtpath, 1) == 0);

git__on_shutdown(shutdown_ssl);

Expand Down Expand Up @@ -388,20 +390,34 @@ int git_mbedtls_stream_new(git_stream **out, const char *host, const char *port)
return error;
}

int git_mbedtls__set_cert_location(const char *file, const char *path)
int git_mbedtls__set_cert_location(const char *path, int is_dir)
{
int ret = 0;
char errbuf[512];
if (!file) {
ret = mbedtls_x509_crt_parse_file(git__ssl_conf->ca_chain, file);
} else if (!path) {
ret = mbedtls_x509_crt_parse_path(git__ssl_conf->ca_chain, path);
mbedtls_x509_crt *cacert;

assert(path != NULL);

cacert = git__malloc(sizeof(mbedtls_x509_crt));
mbedtls_x509_crt_init(cacert);
if (is_dir) {
ret = mbedtls_x509_crt_parse_path(cacert, path);
} else {
ret = mbedtls_x509_crt_parse_file(cacert, path);
}
if (ret != 0) {
/* mbedtls_x509_crt_parse_path returns the number of invalid certs on success */
if (ret < 0) {
mbedtls_x509_crt_free(cacert);
git__free(cacert);
mbedtls_strerror( ret, errbuf, 512 );
giterr_set(GITERR_NET, "SSL error: %d - %s", ret, errbuf);
giterr_set(GITERR_SSL, "failed to load CA certificates : %s (%d)", errbuf, ret);
return -1;
}

mbedtls_x509_crt_free(git__ssl_conf->ca_chain);
git__free(git__ssl_conf->ca_chain);
mbedtls_ssl_conf_ca_chain(git__ssl_conf, cacert, NULL);

return 0;
}

Expand All @@ -424,10 +440,10 @@ int git_mbedtls_stream_new(git_stream **out, const char *host, const char *port)
return -1;
}

int git_mbedtls__set_cert_location(const char *file, const char *path)
int git_mbedtls__set_cert_location(const char *path, int is_dir)
{
GIT_UNUSED(file);
GIT_UNUSED(path);
GIT_UNUSED(is_dir);

giterr_set(GITERR_SSL, "mbedTLS is not supported in this version");
return -1;
Expand Down
2 changes: 1 addition & 1 deletion src/streams/mbedtls.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,6 @@ extern int git_mbedtls_stream_global_init(void);

extern int git_mbedtls_stream_new(git_stream **out, const char *host, const char *port);

extern int git_mbedtls__set_cert_location(const char *file, const char *path);
extern int git_mbedtls__set_cert_location(const char *path, int is_dir);

#endif