Skip to content

Commit b7ff162

Browse files
author
Lauris Kaplinski
committed
Handle PIN status in QSigner::decrypt and DDCryptoBackend
1 parent 1ae8164 commit b7ff162

4 files changed

Lines changed: 49 additions & 15 deletions

File tree

client/CDocSupport.cpp

Lines changed: 35 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -94,14 +94,32 @@ CDocSupport::getCDocFileList(QString filename)
9494
return files;
9595
}
9696

97+
static libcdoc::result_t
98+
getDecryptStatus(const std::vector<uint8_t>& result, QCryptoBackend::PinStatus pin_status)
99+
{
100+
switch (pin_status) {
101+
case QCryptoBackend::PinOK:
102+
return (result.empty()) ? DDCryptoBackend::BACKEND_ERROR : libcdoc::OK;
103+
case QCryptoBackend::PinCanceled:
104+
return DDCryptoBackend::PIN_CANCELED;
105+
case QCryptoBackend::PinIncorrect:
106+
return DDCryptoBackend::PIN_INCORRECT;
107+
case QCryptoBackend::PinLocked:
108+
return DDCryptoBackend::PIN_LOCKED;
109+
default:
110+
return DDCryptoBackend::BACKEND_ERROR;
111+
}
112+
}
113+
97114
libcdoc::result_t
98115
DDCryptoBackend::decryptRSA(std::vector<uint8_t>& result, const std::vector<uint8_t> &data, bool oaep, unsigned int idx)
99116
{
117+
QCryptoBackend::PinStatus pin_status;
100118
QByteArray qkek = qApp->signer()->decrypt([qdata = toByteArray(data), &oaep](QCryptoBackend *backend) {
101119
return backend->decrypt(qdata, oaep);
102-
});
120+
}, pin_status);
103121
result.assign(qkek.cbegin(), qkek.cend());
104-
return (result.empty()) ? BACKEND_ERROR : libcdoc::OK;
122+
return getDecryptStatus(result, pin_status);
105123
}
106124

107125
constexpr std::string_view SHA256_MTH {"http://www.w3.org/2001/04/xmlenc#sha256"};
@@ -115,22 +133,24 @@ libcdoc::result_t
115133
DDCryptoBackend::deriveConcatKDF(std::vector<uint8_t>& dst, const std::vector<uint8_t> &publicKey, const std::string &digest,
116134
const std::vector<uint8_t> &algorithmID, const std::vector<uint8_t> &partyUInfo, const std::vector<uint8_t> &partyVInfo, unsigned int idx)
117135
{
136+
QCryptoBackend::PinStatus pin_status;
118137
QByteArray decryptedKey = qApp->signer()->decrypt([&publicKey, &digest, &algorithmID, &partyUInfo, &partyVInfo](QCryptoBackend *backend) {
119138
return backend->deriveConcatKDF(toByteArray(publicKey), SHA_MTH[digest],
120139
toByteArray(algorithmID), toByteArray(partyUInfo), toByteArray(partyVInfo));
121-
});
140+
}, pin_status);
122141
dst.assign(decryptedKey.cbegin(), decryptedKey.cend());
123-
return (dst.empty()) ? BACKEND_ERROR : libcdoc::OK;
142+
return getDecryptStatus(dst, pin_status);
124143
}
125144

126145
libcdoc::result_t
127146
DDCryptoBackend::deriveHMACExtract(std::vector<uint8_t>& dst, const std::vector<uint8_t> &key_material, const std::vector<uint8_t> &salt, unsigned int idx)
128147
{
148+
QCryptoBackend::PinStatus pin_status;
129149
QByteArray qkekpm = qApp->signer()->decrypt([qkey_material = toByteArray(key_material), qsalt = toByteArray(salt)](QCryptoBackend *backend) {
130150
return backend->deriveHMACExtract(qkey_material, qsalt, ECC_KEY_LEN);
131-
});
151+
}, pin_status);
132152
dst = std::vector<uint8_t>(qkekpm.cbegin(), qkekpm.cend());
133-
return (dst.empty()) ? BACKEND_ERROR : libcdoc::OK;
153+
return getDecryptStatus(dst, pin_status);
134154
}
135155

136156
libcdoc::result_t
@@ -143,8 +163,15 @@ DDCryptoBackend::getSecret(std::vector<uint8_t>& _secret, unsigned int idx)
143163
std::string
144164
DDCryptoBackend::getLastErrorStr(libcdoc::result_t code) const
145165
{
146-
if (code == BACKEND_ERROR) {
147-
return qApp->signer()->getLastErrorStr().toStdString();
166+
switch (code) {
167+
case PIN_CANCELED:
168+
return "PIN entry canceled";
169+
case PIN_INCORRECT:
170+
return "PIN incorrect";
171+
case PIN_LOCKED:
172+
return "PIN locked";
173+
case BACKEND_ERROR:
174+
return qApp->signer()->getLastErrorStr().toStdString();
148175
}
149176
return libcdoc::CryptoBackend::getLastErrorStr(code);
150177
}

client/CDocSupport.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,9 @@ struct DDConfiguration : public libcdoc::Configuration {
5454

5555
struct DDCryptoBackend : public libcdoc::CryptoBackend {
5656
static constexpr int BACKEND_ERROR = -303;
57+
static constexpr int PIN_CANCELED = -304;
58+
static constexpr int PIN_INCORRECT = -305;
59+
static constexpr int PIN_LOCKED = -306;
5760
libcdoc::result_t decryptRSA(std::vector<uint8_t> &result,
5861
const std::vector<uint8_t> &data, bool oaep,
5962
unsigned int idx) override final;

client/QSigner.cpp

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -171,36 +171,40 @@ X509Cert QSigner::cert() const
171171
return X509Cert((const unsigned char*)der.constData(), size_t(der.size()), X509Cert::Der);
172172
}
173173

174-
QByteArray QSigner::decrypt(std::function<QByteArray (QCryptoBackend *)> &&func)
174+
QByteArray QSigner::decrypt(std::function<QByteArray (QCryptoBackend *)> &&func, QCryptoBackend::PinStatus& pin_status)
175175
{
176176
if(!d->lock.tryLockForWrite(10 * 1000))
177177
{
178178
Q_EMIT error(tr("Failed to decrypt document"), tr("Signing/decrypting is already in progress another window."));
179+
pin_status = QCryptoBackend::GeneralError;
179180
return {};
180181
}
181182

182183
if( d->auth.cert().isNull() )
183184
{
184185
Q_EMIT error(tr("Failed to decrypt document"), tr("Authentication certificate is not selected."));
185186
d->lock.unlock();
187+
pin_status = QCryptoBackend::GeneralError;
186188
return {};
187189
}
188190

189-
switch(auto status = QCryptoBackend::PinStatus(login(d->auth)))
191+
switch(pin_status = QCryptoBackend::PinStatus(login(d->auth)))
190192
{
191193
case QCryptoBackend::PinOK: break;
192194
case QCryptoBackend::PinCanceled: return {};
193195
case QCryptoBackend::PinLocked:
194-
Q_EMIT error(tr("Failed to decrypt document"), QCryptoBackend::errorString(status));
196+
Q_EMIT error(tr("Failed to decrypt document"), QCryptoBackend::errorString(pin_status));
195197
return {};
196198
default:
197-
Q_EMIT error(tr("Failed to decrypt document"), tr("Failed to login token") + ' ' + QCryptoBackend::errorString(status));
199+
Q_EMIT error(tr("Failed to decrypt document"), tr("Failed to login token") + ' ' + QCryptoBackend::errorString(pin_status));
198200
return {};
199201
}
200202
QByteArray result = waitFor(func, d->backend);
201203
logout();
202-
if(d->backend->lastError() == QCryptoBackend::PinCanceled)
204+
if(d->backend->lastError() == QCryptoBackend::PinCanceled) {
205+
pin_status = QCryptoBackend::PinCanceled;
203206
return {};
207+
}
204208

205209
if(result.isEmpty())
206210
Q_EMIT error(tr("Failed to decrypt document"), {});

client/QSigner.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,10 +23,10 @@
2323
#include <digidocpp/crypto/Signer.h>
2424

2525
#include <QCryptographicHash>
26+
#include <QCryptoBackend.h>
2627

2728
#include <functional>
2829

29-
class QCryptoBackend;
3030
class QSmartCard;
3131
class QSslKey;
3232
class TokenData;
@@ -41,7 +41,7 @@ class QSigner final: public QThread, public digidoc::Signer
4141

4242
QList<TokenData> cache() const;
4343
digidoc::X509Cert cert() const final;
44-
QByteArray decrypt(std::function<QByteArray (QCryptoBackend *)> &&func);
44+
QByteArray decrypt(std::function<QByteArray (QCryptoBackend *)> &&func, QCryptoBackend::PinStatus& pin_status);
4545
QSslKey key() const;
4646
void logout() const;
4747
void selectCard(const TokenData &token);

0 commit comments

Comments
 (0)