From 7befab856cffaa0357582033083dbc95e2c17000 Mon Sep 17 00:00:00 2001 From: Norbert Federa Date: Mon, 21 Nov 2016 17:28:54 +0100 Subject: [PATCH] Support for OpenSSL 1.1.0 --- CMakeLists.txt | 1 + include/freerdp/crypto/crypto.h | 2 +- libfreerdp/common/assistance.c | 31 +- libfreerdp/core/certificate.c | 25 +- libfreerdp/core/connection.c | 12 - libfreerdp/core/gateway/rdg.c | 47 +-- libfreerdp/core/gateway/tsg.c | 47 +-- libfreerdp/core/gcc.c | 9 +- libfreerdp/core/info.c | 8 +- libfreerdp/core/license.c | 7 +- libfreerdp/core/nla.h | 1 - libfreerdp/core/rdp.c | 7 - libfreerdp/core/rdp.h | 1 - libfreerdp/core/security.c | 188 ++++----- libfreerdp/core/tcp.c | 155 ++++---- libfreerdp/crypto/CMakeLists.txt | 3 +- libfreerdp/crypto/crypto.c | 49 ++- libfreerdp/crypto/opensslcompat.c | 44 +++ libfreerdp/crypto/opensslcompat.h | 65 +++ libfreerdp/crypto/tls.c | 239 ++++++----- winpr/include/winpr/crypto.h | 267 +------------ winpr/libwinpr/crypto/cipher.c | 94 ++--- winpr/libwinpr/crypto/crypto.c | 2 +- winpr/libwinpr/crypto/hash.c | 370 +++++++----------- winpr/libwinpr/crypto/test/TestCryptoCipher.c | 126 +++++- winpr/libwinpr/crypto/test/TestCryptoHash.c | 85 +++- winpr/libwinpr/sspi/NTLM/ntlm.c | 29 +- winpr/libwinpr/sspi/NTLM/ntlm_av_pairs.c | 26 +- winpr/libwinpr/sspi/NTLM/ntlm_compute.c | 41 +- winpr/libwinpr/utils/ntlm.c | 8 +- winpr/libwinpr/utils/ssl.c | 22 +- 31 files changed, 1016 insertions(+), 995 deletions(-) create mode 100644 libfreerdp/crypto/opensslcompat.c create mode 100644 libfreerdp/crypto/opensslcompat.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 68b9436c0..c4334f5de 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -756,6 +756,7 @@ endif() if(OPENSSL_FOUND) add_definitions("-DWITH_OPENSSL") + message(STATUS "Using OpenSSL Version: ${OPENSSL_VERSION}") endif() if(MBEDTLS_FOUND) diff --git a/include/freerdp/crypto/crypto.h b/include/freerdp/crypto/crypto.h index bcd5ee60a..aeda47ec8 100644 --- a/include/freerdp/crypto/crypto.h +++ b/include/freerdp/crypto/crypto.h @@ -28,7 +28,7 @@ #include #include -#if defined(OPENSSL_VERSION_NUMBER) && (OPENSSL_VERSION_NUMBER >= 0x0090800f) +#if OPENSSL_VERSION_NUMBER >= 0x0090800f #define D2I_X509_CONST const #else #define D2I_X509_CONST diff --git a/libfreerdp/common/assistance.c b/libfreerdp/common/assistance.c index c18920771..b63538dac 100644 --- a/libfreerdp/common/assistance.c +++ b/libfreerdp/common/assistance.c @@ -77,7 +77,6 @@ int freerdp_assistance_crypt_derive_key_sha1(BYTE* hash, int hashLength, BYTE* k BYTE* buffer; BYTE pad1[64]; BYTE pad2[64]; - WINPR_SHA1_CTX hashCtx; memset(pad1, 0x36, 64); memset(pad2, 0x5C, 64); @@ -93,18 +92,10 @@ int freerdp_assistance_crypt_derive_key_sha1(BYTE* hash, int hashLength, BYTE* k if (!buffer) goto fail; - if (!winpr_SHA1_Init(&hashCtx)) - goto fail; - if (!winpr_SHA1_Update(&hashCtx, pad1, 64)) - goto fail; - if (!winpr_SHA1_Final(&hashCtx, buffer, hashLength)) + if (!winpr_Digest(WINPR_MD_SHA1, pad1, 64, buffer, hashLength)) goto fail; - if (!winpr_SHA1_Init(&hashCtx)) - goto fail; - if (!winpr_SHA1_Update(&hashCtx, pad2, 64)) - goto fail; - if (!winpr_SHA1_Final(&hashCtx, &buffer[hashLength], hashLength)) + if (!winpr_Digest(WINPR_MD_SHA1, pad2, 64, &buffer[hashLength], hashLength)) goto fail; CopyMemory(key, buffer, keyLength); @@ -550,7 +541,6 @@ BYTE* freerdp_assistance_encrypt_pass_stub(const char* password, const char* pas { BOOL rc; int status; - WINPR_MD5_CTX md5Ctx; int cbPasswordW; int cbPassStubW; int EncryptedSize; @@ -568,17 +558,7 @@ BYTE* freerdp_assistance_encrypt_pass_stub(const char* password, const char* pas cbPasswordW = (status - 1) * 2; - if (!winpr_MD5_Init(&md5Ctx)) - { - free (PasswordW); - return NULL; - } - if (!winpr_MD5_Update(&md5Ctx, (BYTE*)PasswordW, cbPasswordW)) - { - free (PasswordW); - return NULL; - } - if (!winpr_MD5_Final(&md5Ctx, (BYTE*) PasswordHash, sizeof(PasswordHash))) + if (!winpr_Digest(WINPR_MD_MD5, (BYTE*)PasswordW, cbPasswordW, (BYTE*) PasswordHash, sizeof(PasswordHash))) { free (PasswordW); return NULL; @@ -665,7 +645,6 @@ BYTE* freerdp_assistance_encrypt_pass_stub(const char* password, const char* pas int freerdp_assistance_decrypt2(rdpAssistanceFile* file, const char* password) { int status; - WINPR_SHA1_CTX shaCtx; int cbPasswordW; int cchOutW = 0; WCHAR* pbOutW = NULL; @@ -684,9 +663,7 @@ int freerdp_assistance_decrypt2(rdpAssistanceFile* file, const char* password) cbPasswordW = (status - 1) * 2; - if (!winpr_SHA1_Init(&shaCtx) || - !winpr_SHA1_Update(&shaCtx, (BYTE*)PasswordW, cbPasswordW) || - !winpr_SHA1_Final(&shaCtx, PasswordHash, sizeof(PasswordHash))) + if (!winpr_Digest(WINPR_MD_SHA1, (BYTE*)PasswordW, cbPasswordW, PasswordHash, sizeof(PasswordHash))) { free (PasswordW); return -1; diff --git a/libfreerdp/core/certificate.c b/libfreerdp/core/certificate.c index 9ce68f355..6cb76525f 100644 --- a/libfreerdp/core/certificate.c +++ b/libfreerdp/core/certificate.c @@ -35,6 +35,7 @@ #include #include "certificate.h" +#include "../crypto/opensslcompat.h" #define TAG "com.freerdp.core" @@ -399,16 +400,11 @@ static BOOL certificate_process_server_public_signature(rdpCertificate* certific const BYTE* sigdata, int sigdatalen, wStream* s, UINT32 siglen) { int i, sum; - WINPR_MD5_CTX md5ctx; BYTE sig[TSSK_KEY_LENGTH]; BYTE encsig[TSSK_KEY_LENGTH + 8]; BYTE md5hash[WINPR_MD5_DIGEST_LENGTH]; - if (!winpr_MD5_Init(&md5ctx)) - return FALSE; - if (!winpr_MD5_Update(&md5ctx, sigdata, sigdatalen)) - return FALSE; - if (!winpr_MD5_Final(&md5ctx, md5hash, sizeof(md5hash))) + if (!winpr_Digest(WINPR_MD_MD5, sigdata, sigdatalen, md5hash, sizeof(md5hash))) return FALSE; Stream_Read(s, encsig, siglen); @@ -667,6 +663,9 @@ rdpRsaKey* key_new_from_content(const char *keycontent, const char *keyfile) BIO* bio = NULL; RSA* rsa = NULL; rdpRsaKey* key = NULL; + const BIGNUM *rsa_e = NULL; + const BIGNUM *rsa_n = NULL; + const BIGNUM *rsa_d = NULL; key = (rdpRsaKey*) calloc(1, sizeof(rdpRsaKey)); if (!key) @@ -700,30 +699,32 @@ rdpRsaKey* key_new_from_content(const char *keycontent, const char *keyfile) goto out_free_rsa; } - if (BN_num_bytes(rsa->e) > 4) + RSA_get0_key(rsa, &rsa_n, &rsa_e, &rsa_d); + + if (BN_num_bytes(rsa_e) > 4) { WLog_ERR(TAG, "RSA public exponent too large in %s", keyfile); goto out_free_rsa; } - key->ModulusLength = BN_num_bytes(rsa->n); + key->ModulusLength = BN_num_bytes(rsa_n); key->Modulus = (BYTE*) malloc(key->ModulusLength); if (!key->Modulus) goto out_free_rsa; - BN_bn2bin(rsa->n, key->Modulus); + BN_bn2bin(rsa_n, key->Modulus); crypto_reverse(key->Modulus, key->ModulusLength); - key->PrivateExponentLength = BN_num_bytes(rsa->d); + key->PrivateExponentLength = BN_num_bytes(rsa_d); key->PrivateExponent = (BYTE*) malloc(key->PrivateExponentLength); if (!key->PrivateExponent) goto out_free_modulus; - BN_bn2bin(rsa->d, key->PrivateExponent); + BN_bn2bin(rsa_d, key->PrivateExponent); crypto_reverse(key->PrivateExponent, key->PrivateExponentLength); memset(key->exponent, 0, sizeof(key->exponent)); - BN_bn2bin(rsa->e, key->exponent + sizeof(key->exponent) - BN_num_bytes(rsa->e)); + BN_bn2bin(rsa_e, key->exponent + sizeof(key->exponent) - BN_num_bytes(rsa_e)); crypto_reverse(key->exponent, sizeof(key->exponent)); RSA_free(rsa); return key; diff --git a/libfreerdp/core/connection.c b/libfreerdp/core/connection.c index 3d6cd4ab9..c3da023c7 100644 --- a/libfreerdp/core/connection.c +++ b/libfreerdp/core/connection.c @@ -509,12 +509,6 @@ static BOOL rdp_client_establish_keys(rdpRdp* rdp) goto end; } - rdp->fips_hmac = calloc(1, sizeof(WINPR_HMAC_CTX)); - if (!rdp->fips_hmac) - { - WLog_ERR(TAG, "unable to allocate fips hmac"); - goto end; - } ret = TRUE; goto end; } @@ -636,12 +630,6 @@ BOOL rdp_server_establish_keys(rdpRdp* rdp, wStream* s) goto end; } - rdp->fips_hmac = calloc(1, sizeof(WINPR_HMAC_CTX)); - if (!rdp->fips_hmac) - { - WLog_ERR(TAG, "unable to allocate fips hmac"); - goto end; - } ret = TRUE; goto end; } diff --git a/libfreerdp/core/gateway/rdg.c b/libfreerdp/core/gateway/rdg.c index 474ed85ad..be177ab10 100644 --- a/libfreerdp/core/gateway/rdg.c +++ b/libfreerdp/core/gateway/rdg.c @@ -35,6 +35,7 @@ #include "rdg.h" #include "../rdp.h" +#include "../../crypto/opensslcompat.h" #define TAG FREERDP_TAG("core.gateway.rdg") @@ -1389,7 +1390,7 @@ long rdg_bio_callback(BIO* bio, int mode, const char* argp, int argi, long argl, static int rdg_bio_write(BIO* bio, const char* buf, int num) { int status; - rdpRdg* rdg = (rdpRdg*) bio->ptr; + rdpRdg* rdg = (rdpRdg*) BIO_get_data(bio); BIO_clear_flags(bio, BIO_FLAGS_WRITE); @@ -1418,7 +1419,7 @@ static int rdg_bio_write(BIO* bio, const char* buf, int num) static int rdg_bio_read(BIO* bio, char* buf, int size) { int status; - rdpRdg* rdg = (rdpRdg*) bio->ptr; + rdpRdg* rdg = (rdpRdg*) BIO_get_data(bio); status = rdg_read_data_packet(rdg, (BYTE*) buf, size); @@ -1454,7 +1455,7 @@ static int rdg_bio_gets(BIO* bio, char* str, int size) static long rdg_bio_ctrl(BIO* bio, int cmd, long arg1, void* arg2) { int status = 0; - rdpRdg* rdg = (rdpRdg*)bio->ptr; + rdpRdg* rdg = (rdpRdg*) BIO_get_data(bio); rdpTls* tlsOut = rdg->tlsOut; rdpTls* tlsIn = rdg->tlsIn; @@ -1516,10 +1517,8 @@ static long rdg_bio_ctrl(BIO* bio, int cmd, long arg1, void* arg2) static int rdg_bio_new(BIO* bio) { - bio->init = 1; - bio->num = 0; - bio->ptr = NULL; - bio->flags = BIO_FLAGS_SHOULD_RETRY; + BIO_set_init(bio, 1); + BIO_set_flags(bio, BIO_FLAGS_SHOULD_RETRY); return 1; } @@ -1528,23 +1527,25 @@ static int rdg_bio_free(BIO* bio) return 1; } -static BIO_METHOD rdg_bio_methods = -{ - BIO_TYPE_TSG, - "RDGateway", - rdg_bio_write, - rdg_bio_read, - rdg_bio_puts, - rdg_bio_gets, - rdg_bio_ctrl, - rdg_bio_new, - rdg_bio_free, - NULL, -}; - BIO_METHOD* BIO_s_rdg(void) { - return &rdg_bio_methods; + static BIO_METHOD* bio_methods = NULL; + + if (bio_methods == NULL) + { + if (!(bio_methods = BIO_meth_new(BIO_TYPE_TSG, "RDGateway"))) + return NULL; + + BIO_meth_set_write(bio_methods, rdg_bio_write); + BIO_meth_set_read(bio_methods, rdg_bio_read); + BIO_meth_set_puts(bio_methods, rdg_bio_puts); + BIO_meth_set_gets(bio_methods, rdg_bio_gets); + BIO_meth_set_ctrl(bio_methods, rdg_bio_ctrl); + BIO_meth_set_create(bio_methods, rdg_bio_new); + BIO_meth_set_destroy(bio_methods, rdg_bio_free); + } + + return bio_methods; } rdpRdg* rdg_new(rdpTransport* transport) @@ -1610,7 +1611,7 @@ rdpRdg* rdg_new(rdpTransport* transport) if (!rdg->frontBio) goto rdg_alloc_error; - rdg->frontBio->ptr = rdg; + BIO_set_data(rdg->frontBio, rdg); rdg->readEvent = CreateEvent(NULL, TRUE, FALSE, NULL); diff --git a/libfreerdp/core/gateway/tsg.c b/libfreerdp/core/gateway/tsg.c index 3b3064278..2a0a1e265 100644 --- a/libfreerdp/core/gateway/tsg.c +++ b/libfreerdp/core/gateway/tsg.c @@ -35,6 +35,7 @@ #include "rpc_bind.h" #include "rpc_client.h" #include "tsg.h" +#include "../../crypto/opensslcompat.h" #define TAG FREERDP_TAG("core.gateway.tsg") @@ -1770,7 +1771,7 @@ BOOL tsg_connect(rdpTsg* tsg, const char* hostname, UINT16 port, int timeout) if (!tsg->bio) return FALSE; - tsg->bio->ptr = (void*) tsg; + BIO_set_data(tsg->bio, (void*) tsg); return TRUE; } @@ -1937,7 +1938,7 @@ long transport_bio_tsg_callback(BIO* bio, int mode, const char* argp, int argi, static int transport_bio_tsg_write(BIO* bio, const char* buf, int num) { int status; - rdpTsg* tsg = (rdpTsg*) bio->ptr; + rdpTsg* tsg = (rdpTsg*) BIO_get_data(bio); BIO_clear_flags(bio, BIO_FLAGS_WRITE); @@ -1964,7 +1965,7 @@ static int transport_bio_tsg_write(BIO* bio, const char* buf, int num) static int transport_bio_tsg_read(BIO* bio, char* buf, int size) { int status; - rdpTsg* tsg = (rdpTsg*) bio->ptr; + rdpTsg* tsg = (rdpTsg*) BIO_get_data(bio); BIO_clear_flags(bio, BIO_FLAGS_READ); @@ -2001,7 +2002,7 @@ static int transport_bio_tsg_gets(BIO* bio, char* str, int size) static long transport_bio_tsg_ctrl(BIO* bio, int cmd, long arg1, void* arg2) { int status = 0; - rdpTsg* tsg = (rdpTsg*) bio->ptr; + rdpTsg* tsg = (rdpTsg*) BIO_get_data(bio); RpcVirtualConnection* connection = tsg->rpc->VirtualConnection; RpcInChannel* inChannel = connection->DefaultInChannel; RpcOutChannel* outChannel = connection->DefaultOutChannel; @@ -2064,10 +2065,8 @@ static long transport_bio_tsg_ctrl(BIO* bio, int cmd, long arg1, void* arg2) static int transport_bio_tsg_new(BIO* bio) { - bio->init = 1; - bio->num = 0; - bio->ptr = NULL; - bio->flags = BIO_FLAGS_SHOULD_RETRY; + BIO_set_init(bio, 1); + BIO_set_flags(bio, BIO_FLAGS_SHOULD_RETRY); return 1; } @@ -2076,21 +2075,23 @@ static int transport_bio_tsg_free(BIO* bio) return 1; } -static BIO_METHOD transport_bio_tsg_methods = -{ - BIO_TYPE_TSG, - "TSGateway", - transport_bio_tsg_write, - transport_bio_tsg_read, - transport_bio_tsg_puts, - transport_bio_tsg_gets, - transport_bio_tsg_ctrl, - transport_bio_tsg_new, - transport_bio_tsg_free, - NULL, -}; - BIO_METHOD* BIO_s_tsg(void) { - return &transport_bio_tsg_methods; + static BIO_METHOD* bio_methods = NULL; + + if (bio_methods == NULL) + { + if (!(bio_methods = BIO_meth_new(BIO_TYPE_TSG, "TSGateway"))) + return NULL; + + BIO_meth_set_write(bio_methods, transport_bio_tsg_write); + BIO_meth_set_read(bio_methods, transport_bio_tsg_read); + BIO_meth_set_puts(bio_methods, transport_bio_tsg_puts); + BIO_meth_set_gets(bio_methods, transport_bio_tsg_gets); + BIO_meth_set_ctrl(bio_methods, transport_bio_tsg_ctrl); + BIO_meth_set_create(bio_methods, transport_bio_tsg_new); + BIO_meth_set_destroy(bio_methods, transport_bio_tsg_free); + } + + return bio_methods; } diff --git a/libfreerdp/core/gcc.c b/libfreerdp/core/gcc.c index 2d92e1d9c..c020be07a 100644 --- a/libfreerdp/core/gcc.c +++ b/libfreerdp/core/gcc.c @@ -1265,7 +1265,6 @@ const BYTE tssk_exponent[] = BOOL gcc_write_server_security_data(wStream* s, rdpMcs* mcs) { - WINPR_MD5_CTX md5; BYTE* sigData; int expLen, keyLen, sigDataLen; BYTE encryptedSignature[TSSK_KEY_LENGTH]; @@ -1474,13 +1473,7 @@ BOOL gcc_write_server_security_data(wStream* s, rdpMcs* mcs) Stream_Write_UINT16(s, sizeof(encryptedSignature) + 8); /* wSignatureBlobLen */ memcpy(signature, initial_signature, sizeof(initial_signature)); - if (!winpr_MD5_Init(&md5)) - return FALSE; - - if (!winpr_MD5_Update(&md5, sigData, sigDataLen)) - return FALSE; - - if (!winpr_MD5_Final(&md5, signature, sizeof(signature))) + if (!winpr_Digest(WINPR_MD_MD5, sigData, sigDataLen, signature, sizeof(signature))) return FALSE; crypto_rsa_private_encrypt(signature, sizeof(signature), TSSK_KEY_LENGTH, diff --git a/libfreerdp/core/info.c b/libfreerdp/core/info.c index 6e1433f0f..4b5ee5f5c 100644 --- a/libfreerdp/core/info.c +++ b/libfreerdp/core/info.c @@ -45,7 +45,7 @@ static const char* const INFO_TYPE_LOGON_STRINGS[4] = BOOL rdp_compute_client_auto_reconnect_cookie(rdpRdp* rdp) { - WINPR_HMAC_CTX hmac; + WINPR_HMAC_CTX* hmac; BYTE ClientRandom[32]; BYTE AutoReconnectRandom[32]; ARC_SC_PRIVATE_PACKET* serverCookie; @@ -70,11 +70,11 @@ BOOL rdp_compute_client_auto_reconnect_cookie(rdpRdp* rdp) /* SecurityVerifier = HMAC_MD5(AutoReconnectRandom, ClientRandom) */ - if (!winpr_HMAC_Init(&hmac, WINPR_MD_MD5, AutoReconnectRandom, 16)) + if (!(hmac = winpr_HMAC_New(WINPR_MD_MD5, AutoReconnectRandom, 16))) return FALSE; - if (!winpr_HMAC_Update(&hmac, ClientRandom, 32)) + if (!winpr_HMAC_Update(hmac, ClientRandom, 32)) return FALSE; - if (!winpr_HMAC_Final(&hmac, clientCookie->securityVerifier, 16)) + if (!winpr_HMAC_Final(hmac, clientCookie->securityVerifier, 16)) return FALSE; return TRUE; diff --git a/libfreerdp/core/license.c b/libfreerdp/core/license.c index 055a2dc3e..0d467067c 100644 --- a/libfreerdp/core/license.c +++ b/libfreerdp/core/license.c @@ -385,17 +385,12 @@ BOOL license_generate_keys(rdpLicense* license) BOOL license_generate_hwid(rdpLicense* license) { - WINPR_MD5_CTX md5; BYTE macAddress[6]; ZeroMemory(macAddress, sizeof(macAddress)); ZeroMemory(license->HardwareId, HWID_LENGTH); - if (!winpr_MD5_Init(&md5)) - return FALSE; - if (!winpr_MD5_Update(&md5, macAddress, sizeof(macAddress))) - return FALSE; - if (!winpr_MD5_Final(&md5, &license->HardwareId[HWID_PLATFORM_ID_LENGTH], WINPR_MD5_DIGEST_LENGTH)) + if (!winpr_Digest(WINPR_MD_MD5, macAddress, sizeof(macAddress), &license->HardwareId[HWID_PLATFORM_ID_LENGTH], WINPR_MD5_DIGEST_LENGTH)) return FALSE; return TRUE; diff --git a/libfreerdp/core/nla.h b/libfreerdp/core/nla.h index 285bb128f..559add7fe 100644 --- a/libfreerdp/core/nla.h +++ b/libfreerdp/core/nla.h @@ -80,7 +80,6 @@ struct rdp_nla SecBuffer authInfo; SecBuffer PublicKey; SecBuffer tsCredentials; - WINPR_RC4_CTX rc4SealState; LPTSTR ServicePrincipalName; SEC_WINNT_AUTH_IDENTITY* identity; PSecurityFunctionTable table; diff --git a/libfreerdp/core/rdp.c b/libfreerdp/core/rdp.c index e7c5bd242..64d554e79 100644 --- a/libfreerdp/core/rdp.c +++ b/libfreerdp/core/rdp.c @@ -1646,12 +1646,6 @@ void rdp_reset(rdpRdp* rdp) rdp->fips_decrypt = NULL; } - if (rdp->fips_hmac) - { - free(rdp->fips_hmac); - rdp->fips_hmac = NULL; - } - if (settings->ServerRandom) { free(settings->ServerRandom); @@ -1699,7 +1693,6 @@ void rdp_free(rdpRdp* rdp) winpr_RC4_Free(rdp->rc4_encrypt_key); winpr_Cipher_Free(rdp->fips_encrypt); winpr_Cipher_Free(rdp->fips_decrypt); - free(rdp->fips_hmac); freerdp_settings_free(rdp->settings); freerdp_settings_free(rdp->settingsCopy); transport_free(rdp->transport); diff --git a/libfreerdp/core/rdp.h b/libfreerdp/core/rdp.h index 687b1339b..0f1f6f101 100644 --- a/libfreerdp/core/rdp.h +++ b/libfreerdp/core/rdp.h @@ -157,7 +157,6 @@ struct rdp_rdp int encrypt_checksum_use_count; WINPR_CIPHER_CTX* fips_encrypt; WINPR_CIPHER_CTX* fips_decrypt; - WINPR_HMAC_CTX* fips_hmac; UINT32 sec_flags; BOOL do_crypt; BOOL do_crypt_license; diff --git a/libfreerdp/core/security.c b/libfreerdp/core/security.c index e41578687..4d5a03e47 100644 --- a/libfreerdp/core/security.c +++ b/libfreerdp/core/security.c @@ -127,34 +127,34 @@ fips_oddparity_table[256] = static BOOL security_salted_hash(const BYTE* salt, const BYTE* input, int length, const BYTE* salt1, const BYTE* salt2, BYTE* output) { - WINPR_MD5_CTX md5; - WINPR_SHA1_CTX sha1; + WINPR_DIGEST_CTX* md5; + WINPR_DIGEST_CTX* sha1; BYTE sha1_digest[WINPR_SHA1_DIGEST_LENGTH]; /* SaltedHash(Salt, Input, Salt1, Salt2) = MD5(S + SHA1(Input + Salt + Salt1 + Salt2)) */ /* SHA1_Digest = SHA1(Input + Salt + Salt1 + Salt2) */ - if (!winpr_SHA1_Init(&sha1)) + if (!(sha1 = winpr_Digest_New(WINPR_MD_SHA1))) return FALSE; - if (!winpr_SHA1_Update(&sha1, input, length)) /* Input */ + if (!winpr_Digest_Update(sha1, input, length)) /* Input */ return FALSE; - if (!winpr_SHA1_Update(&sha1, salt, 48)) /* Salt (48 bytes) */ + if (!winpr_Digest_Update(sha1, salt, 48)) /* Salt (48 bytes) */ return FALSE; - if (!winpr_SHA1_Update(&sha1, salt1, 32)) /* Salt1 (32 bytes) */ + if (!winpr_Digest_Update(sha1, salt1, 32)) /* Salt1 (32 bytes) */ return FALSE; - if (!winpr_SHA1_Update(&sha1, salt2, 32)) /* Salt2 (32 bytes) */ + if (!winpr_Digest_Update(sha1, salt2, 32)) /* Salt2 (32 bytes) */ return FALSE; - if (!winpr_SHA1_Final(&sha1, sha1_digest, sizeof(sha1_digest))) + if (!winpr_Digest_Final(sha1, sha1_digest, sizeof(sha1_digest))) return FALSE; /* SaltedHash(Salt, Input, Salt1, Salt2) = MD5(S + SHA1_Digest) */ - if (!winpr_MD5_Init(&md5)) + if (!(md5 = winpr_Digest_New(WINPR_MD_MD5))) return FALSE; - if (!winpr_MD5_Update(&md5, salt, 48)) /* Salt (48 bytes) */ + if (!winpr_Digest_Update(md5, salt, 48)) /* Salt (48 bytes) */ return FALSE; - if (!winpr_MD5_Update(&md5, sha1_digest, sizeof(sha1_digest))) /* SHA1_Digest */ + if (!winpr_Digest_Update(md5, sha1_digest, sizeof(sha1_digest))) /* SHA1_Digest */ return FALSE; - if (!winpr_MD5_Final(&md5, output, WINPR_MD5_DIGEST_LENGTH)) + if (!winpr_Digest_Final(md5, output, WINPR_MD5_DIGEST_LENGTH)) return FALSE; return TRUE; } @@ -200,17 +200,17 @@ void security_mac_salt_key(const BYTE* session_key_blob, const BYTE* client_rand BOOL security_md5_16_32_32(const BYTE* in0, const BYTE* in1, const BYTE* in2, BYTE* output) { - WINPR_MD5_CTX md5; + WINPR_DIGEST_CTX* md5; - if (!winpr_MD5_Init(&md5)) + if (!(md5 = winpr_Digest_New(WINPR_MD_MD5))) return FALSE; - if (!winpr_MD5_Update(&md5, in0, 16)) + if (!winpr_Digest_Update(md5, in0, 16)) return FALSE; - if (!winpr_MD5_Update(&md5, in1, 32)) + if (!winpr_Digest_Update(md5, in1, 32)) return FALSE; - if (!winpr_MD5_Update(&md5, in2, 32)) + if (!winpr_Digest_Update(md5, in2, 32)) return FALSE; - if (!winpr_MD5_Final(&md5, output, WINPR_MD5_DIGEST_LENGTH)) + if (!winpr_Digest_Final(md5, output, WINPR_MD5_DIGEST_LENGTH)) return FALSE; return TRUE; } @@ -233,8 +233,8 @@ void security_UINT32_le(BYTE* output, UINT32 value) BOOL security_mac_data(const BYTE* mac_salt_key, const BYTE* data, UINT32 length, BYTE* output) { - WINPR_MD5_CTX md5; - WINPR_SHA1_CTX sha1; + WINPR_DIGEST_CTX* md5; + WINPR_DIGEST_CTX* sha1; BYTE length_le[4]; BYTE sha1_digest[WINPR_SHA1_DIGEST_LENGTH]; @@ -243,37 +243,37 @@ BOOL security_mac_data(const BYTE* mac_salt_key, const BYTE* data, UINT32 length security_UINT32_le(length_le, length); /* length must be little-endian */ /* SHA1_Digest = SHA1(MacSaltKey + pad1 + length + data) */ - if (!winpr_SHA1_Init(&sha1)) + if (!(sha1 = winpr_Digest_New(WINPR_MD_SHA1))) return FALSE; - if (!winpr_SHA1_Update(&sha1, mac_salt_key, 16)) /* MacSaltKey */ + if (!winpr_Digest_Update(sha1, mac_salt_key, 16)) /* MacSaltKey */ return FALSE; - if (!winpr_SHA1_Update(&sha1, pad1, sizeof(pad1))) /* pad1 */ + if (!winpr_Digest_Update(sha1, pad1, sizeof(pad1))) /* pad1 */ return FALSE; - if (!winpr_SHA1_Update(&sha1, length_le, sizeof(length_le))) /* length */ + if (!winpr_Digest_Update(sha1, length_le, sizeof(length_le))) /* length */ return FALSE; - if (!winpr_SHA1_Update(&sha1, data, length)) /* data */ + if (!winpr_Digest_Update(sha1, data, length)) /* data */ return FALSE; - if (!winpr_SHA1_Final(&sha1, sha1_digest, sizeof(sha1_digest))) + if (!winpr_Digest_Final(sha1, sha1_digest, sizeof(sha1_digest))) return FALSE; /* MacData = MD5(MacSaltKey + pad2 + SHA1_Digest) */ - if (!winpr_MD5_Init(&md5)) + if (!(md5 = winpr_Digest_New(WINPR_MD_MD5))) return FALSE; - if (!winpr_MD5_Update(&md5, mac_salt_key, 16)) /* MacSaltKey */ + if (!winpr_Digest_Update(md5, mac_salt_key, 16)) /* MacSaltKey */ return FALSE; - if (!winpr_MD5_Update(&md5, pad2, sizeof(pad2))) /* pad2 */ + if (!winpr_Digest_Update(md5, pad2, sizeof(pad2))) /* pad2 */ return FALSE; - if (!winpr_MD5_Update(&md5, sha1_digest, sizeof(sha1_digest))) /* SHA1_Digest */ + if (!winpr_Digest_Update(md5, sha1_digest, sizeof(sha1_digest))) /* SHA1_Digest */ return FALSE; - if (!winpr_MD5_Final(&md5, output, WINPR_MD5_DIGEST_LENGTH)) + if (!winpr_Digest_Final(md5, output, WINPR_MD5_DIGEST_LENGTH)) return FALSE; return TRUE; } BOOL security_mac_signature(rdpRdp *rdp, const BYTE* data, UINT32 length, BYTE* output) { - WINPR_MD5_CTX md5; - WINPR_SHA1_CTX sha1; + WINPR_DIGEST_CTX* md5; + WINPR_DIGEST_CTX* sha1; BYTE length_le[4]; BYTE md5_digest[WINPR_MD5_DIGEST_LENGTH]; BYTE sha1_digest[WINPR_SHA1_DIGEST_LENGTH]; @@ -281,29 +281,29 @@ BOOL security_mac_signature(rdpRdp *rdp, const BYTE* data, UINT32 length, BYTE* security_UINT32_le(length_le, length); /* length must be little-endian */ /* SHA1_Digest = SHA1(MACKeyN + pad1 + length + data) */ - if (!winpr_SHA1_Init(&sha1)) + if (!(sha1 = winpr_Digest_New(WINPR_MD_SHA1))) return FALSE; - if (!winpr_SHA1_Update(&sha1, rdp->sign_key, rdp->rc4_key_len)) /* MacKeyN */ + if (!winpr_Digest_Update(sha1, rdp->sign_key, rdp->rc4_key_len)) /* MacKeyN */ return FALSE; - if (!winpr_SHA1_Update(&sha1, pad1, sizeof(pad1))) /* pad1 */ + if (!winpr_Digest_Update(sha1, pad1, sizeof(pad1))) /* pad1 */ return FALSE; - if (!winpr_SHA1_Update(&sha1, length_le, sizeof(length_le))) /* length */ + if (!winpr_Digest_Update(sha1, length_le, sizeof(length_le))) /* length */ return FALSE; - if (!winpr_SHA1_Update(&sha1, data, length)) /* data */ + if (!winpr_Digest_Update(sha1, data, length)) /* data */ return FALSE; - if (!winpr_SHA1_Final(&sha1, sha1_digest, sizeof(sha1_digest))) + if (!winpr_Digest_Final(sha1, sha1_digest, sizeof(sha1_digest))) return FALSE; /* MACSignature = First64Bits(MD5(MACKeyN + pad2 + SHA1_Digest)) */ - if (!winpr_MD5_Init(&md5)) + if (!(md5 = winpr_Digest_New(WINPR_MD_MD5))) return FALSE; - if (!winpr_MD5_Update(&md5, rdp->sign_key, rdp->rc4_key_len)) /* MacKeyN */ + if (!winpr_Digest_Update(md5, rdp->sign_key, rdp->rc4_key_len)) /* MacKeyN */ return FALSE; - if (!winpr_MD5_Update(&md5, pad2, sizeof(pad2))) /* pad2 */ + if (!winpr_Digest_Update(md5, pad2, sizeof(pad2))) /* pad2 */ return FALSE; - if (!winpr_MD5_Update(&md5, sha1_digest, sizeof(sha1_digest))) /* SHA1_Digest */ + if (!winpr_Digest_Update(md5, sha1_digest, sizeof(sha1_digest))) /* SHA1_Digest */ return FALSE; - if (!winpr_MD5_Final(&md5, md5_digest, sizeof(md5_digest))) + if (!winpr_Digest_Final(md5, md5_digest, sizeof(md5_digest))) return FALSE; memcpy(output, md5_digest, 8); @@ -313,8 +313,8 @@ BOOL security_mac_signature(rdpRdp *rdp, const BYTE* data, UINT32 length, BYTE* BOOL security_salted_mac_signature(rdpRdp *rdp, const BYTE* data, UINT32 length, BOOL encryption, BYTE* output) { - WINPR_MD5_CTX md5; - WINPR_SHA1_CTX sha1; + WINPR_DIGEST_CTX* md5; + WINPR_DIGEST_CTX* sha1; BYTE length_le[4]; BYTE use_count_le[4]; BYTE md5_digest[WINPR_MD5_DIGEST_LENGTH]; @@ -336,31 +336,31 @@ BOOL security_salted_mac_signature(rdpRdp *rdp, const BYTE* data, UINT32 length, } /* SHA1_Digest = SHA1(MACKeyN + pad1 + length + data) */ - if (!winpr_SHA1_Init(&sha1)) + if (!(sha1 = winpr_Digest_New( WINPR_MD_SHA1))) return FALSE; - if (!winpr_SHA1_Update(&sha1, rdp->sign_key, rdp->rc4_key_len)) /* MacKeyN */ + if (!winpr_Digest_Update(sha1, rdp->sign_key, rdp->rc4_key_len)) /* MacKeyN */ return FALSE; - if (!winpr_SHA1_Update(&sha1, pad1, sizeof(pad1))) /* pad1 */ + if (!winpr_Digest_Update(sha1, pad1, sizeof(pad1))) /* pad1 */ return FALSE; - if (!winpr_SHA1_Update(&sha1, length_le, sizeof(length_le))) /* length */ + if (!winpr_Digest_Update(sha1, length_le, sizeof(length_le))) /* length */ return FALSE; - if (!winpr_SHA1_Update(&sha1, data, length)) /* data */ + if (!winpr_Digest_Update(sha1, data, length)) /* data */ return FALSE; - if (!winpr_SHA1_Update(&sha1, use_count_le, sizeof(use_count_le))) /* encryptionCount */ + if (!winpr_Digest_Update(sha1, use_count_le, sizeof(use_count_le))) /* encryptionCount */ return FALSE; - if (!winpr_SHA1_Final(&sha1, sha1_digest, sizeof(sha1_digest))) + if (!winpr_Digest_Final(sha1, sha1_digest, sizeof(sha1_digest))) return FALSE; /* MACSignature = First64Bits(MD5(MACKeyN + pad2 + SHA1_Digest)) */ - if (!winpr_MD5_Init(&md5)) + if (!(md5 = winpr_Digest_New(WINPR_MD_MD5))) return FALSE; - if (!winpr_MD5_Update(&md5, rdp->sign_key, rdp->rc4_key_len)) /* MacKeyN */ + if (!winpr_Digest_Update(md5, rdp->sign_key, rdp->rc4_key_len)) /* MacKeyN */ return FALSE; - if (!winpr_MD5_Update(&md5, pad2, sizeof(pad2))) /* pad2 */ + if (!winpr_Digest_Update(md5, pad2, sizeof(pad2))) /* pad2 */ return FALSE; - if (!winpr_MD5_Update(&md5, sha1_digest, sizeof(sha1_digest))) /* SHA1_Digest */ + if (!winpr_Digest_Update(md5, sha1_digest, sizeof(sha1_digest))) /* SHA1_Digest */ return FALSE; - if (!winpr_MD5_Final(&md5, md5_digest, sizeof(md5_digest))) + if (!winpr_Digest_Final(md5, md5_digest, sizeof(md5_digest))) return FALSE; memcpy(output, md5_digest, 8); @@ -433,37 +433,37 @@ BOOL security_establish_keys(const BYTE* client_random, rdpRdp* rdp) if (settings->EncryptionMethods == ENCRYPTION_METHOD_FIPS) { - WINPR_SHA1_CTX sha1; + WINPR_DIGEST_CTX* sha1; BYTE client_encrypt_key_t[WINPR_SHA1_DIGEST_LENGTH + 1]; BYTE client_decrypt_key_t[WINPR_SHA1_DIGEST_LENGTH + 1]; - if (!winpr_SHA1_Init(&sha1)) + if (!(sha1 = winpr_Digest_New(WINPR_MD_SHA1))) return FALSE; - if (!winpr_SHA1_Update(&sha1, client_random + 16, 16)) + if (!winpr_Digest_Update(sha1, client_random + 16, 16)) return FALSE; - if (!winpr_SHA1_Update(&sha1, server_random + 16, 16)) + if (!winpr_Digest_Update(sha1, server_random + 16, 16)) return FALSE; - if (!winpr_SHA1_Final(&sha1, client_encrypt_key_t, sizeof(client_encrypt_key_t))) + if (!winpr_Digest_Final(sha1, client_encrypt_key_t, sizeof(client_encrypt_key_t))) return FALSE; client_encrypt_key_t[20] = client_encrypt_key_t[0]; - if (!winpr_SHA1_Init(&sha1)) + if (!(sha1 = winpr_Digest_New(WINPR_MD_SHA1))) return FALSE; - if (!winpr_SHA1_Update(&sha1, client_random, 16)) + if (!winpr_Digest_Update(sha1, client_random, 16)) return FALSE; - if (!winpr_SHA1_Update(&sha1, server_random, 16)) + if (!winpr_Digest_Update(sha1, server_random, 16)) return FALSE; - if (!winpr_SHA1_Final(&sha1, client_decrypt_key_t, sizeof(client_decrypt_key_t))) + if (!winpr_Digest_Final(sha1, client_decrypt_key_t, sizeof(client_decrypt_key_t))) return FALSE; client_decrypt_key_t[20] = client_decrypt_key_t[0]; - if (!winpr_SHA1_Init(&sha1)) + if (!(sha1 = winpr_Digest_New(WINPR_MD_SHA1))) return FALSE; - if (!winpr_SHA1_Update(&sha1, client_decrypt_key_t, WINPR_SHA1_DIGEST_LENGTH)) + if (!winpr_Digest_Update(sha1, client_decrypt_key_t, WINPR_SHA1_DIGEST_LENGTH)) return FALSE; - if (!winpr_SHA1_Update(&sha1, client_encrypt_key_t, WINPR_SHA1_DIGEST_LENGTH)) + if (!winpr_Digest_Update(sha1, client_encrypt_key_t, WINPR_SHA1_DIGEST_LENGTH)) return FALSE; - if (!winpr_SHA1_Final(&sha1, rdp->fips_sign_key, WINPR_SHA1_DIGEST_LENGTH)) + if (!winpr_Digest_Final(sha1, rdp->fips_sign_key, WINPR_SHA1_DIGEST_LENGTH)) return FALSE; if (rdp->settings->ServerMode) @@ -536,35 +536,35 @@ BOOL security_establish_keys(const BYTE* client_random, rdpRdp* rdp) BOOL security_key_update(BYTE* key, BYTE* update_key, int key_len, rdpRdp* rdp) { BYTE sha1h[WINPR_SHA1_DIGEST_LENGTH]; - WINPR_MD5_CTX md5; - WINPR_SHA1_CTX sha1; + WINPR_DIGEST_CTX* md5; + WINPR_DIGEST_CTX* sha1; WINPR_RC4_CTX* rc4; BOOL rc; BYTE salt[] = { 0xD1, 0x26, 0x9E }; /* 40 bits: 3 bytes, 56 bits: 1 byte */ - if (!winpr_SHA1_Init(&sha1)) + if (!(sha1 = winpr_Digest_New(WINPR_MD_SHA1))) return FALSE; - if (!winpr_SHA1_Update(&sha1, update_key, key_len)) + if (!winpr_Digest_Update(sha1, update_key, key_len)) return FALSE; - if (!winpr_SHA1_Update(&sha1, pad1, sizeof(pad1))) + if (!winpr_Digest_Update(sha1, pad1, sizeof(pad1))) return FALSE; - if (!winpr_SHA1_Update(&sha1, key, key_len)) + if (!winpr_Digest_Update(sha1, key, key_len)) return FALSE; - if (!winpr_SHA1_Final(&sha1, sha1h, sizeof(sha1h))) + if (!winpr_Digest_Final(sha1, sha1h, sizeof(sha1h))) return FALSE; - if (!winpr_MD5_Init(&md5)) + if (!(md5 = winpr_Digest_New(WINPR_MD_MD5))) return FALSE; - if (!winpr_MD5_Update(&md5, update_key, key_len)) + if (!winpr_Digest_Update(md5, update_key, key_len)) return FALSE; - if (!winpr_MD5_Update(&md5, pad2, sizeof(pad2))) + if (!winpr_Digest_Update(md5, pad2, sizeof(pad2))) return FALSE; - if (!winpr_MD5_Update(&md5, sha1h, sizeof(sha1h))) + if (!winpr_Digest_Update(md5, sha1h, sizeof(sha1h))) return FALSE; - if (!winpr_MD5_Final(&md5, key, WINPR_MD5_DIGEST_LENGTH)) + if (!winpr_Digest_Final(md5, key, WINPR_MD5_DIGEST_LENGTH)) return FALSE; - if ((rc4 = winpr_RC4_New(key, key_len)) == NULL) + if (!(rc4 = winpr_RC4_New(key, key_len))) return FALSE; rc = winpr_RC4_Update(rc4, key_len, key, key); winpr_RC4_Free(rc4); @@ -630,17 +630,17 @@ BOOL security_hmac_signature(const BYTE* data, int length, BYTE* output, rdpRdp* { BYTE buf[WINPR_SHA1_DIGEST_LENGTH]; BYTE use_count_le[4]; + WINPR_HMAC_CTX* hmac; security_UINT32_le(use_count_le, rdp->encrypt_use_count); - if (!winpr_HMAC_Init(rdp->fips_hmac, WINPR_MD_SHA1, - rdp->fips_sign_key, WINPR_SHA1_DIGEST_LENGTH)) + if (!(hmac = winpr_HMAC_New(WINPR_MD_SHA1, rdp->fips_sign_key, WINPR_SHA1_DIGEST_LENGTH))) return FALSE; - if (!winpr_HMAC_Update(rdp->fips_hmac, data, length)) + if (!winpr_HMAC_Update(hmac, data, length)) return FALSE; - if (!winpr_HMAC_Update(rdp->fips_hmac, use_count_le, 4)) + if (!winpr_HMAC_Update(hmac, use_count_le, 4)) return FALSE; - if (!winpr_HMAC_Final(rdp->fips_hmac, buf, WINPR_SHA1_DIGEST_LENGTH)) + if (!winpr_HMAC_Final(hmac, buf, WINPR_SHA1_DIGEST_LENGTH)) return FALSE; memmove(output, buf, 8); @@ -670,17 +670,17 @@ BOOL security_fips_check_signature(const BYTE* data, int length, const BYTE* sig { BYTE buf[WINPR_SHA1_DIGEST_LENGTH]; BYTE use_count_le[4]; + WINPR_HMAC_CTX* hmac; security_UINT32_le(use_count_le, rdp->decrypt_use_count); - if (!winpr_HMAC_Init(rdp->fips_hmac, WINPR_MD_SHA1, - rdp->fips_sign_key, WINPR_SHA1_DIGEST_LENGTH)) + if (!(hmac = winpr_HMAC_New(WINPR_MD_SHA1, rdp->fips_sign_key, WINPR_SHA1_DIGEST_LENGTH))) return FALSE; - if (!winpr_HMAC_Update(rdp->fips_hmac, data, length)) + if (!winpr_HMAC_Update(hmac, data, length)) return FALSE; - if (!winpr_HMAC_Update(rdp->fips_hmac, use_count_le, 4)) + if (!winpr_HMAC_Update(hmac, use_count_le, 4)) return FALSE; - if (!winpr_HMAC_Final(rdp->fips_hmac, buf, WINPR_SHA1_DIGEST_LENGTH)) + if (!winpr_HMAC_Final(hmac, buf, WINPR_SHA1_DIGEST_LENGTH)) return FALSE; rdp->decrypt_use_count++; diff --git a/libfreerdp/core/tcp.c b/libfreerdp/core/tcp.c index 021722744..12a33cff2 100644 --- a/libfreerdp/core/tcp.c +++ b/libfreerdp/core/tcp.c @@ -84,6 +84,7 @@ #include #include "tcp.h" +#include "../crypto/opensslcompat.h" #define TAG FREERDP_TAG("core") @@ -108,7 +109,7 @@ static int transport_bio_simple_write(BIO* bio, const char* buf, int size) { int error; int status = 0; - WINPR_BIO_SIMPLE_SOCKET* ptr = (WINPR_BIO_SIMPLE_SOCKET*) bio->ptr; + WINPR_BIO_SIMPLE_SOCKET* ptr = (WINPR_BIO_SIMPLE_SOCKET*) BIO_get_data(bio); if (!buf) return 0; @@ -139,7 +140,7 @@ static int transport_bio_simple_read(BIO* bio, char* buf, int size) { int error; int status = 0; - WINPR_BIO_SIMPLE_SOCKET* ptr = (WINPR_BIO_SIMPLE_SOCKET*) bio->ptr; + WINPR_BIO_SIMPLE_SOCKET* ptr = (WINPR_BIO_SIMPLE_SOCKET*) BIO_get_data(bio); if (!buf) return 0; @@ -189,7 +190,7 @@ static int transport_bio_simple_gets(BIO* bio, char* str, int size) static long transport_bio_simple_ctrl(BIO* bio, int cmd, long arg1, void* arg2) { int status = -1; - WINPR_BIO_SIMPLE_SOCKET* ptr = (WINPR_BIO_SIMPLE_SOCKET*) bio->ptr; + WINPR_BIO_SIMPLE_SOCKET* ptr = (WINPR_BIO_SIMPLE_SOCKET*) BIO_get_data(bio); if (cmd == BIO_C_SET_SOCKET) { @@ -199,7 +200,7 @@ static long transport_bio_simple_ctrl(BIO* bio, int cmd, long arg1, void* arg2) } else if (cmd == BIO_C_GET_SOCKET) { - if (!bio->init || !arg2) + if (!BIO_get_init(bio) || !arg2) return 0; *((ULONG_PTR*) arg2) = (ULONG_PTR) ptr->socket; @@ -208,7 +209,7 @@ static long transport_bio_simple_ctrl(BIO* bio, int cmd, long arg1, void* arg2) } else if (cmd == BIO_C_GET_EVENT) { - if (!bio->init || !arg2) + if (!BIO_get_init(bio) || !arg2) return 0; *((ULONG_PTR*) arg2) = (ULONG_PTR) ptr->hEvent; @@ -319,7 +320,7 @@ static long transport_bio_simple_ctrl(BIO* bio, int cmd, long arg1, void* arg2) break; case BIO_C_GET_FD: - if (bio->init) + if (BIO_get_init(bio)) { if (arg2) *((int*) arg2) = (int) ptr->socket; @@ -328,11 +329,11 @@ static long transport_bio_simple_ctrl(BIO* bio, int cmd, long arg1, void* arg2) break; case BIO_CTRL_GET_CLOSE: - status = bio->shutdown; + status = BIO_get_shutdown(bio); break; case BIO_CTRL_SET_CLOSE: - bio->shutdown = (int) arg1; + BIO_set_shutdown(bio, (int) arg1); status = 1; break; @@ -354,13 +355,13 @@ static long transport_bio_simple_ctrl(BIO* bio, int cmd, long arg1, void* arg2) static int transport_bio_simple_init(BIO* bio, SOCKET socket, int shutdown) { - WINPR_BIO_SIMPLE_SOCKET* ptr = (WINPR_BIO_SIMPLE_SOCKET*) bio->ptr; + WINPR_BIO_SIMPLE_SOCKET* ptr = (WINPR_BIO_SIMPLE_SOCKET*) BIO_get_data(bio); ptr->socket = socket; - bio->shutdown = shutdown; - bio->flags = BIO_FLAGS_SHOULD_RETRY; - bio->init = 1; + BIO_set_shutdown(bio, shutdown); + BIO_set_flags(bio, BIO_FLAGS_SHOULD_RETRY); + BIO_set_init(bio, 1); ptr->hEvent = WSACreateEvent(); @@ -379,11 +380,11 @@ static int transport_bio_simple_init(BIO* bio, SOCKET socket, int shutdown) static int transport_bio_simple_uninit(BIO* bio) { - WINPR_BIO_SIMPLE_SOCKET* ptr = (WINPR_BIO_SIMPLE_SOCKET*) bio->ptr; + WINPR_BIO_SIMPLE_SOCKET* ptr = (WINPR_BIO_SIMPLE_SOCKET*) BIO_get_data(bio); - if (bio->shutdown) + if (BIO_get_shutdown(bio)) { - if (bio->init) + if (BIO_get_init(bio)) { _shutdown(ptr->socket, SD_BOTH); closesocket(ptr->socket); @@ -397,8 +398,8 @@ static int transport_bio_simple_uninit(BIO* bio) ptr->hEvent = NULL; } - bio->init = 0; - bio->flags = 0; + BIO_set_init(bio, 0); + BIO_set_flags(bio, 0); return 1; } @@ -407,53 +408,57 @@ static int transport_bio_simple_new(BIO* bio) { WINPR_BIO_SIMPLE_SOCKET* ptr; - bio->init = 0; - bio->ptr = NULL; - bio->flags = BIO_FLAGS_SHOULD_RETRY; + BIO_set_flags(bio, BIO_FLAGS_SHOULD_RETRY); ptr = (WINPR_BIO_SIMPLE_SOCKET*) calloc(1, sizeof(WINPR_BIO_SIMPLE_SOCKET)); if (!ptr) return 0; - bio->ptr = ptr; + BIO_set_data(bio, ptr); return 1; } static int transport_bio_simple_free(BIO* bio) { + WINPR_BIO_SIMPLE_SOCKET* ptr; + if (!bio) return 0; transport_bio_simple_uninit(bio); - if (bio->ptr) + ptr = (WINPR_BIO_SIMPLE_SOCKET*) BIO_get_data(bio); + + if (ptr) { - free(bio->ptr); - bio->ptr = NULL; + BIO_set_data(bio, NULL); + free(ptr); } return 1; } -static BIO_METHOD transport_bio_simple_socket_methods = -{ - BIO_TYPE_SIMPLE, - "SimpleSocket", - transport_bio_simple_write, - transport_bio_simple_read, - transport_bio_simple_puts, - transport_bio_simple_gets, - transport_bio_simple_ctrl, - transport_bio_simple_new, - transport_bio_simple_free, - NULL, -}; - BIO_METHOD* BIO_s_simple_socket(void) { - return &transport_bio_simple_socket_methods; + static BIO_METHOD* bio_methods = NULL; + + if (bio_methods == NULL) + { + if (!(bio_methods = BIO_meth_new(BIO_TYPE_SIMPLE, "SimpleSocket"))) + return NULL; + + BIO_meth_set_write(bio_methods, transport_bio_simple_write); + BIO_meth_set_read(bio_methods, transport_bio_simple_read); + BIO_meth_set_puts(bio_methods, transport_bio_simple_puts); + BIO_meth_set_gets(bio_methods, transport_bio_simple_gets); + BIO_meth_set_ctrl(bio_methods, transport_bio_simple_ctrl); + BIO_meth_set_create(bio_methods, transport_bio_simple_new); + BIO_meth_set_destroy(bio_methods, transport_bio_simple_free); + } + + return bio_methods; } /* Buffered Socket BIO */ @@ -479,7 +484,8 @@ static int transport_bio_buffered_write(BIO* bio, const char* buf, int num) int nchunks; int committedBytes; DataChunk chunks[2]; - WINPR_BIO_BUFFERED_SOCKET* ptr = (WINPR_BIO_BUFFERED_SOCKET*) bio->ptr; + WINPR_BIO_BUFFERED_SOCKET* ptr = (WINPR_BIO_BUFFERED_SOCKET*) BIO_get_data(bio); + BIO* next_bio = NULL; ret = num; ptr->writeBlocked = FALSE; @@ -496,23 +502,24 @@ static int transport_bio_buffered_write(BIO* bio, const char* buf, int num) committedBytes = 0; nchunks = ringbuffer_peek(&ptr->xmitBuffer, chunks, ringbuffer_used(&ptr->xmitBuffer)); + next_bio = BIO_next(bio); for (i = 0; i < nchunks; i++) { while (chunks[i].size) { - status = BIO_write(bio->next_bio, chunks[i].data, chunks[i].size); + status = BIO_write(next_bio, chunks[i].data, chunks[i].size); if (status <= 0) { - if (!BIO_should_retry(bio->next_bio)) + if (!BIO_should_retry(next_bio)) { BIO_clear_flags(bio, BIO_FLAGS_SHOULD_RETRY); ret = -1; /* fatal error */ goto out; } - if (BIO_should_write(bio->next_bio)) + if (BIO_should_write(next_bio)) { BIO_set_flags(bio, BIO_FLAGS_WRITE); ptr->writeBlocked = TRUE; @@ -535,16 +542,17 @@ out: static int transport_bio_buffered_read(BIO* bio, char* buf, int size) { int status; - WINPR_BIO_BUFFERED_SOCKET* ptr = (WINPR_BIO_BUFFERED_SOCKET*) bio->ptr; + WINPR_BIO_BUFFERED_SOCKET* ptr = (WINPR_BIO_BUFFERED_SOCKET*) BIO_get_data(bio); + BIO* next_bio = BIO_next(bio); ptr->readBlocked = FALSE; BIO_clear_flags(bio, BIO_FLAGS_READ); - status = BIO_read(bio->next_bio, buf, size); + status = BIO_read(next_bio, buf, size); if (status <= 0) { - if (!BIO_should_retry(bio->next_bio)) + if (!BIO_should_retry(next_bio)) { BIO_clear_flags(bio, BIO_FLAGS_SHOULD_RETRY); goto out; @@ -552,7 +560,7 @@ static int transport_bio_buffered_read(BIO* bio, char* buf, int size) BIO_set_flags(bio, BIO_FLAGS_SHOULD_RETRY); - if (BIO_should_read(bio->next_bio)) + if (BIO_should_read(next_bio)) { BIO_set_flags(bio, BIO_FLAGS_READ); ptr->readBlocked = TRUE; @@ -577,7 +585,7 @@ static int transport_bio_buffered_gets(BIO* bio, char* str, int size) static long transport_bio_buffered_ctrl(BIO* bio, int cmd, long arg1, void* arg2) { int status = -1; - WINPR_BIO_BUFFERED_SOCKET* ptr = (WINPR_BIO_BUFFERED_SOCKET*) bio->ptr; + WINPR_BIO_BUFFERED_SOCKET* ptr = (WINPR_BIO_BUFFERED_SOCKET*) BIO_get_data(bio); switch (cmd) { @@ -605,7 +613,7 @@ static long transport_bio_buffered_ctrl(BIO* bio, int cmd, long arg1, void* arg2 break; default: - status = BIO_ctrl(bio->next_bio, cmd, arg1, arg2); + status = BIO_ctrl(BIO_next(bio), cmd, arg1, arg2); break; } @@ -616,17 +624,15 @@ static int transport_bio_buffered_new(BIO* bio) { WINPR_BIO_BUFFERED_SOCKET* ptr; - bio->init = 1; - bio->num = 0; - bio->ptr = NULL; - bio->flags = BIO_FLAGS_SHOULD_RETRY; + BIO_set_init(bio, 1); + BIO_set_flags(bio, BIO_FLAGS_SHOULD_RETRY); ptr = (WINPR_BIO_BUFFERED_SOCKET*) calloc(1, sizeof(WINPR_BIO_BUFFERED_SOCKET)); if (!ptr) return -1; - bio->ptr = (void*) ptr; + BIO_set_data(bio, (void*) ptr); if (!ringbuffer_init(&ptr->xmitBuffer, 0x10000)) return -1; @@ -636,12 +642,13 @@ static int transport_bio_buffered_new(BIO* bio) static int transport_bio_buffered_free(BIO* bio) { - WINPR_BIO_BUFFERED_SOCKET* ptr = (WINPR_BIO_BUFFERED_SOCKET*) bio->ptr; + WINPR_BIO_BUFFERED_SOCKET* ptr = (WINPR_BIO_BUFFERED_SOCKET*) BIO_get_data(bio); + BIO* next_bio = BIO_next(bio); - if (bio->next_bio) + if (next_bio) { - BIO_free(bio->next_bio); - bio->next_bio = NULL; + BIO_free(next_bio); + BIO_set_next(bio, NULL); } ringbuffer_destroy(&ptr->xmitBuffer); @@ -651,23 +658,25 @@ static int transport_bio_buffered_free(BIO* bio) return 1; } -static BIO_METHOD transport_bio_buffered_socket_methods = -{ - BIO_TYPE_BUFFERED, - "BufferedSocket", - transport_bio_buffered_write, - transport_bio_buffered_read, - transport_bio_buffered_puts, - transport_bio_buffered_gets, - transport_bio_buffered_ctrl, - transport_bio_buffered_new, - transport_bio_buffered_free, - NULL, -}; - BIO_METHOD* BIO_s_buffered_socket(void) { - return &transport_bio_buffered_socket_methods; + static BIO_METHOD* bio_methods = NULL; + + if (bio_methods == NULL) + { + if (!(bio_methods = BIO_meth_new(BIO_TYPE_BUFFERED, "BufferedSocket"))) + return NULL; + + BIO_meth_set_write(bio_methods, transport_bio_buffered_write); + BIO_meth_set_read(bio_methods, transport_bio_buffered_read); + BIO_meth_set_puts(bio_methods, transport_bio_buffered_puts); + BIO_meth_set_gets(bio_methods, transport_bio_buffered_gets); + BIO_meth_set_ctrl(bio_methods, transport_bio_buffered_ctrl); + BIO_meth_set_create(bio_methods, transport_bio_buffered_new); + BIO_meth_set_destroy(bio_methods, transport_bio_buffered_free); + } + + return bio_methods; } char* freerdp_tcp_get_ip_address(int sockfd) diff --git a/libfreerdp/crypto/CMakeLists.txt b/libfreerdp/crypto/CMakeLists.txt index c56126ff9..87e9860a4 100644 --- a/libfreerdp/crypto/CMakeLists.txt +++ b/libfreerdp/crypto/CMakeLists.txt @@ -26,7 +26,8 @@ freerdp_module_add( base64.c certificate.c crypto.c - tls.c) + tls.c + opensslcompat.c) freerdp_include_directory_add(${OPENSSL_INCLUDE_DIR}) diff --git a/libfreerdp/crypto/crypto.c b/libfreerdp/crypto/crypto.c index 85a28b8c6..3e8b51b36 100644 --- a/libfreerdp/crypto/crypto.c +++ b/libfreerdp/crypto/crypto.c @@ -98,11 +98,12 @@ static int crypto_rsa_common(const BYTE* input, int length, UINT32 key_length, c BYTE* input_reverse; BYTE* modulus_reverse; BYTE* exponent_reverse; - BIGNUM mod, exp, x, y; + BIGNUM *mod, *exp, *x, *y; input_reverse = (BYTE*) malloc(2 * key_length + exponent_size); if (!input_reverse) return -1; + modulus_reverse = input_reverse + key_length; exponent_reverse = modulus_reverse + key_length; @@ -113,32 +114,42 @@ static int crypto_rsa_common(const BYTE* input, int length, UINT32 key_length, c memcpy(input_reverse, input, length); crypto_reverse(input_reverse, length); - ctx = BN_CTX_new(); - if (!ctx) - goto out_free_input_reverse; - BN_init(&mod); - BN_init(&exp); - BN_init(&x); - BN_init(&y); + if (!(ctx = BN_CTX_new())) + goto fail_bn_ctx; - BN_bin2bn(modulus_reverse, key_length, &mod); - BN_bin2bn(exponent_reverse, exponent_size, &exp); - BN_bin2bn(input_reverse, length, &x); - BN_mod_exp(&y, &x, &exp, &mod, ctx); + if (!(mod = BN_new())) + goto fail_bn_mod; - output_length = BN_bn2bin(&y, output); + if (!(exp = BN_new())) + goto fail_bn_exp; + + if (!(x = BN_new())) + goto fail_bn_x; + + if (!(y = BN_new())) + goto fail_bn_y; + + BN_bin2bn(modulus_reverse, key_length, mod); + BN_bin2bn(exponent_reverse, exponent_size, exp); + BN_bin2bn(input_reverse, length, x); + BN_mod_exp(y, x, exp, mod, ctx); + + output_length = BN_bn2bin(y, output); crypto_reverse(output, output_length); if (output_length < (int) key_length) memset(output + output_length, 0, key_length - output_length); - BN_free(&y); - BN_clear_free(&x); - BN_free(&exp); - BN_free(&mod); + BN_free(y); +fail_bn_y: + BN_clear_free(x); +fail_bn_x: + BN_free(exp); +fail_bn_exp: + BN_free(mod); +fail_bn_mod: BN_CTX_free(ctx); - -out_free_input_reverse: +fail_bn_ctx: free(input_reverse); return output_length; diff --git a/libfreerdp/crypto/opensslcompat.c b/libfreerdp/crypto/opensslcompat.c new file mode 100644 index 000000000..bb5aff767 --- /dev/null +++ b/libfreerdp/crypto/opensslcompat.c @@ -0,0 +1,44 @@ +/** + * FreeRDP: A Remote Desktop Protocol Implementation + * OpenSSL Compatibility + * + * Copyright (C) 2016 Norbert Federa + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "opensslcompat.h" + +#if OPENSSL_VERSION_NUMBER < 0x10100000L + +BIO_METHOD* BIO_meth_new(int type, const char* name) +{ + BIO_METHOD* m; + if (!(m = calloc(1, sizeof(BIO_METHOD)))) + return NULL; + m->type = type; + m->name = name; + return m; +} + +void RSA_get0_key(const RSA* r, const BIGNUM** n, const BIGNUM** e, const BIGNUM** d) +{ + if (n != NULL) + *n = r->n; + if (e != NULL) + *e = r->e; + if (d != NULL) + *d = r->d; +} + +#endif /* OPENSSL < 1.1.0 */ diff --git a/libfreerdp/crypto/opensslcompat.h b/libfreerdp/crypto/opensslcompat.h new file mode 100644 index 000000000..a599863b7 --- /dev/null +++ b/libfreerdp/crypto/opensslcompat.h @@ -0,0 +1,65 @@ +/** + * FreeRDP: A Remote Desktop Protocol Implementation + * OpenSSL Compatibility + * + * Copyright (C) 2016 Norbert Federa + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef FREERDP_CRYPTO_OPENSSLCOMPAT_H +#define FREERDP_CRYPTO_OPENSSLCOMPAT_H + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include + +#ifdef WITH_OPENSSL + +#include + +#if OPENSSL_VERSION_NUMBER < 0x10100000L + +#include +#include +#include + +#define BIO_get_data(b) (b)->ptr +#define BIO_set_data(b,v) (b)->ptr = v +#define BIO_get_init(b) (b)->init +#define BIO_set_init(b,v) (b)->init = v +#define BIO_get_next(b,v) (b)->next_bio +#define BIO_set_next(b,v) (b)->next_bio = v +#define BIO_get_shutdown(b) (b)->shutdown +#define BIO_set_shutdown(b,v) (b)->shutdown = v +#define BIO_get_retry_reason(b) (b)->retry_reason +#define BIO_set_retry_reason(b,v) (b)->retry_reason = v + +#define BIO_meth_set_write(b,f) (b)->bwrite = (f) +#define BIO_meth_set_read(b,f) (b)->bread = (f) +#define BIO_meth_set_puts(b,f) (b)->bputs = (f) +#define BIO_meth_set_gets(b,f) (b)->bgets = (f) +#define BIO_meth_set_ctrl(b,f) (b)->ctrl = (f) +#define BIO_meth_set_create(b,f) (b)->create = (f) +#define BIO_meth_set_destroy(b,f) (b)->destroy = (f) +#define BIO_meth_set_callback_ctrl(b,f) (b)->callback_ctrl = (f) + +BIO_METHOD* BIO_meth_new(int type, const char* name); +void RSA_get0_key(const RSA* r, const BIGNUM** n, const BIGNUM** e, const BIGNUM** d); + +#endif /* OPENSSL < 1.1.0 */ +#endif /* WITH_OPENSSL */ + +#endif /* FREERDP_CRYPTO_OPENSSLCOMPAT_H */ diff --git a/libfreerdp/crypto/tls.c b/libfreerdp/crypto/tls.c index c33fe82b4..e839fa2ca 100644 --- a/libfreerdp/crypto/tls.c +++ b/libfreerdp/crypto/tls.c @@ -34,6 +34,7 @@ #include #include #include "../core/tcp.h" +#include "opensslcompat.h" #ifdef HAVE_POLL_H #include @@ -45,6 +46,30 @@ #define TAG FREERDP_TAG("crypto") + + +/** + * Earlier Microsoft iOS RDP clients have sent a null or even double null + * terminated hostname in the SNI TLS extension. + * If the length indicator does not equal the hostname strlen OpenSSL + * will abort (see openssl:ssl/t1_lib.c). + * Here is a tcpdump segment of Microsoft Remote Desktop Client Version + * 8.1.7 running on an iPhone 4 with iOS 7.1.2 showing the transmitted + * SNI hostname TLV blob when connection to server "abcd": + * 00 name_type 0x00 (host_name) + * 00 06 length_in_bytes 0x0006 + * 61 62 63 64 00 00 host_name "abcd\0\0" + * + * Currently the only (runtime) workaround is setting an openssl tls + * extension debug callback that sets the SSL context's servername_done + * to 1 which effectively disables the parsing of that extension type. + * + * Nowadays this workaround is not required anymore but still can be + * activated by adding the following define: + * + * #define MICROSOFT_IOS_SNI_BUG + */ + struct _BIO_RDP_TLS { SSL* ssl; @@ -62,7 +87,7 @@ static int bio_rdp_tls_write(BIO* bio, const char* buf, int size) { int error; int status; - BIO_RDP_TLS* tls = (BIO_RDP_TLS*) bio->ptr; + BIO_RDP_TLS* tls = (BIO_RDP_TLS*) BIO_get_data(bio); if (!buf || !tls) return 0; @@ -91,12 +116,12 @@ static int bio_rdp_tls_write(BIO* bio, const char* buf, int size) case SSL_ERROR_WANT_X509_LOOKUP: BIO_set_flags(bio, BIO_FLAGS_IO_SPECIAL); - bio->retry_reason = BIO_RR_SSL_X509_LOOKUP; + BIO_set_retry_reason(bio, BIO_RR_SSL_X509_LOOKUP); break; case SSL_ERROR_WANT_CONNECT: BIO_set_flags(bio, BIO_FLAGS_IO_SPECIAL); - bio->retry_reason = BIO_RR_CONNECT; + BIO_set_retry_reason(bio, BIO_RR_CONNECT); break; case SSL_ERROR_SYSCALL: @@ -116,7 +141,7 @@ static int bio_rdp_tls_read(BIO* bio, char* buf, int size) { int error; int status; - BIO_RDP_TLS* tls = (BIO_RDP_TLS*) bio->ptr; + BIO_RDP_TLS* tls = (BIO_RDP_TLS*) BIO_get_data(bio); if (!buf || !tls) return 0; @@ -145,17 +170,17 @@ static int bio_rdp_tls_read(BIO* bio, char* buf, int size) case SSL_ERROR_WANT_X509_LOOKUP: BIO_set_flags(bio, BIO_FLAGS_IO_SPECIAL); - bio->retry_reason = BIO_RR_SSL_X509_LOOKUP; + BIO_set_retry_reason(bio, BIO_RR_SSL_X509_LOOKUP); break; case SSL_ERROR_WANT_ACCEPT: BIO_set_flags(bio, BIO_FLAGS_IO_SPECIAL); - bio->retry_reason = BIO_RR_ACCEPT; + BIO_set_retry_reason(bio, BIO_RR_ACCEPT); break; case SSL_ERROR_WANT_CONNECT: BIO_set_flags(bio, BIO_FLAGS_IO_SPECIAL); - bio->retry_reason = BIO_RR_CONNECT; + BIO_set_retry_reason(bio, BIO_RR_CONNECT); break; case SSL_ERROR_SSL: @@ -203,9 +228,12 @@ static int bio_rdp_tls_gets(BIO* bio, char* str, int size) static long bio_rdp_tls_ctrl(BIO* bio, int cmd, long num, void* ptr) { - BIO* rbio; + BIO* ssl_rbio; + BIO* ssl_wbio; + BIO* next_bio; int status = -1; - BIO_RDP_TLS* tls = (BIO_RDP_TLS*) bio->ptr; + BIO_RDP_TLS* tls = (BIO_RDP_TLS*) BIO_get_data(bio); + if (!tls) return 0; @@ -213,29 +241,39 @@ static long bio_rdp_tls_ctrl(BIO* bio, int cmd, long num, void* ptr) if (!tls->ssl && (cmd != BIO_C_SET_SSL)) return 0; + next_bio = BIO_next(bio); + ssl_rbio = tls->ssl ? SSL_get_rbio(tls->ssl) : NULL; + ssl_wbio = tls->ssl ? SSL_get_wbio(tls->ssl) : NULL; + switch (cmd) { case BIO_CTRL_RESET: SSL_shutdown(tls->ssl); - +#if 1 + if (SSL_in_connect_init(tls->ssl)) + SSL_set_connect_state(tls->ssl); + else if (SSL_in_accept_init(tls->ssl)) + SSL_set_accept_state(tls->ssl); +#else if (tls->ssl->handshake_func == tls->ssl->method->ssl_connect) SSL_set_connect_state(tls->ssl); else if (tls->ssl->handshake_func == tls->ssl->method->ssl_accept) SSL_set_accept_state(tls->ssl); +#endif SSL_clear(tls->ssl); - if (bio->next_bio) - status = BIO_ctrl(bio->next_bio, cmd, num, ptr); - else if (tls->ssl->rbio) - status = BIO_ctrl(tls->ssl->rbio, cmd, num, ptr); + if (next_bio) + status = BIO_ctrl(next_bio, cmd, num, ptr); + else if (ssl_rbio) + status = BIO_ctrl(ssl_rbio, cmd, num, ptr); else status = 1; break; case BIO_C_GET_FD: - status = BIO_ctrl(tls->ssl->rbio, cmd, num, ptr); + status = BIO_ctrl(ssl_rbio, cmd, num, ptr); break; case BIO_CTRL_INFO: @@ -261,53 +299,67 @@ static long bio_rdp_tls_ctrl(BIO* bio, int cmd, long num, void* ptr) break; case BIO_CTRL_GET_CLOSE: - status = bio->shutdown; + status = BIO_get_shutdown(bio); break; case BIO_CTRL_SET_CLOSE: - bio->shutdown = (int) num; + BIO_set_shutdown(bio, (int) num); status = 1; break; case BIO_CTRL_WPENDING: - status = BIO_ctrl(tls->ssl->wbio, cmd, num, ptr); + status = BIO_ctrl(ssl_wbio, cmd, num, ptr); break; case BIO_CTRL_PENDING: status = SSL_pending(tls->ssl); if (status == 0) - status = BIO_pending(tls->ssl->rbio); + status = BIO_pending(ssl_rbio); break; case BIO_CTRL_FLUSH: BIO_clear_retry_flags(bio); - status = BIO_ctrl(tls->ssl->wbio, cmd, num, ptr); + status = BIO_ctrl(ssl_wbio, cmd, num, ptr); BIO_copy_next_retry(bio); status = 1; break; case BIO_CTRL_PUSH: - if (bio->next_bio && (bio->next_bio != tls->ssl->rbio)) + if (next_bio && (next_bio != ssl_rbio)) { - SSL_set_bio(tls->ssl, bio->next_bio, bio->next_bio); +#if OPENSSL_VERSION_NUMBER < 0x10100000L + SSL_set_bio(tls->ssl, next_bio, next_bio); CRYPTO_add(&(bio->next_bio->references), 1, CRYPTO_LOCK_BIO); +#else + /* + * We are going to pass ownership of next to the SSL object...but + * we don't own a reference to pass yet - so up ref + */ + BIO_up_ref(next_bio); + SSL_set_bio(tls->ssl, next_bio, next_bio); +#endif } status = 1; break; case BIO_CTRL_POP: + /* Only detach if we are the BIO explicitly being popped */ if (bio == ptr) { - if (tls->ssl->rbio != tls->ssl->wbio) - BIO_free_all(tls->ssl->wbio); + if (ssl_rbio != ssl_wbio) + BIO_free_all(ssl_wbio); - if (bio->next_bio) +#if OPENSSL_VERSION_NUMBER < 0x10100000L + if (next_bio) CRYPTO_add(&(bio->next_bio->references), -1, CRYPTO_LOCK_BIO); - tls->ssl->wbio = tls->ssl->rbio = NULL; +#else + /* OpenSSL 1.1: This will also clear the reference we obtained during push */ + SSL_set_bio(tls->ssl, NULL, NULL); +#endif } status = 1; @@ -323,29 +375,36 @@ static long bio_rdp_tls_ctrl(BIO* bio, int cmd, long num, void* ptr) break; case BIO_C_SET_SSL: - bio->shutdown = (int) num; + BIO_set_shutdown(bio, (int) num); if (ptr) - tls->ssl = (SSL*) ptr; - - rbio = SSL_get_rbio(tls->ssl); - - if (rbio) { - if (bio->next_bio) - BIO_push(rbio, bio->next_bio); - - bio->next_bio = rbio; - CRYPTO_add(&(rbio->references), 1, CRYPTO_LOCK_BIO); + tls->ssl = (SSL*) ptr; + ssl_rbio = SSL_get_rbio(tls->ssl); + ssl_wbio = SSL_get_wbio(tls->ssl); } - bio->init = 1; + if (ssl_rbio) + { + if (next_bio) + BIO_push(ssl_rbio, next_bio); + + BIO_set_next(bio, ssl_rbio); +#if OPENSSL_VERSION_NUMBER < 0x10100000L + CRYPTO_add(&(ssl_rbio->references), 1, CRYPTO_LOCK_BIO); +#else + BIO_up_ref(ssl_rbio); +#endif + } + + BIO_set_init(bio, 1); + status = 1; break; case BIO_C_DO_STATE_MACHINE: BIO_clear_flags(bio, BIO_FLAGS_READ | BIO_FLAGS_WRITE | BIO_FLAGS_IO_SPECIAL); - bio->retry_reason = 0; + BIO_set_retry_reason(bio, 0); status = SSL_do_handshake(tls->ssl); if (status <= 0) @@ -362,7 +421,7 @@ static long bio_rdp_tls_ctrl(BIO* bio, int cmd, long num, void* ptr) case SSL_ERROR_WANT_CONNECT: BIO_set_flags(bio, BIO_FLAGS_IO_SPECIAL | BIO_FLAGS_SHOULD_RETRY); - bio->retry_reason = bio->next_bio->retry_reason; + BIO_set_retry_reason(bio, BIO_get_retry_reason(next_bio)); break; default: @@ -374,7 +433,7 @@ static long bio_rdp_tls_ctrl(BIO* bio, int cmd, long num, void* ptr) break; default: - status = BIO_ctrl(tls->ssl->rbio, cmd, num, ptr); + status = BIO_ctrl(ssl_rbio, cmd, num, ptr); break; } @@ -384,17 +443,16 @@ static long bio_rdp_tls_ctrl(BIO* bio, int cmd, long num, void* ptr) static int bio_rdp_tls_new(BIO* bio) { BIO_RDP_TLS* tls; - bio->init = 0; - bio->num = 0; - bio->flags = BIO_FLAGS_SHOULD_RETRY; - bio->next_bio = NULL; - tls = calloc(1, sizeof(BIO_RDP_TLS)); - if (!tls) + BIO_set_flags(bio, BIO_FLAGS_SHOULD_RETRY); + + if (!(tls = calloc(1, sizeof(BIO_RDP_TLS)))) return 0; - bio->ptr = (void*) tls; InitializeCriticalSectionAndSpinCount(&tls->lock, 4000); + + BIO_set_data(bio, (void*) tls); + return 1; } @@ -405,21 +463,20 @@ static int bio_rdp_tls_free(BIO* bio) if (!bio) return 0; - tls = (BIO_RDP_TLS*) bio->ptr; + tls = (BIO_RDP_TLS*) BIO_get_data(bio); if (!tls) return 0; - if (bio->shutdown) + if (BIO_get_shutdown(bio)) { - if (bio->init && tls->ssl) + if (BIO_get_init(bio) && tls->ssl) { SSL_shutdown(tls->ssl); SSL_free(tls->ssl); } - - bio->init = 0; - bio->flags = 0; + BIO_set_init(bio, 0); + BIO_set_flags(bio, 0); } DeleteCriticalSection(&tls->lock); @@ -435,7 +492,7 @@ static long bio_rdp_tls_callback_ctrl(BIO* bio, int cmd, bio_info_cb* fp) if (!bio) return 0; - tls = (BIO_RDP_TLS*) bio->ptr; + tls = (BIO_RDP_TLS*) BIO_get_data(bio); if (!tls) return 0; @@ -448,7 +505,7 @@ static long bio_rdp_tls_callback_ctrl(BIO* bio, int cmd, bio_info_cb* fp) break; default: - status = BIO_callback_ctrl(tls->ssl->rbio, cmd, fp); + status = BIO_callback_ctrl(SSL_get_rbio(tls->ssl), cmd, fp); break; } @@ -457,23 +514,26 @@ static long bio_rdp_tls_callback_ctrl(BIO* bio, int cmd, bio_info_cb* fp) #define BIO_TYPE_RDP_TLS 68 -static BIO_METHOD bio_rdp_tls_methods = -{ - BIO_TYPE_RDP_TLS, - "RdpTls", - bio_rdp_tls_write, - bio_rdp_tls_read, - bio_rdp_tls_puts, - bio_rdp_tls_gets, - bio_rdp_tls_ctrl, - bio_rdp_tls_new, - bio_rdp_tls_free, - bio_rdp_tls_callback_ctrl, -}; - BIO_METHOD* BIO_s_rdp_tls(void) { - return &bio_rdp_tls_methods; + static BIO_METHOD* bio_methods = NULL; + + if (bio_methods == NULL) + { + if (!(bio_methods = BIO_meth_new(BIO_TYPE_RDP_TLS, "RdpTls"))) + return NULL; + + BIO_meth_set_write(bio_methods, bio_rdp_tls_write); + BIO_meth_set_read(bio_methods, bio_rdp_tls_read); + BIO_meth_set_puts(bio_methods, bio_rdp_tls_puts); + BIO_meth_set_gets(bio_methods, bio_rdp_tls_gets); + BIO_meth_set_ctrl(bio_methods, bio_rdp_tls_ctrl); + BIO_meth_set_create(bio_methods, bio_rdp_tls_new); + BIO_meth_set_destroy(bio_methods, bio_rdp_tls_free); + BIO_meth_set_callback_ctrl(bio_methods, bio_rdp_tls_callback_ctrl); + } + + return bio_methods; } BIO* BIO_new_rdp_tls(SSL_CTX* ctx, int client) @@ -805,11 +865,10 @@ int tls_connect(rdpTls* tls, BIO* underlying) return tls_do_handshake(tls, TRUE); } -#ifndef OPENSSL_NO_TLSEXT +#if defined(MICROSOFT_IOS_SNI_BUG) && !defined(OPENSSL_NO_TLSEXT) static void tls_openssl_tlsext_debug_callback(SSL* s, int client_server, int type, unsigned char* data, int len, void* arg) { - /* see code comment in tls_accept() below */ if (type == TLSEXT_TYPE_server_name) { WLog_DBG(TAG, "Client uses SNI (extension disabled)"); @@ -949,23 +1008,7 @@ BOOL tls_accept(rdpTls* tls, BIO* underlying, rdpSettings* settings) return FALSE; } -#ifndef OPENSSL_NO_TLSEXT - /** - * The Microsoft iOS clients eventually send a null or even double null - * terminated hostname in the SNI TLS extension! - * If the length indicator does not equal the hostname strlen OpenSSL - * will abort (see openssl:ssl/t1_lib.c). - * Here is a tcpdump segment of Microsoft Remote Desktop Client Version - * 8.1.7 running on an iPhone 4 with iOS 7.1.2 showing the transmitted - * SNI hostname TLV blob when connection to server "abcd": - * 00 name_type 0x00 (host_name) - * 00 06 length_in_bytes 0x0006 - * 61 62 63 64 00 00 host_name "abcd\0\0" - * - * Currently the only (runtime) workaround is setting an openssl tls - * extension debug callback that sets the SSL context's servername_done - * to 1 which effectively disables the parsing of that extension type. - */ +#if defined(MICROSOFT_IOS_SNI_BUG) && !defined(OPENSSL_NO_TLSEXT) SSL_set_tlsext_debug_callback(tls->ssl, tls_openssl_tlsext_debug_callback); #endif return tls_do_handshake(tls, FALSE) > 0; @@ -979,6 +1022,12 @@ BOOL tls_send_alert(rdpTls* tls) if (!tls->ssl) return TRUE; +/** + * FIXME: The following code does not work on OpenSSL > 1.1.0 because the + * SSL struct is opaqe now + */ + +#if OPENSSL_VERSION_NUMBER < 0x10100000L if (tls->alertDescription != TLS_ALERT_DESCRIPTION_CLOSE_NOTIFY) { /** @@ -990,10 +1039,13 @@ BOOL tls_send_alert(rdpTls* tls) * Manually sending a TLS alert is necessary in certain cases, * like when server-side NLA results in an authentication failure. */ + SSL_SESSION* ssl_session = SSL_get_session(tls->ssl); + SSL_CTX* ssl_ctx = SSL_get_SSL_CTX(tls->ssl); + SSL_set_quiet_shutdown(tls->ssl, 1); - if ((tls->alertLevel == TLS_ALERT_LEVEL_FATAL) && (tls->ssl->session)) - SSL_CTX_remove_session(tls->ssl->ctx, tls->ssl->session); + if ((tls->alertLevel == TLS_ALERT_LEVEL_FATAL) && (ssl_session)) + SSL_CTX_remove_session(ssl_ctx, ssl_session); tls->ssl->s3->alert_dispatch = 1; tls->ssl->s3->send_alert[0] = tls->alertLevel; @@ -1002,6 +1054,7 @@ BOOL tls_send_alert(rdpTls* tls) if (tls->ssl->s3->wbuf.left == 0) tls->ssl->method->ssl_dispatch_alert(tls->ssl); } +#endif return TRUE; } @@ -1015,7 +1068,7 @@ BIO* findBufferedBio(BIO* front) if (BIO_method_type(ret) == BIO_TYPE_BUFFERED) return ret; - ret = ret->next_bio; + ret = BIO_next(ret); } return ret; diff --git a/winpr/include/winpr/crypto.h b/winpr/include/winpr/crypto.h index 7e05124f6..233f05163 100644 --- a/winpr/include/winpr/crypto.h +++ b/winpr/include/winpr/crypto.h @@ -614,134 +614,10 @@ BOOL CryptBinaryToStringA(CONST BYTE* pbBinary, DWORD cbBinary, DWORD dwFlags, L * Custom Crypto API Abstraction Layer */ -/** - * MD5 hashing - */ - -struct _OPENSSL_MD5_CTX -{ - UINT32 A, B, C, D; - UINT32 Nl, Nh; - UINT32 data[16]; - UINT32 num; -}; -typedef struct _OPENSSL_MD5_CTX OPENSSL_MD5_CTX; - -struct _MBEDTLS_MD5_CTX -{ - UINT32 total[2]; - UINT32 state[4]; - BYTE buffer[64]; -}; -typedef struct _MBEDTLS_MD5_CTX MBEDTLS_MD5_CTX; - -union _WINPR_MD5_CTX -{ - OPENSSL_MD5_CTX openssl; - MBEDTLS_MD5_CTX mbedtls; -}; -typedef union _WINPR_MD5_CTX WINPR_MD5_CTX; - -#define WINPR_MD5_DIGEST_LENGTH 16 - -#ifdef __cplusplus -extern "C" { -#endif - -WINPR_API BOOL winpr_MD5_Init(WINPR_MD5_CTX* ctx); -WINPR_API BOOL winpr_MD5_Update(WINPR_MD5_CTX* ctx, const BYTE* input, size_t ilen); -WINPR_API BOOL winpr_MD5_Final(WINPR_MD5_CTX* ctx, BYTE* output, size_t ilen); -WINPR_API BOOL winpr_MD5(const BYTE* input, size_t ilen, BYTE* output, size_t olen); - -#ifdef __cplusplus -} -#endif - -/** - * MD4 hashing - */ - -struct _OPENSSL_MD4_CTX -{ - UINT32 A, B, C, D; - UINT32 Nl, Nh; - UINT32 data[16]; - UINT32 num; -}; -typedef struct _OPENSSL_MD4_CTX OPENSSL_MD4_CTX; - -struct _MBEDTLS_MD4_CTX -{ - UINT32 total[2]; - UINT32 state[4]; - BYTE buffer[64]; -}; -typedef struct _MBEDTLS_MD4_CTX MBEDTLS_MD4_CTX; - -union _WINPR_MD4_CTX -{ - OPENSSL_MD4_CTX openssl; - MBEDTLS_MD4_CTX mbedtls; -}; -typedef union _WINPR_MD4_CTX WINPR_MD4_CTX; - #define WINPR_MD4_DIGEST_LENGTH 16 +#define WINPR_MD5_DIGEST_LENGTH 16 +#define WINPR_SHA1_DIGEST_LENGTH 20 -#ifdef __cplusplus -extern "C" { -#endif - -WINPR_API BOOL winpr_MD4_Init(WINPR_MD4_CTX* ctx); -WINPR_API BOOL winpr_MD4_Update(WINPR_MD4_CTX* ctx, const BYTE* input, size_t ilen); -WINPR_API BOOL winpr_MD4_Final(WINPR_MD4_CTX* ctx, BYTE* output, size_t ilen); -WINPR_API BOOL winpr_MD4(const BYTE* input, size_t ilen, BYTE* output, size_t olen); - -#ifdef __cplusplus -} -#endif - -/** - * SHA1 Hashing - */ - -#define WINPR_SHA1_DIGEST_LENGTH 20 - -struct _OPENSSL_SHA1_CTX -{ - UINT32 h0, h1, h2, h3, h4; - UINT32 Nl, Nh; - UINT32 data[16]; - UINT32 num; -}; -typedef struct _OPENSSL_SHA1_CTX OPENSSL_SHA1_CTX; - -struct _MBEDTLS_SHA1_CTX -{ - UINT32 total[2]; - UINT32 state[5]; - BYTE buffer[64]; -}; -typedef struct _MBEDTLS_SHA1_CTX MBEDTLS_SHA1_CTX; - -union _WINPR_SHA1_CTX -{ - OPENSSL_SHA1_CTX openssl; - MBEDTLS_SHA1_CTX mbedtls; -}; -typedef union _WINPR_SHA1_CTX WINPR_SHA1_CTX; - -#ifdef __cplusplus -extern "C" { -#endif - -WINPR_API BOOL winpr_SHA1_Init(WINPR_SHA1_CTX* ctx); -WINPR_API BOOL winpr_SHA1_Update(WINPR_SHA1_CTX* ctx, const BYTE* input, size_t ilen); -WINPR_API BOOL winpr_SHA1_Final(WINPR_SHA1_CTX* ctx, BYTE* output, size_t ilen); -WINPR_API BOOL winpr_SHA1(const BYTE* input, size_t ilen, BYTE* output, size_t olen); - -#ifdef __cplusplus -} -#endif /** * HMAC @@ -760,50 +636,16 @@ typedef enum WINPR_MD_RIPEMD160 = 9 } WINPR_MD_TYPE; -struct _OPENSSL_EVP_MD_CTX -{ - const void* digest; - void* engine; - unsigned long flags; - void* md_data; - void* pctx; - void* update; -}; -typedef struct _OPENSSL_EVP_MD_CTX OPENSSL_EVP_MD_CTX; - -struct _OPENSSL_HMAC_CTX -{ - const void* md; - OPENSSL_EVP_MD_CTX md_ctx; - OPENSSL_EVP_MD_CTX i_ctx; - OPENSSL_EVP_MD_CTX o_ctx; - unsigned int key_length; - unsigned char key[128]; -}; -typedef struct _OPENSSL_HMAC_CTX OPENSSL_HMAC_CTX; - -struct _MBEDTLS_HMAC_CTX -{ - const void* md_info; - void* md_ctx; - void* hmac_ctx; -}; -typedef struct _MBEDTLS_HMAC_CTX MBEDTLS_HMAC_CTX; - -union _WINPR_HMAC_CTX -{ - OPENSSL_HMAC_CTX openssl; - MBEDTLS_HMAC_CTX mbedtls; -}; -typedef union _WINPR_HMAC_CTX WINPR_HMAC_CTX; +typedef struct _winpr_hmac_ctx_private_st WINPR_HMAC_CTX; #ifdef __cplusplus extern "C" { #endif -WINPR_API BOOL winpr_HMAC_Init(WINPR_HMAC_CTX* ctx, WINPR_MD_TYPE md, const BYTE* key, size_t keylen); +WINPR_API WINPR_HMAC_CTX* winpr_HMAC_New(WINPR_MD_TYPE md, const BYTE* key, size_t keylen); WINPR_API BOOL winpr_HMAC_Update(WINPR_HMAC_CTX* ctx, const BYTE* input, size_t ilen); WINPR_API BOOL winpr_HMAC_Final(WINPR_HMAC_CTX* ctx, BYTE* output, size_t ilen); +//WINPR_API void winpr_HMAC_Free(WINPR_HMAC_CTX* ctx); WINPR_API BOOL winpr_HMAC(WINPR_MD_TYPE md, const BYTE* key, size_t keylen, const BYTE* input, size_t ilen, BYTE* output, size_t olen); @@ -815,41 +657,16 @@ WINPR_API BOOL winpr_HMAC(WINPR_MD_TYPE md, const BYTE* key, size_t keylen, * Generic Digest API */ -struct _OPENSSL_DIGEST_CTX -{ - const void* digest; - void* engine; - unsigned long flags; - void* md_data; - void* pctx; - void* update; - BYTE winpr_pad[8]; -}; -typedef struct _OPENSSL_DIGEST_CTX OPENSSL_DIGEST_CTX; - -struct _MBEDTLS_DIGEST_CTX -{ - const void* md_info; - void* md_ctx; - void* hmac_ctx; - BYTE winpr_pad[8]; -}; -typedef struct _MBEDTLS_DIGEST_CTX MBEDTLS_DIGEST_CTX; - -union _WINPR_DIGEST_CTX -{ - OPENSSL_DIGEST_CTX openssl; - MBEDTLS_DIGEST_CTX mbedtls; -}; -typedef union _WINPR_DIGEST_CTX WINPR_DIGEST_CTX; +typedef struct _winpr_digest_ctx_private_st WINPR_DIGEST_CTX; #ifdef __cplusplus extern "C" { #endif -WINPR_API BOOL winpr_Digest_Init(WINPR_DIGEST_CTX* ctx, WINPR_MD_TYPE md); +WINPR_API WINPR_DIGEST_CTX* winpr_Digest_New(WINPR_MD_TYPE md); WINPR_API BOOL winpr_Digest_Update(WINPR_DIGEST_CTX* ctx, const BYTE* input, size_t ilen); WINPR_API BOOL winpr_Digest_Final(WINPR_DIGEST_CTX* ctx, BYTE* output, size_t ilen); +WINPR_API void winpr_Digest_Free(WINPR_DIGEST_CTX* ctx); WINPR_API BOOL winpr_Digest(int md, const BYTE* input, size_t ilen, BYTE* output, size_t olen); #ifdef __cplusplus @@ -875,27 +692,7 @@ WINPR_API int winpr_RAND_pseudo(BYTE* output, size_t len); * RC4 */ -struct _OPENSSL_RC4_CTX -{ - int x, y; - int data[256]; -}; -typedef struct _OPENSSL_RC4_CTX OPENSSL_RC4_CTX; - -struct _MBEDTLS_RC4_CTX -{ - int x; - int y; - BYTE m[256]; -}; -typedef struct _MBEDTLS_RC4_CTX MBEDTLS_RC4_CTX; - -union _WINPR_RC4_CTX -{ - OPENSSL_RC4_CTX openssl; - MBEDTLS_RC4_CTX mbedtls; -}; -typedef union _WINPR_RC4_CTX WINPR_RC4_CTX; +typedef struct _winpr_rc4_ctx_private_st WINPR_RC4_CTX; #ifdef __cplusplus extern "C" { @@ -970,49 +767,7 @@ WINPR_API void winpr_RC4_Free(WINPR_RC4_CTX* ctx); #define WINPR_CIPHER_CAMELLIA_192_CCM 47 #define WINPR_CIPHER_CAMELLIA_256_CCM 48 -struct _OPENSSL_CIPHER_CTX -{ - const void* cipher; - void* engine; - int encrypt; - int buf_len; - BYTE oiv[16]; - BYTE iv[16]; - BYTE buf[32]; - int num; - void* app_data; - int key_len; - unsigned long flags; - void* cipher_data; - int final_used; - int block_mask; - BYTE final[32]; - BYTE winpr_pad[32]; -}; -typedef struct _OPENSSL_CIPHER_CTX OPENSSL_CIPHER_CTX; - -struct _MBEDTLS_CIPHER_CTX -{ - const void* cipher_info; - int key_bitlen; - int operation; - void* add_padding; - int* get_padding; - BYTE unprocessed_data[16]; - size_t unprocessed_len; - BYTE iv[16]; - size_t iv_size; - void* cipher_ctx; - BYTE winpr_pad[32]; -}; -typedef struct _MBEDTLS_CIPHER_CTX MBEDTLS_CIPHER_CTX; - -union _WINPR_CIPHER_CTX -{ - OPENSSL_CIPHER_CTX openssl; - MBEDTLS_CIPHER_CTX mbedtls; -}; -typedef union _WINPR_CIPHER_CTX WINPR_CIPHER_CTX; +typedef struct _winpr_cipher_ctx_private_st WINPR_CIPHER_CTX; #ifdef __cplusplus extern "C" { @@ -1035,7 +790,7 @@ WINPR_API void winpr_Cipher_Free(WINPR_CIPHER_CTX* ctx); extern "C" { #endif -WINPR_API int winpr_openssl_BytesToKey(int cipher, int md, const BYTE* salt, const BYTE* data, int datal, int count, BYTE* key, BYTE* iv); +WINPR_API int winpr_Cipher_BytesToKey(int cipher, int md, const BYTE* salt, const BYTE* data, int datal, int count, BYTE* key, BYTE* iv); #ifdef __cplusplus } diff --git a/winpr/libwinpr/crypto/cipher.c b/winpr/libwinpr/crypto/cipher.c index f85ab6532..b9948682f 100644 --- a/winpr/libwinpr/crypto/cipher.c +++ b/winpr/libwinpr/crypto/cipher.c @@ -39,6 +39,7 @@ #include #endif + /** * RC4 */ @@ -50,13 +51,14 @@ WINPR_RC4_CTX* winpr_RC4_New(const BYTE* key, size_t keylen) if (!key || (keylen == 0)) return NULL; - ctx = calloc(1, sizeof(WINPR_RC4_CTX)); - if (!ctx) - return NULL; - #if defined(WITH_OPENSSL) + if (!(ctx = (WINPR_RC4_CTX*) calloc(1, sizeof(RC4_KEY)))) + return NULL; RC4_set_key((RC4_KEY*) ctx, keylen, key); + #elif defined(WITH_MBEDTLS) && defined(MBEDTLS_ARC4_C) + if (!(ctx = (WINPR_RC4_CTX*) calloc(1, sizeof(mbedtls_arc4_context)))) + return NULL; mbedtls_arc4_init((mbedtls_arc4_context*) ctx); mbedtls_arc4_setup((mbedtls_arc4_context*) ctx, key, (unsigned int) keylen); #endif @@ -67,11 +69,11 @@ BOOL winpr_RC4_Update(WINPR_RC4_CTX* ctx, size_t length, const BYTE* input, BYTE { #if defined(WITH_OPENSSL) RC4((RC4_KEY*) ctx, length, input, output); + #elif defined(WITH_MBEDTLS) && defined(MBEDTLS_ARC4_C) if (mbedtls_arc4_crypt((mbedtls_arc4_context*) ctx, length, input, output) != 0) return FALSE; #endif - return TRUE; } @@ -81,11 +83,13 @@ void winpr_RC4_Free(WINPR_RC4_CTX* ctx) return; #if defined(WITH_OPENSSL) + memset(ctx, 0, sizeof(RC4_KEY)); + free(ctx); #elif defined(WITH_MBEDTLS) && defined(MBEDTLS_ARC4_C) mbedtls_arc4_free((mbedtls_arc4_context*) ctx); -#endif free(ctx); +#endif } /** @@ -514,71 +518,72 @@ mbedtls_cipher_type_t winpr_mbedtls_get_cipher_type(int cipher) WINPR_CIPHER_CTX* winpr_Cipher_New(int cipher, int op, const BYTE* key, const BYTE* iv) { - WINPR_CIPHER_CTX* ctx; + WINPR_CIPHER_CTX* ctx = NULL; + #if defined(WITH_OPENSSL) int operation; const EVP_CIPHER* evp; EVP_CIPHER_CTX* octx; -#elif defined(WITH_MBEDTLS) - int key_bitlen; - mbedtls_operation_t operation; - mbedtls_cipher_type_t cipher_type; - const mbedtls_cipher_info_t* cipher_info; -#endif - ctx = calloc(1, sizeof(WINPR_CIPHER_CTX)); - if (!ctx) + if (!(evp = winpr_openssl_get_evp_cipher(cipher))) return NULL; -#if defined(WITH_OPENSSL) - octx = (EVP_CIPHER_CTX*)ctx; - evp = winpr_openssl_get_evp_cipher(cipher); - - if (!evp) - { - free (ctx); + if (!(octx = EVP_CIPHER_CTX_new())) return NULL; - } operation = (op == WINPR_ENCRYPT) ? 1 : 0; - EVP_CIPHER_CTX_init(octx); if (EVP_CipherInit_ex(octx, evp, NULL, key, iv, operation) != 1) { - EVP_CIPHER_CTX_cleanup(octx); - free (octx); + EVP_CIPHER_CTX_free(octx); return NULL; } EVP_CIPHER_CTX_set_padding(octx, 0); + + ctx = (WINPR_CIPHER_CTX*) octx; + #elif defined(WITH_MBEDTLS) - cipher_type = winpr_mbedtls_get_cipher_type(cipher); - cipher_info = mbedtls_cipher_info_from_type(cipher_type); + int key_bitlen; + mbedtls_operation_t operation; + mbedtls_cipher_context_t* mctx; + mbedtls_cipher_type_t cipher_type = winpr_mbedtls_get_cipher_type(cipher); + const mbedtls_cipher_info_t* cipher_info = mbedtls_cipher_info_from_type(cipher_type); if (!cipher_info) - { - free (ctx); return NULL; - } + + if (!(mctx = (mbedtls_cipher_context_t*) calloc(1, sizeof(mbedtls_cipher_context_t)))) + return NULL; operation = (op == WINPR_ENCRYPT) ? MBEDTLS_ENCRYPT : MBEDTLS_DECRYPT; - mbedtls_cipher_init((mbedtls_cipher_context_t*) ctx); + mbedtls_cipher_init(mctx); - if (mbedtls_cipher_setup((mbedtls_cipher_context_t*) ctx, cipher_info) != 0) + if (mbedtls_cipher_setup(mctx, cipher_info) != 0) { - free (ctx); + free (mctx); return NULL; } - key_bitlen = mbedtls_cipher_get_key_bitlen((mbedtls_cipher_context_t*) ctx); + key_bitlen = mbedtls_cipher_get_key_bitlen(mctx); - if (mbedtls_cipher_setkey((mbedtls_cipher_context_t*) ctx, key, key_bitlen, operation) != 0) + if (mbedtls_cipher_setkey(mctx, key, key_bitlen, operation) != 0) { - mbedtls_cipher_free((mbedtls_cipher_context_t*) ctx); - free (ctx); + mbedtls_cipher_free(mctx); + free (mctx); return NULL; } + + if (mbedtls_cipher_set_padding_mode(mctx, MBEDTLS_PADDING_NONE) != 0) + { + mbedtls_cipher_free(mctx); + free (mctx); + return NULL; + } + + ctx = (WINPR_CIPHER_CTX*) mctx; #endif + return ctx; } @@ -620,9 +625,10 @@ void winpr_Cipher_Free(WINPR_CIPHER_CTX* ctx) return; #if defined(WITH_OPENSSL) - EVP_CIPHER_CTX_cleanup((EVP_CIPHER_CTX*) ctx); + EVP_CIPHER_CTX_free((EVP_CIPHER_CTX*) ctx); #elif defined(WITH_MBEDTLS) mbedtls_cipher_free((mbedtls_cipher_context_t*) ctx); + free(ctx); #endif } @@ -631,7 +637,7 @@ void winpr_Cipher_Free(WINPR_CIPHER_CTX* ctx) * Key Generation */ -int winpr_openssl_BytesToKey(int cipher, int md, const BYTE* salt, const BYTE* data, int datal, int count, BYTE* key, BYTE* iv) +int winpr_Cipher_BytesToKey(int cipher, int md, const BYTE* salt, const BYTE* data, int datal, int count, BYTE* key, BYTE* iv) { /** * Key and IV generation compatible with OpenSSL EVP_BytesToKey(): @@ -671,13 +677,13 @@ int winpr_openssl_BytesToKey(int cipher, int md, const BYTE* salt, const BYTE* d mbedtls_md_init(&ctx); + if (mbedtls_md_setup(&ctx, md_info, 0) != 0) + goto err; + while (1) { - if (mbedtls_md_setup(&ctx, md_info, 0) != 0) - return 0; - if (mbedtls_md_starts(&ctx) != 0) - return 0; + goto err; if (addmd++) { diff --git a/winpr/libwinpr/crypto/crypto.c b/winpr/libwinpr/crypto/crypto.c index 144222af3..2ce6a8625 100644 --- a/winpr/libwinpr/crypto/crypto.c +++ b/winpr/libwinpr/crypto/crypto.c @@ -177,7 +177,7 @@ BOOL CryptProtectMemory(LPVOID pData, DWORD cbData, DWORD dwFlags) winpr_RAND(pMemBlock->salt, 8); winpr_RAND(randomKey, sizeof(randomKey)); - winpr_openssl_BytesToKey(WINPR_CIPHER_AES_256_CBC, WINPR_MD_SHA1, + winpr_Cipher_BytesToKey(WINPR_CIPHER_AES_256_CBC, WINPR_MD_SHA1, pMemBlock->salt, randomKey, sizeof(randomKey), 4, pMemBlock->key, pMemBlock->iv); SecureZeroMemory(randomKey, sizeof(randomKey)); diff --git a/winpr/libwinpr/crypto/hash.c b/winpr/libwinpr/crypto/hash.c index 70c4392fa..ccc768ced 100644 --- a/winpr/libwinpr/crypto/hash.c +++ b/winpr/libwinpr/crypto/hash.c @@ -39,172 +39,6 @@ #include #endif -/** - * MD5 - */ - -BOOL winpr_MD5_Init(WINPR_MD5_CTX* ctx) -{ -#if defined(WITH_OPENSSL) - if (MD5_Init((MD5_CTX*) ctx) != 1) - return FALSE; -#elif defined(WITH_MBEDTLS) && defined(MBEDTLS_MD5_C) - mbedtls_md5_init((mbedtls_md5_context*) ctx); - mbedtls_md5_starts((mbedtls_md5_context*) ctx); -#endif - - return TRUE; -} - -BOOL winpr_MD5_Update(WINPR_MD5_CTX* ctx, const BYTE* input, size_t ilen) -{ -#if defined(WITH_OPENSSL) - if (MD5_Update((MD5_CTX*) ctx, input, ilen) != 1) - return FALSE; -#elif defined(WITH_MBEDTLS) && defined(MBEDTLS_MD5_C) - mbedtls_md5_update((mbedtls_md5_context*) ctx, input, ilen); -#endif - - return TRUE; -} - -BOOL winpr_MD5_Final(WINPR_MD5_CTX* ctx, BYTE* output, size_t ilen) -{ - if (ilen < WINPR_MD5_DIGEST_LENGTH) - return FALSE; - -#if defined(WITH_OPENSSL) - if (MD5_Final(output, (MD5_CTX*) ctx) != 1) - return FALSE; -#elif defined(WITH_MBEDTLS) && defined(MBEDTLS_MD5_C) - mbedtls_md5_finish((mbedtls_md5_context*) ctx, output); - mbedtls_md5_free((mbedtls_md5_context*) ctx); -#endif - - return TRUE; -} - -BOOL winpr_MD5(const BYTE* input, size_t ilen, BYTE* output, size_t olen) -{ - WINPR_MD5_CTX ctx; - - if (!winpr_MD5_Init(&ctx)) - return FALSE; - if (!winpr_MD5_Update(&ctx, input, ilen)) - return FALSE; - return winpr_MD5_Final(&ctx, output, olen); -} - -/** - * MD4 - */ - -BOOL winpr_MD4_Init(WINPR_MD4_CTX* ctx) -{ -#if defined(WITH_OPENSSL) - if (MD4_Init((MD4_CTX*) ctx) != 1) - return FALSE; -#elif defined(WITH_MBEDTLS) && defined(MBEDTLS_MD4_C) - mbedtls_md4_init((mbedtls_md4_context*) ctx); - mbedtls_md4_starts((mbedtls_md4_context*) ctx); -#endif - return TRUE; -} - -BOOL winpr_MD4_Update(WINPR_MD4_CTX* ctx, const BYTE* input, size_t ilen) -{ -#if defined(WITH_OPENSSL) - if (MD4_Update((MD4_CTX*) ctx, input, ilen) != 1) - return FALSE; -#elif defined(WITH_MBEDTLS) && defined(MBEDTLS_MD4_C) - mbedtls_md4_update((mbedtls_md4_context*) ctx, input, ilen); -#endif - - return TRUE; -} - -BOOL winpr_MD4_Final(WINPR_MD4_CTX* ctx, BYTE* output, size_t olen) -{ - if (olen < WINPR_MD4_DIGEST_LENGTH) - return FALSE; - -#if defined(WITH_OPENSSL) - if (MD4_Final(output, (MD4_CTX*) ctx) != 1) - return FALSE; -#elif defined(WITH_MBEDTLS) && defined(MBEDTLS_MD4_C) - mbedtls_md4_finish((mbedtls_md4_context*) ctx, output); - mbedtls_md4_free((mbedtls_md4_context*) ctx); -#endif - - return TRUE; -} - -BOOL winpr_MD4(const BYTE* input, size_t ilen, BYTE* output, size_t olen) -{ - WINPR_MD4_CTX ctx; - - if (!winpr_MD4_Init(&ctx)) - return FALSE; - if (!winpr_MD4_Update(&ctx, input, ilen)) - return FALSE; - return winpr_MD4_Final(&ctx, output, olen); -} - -/** - * SHA1 - */ - -BOOL winpr_SHA1_Init(WINPR_SHA1_CTX* ctx) -{ -#if defined(WITH_OPENSSL) - if (SHA1_Init((SHA_CTX*) ctx) != 1) - return FALSE; -#elif defined(WITH_MBEDTLS) && defined(MBEDTLS_SHA1_C) - mbedtls_sha1_init((mbedtls_sha1_context*) ctx); - mbedtls_sha1_starts((mbedtls_sha1_context*) ctx); -#endif - - return TRUE; -} - -BOOL winpr_SHA1_Update(WINPR_SHA1_CTX* ctx, const BYTE* input, size_t ilen) -{ -#if defined(WITH_OPENSSL) - if (SHA1_Update((SHA_CTX*) ctx, input, ilen) != 1) - return FALSE; -#elif defined(WITH_MBEDTLS) && defined(MBEDTLS_SHA1_C) - mbedtls_sha1_update((mbedtls_sha1_context*) ctx, input, ilen); -#endif - - return TRUE; -} - -BOOL winpr_SHA1_Final(WINPR_SHA1_CTX* ctx, BYTE* output, size_t olen) -{ - if (olen < WINPR_SHA1_DIGEST_LENGTH) - return FALSE; - -#if defined(WITH_OPENSSL) - if (SHA1_Final(output, (SHA_CTX*) ctx) != 1) - return FALSE; -#elif defined(WITH_MBEDTLS) && defined(MBEDTLS_SHA1_C) - mbedtls_sha1_finish((mbedtls_sha1_context*) ctx, output); - mbedtls_sha1_free((mbedtls_sha1_context*) ctx); -#endif - - return TRUE; -} - -BOOL winpr_SHA1(const BYTE* input, size_t ilen, BYTE* output, size_t olen) -{ - WINPR_SHA1_CTX ctx; - - if (!winpr_SHA1_Init(&ctx)) - return FALSE; - if (!winpr_SHA1_Update(&ctx, input, ilen)) - return FALSE; - return winpr_SHA1_Final(&ctx, output, olen); -} /** * HMAC @@ -308,53 +142,89 @@ mbedtls_md_type_t winpr_mbedtls_get_md_type(int md) } #endif -BOOL winpr_HMAC_Init(WINPR_HMAC_CTX* ctx, WINPR_MD_TYPE md, const BYTE* key, size_t keylen) + +WINPR_HMAC_CTX* winpr_HMAC_New(WINPR_MD_TYPE md, const BYTE* key, size_t keylen) { + WINPR_HMAC_CTX* ctx = NULL; + #if defined(WITH_OPENSSL) const EVP_MD* evp = winpr_openssl_get_evp_md(md); + HMAC_CTX* hmac; if (!evp) - return FALSE; + return NULL; - HMAC_CTX_init((HMAC_CTX*) ctx); +#if (OPENSSL_VERSION_NUMBER < 0x10100000L) + if (!(hmac = calloc(1, sizeof(HMAC_CTX)))) + return NULL; + + HMAC_CTX_init(hmac); +#else + if (!(hmac = HMAC_CTX_new())) + return NULL; +#endif #if (OPENSSL_VERSION_NUMBER < 0x10000000L) - HMAC_Init_ex((HMAC_CTX*) ctx, key, keylen, evp, NULL); + HMAC_Init_ex(hmac, key, keylen, evp, NULL); #else - if (HMAC_Init_ex((HMAC_CTX*) ctx, key, keylen, evp, NULL) != 1) - return FALSE; + if (HMAC_Init_ex(hmac, key, keylen, evp, NULL) != 1) + { +#if (OPENSSL_VERSION_NUMBER < 0x10100000L) + HMAC_CTX_cleanup(hmac); + free(hmac); +#else + HMAC_CTX_free(hmac); #endif + return NULL; + } +#endif + ctx = (WINPR_HMAC_CTX*) hmac; #elif defined(WITH_MBEDTLS) - const mbedtls_md_info_t* md_info; + mbedtls_md_context_t* mdctx; mbedtls_md_type_t md_type = winpr_mbedtls_get_md_type(md); - md_info = mbedtls_md_info_from_type(md_type); + const mbedtls_md_info_t* md_info = mbedtls_md_info_from_type(md_type); if (!md_info) - return FALSE; + return NULL; - mbedtls_md_init((mbedtls_md_context_t*) ctx); + if (!(mdctx = (mbedtls_md_context_t*) calloc(1, sizeof(mbedtls_md_context_t)))) + return NULL; - if (mbedtls_md_setup((mbedtls_md_context_t*) ctx, md_info, 1) != 0) - return FALSE; + mbedtls_md_init(mdctx); - if (mbedtls_md_hmac_starts((mbedtls_md_context_t*) ctx, key, keylen) != 0) - return FALSE; + if (mbedtls_md_setup(mdctx, md_info, 1) != 0) + { + mbedtls_md_free(mdctx); + free(mdctx); + return NULL; + } + + if (mbedtls_md_hmac_starts(mdctx, key, keylen) != 0) + { + mbedtls_md_free(mdctx); + free(mdctx); + return NULL; + } + ctx = (WINPR_HMAC_CTX*) mdctx; #endif - return TRUE; + return ctx; } BOOL winpr_HMAC_Update(WINPR_HMAC_CTX* ctx, const BYTE* input, size_t ilen) { #if defined(WITH_OPENSSL) + HMAC_CTX* hmac = (HMAC_CTX*) ctx; #if (OPENSSL_VERSION_NUMBER < 0x10000000L) - HMAC_Update((HMAC_CTX*) ctx, input, ilen); + HMAC_Update(hmac, input, ilen); #else - if (HMAC_Update((HMAC_CTX*) ctx, input, ilen) != 1) + if (HMAC_Update(hmac, input, ilen) != 1) return FALSE; #endif + #elif defined(WITH_MBEDTLS) - if (mbedtls_md_hmac_update((mbedtls_md_context_t*) ctx, input, ilen) != 0) + mbedtls_md_context_t* mdctx = (mbedtls_md_context_t*) ctx; + if (mbedtls_md_hmac_update(mdctx, input, ilen) != 0) return FALSE; #endif return TRUE; @@ -366,36 +236,46 @@ BOOL winpr_HMAC_Final(WINPR_HMAC_CTX* ctx, BYTE* output, size_t olen) if (olen < ctx->digestLength) return FALSE; */ - + BOOL ret = TRUE; #if defined(WITH_OPENSSL) + HMAC_CTX* hmac = (HMAC_CTX*) ctx; #if (OPENSSL_VERSION_NUMBER < 0x10000000L) - HMAC_Final((HMAC_CTX*) ctx, output, NULL); + HMAC_Final(hmac, output, NULL); #else - if (HMAC_Final((HMAC_CTX*) ctx, output, NULL) != 1) - return FALSE; + if (HMAC_Final(hmac, output, NULL) != 1) + ret = FALSE; #endif - HMAC_CTX_cleanup((HMAC_CTX*) ctx); + +#if (OPENSSL_VERSION_NUMBER < 0x10100000L) + HMAC_CTX_cleanup(hmac); + free(hmac); +#else + HMAC_CTX_free(hmac); +#endif + #elif defined(WITH_MBEDTLS) - if (mbedtls_md_hmac_finish((mbedtls_md_context_t*) ctx, output) != 0) - return FALSE; + mbedtls_md_context_t* mdctx = (mbedtls_md_context_t*) ctx; + if (mbedtls_md_hmac_finish(mdctx, output) != 0) + ret = FALSE; mbedtls_md_free((mbedtls_md_context_t*) ctx); + free(mdctx); #endif - return TRUE; + return ret; } BOOL winpr_HMAC(WINPR_MD_TYPE md, const BYTE* key, size_t keylen, const BYTE* input, size_t ilen, BYTE* output, size_t olen) { - WINPR_HMAC_CTX ctx; + WINPR_HMAC_CTX *ctx = winpr_HMAC_New(md, key, keylen); - if (!winpr_HMAC_Init(&ctx, md, key, keylen)) + if (!ctx) return FALSE; - if (!winpr_HMAC_Update(&ctx, input, ilen)) + if (!winpr_HMAC_Update(ctx, input, ilen)) return FALSE; - if (!winpr_HMAC_Final(&ctx, output, olen)) + if (!winpr_HMAC_Final(ctx, output, olen)) return FALSE; return TRUE; @@ -405,44 +285,77 @@ BOOL winpr_HMAC(WINPR_MD_TYPE md, const BYTE* key, size_t keylen, * Generic Digest API */ -BOOL winpr_Digest_Init(WINPR_DIGEST_CTX* ctx, WINPR_MD_TYPE md) +WINPR_DIGEST_CTX* winpr_Digest_New(WINPR_MD_TYPE md) { + WINPR_DIGEST_CTX* ctx = NULL; + #if defined(WITH_OPENSSL) const EVP_MD* evp = winpr_openssl_get_evp_md(md); + EVP_MD_CTX* mdctx; if (!evp) - return FALSE; + return NULL; - EVP_MD_CTX_init((EVP_MD_CTX*) ctx); +#if (OPENSSL_VERSION_NUMBER < 0x10100000L) + mdctx = EVP_MD_CTX_create(); +#else + mdctx = EVP_MD_CTX_new(); +#endif + if (!mdctx) + return NULL; + + if (EVP_DigestInit_ex(mdctx, evp, NULL) != 1) + { +#if (OPENSSL_VERSION_NUMBER < 0x10100000L) + EVP_MD_CTX_destroy(mdctx); +#else + EVP_MD_CTX_free(mdctx); +#endif + return NULL; + } + ctx = (WINPR_DIGEST_CTX*) mdctx; - if (EVP_DigestInit_ex((EVP_MD_CTX*) ctx, evp, NULL) != 1) - return FALSE; #elif defined(WITH_MBEDTLS) - const mbedtls_md_info_t* md_info; + mbedtls_md_context_t* mdctx; mbedtls_md_type_t md_type = winpr_mbedtls_get_md_type(md); - md_info = mbedtls_md_info_from_type(md_type); + const mbedtls_md_info_t* md_info = mbedtls_md_info_from_type(md_type); if (!md_info) - return FALSE; + return NULL; - mbedtls_md_init((mbedtls_md_context_t*) ctx); + if (!(mdctx = (mbedtls_md_context_t*) calloc(1, sizeof(mbedtls_md_context_t)))) + return NULL; - if (mbedtls_md_setup((mbedtls_md_context_t*) ctx, md_info, 0) != 0) - return FALSE; + mbedtls_md_init(mdctx); - if (mbedtls_md_starts((mbedtls_md_context_t*) ctx) != 0) - return FALSE; + if (mbedtls_md_setup(mdctx, md_info, 0) != 0) + { + mbedtls_md_free(mdctx); + free(mdctx); + return NULL; + } + + if (mbedtls_md_starts(mdctx) != 0) + { + mbedtls_md_free(mdctx); + free(mdctx); + return NULL; + } + ctx = (WINPR_DIGEST_CTX*) mdctx; #endif - return TRUE; + + return ctx; } BOOL winpr_Digest_Update(WINPR_DIGEST_CTX* ctx, const BYTE* input, size_t ilen) { #if defined(WITH_OPENSSL) - if (EVP_DigestUpdate((EVP_MD_CTX*) ctx, input, ilen) != 1) + EVP_MD_CTX* mdctx = (EVP_MD_CTX*) ctx; + if (EVP_DigestUpdate(mdctx, input, ilen) != 1) return FALSE; #elif defined(WITH_MBEDTLS) - if (mbedtls_md_update((mbedtls_md_context_t*) ctx, input, ilen) != 0) + mbedtls_md_context_t* mdctx = (mbedtls_md_context_t*) ctx; + if (mbedtls_md_update(mdctx, input, ilen) != 0) return FALSE; #endif return TRUE; @@ -451,29 +364,40 @@ BOOL winpr_Digest_Update(WINPR_DIGEST_CTX* ctx, const BYTE* input, size_t ilen) BOOL winpr_Digest_Final(WINPR_DIGEST_CTX* ctx, BYTE* output, size_t olen) { // TODO: output length check + BOOL ret = TRUE; #if defined(WITH_OPENSSL) - if (EVP_DigestFinal_ex((EVP_MD_CTX*) ctx, output, NULL) != 1) - return FALSE; -#elif defined(WITH_MBEDTLS) - if (mbedtls_md_finish((mbedtls_md_context_t*) ctx, output) != 0) - return FALSE; + EVP_MD_CTX* mdctx = (EVP_MD_CTX*) ctx; + if (EVP_DigestFinal_ex(mdctx, output, NULL) != 1) + ret = FALSE; - mbedtls_md_free((mbedtls_md_context_t*) ctx); +#if (OPENSSL_VERSION_NUMBER < 0x10100000L) + EVP_MD_CTX_destroy(mdctx); +#else + EVP_MD_CTX_free(mdctx); #endif - return TRUE; + +#elif defined(WITH_MBEDTLS) + mbedtls_md_context_t* mdctx = (mbedtls_md_context_t*) ctx; + if (mbedtls_md_finish(mdctx, output) != 0) + ret = FALSE; + + mbedtls_md_free(mdctx); + free(mdctx); +#endif + return ret; } BOOL winpr_Digest(int md, const BYTE* input, size_t ilen, BYTE* output, size_t olen) { - WINPR_DIGEST_CTX ctx; + WINPR_DIGEST_CTX *ctx = winpr_Digest_New(md); - if (!winpr_Digest_Init(&ctx, md)) + if (!ctx) return FALSE; - if (!winpr_Digest_Update(&ctx, input, ilen)) + if (!winpr_Digest_Update(ctx, input, ilen)) return FALSE; - if (!winpr_Digest_Final(&ctx, output, olen)) + if (!winpr_Digest_Final(ctx, output, olen)) return FALSE; return TRUE; diff --git a/winpr/libwinpr/crypto/test/TestCryptoCipher.c b/winpr/libwinpr/crypto/test/TestCryptoCipher.c index cbf940d9a..1f99a3f93 100644 --- a/winpr/libwinpr/crypto/test/TestCryptoCipher.c +++ b/winpr/libwinpr/crypto/test/TestCryptoCipher.c @@ -3,6 +3,112 @@ #include #include + + +static BOOL test_crypto_cipher_aes_128_cbc() +{ + WINPR_CIPHER_CTX* ctx; + BOOL result = FALSE; + BYTE key[] = "0123456789abcdeF"; + BYTE iv[] = "1234567887654321"; + BYTE ibuf[1024]; + BYTE obuf[1024]; + size_t ilen; + size_t olen; + size_t xlen; + const char plaintext[] = "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua."; + + /* encrypt */ + + if (!(ctx = winpr_Cipher_New(WINPR_CIPHER_AES_128_CBC, WINPR_ENCRYPT, key, iv))) + { + fprintf(stderr, "%s: winpr_Cipher_New (encrypt) failed\n", __FUNCTION__); + return FALSE; + } + + memset(ibuf, 0, sizeof(ibuf)); + memset(obuf, 0, sizeof(obuf)); + + ilen = strlen(plaintext) + 1; + memcpy(ibuf, plaintext, ilen); + + ilen = ((ilen + 15) / 16) * 16; + olen = 0; + xlen = 0; + + + if (!winpr_Cipher_Update(ctx, ibuf, ilen, obuf, &olen)) + { + fprintf(stderr, "%s: winpr_Cipher_New (encrypt) failed\n", __FUNCTION__); + goto out; + } + xlen += olen; + + if (!winpr_Cipher_Final(ctx, obuf + xlen, &olen)) + { + fprintf(stderr, "%s: winpr_Cipher_Final (encrypt) failed\n", __FUNCTION__); + goto out; + } + xlen += olen; + + if (xlen != ilen) + { + fprintf(stderr, "%s: error, xlen (%u) != ilen (%u) (encrypt)\n", __FUNCTION__, (unsigned)xlen, (unsigned)ilen); + goto out; + } + + winpr_Cipher_Free(ctx); + + + /* decrypt */ + + if (!(ctx = winpr_Cipher_New(WINPR_CIPHER_AES_128_CBC, WINPR_DECRYPT, key, iv))) + { + fprintf(stderr, "%s: winpr_Cipher_New (decrypt) failed\n", __FUNCTION__); + return FALSE; + } + + memset(ibuf, 0, sizeof(ibuf)); + memcpy(ibuf, obuf, xlen); + memset(obuf, 0, sizeof(obuf)); + + ilen = xlen; + olen = 0; + xlen = 0; + + if (!winpr_Cipher_Update(ctx, ibuf, ilen, obuf, &olen)) + { + fprintf(stderr, "%s: winpr_Cipher_New (decrypt) failed\n", __FUNCTION__); + goto out; + } + xlen += olen; + + if (!winpr_Cipher_Final(ctx, obuf + xlen, &olen)) + { + fprintf(stderr, "%s: winpr_Cipher_Final (decrypt) failed\n", __FUNCTION__); + goto out; + } + xlen += olen; + + if (xlen != ilen) + { + fprintf(stderr, "%s: error, xlen (%u) != ilen (%u) (decrypt)\n", __FUNCTION__, (unsigned)xlen, (unsigned)ilen); + goto out; + } + + if (strcmp((const char*) obuf, plaintext)) + { + fprintf(stderr, "%s: error, decrypted data does not match plaintext\n", __FUNCTION__); + goto out; + } + + result = TRUE; + +out: + winpr_Cipher_Free(ctx); + return result; +} + static const BYTE* TEST_RC4_KEY = (BYTE*) "Key"; static const char* TEST_RC4_PLAINTEXT = "Plaintext"; static const BYTE* TEST_RC4_CIPHERTEXT = (BYTE*) "\xBB\xF3\x16\xE8\xD9\x40\xAF\x0A\xD3"; @@ -16,17 +122,24 @@ static BOOL test_crypto_cipher_rc4() len = strlen(TEST_RC4_PLAINTEXT); - text = (BYTE*) calloc(1, len); - - if (!text) + if (!(text = (BYTE*) calloc(1, len))) + { + fprintf(stderr, "%s: failed to allocate text buffer (len=%u)\n", __FUNCTION__, (unsigned)len); goto out; + } if ((ctx = winpr_RC4_New(TEST_RC4_KEY, strlen((char*) TEST_RC4_KEY))) == NULL) + { + fprintf(stderr, "%s: winpr_RC4_New failed\n", __FUNCTION__); goto out; + } rc = winpr_RC4_Update(ctx, len, (BYTE*) TEST_RC4_PLAINTEXT, text); winpr_RC4_Free(ctx); if (!rc) + { + fprintf(stderr, "%s: winpr_RC4_Update failed\n", __FUNCTION__); goto out; + } if (memcmp(text, TEST_RC4_CIPHERTEXT, len) != 0) { @@ -36,7 +149,7 @@ static BOOL test_crypto_cipher_rc4() actual = winpr_BinToHexString(text, len, FALSE); expected = winpr_BinToHexString(TEST_RC4_CIPHERTEXT, len, FALSE); - fprintf(stderr, "unexpected RC4 ciphertext: Actual: %s Expected: %s\n", actual, expected); + fprintf(stderr, "%s: unexpected RC4 ciphertext: Actual: %s Expected: %s\n", __FUNCTION__, actual, expected); free(actual); free(expected); @@ -73,7 +186,7 @@ static BOOL test_crypto_cipher_key() ZeroMemory(key, sizeof(key)); ZeroMemory(iv, sizeof(iv)); - status = winpr_openssl_BytesToKey(WINPR_CIPHER_AES_256_CBC, WINPR_MD_SHA1, + status = winpr_Cipher_BytesToKey(WINPR_CIPHER_AES_256_CBC, WINPR_MD_SHA1, salt, TEST_RAND_DATA, 64, 4, key, iv); if (status != 32 || memcmp(key, TEST_CIPHER_KEY, 32) || memcmp(iv, TEST_CIPHER_IV, 16)) @@ -103,6 +216,9 @@ static BOOL test_crypto_cipher_key() int TestCryptoCipher(int argc, char* argv[]) { + if (!test_crypto_cipher_aes_128_cbc()) + return -1; + if (!test_crypto_cipher_rc4()) return -1; diff --git a/winpr/libwinpr/crypto/test/TestCryptoHash.c b/winpr/libwinpr/crypto/test/TestCryptoHash.c index ffdf3dba9..f5b990d65 100644 --- a/winpr/libwinpr/crypto/test/TestCryptoHash.c +++ b/winpr/libwinpr/crypto/test/TestCryptoHash.c @@ -9,14 +9,23 @@ static const BYTE* TEST_MD5_HASH = (BYTE*) "\x09\x8f\x6b\xcd\x46\x21\xd3\x73\xca static BOOL test_crypto_hash_md5(void) { BYTE hash[WINPR_MD5_DIGEST_LENGTH]; - WINPR_MD5_CTX ctx; + WINPR_DIGEST_CTX* ctx; - if (!winpr_MD5_Init(&ctx)) + if (!(ctx = winpr_Digest_New(WINPR_MD_MD5))) + { + fprintf(stderr, "%s: winpr_Digest_New failed\n", __FUNCTION__); return FALSE; - if (!winpr_MD5_Update(&ctx, (BYTE*) TEST_MD5_DATA, strlen(TEST_MD5_DATA))) + } + if (!winpr_Digest_Update(ctx, (BYTE*) TEST_MD5_DATA, strlen(TEST_MD5_DATA))) + { + fprintf(stderr, "%s: winpr_Digest_Update failed\n", __FUNCTION__); return FALSE; - if (!winpr_MD5_Final(&ctx, hash, sizeof(hash))) + } + if (!winpr_Digest_Final(ctx, hash, sizeof(hash))) + { + fprintf(stderr, "%s: winpr_Digest_Final failed\n", __FUNCTION__); return FALSE; + } if (memcmp(hash, TEST_MD5_HASH, WINPR_MD5_DIGEST_LENGTH) != 0) { @@ -43,14 +52,23 @@ static const BYTE* TEST_MD4_HASH = (BYTE*) "\xdb\x34\x6d\x69\x1d\x7a\xcc\x4d\xc2 static BOOL test_crypto_hash_md4(void) { BYTE hash[WINPR_MD4_DIGEST_LENGTH]; - WINPR_MD4_CTX ctx; + WINPR_DIGEST_CTX* ctx; - if (!winpr_MD4_Init(&ctx)) + if (!(ctx = winpr_Digest_New(WINPR_MD_MD4))) + { + fprintf(stderr, "%s: winpr_Digest_New failed\n", __FUNCTION__); return FALSE; - if (!winpr_MD4_Update(&ctx, (BYTE*) TEST_MD4_DATA, strlen(TEST_MD4_DATA))) + } + if (!winpr_Digest_Update(ctx, (BYTE*) TEST_MD4_DATA, strlen(TEST_MD4_DATA))) + { + fprintf(stderr, "%s: winpr_Digest_Update failed\n", __FUNCTION__); return FALSE; - if (!winpr_MD4_Final(&ctx, hash, sizeof(hash))) + } + if (!winpr_Digest_Final(ctx, hash, sizeof(hash))) + { + fprintf(stderr, "%s: winpr_Digest_Final failed\n", __FUNCTION__); return FALSE; + } if (memcmp(hash, TEST_MD4_HASH, WINPR_MD4_DIGEST_LENGTH) != 0) { @@ -77,14 +95,23 @@ static const BYTE* TEST_SHA1_HASH = (BYTE*) "\xa9\x4a\x8f\xe5\xcc\xb1\x9b\xa6\x1 static BOOL test_crypto_hash_sha1(void) { BYTE hash[WINPR_SHA1_DIGEST_LENGTH]; - WINPR_SHA1_CTX ctx; + WINPR_DIGEST_CTX* ctx; - if (!winpr_SHA1_Init(&ctx)) + if (!(ctx = winpr_Digest_New(WINPR_MD_SHA1))) + { + fprintf(stderr, "%s: winpr_Digest_New failed\n", __FUNCTION__); return FALSE; - if (!winpr_SHA1_Update(&ctx, (BYTE*) TEST_SHA1_DATA, strlen(TEST_SHA1_DATA))) + } + if (!winpr_Digest_Update(ctx, (BYTE*) TEST_SHA1_DATA, strlen(TEST_SHA1_DATA))) + { + fprintf(stderr, "%s: winpr_Digest_Update failed\n", __FUNCTION__); return FALSE; - if (!winpr_SHA1_Final(&ctx, hash, sizeof(hash))) + } + if (!winpr_Digest_Final(ctx, hash, sizeof(hash))) + { + fprintf(stderr, "%s: winpr_Digest_Final failed\n", __FUNCTION__); return FALSE; + } if (memcmp(hash, TEST_SHA1_HASH, WINPR_MD5_DIGEST_LENGTH) != 0) { @@ -112,14 +139,23 @@ static const BYTE* TEST_HMAC_MD5_HASH = (BYTE*) "\x92\x94\x72\x7a\x36\x38\xbb\x1 static BOOL test_crypto_hash_hmac_md5(void) { BYTE hash[WINPR_MD5_DIGEST_LENGTH]; - WINPR_HMAC_CTX ctx; + WINPR_HMAC_CTX* ctx; - if (!winpr_HMAC_Init(&ctx, WINPR_MD_MD5, TEST_HMAC_MD5_KEY, WINPR_MD5_DIGEST_LENGTH)) + if (!(ctx = winpr_HMAC_New(WINPR_MD_MD5, TEST_HMAC_MD5_KEY, WINPR_MD5_DIGEST_LENGTH))) + { + fprintf(stderr, "%s: winpr_HMAC_New failed\n", __FUNCTION__); return FALSE; - if (!winpr_HMAC_Update(&ctx, (BYTE*) TEST_HMAC_MD5_DATA, strlen(TEST_HMAC_MD5_DATA))) + } + if (!winpr_HMAC_Update(ctx, (BYTE*) TEST_HMAC_MD5_DATA, strlen(TEST_HMAC_MD5_DATA))) + { + fprintf(stderr, "%s: winpr_HMAC_Update failed\n", __FUNCTION__); return FALSE; - if (!winpr_HMAC_Final(&ctx, hash, sizeof(hash))) + } + if (!winpr_HMAC_Final(ctx, hash, sizeof(hash))) + { + fprintf(stderr, "%s: winpr_HMAC_Final failed\n", __FUNCTION__); return FALSE; + } if (memcmp(hash, TEST_HMAC_MD5_HASH, WINPR_MD5_DIGEST_LENGTH) != 0) { @@ -147,14 +183,23 @@ static const BYTE* TEST_HMAC_SHA1_HASH = (BYTE*) "\xb6\x17\x31\x86\x55\x05\x72\x static BOOL test_crypto_hash_hmac_sha1(void) { BYTE hash[WINPR_SHA1_DIGEST_LENGTH]; - WINPR_HMAC_CTX ctx; + WINPR_HMAC_CTX* ctx; - if (!winpr_HMAC_Init(&ctx, WINPR_MD_SHA1, TEST_HMAC_SHA1_KEY, WINPR_SHA1_DIGEST_LENGTH)) + if (!(ctx = winpr_HMAC_New(WINPR_MD_SHA1, TEST_HMAC_SHA1_KEY, WINPR_SHA1_DIGEST_LENGTH))) + { + fprintf(stderr, "%s: winpr_HMAC_New failed\n", __FUNCTION__); return FALSE; - if (!winpr_HMAC_Update(&ctx, (BYTE*) TEST_HMAC_SHA1_DATA, strlen(TEST_HMAC_SHA1_DATA))) + } + if (!winpr_HMAC_Update(ctx, (BYTE*) TEST_HMAC_SHA1_DATA, strlen(TEST_HMAC_SHA1_DATA))) + { + fprintf(stderr, "%s: winpr_HMAC_Update failed\n", __FUNCTION__); return FALSE; - if (!winpr_HMAC_Final(&ctx, hash, sizeof(hash))) + } + if (!winpr_HMAC_Final(ctx, hash, sizeof(hash))) + { + fprintf(stderr, "%s: winpr_HMAC_Final failed\n", __FUNCTION__); return FALSE; + } if (memcmp(hash, TEST_HMAC_SHA1_HASH, WINPR_SHA1_DIGEST_LENGTH) != 0) { diff --git a/winpr/libwinpr/sspi/NTLM/ntlm.c b/winpr/libwinpr/sspi/NTLM/ntlm.c index 0420dcf76..2eff5aa29 100644 --- a/winpr/libwinpr/sspi/NTLM/ntlm.c +++ b/winpr/libwinpr/sspi/NTLM/ntlm.c @@ -913,7 +913,7 @@ SECURITY_STATUS SEC_ENTRY ntlm_EncryptMessage(PCtxtHandle phContext, ULONG fQOP, BYTE checksum[8]; BYTE* signature; ULONG version = 1; - WINPR_HMAC_CTX hmac; + WINPR_HMAC_CTX* hmac; NTLM_CONTEXT* context; PSecBuffer data_buffer = NULL; PSecBuffer signature_buffer = NULL; @@ -943,11 +943,16 @@ SECURITY_STATUS SEC_ENTRY ntlm_EncryptMessage(PCtxtHandle phContext, ULONG fQOP, CopyMemory(data, data_buffer->pvBuffer, length); /* Compute the HMAC-MD5 hash of ConcatenationOf(seq_num,data) using the client signing key */ - winpr_HMAC_Init(&hmac, WINPR_MD_MD5, context->SendSigningKey, WINPR_MD5_DIGEST_LENGTH); + if (!(hmac = winpr_HMAC_New(WINPR_MD_MD5, context->SendSigningKey, WINPR_MD5_DIGEST_LENGTH))) + { + free(data); + return SEC_E_INSUFFICIENT_MEMORY; + } + Data_Write_UINT32(&value, SeqNo); - winpr_HMAC_Update(&hmac, (void*) &value, 4); - winpr_HMAC_Update(&hmac, (void*) data, length); - winpr_HMAC_Final(&hmac, digest, WINPR_MD5_DIGEST_LENGTH); + winpr_HMAC_Update(hmac, (void*) &value, 4); + winpr_HMAC_Update(hmac, (void*) data, length); + winpr_HMAC_Final(hmac, digest, WINPR_MD5_DIGEST_LENGTH); /* Encrypt message using with RC4, result overwrites original buffer */ @@ -988,7 +993,7 @@ SECURITY_STATUS SEC_ENTRY ntlm_DecryptMessage(PCtxtHandle phContext, PSecBufferD BYTE digest[WINPR_MD5_DIGEST_LENGTH]; BYTE checksum[8]; UINT32 version = 1; - WINPR_HMAC_CTX hmac; + WINPR_HMAC_CTX* hmac; NTLM_CONTEXT* context; BYTE expected_signature[WINPR_MD5_DIGEST_LENGTH]; PSecBuffer data_buffer = NULL; @@ -1027,11 +1032,15 @@ SECURITY_STATUS SEC_ENTRY ntlm_DecryptMessage(PCtxtHandle phContext, PSecBufferD CopyMemory(data_buffer->pvBuffer, data, length); /* Compute the HMAC-MD5 hash of ConcatenationOf(seq_num,data) using the client signing key */ - winpr_HMAC_Init(&hmac, WINPR_MD_MD5, context->RecvSigningKey, WINPR_MD5_DIGEST_LENGTH); + if (!(hmac = winpr_HMAC_New(WINPR_MD_MD5, context->RecvSigningKey, WINPR_MD5_DIGEST_LENGTH))) + { + free(data); + return SEC_E_INSUFFICIENT_MEMORY; + } Data_Write_UINT32(&value, SeqNo); - winpr_HMAC_Update(&hmac, (void*) &value, 4); - winpr_HMAC_Update(&hmac, (void*) data_buffer->pvBuffer, data_buffer->cbBuffer); - winpr_HMAC_Final(&hmac, digest, WINPR_MD5_DIGEST_LENGTH); + winpr_HMAC_Update(hmac, (void*) &value, 4); + winpr_HMAC_Update(hmac, (void*) data_buffer->pvBuffer, data_buffer->cbBuffer); + winpr_HMAC_Final(hmac, digest, WINPR_MD5_DIGEST_LENGTH); #ifdef WITH_DEBUG_NTLM WLog_DBG(TAG, "Encrypted Data Buffer (length = %d)", length); winpr_HexDump(TAG, WLOG_DEBUG, data, length); diff --git a/winpr/libwinpr/sspi/NTLM/ntlm_av_pairs.c b/winpr/libwinpr/sspi/NTLM/ntlm_av_pairs.c index e14071386..4d643b58f 100644 --- a/winpr/libwinpr/sspi/NTLM/ntlm_av_pairs.c +++ b/winpr/libwinpr/sspi/NTLM/ntlm_av_pairs.c @@ -246,19 +246,19 @@ typedef struct gss_channel_bindings_struct { } *gss_channel_bindings_t; */ -static void ntlm_md5_update_uint32_be(WINPR_MD5_CTX* md5, UINT32 num) +static void ntlm_md5_update_uint32_be(WINPR_DIGEST_CTX* md5, UINT32 num) { BYTE be32[4]; be32[0] = (num >> 0) & 0xFF; be32[1] = (num >> 8) & 0xFF; be32[2] = (num >> 16) & 0xFF; be32[3] = (num >> 24) & 0xFF; - winpr_MD5_Update(md5, be32, 4); + winpr_Digest_Update(md5, be32, 4); } void ntlm_compute_channel_bindings(NTLM_CONTEXT* context) { - WINPR_MD5_CTX md5; + WINPR_DIGEST_CTX* md5; BYTE* ChannelBindingToken; UINT32 ChannelBindingTokenLength; SEC_CHANNEL_BINDINGS* ChannelBindings; @@ -269,16 +269,20 @@ void ntlm_compute_channel_bindings(NTLM_CONTEXT* context) if (!ChannelBindings) return; + if (!(md5 = winpr_Digest_New(WINPR_MD_MD5))) + return; + ChannelBindingTokenLength = context->Bindings.BindingsLength - sizeof(SEC_CHANNEL_BINDINGS); ChannelBindingToken = &((BYTE*) ChannelBindings)[ChannelBindings->dwApplicationDataOffset]; - winpr_MD5_Init(&md5); - ntlm_md5_update_uint32_be(&md5, ChannelBindings->dwInitiatorAddrType); - ntlm_md5_update_uint32_be(&md5, ChannelBindings->cbInitiatorLength); - ntlm_md5_update_uint32_be(&md5, ChannelBindings->dwAcceptorAddrType); - ntlm_md5_update_uint32_be(&md5, ChannelBindings->cbAcceptorLength); - ntlm_md5_update_uint32_be(&md5, ChannelBindings->cbApplicationDataLength); - winpr_MD5_Update(&md5, (void*) ChannelBindingToken, ChannelBindingTokenLength); - winpr_MD5_Final(&md5, context->ChannelBindingsHash, WINPR_MD5_DIGEST_LENGTH); + + ntlm_md5_update_uint32_be(md5, ChannelBindings->dwInitiatorAddrType); + ntlm_md5_update_uint32_be(md5, ChannelBindings->cbInitiatorLength); + ntlm_md5_update_uint32_be(md5, ChannelBindings->dwAcceptorAddrType); + ntlm_md5_update_uint32_be(md5, ChannelBindings->cbAcceptorLength); + ntlm_md5_update_uint32_be(md5, ChannelBindings->cbApplicationDataLength); + + winpr_Digest_Update(md5, (void*) ChannelBindingToken, ChannelBindingTokenLength); + winpr_Digest_Final(md5, context->ChannelBindingsHash, WINPR_MD5_DIGEST_LENGTH); } void ntlm_compute_single_host_data(NTLM_CONTEXT* context) diff --git a/winpr/libwinpr/sspi/NTLM/ntlm_compute.c b/winpr/libwinpr/sspi/NTLM/ntlm_compute.c index bde267bf7..8fb194c73 100644 --- a/winpr/libwinpr/sspi/NTLM/ntlm_compute.c +++ b/winpr/libwinpr/sspi/NTLM/ntlm_compute.c @@ -549,7 +549,7 @@ int ntlm_generate_signing_key(BYTE* exported_session_key, PSecBuffer sign_magic, { int length; BYTE* value; - WINPR_MD5_CTX md5; + WINPR_DIGEST_CTX* md5; length = WINPR_MD5_DIGEST_LENGTH + sign_magic->cbBuffer; value = (BYTE*) malloc(length); @@ -560,9 +560,14 @@ int ntlm_generate_signing_key(BYTE* exported_session_key, PSecBuffer sign_magic, /* Concatenate ExportedSessionKey with sign magic */ CopyMemory(value, exported_session_key, WINPR_MD5_DIGEST_LENGTH); CopyMemory(&value[WINPR_MD5_DIGEST_LENGTH], sign_magic->pvBuffer, sign_magic->cbBuffer); - winpr_MD5_Init(&md5); - winpr_MD5_Update(&md5, value, length); - winpr_MD5_Final(&md5, signing_key, WINPR_MD5_DIGEST_LENGTH); + + if (!(md5 = winpr_Digest_New(WINPR_MD_MD5))) + { + free(value); + return -1; + } + winpr_Digest_Update(md5, value, length); + winpr_Digest_Final(md5, signing_key, WINPR_MD5_DIGEST_LENGTH); free(value); return 1; } @@ -606,7 +611,7 @@ void ntlm_generate_server_signing_key(NTLM_CONTEXT* context) int ntlm_generate_sealing_key(BYTE* exported_session_key, PSecBuffer seal_magic, BYTE* sealing_key) { BYTE* p; - WINPR_MD5_CTX md5; + WINPR_DIGEST_CTX* md5; SecBuffer buffer; if (!sspi_SecBufferAlloc(&buffer, WINPR_MD5_DIGEST_LENGTH + seal_magic->cbBuffer)) @@ -616,9 +621,14 @@ int ntlm_generate_sealing_key(BYTE* exported_session_key, PSecBuffer seal_magic, /* Concatenate ExportedSessionKey with seal magic */ CopyMemory(p, exported_session_key, WINPR_MD5_DIGEST_LENGTH); CopyMemory(&p[WINPR_MD5_DIGEST_LENGTH], seal_magic->pvBuffer, seal_magic->cbBuffer); - winpr_MD5_Init(&md5); - winpr_MD5_Update(&md5, buffer.pvBuffer, buffer.cbBuffer); - winpr_MD5_Final(&md5, sealing_key, WINPR_MD5_DIGEST_LENGTH); + + if (!(md5 = winpr_Digest_New(WINPR_MD_MD5))) + { + sspi_SecBufferFree(&buffer); + return -1; + } + winpr_Digest_Update(md5, buffer.pvBuffer, buffer.cbBuffer); + winpr_Digest_Final(md5, sealing_key, WINPR_MD5_DIGEST_LENGTH); sspi_SecBufferFree(&buffer); return 1; } @@ -680,15 +690,18 @@ void ntlm_init_rc4_seal_states(NTLM_CONTEXT* context) void ntlm_compute_message_integrity_check(NTLM_CONTEXT* context) { - WINPR_HMAC_CTX hmac; /* * Compute the HMAC-MD5 hash of ConcatenationOf(NEGOTIATE_MESSAGE, * CHALLENGE_MESSAGE, AUTHENTICATE_MESSAGE) using the ExportedSessionKey */ - winpr_HMAC_Init(&hmac, WINPR_MD_MD5, context->ExportedSessionKey, WINPR_MD5_DIGEST_LENGTH); - winpr_HMAC_Update(&hmac, (BYTE*) context->NegotiateMessage.pvBuffer, context->NegotiateMessage.cbBuffer); - winpr_HMAC_Update(&hmac, (BYTE*) context->ChallengeMessage.pvBuffer, context->ChallengeMessage.cbBuffer); - winpr_HMAC_Update(&hmac, (BYTE*) context->AuthenticateMessage.pvBuffer, context->AuthenticateMessage.cbBuffer); - winpr_HMAC_Final(&hmac, context->MessageIntegrityCheck, WINPR_MD5_DIGEST_LENGTH); + WINPR_HMAC_CTX* hmac = winpr_HMAC_New(WINPR_MD_MD5, context->ExportedSessionKey, WINPR_MD5_DIGEST_LENGTH); + + if (hmac) + { + winpr_HMAC_Update(hmac, (BYTE*) context->NegotiateMessage.pvBuffer, context->NegotiateMessage.cbBuffer); + winpr_HMAC_Update(hmac, (BYTE*) context->ChallengeMessage.pvBuffer, context->ChallengeMessage.cbBuffer); + winpr_HMAC_Update(hmac, (BYTE*) context->AuthenticateMessage.pvBuffer, context->AuthenticateMessage.cbBuffer); + winpr_HMAC_Final(hmac, context->MessageIntegrityCheck, WINPR_MD5_DIGEST_LENGTH); + } } diff --git a/winpr/libwinpr/utils/ntlm.c b/winpr/libwinpr/utils/ntlm.c index fa4493f54..4ca9c8d55 100644 --- a/winpr/libwinpr/utils/ntlm.c +++ b/winpr/libwinpr/utils/ntlm.c @@ -35,18 +35,18 @@ BYTE* NTOWFv1W(LPWSTR Password, UINT32 PasswordLength, BYTE* NtHash) { BOOL allocate = !NtHash; - WINPR_MD4_CTX md4; + WINPR_DIGEST_CTX* md4; if (!Password) return NULL; - if (!winpr_MD4_Init(&md4)) + if (!(md4 = winpr_Digest_New(WINPR_MD_MD4))) return NULL; - if (!winpr_MD4_Update(&md4, (BYTE*) Password, (size_t) PasswordLength)) + if (!winpr_Digest_Update(md4, (BYTE*) Password, (size_t) PasswordLength)) return NULL; if (!NtHash && !(NtHash = malloc(WINPR_MD4_DIGEST_LENGTH))) return NULL; - if (!winpr_MD4_Final(&md4, NtHash, WINPR_MD4_DIGEST_LENGTH)) + if (!winpr_Digest_Final(md4, NtHash, WINPR_MD4_DIGEST_LENGTH)) { if (allocate) free(NtHash); diff --git a/winpr/libwinpr/utils/ssl.c b/winpr/libwinpr/utils/ssl.c index 3da730ca6..86e6b083e 100644 --- a/winpr/libwinpr/utils/ssl.c +++ b/winpr/libwinpr/utils/ssl.c @@ -35,9 +35,21 @@ #include "../log.h" #define TAG WINPR_TAG("utils.ssl") +static BOOL g_winpr_openssl_initialized_by_winpr = FALSE; + + +/** + * Note from OpenSSL 1.1.0 "CHANGES": + * OpenSSL now uses a new threading API. It is no longer necessary to + * set locking callbacks to use OpenSSL in a multi-threaded environment. + */ + +#if (OPENSSL_VERSION_NUMBER < 0x10100000L) + +#define WINPR_OPENSSL_LOCKING_REQUIRED 1 + static int g_winpr_openssl_num_locks = 0; static HANDLE* g_winpr_openssl_locks = NULL; -static BOOL g_winpr_openssl_initialized_by_winpr = FALSE; struct CRYPTO_dynlock_value { @@ -220,6 +232,9 @@ static BOOL _winpr_openssl_cleanup_locking(void) return TRUE; } +#endif /* OpenSSL < 1.1.0 */ + + static BOOL CALLBACK _winpr_openssl_initialize(PINIT_ONCE once, PVOID param, PVOID* context) { DWORD flags = param ? *(PDWORD)param : WINPR_SSL_INIT_DEFAULT; @@ -229,6 +244,7 @@ static BOOL CALLBACK _winpr_openssl_initialize(PINIT_ONCE once, PVOID param, PVO return TRUE; } +#ifdef WINPR_OPENSSL_LOCKING_REQUIRED if (flags & WINPR_SSL_INIT_ENABLE_LOCKING) { if (!_winpr_openssl_initialize_locking()) @@ -236,7 +252,7 @@ static BOOL CALLBACK _winpr_openssl_initialize(PINIT_ONCE once, PVOID param, PVO return FALSE; } } - +#endif /* SSL_load_error_strings() is void */ SSL_load_error_strings(); /* SSL_library_init() always returns "1" */ @@ -265,7 +281,9 @@ BOOL winpr_CleanupSSL(DWORD flags) } g_winpr_openssl_initialized_by_winpr = FALSE; +#ifdef WINPR_OPENSSL_LOCKING_REQUIRED _winpr_openssl_cleanup_locking(); +#endif CRYPTO_cleanup_all_ex_data(); ERR_free_strings(); EVP_cleanup();