Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
34 changes: 18 additions & 16 deletions client/QCNG.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ QCNG::Status QCNG::login(const TokenData &token)
std::unique_ptr<Private> p = std::make_unique<Private>();
if(FAILED(NCryptOpenStorageProvider(&p->prov, LPCWSTR(token.data(u"provider"_s).toString().utf16()), 0)))
return DeviceError;
if(FAILED(NCryptOpenKey(p->prov, &p->key, LPWSTR(token.data(u"key"_s).toString().utf16()),
if(FAILED(NCryptOpenKey(p->prov, &p->key, LPCWSTR(token.data(u"key"_s).toString().utf16()),
token.data(u"spec"_s).value<DWORD>(), 0)))
return DeviceError;
// https://docs.microsoft.com/en-us/archive/blogs/alejacma/smart-cards-pin-gets-cached
Expand Down Expand Up @@ -115,12 +115,12 @@ QByteArray QCNG::deriveConcatKDF(const QByteArray &publicKey, QCryptographicHash
const QByteArray &algorithmID, const QByteArray &partyUInfo, const QByteArray &partyVInfo) const
{
return derive(publicKey, [&](NCRYPT_SECRET_HANDLE sharedSecret, QByteArray &derived) {
std::array paramValues{
BCryptBuffer{ULONG(algorithmID.size()), KDF_ALGORITHMID, PBYTE(algorithmID.data())},
BCryptBuffer{ULONG(partyUInfo.size()), KDF_PARTYUINFO, PBYTE(partyUInfo.data())},
BCryptBuffer{ULONG(partyVInfo.size()), KDF_PARTYVINFO, PBYTE(partyVInfo.data())},
BCryptBuffer{ULONG(sizeof(BCRYPT_SHA256_ALGORITHM)), KDF_HASH_ALGORITHM, PBYTE(BCRYPT_SHA256_ALGORITHM)}
};
auto paramValues = std::to_array<BCryptBuffer>({
{ULONG(algorithmID.size()), KDF_ALGORITHMID, PBYTE(algorithmID.data())},
{ULONG(partyUInfo.size()), KDF_PARTYUINFO, PBYTE(partyUInfo.data())},
{ULONG(partyVInfo.size()), KDF_PARTYVINFO, PBYTE(partyVInfo.data())},
{ULONG(sizeof(BCRYPT_SHA256_ALGORITHM)), KDF_HASH_ALGORITHM, PBYTE(BCRYPT_SHA256_ALGORITHM)}
});
switch(digest)
{
case QCryptographicHash::Sha256: break;
Expand All @@ -145,10 +145,10 @@ QByteArray QCNG::deriveConcatKDF(const QByteArray &publicKey, QCryptographicHash
QByteArray QCNG::deriveHMACExtract(const QByteArray &publicKey, const QByteArray &salt, int keySize) const
{
return derive(publicKey, [&](NCRYPT_SECRET_HANDLE sharedSecret, QByteArray &derived) {
std::array paramValues{
BCryptBuffer{ULONG(salt.size()), KDF_HMAC_KEY, PBYTE(salt.data())},
BCryptBuffer{ULONG(sizeof(BCRYPT_SHA256_ALGORITHM)), KDF_HASH_ALGORITHM, PBYTE(BCRYPT_SHA256_ALGORITHM)},
};
auto paramValues = std::to_array<BCryptBuffer>({
{ULONG(salt.size()), KDF_HMAC_KEY, PBYTE(salt.data())},
{ULONG(sizeof(BCRYPT_SHA256_ALGORITHM)), KDF_HASH_ALGORITHM, PBYTE(BCRYPT_SHA256_ALGORITHM)},
});
BCryptBufferDesc params{BCRYPTBUFFER_VERSION, ULONG(paramValues.size()), paramValues.data()};
DWORD size = 0;
SECURITY_STATUS err = 0;
Expand Down Expand Up @@ -185,14 +185,15 @@ QList<TokenData> QCNG::tokens()
{
QList<TokenData> result;
auto prop = [](NCRYPT_HANDLE handle, LPCWSTR param) -> QByteArray {
QByteArray data;
if(!handle)
return {};
return data;
DWORD size {};
if(NCryptGetProperty(handle, param, nullptr, 0, &size, 0))
return {};
QByteArray data(int(size), '\0');
return data;
data.resize(int(size));
if(NCryptGetProperty(handle, param, PBYTE(data.data()), size, &size, 0))
return {};
data.clear();
return data;
};
auto enumKeys = [&result, &prop](const QString &provider, QString reader = {}) {
Expand Down Expand Up @@ -290,7 +291,8 @@ QByteArray QCNG::sign(QCryptographicHash::Algorithm type, const QByteArray &dige
BCRYPT_PKCS1_PADDING_INFO rsaPKCS1 { rsaPSS.pszAlgId };
DWORD size {};
QString algo(5, '\0');
NCryptGetProperty(key, NCRYPT_ALGORITHM_GROUP_PROPERTY, PBYTE(algo.data()), DWORD((algo.size() + 1) * 2), &size, 0);
if(auto err = NCryptGetProperty(key, NCRYPT_ALGORITHM_GROUP_PROPERTY, PBYTE(algo.data()), DWORD((algo.size() + 1) * 2), &size, 0))
return err;
algo.resize(size/2 - 1);
bool isRSA = algo == QLatin1String("RSA");
DWORD padding {};
Expand Down
Loading