diff --git a/libfreerdp/emu/scard/smartcard_virtual_gids.c b/libfreerdp/emu/scard/smartcard_virtual_gids.c index 972202967..aad85bd5f 100644 --- a/libfreerdp/emu/scard/smartcard_virtual_gids.c +++ b/libfreerdp/emu/scard/smartcard_virtual_gids.c @@ -24,13 +24,12 @@ #include #include -#include -#include -#include -#include +#include #include +#include "../../crypto/certificate.h" +#include "../../crypto/privatekey.h" #include "smartcard_virtual_gids.h" #define TAG CHANNELS_TAG("smartcard.vgids") @@ -140,10 +139,8 @@ struct vgids_context BOOL pinVerified; vgidsSE currentSE; - X509* certificate; - - RSA* publicKey; - RSA* privateKey; + rdpCertificate* certificate; + rdpRsaKey* privateKey; wArrayList* files; }; @@ -444,41 +441,34 @@ static BOOL vgids_prepare_fstable(const vgidsFilesysTableEntry* fstable, DWORD n return TRUE; } -static BOOL vgids_prepare_certificate(X509* cert, BYTE** kxc, DWORD* kxcSize) +static BOOL vgids_prepare_certificate(const rdpCertificate* cert, BYTE** kxc, DWORD* kxcSize) { /* Key exchange container: UINT16 compression version: 0001 UINT16 source size ZLIB compressed cert */ - BYTE* i2dParam; uLongf destSize; wStream* s = NULL; - BYTE* certData = NULL; BYTE* comprData = NULL; - int certSize = i2d_X509(cert, NULL); - if (certSize < 0) + + WINPR_ASSERT(cert); + + size_t certSize = 0; + BYTE* certData = freerdp_certificate_get_der(cert, &certSize); + if (!certData || (certSize == 0)) { WLog_ERR(TAG, "Failed to get certificate size"); goto handle_error; } - certData = malloc(certSize); comprData = malloc(certSize); - if (!certData || !comprData) + if (!comprData) { WLog_ERR(TAG, "Failed to allocate certificate buffer"); goto handle_error; } - /* serialize certificate to buffer (out buffer pointer is modified so pass a copy!) */ - i2dParam = certData; - if (i2d_X509(cert, &i2dParam) < 0) - { - WLog_ERR(TAG, "Failed to encode X509 certificate to DER"); - goto handle_error; - } - /* compress certificate data */ destSize = certSize; if (compress(comprData, &destSize, certData, certSize) != Z_OK) @@ -511,8 +501,12 @@ handle_error: static BYTE vgids_get_algid(vgidsContext* p_Ctx) { - int modulusSize = RSA_size(p_Ctx->privateKey); - switch (modulusSize) + WINPR_ASSERT(p_Ctx); + + const rdpCertInfo* info = freerdp_key_get_info(p_Ctx->privateKey); + WINPR_ASSERT(info); + + switch (info->ModulusLength) { case (1024 / 8): return VGIDS_ALGID_RSA_1024; @@ -799,13 +793,15 @@ static BOOL vgids_get_public_key(vgidsContext* context, UINT16 doTag) BYTE* buf = NULL; wStream* pubKey = NULL; wStream* response = NULL; - const BIGNUM *n, *e; - int nSize, eSize; + + WINPR_ASSERT(context); /* Get key components */ - RSA_get0_key(context->publicKey, &n, &e, NULL); - nSize = BN_num_bytes(n); - eSize = BN_num_bytes(e); + const rdpCertInfo* info = freerdp_certificate_get_info(context->certificate); + WINPR_ASSERT(info); + + const size_t nSize = info->ModulusLength; + const size_t eSize = sizeof(info->exponent); buf = malloc(nSize > eSize ? nSize : eSize); if (!buf) @@ -829,12 +825,10 @@ static BOOL vgids_get_public_key(vgidsContext* context, UINT16 doTag) } /* write modulus and exponent DOs */ - BN_bn2bin(n, buf); - if (!vgids_write_tlv(pubKey, 0x81, buf, nSize)) + if (!vgids_write_tlv(pubKey, 0x81, info->Modulus, nSize)) goto handle_error; - BN_bn2bin(e, buf); - if (!vgids_write_tlv(pubKey, 0x82, buf, eSize)) + if (!vgids_write_tlv(pubKey, 0x82, info->exponent, eSize)) goto handle_error; /* write ISO public key template */ @@ -1035,7 +1029,7 @@ static BOOL vgids_perform_digital_signature(vgidsContext* context) size_t sigSize, msgSize; EVP_PKEY_CTX* ctx = NULL; EVP_PKEY* pk = EVP_PKEY_new(); - vgidsDigestInfoMap gidsDigestInfo[VGIDS_MAX_DIGEST_INFO] = { + const vgidsDigestInfoMap gidsDigestInfo[VGIDS_MAX_DIGEST_INFO] = { { g_PKCS1_SHA1, sizeof(g_PKCS1_SHA1), EVP_sha1() }, { g_PKCS1_SHA224, sizeof(g_PKCS1_SHA224), EVP_sha224() }, { g_PKCS1_SHA256, sizeof(g_PKCS1_SHA256), EVP_sha256() }, @@ -1051,7 +1045,8 @@ static BOOL vgids_perform_digital_signature(vgidsContext* context) return FALSE; } - EVP_PKEY_set1_RSA(pk, context->privateKey); + RSA* rsa = freerdp_key_get_RSA(context->privateKey); + EVP_PKEY_set1_RSA(pk, rsa); vgids_reset_context_response(context); /* for each digest info */ @@ -1129,6 +1124,7 @@ static BOOL vgids_perform_digital_signature(vgidsContext* context) } EVP_PKEY_free(pk); + RSA_free(rsa); vgids_reset_context_command_data(context); return TRUE; @@ -1154,7 +1150,10 @@ static BOOL vgids_perform_decrypt(vgidsContext* context) padding = RSA_PKCS1_OAEP_PADDING; /* init response buffer */ - context->responseData = Stream_New(NULL, RSA_size(context->privateKey)); + const rdpCertInfo* info = freerdp_key_get_info(context->privateKey); + WINPR_ASSERT(info); + + context->responseData = Stream_New(NULL, info->ModulusLength); if (!context->responseData) { WLog_ERR(TAG, "Failed to create decryption buffer"); @@ -1162,9 +1161,12 @@ static BOOL vgids_perform_decrypt(vgidsContext* context) } /* Determine buffer length */ + RSA* rsa = freerdp_key_get_RSA(context->privateKey); res = RSA_private_decrypt((int)Stream_Length(context->commandData), Stream_Buffer(context->commandData), - Stream_Buffer(context->responseData), context->privateKey, padding); + Stream_Buffer(context->responseData), rsa, padding); + RSA_free(rsa); + if (res < 0) { WLog_ERR(TAG, "Failed to decrypt data"); @@ -1417,12 +1419,9 @@ BOOL vgids_init(vgidsContext* ctx, const char* cert, const char* privateKey, con DWORD keymapSize; DWORD fsTableSize; BOOL rc = FALSE; - BIO* certBio = NULL; - BIO* privateKeyBio = NULL; BYTE* kxc = NULL; BYTE* keymap = NULL; BYTE* fsTable = NULL; - EVP_PKEY* pubKey = NULL; vgidsEF* masterEF = NULL; vgidsEF* cardidEF = NULL; vgidsEF* commonEF = NULL; @@ -1452,23 +1451,11 @@ BOOL vgids_init(vgidsContext* ctx, const char* cert, const char* privateKey, con } /* Convert PEM input to DER certificate/public key/private key */ - certBio = BIO_new_mem_buf((const void*)cert, (int)strlen(cert)); - if (!certBio) - goto init_failed; - ctx->certificate = PEM_read_bio_X509(certBio, NULL, NULL, NULL); + ctx->certificate = freerdp_certificate_new_from_pem(cert); if (!ctx->certificate) goto init_failed; - pubKey = X509_get_pubkey(ctx->certificate); - if (!pubKey) - goto init_failed; - ctx->publicKey = EVP_PKEY_get1_RSA(pubKey); - if (!ctx->publicKey) - goto init_failed; - privateKeyBio = BIO_new_mem_buf((const void*)privateKey, (int)strlen(privateKey)); - if (!privateKeyBio) - goto init_failed; - ctx->privateKey = PEM_read_bio_RSAPrivateKey(privateKeyBio, NULL, NULL, NULL); + ctx->privateKey = freerdp_key_new_from_pem(privateKey); if (!ctx->privateKey) goto init_failed; @@ -1481,7 +1468,7 @@ BOOL vgids_init(vgidsContext* ctx, const char* cert, const char* privateKey, con cardidEF = vgids_ef_new(ctx, VGIDS_EFID_CARDID); if (!cardidEF) goto init_failed; - RAND_bytes(cardid, sizeof(cardid)); + winpr_RAND(cardid, sizeof(cardid)); if (!vgids_ef_write_do(cardidEF, VGIDS_DO_CARDID, cardid, sizeof(cardid))) goto init_failed; @@ -1495,7 +1482,10 @@ BOOL vgids_init(vgidsContext* ctx, const char* cert, const char* privateKey, con goto init_failed; /* write container map DO */ - cmrec.wKeyExchangeKeySizeBits = (WORD)(RSA_size(ctx->privateKey) * 8); + const rdpCertInfo* info = freerdp_key_get_info(ctx->privateKey); + if (!info) + goto init_failed; + cmrec.wKeyExchangeKeySizeBits = (WORD)info->ModulusLength; if (!vgids_ef_write_do(commonEF, VGIDS_DO_CMAPFILE, (BYTE*)&cmrec, sizeof(cmrec))) goto init_failed; @@ -1531,9 +1521,6 @@ BOOL vgids_init(vgidsContext* ctx, const char* cert, const char* privateKey, con rc = TRUE; init_failed: - EVP_PKEY_free(pubKey); - BIO_free_all(certBio); - BIO_free_all(privateKeyBio); free(kxc); free(keymap); free(fsTable); @@ -1589,9 +1576,8 @@ void vgids_free(vgidsContext* context) { if (context) { - RSA_free(context->privateKey); - RSA_free(context->publicKey); - X509_free(context->certificate); + freerdp_key_free(context->privateKey); + freerdp_certificate_free(context->certificate); Stream_Free(context->commandData, TRUE); Stream_Free(context->responseData, TRUE); free(context->pin);