[emu,scard] use rdpCertificate and rdpRsaKey
This commit is contained in:
parent
b5d1ea7138
commit
67bd1d08d3
@ -24,13 +24,12 @@
|
||||
#include <winpr/stream.h>
|
||||
#include <winpr/collections.h>
|
||||
|
||||
#include <openssl/bn.h>
|
||||
#include <openssl/pem.h>
|
||||
#include <openssl/rsa.h>
|
||||
#include <openssl/rand.h>
|
||||
#include <freerdp/crypto/crypto.h>
|
||||
|
||||
#include <zlib.h>
|
||||
|
||||
#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);
|
||||
|
Loading…
Reference in New Issue
Block a user