From 598ecf216b5115fdb2e60d4546e0d7d3e10bd904 Mon Sep 17 00:00:00 2001 From: Raul Metsma Date: Mon, 25 May 2026 10:54:54 +0300 Subject: [PATCH] Be explicit that we sign encoded URL format + minor code cleanup/reuse WE2-1241 Signed-off-by: Raul Metsma --- .../command-handlers/authenticate.cpp | 46 ++++++++----------- src/controller/command-handlers/sign.cpp | 7 +-- .../command-handlers/signauthutils.cpp | 11 ++++- .../command-handlers/signauthutils.hpp | 2 +- 4 files changed, 31 insertions(+), 35 deletions(-) diff --git a/src/controller/command-handlers/authenticate.cpp b/src/controller/command-handlers/authenticate.cpp index 92f08cd0..fcb2661d 100644 --- a/src/controller/command-handlers/authenticate.cpp +++ b/src/controller/command-handlers/authenticate.cpp @@ -58,28 +58,27 @@ QVariantMap createAuthenticationToken(const QString& signatureAlgorithm, }; } -QByteArray createSignature(const QString& origin, const QString& challengeNonce, +QByteArray createSignature(const QByteArray& origin, const QString& challengeNonce, const ElectronicID& eid, pcsc_cpp::byte_vector&& pin) { - static const std::map - SIGNATURE_ALGO_TO_HASH { - {JsonWebSignatureAlgorithm::RS256, QCryptographicHash::Sha256}, - {JsonWebSignatureAlgorithm::PS256, QCryptographicHash::Sha256}, - {JsonWebSignatureAlgorithm::ES256, QCryptographicHash::Sha256}, - {JsonWebSignatureAlgorithm::ES384, QCryptographicHash::Sha384}, - {JsonWebSignatureAlgorithm::ES512, QCryptographicHash::Sha512}, - }; - - if (!SIGNATURE_ALGO_TO_HASH.count(eid.authSignatureAlgorithm())) { - THROW(ProgrammingError, - "Hash algorithm mapping missing for signature algorithm " - + std::string(eid.authSignatureAlgorithm())); - } - - const auto hashAlgo = SIGNATURE_ALGO_TO_HASH.at(eid.authSignatureAlgorithm()); + const auto hashAlgo = [algo = eid.authSignatureAlgorithm()] { + switch (algo) { + case JsonWebSignatureAlgorithm::RS256: + case JsonWebSignatureAlgorithm::PS256: + case JsonWebSignatureAlgorithm::ES256: + return QCryptographicHash::Sha256; + case JsonWebSignatureAlgorithm::ES384: + return QCryptographicHash::Sha384; + case JsonWebSignatureAlgorithm::ES512: + return QCryptographicHash::Sha512; + default: + THROW(ProgrammingError, + "Hash algorithm mapping missing for signature algorithm " + std::string(algo)); + } + }(); // Take the hash of the origin and nonce to ensure field separation. - const auto originHash = QCryptographicHash::hash(origin.toUtf8(), hashAlgo); + const auto originHash = QCryptographicHash::hash(origin, hashAlgo); const auto challengeNonceHash = QCryptographicHash::hash(challengeNonce.toUtf8(), hashAlgo); // The value that is signed is hash(origin)+hash(challenge). @@ -125,14 +124,9 @@ QVariantMap Authenticate::onConfirm(WebEidUI* window, try { const auto signatureAlgorithm = QString::fromStdString(certAndPinInfo.eid->authSignatureAlgorithm()); - pcsc_cpp::byte_vector pin; - // Reserve space for APDU overhead (5 bytes) + PIN padding (16 bytes) to prevent PIN memory - // reallocation. The 16-byte limit comes from the max PIN length of 12 bytes across all card - // implementations in lib/libelectronic-id/src/electronic-ids/pcsc/. - pin.reserve(5 + 16); - getPin(pin, *certAndPinInfo.eid, window); - const auto signature = - createSignature(origin.url(), challengeNonce, *certAndPinInfo.eid, std::move(pin)); + auto pin = getPin(*certAndPinInfo.eid, window); + const auto signature = createSignature(origin.toEncoded(), challengeNonce, + *certAndPinInfo.eid, std::move(pin)); return createAuthenticationToken(signatureAlgorithm, certAndPinInfo.certificateBytesInDer, signature); diff --git a/src/controller/command-handlers/sign.cpp b/src/controller/command-handlers/sign.cpp index 87c81ee5..d861741b 100644 --- a/src/controller/command-handlers/sign.cpp +++ b/src/controller/command-handlers/sign.cpp @@ -98,12 +98,7 @@ void Sign::emitCertificatesReady(const std::vector& ce QVariantMap Sign::onConfirm(WebEidUI* window, const EidCertificateAndPinInfo& certAndPinInfo) { try { - pcsc_cpp::byte_vector pin; - // Reserve space for APDU overhead (5 bytes) + PIN padding (16 bytes) to prevent PIN memory - // reallocation. The 16-byte limit comes from the max PIN length of 12 bytes across all card - // implementations in lib/libelectronic-id/src/electronic-ids/pcsc/. - pin.reserve(5 + 16); - getPin(pin, *certAndPinInfo.eid, window); + auto pin = getPin(*certAndPinInfo.eid, window); auto signature = signHash(*certAndPinInfo.eid, std::move(pin), docHash, hashAlgo); return {{QStringLiteral("signature"), std::move(signature.first)}, {QStringLiteral("signatureAlgorithm"), std::move(signature.second)}}; diff --git a/src/controller/command-handlers/signauthutils.cpp b/src/controller/command-handlers/signauthutils.cpp index 8cc023d6..d1574316 100644 --- a/src/controller/command-handlers/signauthutils.cpp +++ b/src/controller/command-handlers/signauthutils.cpp @@ -69,11 +69,17 @@ template QString validateAndGetArgument(const QString& argName, const Q template QByteArray validateAndGetArgument(const QString& argName, const QVariantMap& args, bool allowNull); -void getPin(pcsc_cpp::byte_vector& pin, const ElectronicID& eid, WebEidUI* window) +pcsc_cpp::byte_vector getPin(const ElectronicID& eid, WebEidUI* window) { + pcsc_cpp::byte_vector pin; + // Reserve space for APDU overhead (5 bytes) + PIN padding (16 bytes) to prevent PIN memory + // reallocation. The 16-byte limit comes from the max PIN length of 12 bytes across all card + // implementations in lib/libelectronic-id/src/electronic-ids/pcsc/. + pin.reserve(5 + 16); + // If the reader has a PIN pad or when enternal PIN dialog is used, do nothing. if (eid.smartcard().readerHasPinPad() || eid.providesExternalPinDialog()) { - return; + return pin; } REQUIRE_NON_NULL(window) @@ -91,6 +97,7 @@ void getPin(pcsc_cpp::byte_vector& pin, const ElectronicID& eid, WebEidUI* windo } eraseData(pinQStr); + return pin; } QVariantMap signatureAlgoToVariantMap(const SignatureAlgorithm signatureAlgo) diff --git a/src/controller/command-handlers/signauthutils.hpp b/src/controller/command-handlers/signauthutils.hpp index 2aaa2b38..ff53b845 100644 --- a/src/controller/command-handlers/signauthutils.hpp +++ b/src/controller/command-handlers/signauthutils.hpp @@ -45,6 +45,6 @@ extern template QString validateAndGetArgument(const QString& argName, extern template QByteArray validateAndGetArgument(const QString& argName, const QVariantMap& args, bool allowNull); -void getPin(pcsc_cpp::byte_vector& pin, const electronic_id::ElectronicID& eid, WebEidUI* window); +pcsc_cpp::byte_vector getPin(const electronic_id::ElectronicID& eid, WebEidUI* window); QVariantMap signatureAlgoToVariantMap(const electronic_id::SignatureAlgorithm signatureAlgo);