8000 mbedTLS support by tiennou · Pull Request #4173 · libgit2/libgit2 · GitHub
[go: up one dir, main page]

Skip to content

mbedTLS support #4173

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 15 commits into from
Apr 22, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
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
10 changes: 10 additions & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,16 @@ matrix:
OPTIONS="-DBUILD_CLAR=ON -DBUILD_EXAMPLES=OFF -DDEBUG_POOL=ON -DCMAKE_BUILD_TYPE=Debug"
os: linux
dist: trusty
- compiler: gcc
env:
MBEDTLS=1
OPTIONS="-DTHREADSAFE=ON -DCMAKE_BUILD_TYPE=Release -DUSE_HTTPS=mbedTLS -DMBEDTLS_ROOT_DIR=../deps/mbedtls"
os: linux
- compiler: gcc
env:
MBEDTLS=1
OPTIONS="-DTHREADSAFE=OFF -DBUILD_EXAMPLES=ON -DUSE_HTTPS=mbedTLS -DMBEDTLS_ROOT_DIR=../deps/mbedtls"
os: linux
allow_failures:
- env: COVERITY=1

Expand Down
2 changes: 1 addition & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ OPTION( PROFILE "Generate profiling information" OFF )
OPTION( ENABLE_TRACE "Enables tracing support" OFF )
OPTION( LIBGIT2_FILENAME "Name of the produced binary" OFF )

SET(SHA1_BACKEND "CollisionDetection" CACHE STRING "Backend to use for SHA1. One of Generic, OpenSSL, Win32, CommonCrypto, CollisionDetection. ")
SET(SHA1_BACKEND "CollisionDetection" CACHE STRING "Backend to use for SHA1. One of Generic, OpenSSL, Win32, CommonCrypto, mbedTLS, CollisionDetection. ")
OPTION( USE_SSH "Link with libssh to enable SSH support" ON )
OPTION( USE_HTTPS "Enable HTTPS support. Can be set to a specific backend" ON )
OPTION( USE_GSSAPI "Link with libgssapi for SPNEGO auth" OFF )
Expand Down
93 changes: 93 additions & 0 deletions cmake/Modules/FindmbedTLS.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
# - Try to find mbedTLS
# Once done this will define
#
# Read-Only variables
# MBEDTLS_FOUND - system has mbedTLS
# MBEDTLS_INCLUDE_DIR - the mbedTLS include directory
# MBEDTLS_LIBRARY_DIR - the mbedTLS library directory
# MBEDTLS_LIBRARIES - Link these to use mbedTLS
# MBEDTLS_LIBRARY - path to mbedTLS library
# MBEDX509_LIBRARY - path to mbedTLS X.509 library
# MBEDCRYPTO_LIBRARY - path to mbedTLS Crypto library
#
# Hint
# MBEDTLS_ROOT_DIR can be pointed to a local mbedTLS installation.

SET(_MBEDTLS_ROOT_HINTS
${MBEDTLS_ROOT_DIR}
ENV MBEDTLS_ROOT_DIR
)

SET(_MBEDTLS_ROOT_HINTS_AND_PATHS
HINTS ${_MBEDTLS_ROOT_HINTS}
PATHS ${_MBEDTLS_ROOT_PATHS}
)

FIND_PATH(MBEDTLS_INCLUDE_DIR
NAMES mbedtls/version.h
${_MBEDTLS_ROOT_HINTS_AND_PATHS}
PATH_SUFFIXES include
)

IF(MBEDTLS_INCLUDE_DIR AND MBEDTLS_LIBRARIES)
# Already in cache, be silent
SET(MBEDTLS_FIND_QUIETLY TRUE)
ENDIF()

FIND_LIBRARY(MBEDTLS_LIBRARY
NAMES mbedtls libmbedtls
${_MBEDTLS_ROOT_HINTS_AND_PATHS}
PATH_SUFFIXES library
)
FIND_LIBRARY(MBEDX509_LIBRARY
NAMES mbedx509 libmbedx509
${_MBEDTLS_ROOT_HINTS_AND_PATHS}
PATH_SUFFIXES library
)
FIND_LIBRARY(MBEDCRYPTO_LIBRARY
NAMES mbedcrypto libmbedcrypto
${_MBEDTLS_ROOT_HINTS_AND_PATHS}
PATH_SUFFIXES library
)

IF(MBEDTLS_INCLUDE_DIR AND MBEDTLS_LIBRARY AND MBEDX509_LIBRARY AND MBEDCRYPTO_LIBRARY)
SET(MBEDTLS_FOUND TRUE)
ENDIF()

IF(MBEDTLS_FOUND)
# split mbedTLS into -L and -l linker options, so we can set them for pkg-config
GET_FILENAME_COMPONENT(MBEDTLS_LIBRARY_DIR ${MBEDTLS_LIBRARY} PATH)
GET_FILENAME_COMPONENT(MBEDTLS_LIBRARY_FILE ${MBEDTLS_LIBRARY} NAME_WE)
GET_FILENAME_COMPONENT(MBEDX509_LIBRARY_FILE ${MBEDX509_LIBRARY} NAME_WE)
GET_FILENAME_COMPONENT(MBEDCRYPTO_LIBRARY_FILE ${MBEDCRYPTO_LIBRARY} NAME_WE)
STRING(REGEX REPLACE "^lib" "" MBEDTLS_LIBRARY_FILE ${MBEDTLS_LIBRARY_FILE})
STRING(REGEX REPLACE "^lib" "" MBEDX509_LIBRARY_FILE ${MBEDX509_LIBRARY_FILE})
STRING(REGEX REPLACE "^lib" "" MBEDCRYPTO_LIBRARY_FILE ${MBEDCRYPTO_LIBRARY_FILE})
SET(MBEDTLS_LIBRARIES "-L${MBEDTLS_LIBRARY_DIR} -l${MBEDTLS_LIBRARY_FILE} -l${MBEDX509_LIBRARY_FILE} -l${MBEDCRYPTO_LIBRARY_FILE}")

IF(NOT MBEDTLS_FIND_QUIETLY)
MESSAGE(STATUS "Found mbedTLS:")
FILE(READ ${MBEDTLS_INCLUDE_DIR}/mbedtls/version.h MBEDTLSCONTENT)
STRING(REGEX MATCH "MBEDTLS_VERSION_STRING +\"[0-9|.]+\"" MBEDTLSMATCH ${MBEDTLSCONTENT})
IF (MBEDTLSMATCH)
STRING(REGEX REPLACE "MBEDTLS_VERSION_STRING +\"([0-9|.]+)\"" "\\1" MBEDTLS_VERSION ${MBEDTLSMATCH})
MESSAGE(STATUS " version ${MBEDTLS_VERSION}")
ENDIF(MBEDTLSMATCH)
MESSAGE(STATUS " TLS: ${MBEDTLS_LIBRARY}")
MESSAGE(STATUS " X509: ${MBEDX509_LIBRARY}")
MESSAGE(STATUS " Crypto: ${MBEDCRYPTO_LIBRARY}")
ENDIF(NOT MBEDTLS_FIND_QUIETLY)
ELSE(MBEDTLS_FOUND)
IF(MBEDTLS_FIND_REQUIRED)
MESSAGE(FATAL_ERROR "Could not find mbedTLS")
ENDIF(MBEDTLS_FIND_REQUIRED)
ENDIF(MBEDTLS_FOUND)

MARK_AS_ADVANCED(
MBEDTLS_INCLUDE_DIR
MBEDTLS_LIBRARY_DIR
MBEDTLS_LIBRARIES
MBEDTLS_LIBRARY
MBEDX509_LIBRARY
MBEDCRYPTO_LIBRARY
)
13 changes: 13 additions & 0 deletions script/install-deps-linux.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
#!/bin/sh

set -x

if [ "$MBEDTLS" ]; then
git clone --depth 10 --single-branch --branch mbedtls-2.6.1 https://github.com/ARMmbed/mbedtls.git ./deps/mbedtls
cd ./deps/mbedtls
# We pass -fPIC explicitely because we'll include it in libgit2.so
CFLAGS=-fPIC cmake -DENABLE_PROGRAMS=OFF -DENABLE_TESTING=OFF -DUSE_SHARED_MBEDTLS_LIBRARY=OFF -DUSE_STATIC_MBEDTLS_LIBRARY=ON .
cmake --build .

echo "mbedTLS built in `pwd`"
fi
64 changes: 61 additions & 3 deletions src/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,9 @@ ELSE ()
ENDIF()

IF (USE_HTTPS)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The comment for USE_HTTPS says that you can set it to the name of the backend that you want to use. I don't think that's true, but it would be nice if it was.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It does though. If you pass ON, this will use "autodetection" (a.k.a. use whatever backend we've found and is first in the following tests), Otherwise, this will be passed verbatim as HTTPS_BACKEND, which is handled just below (and will error if you passed nonsense).

Copy link
Member
1E0A

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yep, rereading, I see it now. Thanks!

# We try to find any packages our backends might use
FIND_PACKAGE(OpenSSL)
FIND_PACKAGE(mbedTLS)
IF (CMAKE_SYSTEM_NAME MATCHES "Darwin")
FIND_PACKAGE(Security)
FIND_PACKAGE(CoreFoundation)
Expand All @@ -149,8 +152,13 @@ IF (USE_HTTPS)
ENDIF()
ELSEIF (WINHTTP)
SET(HTTPS_BACKEND "WinHTTP")
ELSE()
ELSEIF(OPENSSL_FOUND)
SET(HTTPS_BACKEND "OpenSSL")
ELSEIF(MBEDTLS_FOUND)
SET(HTTPS_BACKEND "mbedTLS")
ELSE()
MESSAGE(FATAL_ERROR "Unable to autodetect a usable HTTPS backend."
"Please pass the backend name explicitly (-DUSE_HTTPS=backend)")
ENDIF()
ELSE()
# Backend was explicitly set
Expand All @@ -174,8 +182,6 @@ IF (USE_HTTPS)
LIST(APPEND LIBGIT2_LIBS ${COREFOUNDATION_LIBRARIES} ${SECURITY_LIBRARIES})
LIST(APPEND LIBGIT2_PC_LIBS ${COREFOUNDATION_LDFLAGS} ${SECURITY_LDFLAGS})
ELSEIF (HTTPS_BACKEND STREQUAL "OpenSSL")
FIND_PACKAGE(OpenSSL)

IF (NOT OPENSSL_FOUND)
MESSAGE(FATAL_ERROR "Asked for OpenSSL TLS backend, but it wasn't found")
ENDIF()
Expand All @@ -185,6 +191,53 @@ IF (USE_HTTPS)
LIST(APPEND LIBGIT2_LIBS ${OPENSSL_LIBRARIES})
LIST(APPEND LIBGIT2_PC_LIBS ${OPENSSL_LDFLAGS})
LIST(APPEND LIBGIT2_PC_REQUIRES "openssl")
ELSEIF(HTTPS_BACKEND STREQUAL "mbedTLS")
IF (NOT MBEDTLS_FOUND)
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})
LIST(APPEND LIBGIT2_PC_LIBS ${MBEDTLS_LDFLAGS})
LIST(APPEND LIBGIT2_PC_REQUIRES "mbedtls")
ELSEIF (HTTPS_BACKEND STREQUAL "WinHTTP")
# WinHTTP setup was handled in the WinHTTP-specific block above
ELSE()
Expand Down Expand Up @@ -230,6 +283,11 @@ ELSEIF(SHA1_BACKEND STREQUAL "Win32")
ELSEIF(SHA1_BACKEND STREQUAL "CommonCrypto")
ADD_FEATURE_INFO(SHA ON "using CommonCrypto")
SET(GIT_SHA1_COMMON_CRYPTO 1)
ELSEIF (SHA1_BACKEND STREQUAL "mbedTLS")
ADD_FEATURE_INFO(SHA ON "using mbedTLS")
SET(GIT_SHA1_MBEDTLS 1)
FILE(GLOB SRC_SHA1 src/hash/hash_mbedtls.c)
LIST(APPEND LIBGIT2_PC_REQUIRES "mbedtls")
ELSE()
MESSAGE(FATAL_ERROR "Asked for unknown SHA1 backend ${SHA1_BACKEND}")
ENDIF()
Expand Down
2 changes: 2 additions & 0 deletions src/features.h.in
Original file line number Diff line number Diff line change
Expand Up @@ -27,10 +27,12 @@
#cmakedefine GIT_HTTPS 1
#cmakedefine GIT_OPENSSL 1
#cmakedefine GIT_SECURE_TRANSPORT 1
#cmakedefine GIT_MBEDTLS 1

#cmakedefine GIT_SHA1_COLLISIONDETECT 1
#cmakedefine GIT_SHA1_WIN32 1
#cmakedefine GIT_SHA1_COMMON_CRYPTO 1
#cmakedefine GIT_SHA1_OPENSSL 1
#cmakedefine GIT_SHA1_MBEDTLS 1

#endif
4 changes: 3 additions & 1 deletion src/global.c
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
#include "filter.h"
#include "merge_driver.h"
#include "streams/curl.h"
#include "streams/mbedtls.h"
#include "streams/openssl.h"
#include "thread-utils.h"
#include "git2/global.h"
Expand Down Expand Up @@ -65,7 +66,8 @@ static int init_common(void)
(ret = git_merge_driver_global_init()) == 0 &&
(ret = git_transport_ssh_global_init()) == 0 &&
(ret = git_openssl_stream_global_init()) == 0 &&
(ret = git_curl_stream_global_init()) == 0)
(ret = git_curl_stream_global_init()) == 0 &&
(ret = git_mbedtls_stream_global_init()) == 0)
ret = git_mwindow_global_init();

GIT_MEMORY_BARRIER;
Expand Down
2 changes: 2 additions & 0 deletions src/hash.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@ void git_hash_ctx_cleanup(git_hash_ctx *ctx);
# include "hash/hash_openssl.h"
#elif defined(GIT_SHA1_WIN32)
# include "hash/hash_win32.h"
#elif defined(GIT_SHA1_MBEDTLS)
# include "hash/hash_mbedtls.h"
#else
# include "hash/hash_generic.h"
#endif
Expand Down
38 changes: 38 additions & 0 deletions src/hash/hash_mbedtls.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
/*
* Copyright (C) the libgit2 contributors. All rights reserved.
*
* This file is part of libgit2, distributed under the GNU GPL v2 with
* a Linking Exception. For full terms see the included COPYING file.
*/

#include "common.h"
#include "hash.h"
#include "hash/hash_mbedtls.h"

void git_hash_ctx_cleanup(git_hash_ctx *ctx)
{
assert(ctx);
mbedtls_sha1_free(&ctx->c);
}

int git_hash_init(git_hash_ctx *ctx)
{
assert(ctx);
mbedtls_sha1_init(&ctx->c);
mbedtls_sha1_starts(&ctx->c);
return 0;
}

int git_hash_update(git_hash_ctx *ctx, const void *data, size_t len)
{
assert(ctx);
mbedtls_sha1_update(&ctx->c, data, len);
return 0;
}

int git_hash_final(git_oid *out, git_hash_ctx *ctx)
{
assert(ctx);
mbedtls_sha1_finish(&ctx->c, out->id);
return 0;
}
20 changes: 20 additions & 0 deletions src/hash/hash_mbedtls.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
/*
* Copyright (C) the libgit2 contributors. All rights reserved.
*
* This file is part of libgit2, distributed under the GNU GPL v2 with
* a Linking Exception. For full terms see the included COPYING file.
*/

#ifndef INCLUDE_hash_mbedtld_h__
#define INCLUDE_hash_mbedtld_h__

#include <mbedtls/sha1.h>

struct git_hash_ctx {
mbedtls_sha1_context c;
};

#define git_hash_global_init() 0
#define git_hash_ctx_init(ctx) git_hash_init(ctx)

#endif /* INCLUDE_hash_mbedtld_h__ */
16 changes: 15 additions & 1 deletion src/settings.c
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,10 @@
# include <openssl/err.h>
#endif

#ifdef GIT_MBEDTLS
# include <mbedtls/error.h>
#endif

#include <git2.h>
#include "sysdir.h"
#include "cache.h"
Expand All @@ -20,6 +24,7 @@
#include "refs.h"
#include "transports/smart.h"
#include "streams/openssl.h"
#include "streams/mbedtls.h"

void git_libgit2_version(int *major, int *minor, int *rev)
{
Expand Down Expand Up @@ -175,6 +180,15 @@ int git_libgit2_opts(int key, ...)
const char *path = va_arg(ap, const char *);
error = git_openssl__set_cert_location(file, path);
}
#elif defined(GIT_MBEDTLS)
{
const char *file = va_arg(ap, const char *);
const char *path = va_arg(ap, const char *);
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");
error = -1;
Expand All @@ -199,7 +213,7 @@ int git_libgit2_opts(int key, ...)
break;

case GIT_OPT_SET_SSL_CIPHERS:
#ifdef GIT_OPENSSL
#if (GIT_OPENSSL || GIT_MBEDTLS)
{
git__free(git__ssl_ciphers);
git__ssl_ciphers = git__strdup(va_arg(ap, const char *));
Expand Down
Loading
0