parent
3538eb93c3
commit
f3968b7708
|
@ -345,6 +345,11 @@
|
|||
C12F19791E1AE3C30005E93F /* upnperrors.c in Sources */ = {isa = PBXBuildFile; fileRef = C12F19771E1AE3C30005E93F /* upnperrors.c */; };
|
||||
C12F197B1E1AE4460005E93F /* upnperrors.h in Headers */ = {isa = PBXBuildFile; fileRef = C12F197A1E1AE4460005E93F /* upnperrors.h */; };
|
||||
C1305EBE186A13B100F03351 /* file.c in Sources */ = {isa = PBXBuildFile; fileRef = C1305EB8186A134000F03351 /* file.c */; };
|
||||
C139E3B122BE70FB0007870C /* libssl.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = C139E3B022BE70FA0007870C /* libssl.dylib */; };
|
||||
C139E3B222BE71030007870C /* libssl.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = C139E3B022BE70FA0007870C /* libssl.dylib */; };
|
||||
C139E3B322BE71180007870C /* libssl.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = C139E3B022BE70FA0007870C /* libssl.dylib */; };
|
||||
C139E3B422BE71250007870C /* libssl.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = C139E3B022BE70FA0007870C /* libssl.dylib */; };
|
||||
C139E3B522BE712C0007870C /* libssl.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = C139E3B022BE70FA0007870C /* libssl.dylib */; };
|
||||
C1425B351EE9C5F5001DB85F /* tr-assert.c in Sources */ = {isa = PBXBuildFile; fileRef = C1425B321EE9C5EA001DB85F /* tr-assert.c */; };
|
||||
C1425B361EE9C605001DB85F /* tr-assert.h in Headers */ = {isa = PBXBuildFile; fileRef = C1425B331EE9C5EA001DB85F /* tr-assert.h */; };
|
||||
C1425B371EE9C705001DB85F /* tr-macros.h in Headers */ = {isa = PBXBuildFile; fileRef = C1425B341EE9C5EA001DB85F /* tr-macros.h */; };
|
||||
|
@ -994,6 +999,7 @@
|
|||
C12F19771E1AE3C30005E93F /* upnperrors.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; name = upnperrors.c; path = "third-party/miniupnpc/upnperrors.c"; sourceTree = "<group>"; };
|
||||
C12F197A1E1AE4460005E93F /* upnperrors.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = upnperrors.h; path = "third-party/miniupnpc/upnperrors.h"; sourceTree = "<group>"; };
|
||||
C1305EB8186A134000F03351 /* file.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; name = file.c; path = libtransmission/file.c; sourceTree = "<group>"; };
|
||||
C139E3B022BE70FA0007870C /* libssl.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libssl.dylib; path = "third-party/openssl/lib/libssl.dylib"; sourceTree = "<group>"; };
|
||||
C1425B321EE9C5EA001DB85F /* tr-assert.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = "tr-assert.c"; path = "libtransmission/tr-assert.c"; sourceTree = "<group>"; };
|
||||
C1425B331EE9C5EA001DB85F /* tr-assert.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "tr-assert.h"; path = "libtransmission/tr-assert.h"; sourceTree = "<group>"; };
|
||||
C1425B341EE9C5EA001DB85F /* tr-macros.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "tr-macros.h"; path = "libtransmission/tr-macros.h"; sourceTree = "<group>"; };
|
||||
|
@ -1035,6 +1041,7 @@
|
|||
A296EF3C11E560BD004A2781 /* libiconv.dylib in Frameworks */,
|
||||
A2290D1E14421CC100B95A09 /* libcrypto.dylib in Frameworks */,
|
||||
A2290D2F1442B23200B95A09 /* libcurl.4.dylib in Frameworks */,
|
||||
C139E3B322BE71180007870C /* libssl.dylib in Frameworks */,
|
||||
A2B6141E1395B0EC000E0975 /* libz.dylib in Frameworks */,
|
||||
A2B3FB4C0E59023000FF78FB /* Cocoa.framework in Frameworks */,
|
||||
);
|
||||
|
@ -1051,6 +1058,7 @@
|
|||
A296EF3B11E560A7004A2781 /* libiconv.dylib in Frameworks */,
|
||||
A2290D2514421D1A00B95A09 /* libcrypto.dylib in Frameworks */,
|
||||
A2290D2E1442B23200B95A09 /* libcurl.4.dylib in Frameworks */,
|
||||
C139E3B122BE70FB0007870C /* libssl.dylib in Frameworks */,
|
||||
A2B6141F1395B0F5000E0975 /* libz.dylib in Frameworks */,
|
||||
A2E669790F5B8E5A00B4251A /* Security.framework in Frameworks */,
|
||||
A22CFB820FB66EF30009BD3E /* Carbon.framework in Frameworks */,
|
||||
|
@ -1082,9 +1090,10 @@
|
|||
A2F35BE315C5A7F900EBF632 /* Foundation.framework in Frameworks */,
|
||||
A2F35BD415C5A19A00EBF632 /* libtransmission.a in Frameworks */,
|
||||
A2F35BDB15C5A4A000EBF632 /* libiconv.dylib in Frameworks */,
|
||||
A2F35BDA15C5A49200EBF632 /* libz.dylib in Frameworks */,
|
||||
A2F35BD715C5A46D00EBF632 /* libcrypto.dylib in Frameworks */,
|
||||
A2AB76EA15D8130B009EFC95 /* libcurl.4.dylib in Frameworks */,
|
||||
C139E3B222BE71030007870C /* libssl.dylib in Frameworks */,
|
||||
A2F35BDA15C5A49200EBF632 /* libz.dylib in Frameworks */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
|
@ -1123,6 +1132,7 @@
|
|||
A296EF3D11E560C3004A2781 /* libiconv.dylib in Frameworks */,
|
||||
A2290D2014421CD000B95A09 /* libcrypto.dylib in Frameworks */,
|
||||
A2290D301442B23200B95A09 /* libcurl.4.dylib in Frameworks */,
|
||||
C139E3B422BE71250007870C /* libssl.dylib in Frameworks */,
|
||||
A2B6141D1395B0E3000E0975 /* libz.dylib in Frameworks */,
|
||||
A2B3FB530E59027100FF78FB /* Cocoa.framework in Frameworks */,
|
||||
);
|
||||
|
@ -1136,6 +1146,7 @@
|
|||
A296EF3E11E560D1004A2781 /* libiconv.dylib in Frameworks */,
|
||||
A2290D2214421CD800B95A09 /* libcrypto.dylib in Frameworks */,
|
||||
A2290D311442B23200B95A09 /* libcurl.4.dylib in Frameworks */,
|
||||
C139E3B522BE712C0007870C /* libssl.dylib in Frameworks */,
|
||||
A2B6141C1395ADE9000E0975 /* libz.dylib in Frameworks */,
|
||||
A25E03D90E4015100086C225 /* Cocoa.framework in Frameworks */,
|
||||
);
|
||||
|
@ -1586,6 +1597,7 @@
|
|||
A2F35BBA15C5A0A100EBF632 /* Frameworks */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
C139E3B022BE70FA0007870C /* libssl.dylib */,
|
||||
A2F35BBB15C5A0A100EBF632 /* QuickLook.framework */,
|
||||
A2F35BE215C5A7F900EBF632 /* Foundation.framework */,
|
||||
A2F35BE015C5A7ED00EBF632 /* Cocoa.framework */,
|
||||
|
|
|
@ -269,7 +269,7 @@ if(ICONV_FOUND)
|
|||
endif()
|
||||
|
||||
if(WIN32)
|
||||
target_link_libraries(${TR_NAME} shlwapi)
|
||||
target_link_libraries(${TR_NAME} crypt32 shlwapi)
|
||||
endif()
|
||||
|
||||
if(ENABLE_TESTS)
|
||||
|
|
|
@ -19,6 +19,9 @@
|
|||
#define tr_rc4_ctx_t tr_rc4_ctx_t_
|
||||
#define tr_dh_ctx_t tr_dh_ctx_t_
|
||||
#define tr_dh_secret_t tr_dh_secret_t_
|
||||
#define tr_ssl_ctx_t tr_ssl_ctx_t_
|
||||
#define tr_x509_store_t tr_x509_store_t_
|
||||
#define tr_x509_cert_t tr_x509_cert_t_
|
||||
#define tr_crypto tr_crypto_
|
||||
#define tr_cryptoConstruct tr_cryptoConstruct_
|
||||
#define tr_cryptoDestruct tr_cryptoDestruct_
|
||||
|
@ -47,6 +50,10 @@
|
|||
#define tr_dh_secret_derive tr_dh_secret_derive_
|
||||
#define tr_dh_secret_free tr_dh_secret_free_
|
||||
#define tr_dh_align_key tr_dh_align_key_
|
||||
#define tr_ssl_get_x509_store tr_ssl_get_x509_store_
|
||||
#define tr_x509_store_add tr_x509_store_add_
|
||||
#define tr_x509_cert_new tr_x509_cert_new_
|
||||
#define tr_x509_cert_free tr_x509_cert_free_
|
||||
#define tr_rand_int tr_rand_int_
|
||||
#define tr_rand_int_weak tr_rand_int_weak_
|
||||
#define tr_rand_buffer tr_rand_buffer_
|
||||
|
@ -76,6 +83,9 @@
|
|||
#undef tr_rc4_ctx_t
|
||||
#undef tr_dh_ctx_t
|
||||
#undef tr_dh_secret_t
|
||||
#undef tr_ssl_ctx_t
|
||||
#undef tr_x509_store_t
|
||||
#undef tr_x509_cert_t
|
||||
#undef tr_crypto
|
||||
#undef tr_cryptoConstruct
|
||||
#undef tr_cryptoDestruct
|
||||
|
@ -104,6 +114,10 @@
|
|||
#undef tr_dh_secret_derive
|
||||
#undef tr_dh_secret_free
|
||||
#undef tr_dh_align_key
|
||||
#undef tr_ssl_get_x509_store
|
||||
#undef tr_x509_store_add
|
||||
#undef tr_x509_cert_new
|
||||
#undef tr_x509_cert_free
|
||||
#undef tr_rand_int
|
||||
#undef tr_rand_int_weak
|
||||
#undef tr_rand_buffer
|
||||
|
@ -126,6 +140,9 @@
|
|||
#define tr_rc4_ctx_t_ tr_rc4_ctx_t
|
||||
#define tr_dh_ctx_t_ tr_dh_ctx_t
|
||||
#define tr_dh_secret_t_ tr_dh_secret_t
|
||||
#define tr_ssl_ctx_t_ tr_ssl_ctx_t
|
||||
#define tr_x509_store_t_ tr_x509_store_t
|
||||
#define tr_x509_cert_t_ tr_x509_cert_t
|
||||
#define tr_crypto_ tr_crypto
|
||||
#define tr_cryptoConstruct_ tr_cryptoConstruct
|
||||
#define tr_cryptoDestruct_ tr_cryptoDestruct
|
||||
|
@ -154,6 +171,10 @@
|
|||
#define tr_dh_secret_derive_ tr_dh_secret_derive
|
||||
#define tr_dh_secret_free_ tr_dh_secret_free
|
||||
#define tr_dh_align_key_ tr_dh_align_key
|
||||
#define tr_ssl_get_x509_store_ tr_ssl_get_x509_store
|
||||
#define tr_x509_store_add_ tr_x509_store_add
|
||||
#define tr_x509_cert_new_ tr_x509_cert_new
|
||||
#define tr_x509_cert_free_ tr_x509_cert_free
|
||||
#define tr_rand_int_ tr_rand_int
|
||||
#define tr_rand_int_weak_ tr_rand_int_weak
|
||||
#define tr_rand_buffer_ tr_rand_buffer
|
||||
|
|
|
@ -35,6 +35,7 @@
|
|||
#include "utils.h"
|
||||
|
||||
#define TR_CRYPTO_DH_SECRET_FALLBACK
|
||||
#define TR_CRYPTO_X509_FALLBACK
|
||||
#include "crypto-utils-fallback.c"
|
||||
|
||||
struct tr_dh_ctx
|
||||
|
|
|
@ -60,3 +60,35 @@ void tr_dh_secret_free(tr_dh_secret_t handle)
|
|||
}
|
||||
|
||||
#endif /* TR_CRYPTO_DH_SECRET_FALLBACK */
|
||||
|
||||
#ifdef TR_CRYPTO_X509_FALLBACK
|
||||
|
||||
tr_x509_store_t tr_ssl_get_x509_store(tr_ssl_ctx_t handle)
|
||||
{
|
||||
(void)handle;
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
bool tr_x509_store_add(tr_x509_store_t handle, tr_x509_cert_t cert)
|
||||
{
|
||||
(void)handle;
|
||||
(void)cert;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
tr_x509_cert_t tr_x509_cert_new(void const* der, size_t der_length)
|
||||
{
|
||||
(void)der;
|
||||
(void)der_length;
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void tr_x509_cert_free(tr_x509_cert_t handle)
|
||||
{
|
||||
(void)handle;
|
||||
}
|
||||
|
||||
#endif /* TR_CRYPTO_X509_FALLBACK */
|
||||
|
|
|
@ -16,8 +16,10 @@
|
|||
#include <openssl/dh.h>
|
||||
#include <openssl/err.h>
|
||||
#include <openssl/evp.h>
|
||||
#include <openssl/rand.h>
|
||||
#include <openssl/opensslv.h>
|
||||
#include <openssl/rand.h>
|
||||
#include <openssl/ssl.h>
|
||||
#include <openssl/x509.h>
|
||||
|
||||
#include "transmission.h"
|
||||
#include "crypto-utils.h"
|
||||
|
@ -400,6 +402,52 @@ tr_dh_secret_t tr_dh_agree(tr_dh_ctx_t handle, uint8_t const* other_public_key,
|
|||
****
|
||||
***/
|
||||
|
||||
tr_x509_store_t tr_ssl_get_x509_store(tr_ssl_ctx_t handle)
|
||||
{
|
||||
if (handle == NULL)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return SSL_CTX_get_cert_store(handle);
|
||||
}
|
||||
|
||||
bool tr_x509_store_add(tr_x509_store_t handle, tr_x509_cert_t cert)
|
||||
{
|
||||
TR_ASSERT(handle != NULL);
|
||||
TR_ASSERT(cert != NULL);
|
||||
|
||||
return check_result(X509_STORE_add_cert(handle, cert));
|
||||
}
|
||||
|
||||
tr_x509_cert_t tr_x509_cert_new(void const* der, size_t der_length)
|
||||
{
|
||||
TR_ASSERT(der != NULL);
|
||||
|
||||
X509* const ret = d2i_X509(NULL, (unsigned char const**)&der, der_length);
|
||||
|
||||
if (ret == NULL)
|
||||
{
|
||||
log_error();
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void tr_x509_cert_free(tr_x509_cert_t handle)
|
||||
{
|
||||
if (handle == NULL)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
X509_free(handle);
|
||||
}
|
||||
|
||||
/***
|
||||
****
|
||||
***/
|
||||
|
||||
bool tr_rand_buffer(void* buffer, size_t length)
|
||||
{
|
||||
TR_ASSERT(buffer != NULL);
|
||||
|
|
|
@ -34,6 +34,7 @@
|
|||
#include "utils.h"
|
||||
|
||||
#define TR_CRYPTO_DH_SECRET_FALLBACK
|
||||
#define TR_CRYPTO_X509_FALLBACK
|
||||
#include "crypto-utils-fallback.c"
|
||||
|
||||
/***
|
||||
|
|
|
@ -33,6 +33,12 @@ typedef void* tr_rc4_ctx_t;
|
|||
typedef void* tr_dh_ctx_t;
|
||||
/** @brief Opaque DH secret key type. */
|
||||
typedef void* tr_dh_secret_t;
|
||||
/** @brief Opaque SSL context type. */
|
||||
typedef void* tr_ssl_ctx_t;
|
||||
/** @brief Opaque X509 certificate store type. */
|
||||
typedef void* tr_x509_store_t;
|
||||
/** @brief Opaque X509 certificate type. */
|
||||
typedef void* tr_x509_cert_t;
|
||||
|
||||
/**
|
||||
* @brief Generate a SHA1 hash from one or more chunks of memory.
|
||||
|
@ -112,6 +118,26 @@ void tr_dh_secret_free(tr_dh_secret_t handle);
|
|||
*/
|
||||
void tr_dh_align_key(uint8_t* key_buffer, size_t key_size, size_t buffer_size);
|
||||
|
||||
/**
|
||||
* @brief Get X509 certificate store from SSL context.
|
||||
*/
|
||||
tr_x509_store_t tr_ssl_get_x509_store(tr_ssl_ctx_t handle);
|
||||
|
||||
/**
|
||||
* @brief Add certificate to X509 certificate store.
|
||||
*/
|
||||
bool tr_x509_store_add(tr_x509_store_t handle, tr_x509_cert_t cert);
|
||||
|
||||
/**
|
||||
* @brief Allocate and initialize new X509 certificate from DER-encoded buffer.
|
||||
*/
|
||||
tr_x509_cert_t tr_x509_cert_new(void const* der_data, size_t der_data_size);
|
||||
|
||||
/**
|
||||
* @brief Free X509 certificate returned by @ref tr_x509_cert_new.
|
||||
*/
|
||||
void tr_x509_cert_free(tr_x509_cert_t handle);
|
||||
|
||||
/**
|
||||
* @brief Returns a random number in the range of [0...upper_bound).
|
||||
*/
|
||||
|
|
|
@ -9,6 +9,8 @@
|
|||
#include <string.h> /* strlen(), strstr() */
|
||||
|
||||
#ifdef _WIN32
|
||||
#include <windows.h>
|
||||
#include <wincrypt.h>
|
||||
#include <ws2tcpip.h>
|
||||
#else
|
||||
#include <sys/select.h>
|
||||
|
@ -19,6 +21,7 @@
|
|||
#include <event2/buffer.h>
|
||||
|
||||
#include "transmission.h"
|
||||
#include "crypto-utils.h"
|
||||
#include "file.h"
|
||||
#include "list.h"
|
||||
#include "log.h"
|
||||
|
@ -149,6 +152,67 @@ static int sockoptfunction(void* vtask, curl_socket_t fd, curlsocktype purpose U
|
|||
|
||||
#endif
|
||||
|
||||
static CURLcode ssl_context_func(CURL* curl, void* ssl_ctx, void* user_data)
|
||||
{
|
||||
(void)curl;
|
||||
(void)user_data;
|
||||
|
||||
tr_x509_store_t const cert_store = tr_ssl_get_x509_store(ssl_ctx);
|
||||
if (cert_store == NULL)
|
||||
{
|
||||
return CURLE_OK;
|
||||
}
|
||||
|
||||
#ifdef _WIN32
|
||||
|
||||
curl_version_info_data const* const curl_ver = curl_version_info(CURLVERSION_NOW);
|
||||
if (curl_ver->age >= 0 && strncmp(curl_ver->ssl_version, "Schannel", 8) == 0)
|
||||
{
|
||||
return CURLE_OK;
|
||||
}
|
||||
|
||||
static LPCWSTR const sys_store_names[] =
|
||||
{
|
||||
L"CA",
|
||||
L"ROOT"
|
||||
};
|
||||
|
||||
for (size_t i = 0; i < TR_N_ELEMENTS(sys_store_names); ++i)
|
||||
{
|
||||
HCERTSTORE const sys_cert_store = CertOpenSystemStoreW(0, sys_store_names[i]);
|
||||
if (sys_cert_store == NULL)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
PCCERT_CONTEXT sys_cert = NULL;
|
||||
|
||||
while (true)
|
||||
{
|
||||
sys_cert = CertFindCertificateInStore(sys_cert_store, X509_ASN_ENCODING, 0, CERT_FIND_ANY, NULL, sys_cert);
|
||||
if (sys_cert == NULL)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
tr_x509_cert_t const cert = tr_x509_cert_new(sys_cert->pbCertEncoded, sys_cert->cbCertEncoded);
|
||||
if (cert == NULL)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
tr_x509_store_add(cert_store, cert);
|
||||
tr_x509_cert_free(cert);
|
||||
}
|
||||
|
||||
CertCloseStore(sys_cert_store, 0);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
return CURLE_OK;
|
||||
}
|
||||
|
||||
static long getTimeoutFromURL(struct tr_web_task const* task)
|
||||
{
|
||||
long timeout;
|
||||
|
@ -201,6 +265,10 @@ static CURL* createEasy(tr_session* s, struct tr_web* web, struct tr_web_task* t
|
|||
{
|
||||
curl_easy_setopt(e, CURLOPT_CAINFO, web->curl_ca_bundle);
|
||||
}
|
||||
else
|
||||
{
|
||||
curl_easy_setopt(e, CURLOPT_SSL_CTX_FUNCTION, ssl_context_func);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
Loading…
Reference in New Issue