Skip to content

Instantly share code, notes, and snippets.

@ReFLeXive007
Created October 15, 2019 09:29
Show Gist options
  • Save ReFLeXive007/cedc12435a764c49c05f381b8b8be6ea to your computer and use it in GitHub Desktop.
Save ReFLeXive007/cedc12435a764c49c05f381b8b8be6ea to your computer and use it in GitHub Desktop.
char * cppImportSessionKeyEphem(const char * containerName, const char * containerPin, const char * sessionKey) {
HCRYPTPROV hProv = 0;
bool isPinOk = false;
HCRYPTKEY hResKey = 0;
size_t sessionDataSize = 0;
unsigned char * sessionData = NULL;
BYTE *pData = NULL;
DWORD dwEphemKeyBlobLen= 0;
BYTE *pbEphemKeyBlob = NULL;
HCRYPTKEY hAgreeKey = 0;
ProvKeyInfo pkInfo;
DWORD keyBlobLen = 0;
BYTE *keyBlob = NULL;
char *keyId = NULL;
//
if (CryptAcquireContextA(&hProv, containerName, PROV_NAME, PROV_TYPE, CRYPT_SILENT)){
isPinOk = true;
if (strlen(containerPin) > 0) {
if (!CryptSetProvParam(hProv, PP_KEYEXCHANGE_PIN, (BYTE *)containerPin, 0)){
isPinOk = false;
}
}
}
//
if (isPinOk) {
if (CryptGetUserKey(hProv, AT_KEYEXCHANGE, &hResKey)) {
sessionData = base64_decode(sessionKey, strlen(sessionKey), &sessionDataSize);
pData = (BYTE *) sessionData;
}
}
if (pData) {
// получаем блоб эфемерного ключа
memcpy(&dwEphemKeyBlobLen, pData, sizeof(DWORD));
pData += sizeof(DWORD);
pbEphemKeyBlob = pData;
pData += dwEphemKeyBlobLen;
// получаем ключ согласования
if (CryptImportKey(hProv, pbEphemKeyBlob, dwEphemKeyBlobLen, hResKey, 0, &hAgreeKey)) {
if (CryptAcquireContext(&pkInfo.provider, NULL, PROV_NAME, PROV_TYPE, CRYPT_VERIFYCONTEXT | CRYPT_SILENT)) {
// получаем блоб ключа
memcpy(&keyBlobLen, pData, sizeof(DWORD));
pData += sizeof(DWORD);
keyBlob = pData;
pData += keyBlobLen;
if (CryptImportKey(pkInfo.provider, keyBlob, keyBlobLen, hAgreeKey, CRYPT_EXPORTABLE, &pkInfo.key)) {
memcpy(&pkInfo.IVLen, pData, sizeof(DWORD));
pData += sizeof(DWORD);
if (pkInfo.IVLen <= sizeof(pkInfo.IV)) {
memcpy(&pkInfo.IV, pData, pkInfo.IVLen);
//
if (CryptSetKeyParam(pkInfo.key, KP_IV, pkInfo.IV, 0)) {
keyId = ProvKeyInfoToB64(pkInfo);
}
}
}
}
}
}
if (hResKey) {
CryptDestroyKey(hResKey);
}
if (hAgreeKey) {
CryptDestroyKey(hAgreeKey);
}
if (hProv) {
CryptReleaseContext(hProv, 0);
}
if (sessionData) {
free(sessionData);
}
return keyId;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment