Merge pull request #10489 from akallabeth/verify-cert-improve

Verify cert improve
This commit is contained in:
akallabeth 2024-08-20 13:13:57 +02:00 committed by GitHub
commit 1265498b1f
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
12 changed files with 141 additions and 51 deletions

View File

@ -329,6 +329,30 @@ static DWORD sdl_show_ceritifcate_dialog(rdpContext* context, const char* title,
return static_cast<DWORD>(event.user.code);
}
static char* sdl_pem_cert(const char* pem)
{
rdpCertificate* cert = freerdp_certificate_new_from_pem(pem);
if (!cert)
return NULL;
char* fp = freerdp_certificate_get_fingerprint(cert);
char* start = freerdp_certificate_get_validity(cert, TRUE);
char* end = freerdp_certificate_get_validity(cert, FALSE);
freerdp_certificate_free(cert);
char* str = NULL;
size_t slen = 0;
winpr_asprintf(&str, &slen,
"\tValid from: %s\n"
"\tValid to: %s\n"
"\tThumbprint: %s\n",
start, end, fp);
free(fp);
free(start);
free(end);
return str;
}
DWORD sdl_verify_changed_certificate_ex(freerdp* instance, const char* host, UINT16 port,
const char* common_name, const char* subject,
const char* issuer, const char* new_fingerprint,
@ -348,13 +372,7 @@ DWORD sdl_verify_changed_certificate_ex(freerdp* instance, const char* host, UIN
char* new_fp_str = nullptr;
size_t len = 0;
if (flags & VERIFY_CERT_FLAG_FP_IS_PEM)
{
winpr_asprintf(&new_fp_str, &len,
"----------- Certificate --------------\n"
"%s\n"
"--------------------------------------\n",
new_fingerprint);
}
new_fp_str = sdl_pem_cert(new_fingerprint);
else
winpr_asprintf(&new_fp_str, &len, "Thumbprint: %s\n", new_fingerprint);
@ -364,13 +382,7 @@ DWORD sdl_verify_changed_certificate_ex(freerdp* instance, const char* host, UIN
char* old_fp_str = nullptr;
size_t olen = 0;
if (flags & VERIFY_CERT_FLAG_FP_IS_PEM)
{
winpr_asprintf(&old_fp_str, &olen,
"----------- Certificate --------------\n"
"%s\n"
"--------------------------------------\n",
old_fingerprint);
}
old_fp_str = sdl_pem_cert(old_fingerprint);
else
winpr_asprintf(&old_fp_str, &olen, "Thumbprint: %s\n", old_fingerprint);
@ -431,13 +443,7 @@ DWORD sdl_verify_certificate_ex(freerdp* instance, const char* host, UINT16 port
char* fp_str = nullptr;
size_t len = 0;
if (flags & VERIFY_CERT_FLAG_FP_IS_PEM)
{
winpr_asprintf(&fp_str, &len,
"----------- Certificate --------------\n"
"%s\n"
"--------------------------------------\n",
fingerprint);
}
fp_str = sdl_pem_cert(fingerprint);
else
winpr_asprintf(&fp_str, &len, "Thumbprint: %s\n", fingerprint);

View File

@ -573,6 +573,9 @@ static BOOL sdl_pre_connect(freerdp* instance)
auto settings = instance->context->settings;
WINPR_ASSERT(settings);
if (!freerdp_settings_set_bool(settings, FreeRDP_CertificateCallbackPreferPEM, TRUE))
return FALSE;
/* Optional OS identifier sent to server */
if (!freerdp_settings_set_uint32(settings, FreeRDP_OsMajorType, OSMAJORTYPE_UNIX))
return FALSE;

View File

@ -327,6 +327,30 @@ static DWORD sdl_show_ceritifcate_dialog(rdpContext* context, const char* title,
return static_cast<DWORD>(event.user.code);
}
static char* sdl_pem_cert(const char* pem)
{
rdpCertificate* cert = freerdp_certificate_new_from_pem(pem);
if (!cert)
return NULL;
char* fp = freerdp_certificate_get_fingerprint(cert);
char* start = freerdp_certificate_get_validity(cert, TRUE);
char* end = freerdp_certificate_get_validity(cert, FALSE);
freerdp_certificate_free(cert);
char* str = NULL;
size_t slen = 0;
winpr_asprintf(&str, &slen,
"\tValid from: %s\n"
"\tValid to: %s\n"
"\tThumbprint: %s\n",
start, end, fp);
free(fp);
free(start);
free(end);
return str;
}
DWORD sdl_verify_changed_certificate_ex(freerdp* instance, const char* host, UINT16 port,
const char* common_name, const char* subject,
const char* issuer, const char* new_fingerprint,
@ -346,13 +370,7 @@ DWORD sdl_verify_changed_certificate_ex(freerdp* instance, const char* host, UIN
char* new_fp_str = nullptr;
size_t len = 0;
if (flags & VERIFY_CERT_FLAG_FP_IS_PEM)
{
winpr_asprintf(&new_fp_str, &len,
"----------- Certificate --------------\n"
"%s\n"
"--------------------------------------\n",
new_fingerprint);
}
new_fp_str = sdl_pem_cert(new_fingerprint);
else
winpr_asprintf(&new_fp_str, &len, "Thumbprint: %s\n", new_fingerprint);
@ -362,13 +380,7 @@ DWORD sdl_verify_changed_certificate_ex(freerdp* instance, const char* host, UIN
char* old_fp_str = nullptr;
size_t olen = 0;
if (flags & VERIFY_CERT_FLAG_FP_IS_PEM)
{
winpr_asprintf(&old_fp_str, &olen,
"----------- Certificate --------------\n"
"%s\n"
"--------------------------------------\n",
old_fingerprint);
}
old_fp_str = sdl_pem_cert(old_fingerprint);
else
winpr_asprintf(&old_fp_str, &olen, "Thumbprint: %s\n", old_fingerprint);
@ -429,13 +441,7 @@ DWORD sdl_verify_certificate_ex(freerdp* instance, const char* host, UINT16 port
char* fp_str = nullptr;
size_t len = 0;
if (flags & VERIFY_CERT_FLAG_FP_IS_PEM)
{
winpr_asprintf(&fp_str, &len,
"----------- Certificate --------------\n"
"%s\n"
"--------------------------------------\n",
fingerprint);
}
fp_str = sdl_pem_cert(fingerprint);
else
winpr_asprintf(&fp_str, &len, "Thumbprint: %s\n", fingerprint);

View File

@ -571,6 +571,9 @@ static BOOL sdl_pre_connect(freerdp* instance)
auto settings = instance->context->settings;
WINPR_ASSERT(settings);
if (!freerdp_settings_set_bool(settings, FreeRDP_CertificateCallbackPreferPEM, TRUE))
return FALSE;
/* Optional OS identifier sent to server */
if (!freerdp_settings_set_uint32(settings, FreeRDP_OsMajorType, OSMAJORTYPE_UNIX))
return FALSE;

View File

@ -147,6 +147,11 @@ static BOOL tf_pre_connect(freerdp* instance)
settings = instance->context->settings;
WINPR_ASSERT(settings);
/* If the callbacks provide the PEM all certificate options can be extracted, otherwise
* only the certificate fingerprint is available. */
if (!freerdp_settings_set_bool(settings, FreeRDP_CertificateCallbackPreferPEM, TRUE))
return FALSE;
/* Optional OS identifier sent to server */
if (!freerdp_settings_set_uint32(settings, FreeRDP_OsMajorType, OSMAJORTYPE_UNIX))
return FALSE;

View File

@ -191,6 +191,9 @@ static BOOL wl_pre_connect(freerdp* instance)
settings = instance->context->settings;
WINPR_ASSERT(settings);
if (!freerdp_settings_set_bool(settings, FreeRDP_CertificateCallbackPreferPEM, TRUE))
return FALSE;
if (!freerdp_settings_set_uint32(settings, FreeRDP_OsMajorType, OSMAJORTYPE_UNIX))
return FALSE;
if (!freerdp_settings_set_uint32(settings, FreeRDP_OsMinorType, OSMINORTYPE_NATIVE_WAYLAND))

View File

@ -1112,6 +1112,9 @@ static BOOL xf_pre_connect(freerdp* instance)
settings = context->settings;
WINPR_ASSERT(settings);
if (!freerdp_settings_set_bool(settings, FreeRDP_CertificateCallbackPreferPEM, TRUE))
return FALSE;
if (!freerdp_settings_get_bool(settings, FreeRDP_AuthenticationOnly))
{
if (!xf_setup_x11(xfc))

View File

@ -708,6 +708,30 @@ DWORD client_cli_verify_certificate(freerdp* instance, const char* common_name,
}
#endif
static char* client_cli_pem_cert(const char* pem)
{
rdpCertificate* cert = freerdp_certificate_new_from_pem(pem);
if (!cert)
return NULL;
char* fp = freerdp_certificate_get_fingerprint(cert);
char* start = freerdp_certificate_get_validity(cert, TRUE);
char* end = freerdp_certificate_get_validity(cert, FALSE);
freerdp_certificate_free(cert);
char* str = NULL;
size_t slen = 0;
winpr_asprintf(&str, &slen,
"\tValid from: %s\n"
"\tValid to: %s\n"
"\tThumbprint: %s\n",
start, end, fp);
free(fp);
free(start);
free(end);
return str;
}
/** Callback set in the rdp_freerdp structure, and used to make a certificate validation
* when the connection requires it.
* This function will actually be called by tls_verify_certificate().
@ -748,9 +772,9 @@ DWORD client_cli_verify_certificate_ex(freerdp* instance, const char* host, UINT
*/
if (flags & VERIFY_CERT_FLAG_FP_IS_PEM)
{
printf("\t----------- Certificate --------------\n");
printf("%s\n", fingerprint);
printf("\t--------------------------------------\n");
char* str = client_cli_pem_cert(fingerprint);
printf("%s", str);
free(str);
}
else
printf("\tThumbprint: %s\n", fingerprint);
@ -854,9 +878,9 @@ DWORD client_cli_verify_changed_certificate_ex(freerdp* instance, const char* ho
*/
if (flags & VERIFY_CERT_FLAG_FP_IS_PEM)
{
printf("\t----------- Certificate --------------\n");
printf("%s\n", fingerprint);
printf("\t--------------------------------------\n");
char* str = client_cli_pem_cert(fingerprint);
printf("%s", str);
free(str);
}
else
printf("\tThumbprint: %s\n", fingerprint);
@ -869,9 +893,9 @@ DWORD client_cli_verify_changed_certificate_ex(freerdp* instance, const char* ho
*/
if (flags & VERIFY_CERT_FLAG_FP_IS_PEM)
{
printf("\t----------- Certificate --------------\n");
printf("%s\n", old_fingerprint);
printf("\t--------------------------------------\n");
char* str = client_cli_pem_cert(old_fingerprint);
printf("%s", str);
free(str);
}
else
printf("\tThumbprint: %s\n", old_fingerprint);

View File

@ -76,6 +76,9 @@ extern "C"
FREERDP_API char* freerdp_certificate_get_upn(const rdpCertificate* certificate);
FREERDP_API char* freerdp_certificate_get_email(const rdpCertificate* certificate);
FREERDP_API char* freerdp_certificate_get_validity(const rdpCertificate* certificate,
BOOL startDate);
FREERDP_API WINPR_MD_TYPE freerdp_certificate_get_signature_alg(const rdpCertificate* cert);
FREERDP_API char* freerdp_certificate_get_common_name(const rdpCertificate* cert,

View File

@ -1507,6 +1507,12 @@ char* freerdp_certificate_get_email(const rdpCertificate* cert)
return x509_utils_get_email(cert->x509);
}
char* freerdp_certificate_get_validity(const rdpCertificate* cert, BOOL startDate)
{
WINPR_ASSERT(cert);
return x509_utils_get_date(cert->x509, startDate);
}
BOOL freerdp_certificate_check_eku(const rdpCertificate* cert, int nid)
{
WINPR_ASSERT(cert);

View File

@ -463,6 +463,33 @@ char* x509_utils_get_upn(const X509* x509)
return result;
}
char* x509_utils_get_date(const X509* x509, BOOL startDate)
{
WINPR_ASSERT(x509);
const ASN1_TIME* date = startDate ? X509_get0_notBefore(x509) : X509_get0_notAfter(x509);
if (!date)
return NULL;
BIO* bmem = BIO_new(BIO_s_mem());
if (!bmem)
return NULL;
char* str = NULL;
if (ASN1_TIME_print(bmem, date))
{
BUF_MEM* bptr;
BIO_get_mem_ptr(bmem, &bptr);
str = strndup(bptr->data, bptr->length);
}
else
{ // Log error
}
BIO_free_all(bmem);
return str;
}
void x509_utils_dns_names_free(size_t count, size_t* lengths, char** dns_names)
{
free(lengths);

View File

@ -44,6 +44,7 @@ extern "C"
FREERDP_LOCAL char* x509_utils_get_issuer(const X509* xcert);
FREERDP_LOCAL char* x509_utils_get_email(const X509* x509);
FREERDP_LOCAL char* x509_utils_get_upn(const X509* x509);
FREERDP_LOCAL char* x509_utils_get_date(const X509* x509, BOOL startDate);
FREERDP_LOCAL char* x509_utils_get_common_name(const X509* xcert, size_t* plength);
FREERDP_LOCAL char** x509_utils_get_dns_names(const X509* xcert, size_t* count,