summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--cmake/SelectHashes.cmake8
-rw-r--r--src/features.h.in2
-rw-r--r--src/util/CMakeLists.txt4
-rw-r--r--src/util/hash/openssl.c76
-rw-r--r--src/util/hash/openssl.h20
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 {