diff options
-rw-r--r-- | cmake/SelectHashes.cmake | 8 | ||||
-rw-r--r-- | src/features.h.in | 2 | ||||
-rw-r--r-- | src/util/CMakeLists.txt | 4 | ||||
-rw-r--r-- | src/util/hash/openssl.c | 76 | ||||
-rw-r--r-- | src/util/hash/openssl.h | 20 |
5 files changed, 107 insertions, 3 deletions
diff --git a/cmake/SelectHashes.cmake b/cmake/SelectHashes.cmake index 29a50b672..faf9e2ea3 100644 --- a/cmake/SelectHashes.cmake +++ b/cmake/SelectHashes.cmake @@ -26,6 +26,10 @@ if(USE_SHA1 STREQUAL "CollisionDetection") set(GIT_SHA1_COLLISIONDETECT 1) elseif(USE_SHA1 STREQUAL "OpenSSL") set(GIT_SHA1_OPENSSL 1) +elseif(USE_SHA1 STREQUAL "OpenSSL-Dynamic") + set(GIT_SHA1_OPENSSL 1) + set(GIT_SHA1_OPENSSL_DYNAMIC 1) + list(APPEND LIBGIT2_SYSTEM_LIBS dl) elseif(USE_SHA1 STREQUAL "CommonCrypto") set(GIT_SHA1_COMMON_CRYPTO 1) elseif(USE_SHA1 STREQUAL "mbedTLS") @@ -58,6 +62,10 @@ if(USE_SHA256 STREQUAL "Builtin") set(GIT_SHA256_BUILTIN 1) elseif(USE_SHA256 STREQUAL "OpenSSL") set(GIT_SHA256_OPENSSL 1) +elseif(USE_SHA256 STREQUAL "OpenSSL-Dynamic") + set(GIT_SHA256_OPENSSL 1) + set(GIT_SHA256_OPENSSL_DYNAMIC 1) + list(APPEND LIBGIT2_SYSTEM_LIBS dl) elseif(USE_SHA256 STREQUAL "CommonCrypto") set(GIT_SHA256_COMMON_CRYPTO 1) elseif(USE_SHA256 STREQUAL "mbedTLS") diff --git a/src/features.h.in b/src/features.h.in index f6510aefa..e14e83359 100644 --- a/src/features.h.in +++ b/src/features.h.in @@ -46,12 +46,14 @@ #cmakedefine GIT_SHA1_WIN32 1 #cmakedefine GIT_SHA1_COMMON_CRYPTO 1 #cmakedefine GIT_SHA1_OPENSSL 1 +#cmakedefine GIT_SHA1_OPENSSL_DYNAMIC 1 #cmakedefine GIT_SHA1_MBEDTLS 1 #cmakedefine GIT_SHA256_BUILTIN 1 #cmakedefine GIT_SHA256_WIN32 1 #cmakedefine GIT_SHA256_COMMON_CRYPTO 1 #cmakedefine GIT_SHA256_OPENSSL 1 +#cmakedefine GIT_SHA256_OPENSSL_DYNAMIC 1 #cmakedefine GIT_SHA256_MBEDTLS 1 #cmakedefine GIT_RAND_GETENTROPY 1 diff --git a/src/util/CMakeLists.txt b/src/util/CMakeLists.txt index 6ac8bfeca..b2833954d 100644 --- a/src/util/CMakeLists.txt +++ b/src/util/CMakeLists.txt @@ -33,7 +33,7 @@ if(USE_SHA1 STREQUAL "CollisionDetection") target_compile_definitions(util PRIVATE SHA1DC_NO_STANDARD_INCLUDES=1) target_compile_definitions(util PRIVATE SHA1DC_CUSTOM_INCLUDE_SHA1_C=\"git2_util.h\") target_compile_definitions(util PRIVATE SHA1DC_CUSTOM_INCLUDE_UBC_CHECK_C=\"git2_util.h\") -elseif(USE_SHA1 STREQUAL "OpenSSL") +elseif(USE_SHA1 STREQUAL "OpenSSL" OR USE_SHA1 STREQUAL "OpenSSL-Dynamic") file(GLOB UTIL_SRC_SHA1 hash/openssl.*) elseif(USE_SHA1 STREQUAL "CommonCrypto") file(GLOB UTIL_SRC_SHA1 hash/common_crypto.*) @@ -49,7 +49,7 @@ list(SORT UTIL_SRC_SHA1) if(USE_SHA256 STREQUAL "Builtin") file(GLOB UTIL_SRC_SHA256 hash/builtin.* hash/rfc6234/*) -elseif(USE_SHA256 STREQUAL "OpenSSL") +elseif(USE_SHA256 STREQUAL "OpenSSL" OR USE_SHA256 STREQUAL "OpenSSL-Dynamic") file(GLOB UTIL_SRC_SHA256 hash/openssl.*) elseif(USE_SHA256 STREQUAL "CommonCrypto") file(GLOB UTIL_SRC_SHA256 hash/common_crypto.*) diff --git a/src/util/hash/openssl.c b/src/util/hash/openssl.c index f95ddb76a..649358ca2 100644 --- a/src/util/hash/openssl.c +++ b/src/util/hash/openssl.c @@ -7,10 +7,67 @@ #include "openssl.h" +#ifdef GIT_OPENSSL_DYNAMIC +# include <dlfcn.h> + +int handle_count; +void *openssl_handle; + +static int git_hash_openssl_global_shutdown(void) +{ + if (--handle_count == 0) { + dlclose(openssl_handle); + openssl_handle = NULL; + } + + return 0; +} + +static int git_hash_openssl_global_init(void) +{ + if (!handle_count) { + if ((openssl_handle = dlopen("libssl.so.1.1", RTLD_NOW)) == NULL && + (openssl_handle = dlopen("libssl.1.1.dylib", RTLD_NOW)) == NULL && + (openssl_handle = dlopen("libssl.so.1.0.0", RTLD_NOW)) == NULL && + (openssl_handle = dlopen("libssl.1.0.0.dylib", RTLD_NOW)) == NULL && + (openssl_handle = dlopen("libssl.so.10", RTLD_NOW)) == NULL) { + git_error_set(GIT_ERROR_SSL, "could not load ssl libraries"); + return -1; + } + } + + if (git_hash_openssl_global_shutdown() < 0) + return -1; + + handle_count++; + return 0; +} + +#endif + #ifdef GIT_SHA1_OPENSSL +# ifdef GIT_OPENSSL_DYNAMIC +static int (*SHA1_Init)(SHA_CTX *c); +static int (*SHA1_Update)(SHA_CTX *c, const void *data, size_t len); +static int (*SHA1_Final)(unsigned char *md, SHA_CTX *c); +# endif + int git_hash_sha1_global_init(void) { +#ifdef GIT_OPENSSL_DYNAMIC + if (git_hash_openssl_global_init() < 0) + return -1; + + if ((SHA1_Init = dlsym(openssl_handle, "SHA1_Init")) == NULL || + (SHA1_Update = dlsym(openssl_handle, "SHA1_Update")) == NULL || + (SHA1_Final = dlsym(openssl_handle, "SHA1_Final")) == NULL) { + const char *msg = dlerror(); + git_error_set(GIT_ERROR_SSL, "could not load hash function: %s", msg ? msg : "unknown error"); + return -1; + } +#endif + return 0; } @@ -64,8 +121,27 @@ int git_hash_sha1_final(unsigned char *out, git_hash_sha1_ctx *ctx) #ifdef GIT_SHA256_OPENSSL +# ifdef GIT_OPENSSL_DYNAMIC +static int (*SHA256_Init)(SHA256_CTX *c); +static int (*SHA256_Update)(SHA256_CTX *c, const void *data, size_t len); +static int (*SHA256_Final)(unsigned char *md, SHA256_CTX *c); +#endif + int git_hash_sha256_global_init(void) { +#ifdef GIT_OPENSSL_DYNAMIC + if (git_hash_openssl_global_init() < 0) + return -1; + + if ((SHA256_Init = dlsym(openssl_handle, "SHA256_Init")) == NULL || + (SHA256_Update = dlsym(openssl_handle, "SHA256_Update")) == NULL || + (SHA256_Final = dlsym(openssl_handle, "SHA256_Final")) == NULL) { + const char *msg = dlerror(); + git_error_set(GIT_ERROR_SSL, "could not load hash function: %s", msg ? msg : "unknown error"); + return -1; + } +#endif + return 0; } diff --git a/src/util/hash/openssl.h b/src/util/hash/openssl.h index ff4b6d640..7cb089abc 100644 --- a/src/util/hash/openssl.h +++ b/src/util/hash/openssl.h @@ -10,7 +10,25 @@ #include "hash/sha.h" -#include <openssl/sha.h> +#ifndef GIT_OPENSSL_DYNAMIC +# include <openssl/sha.h> +#else + +typedef struct { + unsigned int h0, h1, h2, h3, h4; + unsigned int Nl, Nh; + unsigned int data[16]; + unsigned int num; +} SHA_CTX; + +typedef struct { + unsigned int h[8]; + unsigned int Nl, Nh; + unsigned int data[16]; + unsigned int num, md_len; +} SHA256_CTX; + +#endif #ifdef GIT_SHA1_OPENSSL struct git_hash_sha1_ctx { |