summaryrefslogtreecommitdiffstats
path: root/libfreerdp/crypto
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-05-04 01:25:12 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-05-04 01:25:12 +0000
commit827a4c3faa27e0c186452585b15094eee1119085 (patch)
treee6a08b0c767863d66f7d4a9de80db5edc7db29be /libfreerdp/crypto
parentReleasing progress-linux version 3.3.0+dfsg1-1~progress7.99u1. (diff)
downloadfreerdp3-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.c12
-rw-r--r--libfreerdp/crypto/certificate.c35
-rw-r--r--libfreerdp/crypto/certificate_data.c42
-rw-r--r--libfreerdp/crypto/privatekey.c6
-rw-r--r--libfreerdp/crypto/tls.c3
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