From cbd310df52ad310a146265c21560d13c4a5fcc9c Mon Sep 17 00:00:00 2001 From: fifthdegree Date: Sun, 23 Oct 2022 14:51:40 -0400 Subject: [PATCH] Check smartcard certificates for correct EKU To be used for login, smartcard certificates must have the Microsoft Smart Card Logon EKU --- include/freerdp/crypto/crypto.h | 1 + libfreerdp/core/smartcardlogon.c | 7 +++++++ libfreerdp/crypto/crypto.c | 24 ++++++++++++++++++++++++ 3 files changed, 32 insertions(+) diff --git a/include/freerdp/crypto/crypto.h b/include/freerdp/crypto/crypto.h index fceb6a26a..1be0149ae 100644 --- a/include/freerdp/crypto/crypto.h +++ b/include/freerdp/crypto/crypto.h @@ -69,6 +69,7 @@ extern "C" FREERDP_API char* crypto_cert_get_upn(X509* x509); FREERDP_API void crypto_cert_dns_names_free(int count, int* lengths, char** dns_names); FREERDP_API char* crypto_cert_issuer(X509* xcert); + FREERDP_API BOOL crypto_check_eku(X509* scert, int nid); FREERDP_API void crypto_cert_print_info(X509* xcert); FREERDP_API void crypto_cert_free(CryptoCert cert); diff --git a/libfreerdp/core/smartcardlogon.c b/libfreerdp/core/smartcardlogon.c index c0707c47e..762399319 100644 --- a/libfreerdp/core/smartcardlogon.c +++ b/libfreerdp/core/smartcardlogon.c @@ -339,6 +339,13 @@ static BOOL list_provider_keys(const rdpSettings* settings, NCRYPT_PROV_HANDLE p goto endofloop; } + if (!crypto_check_eku(cert->certificate->px509, NID_ms_smartcard_login)) + { + WLog_DBG(TAG, "discarding certificate without Smartcard Login EKU for key %s", + cert->keyName); + goto endofloop; + } + if (!treat_sc_cert(cert)) { WLog_DBG(TAG, "error treating cert"); diff --git a/libfreerdp/crypto/crypto.c b/libfreerdp/crypto/crypto.c index 4a099c431..9f96f6b0a 100644 --- a/libfreerdp/crypto/crypto.c +++ b/libfreerdp/crypto/crypto.c @@ -868,6 +868,30 @@ char* crypto_cert_issuer(X509* xcert) return issuer; } +BOOL crypto_check_eku(X509* xcert, int nid) +{ + BOOL ret = FALSE; + STACK_OF(ASN1_OBJECT) * oid_stack; + ASN1_OBJECT* oid; + + if (!xcert) + return FALSE; + + oid = OBJ_nid2obj(nid); + if (!oid) + return FALSE; + + oid_stack = X509_get_ext_d2i(xcert, NID_ext_key_usage, NULL, NULL); + if (!oid_stack) + return FALSE; + + if (sk_ASN1_OBJECT_find(oid_stack, oid) >= 0) + ret = TRUE; + + sk_ASN1_OBJECT_pop_free(oid_stack, ASN1_OBJECT_free); + return ret; +} + static int verify_cb(int ok, X509_STORE_CTX* csc) { if (ok != 1)