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
21 changes: 21 additions & 0 deletions src/controller/command-handlers/signauthutils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,12 @@

#include "pcsc-cpp/pcsc-cpp-utils.hpp"

#ifdef Q_OS_WIN
#include <windows.h>
#elif defined(Q_OS_UNIX)
#include <sys/mman.h>
#endif

using namespace electronic_id;

// Take argument names by copy/move as they will be modified.
Expand Down Expand Up @@ -84,6 +90,21 @@ pcsc_cpp::byte_vector getPin(const ElectronicID& eid, WebEidUI* window)

REQUIRE_NON_NULL(window)

// Lock the reserved buffer's pages in physical memory so the PIN is never written to the
// swap/page file under normal memory pressure. This does NOT protect against suspend-to-disk
// hibernation, which snapshots all of RAM -- including locked pages -- to disk regardless;
// that can only be mitigated at the OS level (e.g. encrypted hibernation image).
// The buffer never grows past the capacity reserved above (enforced by CommandApdu::verify(),
// which throws rather than let the vector holding the PIN reallocate), so the locked address
// range stays valid for the buffer's whole lifetime, including after it is moved into the
// smart card call chain. The process exits shortly after each command, which releases the
// lock, so no matching unlock call is needed.
#ifdef Q_OS_WIN
VirtualLock(pin.data(), pin.capacity());
#elif defined(Q_OS_UNIX)
mlock(pin.data(), pin.capacity());
#endif

QString pinQStr = window->getPin();
if (pinQStr.isEmpty()) {
THROW(ProgrammingError, "Empty PIN");
Expand Down
6 changes: 6 additions & 0 deletions src/ui/webeiddialog.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
#include "webeiddialog.hpp"
#include "application.hpp"
#include "languageselect.hpp"
#include "utils/erasedata.hpp"
#include "utils/qt_comp.hpp"

#include "ui_dialog.h"
Expand Down Expand Up @@ -178,6 +179,11 @@ WebEidDialog::WebEidDialog(QWidget* parent) : WebEidUI(parent), ui(new Private)

WebEidDialog::~WebEidDialog()
{
// Zero any PIN left in the cache in case the dialog is destroyed (e.g. cancelled) before
// getPin() was called to consume it.
if (!pin.isEmpty()) {
eraseData(pin);
}
delete ui;
}

Expand Down
Loading