25 #include <freerdp/config.h>
31 #include <winpr/assert.h>
32 #include <winpr/wtypes.h>
33 #include <winpr/crt.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
79 typedef struct rdp_CertBlob rdpCertBlob;
81 struct rdp_X509CertChain
86 typedef struct rdp_X509CertChain rdpX509CertChain;
88 struct rdp_certificate
91 STACK_OF(X509) * chain;
93 rdpCertInfo cert_info;
94 rdpX509CertChain x509_cert_chain;
185 static const char rsa_magic[4] =
"RSA1";
187 static 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",
207 static 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)
215 static const BYTE tssk_exponent[] = { 0x5b, 0x7b, 0x88, 0xc0 };
218 static void certificate_free_int(rdpCertificate* certificate);
219 static BOOL cert_clone_int(rdpCertificate* dst,
const rdpCertificate* src);
225 static BOOL cert_blob_copy(rdpCertBlob* dst,
const rdpCertBlob* src);
226 static void cert_blob_free(rdpCertBlob* blob);
227 static BOOL cert_blob_write(
const rdpCertBlob* blob,
wStream* s);
228 static BOOL cert_blob_read(rdpCertBlob* blob,
wStream* s);
230 BOOL 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);
260 BOOL 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);
272 void cert_blob_free(rdpCertBlob* blob)
285 static BOOL is_rsa_key(
const X509* x509)
287 EVP_PKEY* evp = X509_get0_pubkey(x509);
291 return (EVP_PKEY_id(evp) == EVP_PKEY_RSA);
294 static 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);
442 static 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;
459 static 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);
476 #if defined(OPENSSL_VERSION_MAJOR) && (OPENSSL_VERSION_MAJOR >= 3)
477 static OSSL_PARAM* get_params(
const BIGNUM* e,
const BIGNUM* mod)
482 OSSL_PARAM* parameters = NULL;
483 OSSL_PARAM_BLD* param = OSSL_PARAM_BLD_new();
487 const int bits = BN_num_bits(e);
488 if ((bits < 0) || (bits > 32))
492 const int ne = BN_bn2nativepad(e, (BYTE*)&ie,
sizeof(ie));
493 if ((ne < 0) || (ne > 4))
495 if (OSSL_PARAM_BLD_push_BN(param, OSSL_PKEY_PARAM_RSA_N, mod) != 1)
497 if (OSSL_PARAM_BLD_push_uint(param, OSSL_PKEY_PARAM_RSA_E, ie) != 1)
500 parameters = OSSL_PARAM_BLD_to_param(param);
502 OSSL_PARAM_BLD_free(param);
508 static BOOL update_x509_from_info(rdpCertificate* cert)
514 X509_free(cert->x509);
517 rdpCertInfo* info = &cert->cert_info;
519 BIGNUM* e = BN_new();
520 BIGNUM* mod = BN_new();
521 #if !defined(OPENSSL_VERSION_MAJOR) || (OPENSSL_VERSION_MAJOR < 3)
522 RSA* rsa = RSA_new();
530 WINPR_ASSERT(info->ModulusLength <= INT_MAX);
531 if (!BN_bin2bn(info->Modulus, (
int)info->ModulusLength, mod))
534 if (!BN_bin2bn(info->exponent, (
int)
sizeof(info->exponent), e))
537 #if !defined(OPENSSL_VERSION_MAJOR) || (OPENSSL_VERSION_MAJOR < 3)
538 const int rec = RSA_set0_key(rsa, mod, e, NULL);
542 cert->x509 = x509_from_rsa(rsa);
544 EVP_PKEY* pkey = NULL;
545 EVP_PKEY_CTX* ctx = EVP_PKEY_CTX_new_id(EVP_PKEY_RSA, NULL);
548 const int xx = EVP_PKEY_fromdata_init(ctx);
551 OSSL_PARAM* parameters = get_params(e, mod);
555 const int rc2 = EVP_PKEY_fromdata(ctx, &pkey, EVP_PKEY_PUBLIC_KEY, parameters);
556 OSSL_PARAM_free(parameters);
560 cert->x509 = X509_new();
563 if (X509_set_pubkey(cert->x509, pkey) != 1)
565 X509_free(cert->x509);
570 EVP_PKEY_CTX_free(ctx);
579 WLog_ERR(TAG,
"failed to update x509 from rdpCertInfo");
581 #if !defined(OPENSSL_VERSION_MAJOR) || (OPENSSL_VERSION_MAJOR < 3)
593 static BOOL certificate_process_server_public_key(rdpCertificate* cert,
wStream* s, UINT32 length)
595 char magic[
sizeof(rsa_magic)] = { 0 };
603 if (!Stream_CheckAndLogRequiredLength(TAG, s, 20))
606 Stream_Read(s, magic,
sizeof(magic));
608 if (memcmp(magic, rsa_magic,
sizeof(magic)) != 0)
610 WLog_ERR(TAG,
"invalid RSA magic bytes");
614 rdpCertInfo* info = &cert->cert_info;
615 cert_info_free(info);
617 Stream_Read_UINT32(s, keylen);
618 Stream_Read_UINT32(s, bitlen);
619 Stream_Read_UINT32(s, datalen);
620 Stream_Read(s, info->exponent, 4);
624 WLog_ERR(TAG,
"Invalid RSA keylen=%" PRIu32
" <= 8", keylen);
627 if (!Stream_CheckAndLogRequiredLength(TAG, s, keylen))
629 if (keylen != (bitlen / 8ull) + 8ull)
631 WLog_ERR(TAG,
"Invalid RSA key bitlen %" PRIu32
", expected %" PRIu32, bitlen,
635 if (datalen != (bitlen / 8ull) - 1ull)
637 WLog_ERR(TAG,
"Invalid RSA key datalen %" PRIu32
", expected %" PRIu32, datalen,
638 (bitlen / 8ull) - 1ull);
641 info->ModulusLength = keylen - 8;
642 BYTE* tmp = realloc(info->Modulus, info->ModulusLength);
646 WLog_ERR(TAG,
"Failed to reallocate modulus of length %" PRIu32, info->ModulusLength);
651 Stream_Read(s, info->Modulus, info->ModulusLength);
653 return update_x509_from_info(cert);
656 static BOOL certificate_process_server_public_signature(rdpCertificate* certificate,
657 const BYTE* sigdata,
size_t sigdatalen,
660 WINPR_ASSERT(certificate);
661 #if defined(CERT_VALIDATE_RSA)
662 BYTE sig[TSSK_KEY_LENGTH];
664 BYTE encsig[TSSK_KEY_LENGTH + 8];
665 #if defined(CERT_VALIDATE_MD5) && defined(CERT_VALIDATE_RSA)
666 BYTE md5hash[WINPR_MD5_DIGEST_LENGTH];
668 #if !defined(CERT_VALIDATE_MD5) || !defined(CERT_VALIDATE_RSA)
679 #if defined(CERT_VALIDATE_MD5)
681 if (!winpr_Digest(WINPR_MD_MD5, sigdata, sigdatalen, md5hash,
sizeof(md5hash)))
685 Stream_Read(s, encsig, siglen);
691 #if defined(CERT_VALIDATE_PADDING)
694 for (
size_t i =
sizeof(encsig) - 8; i <
sizeof(encsig); i++)
699 WLog_ERR(TAG,
"invalid signature");
704 #if defined(CERT_VALIDATE_RSA)
706 if (crypto_rsa_public_decrypt(encsig, siglen - 8, TSSK_KEY_LENGTH, tssk_modulus, tssk_exponent,
709 WLog_ERR(TAG,
"invalid RSA decrypt");
715 #if defined(CERT_VALIDATE_MD5)
717 if (memcmp(md5hash, sig,
sizeof(md5hash)) != 0)
719 WLog_ERR(TAG,
"invalid signature");
732 for (
size_t i = 17; i < 62; i++)
735 if (sig[16] != 0x00 || sum != 0xFF * (62 - 17) || sig[62] != 0x01)
737 WLog_ERR(TAG,
"invalid signature");
745 static BOOL certificate_read_server_proprietary_certificate(rdpCertificate* certificate,
wStream* s)
747 UINT32 dwSigAlgId = 0;
748 UINT32 dwKeyAlgId = 0;
749 UINT16 wPublicKeyBlobType = 0;
750 UINT16 wPublicKeyBlobLen = 0;
751 UINT16 wSignatureBlobType = 0;
752 UINT16 wSignatureBlobLen = 0;
753 size_t sigdatalen = 0;
755 WINPR_ASSERT(certificate);
756 if (!Stream_CheckAndLogRequiredLength(TAG, s, 12))
760 const BYTE* sigdata = Stream_PointerAs(s,
const BYTE) - 4;
761 Stream_Read_UINT32(s, dwSigAlgId);
762 Stream_Read_UINT32(s, dwKeyAlgId);
764 if (!((dwSigAlgId == SIGNATURE_ALG_RSA) && (dwKeyAlgId == KEY_EXCHANGE_ALG_RSA)))
767 "unsupported signature or key algorithm, dwSigAlgId=%" PRIu32
768 " dwKeyAlgId=%" PRIu32
"",
769 dwSigAlgId, dwKeyAlgId);
773 Stream_Read_UINT16(s, wPublicKeyBlobType);
775 if (wPublicKeyBlobType != BB_RSA_KEY_BLOB)
777 WLog_ERR(TAG,
"unsupported public key blob type %" PRIu16
"", wPublicKeyBlobType);
781 Stream_Read_UINT16(s, wPublicKeyBlobLen);
783 if (!Stream_CheckAndLogRequiredLength(TAG, s, wPublicKeyBlobLen))
786 if (!certificate_process_server_public_key(certificate, s, wPublicKeyBlobLen))
789 if (!Stream_CheckAndLogRequiredLength(TAG, s, 4))
792 sigdatalen = Stream_PointerAs(s,
const BYTE) - sigdata;
793 Stream_Read_UINT16(s, wSignatureBlobType);
795 if (wSignatureBlobType != BB_RSA_SIGNATURE_BLOB)
797 WLog_ERR(TAG,
"unsupported blob signature %" PRIu16
"", wSignatureBlobType);
801 Stream_Read_UINT16(s, wSignatureBlobLen);
803 if (!Stream_CheckAndLogRequiredLength(TAG, s, wSignatureBlobLen))
806 if (wSignatureBlobLen != 72)
808 WLog_ERR(TAG,
"invalid signature length (got %" PRIu16
", expected 72)", wSignatureBlobLen);
812 if (!certificate_process_server_public_signature(certificate, sigdata, sigdatalen, s,
815 WLog_ERR(TAG,
"unable to parse server public signature");
822 static BOOL cert_write_rsa_public_key(
wStream* s,
const rdpCertificate* cert)
825 WINPR_ASSERT(freerdp_certificate_is_rsa(cert));
827 const rdpCertInfo* info = &cert->cert_info;
829 const UINT32 keyLen = info->ModulusLength + 8;
830 const UINT32 bitLen = info->ModulusLength * 8;
831 const UINT32 dataLen = (bitLen / 8) - 1;
832 const size_t pubExpLen =
sizeof(info->exponent);
833 const BYTE* pubExp = info->exponent;
834 const BYTE* modulus = info->Modulus;
836 const size_t wPublicKeyBlobLen = 16 + pubExpLen + keyLen;
837 WINPR_ASSERT(wPublicKeyBlobLen <= UINT16_MAX);
838 if (!Stream_EnsureRemainingCapacity(s, 2 + wPublicKeyBlobLen))
840 Stream_Write_UINT16(s, (UINT16)wPublicKeyBlobLen);
841 Stream_Write(s, rsa_magic,
sizeof(rsa_magic));
842 Stream_Write_UINT32(s, keyLen);
843 Stream_Write_UINT32(s, bitLen);
844 Stream_Write_UINT32(s, dataLen);
845 Stream_Write(s, pubExp, pubExpLen);
846 Stream_Write(s, modulus, info->ModulusLength);
851 static BOOL cert_write_rsa_signature(
wStream* s,
const void* sigData,
size_t sigDataLen)
853 BYTE encryptedSignature[TSSK_KEY_LENGTH] = { 0 };
854 BYTE signature[
sizeof(initial_signature)] = { 0 };
856 memcpy(signature, initial_signature,
sizeof(initial_signature));
857 if (!winpr_Digest(WINPR_MD_MD5, sigData, sigDataLen, signature,
sizeof(signature)))
860 crypto_rsa_private_encrypt(signature,
sizeof(signature), priv_key_tssk, encryptedSignature,
861 sizeof(encryptedSignature));
863 if (!Stream_EnsureRemainingCapacity(s, 2 *
sizeof(UINT16) +
sizeof(encryptedSignature) + 8))
865 Stream_Write_UINT16(s, BB_RSA_SIGNATURE_BLOB);
866 Stream_Write_UINT16(s,
sizeof(encryptedSignature) + 8);
867 Stream_Write(s, encryptedSignature,
sizeof(encryptedSignature));
873 static BOOL cert_write_server_certificate_v1(
wStream* s,
const rdpCertificate* certificate)
875 const size_t start = Stream_GetPosition(s);
876 const BYTE* sigData = Stream_PointerAs(s,
const BYTE) -
sizeof(UINT32);
878 WINPR_ASSERT(start >= 4);
879 if (!Stream_EnsureRemainingCapacity(s, 10))
881 Stream_Write_UINT32(s, SIGNATURE_ALG_RSA);
882 Stream_Write_UINT32(s, KEY_EXCHANGE_ALG_RSA);
883 Stream_Write_UINT16(s, BB_RSA_KEY_BLOB);
884 if (!cert_write_rsa_public_key(s, certificate))
887 const size_t end = Stream_GetPosition(s);
888 return cert_write_rsa_signature(s, sigData, end - start +
sizeof(UINT32));
891 static BOOL cert_write_server_certificate_v2(
wStream* s,
const rdpCertificate* certificate)
893 WINPR_ASSERT(certificate);
895 const rdpX509CertChain* chain = &certificate->x509_cert_chain;
896 const size_t padding = 8ull + 4ull * chain->count;
898 if (!Stream_EnsureRemainingCapacity(s,
sizeof(UINT32)))
901 Stream_Write_UINT32(s, chain->count);
902 for (UINT32 x = 0; x < chain->count; x++)
904 const rdpCertBlob* cert = &chain->array[x];
905 if (!cert_blob_write(cert, s))
909 if (!Stream_EnsureRemainingCapacity(s, padding))
911 Stream_Zero(s, padding);
915 SSIZE_T freerdp_certificate_write_server_cert(
const rdpCertificate* certificate, UINT32 dwVersion,
921 const size_t start = Stream_GetPosition(s);
922 if (!Stream_EnsureRemainingCapacity(s, 4))
924 Stream_Write_UINT32(s, dwVersion);
926 switch (dwVersion & CERT_CHAIN_VERSION_MASK)
928 case CERT_CHAIN_VERSION_1:
929 if (!cert_write_server_certificate_v1(s, certificate))
932 case CERT_CHAIN_VERSION_2:
933 if (!cert_write_server_certificate_v2(s, certificate))
937 WLog_ERR(TAG,
"invalid certificate chain version:%" PRIu32
"",
938 dwVersion & CERT_CHAIN_VERSION_MASK);
942 const size_t end = Stream_GetPosition(s);
946 const size_t diff = end - start;
947 WINPR_ASSERT(diff <= SSIZE_MAX);
948 return (SSIZE_T)diff;
958 static BOOL certificate_read_server_x509_certificate_chain(rdpCertificate* cert,
wStream* s)
960 UINT32 numCertBlobs = 0;
961 DEBUG_CERTIFICATE(
"Server X.509 Certificate Chain");
964 if (!Stream_CheckAndLogRequiredLength(TAG, s, 4))
967 Stream_Read_UINT32(s, numCertBlobs);
968 certificate_free_x509_certificate_chain(&cert->x509_cert_chain);
969 cert->x509_cert_chain = certificate_new_x509_certificate_chain(numCertBlobs);
971 for (UINT32 i = 0; i < cert->x509_cert_chain.count; i++)
973 rdpCertBlob* blob = &cert->x509_cert_chain.array[i];
974 if (!cert_blob_read(blob, s))
977 if (numCertBlobs - i == 1)
979 DEBUG_CERTIFICATE(
"Terminal Server Certificate");
981 BOOL res = certificate_read_x509_certificate(blob, &cert->cert_info);
985 if (!update_x509_from_info(cert))
991 WLog_ERR(TAG,
"Failed to read x509 certificate");
995 DEBUG_CERTIFICATE(
"modulus length:%" PRIu32
"", cert->cert_info.ModulusLength);
999 return update_x509_from_info(cert);
1002 static BOOL certificate_write_server_x509_certificate_chain(
const rdpCertificate* certificate,
1005 UINT32 numCertBlobs = 0;
1007 WINPR_ASSERT(certificate);
1010 numCertBlobs = certificate->x509_cert_chain.count;
1012 if (!Stream_EnsureRemainingCapacity(s, 4))
1014 Stream_Write_UINT32(s, numCertBlobs);
1016 for (UINT32 i = 0; i < numCertBlobs; i++)
1018 const rdpCertBlob* cert = &certificate->x509_cert_chain.array[i];
1019 if (!cert_blob_write(cert, s))
1033 BOOL freerdp_certificate_read_server_cert(rdpCertificate* certificate,
const BYTE* server_cert,
1039 UINT32 dwVersion = 0;
1041 WINPR_ASSERT(certificate);
1044 WLog_DBG(TAG,
"Received empty certificate, ignoring...");
1048 WINPR_ASSERT(server_cert);
1049 s = Stream_StaticConstInit(&sbuffer, server_cert, length);
1053 WLog_ERR(TAG,
"Stream_New failed!");
1057 Stream_Read_UINT32(s, dwVersion);
1059 switch (dwVersion & CERT_CHAIN_VERSION_MASK)
1061 case CERT_CHAIN_VERSION_1:
1062 ret = certificate_read_server_proprietary_certificate(certificate, s);
1065 case CERT_CHAIN_VERSION_2:
1066 ret = certificate_read_server_x509_certificate_chain(certificate, s);
1070 WLog_ERR(TAG,
"invalid certificate chain version:%" PRIu32
"",
1071 dwVersion & CERT_CHAIN_VERSION_MASK);
1079 static BOOL cert_blob_copy(rdpCertBlob* dst,
const rdpCertBlob* src)
1084 cert_blob_free(dst);
1085 if (src->length > 0)
1087 dst->data = malloc(src->length);
1090 dst->length = src->length;
1091 memcpy(dst->data, src->data, src->length);
1097 static BOOL cert_x509_chain_copy(rdpX509CertChain* cert,
const rdpX509CertChain* src)
1101 certificate_free_x509_certificate_chain(cert);
1107 cert->array = calloc(src->count,
sizeof(rdpCertBlob));
1112 cert->count = src->count;
1114 for (UINT32 x = 0; x < cert->count; x++)
1116 const rdpCertBlob* srcblob = &src->array[x];
1117 rdpCertBlob* dstblob = &cert->array[x];
1119 if (!cert_blob_copy(dstblob, srcblob))
1121 certificate_free_x509_certificate_chain(cert);
1130 BOOL cert_clone_int(rdpCertificate* dst,
const rdpCertificate* src)
1137 dst->x509 = X509_dup(src->x509);
1142 if (!cert_info_clone(&dst->cert_info, &src->cert_info))
1144 return cert_x509_chain_copy(&dst->x509_cert_chain, &src->x509_cert_chain);
1147 rdpCertificate* freerdp_certificate_clone(
const rdpCertificate* certificate)
1152 rdpCertificate* _certificate = freerdp_certificate_new();
1157 if (!cert_clone_int(_certificate, certificate))
1160 return _certificate;
1163 freerdp_certificate_free(_certificate);
1172 rdpCertificate* freerdp_certificate_new(
void)
1174 return (rdpCertificate*)calloc(1,
sizeof(rdpCertificate));
1177 void certificate_free_int(rdpCertificate* cert)
1182 X509_free(cert->x509);
1184 sk_X509_pop_free(cert->chain, X509_free);
1186 certificate_free_x509_certificate_chain(&cert->x509_cert_chain);
1187 cert_info_free(&cert->cert_info);
1195 void freerdp_certificate_free(rdpCertificate* cert)
1200 certificate_free_int(cert);
1204 static BOOL freerdp_rsa_from_x509(rdpCertificate* cert)
1210 if (!freerdp_certificate_is_rsa(cert))
1213 #if !defined(OPENSSL_VERSION_MAJOR) || (OPENSSL_VERSION_MAJOR < 3)
1215 const BIGNUM* rsa_n = NULL;
1216 const BIGNUM* rsa_e = NULL;
1218 BIGNUM* rsa_n = NULL;
1219 BIGNUM* rsa_e = NULL;
1221 EVP_PKEY* pubkey = X509_get0_pubkey(cert->x509);
1225 #if !defined(OPENSSL_VERSION_MAJOR) || (OPENSSL_VERSION_MAJOR < 3)
1226 rsa = EVP_PKEY_get1_RSA(pubkey);
1236 RSA_get0_key(rsa, &rsa_n, &rsa_e, NULL);
1238 if (!EVP_PKEY_get_bn_param(pubkey, OSSL_PKEY_PARAM_RSA_E, &rsa_e))
1240 if (!EVP_PKEY_get_bn_param(pubkey, OSSL_PKEY_PARAM_RSA_N, &rsa_n))
1243 if (!rsa_n || !rsa_e)
1245 if (!cert_info_create(&cert->cert_info, rsa_n, rsa_e))
1249 #if !defined(OPENSSL_VERSION_MAJOR) || (OPENSSL_VERSION_MAJOR < 3)
1258 rdpCertificate* freerdp_certificate_new_from_der(
const BYTE* data,
size_t length)
1260 rdpCertificate* cert = freerdp_certificate_new();
1262 if (!cert || !data || (length == 0) || (length > INT_MAX))
1264 const BYTE* ptr = data;
1265 cert->x509 = d2i_X509(NULL, &ptr, (
int)length);
1268 if (!freerdp_rsa_from_x509(cert))
1272 freerdp_certificate_free(cert);
1276 rdpCertificate* freerdp_certificate_new_from_x509(
const X509* xcert,
const STACK_OF(X509) * chain)
1278 WINPR_ASSERT(xcert);
1280 rdpCertificate* cert = freerdp_certificate_new();
1284 X509* wcert = WINPR_CAST_CONST_PTR_AWAY(xcert, X509*);
1285 cert->x509 = X509_dup(wcert);
1289 if (!freerdp_rsa_from_x509(cert))
1293 cert->chain = sk_X509_deep_copy(chain, X509_const_dup, X509_free);
1297 freerdp_certificate_free(cert);
1301 static rdpCertificate* freerdp_certificate_new_from(
const char* file, BOOL isFile)
1303 X509* x509 = x509_utils_from_pem(file, strlen(file), isFile);
1306 rdpCertificate* cert = freerdp_certificate_new_from_x509(x509, NULL);
1311 rdpCertificate* freerdp_certificate_new_from_file(
const char* file)
1313 return freerdp_certificate_new_from(file, TRUE);
1316 rdpCertificate* freerdp_certificate_new_from_pem(
const char* pem)
1318 return freerdp_certificate_new_from(pem, FALSE);
1321 const rdpCertInfo* freerdp_certificate_get_info(
const rdpCertificate* cert)
1324 if (!freerdp_certificate_is_rsa(cert))
1326 return &cert->cert_info;
1329 char* freerdp_certificate_get_fingerprint(
const rdpCertificate* cert)
1331 return freerdp_certificate_get_fingerprint_by_hash(cert,
"sha256");
1334 char* freerdp_certificate_get_fingerprint_by_hash(
const rdpCertificate* cert,
const char* hash)
1336 return freerdp_certificate_get_fingerprint_by_hash_ex(cert, hash, TRUE);
1339 char* freerdp_certificate_get_fingerprint_by_hash_ex(
const rdpCertificate* cert,
const char* hash,
1346 char* fp_buffer = NULL;
1347 if (!cert || !cert->x509)
1349 WLog_ERR(TAG,
"Invalid certificate [%p, %p]", cert, cert ? cert->x509 : NULL);
1354 WLog_ERR(TAG,
"Invalid certificate hash %p", hash);
1357 fp = x509_utils_get_hash(cert->x509, hash, &fp_len);
1364 size = fp_len * 3 + 1;
1365 fp_buffer = calloc(size,
sizeof(
char));
1372 for (; i < (fp_len - 1); i++)
1375 char* p = &fp_buffer[pos];
1377 rc = sprintf_s(p, size - pos,
"%02" PRIx8
":", fp[i]);
1379 rc = sprintf_s(p, size - pos,
"%02" PRIx8, fp[i]);
1385 (void)sprintf_s(&fp_buffer[pos], size - pos,
"%02" PRIx8
"", fp[i]);
1396 static BOOL bio_read_pem(BIO* bio,
char** ppem,
size_t* plength)
1403 const size_t blocksize = 2048;
1405 size_t length = blocksize;
1412 while (offset < length)
1414 char* tmp = realloc(pem, length + 1);
1421 const int status = BIO_read(bio, &pem[offset], (
int)(length - offset));
1424 WLog_ERR(TAG,
"failed to read certificate");
1431 offset += (size_t)status;
1432 if (length - offset > 0)
1434 length += blocksize;
1448 char* freerdp_certificate_get_pem(
const rdpCertificate* cert,
size_t* pLength)
1450 return freerdp_certificate_get_pem_ex(cert, pLength, TRUE);
1453 char* freerdp_certificate_get_pem_ex(
const rdpCertificate* cert,
size_t* pLength,
1465 BIO* bio = BIO_new(BIO_s_mem());
1469 WLog_ERR(TAG,
"BIO_new() failure");
1475 const int status = PEM_write_bio_X509(bio, cert->x509);
1478 WLog_ERR(TAG,
"PEM_write_bio_X509 failure: %d", status);
1482 if (cert->chain && withCertChain)
1484 const int count = sk_X509_num(cert->chain);
1485 for (
int x = 0; x < count; x++)
1487 X509* c = sk_X509_value(cert->chain, x);
1488 const int rc = PEM_write_bio_X509(bio, c);
1491 WLog_ERR(TAG,
"PEM_write_bio_X509 failure: %d", rc);
1497 (void)bio_read_pem(bio, &pem, pLength);
1504 char* freerdp_certificate_get_subject(
const rdpCertificate* cert)
1507 return x509_utils_get_subject(cert->x509);
1510 char* freerdp_certificate_get_issuer(
const rdpCertificate* cert)
1513 return x509_utils_get_issuer(cert->x509);
1516 char* freerdp_certificate_get_upn(
const rdpCertificate* cert)
1519 return x509_utils_get_upn(cert->x509);
1522 char* freerdp_certificate_get_email(
const rdpCertificate* cert)
1525 return x509_utils_get_email(cert->x509);
1528 char* freerdp_certificate_get_validity(
const rdpCertificate* cert, BOOL startDate)
1531 return x509_utils_get_date(cert->x509, startDate);
1534 BOOL freerdp_certificate_check_eku(
const rdpCertificate* cert,
int nid)
1537 return x509_utils_check_eku(cert->x509, nid);
1540 BOOL freerdp_certificate_get_public_key(
const rdpCertificate* cert, BYTE** PublicKey,
1541 DWORD* PublicKeyLength)
1546 BOOL status = FALSE;
1547 EVP_PKEY* pkey = NULL;
1551 pkey = X509_get0_pubkey(cert->x509);
1555 WLog_ERR(TAG,
"X509_get_pubkey() failed");
1559 length = i2d_PublicKey(pkey, NULL);
1563 WLog_ERR(TAG,
"i2d_PublicKey() failed");
1567 *PublicKey = optr = ptr = (BYTE*)calloc(length,
sizeof(BYTE));
1572 const int length2 = i2d_PublicKey(pkey, &ptr);
1573 if (length != length2)
1575 *PublicKeyLength = (DWORD)length2;
1585 BOOL freerdp_certificate_verify(
const rdpCertificate* cert,
const char* certificate_store_path)
1588 return x509_utils_verify(cert->x509, cert->chain, certificate_store_path);
1591 char** freerdp_certificate_get_dns_names(
const rdpCertificate* cert,
size_t* pcount,
1595 return x509_utils_get_dns_names(cert->x509, pcount, pplengths);
1598 char* freerdp_certificate_get_common_name(
const rdpCertificate* cert,
size_t* plength)
1601 return x509_utils_get_common_name(cert->x509, plength);
1604 WINPR_MD_TYPE freerdp_certificate_get_signature_alg(
const rdpCertificate* cert)
1607 return x509_utils_get_signature_alg(cert->x509);
1610 void freerdp_certificate_free_dns_names(
size_t count,
size_t* lengths,
char** names)
1612 x509_utils_dns_names_free(count, lengths, names);
1615 char* freerdp_certificate_get_hash(
const rdpCertificate* cert,
const char* hash,
size_t* plength)
1618 return (
char*)x509_utils_get_hash(cert->x509, hash, plength);
1621 X509* freerdp_certificate_get_x509(rdpCertificate* cert)
1627 BOOL freerdp_certificate_publickey_encrypt(
const rdpCertificate* cert,
const BYTE* input,
1628 size_t cbInput, BYTE** poutput,
size_t* pcbOutput)
1631 WINPR_ASSERT(input);
1632 WINPR_ASSERT(poutput);
1633 WINPR_ASSERT(pcbOutput);
1636 BYTE* output = NULL;
1637 EVP_PKEY* pkey = X509_get0_pubkey(cert->x509);
1641 EVP_PKEY_CTX* ctx = EVP_PKEY_CTX_new(pkey, NULL);
1645 size_t outputSize = EVP_PKEY_size(pkey);
1646 output = malloc(outputSize);
1649 *pcbOutput = outputSize;
1651 if (EVP_PKEY_encrypt_init(ctx) != 1 ||
1652 EVP_PKEY_CTX_set_rsa_padding(ctx, RSA_PKCS1_PADDING) != 1 ||
1653 EVP_PKEY_encrypt(ctx, output, pcbOutput, input, cbInput) != 1)
1655 WLog_ERR(TAG,
"error when setting up public key");
1663 EVP_PKEY_CTX_free(ctx);
1668 #if !defined(OPENSSL_VERSION_MAJOR) || (OPENSSL_VERSION_MAJOR < 3)
1669 static RSA* freerdp_certificate_get_RSA(
const rdpCertificate* cert)
1673 if (!freerdp_certificate_is_rsa(cert))
1676 EVP_PKEY* pubkey = X509_get0_pubkey(cert->x509);
1680 return EVP_PKEY_get1_RSA(pubkey);
1684 BYTE* freerdp_certificate_get_der(
const rdpCertificate* cert,
size_t* pLength)
1691 const int rc = i2d_X509(cert->x509, NULL);
1695 BYTE* ptr = calloc(rc + 1,
sizeof(BYTE));
1698 BYTE* i2d_ptr = ptr;
1700 const int rc2 = i2d_X509(cert->x509, &i2d_ptr);
1708 *pLength = (size_t)rc2;
1712 BOOL freerdp_certificate_is_rsa(
const rdpCertificate* cert)
1715 return is_rsa_key(cert->x509);
1718 BOOL freerdp_certificate_is_rdp_security_compatible(
const rdpCertificate* cert)
1720 const rdpCertInfo* info = freerdp_certificate_get_info(cert);
1721 if (!freerdp_certificate_is_rsa(cert) || !info || (info->ModulusLength != 2048 / 8))
1723 WLog_INFO(TAG,
"certificate is not RSA 2048, RDP security not supported.");
1729 char* freerdp_certificate_get_param(
const rdpCertificate* cert,
enum FREERDP_CERT_PARAM what,
1733 WINPR_ASSERT(psize);
1737 #if !defined(OPENSSL_VERSION_MAJOR) || (OPENSSL_VERSION_MAJOR < 3)
1738 const BIGNUM* bn = NULL;
1739 RSA* rsa = freerdp_certificate_get_RSA(cert);
1742 case FREERDP_CERT_RSA_E:
1743 RSA_get0_key(rsa, NULL, &bn, NULL);
1745 case FREERDP_CERT_RSA_N:
1746 RSA_get0_key(rsa, &bn, NULL, NULL);
1754 EVP_PKEY* pkey = X509_get0_pubkey(cert->x509);
1761 case FREERDP_CERT_RSA_E:
1762 if (!EVP_PKEY_get_bn_param(pkey, OSSL_PKEY_PARAM_RSA_E, &bn))
1765 case FREERDP_CERT_RSA_N:
1766 if (!EVP_PKEY_get_bn_param(pkey, OSSL_PKEY_PARAM_RSA_N, &bn))
1774 const size_t bnsize = BN_num_bytes(bn);
1775 char* rc = calloc(bnsize + 1,
sizeof(
char));
1778 BN_bn2bin(bn, (BYTE*)rc);
1782 #if defined(OPENSSL_VERSION_MAJOR) && (OPENSSL_VERSION_MAJOR < 3)