diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-05-04 01:25:12 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-05-04 01:25:12 +0000 |
commit | 827a4c3faa27e0c186452585b15094eee1119085 (patch) | |
tree | e6a08b0c767863d66f7d4a9de80db5edc7db29be /libfreerdp/crypto | |
parent | Releasing progress-linux version 3.3.0+dfsg1-1~progress7.99u1. (diff) | |
download | freerdp3-827a4c3faa27e0c186452585b15094eee1119085.tar.xz freerdp3-827a4c3faa27e0c186452585b15094eee1119085.zip |
Merging upstream version 3.5.0+dfsg1.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'libfreerdp/crypto')
-rw-r--r-- | libfreerdp/crypto/cert_common.c | 12 | ||||
-rw-r--r-- | libfreerdp/crypto/certificate.c | 35 | ||||
-rw-r--r-- | libfreerdp/crypto/certificate_data.c | 42 | ||||
-rw-r--r-- | libfreerdp/crypto/privatekey.c | 6 | ||||
-rw-r--r-- | libfreerdp/crypto/tls.c | 3 |
5 files changed, 76 insertions, 22 deletions
diff --git a/libfreerdp/crypto/cert_common.c b/libfreerdp/crypto/cert_common.c index 60ef60f..bd0abad 100644 --- a/libfreerdp/crypto/cert_common.c +++ b/libfreerdp/crypto/cert_common.c @@ -144,7 +144,10 @@ BOOL cert_info_allocate(rdpCertInfo* info, size_t size) info->Modulus = (BYTE*)malloc(size); if (!info->Modulus && (size > 0)) + { + WLog_ERR(TAG, "Failed to allocate info->Modulus of size %" PRIuz, size); return FALSE; + } info->ModulusLength = (UINT32)size; return TRUE; } @@ -154,7 +157,10 @@ BOOL cert_info_read_modulus(rdpCertInfo* info, size_t size, wStream* s) if (!Stream_CheckAndLogRequiredLength(TAG, s, size)) return FALSE; if (size > UINT32_MAX) + { + WLog_ERR(TAG, "modulus size %" PRIuz " exceeds limit of %" PRIu32, size, UINT32_MAX); return FALSE; + } if (!cert_info_allocate(info, size)) return FALSE; Stream_Read(s, info->Modulus, info->ModulusLength); @@ -166,9 +172,15 @@ BOOL cert_info_read_exponent(rdpCertInfo* info, size_t size, wStream* s) if (!Stream_CheckAndLogRequiredLength(TAG, s, size)) return FALSE; if (size > 4) + { + WLog_ERR(TAG, "exponent size %" PRIuz " exceeds limit of %" PRIu32, size, 4); return FALSE; + } if (!info->Modulus || (info->ModulusLength == 0)) + { + WLog_ERR(TAG, "invalid modulus=%p [%" PRIu32 "]", info->Modulus, info->ModulusLength); return FALSE; + } Stream_Read(s, &info->exponent[4 - size], size); crypto_reverse(info->Modulus, info->ModulusLength); crypto_reverse(info->exponent, 4); diff --git a/libfreerdp/crypto/certificate.c b/libfreerdp/crypto/certificate.c index ddfe776..896b605 100644 --- a/libfreerdp/crypto/certificate.c +++ b/libfreerdp/crypto/certificate.c @@ -301,8 +301,8 @@ static BOOL certificate_read_x509_certificate(const rdpCertBlob* cert, rdpCertIn size_t exponent_length = 0; int error = 0; - if (!cert || !info) - return FALSE; + WINPR_ASSERT(cert); + WINPR_ASSERT(info); cert_info_free(info); @@ -571,6 +571,9 @@ fail2: rc = TRUE; fail: + if (!rc) + WLog_ERR(TAG, "failed to update x509 from rdpCertInfo"); + #if !defined(OPENSSL_VERSION_MAJOR) || (OPENSSL_VERSION_MAJOR < 3) if (rsa) RSA_free(rsa); @@ -600,7 +603,7 @@ static BOOL certificate_process_server_public_key(rdpCertificate* cert, wStream* if (memcmp(magic, rsa_magic, sizeof(magic)) != 0) { - WLog_ERR(TAG, "magic error"); + WLog_ERR(TAG, "invalid RSA magic bytes"); return FALSE; } @@ -612,14 +615,33 @@ static BOOL certificate_process_server_public_key(rdpCertificate* cert, wStream* Stream_Read_UINT32(s, datalen); Stream_Read(s, info->exponent, 4); - if ((keylen <= 8) || (!Stream_CheckAndLogRequiredLength(TAG, s, keylen))) + if (keylen <= 8) + { + WLog_ERR(TAG, "Invalid RSA keylen=%" PRIu32 " <= 8", keylen); return FALSE; - + } + if (!Stream_CheckAndLogRequiredLength(TAG, s, keylen)) + return FALSE; + if (keylen != (bitlen / 8ull) + 8ull) + { + WLog_ERR(TAG, "Invalid RSA key bitlen %" PRIu32 ", expected %" PRIu32, bitlen, + (keylen - 8) * 8); + return FALSE; + } + if (datalen != (bitlen / 8ull) - 1ull) + { + WLog_ERR(TAG, "Invalid RSA key datalen %" PRIu32 ", expected %" PRIu32, datalen, + (bitlen / 8ull) - 1ull); + return FALSE; + } info->ModulusLength = keylen - 8; BYTE* tmp = realloc(info->Modulus, info->ModulusLength); if (!tmp) + { + WLog_ERR(TAG, "Failed to reallocate modulus of length %" PRIu32, info->ModulusLength); return FALSE; + } info->Modulus = tmp; Stream_Read(s, info->Modulus, info->ModulusLength); @@ -957,6 +979,7 @@ static BOOL certificate_read_server_x509_certificate_chain(rdpCertificate* cert, if (!res) { + WLog_ERR(TAG, "Failed to read x509 certificate"); return FALSE; } @@ -1592,6 +1615,8 @@ BOOL freerdp_certificate_publickey_encrypt(const rdpCertificate* cert, const BYT size_t outputSize = EVP_PKEY_size(pkey); output = malloc(outputSize); + if (output == NULL) + goto out; *pcbOutput = outputSize; if (EVP_PKEY_encrypt_init(ctx) != 1 || diff --git a/libfreerdp/crypto/certificate_data.c b/libfreerdp/crypto/certificate_data.c index a48beb4..04b5432 100644 --- a/libfreerdp/crypto/certificate_data.c +++ b/libfreerdp/crypto/certificate_data.c @@ -50,11 +50,21 @@ struct rdp_certificate_data char* cached_pem; }; +/* ensure our hostnames (and therefore filenames) always use the same capitalization. + * the user might have input random case, but we always need to have a sane + * baseline to compare against. */ +static char* ensure_lowercase(char* str, size_t length) +{ + const size_t len = strnlen(str, length); + for (size_t x = 0; x < len; x++) + str[x] = tolower(str[x]); + return str; +} static const char* freerdp_certificate_data_hash_(const char* hostname, UINT16 port, char* name, size_t length) { _snprintf(name, length, "%s_%" PRIu16 ".pem", hostname, port); - return name; + return ensure_lowercase(name, length); } static BOOL freerdp_certificate_data_load_cache(rdpCertificateData* data) @@ -107,8 +117,7 @@ static rdpCertificateData* freerdp_certificate_data_new_nocopy(const char* hostn certdata->hostname = _strdup(hostname); if (!certdata->hostname) goto fail; - for (size_t i = 0; i < strlen(hostname); i++) - certdata->hostname[i] = tolower(certdata->hostname[i]); + ensure_lowercase(certdata->hostname, strlen(certdata->hostname)); certdata->cert = xcert; if (!freerdp_certificate_data_load_cache(certdata)) @@ -176,43 +185,44 @@ void freerdp_certificate_data_free(rdpCertificateData* data) const char* freerdp_certificate_data_get_host(const rdpCertificateData* cert) { - WINPR_ASSERT(cert); + if (!cert) + return NULL; return cert->hostname; } UINT16 freerdp_certificate_data_get_port(const rdpCertificateData* cert) { - WINPR_ASSERT(cert); + if (!cert) + return 0; return cert->port; } const char* freerdp_certificate_data_get_pem(const rdpCertificateData* cert) { - WINPR_ASSERT(cert); - WINPR_ASSERT(cert->cached_pem); - + if (!cert) + return NULL; return cert->cached_pem; } const char* freerdp_certificate_data_get_subject(const rdpCertificateData* cert) { - WINPR_ASSERT(cert); - WINPR_ASSERT(cert->cached_subject); + if (!cert) + return NULL; return cert->cached_subject; } const char* freerdp_certificate_data_get_issuer(const rdpCertificateData* cert) { - WINPR_ASSERT(cert); - WINPR_ASSERT(cert->cached_issuer); + if (!cert) + return NULL; return cert->cached_issuer; } const char* freerdp_certificate_data_get_fingerprint(const rdpCertificateData* cert) { - WINPR_ASSERT(cert); - WINPR_ASSERT(cert->cached_fingerprint); + if (!cert) + return NULL; return cert->cached_fingerprint; } @@ -241,8 +251,8 @@ BOOL freerdp_certificate_data_equal(const rdpCertificateData* a, const rdpCertif const char* freerdp_certificate_data_get_hash(const rdpCertificateData* cert) { - WINPR_ASSERT(cert); - WINPR_ASSERT(cert->cached_hash); + if (!cert) + return NULL; return cert->cached_hash; } diff --git a/libfreerdp/crypto/privatekey.c b/libfreerdp/crypto/privatekey.c index 159157c..55379d4 100644 --- a/libfreerdp/crypto/privatekey.c +++ b/libfreerdp/crypto/privatekey.c @@ -482,13 +482,19 @@ char* freerdp_key_get_param(const rdpPrivateKey* key, enum FREERDP_KEY_PARAM par switch (param) { case FREERDP_KEY_PARAM_RSA_D: +#if OPENSSL_VERSION_NUMBER >= 0x10101007L cbn = RSA_get0_d(rsa); +#endif break; case FREERDP_KEY_PARAM_RSA_E: +#if OPENSSL_VERSION_NUMBER >= 0x10101007L cbn = RSA_get0_e(rsa); +#endif break; case FREERDP_KEY_PARAM_RSA_N: +#if OPENSSL_VERSION_NUMBER >= 0x10101007L cbn = RSA_get0_n(rsa); +#endif break; default: return NULL; diff --git a/libfreerdp/crypto/tls.c b/libfreerdp/crypto/tls.c index 371b81b..2d40038 100644 --- a/libfreerdp/crypto/tls.c +++ b/libfreerdp/crypto/tls.c @@ -985,6 +985,7 @@ static int pollAndHandshake(rdpTls* tls) case WAIT_OBJECT_0: break; case WAIT_TIMEOUT: + case WAIT_IO_COMPLETION: continue; default: WLog_ERR(TAG, "error during WaitForSingleObject(): 0x%08" PRIX32 "", status); @@ -1107,7 +1108,7 @@ TlsHandshakeResult freerdp_tls_accept_ex(rdpTls* tls, BIO* underlying, rdpSettin * Disable SSL client site renegotiation. */ -#if (OPENSSL_VERSION_NUMBER >= 0x10100000L) && (OPENSSL_VERSION_NUMBER < 0x30000000L) && \ +#if (OPENSSL_VERSION_NUMBER >= 0x10101000L) && (OPENSSL_VERSION_NUMBER < 0x30000000L) && \ !defined(LIBRESSL_VERSION_NUMBER) options |= SSL_OP_NO_RENEGOTIATION; #endif |