diff --git a/client/QCNG.cpp b/client/QCNG.cpp index 7da8c4b1a..9e0e5fb7f 100644 --- a/client/QCNG.cpp +++ b/client/QCNG.cpp @@ -57,7 +57,7 @@ QCNG::Status QCNG::login(const TokenData &token) std::unique_ptr p = std::make_unique(); 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(), 0))) return DeviceError; // https://docs.microsoft.com/en-us/archive/blogs/alejacma/smart-cards-pin-gets-cached @@ -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({ + {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; @@ -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({ + {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; @@ -185,14 +185,15 @@ QList QCNG::tokens() { QList 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 = {}) { @@ -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 {};