Skip to content
Open
Show file tree
Hide file tree
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
46 changes: 20 additions & 26 deletions src/controller/command-handlers/authenticate.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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<JsonWebSignatureAlgorithm, QCryptographicHash::Algorithm>
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).
Expand Down Expand Up @@ -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);

Expand Down
7 changes: 1 addition & 6 deletions src/controller/command-handlers/sign.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -98,12 +98,7 @@ void Sign::emitCertificatesReady(const std::vector<EidCertificateAndPinInfo>& 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)}};
Expand Down
11 changes: 9 additions & 2 deletions src/controller/command-handlers/signauthutils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -69,11 +69,17 @@ template QString validateAndGetArgument<QString>(const QString& argName, const Q
template QByteArray validateAndGetArgument<QByteArray>(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)
Expand All @@ -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)
Expand Down
2 changes: 1 addition & 1 deletion src/controller/command-handlers/signauthutils.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,6 @@ extern template QString validateAndGetArgument<QString>(const QString& argName,
extern template QByteArray
validateAndGetArgument<QByteArray>(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);
Loading