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/crypto.h>
37 #include <openssl/pem.h>
38 #include <openssl/rsa.h>
39 #include <openssl/bn.h>
41 #include "cert_common.h"
43 #include "opensslcompat.h"
45 #define TAG FREERDP_TAG("core")
47 static BOOL cert_info_allocate(rdpCertInfo* info,
size_t size);
49 BOOL read_bignum(BYTE** dst, UINT32* length,
const BIGNUM* num, BOOL alloc)
62 const int len = BN_num_bytes(num);
68 if (*length < (UINT32)len)
76 *dst = malloc((
size_t)len);
81 crypto_reverse(*dst, (
size_t)len);
82 *length = (UINT32)len;
88 BOOL cert_info_create(rdpCertInfo* dst,
const BIGNUM* rsa,
const BIGNUM* rsa_e)
90 const rdpCertInfo empty = { 0 };
97 if (!read_bignum(&dst->Modulus, &dst->ModulusLength, rsa, TRUE))
100 UINT32 len =
sizeof(dst->exponent);
101 BYTE* ptr = &dst->exponent[0];
102 if (!read_bignum(&ptr, &len, rsa_e, FALSE))
111 BOOL cert_info_clone(rdpCertInfo* dst,
const rdpCertInfo* src)
119 dst->ModulusLength = 0;
120 if (src->ModulusLength > 0)
122 dst->Modulus = malloc(src->ModulusLength);
125 memcpy(dst->Modulus, src->Modulus, src->ModulusLength);
126 dst->ModulusLength = src->ModulusLength;
131 void cert_info_free(rdpCertInfo* info)
135 info->ModulusLength = 0;
136 info->Modulus = NULL;
139 BOOL cert_info_allocate(rdpCertInfo* info,
size_t size)
142 cert_info_free(info);
144 info->Modulus = (BYTE*)malloc(size);
146 if (!info->Modulus && (size > 0))
148 WLog_ERR(TAG,
"Failed to allocate info->Modulus of size %" PRIuz, size);
151 info->ModulusLength = (UINT32)size;
155 BOOL cert_info_read_modulus(rdpCertInfo* info,
size_t size,
wStream* s)
157 if (!Stream_CheckAndLogRequiredLength(TAG, s, size))
159 if (size > UINT32_MAX)
161 WLog_ERR(TAG,
"modulus size %" PRIuz
" exceeds limit of %" PRIu32, size, UINT32_MAX);
164 if (!cert_info_allocate(info, size))
166 Stream_Read(s, info->Modulus, info->ModulusLength);
170 BOOL cert_info_read_exponent(rdpCertInfo* info,
size_t size,
wStream* s)
172 if (!Stream_CheckAndLogRequiredLength(TAG, s, size))
176 WLog_ERR(TAG,
"exponent size %" PRIuz
" exceeds limit of %" PRIu32, size, 4);
179 if (!info->Modulus || (info->ModulusLength == 0))
181 WLog_ERR(TAG,
"invalid modulus=%p [%" PRIu32
"]", info->Modulus, info->ModulusLength);
184 Stream_Read(s, &info->exponent[4 - size], size);
185 crypto_reverse(info->Modulus, info->ModulusLength);
186 crypto_reverse(info->exponent, 4);
190 #if !defined(OPENSSL_VERSION_MAJOR) || (OPENSSL_VERSION_MAJOR < 3)
191 X509* x509_from_rsa(
const RSA* rsa)
193 EVP_PKEY* pubkey = NULL;
196 #
if defined(LIBRESSL_VERSION_NUMBER)
205 const int rc = PEM_write_bio_RSA_PUBKEY(bio, (RSA*)rsa);
209 pubkey = PEM_read_bio_PUBKEY(bio, NULL, NULL, NULL);
217 const int res = X509_set_pubkey(x509, pubkey);
226 EVP_PKEY_free(pubkey);