25#include <freerdp/config.h>
31#include <winpr/assert.h>
32#include <winpr/wtypes.h>
34#include <winpr/file.h>
35#include <winpr/print.h>
36#include <winpr/crypto.h>
38#include <freerdp/crypto/certificate.h>
40#include <openssl/err.h>
41#include <openssl/pem.h>
42#include <openssl/rsa.h>
43#include <openssl/bn.h>
45#if defined(OPENSSL_VERSION_MAJOR) && (OPENSSL_VERSION_MAJOR >= 3)
46#include <openssl/core_names.h>
47#include <openssl/param_build.h>
48#include <openssl/evp.h>
49#include <openssl/x509.h>
52#include "certificate.h"
53#include "cert_common.h"
56#include "x509_utils.h"
57#include "privatekey.h"
58#include "opensslcompat.h"
60#define TAG FREERDP_TAG("core")
62#ifdef WITH_DEBUG_CERTIFICATE
63#define CERTIFICATE_TAG FREERDP_TAG("core.certificate")
64#define DEBUG_CERTIFICATE(...) WLog_DBG(TAG, __VA_ARGS__)
66#define DEBUG_CERTIFICATE(...) \
72#define TSSK_KEY_LENGTH 64
79typedef struct rdp_CertBlob rdpCertBlob;
81struct rdp_X509CertChain
86typedef struct rdp_X509CertChain rdpX509CertChain;
91 STACK_OF(X509) * chain;
93 rdpCertInfo cert_info;
94 rdpX509CertChain x509_cert_chain;
185static const char rsa_magic[4] =
"RSA1";
187static const char* certificate_read_errors[] = {
"Certificate tag",
189 "Explicit Contextual Tag [0]",
191 "CertificateSerialNumber",
192 "AlgorithmIdentifier",
196 "SubjectPublicKeyInfo Tag",
197 "subjectPublicKeyInfo::AlgorithmIdentifier",
198 "subjectPublicKeyInfo::subjectPublicKey",
204 "publicExponent length",
207static const BYTE initial_signature[] = {
208 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
209 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
210 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
211 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x01
214#if defined(CERT_VALIDATE_RSA)
215static const BYTE tssk_exponent[] = { 0x5b, 0x7b, 0x88, 0xc0 };
218static void certificate_free_int(rdpCertificate* certificate);
219static BOOL cert_clone_int(rdpCertificate* dst,
const rdpCertificate* src);
225static BOOL cert_blob_copy(rdpCertBlob* dst,
const rdpCertBlob* src);
226static void cert_blob_free(rdpCertBlob* blob);
227static BOOL cert_blob_write(
const rdpCertBlob* blob,
wStream* s);
228static BOOL cert_blob_read(rdpCertBlob* blob,
wStream* s);
230BOOL cert_blob_read(rdpCertBlob* blob,
wStream* s)
232 UINT32 certLength = 0;
234 cert_blob_free(blob);
236 if (!Stream_CheckAndLogRequiredLength(TAG, s, 4))
239 Stream_Read_UINT32(s, certLength);
241 if (!Stream_CheckAndLogRequiredLength(TAG, s, certLength))
244 DEBUG_CERTIFICATE(
"X.509 Certificate length:%" PRIu32
"", certLength);
245 blob->data = (BYTE*)malloc(certLength);
250 Stream_Read(s, blob->data, certLength);
251 blob->length = certLength;
256 cert_blob_free(blob);
260BOOL cert_blob_write(
const rdpCertBlob* blob,
wStream* s)
264 if (!Stream_EnsureRemainingCapacity(s, 4 + blob->length))
267 Stream_Write_UINT32(s, blob->length);
268 Stream_Write(s, blob->data, blob->length);
272void cert_blob_free(rdpCertBlob* blob)
285static BOOL is_rsa_key(
const X509* x509)
287 EVP_PKEY* evp = X509_get0_pubkey(x509);
291 return (EVP_PKEY_id(evp) == EVP_PKEY_RSA);
294static BOOL certificate_read_x509_certificate(
const rdpCertBlob* cert, rdpCertInfo* info)
301 size_t modulus_length = 0;
302 size_t exponent_length = 0;
308 cert_info_free(info);
310 s = Stream_StaticConstInit(&sbuffer, cert->data, cert->length);
315 if (!ber_read_sequence_tag(s, &length))
320 if (!ber_read_sequence_tag(s, &length))
325 if (!ber_read_contextual_tag(s, 0, &length, TRUE))
330 if (!ber_read_integer(s, &version))
337 if (!ber_read_integer(s, NULL))
343 if (!ber_read_sequence_tag(s, &length) ||
344 !Stream_SafeSeek(s, length))
350 if (!ber_read_sequence_tag(s, &length) || !Stream_SafeSeek(s, length))
356 if (!ber_read_sequence_tag(s, &length) || !Stream_SafeSeek(s, length))
362 if (!ber_read_sequence_tag(s, &length) || !Stream_SafeSeek(s, length))
368 if (!ber_read_sequence_tag(s, &length))
374 if (!ber_read_sequence_tag(s, &length) ||
375 !Stream_SafeSeek(s, length))
381 if (!ber_read_bit_string(s, &length, &padding))
387 if (!ber_read_sequence_tag(s, &length))
392 if (!ber_read_integer_length(s, &modulus_length))
400 if (!Stream_CheckAndLogRequiredLength(TAG, s, 1))
403 Stream_Peek_UINT8(s, padding);
407 if (!Stream_SafeSeek(s, 1))
412 }
while (padding == 0);
416 if (!cert_info_read_modulus(info, modulus_length, s))
421 if (!ber_read_integer_length(s, &exponent_length))
426 if (!cert_info_read_exponent(info, exponent_length, s))
430 WLog_ERR(TAG,
"error reading when reading certificate: part=%s error=%d",
431 certificate_read_errors[error], error);
432 cert_info_free(info);
442static rdpX509CertChain certificate_new_x509_certificate_chain(UINT32 count)
444 rdpX509CertChain x509_cert_chain = { 0 };
446 x509_cert_chain.array = (rdpCertBlob*)calloc(count,
sizeof(rdpCertBlob));
448 if (x509_cert_chain.array)
449 x509_cert_chain.count = count;
451 return x509_cert_chain;
459static void certificate_free_x509_certificate_chain(rdpX509CertChain* x509_cert_chain)
461 if (!x509_cert_chain)
464 if (x509_cert_chain->array)
466 for (UINT32 i = 0; i < x509_cert_chain->count; i++)
468 rdpCertBlob* element = &x509_cert_chain->array[i];
469 cert_blob_free(element);
473 free(x509_cert_chain->array);
474 x509_cert_chain->array = NULL;
475 x509_cert_chain->count = 0;
478#if defined(OPENSSL_VERSION_MAJOR) && (OPENSSL_VERSION_MAJOR >= 3)
479static OSSL_PARAM* get_params(
const BIGNUM* e,
const BIGNUM* mod)
484 OSSL_PARAM* parameters = NULL;
485 OSSL_PARAM_BLD* param = OSSL_PARAM_BLD_new();
488 WLog_ERR(TAG,
"OSSL_PARAM_BLD_new() failed");
492 const int bits = BN_num_bits(e);
493 if ((bits < 0) || (bits > 32))
495 WLog_ERR(TAG,
"BN_num_bits(e) out of range: 0 <= %d <= 32", bits);
500 const int ne = BN_bn2nativepad(e, (BYTE*)&ie,
sizeof(ie));
501 if ((ne < 0) || (ne > 4))
503 WLog_ERR(TAG,
"BN_bn2nativepad(e, (BYTE*)&ie, sizeof(ie)) out of range: 0<= %d <= 4", ne);
506 if (OSSL_PARAM_BLD_push_BN(param, OSSL_PKEY_PARAM_RSA_N, mod) != 1)
508 WLog_ERR(TAG,
"OSSL_PARAM_BLD_push_BN(param, OSSL_PKEY_PARAM_RSA_N, mod) failed");
511 if (OSSL_PARAM_BLD_push_uint(param, OSSL_PKEY_PARAM_RSA_E, ie) != 1)
513 WLog_ERR(TAG,
"OSSL_PARAM_BLD_push_uint(param, OSSL_PKEY_PARAM_RSA_E, ie) failed");
517 parameters = OSSL_PARAM_BLD_to_param(param);
519 WLog_ERR(TAG,
"OSSL_PARAM_BLD_to_param(param) failed");
521 OSSL_PARAM_BLD_free(param);
527static BOOL update_x509_from_info(rdpCertificate* cert)
533 X509_free(cert->x509);
536 rdpCertInfo* info = &cert->cert_info;
538 BIGNUM* e = BN_new();
539 BIGNUM* mod = BN_new();
540#if !defined(OPENSSL_VERSION_MAJOR) || (OPENSSL_VERSION_MAJOR < 3)
541 RSA* rsa = RSA_new();
544 WLog_ERR(TAG,
"RSA_new() failed");
551 WLog_ERR(TAG,
"failure: mod=%p, e=%p", mod, e);
555 WINPR_ASSERT(info->ModulusLength <= INT_MAX);
556 if (!BN_bin2bn(info->Modulus, (
int)info->ModulusLength, mod))
558 WLog_ERR(TAG,
"BN_bin2bn(info->Modulus, (int)info->ModulusLength, mod) failed");
562 if (!BN_bin2bn(info->exponent, (
int)
sizeof(info->exponent), e))
564 WLog_ERR(TAG,
"BN_bin2bn(info->exponent, (int)sizeof(info->exponent), e) failed");
568#if !defined(OPENSSL_VERSION_MAJOR) || (OPENSSL_VERSION_MAJOR < 3)
569 const int rec = RSA_set0_key(rsa, mod, e, NULL);
572 WLog_ERR(TAG,
"RSA_set0_key(rsa, mod, e, NULL) failed");
576 cert->x509 = x509_from_rsa(rsa);
578 EVP_PKEY* pkey = NULL;
579 EVP_PKEY_CTX* ctx = EVP_PKEY_CTX_new_id(EVP_PKEY_RSA, NULL);
582 WLog_ERR(TAG,
"EVP_PKEY_CTX_new_id(EVP_PKEY_RSA, NULL) failed");
585 const int xx = EVP_PKEY_fromdata_init(ctx);
588 WLog_ERR(TAG,
"EVP_PKEY_fromdata_init(ctx) failed");
592 OSSL_PARAM* parameters = get_params(e, mod);
596 const int rc2 = EVP_PKEY_fromdata(ctx, &pkey, EVP_PKEY_PUBLIC_KEY, parameters);
597 OSSL_PARAM_free(parameters);
600 WLog_ERR(TAG,
"EVP_PKEY_fromdata(ctx, &pkey, EVP_PKEY_PUBLIC_KEY, parameters) failed");
604 cert->x509 = X509_new();
607 WLog_ERR(TAG,
"X509_new() failed");
611 if (X509_set_pubkey(cert->x509, pkey) != 1)
613 WLog_ERR(TAG,
"X509_set_pubkey(cert->x509, pkey) failed");
614 X509_free(cert->x509);
619 EVP_PKEY_CTX_free(ctx);
628 WLog_ERR(TAG,
"failed to update x509 from rdpCertInfo");
630#if !defined(OPENSSL_VERSION_MAJOR) || (OPENSSL_VERSION_MAJOR < 3)
642static BOOL certificate_process_server_public_key(rdpCertificate* cert,
wStream* s,
643 WINPR_ATTR_UNUSED UINT32 length)
645 char magic[
sizeof(rsa_magic)] = { 0 };
653 if (!Stream_CheckAndLogRequiredLength(TAG, s, 20))
656 Stream_Read(s, magic,
sizeof(magic));
658 if (memcmp(magic, rsa_magic,
sizeof(magic)) != 0)
660 WLog_ERR(TAG,
"invalid RSA magic bytes");
664 rdpCertInfo* info = &cert->cert_info;
665 cert_info_free(info);
667 Stream_Read_UINT32(s, keylen);
668 Stream_Read_UINT32(s, bitlen);
669 Stream_Read_UINT32(s, datalen);
670 Stream_Read(s, info->exponent, 4);
674 WLog_ERR(TAG,
"Invalid RSA keylen=%" PRIu32
" <= 8", keylen);
677 if (!Stream_CheckAndLogRequiredLength(TAG, s, keylen))
679 if (keylen != (bitlen / 8ull) + 8ull)
681 WLog_ERR(TAG,
"Invalid RSA key bitlen %" PRIu32
", expected %" PRIu32, bitlen,
685 if (datalen != (bitlen / 8ull) - 1ull)
687 WLog_ERR(TAG,
"Invalid RSA key datalen %" PRIu32
", expected %" PRIu32, datalen,
688 (bitlen / 8ull) - 1ull);
691 info->ModulusLength = keylen - 8;
692 BYTE* tmp = realloc(info->Modulus, info->ModulusLength);
696 WLog_ERR(TAG,
"Failed to reallocate modulus of length %" PRIu32, info->ModulusLength);
701 Stream_Read(s, info->Modulus, info->ModulusLength);
703 return update_x509_from_info(cert);
706static BOOL certificate_process_server_public_signature(rdpCertificate* certificate,
707 const BYTE* sigdata,
size_t sigdatalen,
710 WINPR_ASSERT(certificate);
711#if defined(CERT_VALIDATE_RSA)
712 BYTE sig[TSSK_KEY_LENGTH];
714 BYTE encsig[TSSK_KEY_LENGTH + 8];
715#if defined(CERT_VALIDATE_MD5) && defined(CERT_VALIDATE_RSA)
716 BYTE md5hash[WINPR_MD5_DIGEST_LENGTH];
718#if !defined(CERT_VALIDATE_MD5) || !defined(CERT_VALIDATE_RSA)
729#if defined(CERT_VALIDATE_MD5)
731 if (!winpr_Digest(WINPR_MD_MD5, sigdata, sigdatalen, md5hash,
sizeof(md5hash)))
735 Stream_Read(s, encsig, siglen);
741#if defined(CERT_VALIDATE_PADDING)
744 for (
size_t i =
sizeof(encsig) - 8; i <
sizeof(encsig); i++)
749 WLog_ERR(TAG,
"invalid signature");
754#if defined(CERT_VALIDATE_RSA)
756 if (crypto_rsa_public_decrypt(encsig, siglen - 8, TSSK_KEY_LENGTH, tssk_modulus, tssk_exponent,
759 WLog_ERR(TAG,
"invalid RSA decrypt");
765#if defined(CERT_VALIDATE_MD5)
767 if (memcmp(md5hash, sig,
sizeof(md5hash)) != 0)
769 WLog_ERR(TAG,
"invalid signature");
782 for (
size_t i = 17; i < 62; i++)
785 if (sig[16] != 0x00 || sum != 0xFF * (62 - 17) || sig[62] != 0x01)
787 WLog_ERR(TAG,
"invalid signature");
795static BOOL certificate_read_server_proprietary_certificate(rdpCertificate* certificate,
wStream* s)
797 UINT32 dwSigAlgId = 0;
798 UINT32 dwKeyAlgId = 0;
799 UINT16 wPublicKeyBlobType = 0;
800 UINT16 wPublicKeyBlobLen = 0;
801 UINT16 wSignatureBlobType = 0;
802 UINT16 wSignatureBlobLen = 0;
803 size_t sigdatalen = 0;
805 WINPR_ASSERT(certificate);
806 if (!Stream_CheckAndLogRequiredLength(TAG, s, 12))
810 const BYTE* sigdata = Stream_PointerAs(s,
const BYTE) - 4;
811 Stream_Read_UINT32(s, dwSigAlgId);
812 Stream_Read_UINT32(s, dwKeyAlgId);
814 if (!((dwSigAlgId == SIGNATURE_ALG_RSA) && (dwKeyAlgId == KEY_EXCHANGE_ALG_RSA)))
817 "unsupported signature or key algorithm, dwSigAlgId=%" PRIu32
818 " dwKeyAlgId=%" PRIu32
"",
819 dwSigAlgId, dwKeyAlgId);
823 Stream_Read_UINT16(s, wPublicKeyBlobType);
825 if (wPublicKeyBlobType != BB_RSA_KEY_BLOB)
827 WLog_ERR(TAG,
"unsupported public key blob type %" PRIu16
"", wPublicKeyBlobType);
831 Stream_Read_UINT16(s, wPublicKeyBlobLen);
833 if (!Stream_CheckAndLogRequiredLength(TAG, s, wPublicKeyBlobLen))
836 if (!certificate_process_server_public_key(certificate, s, wPublicKeyBlobLen))
839 if (!Stream_CheckAndLogRequiredLength(TAG, s, 4))
842 sigdatalen = WINPR_ASSERTING_INT_CAST(
size_t, Stream_PointerAs(s,
const BYTE) - sigdata);
843 Stream_Read_UINT16(s, wSignatureBlobType);
845 if (wSignatureBlobType != BB_RSA_SIGNATURE_BLOB)
847 WLog_ERR(TAG,
"unsupported blob signature %" PRIu16
"", wSignatureBlobType);
851 Stream_Read_UINT16(s, wSignatureBlobLen);
853 if (!Stream_CheckAndLogRequiredLength(TAG, s, wSignatureBlobLen))
856 if (wSignatureBlobLen != 72)
858 WLog_ERR(TAG,
"invalid signature length (got %" PRIu16
", expected 72)", wSignatureBlobLen);
862 if (!certificate_process_server_public_signature(certificate, sigdata, sigdatalen, s,
865 WLog_ERR(TAG,
"unable to parse server public signature");
872static BOOL cert_write_rsa_public_key(
wStream* s,
const rdpCertificate* cert)
875 WINPR_ASSERT(freerdp_certificate_is_rsa(cert));
877 const rdpCertInfo* info = &cert->cert_info;
879 const UINT32 keyLen = info->ModulusLength + 8;
880 const UINT32 bitLen = info->ModulusLength * 8;
881 const UINT32 dataLen = (bitLen / 8) - 1;
882 const size_t pubExpLen =
sizeof(info->exponent);
883 const BYTE* pubExp = info->exponent;
884 const BYTE* modulus = info->Modulus;
886 const size_t wPublicKeyBlobLen = 16 + pubExpLen + keyLen;
887 WINPR_ASSERT(wPublicKeyBlobLen <= UINT16_MAX);
888 if (!Stream_EnsureRemainingCapacity(s, 2 + wPublicKeyBlobLen))
890 Stream_Write_UINT16(s, (UINT16)wPublicKeyBlobLen);
891 Stream_Write(s, rsa_magic,
sizeof(rsa_magic));
892 Stream_Write_UINT32(s, keyLen);
893 Stream_Write_UINT32(s, bitLen);
894 Stream_Write_UINT32(s, dataLen);
895 Stream_Write(s, pubExp, pubExpLen);
896 Stream_Write(s, modulus, info->ModulusLength);
901static BOOL cert_write_rsa_signature(
wStream* s,
const void* sigData,
size_t sigDataLen)
903 BYTE encryptedSignature[TSSK_KEY_LENGTH] = { 0 };
904 BYTE signature[
sizeof(initial_signature)] = { 0 };
906 memcpy(signature, initial_signature,
sizeof(initial_signature));
907 if (!winpr_Digest(WINPR_MD_MD5, sigData, sigDataLen, signature,
sizeof(signature)))
910 crypto_rsa_private_encrypt(signature,
sizeof(signature), priv_key_tssk, encryptedSignature,
911 sizeof(encryptedSignature));
913 if (!Stream_EnsureRemainingCapacity(s, 2 *
sizeof(UINT16) +
sizeof(encryptedSignature) + 8))
915 Stream_Write_UINT16(s, BB_RSA_SIGNATURE_BLOB);
916 Stream_Write_UINT16(s,
sizeof(encryptedSignature) + 8);
917 Stream_Write(s, encryptedSignature,
sizeof(encryptedSignature));
923static BOOL cert_write_server_certificate_v1(
wStream* s,
const rdpCertificate* certificate)
925 const size_t start = Stream_GetPosition(s);
926 const BYTE* sigData = Stream_PointerAs(s,
const BYTE) -
sizeof(UINT32);
928 WINPR_ASSERT(start >= 4);
929 if (!Stream_EnsureRemainingCapacity(s, 10))
931 Stream_Write_UINT32(s, SIGNATURE_ALG_RSA);
932 Stream_Write_UINT32(s, KEY_EXCHANGE_ALG_RSA);
933 Stream_Write_UINT16(s, BB_RSA_KEY_BLOB);
934 if (!cert_write_rsa_public_key(s, certificate))
937 const size_t end = Stream_GetPosition(s);
938 return cert_write_rsa_signature(s, sigData, end - start +
sizeof(UINT32));
941static BOOL cert_write_server_certificate_v2(
wStream* s,
const rdpCertificate* certificate)
943 WINPR_ASSERT(certificate);
945 const rdpX509CertChain* chain = &certificate->x509_cert_chain;
946 const size_t padding = 8ull + 4ull * chain->count;
948 if (!Stream_EnsureRemainingCapacity(s,
sizeof(UINT32)))
951 Stream_Write_UINT32(s, chain->count);
952 for (UINT32 x = 0; x < chain->count; x++)
954 const rdpCertBlob* cert = &chain->array[x];
955 if (!cert_blob_write(cert, s))
959 if (!Stream_EnsureRemainingCapacity(s, padding))
961 Stream_Zero(s, padding);
965SSIZE_T freerdp_certificate_write_server_cert(
const rdpCertificate* certificate, UINT32 dwVersion,
971 const size_t start = Stream_GetPosition(s);
972 if (!Stream_EnsureRemainingCapacity(s, 4))
974 Stream_Write_UINT32(s, dwVersion);
976 switch (dwVersion & CERT_CHAIN_VERSION_MASK)
978 case CERT_CHAIN_VERSION_1:
979 if (!cert_write_server_certificate_v1(s, certificate))
982 case CERT_CHAIN_VERSION_2:
983 if (!cert_write_server_certificate_v2(s, certificate))
987 WLog_ERR(TAG,
"invalid certificate chain version:%" PRIu32
"",
988 dwVersion & CERT_CHAIN_VERSION_MASK);
992 const size_t end = Stream_GetPosition(s);
996 const size_t diff = end - start;
997 WINPR_ASSERT(diff <= SSIZE_MAX);
998 return (SSIZE_T)diff;
1008static BOOL certificate_read_server_x509_certificate_chain(rdpCertificate* cert,
wStream* s)
1010 UINT32 numCertBlobs = 0;
1011 DEBUG_CERTIFICATE(
"Server X.509 Certificate Chain");
1014 if (!Stream_CheckAndLogRequiredLength(TAG, s, 4))
1017 Stream_Read_UINT32(s, numCertBlobs);
1018 certificate_free_x509_certificate_chain(&cert->x509_cert_chain);
1019 cert->x509_cert_chain = certificate_new_x509_certificate_chain(numCertBlobs);
1021 for (UINT32 i = 0; i < cert->x509_cert_chain.count; i++)
1023 rdpCertBlob* blob = &cert->x509_cert_chain.array[i];
1024 if (!cert_blob_read(blob, s))
1027 if (numCertBlobs - i == 1)
1029 DEBUG_CERTIFICATE(
"Terminal Server Certificate");
1031 BOOL res = certificate_read_x509_certificate(blob, &cert->cert_info);
1035 if (!update_x509_from_info(cert))
1041 WLog_ERR(TAG,
"Failed to read x509 certificate");
1045 DEBUG_CERTIFICATE(
"modulus length:%" PRIu32
"", cert->cert_info.ModulusLength);
1049 return update_x509_from_info(cert);
1059BOOL freerdp_certificate_read_server_cert(rdpCertificate* certificate,
const BYTE* server_cert,
1065 UINT32 dwVersion = 0;
1067 WINPR_ASSERT(certificate);
1070 WLog_DBG(TAG,
"Received empty certificate, ignoring...");
1074 WINPR_ASSERT(server_cert);
1075 s = Stream_StaticConstInit(&sbuffer, server_cert, length);
1079 WLog_ERR(TAG,
"Stream_New failed!");
1083 Stream_Read_UINT32(s, dwVersion);
1085 switch (dwVersion & CERT_CHAIN_VERSION_MASK)
1087 case CERT_CHAIN_VERSION_1:
1088 ret = certificate_read_server_proprietary_certificate(certificate, s);
1091 case CERT_CHAIN_VERSION_2:
1092 ret = certificate_read_server_x509_certificate_chain(certificate, s);
1096 WLog_ERR(TAG,
"invalid certificate chain version:%" PRIu32
"",
1097 dwVersion & CERT_CHAIN_VERSION_MASK);
1105static BOOL cert_blob_copy(rdpCertBlob* dst,
const rdpCertBlob* src)
1110 cert_blob_free(dst);
1111 if (src->length > 0)
1113 dst->data = malloc(src->length);
1116 dst->length = src->length;
1117 memcpy(dst->data, src->data, src->length);
1123static BOOL cert_x509_chain_copy(rdpX509CertChain* cert,
const rdpX509CertChain* src)
1127 certificate_free_x509_certificate_chain(cert);
1133 cert->array = calloc(src->count,
sizeof(rdpCertBlob));
1138 cert->count = src->count;
1140 for (UINT32 x = 0; x < cert->count; x++)
1142 const rdpCertBlob* srcblob = &src->array[x];
1143 rdpCertBlob* dstblob = &cert->array[x];
1145 if (!cert_blob_copy(dstblob, srcblob))
1147 certificate_free_x509_certificate_chain(cert);
1156BOOL cert_clone_int(rdpCertificate* dst,
const rdpCertificate* src)
1161 if (!cert_info_clone(&dst->cert_info, &src->cert_info))
1166 dst->x509 = X509_dup(src->x509);
1173 if (!update_x509_from_info(dst))
1175 WLog_ERR(TAG,
"X509_dup failed, SSL configuration bug?");
1184 sk_X509_pop_free(dst->chain, X509_free);
1186 dst->chain = sk_X509_deep_copy(src->chain, X509_const_dup, X509_free);
1188 return cert_x509_chain_copy(&dst->x509_cert_chain, &src->x509_cert_chain);
1191rdpCertificate* freerdp_certificate_clone(
const rdpCertificate* certificate)
1196 rdpCertificate* _certificate = freerdp_certificate_new();
1201 if (!cert_clone_int(_certificate, certificate))
1204 return _certificate;
1207 freerdp_certificate_free(_certificate);
1216rdpCertificate* freerdp_certificate_new(
void)
1218 return (rdpCertificate*)calloc(1,
sizeof(rdpCertificate));
1221void certificate_free_int(rdpCertificate* cert)
1226 X509_free(cert->x509);
1228 sk_X509_pop_free(cert->chain, X509_free);
1230 certificate_free_x509_certificate_chain(&cert->x509_cert_chain);
1231 cert_info_free(&cert->cert_info);
1239void freerdp_certificate_free(rdpCertificate* cert)
1244 certificate_free_int(cert);
1248static BOOL freerdp_rsa_from_x509(rdpCertificate* cert)
1254 if (!freerdp_certificate_is_rsa(cert))
1257#if !defined(OPENSSL_VERSION_MAJOR) || (OPENSSL_VERSION_MAJOR < 3)
1259 const BIGNUM* rsa_n = NULL;
1260 const BIGNUM* rsa_e = NULL;
1262 BIGNUM* rsa_n = NULL;
1263 BIGNUM* rsa_e = NULL;
1265 EVP_PKEY* pubkey = X509_get0_pubkey(cert->x509);
1269#if !defined(OPENSSL_VERSION_MAJOR) || (OPENSSL_VERSION_MAJOR < 3)
1270 rsa = EVP_PKEY_get1_RSA(pubkey);
1280 RSA_get0_key(rsa, &rsa_n, &rsa_e, NULL);
1282 if (!EVP_PKEY_get_bn_param(pubkey, OSSL_PKEY_PARAM_RSA_E, &rsa_e))
1284 if (!EVP_PKEY_get_bn_param(pubkey, OSSL_PKEY_PARAM_RSA_N, &rsa_n))
1287 if (!rsa_n || !rsa_e)
1289 if (!cert_info_create(&cert->cert_info, rsa_n, rsa_e))
1293#if !defined(OPENSSL_VERSION_MAJOR) || (OPENSSL_VERSION_MAJOR < 3)
1302rdpCertificate* freerdp_certificate_new_from_der(
const BYTE* data,
size_t length)
1304 rdpCertificate* cert = freerdp_certificate_new();
1306 if (!cert || !data || (length == 0) || (length > INT_MAX))
1308 const BYTE* ptr = data;
1309 cert->x509 = d2i_X509(NULL, &ptr, (
int)length);
1312 if (!freerdp_rsa_from_x509(cert))
1316 freerdp_certificate_free(cert);
1320rdpCertificate* freerdp_certificate_new_from_x509(
const X509* xcert,
const STACK_OF(X509) * chain)
1322 WINPR_ASSERT(xcert);
1324 rdpCertificate* cert = freerdp_certificate_new();
1328 X509* wcert = WINPR_CAST_CONST_PTR_AWAY(xcert, X509*);
1329 cert->x509 = X509_dup(wcert);
1333 if (!freerdp_rsa_from_x509(cert))
1337 cert->chain = sk_X509_deep_copy(chain, X509_const_dup, X509_free);
1341 freerdp_certificate_free(cert);
1345static STACK_OF(X509) * extract_chain_from_pem(
const char* pem, BOOL isFile)
1354 bio = BIO_new_file(pem,
"rb");
1357 const size_t len = strlen(pem);
1358 bio = BIO_new_mem_buf(pem, WINPR_ASSERTING_INT_CAST(
int, len));
1366 X509* leaf = PEM_read_bio_X509(bio, NULL, NULL, NULL);
1373 STACK_OF(X509)* chain = sk_X509_new_null();
1382 while ((cert = PEM_read_bio_X509(bio, NULL, NULL, NULL)) != NULL)
1384 sk_X509_push(chain, cert);
1392static rdpCertificate* freerdp_certificate_new_from(
const char* file, BOOL isFile)
1394 X509* x509 = x509_utils_from_pem(file, strlen(file), isFile);
1397 STACK_OF(X509)* chain = extract_chain_from_pem(file, isFile);
1398 rdpCertificate* cert = freerdp_certificate_new_from_x509(x509, chain);
1400 sk_X509_pop_free(chain, X509_free);
1405rdpCertificate* freerdp_certificate_new_from_file(
const char* file)
1407 return freerdp_certificate_new_from(file, TRUE);
1410rdpCertificate* freerdp_certificate_new_from_pem(
const char* pem)
1412 return freerdp_certificate_new_from(pem, FALSE);
1415const rdpCertInfo* freerdp_certificate_get_info(
const rdpCertificate* cert)
1418 if (!freerdp_certificate_is_rsa(cert))
1420 return &cert->cert_info;
1423char* freerdp_certificate_get_fingerprint(
const rdpCertificate* cert)
1425 return freerdp_certificate_get_fingerprint_by_hash(cert,
"sha256");
1428char* freerdp_certificate_get_fingerprint_by_hash(
const rdpCertificate* cert,
const char* hash)
1430 return freerdp_certificate_get_fingerprint_by_hash_ex(cert, hash, TRUE);
1433char* freerdp_certificate_get_fingerprint_by_hash_ex(
const rdpCertificate* cert,
const char* hash,
1440 char* fp_buffer = NULL;
1441 if (!cert || !cert->x509)
1443 WLog_ERR(TAG,
"Invalid certificate [%p, %p]", cert, cert ? cert->x509 : NULL);
1448 WLog_ERR(TAG,
"Invalid certificate hash %p", hash);
1451 fp = x509_utils_get_hash(cert->x509, hash, &fp_len);
1458 size = fp_len * 3 + 1;
1459 fp_buffer = calloc(size,
sizeof(
char));
1466 for (; i < (fp_len - 1); i++)
1469 char* p = &fp_buffer[pos];
1471 rc = sprintf_s(p, size - pos,
"%02" PRIx8
":", fp[i]);
1473 rc = sprintf_s(p, size - pos,
"%02" PRIx8, fp[i]);
1479 (void)sprintf_s(&fp_buffer[pos], size - pos,
"%02" PRIx8
"", fp[i]);
1490static BOOL bio_read_pem(BIO* bio,
char** ppem,
size_t* plength)
1497 const size_t blocksize = 2048;
1499 size_t length = blocksize;
1506 while (offset < length)
1508 char* tmp = realloc(pem, length + 1);
1515 const int status = BIO_read(bio, &pem[offset], (
int)(length - offset));
1518 WLog_ERR(TAG,
"failed to read certificate");
1525 offset += (size_t)status;
1526 if (length - offset > 0)
1528 length += blocksize;
1533 if (offset >= length)
1548char* freerdp_certificate_get_pem(
const rdpCertificate* cert,
size_t* pLength)
1550 return freerdp_certificate_get_pem_ex(cert, pLength, TRUE);
1553char* freerdp_certificate_get_pem_ex(
const rdpCertificate* cert,
size_t* pLength,
1565 BIO* bio = BIO_new(BIO_s_mem());
1569 WLog_ERR(TAG,
"BIO_new() failure");
1575 const int status = PEM_write_bio_X509(bio, cert->x509);
1578 WLog_ERR(TAG,
"PEM_write_bio_X509 failure: %d", status);
1582 if (cert->chain && withCertChain)
1584 const int count = sk_X509_num(cert->chain);
1585 for (
int x = 0; x < count; x++)
1587 X509* c = sk_X509_value(cert->chain, x);
1588 const int rc = PEM_write_bio_X509(bio, c);
1591 WLog_ERR(TAG,
"PEM_write_bio_X509 failure: %d", rc);
1597 (void)bio_read_pem(bio, &pem, pLength);
1604char* freerdp_certificate_get_subject(
const rdpCertificate* cert)
1607 return x509_utils_get_subject(cert->x509);
1610char* freerdp_certificate_get_issuer(
const rdpCertificate* cert)
1613 return x509_utils_get_issuer(cert->x509);
1616char* freerdp_certificate_get_upn(
const rdpCertificate* cert)
1619 return x509_utils_get_upn(cert->x509);
1622char* freerdp_certificate_get_email(
const rdpCertificate* cert)
1625 return x509_utils_get_email(cert->x509);
1628char* freerdp_certificate_get_validity(
const rdpCertificate* cert, BOOL startDate)
1631 return x509_utils_get_date(cert->x509, startDate);
1634BOOL freerdp_certificate_check_eku(
const rdpCertificate* cert,
int nid)
1637 return x509_utils_check_eku(cert->x509, nid);
1640BOOL freerdp_certificate_get_public_key(
const rdpCertificate* cert, BYTE** PublicKey,
1641 DWORD* PublicKeyLength)
1646 BOOL status = FALSE;
1647 EVP_PKEY* pkey = NULL;
1651 pkey = X509_get0_pubkey(cert->x509);
1655 WLog_ERR(TAG,
"X509_get_pubkey() failed");
1659 length = i2d_PublicKey(pkey, NULL);
1663 WLog_ERR(TAG,
"i2d_PublicKey() failed");
1667 *PublicKey = optr = ptr = (BYTE*)calloc(WINPR_ASSERTING_INT_CAST(
size_t, length),
sizeof(BYTE));
1672 const int length2 = i2d_PublicKey(pkey, &ptr);
1673 if (length != length2)
1675 *PublicKeyLength = (DWORD)length2;
1685BOOL freerdp_certificate_verify(
const rdpCertificate* cert,
const char* certificate_store_path)
1688 return x509_utils_verify(cert->x509, cert->chain, certificate_store_path);
1691char** freerdp_certificate_get_dns_names(
const rdpCertificate* cert,
size_t* pcount,
1695 return x509_utils_get_dns_names(cert->x509, pcount, pplengths);
1698char* freerdp_certificate_get_common_name(
const rdpCertificate* cert,
size_t* plength)
1701 return x509_utils_get_common_name(cert->x509, plength);
1704WINPR_MD_TYPE freerdp_certificate_get_signature_alg(
const rdpCertificate* cert)
1707 return x509_utils_get_signature_alg(cert->x509);
1710void freerdp_certificate_free_dns_names(
size_t count,
size_t* lengths,
char** names)
1712 x509_utils_dns_names_free(count, lengths, names);
1715char* freerdp_certificate_get_hash(
const rdpCertificate* cert,
const char* hash,
size_t* plength)
1718 return (
char*)x509_utils_get_hash(cert->x509, hash, plength);
1721X509* freerdp_certificate_get_x509(rdpCertificate* cert)
1727BOOL freerdp_certificate_publickey_encrypt(
const rdpCertificate* cert,
const BYTE* input,
1728 size_t cbInput, BYTE** poutput,
size_t* pcbOutput)
1731 WINPR_ASSERT(input);
1732 WINPR_ASSERT(poutput);
1733 WINPR_ASSERT(pcbOutput);
1736 BYTE* output = NULL;
1737 EVP_PKEY* pkey = X509_get0_pubkey(cert->x509);
1741 EVP_PKEY_CTX* ctx = EVP_PKEY_CTX_new(pkey, NULL);
1745 size_t outputSize = WINPR_ASSERTING_INT_CAST(
size_t, EVP_PKEY_size(pkey));
1746 output = malloc(outputSize);
1749 *pcbOutput = outputSize;
1751 if (EVP_PKEY_encrypt_init(ctx) != 1 ||
1752 EVP_PKEY_CTX_set_rsa_padding(ctx, RSA_PKCS1_PADDING) != 1 ||
1753 EVP_PKEY_encrypt(ctx, output, pcbOutput, input, cbInput) != 1)
1755 WLog_ERR(TAG,
"error when setting up public key");
1763 EVP_PKEY_CTX_free(ctx);
1768#if !defined(OPENSSL_VERSION_MAJOR) || (OPENSSL_VERSION_MAJOR < 3)
1769static RSA* freerdp_certificate_get_RSA(
const rdpCertificate* cert)
1773 if (!freerdp_certificate_is_rsa(cert))
1776 EVP_PKEY* pubkey = X509_get0_pubkey(cert->x509);
1780 return EVP_PKEY_get1_RSA(pubkey);
1784BYTE* freerdp_certificate_get_der(
const rdpCertificate* cert,
size_t* pLength)
1791 const int rc = i2d_X509(cert->x509, NULL);
1795 BYTE* ptr = calloc(WINPR_ASSERTING_INT_CAST(
size_t, rc) + 1,
sizeof(BYTE));
1798 BYTE* i2d_ptr = ptr;
1800 const int rc2 = i2d_X509(cert->x509, &i2d_ptr);
1808 *pLength = (size_t)rc2;
1812BOOL freerdp_certificate_is_rsa(
const rdpCertificate* cert)
1815 return is_rsa_key(cert->x509);
1818BOOL freerdp_certificate_is_rdp_security_compatible(
const rdpCertificate* cert)
1820 const rdpCertInfo* info = freerdp_certificate_get_info(cert);
1821 if (!freerdp_certificate_is_rsa(cert) || !info || (info->ModulusLength != 2048 / 8))
1823 WLog_INFO(TAG,
"certificate is not RSA 2048, RDP security not supported.");
1829char* freerdp_certificate_get_param(
const rdpCertificate* cert,
enum FREERDP_CERT_PARAM what,
1833 WINPR_ASSERT(psize);
1837#if !defined(OPENSSL_VERSION_MAJOR) || (OPENSSL_VERSION_MAJOR < 3)
1838 const BIGNUM* bn = NULL;
1839 RSA* rsa = freerdp_certificate_get_RSA(cert);
1842 case FREERDP_CERT_RSA_E:
1843 RSA_get0_key(rsa, NULL, &bn, NULL);
1845 case FREERDP_CERT_RSA_N:
1846 RSA_get0_key(rsa, &bn, NULL, NULL);
1854 EVP_PKEY* pkey = X509_get0_pubkey(cert->x509);
1861 case FREERDP_CERT_RSA_E:
1862 if (!EVP_PKEY_get_bn_param(pkey, OSSL_PKEY_PARAM_RSA_E, &bn))
1865 case FREERDP_CERT_RSA_N:
1866 if (!EVP_PKEY_get_bn_param(pkey, OSSL_PKEY_PARAM_RSA_N, &bn))
1874 const size_t bnsize = WINPR_ASSERTING_INT_CAST(
size_t, BN_num_bytes(bn));
1875 char* rc = calloc(bnsize + 1,
sizeof(
char));
1878 BN_bn2bin(bn, (BYTE*)rc);
1882#if defined(OPENSSL_VERSION_MAJOR) && (OPENSSL_VERSION_MAJOR < 3)
1888size_t freerdp_certificate_get_chain_len(rdpCertificate* certificate)
1890 WINPR_ASSERT(certificate);
1891 if (!certificate->chain)
1894 return WINPR_ASSERTING_INT_CAST(
size_t, sk_X509_num(certificate->chain));
1897X509* freerdp_certificate_get_chain_at(rdpCertificate* certificate,
size_t offset)
1899 WINPR_ASSERT(certificate);
1900 WINPR_ASSERT(freerdp_certificate_get_chain_len(certificate) > offset);
1901 const int ioff = WINPR_ASSERTING_INT_CAST(
int, offset);
1902 return sk_X509_value(certificate->chain, ioff);