Thales' cellular IoT products business is now part of Telit Cinterion, find out more.

You are here

Crypto API fails with my new Gemalto SIM | Telit Cinterion IoT Developer Community

September 1, 2016 - 6:10am, 2862 views

I purchased the card to be used programmatically.

While I am able to load a certificate, sign and encrypt with it, decryption fails.

Here is my test code:

int main()

{

#define MY_ENCODING_TYPE  (PKCS_7_ASN_ENCODING | X509_ASN_ENCODING)

HCRYPTPROV smprov = 0;

HCERTSTORE smstore = 0;

PCCERT_CONTEXT smcertx = 0;

BOOL S = false;

vector<BYTE> databuffer;

databuffer.resize(100);

if (!CryptAcquireContext(&smprov, 0, MS_SCARD_PROV_W, PROV_RSA_FULL, 0))

return 0;

DWORD sz = sizeof(smstore);

CryptGetProvParam(smprov, PP_USER_CERTSTORE, (BYTE*)&smstore, &sz, 0);

smcertx = CryptUIDlgSelectCertificateFromStore(smstore, 0, 0, 0, 0, 0, 0);

if (1)

{

// Parameters

CRYPT_SIGN_MESSAGE_PARA SignMessagePara = { 0 };

SignMessagePara.cbSize = sizeof(CRYPT_SIGN_MESSAGE_PARA);

SignMessagePara.HashAlgorithm.pszObjId = szOID_RSA_SHA256RSA;

SignMessagePara.pSigningCert = smcertx;

SignMessagePara.dwMsgEncodingType = MY_ENCODING_TYPE;

SignMessagePara.cMsgCert = 1;

SignMessagePara.rgpMsgCert = &smcertx;

const BYTE *rgpbToBeSigned[1];

DWORD rgcbToBeSigned[1];

rgpbToBeSigned[0] = databuffer.data();

DWORD cbContent = (DWORD)databuffer.size();

rgcbToBeSigned[0] = cbContent;

CRYPT_DATA_BLOB blob = { databuffer.size(),databuffer.data() };

BOOL Detached = false;

// Get bytes

S = CryptSignMessage(&SignMessagePara, Detached, 1, rgpbToBeSigned, rgcbToBeSigned, NULL, &blob.cbData);

if (S)

{

vector<char> enc(blob.cbData + 100);

S = CryptSignMessage(&SignMessagePara, Detached, 1, rgpbToBeSigned, rgcbToBeSigned, (BYTE*)enc.data(), &blob.cbData);

if (S)

{

// OK, works

}

}

}

if (1)

{

CRYPT_ENCRYPT_MESSAGE_PARA EncryptMessagePara = { 0 };

EncryptMessagePara.cbSize = sizeof(EncryptMessagePara);

EncryptMessagePara.dwMsgEncodingType = MY_ENCODING_TYPE;

EncryptMessagePara.ContentEncryptionAlgorithm.pszObjId = szOID_NIST_AES256_CBC;

sz = 0;

S = CryptEncryptMessage(&EncryptMessagePara, 1, (PCCERT_CONTEXT*)&smcertx, databuffer.data(), (DWORD)databuffer.size(), 0, &sz);

vector<BYTE> result(sz);

S = CryptEncryptMessage(&EncryptMessagePara, 1, (PCCERT_CONTEXT*)&smcertx, databuffer.data(), (DWORD)databuffer.size(), (BYTE*)result.data(), &sz);

// Test decrypt

if (S)

{

CRYPT_DECRYPT_MESSAGE_PARA DecryptMessagePara = { 0 };

DecryptMessagePara.cbSize = sizeof(DecryptMessagePara);

DecryptMessagePara.rghCertStore = &smstore;

DecryptMessagePara.cCertStore = 1;

DecryptMessagePara.dwMsgAndCertEncodingType = MY_ENCODING_TYPE;

sz = 0;

auto Z = CryptDecryptMessage(&DecryptMessagePara, result.data(), result.size(), 0, &sz, 0);

vector<BYTE> result2(sz);

S = CryptDecryptMessage(&DecryptMessagePara, result.data(), result.size(), result2.data(), &sz, &smcertx);

// Fails

}

}

    return 0;

}

The last call to CryptDecryptMessage fails with 

SCARD_E_UNSUPPORTED_FEATURE0x80100022L

This smart card does not support the requested feature.

What am I doing wrong?

Thanks.