narkive is for sale. Interested? (dismiss)
Discussion:
CardGetChallenge; How To Compute Response
(too old to reply)
r***@omegusprime.com
2015-04-12 17:35:17 UTC
Permalink
Hello All,

I'm using the CardGetChallenge but don't see any documentation on *how to* compute the response to pass to CardAuthenticateChallenge.

Can someone give a simple code example or an online article explaining the process? I'll also take a book suggestion too.

REF: https://msdn.microsoft.com/en-us/library/dd627616(v=vs.85).aspx

- Rashad Rivera
r***@omegusprime.com
2015-04-26 05:48:56 UTC
Permalink
I'm more than shocked that no one knows how to do this. Its really depressing to also see that not even Microsoft was incline to answer. Very disappointed in this community and have never seen such a poor display of support.
r***@gmail.com
2015-09-12 02:19:55 UTC
Permalink
So it took 5 months and $1,800 shillings before I got the following 20 or so lines of code. A word of advice; don't pay Microsoft for something they clearly neglected.


REFERENCE: https://social.msdn.microsoft.com/Forums/en-US/7b8f77fc-23e5-4cb3-b75f-774f8da5444a/cardgetchallenge-how-to-compute-response?forum=wdk&prof=required

THIS IS A C++ P/Invoke CODE SAMPLE

header.h
#define CHECK_ERROR_MSG(X) if(X != NO_ERROR) { goto error; }

code.cpp

__declspec(dllexport) DWORD WINAPI MgScCardCalculateResponse(
__in_bcount(cbPin) PBYTE pbChallenge,
__in DWORD cbChallenge,
__in_bcount(cbPin) PBYTE pbAdminPin,
__in DWORD cbAdminPin,
__deref_out_bcount(*pcbChallengeData) PBYTE *ppbResponseData,
__out PDWORD cbResponseData) {


HCRYPTPROV crypt_handle = NULL;
DWORD dwMode = CRYPT_MODE_ECB;
HCRYPTKEY key_handle = 0;
const size_t DES_HEADER_LENGTH = 12;

HRESULT returnCode = NO_ERROR;
HRESULT ret;

BYTE blob[] = {
0x08, 0x02, 0x00, 0x00, 0x03, 0x66, 0x00, 0x00,
0x18, 0x00, 0x00, 0x00,

0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
};

*cbResponseData = cbChallenge;
*ppbResponseData = (PBYTE)_Alloc(cbChallenge);

memcpy(blob + DES_HEADER_LENGTH, pbAdminPin, cbAdminPin);
memcpy(*ppbResponseData, pbChallenge, sizeof(BYTE) * cbChallenge);

// Get Cryto-context
ret = CryptAcquireContext(&crypt_handle, NULL, L"Microsoft Enhanced Cryptographic Provider V1.0", PROV_RSA_FULL, CRYPT_VERIFYCONTEXT);
CHECK_ERROR_MSG(!ret);

// Import Deskey
ret = CryptImportKey(crypt_handle, blob, sizeof(blob), 0, 0, &key_handle);
CHECK_ERROR_MSG(!ret);

// Set Deskey
ret = CryptSetKeyParam(key_handle, KP_MODE, (BYTE *)&dwMode, 0);
CHECK_ERROR_MSG(!ret);

// Encrypt data
DWORD length = *cbResponseData;
ret = CryptEncrypt(key_handle, 0, FALSE, 0, *ppbResponseData, &length, length);
CHECK_ERROR_MSG(!ret);

goto cleanup;

error:
returnCode = ret;

cleanup:

if (key_handle)
{
CryptDestroyKey(key_handle);
key_handle = NULL;
}

if (crypt_handle)
{
CryptReleaseContext(crypt_handle, 0);
}

return returnCode;
}

Loading...