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);