File indexing completed on 2024-05-19 15:50:35
0001 /* 0002 * Copyright (C) 2004 Justin Karneges <justin@affinix.com> 0003 * Copyright (C) 2006-2007 Alon Bar-Lev <alon.barlev@gmail.com> 0004 * 0005 * This library is free software; you can redistribute it and/or 0006 * modify it under the terms of the GNU Lesser General Public 0007 * License as published by the Free Software Foundation; either 0008 * version 2.1 of the License, or (at your option) any later version. 0009 * 0010 * This library is distributed in the hope that it will be useful, 0011 * but WITHANY WARRANTY; without even the implied warranty of 0012 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 0013 * Lesser General Public License for more details. 0014 * 0015 * You should have received a copy of the GNU Lesser General Public 0016 * License along with this library; if not, write to the Free Software 0017 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA 0018 * 0019 */ 0020 0021 #include <QtCrypto> 0022 #include <qcaprovider.h> 0023 #include <qplatformdefs.h> 0024 0025 #include <QHash> 0026 #include <QMutexLocker> 0027 #include <QtPlugin> 0028 0029 #include <pkcs11-helper-1.0/pkcs11h-certificate.h> 0030 #include <pkcs11-helper-1.0/pkcs11h-token.h> 0031 0032 using namespace QCA; 0033 0034 // qPrintable is ASCII only!!! 0035 #define myPrintable(s) (s).toUtf8().constData() 0036 0037 static inline QString certificateHash(const Certificate &cert) 0038 { 0039 if (cert.isNull()) { 0040 return QString(); 0041 } else { 0042 return Hash(QStringLiteral("sha1")).hashToString(cert.toDER()); 0043 } 0044 } 0045 0046 //---------------------------------------------------------------------------- 0047 // pkcs11Provider 0048 //---------------------------------------------------------------------------- 0049 class pkcs11Provider : public Provider 0050 { 0051 private: 0052 static const int _CONFIG_MAX_PROVIDERS; 0053 0054 bool _lowLevelInitialized; 0055 bool _slotEventsActive; 0056 bool _slotEventsLowLevelActive; 0057 QStringList _providers; 0058 0059 public: 0060 bool _allowLoadRootCA; 0061 0062 public: 0063 pkcs11Provider(); 0064 ~pkcs11Provider() override; 0065 0066 public: 0067 int qcaVersion() const override; 0068 0069 void init() override; 0070 0071 void deinit() override; 0072 0073 QString name() const override; 0074 0075 QStringList features() const override; 0076 0077 Context *createContext(const QString &type) override; 0078 0079 void startSlotEvents(); 0080 0081 void stopSlotEvents(); 0082 0083 QVariantMap defaultConfig() const override; 0084 0085 void configChanged(const QVariantMap &config) override; 0086 0087 protected: 0088 static void __logHook(void *const global_data, const unsigned flags, const char *const format, va_list args); 0089 0090 static void __slotEventHook(void *const global_data); 0091 0092 static PKCS11H_BOOL __tokenPromptHook(void *const global_data, 0093 void *const user_data, 0094 const pkcs11h_token_id_t token, 0095 const unsigned retry); 0096 0097 static PKCS11H_BOOL __pinPromptHook(void *const global_data, 0098 void *const user_data, 0099 const pkcs11h_token_id_t token, 0100 const unsigned retry, 0101 char *const pin, 0102 const size_t pin_max); 0103 0104 void _logHook(const unsigned flags, const char *const format, va_list args); 0105 0106 void _slotEventHook(); 0107 0108 PKCS11H_BOOL 0109 _tokenPromptHook(void *const user_data, const pkcs11h_token_id_t token); 0110 0111 PKCS11H_BOOL 0112 _pinPromptHook(void *const user_data, const pkcs11h_token_id_t token, char *const pin, const size_t pin_max); 0113 }; 0114 0115 namespace pkcs11QCAPlugin { 0116 0117 class pkcs11KeyStoreEntryContext; 0118 0119 //---------------------------------------------------------------------------- 0120 // pkcs11KeyStoreListContext 0121 //---------------------------------------------------------------------------- 0122 class pkcs11KeyStoreListContext : public KeyStoreListContext 0123 { 0124 Q_OBJECT 0125 0126 private: 0127 struct pkcs11KeyStoreItem 0128 { 0129 protected: 0130 int _id; 0131 pkcs11h_token_id_t _token_id; 0132 QList<Certificate> _certs; 0133 0134 public: 0135 pkcs11KeyStoreItem(const int id, const pkcs11h_token_id_t token_id) 0136 { 0137 _id = id; 0138 ; 0139 pkcs11h_token_duplicateTokenId(&_token_id, token_id); 0140 } 0141 0142 ~pkcs11KeyStoreItem() 0143 { 0144 if (_token_id != nullptr) { 0145 pkcs11h_token_freeTokenId(_token_id); 0146 } 0147 } 0148 0149 pkcs11KeyStoreItem(const pkcs11KeyStoreItem &) = delete; 0150 pkcs11KeyStoreItem &operator=(const pkcs11KeyStoreItem &) = delete; 0151 0152 inline int id() const 0153 { 0154 return _id; 0155 } 0156 0157 inline pkcs11h_token_id_t tokenId() const 0158 { 0159 return _token_id; 0160 } 0161 0162 void registerCertificates(const QList<Certificate> &certs) 0163 { 0164 foreach (Certificate i, certs) { 0165 if (std::find(_certs.begin(), _certs.end(), i) == _certs.end()) { 0166 _certs += i; 0167 } 0168 } 0169 } 0170 0171 QMap<QString, QString> friendlyNames() 0172 { 0173 const QStringList names = makeFriendlyNames(_certs); 0174 QMap<QString, QString> friendlyNames; 0175 0176 for (int i = 0; i < names.size(); i++) { 0177 friendlyNames.insert(certificateHash(_certs[i]), names[i]); 0178 } 0179 0180 return friendlyNames; 0181 } 0182 }; 0183 int _last_id; 0184 typedef QList<pkcs11KeyStoreItem *> _stores_t; 0185 _stores_t _stores; 0186 QHash<int, pkcs11KeyStoreItem *> _storesById; 0187 QMutex _mutexStores; 0188 bool _initialized; 0189 0190 public: 0191 pkcs11KeyStoreListContext(Provider *p); 0192 0193 ~pkcs11KeyStoreListContext() override; 0194 0195 Provider::Context *clone() const override; 0196 0197 public: 0198 void start() override; 0199 0200 void setUpdatesEnabled(bool enabled) override; 0201 0202 KeyStoreEntryContext *entry(int id, const QString &entryId) override; 0203 0204 KeyStoreEntryContext *entryPassive(const QString &serialized) override; 0205 0206 KeyStore::Type type(int id) const override; 0207 0208 QString storeId(int id) const override; 0209 0210 QString name(int id) const override; 0211 0212 QList<KeyStoreEntry::Type> entryTypes(int id) const override; 0213 0214 QList<int> keyStores() override; 0215 0216 QList<KeyStoreEntryContext *> entryList(int id) override; 0217 0218 bool _tokenPrompt(void *const user_data, const pkcs11h_token_id_t token_id); 0219 0220 bool _pinPrompt(void *const user_data, const pkcs11h_token_id_t token_id, SecureArray &pin); 0221 0222 void _emit_diagnosticText(const QString &t); 0223 0224 private Q_SLOTS: 0225 void doReady(); 0226 0227 void doUpdated(); 0228 0229 private: 0230 pkcs11KeyStoreItem *_registerTokenId(const pkcs11h_token_id_t token_id); 0231 0232 void _clearStores(); 0233 0234 pkcs11KeyStoreEntryContext *_keyStoreEntryByCertificateId(const pkcs11h_certificate_id_t certificate_id, 0235 const bool has_private, 0236 const CertificateChain &chain, 0237 const QString &description) const; 0238 0239 QString _tokenId2storeId(const pkcs11h_token_id_t token_id) const; 0240 0241 QString _serializeCertificate(const pkcs11h_certificate_id_t certificate_id, 0242 const CertificateChain &chain, 0243 const bool has_private) const; 0244 0245 void _deserializeCertificate(const QString &from, 0246 pkcs11h_certificate_id_t *const p_certificate_id, 0247 bool *const p_has_private, 0248 CertificateChain &chain) const; 0249 0250 QString _escapeString(const QString &from) const; 0251 0252 QString _unescapeString(const QString &from) const; 0253 }; 0254 0255 static pkcs11KeyStoreListContext *s_keyStoreList = nullptr; 0256 0257 //---------------------------------------------------------------------------- 0258 // pkcs11Exception 0259 //---------------------------------------------------------------------------- 0260 class pkcs11Exception 0261 { 0262 private: 0263 CK_RV _rv; 0264 QString _msg; 0265 0266 private: 0267 pkcs11Exception() 0268 { 0269 } 0270 0271 public: 0272 pkcs11Exception(const CK_RV rv, const QString &msg) 0273 { 0274 _rv = rv; 0275 _msg = msg; 0276 } 0277 0278 CK_RV 0279 rv() const 0280 { 0281 return _rv; 0282 } 0283 0284 QString message() const 0285 { 0286 return _msg + QStringLiteral(" ") + QString::fromLatin1(pkcs11h_getMessage(_rv)); 0287 } 0288 }; 0289 0290 //---------------------------------------------------------------------------- 0291 // pkcs11RSAContext 0292 //---------------------------------------------------------------------------- 0293 class pkcs11RSAContext : public RSAContext 0294 { 0295 Q_OBJECT 0296 0297 private: 0298 bool _has_privateKeyRole; 0299 pkcs11h_certificate_id_t _pkcs11h_certificate_id; 0300 pkcs11h_certificate_t _pkcs11h_certificate; 0301 RSAPublicKey _pubkey; 0302 QString _serialized; 0303 0304 struct _sign_data_s 0305 { 0306 SignatureAlgorithm alg; 0307 Hash *hash; 0308 QByteArray raw; 0309 0310 _sign_data_s() 0311 { 0312 hash = nullptr; 0313 } 0314 } _sign_data; 0315 0316 public: 0317 pkcs11RSAContext(Provider *p, 0318 const pkcs11h_certificate_id_t pkcs11h_certificate_id, 0319 const QString &serialized, 0320 const RSAPublicKey &pubkey) 0321 : RSAContext(p) 0322 { 0323 CK_RV rv; 0324 0325 QCA_logTextMessage(QStringLiteral("pkcs11RSAContext::pkcs11RSAContext1 - entry"), Logger::Debug); 0326 0327 _has_privateKeyRole = true; 0328 _pkcs11h_certificate_id = nullptr; 0329 _pkcs11h_certificate = nullptr; 0330 _pubkey = pubkey; 0331 _serialized = serialized; 0332 _clearSign(); 0333 0334 if ((rv = pkcs11h_certificate_duplicateCertificateId(&_pkcs11h_certificate_id, pkcs11h_certificate_id)) != 0335 CKR_OK) { 0336 throw pkcs11Exception(rv, QStringLiteral("Memory error")); 0337 } 0338 0339 QCA_logTextMessage(QStringLiteral("pkcs11RSAContext::pkcs11RSAContext1 - return"), Logger::Debug); 0340 } 0341 0342 pkcs11RSAContext(const pkcs11RSAContext &from) 0343 : RSAContext(from.provider()) 0344 { 0345 CK_RV rv; 0346 0347 QCA_logTextMessage(QStringLiteral("pkcs11RSAContext::pkcs11RSAContextC - entry"), Logger::Debug); 0348 0349 _has_privateKeyRole = from._has_privateKeyRole; 0350 _pkcs11h_certificate_id = nullptr; 0351 _pkcs11h_certificate = nullptr; 0352 _pubkey = from._pubkey; 0353 _serialized = from._serialized; 0354 _sign_data.hash = nullptr; 0355 _clearSign(); 0356 0357 if ((rv = pkcs11h_certificate_duplicateCertificateId(&_pkcs11h_certificate_id, from._pkcs11h_certificate_id)) != 0358 CKR_OK) { 0359 throw pkcs11Exception(rv, QStringLiteral("Memory error")); 0360 } 0361 0362 QCA_logTextMessage(QStringLiteral("pkcs11RSAContext::pkcs11RSAContextC - return"), Logger::Debug); 0363 } 0364 0365 ~pkcs11RSAContext() override 0366 { 0367 QCA_logTextMessage(QStringLiteral("pkcs11RSAContext::~pkcs11RSAContext - entry"), Logger::Debug); 0368 0369 _clearSign(); 0370 0371 if (_pkcs11h_certificate != nullptr) { 0372 pkcs11h_certificate_freeCertificate(_pkcs11h_certificate); 0373 _pkcs11h_certificate = nullptr; 0374 } 0375 0376 if (_pkcs11h_certificate_id != nullptr) { 0377 pkcs11h_certificate_freeCertificateId(_pkcs11h_certificate_id); 0378 _pkcs11h_certificate_id = nullptr; 0379 } 0380 0381 QCA_logTextMessage(QStringLiteral("pkcs11RSAContext::~pkcs11RSAContext - return"), Logger::Debug); 0382 } 0383 0384 Provider::Context *clone() const override 0385 { 0386 return new pkcs11RSAContext(*this); 0387 } 0388 0389 public: 0390 bool isNull() const override 0391 { 0392 return _pubkey.isNull(); 0393 } 0394 0395 PKey::Type type() const override 0396 { 0397 return _pubkey.type(); 0398 } 0399 0400 bool isPrivate() const override 0401 { 0402 return _has_privateKeyRole; 0403 } 0404 0405 bool canExport() const override 0406 { 0407 return !_has_privateKeyRole; 0408 } 0409 0410 void convertToPublic() override 0411 { 0412 QCA_logTextMessage(QStringLiteral("pkcs11RSAContext::convertToPublic - entry"), Logger::Debug); 0413 0414 if (_has_privateKeyRole) { 0415 if (_pkcs11h_certificate != nullptr) { 0416 pkcs11h_certificate_freeCertificate(_pkcs11h_certificate); 0417 _pkcs11h_certificate = nullptr; 0418 } 0419 _has_privateKeyRole = false; 0420 } 0421 0422 QCA_logTextMessage(QStringLiteral("pkcs11RSAContext::convertToPublic - return"), Logger::Debug); 0423 } 0424 0425 int bits() const override 0426 { 0427 return _pubkey.bitSize(); 0428 } 0429 0430 int maximumEncryptSize(EncryptionAlgorithm alg) const override 0431 { 0432 return _pubkey.maximumEncryptSize(alg); 0433 } 0434 0435 SecureArray encrypt(const SecureArray &in, EncryptionAlgorithm alg) override 0436 { 0437 return _pubkey.encrypt(in, alg); 0438 } 0439 0440 bool decrypt(const SecureArray &in, SecureArray *out, EncryptionAlgorithm alg) override 0441 { 0442 bool session_locked = false; 0443 bool ret = false; 0444 0445 QCA_logTextMessage( 0446 QString::asprintf("pkcs11RSAContext::decrypt - decrypt in.size()=%d, alg=%d", in.size(), (int)alg), 0447 Logger::Debug); 0448 0449 try { 0450 CK_MECHANISM_TYPE mech; 0451 CK_RV rv; 0452 size_t my_size; 0453 0454 switch (alg) { 0455 case EME_PKCS1v15: 0456 mech = CKM_RSA_PKCS; 0457 break; 0458 case EME_PKCS1_OAEP: 0459 mech = CKM_RSA_PKCS_OAEP; 0460 break; 0461 default: 0462 throw pkcs11Exception(CKR_FUNCTION_NOT_SUPPORTED, QStringLiteral("Invalid algorithm")); 0463 break; 0464 } 0465 0466 _ensureCertificate(); 0467 0468 if ((rv = pkcs11h_certificate_lockSession(_pkcs11h_certificate)) != CKR_OK) { 0469 throw pkcs11Exception(rv, QStringLiteral("Cannot lock session")); 0470 } 0471 session_locked = true; 0472 0473 if ((rv = pkcs11h_certificate_decryptAny(_pkcs11h_certificate, 0474 mech, 0475 (const unsigned char *)in.constData(), 0476 in.size(), 0477 nullptr, 0478 &my_size)) != CKR_OK) { 0479 throw pkcs11Exception(rv, QStringLiteral("Decryption error")); 0480 } 0481 0482 out->resize(my_size); 0483 0484 if ((rv = pkcs11h_certificate_decryptAny(_pkcs11h_certificate, 0485 mech, 0486 (const unsigned char *)in.constData(), 0487 in.size(), 0488 (unsigned char *)out->data(), 0489 &my_size)) != CKR_OK) { 0490 throw pkcs11Exception(rv, QStringLiteral("Decryption error")); 0491 } 0492 0493 rv = out->resize(my_size); 0494 0495 if ((rv = pkcs11h_certificate_releaseSession(_pkcs11h_certificate)) != CKR_OK) { 0496 throw pkcs11Exception(rv, QStringLiteral("Cannot release session")); 0497 } 0498 session_locked = false; 0499 0500 ret = true; 0501 } catch (const pkcs11Exception &e) { 0502 if (session_locked) { 0503 pkcs11h_certificate_releaseSession(_pkcs11h_certificate); 0504 session_locked = false; 0505 } 0506 0507 if (s_keyStoreList != nullptr) { 0508 s_keyStoreList->_emit_diagnosticText( 0509 QString::asprintf("PKCS#11: Cannot decrypt: %lu-'%s'.\n", e.rv(), myPrintable(e.message()))); 0510 } 0511 } 0512 0513 QCA_logTextMessage(QString::asprintf("pkcs11RSAContext::decrypt - decrypt out->size()=%d", out->size()), 0514 Logger::Debug); 0515 0516 return ret; 0517 } 0518 0519 void startSign(SignatureAlgorithm alg, SignatureFormat) override 0520 { 0521 _clearSign(); 0522 0523 _sign_data.alg = alg; 0524 0525 switch (_sign_data.alg) { 0526 case EMSA3_SHA1: 0527 _sign_data.hash = new Hash(QStringLiteral("sha1")); 0528 break; 0529 case EMSA3_MD5: 0530 _sign_data.hash = new Hash(QStringLiteral("md5")); 0531 break; 0532 case EMSA3_MD2: 0533 _sign_data.hash = new Hash(QStringLiteral("md2")); 0534 break; 0535 case EMSA3_Raw: 0536 break; 0537 case SignatureUnknown: 0538 case EMSA1_SHA1: 0539 case EMSA3_RIPEMD160: 0540 default: 0541 QCA_logTextMessage(QString::asprintf("PKCS#11: Invalid hash algorithm %d", _sign_data.alg), 0542 Logger::Warning); 0543 break; 0544 } 0545 } 0546 0547 void startVerify(SignatureAlgorithm alg, SignatureFormat sf) override 0548 { 0549 _pubkey.startVerify(alg, sf); 0550 } 0551 0552 void update(const MemoryRegion &in) override 0553 { 0554 if (_has_privateKeyRole) { 0555 if (_sign_data.hash != nullptr) { 0556 _sign_data.hash->update(in); 0557 } else { 0558 _sign_data.raw.append(in.toByteArray()); 0559 } 0560 } else { 0561 _pubkey.update(in); 0562 } 0563 } 0564 0565 QByteArray endSign() override 0566 { 0567 QByteArray result; 0568 bool session_locked = false; 0569 0570 QCA_logTextMessage(QStringLiteral("pkcs11RSAContext::endSign - entry"), Logger::Debug); 0571 0572 try { 0573 QByteArray final; 0574 CK_RV rv; 0575 0576 // from some strange reason I got 2047... (for some) <---- BUG?!?!?! 0577 int myrsa_size = (_pubkey.bitSize() + 7) / 8; 0578 0579 if (_sign_data.hash != nullptr) { 0580 final = emsa3Encode(_sign_data.hash->type(), _sign_data.hash->final().toByteArray(), myrsa_size); 0581 } else { 0582 final = _sign_data.raw; 0583 } 0584 0585 if (final.size() == 0) { 0586 throw pkcs11Exception(CKR_FUNCTION_FAILED, QStringLiteral("Cannot encode signature")); 0587 } 0588 0589 _ensureCertificate(); 0590 0591 size_t my_size; 0592 0593 if ((rv = pkcs11h_certificate_lockSession(_pkcs11h_certificate)) != CKR_OK) { 0594 throw pkcs11Exception(rv, QStringLiteral("Cannot lock session")); 0595 } 0596 session_locked = true; 0597 0598 if ((rv = pkcs11h_certificate_signAny(_pkcs11h_certificate, 0599 CKM_RSA_PKCS, 0600 (const unsigned char *) final.constData(), 0601 (size_t) final.size(), 0602 nullptr, 0603 &my_size)) != CKR_OK) { 0604 throw pkcs11Exception(rv, QStringLiteral("Signature failed")); 0605 } 0606 0607 result.resize(my_size); 0608 0609 if ((rv = pkcs11h_certificate_signAny(_pkcs11h_certificate, 0610 CKM_RSA_PKCS, 0611 (const unsigned char *) final.constData(), 0612 (size_t) final.size(), 0613 (unsigned char *)result.data(), 0614 &my_size)) != CKR_OK) { 0615 throw pkcs11Exception(rv, QStringLiteral("Signature failed")); 0616 } 0617 0618 result.resize(my_size); 0619 0620 if ((rv = pkcs11h_certificate_releaseSession(_pkcs11h_certificate)) != CKR_OK) { 0621 throw pkcs11Exception(rv, QStringLiteral("Cannot release session")); 0622 } 0623 session_locked = false; 0624 0625 } catch (const pkcs11Exception &e) { 0626 result.clear(); 0627 0628 if (session_locked) { 0629 pkcs11h_certificate_releaseSession(_pkcs11h_certificate); 0630 session_locked = false; 0631 } 0632 0633 if (s_keyStoreList != nullptr) { 0634 s_keyStoreList->_emit_diagnosticText( 0635 QString::asprintf("PKCS#11: Cannot sign: %lu-'%s'.\n", e.rv(), myPrintable(e.message()))); 0636 } 0637 } 0638 0639 _clearSign(); 0640 0641 QCA_logTextMessage( 0642 QString::asprintf("pkcs11RSAContext::endSign - return result.size ()=%d", int(result.size())), 0643 Logger::Debug); 0644 0645 return result; 0646 } 0647 0648 virtual bool validSignature(const QByteArray &sig) 0649 { 0650 return _pubkey.validSignature(sig); 0651 } 0652 0653 void createPrivate(int bits, int exp, bool block) override 0654 { 0655 Q_UNUSED(bits); 0656 Q_UNUSED(exp); 0657 Q_UNUSED(block); 0658 } 0659 0660 void createPrivate(const BigInteger &n, 0661 const BigInteger &e, 0662 const BigInteger &p, 0663 const BigInteger &q, 0664 const BigInteger &d) override 0665 { 0666 Q_UNUSED(n); 0667 Q_UNUSED(e); 0668 Q_UNUSED(p); 0669 Q_UNUSED(q); 0670 Q_UNUSED(d); 0671 } 0672 0673 void createPublic(const BigInteger &n, const BigInteger &e) override 0674 { 0675 Q_UNUSED(n); 0676 Q_UNUSED(e); 0677 } 0678 0679 BigInteger n() const override 0680 { 0681 return _pubkey.n(); 0682 } 0683 0684 BigInteger e() const override 0685 { 0686 return _pubkey.e(); 0687 } 0688 0689 BigInteger p() const override 0690 { 0691 return BigInteger(); 0692 } 0693 0694 BigInteger q() const override 0695 { 0696 return BigInteger(); 0697 } 0698 0699 BigInteger d() const override 0700 { 0701 return BigInteger(); 0702 } 0703 0704 public: 0705 PublicKey _publicKey() const 0706 { 0707 return _pubkey; 0708 } 0709 0710 bool _isTokenAvailable() const 0711 { 0712 bool ret; 0713 0714 QCA_logTextMessage(QStringLiteral("pkcs11RSAContext::_ensureTokenAvailable - entry"), Logger::Debug); 0715 0716 ret = pkcs11h_token_ensureAccess(_pkcs11h_certificate_id->token_id, nullptr, 0) == CKR_OK; 0717 0718 QCA_logTextMessage(QString::asprintf("pkcs11RSAContext::_ensureTokenAvailable - return ret=%d", ret ? 1 : 0), 0719 Logger::Debug); 0720 0721 return ret; 0722 } 0723 0724 bool _ensureTokenAccess() 0725 { 0726 bool ret; 0727 0728 QCA_logTextMessage(QStringLiteral("pkcs11RSAContext::_ensureTokenAccess - entry"), Logger::Debug); 0729 0730 ret = pkcs11h_token_ensureAccess(_pkcs11h_certificate_id->token_id, nullptr, PKCS11H_PROMPT_MASK_ALLOW_ALL) == 0731 CKR_OK; 0732 0733 QCA_logTextMessage(QString::asprintf("pkcs11RSAContext::_ensureTokenAccess - return ret=%d", ret ? 1 : 0), 0734 Logger::Debug); 0735 0736 return ret; 0737 } 0738 0739 private: 0740 void _clearSign() 0741 { 0742 _sign_data.raw.clear(); 0743 _sign_data.alg = SignatureUnknown; 0744 delete _sign_data.hash; 0745 _sign_data.hash = nullptr; 0746 } 0747 0748 void _ensureCertificate() 0749 { 0750 CK_RV rv; 0751 0752 QCA_logTextMessage(QStringLiteral("pkcs11RSAContext::_ensureCertificate - entry"), Logger::Debug); 0753 0754 if (_pkcs11h_certificate == nullptr) { 0755 if ((rv = pkcs11h_certificate_create(_pkcs11h_certificate_id, 0756 &_serialized, 0757 PKCS11H_PROMPT_MASK_ALLOW_ALL, 0758 PKCS11H_PIN_CACHE_INFINITE, 0759 &_pkcs11h_certificate)) != CKR_OK) { 0760 throw pkcs11Exception(rv, QStringLiteral("Cannot create low-level certificate")); 0761 } 0762 } 0763 0764 QCA_logTextMessage(QStringLiteral("pkcs11RSAContext::_ensureCertificate - return"), Logger::Debug); 0765 } 0766 }; 0767 0768 //---------------------------------------------------------------------------- 0769 // pkcs11PKeyContext 0770 //---------------------------------------------------------------------------- 0771 class pkcs11PKeyContext : public PKeyContext 0772 { 0773 Q_OBJECT 0774 0775 private: 0776 PKeyBase *_k; 0777 0778 public: 0779 pkcs11PKeyContext(Provider *p) 0780 : PKeyContext(p) 0781 { 0782 _k = nullptr; 0783 } 0784 0785 ~pkcs11PKeyContext() override 0786 { 0787 delete _k; 0788 _k = nullptr; 0789 } 0790 0791 Provider::Context *clone() const override 0792 { 0793 pkcs11PKeyContext *c = new pkcs11PKeyContext(*this); 0794 c->_k = (PKeyBase *)_k->clone(); 0795 return c; 0796 } 0797 0798 public: 0799 QList<PKey::Type> supportedTypes() const override 0800 { 0801 QList<PKey::Type> list; 0802 list += PKey::RSA; 0803 return list; 0804 } 0805 0806 QList<PKey::Type> supportedIOTypes() const override 0807 { 0808 QList<PKey::Type> list; 0809 list += PKey::RSA; 0810 return list; 0811 } 0812 0813 QList<PBEAlgorithm> supportedPBEAlgorithms() const override 0814 { 0815 QList<PBEAlgorithm> list; 0816 return list; 0817 } 0818 0819 PKeyBase *key() override 0820 { 0821 return _k; 0822 } 0823 0824 const PKeyBase *key() const override 0825 { 0826 return _k; 0827 } 0828 0829 void setKey(PKeyBase *key) override 0830 { 0831 delete _k; 0832 _k = key; 0833 } 0834 0835 bool importKey(const PKeyBase *key) override 0836 { 0837 Q_UNUSED(key); 0838 return false; 0839 } 0840 0841 static int passphrase_cb(char *buf, int size, int rwflag, void *u) 0842 { 0843 Q_UNUSED(buf); 0844 Q_UNUSED(size); 0845 Q_UNUSED(rwflag); 0846 Q_UNUSED(u); 0847 return 0; 0848 } 0849 0850 QByteArray publicToDER() const override 0851 { 0852 return static_cast<pkcs11RSAContext *>(_k)->_publicKey().toDER(); 0853 } 0854 0855 QString publicToPEM() const override 0856 { 0857 return static_cast<pkcs11RSAContext *>(_k)->_publicKey().toPEM(); 0858 } 0859 0860 ConvertResult publicFromDER(const QByteArray &in) override 0861 { 0862 Q_UNUSED(in); 0863 return ErrorDecode; 0864 } 0865 0866 ConvertResult publicFromPEM(const QString &s) override 0867 { 0868 Q_UNUSED(s); 0869 return ErrorDecode; 0870 } 0871 0872 SecureArray privateToDER(const SecureArray &passphrase, PBEAlgorithm pbe) const override 0873 { 0874 Q_UNUSED(passphrase); 0875 Q_UNUSED(pbe); 0876 return SecureArray(); 0877 } 0878 0879 QString privateToPEM(const SecureArray &passphrase, PBEAlgorithm pbe) const override 0880 { 0881 Q_UNUSED(passphrase); 0882 Q_UNUSED(pbe); 0883 return QString(); 0884 } 0885 0886 ConvertResult privateFromDER(const SecureArray &in, const SecureArray &passphrase) override 0887 { 0888 Q_UNUSED(in); 0889 Q_UNUSED(passphrase); 0890 return ErrorDecode; 0891 } 0892 0893 ConvertResult privateFromPEM(const QString &s, const SecureArray &passphrase) override 0894 { 0895 Q_UNUSED(s); 0896 Q_UNUSED(passphrase); 0897 return ErrorDecode; 0898 } 0899 }; 0900 0901 //---------------------------------------------------------------------------- 0902 // pkcs11KeyStoreEntryContext 0903 //---------------------------------------------------------------------------- 0904 class pkcs11KeyStoreEntryContext : public KeyStoreEntryContext 0905 { 0906 Q_OBJECT 0907 private: 0908 KeyStoreEntry::Type _item_type; 0909 KeyBundle _key; 0910 Certificate _cert; 0911 QString _storeId; 0912 QString _id; 0913 QString _serialized; 0914 QString _storeName; 0915 QString _name; 0916 0917 public: 0918 pkcs11KeyStoreEntryContext(const Certificate &cert, 0919 const QString &storeId, 0920 const QString &serialized, 0921 const QString &storeName, 0922 const QString &name, 0923 Provider *p) 0924 : KeyStoreEntryContext(p) 0925 { 0926 _item_type = KeyStoreEntry::TypeCertificate; 0927 _cert = cert; 0928 _storeId = storeId; 0929 _id = certificateHash(_cert); 0930 _serialized = serialized; 0931 _storeName = storeName; 0932 _name = name; 0933 } 0934 0935 pkcs11KeyStoreEntryContext(const KeyBundle &key, 0936 const QString &storeId, 0937 const QString &serialized, 0938 const QString &storeName, 0939 const QString &name, 0940 Provider *p) 0941 : KeyStoreEntryContext(p) 0942 { 0943 _item_type = KeyStoreEntry::TypeKeyBundle; 0944 _key = key; 0945 _storeId = storeId, _id = certificateHash(key.certificateChain().primary()); 0946 _serialized = serialized; 0947 _storeName = storeName; 0948 _name = name; 0949 } 0950 0951 pkcs11KeyStoreEntryContext(const pkcs11KeyStoreEntryContext &from) 0952 : KeyStoreEntryContext(from) 0953 { 0954 _item_type = from._item_type; 0955 _key = from._key; 0956 _storeId = from._storeId; 0957 _id = from._id; 0958 _serialized = from._serialized; 0959 _storeName = from._storeName; 0960 _name = from._name; 0961 } 0962 0963 Provider::Context *clone() const override 0964 { 0965 return new pkcs11KeyStoreEntryContext(*this); 0966 } 0967 0968 public: 0969 KeyStoreEntry::Type type() const override 0970 { 0971 return _item_type; 0972 } 0973 0974 QString name() const override 0975 { 0976 return _name; 0977 } 0978 0979 QString id() const override 0980 { 0981 return _id; 0982 } 0983 0984 KeyBundle keyBundle() const override 0985 { 0986 return _key; 0987 } 0988 0989 Certificate certificate() const override 0990 { 0991 return _cert; 0992 } 0993 0994 QString storeId() const override 0995 { 0996 return _storeId; 0997 } 0998 0999 QString storeName() const override 1000 { 1001 return _storeName; 1002 } 1003 1004 bool isAvailable() const override 1005 { 1006 return static_cast<pkcs11RSAContext *>(static_cast<PKeyContext *>(_key.privateKey().context())->key()) 1007 ->_isTokenAvailable(); 1008 } 1009 1010 bool ensureAccess() override 1011 { 1012 return static_cast<pkcs11RSAContext *>(static_cast<PKeyContext *>(_key.privateKey().context())->key()) 1013 ->_ensureTokenAccess(); 1014 } 1015 1016 QString serialize() const override 1017 { 1018 return _serialized; 1019 } 1020 }; 1021 1022 //---------------------------------------------------------------------------- 1023 // pkcs11QCACrypto 1024 //---------------------------------------------------------------------------- 1025 class pkcs11QCACrypto 1026 { 1027 private: 1028 static int _pkcs11h_crypto_qca_initialize(void *const global_data) 1029 { 1030 Q_UNUSED(global_data); 1031 1032 return TRUE; // krazy:exclude=captruefalse 1033 } 1034 1035 static int _pkcs11h_crypto_qca_uninitialize(void *const global_data) 1036 { 1037 Q_UNUSED(global_data); 1038 1039 return TRUE; // krazy:exclude=captruefalse 1040 } 1041 1042 static int _pkcs11h_crypto_qca_certificate_get_expiration(void *const global_data, 1043 const unsigned char *const blob, 1044 const size_t blob_size, 1045 time_t *const expiration) 1046 { 1047 Q_UNUSED(global_data); 1048 1049 Certificate cert = Certificate::fromDER(QByteArray((char *)blob, blob_size)); 1050 1051 *expiration = cert.notValidAfter().toSecsSinceEpoch(); 1052 1053 return TRUE; // krazy:exclude=captruefalse 1054 } 1055 1056 static int _pkcs11h_crypto_qca_certificate_get_dn(void *const global_data, 1057 const unsigned char *const blob, 1058 const size_t blob_size, 1059 char *const dn, 1060 const size_t dn_max) 1061 { 1062 Q_UNUSED(global_data); 1063 1064 Certificate cert = Certificate::fromDER(QByteArray((char *)blob, blob_size)); 1065 QString qdn = cert.subjectInfoOrdered().toString(); 1066 1067 if ((size_t)qdn.length() > dn_max - 1) { 1068 return FALSE; // krazy:exclude=captruefalse 1069 } else { 1070 qstrcpy(dn, myPrintable(qdn)); 1071 return TRUE; // krazy:exclude=captruefalse 1072 } 1073 } 1074 1075 static int _pkcs11h_crypto_qca_certificate_is_issuer(void *const global_data, 1076 const unsigned char *const signer_blob, 1077 const size_t signer_blob_size, 1078 const unsigned char *const cert_blob, 1079 const size_t cert_blob_size) 1080 { 1081 Q_UNUSED(global_data); 1082 1083 Certificate signer = Certificate::fromDER(QByteArray((char *)signer_blob, signer_blob_size)); 1084 1085 Certificate cert = Certificate::fromDER(QByteArray((char *)cert_blob, cert_blob_size)); 1086 1087 return signer.isIssuerOf(cert); 1088 } 1089 1090 public: 1091 static pkcs11h_engine_crypto_t crypto; 1092 }; 1093 1094 pkcs11h_engine_crypto_t pkcs11QCACrypto::crypto = {nullptr, 1095 _pkcs11h_crypto_qca_initialize, 1096 _pkcs11h_crypto_qca_uninitialize, 1097 _pkcs11h_crypto_qca_certificate_get_expiration, 1098 _pkcs11h_crypto_qca_certificate_get_dn, 1099 _pkcs11h_crypto_qca_certificate_is_issuer}; 1100 1101 //---------------------------------------------------------------------------- 1102 // pkcs11KeyStoreListContext 1103 //---------------------------------------------------------------------------- 1104 pkcs11KeyStoreListContext::pkcs11KeyStoreListContext(Provider *p) 1105 : KeyStoreListContext(p) 1106 { 1107 QCA_logTextMessage( 1108 QString::asprintf("pkcs11KeyStoreListContext::pkcs11KeyStoreListContext - entry Provider=%p", (void *)p), 1109 Logger::Debug); 1110 1111 _last_id = 0; 1112 _initialized = false; 1113 1114 QCA_logTextMessage(QStringLiteral("pkcs11KeyStoreListContext::pkcs11KeyStoreListContext - return"), Logger::Debug); 1115 } 1116 1117 pkcs11KeyStoreListContext::~pkcs11KeyStoreListContext() 1118 { 1119 QCA_logTextMessage(QStringLiteral("pkcs11KeyStoreListContext::~pkcs11KeyStoreListContext - entry"), Logger::Debug); 1120 1121 s_keyStoreList = nullptr; 1122 _clearStores(); 1123 1124 QCA_logTextMessage(QStringLiteral("pkcs11KeyStoreListContext::~pkcs11KeyStoreListContext - return"), Logger::Debug); 1125 } 1126 1127 Provider::Context *pkcs11KeyStoreListContext::clone() const 1128 { 1129 QCA_logTextMessage(QStringLiteral("pkcs11KeyStoreListContext::clone - entry/return"), Logger::Debug); 1130 return nullptr; 1131 } 1132 1133 void pkcs11KeyStoreListContext::start() 1134 { 1135 QCA_logTextMessage(QStringLiteral("pkcs11KeyStoreListContext::start - entry"), Logger::Debug); 1136 1137 QMetaObject::invokeMethod(this, "doReady", Qt::QueuedConnection); 1138 1139 QCA_logTextMessage(QStringLiteral("pkcs11KeyStoreListContext::start - return"), Logger::Debug); 1140 } 1141 1142 void pkcs11KeyStoreListContext::setUpdatesEnabled(bool enabled) 1143 { 1144 QCA_logTextMessage( 1145 QString::asprintf("pkcs11KeyStoreListContext::setUpdatesEnabled - entry enabled=%d", enabled ? 1 : 0), 1146 Logger::Debug); 1147 1148 try { 1149 pkcs11Provider *p = static_cast<pkcs11Provider *>(provider()); 1150 if (enabled) { 1151 p->startSlotEvents(); 1152 } else { 1153 p->stopSlotEvents(); 1154 } 1155 } catch (const pkcs11Exception &e) { 1156 s_keyStoreList->_emit_diagnosticText( 1157 QString::asprintf("PKCS#11: Start event failed %lu-'%s'.\n", e.rv(), myPrintable(e.message()))); 1158 } 1159 1160 QCA_logTextMessage(QStringLiteral("pkcs11KeyStoreListContext::setUpdatesEnabled - return"), Logger::Debug); 1161 } 1162 1163 KeyStoreEntryContext *pkcs11KeyStoreListContext::entry(int id, const QString &entryId) 1164 { 1165 QCA_logTextMessage(QString::asprintf("pkcs11KeyStoreListContext::entry - entry/return id=%d entryId='%s'", 1166 id, 1167 myPrintable(entryId)), 1168 Logger::Debug); 1169 1170 Q_UNUSED(id); 1171 Q_UNUSED(entryId); 1172 return nullptr; 1173 } 1174 1175 KeyStoreEntryContext *pkcs11KeyStoreListContext::entryPassive(const QString &serialized) 1176 { 1177 KeyStoreEntryContext *entry = nullptr; 1178 pkcs11h_certificate_id_t certificate_id = nullptr; 1179 1180 QCA_logTextMessage( 1181 QString::asprintf("pkcs11KeyStoreListContext::entryPassive - entry serialized='%s'", myPrintable(serialized)), 1182 Logger::Debug); 1183 1184 try { 1185 if (serialized.startsWith(QLatin1String("qca-pkcs11/"))) { 1186 CertificateChain chain; 1187 bool has_private; 1188 1189 _deserializeCertificate(serialized, &certificate_id, &has_private, chain); 1190 pkcs11KeyStoreItem *sentry = _registerTokenId(certificate_id->token_id); 1191 sentry->registerCertificates(chain); 1192 QMap<QString, QString> friendlyNames = sentry->friendlyNames(); 1193 1194 entry = _keyStoreEntryByCertificateId( 1195 certificate_id, has_private, chain, friendlyNames[certificateHash(chain.primary())]); 1196 } 1197 } catch (const pkcs11Exception &e) { 1198 s_keyStoreList->_emit_diagnosticText( 1199 QString::asprintf("PKCS#11: Add key store entry %lu-'%s'.\n", e.rv(), myPrintable(e.message()))); 1200 } 1201 1202 if (certificate_id != nullptr) { 1203 pkcs11h_certificate_freeCertificateId(certificate_id); 1204 certificate_id = nullptr; 1205 } 1206 1207 QCA_logTextMessage(QString::asprintf("pkcs11KeyStoreListContext::entryPassive - return entry=%p", (void *)entry), 1208 Logger::Debug); 1209 1210 return entry; 1211 } 1212 1213 KeyStore::Type pkcs11KeyStoreListContext::type(int id) const 1214 { 1215 Q_UNUSED(id); 1216 1217 QCA_logTextMessage(QString::asprintf("pkcs11KeyStoreListContext::type - entry/return id=%d", id), Logger::Debug); 1218 1219 return KeyStore::SmartCard; 1220 } 1221 1222 QString pkcs11KeyStoreListContext::storeId(int id) const 1223 { 1224 QString ret; 1225 1226 QCA_logTextMessage(QString::asprintf("pkcs11KeyStoreListContext::storeId - entry id=%d", id), Logger::Debug); 1227 1228 if (_storesById.contains(id)) { 1229 ret = _tokenId2storeId(_storesById[id]->tokenId()); 1230 } 1231 1232 QCA_logTextMessage(QString::asprintf("pkcs11KeyStoreListContext::storeId - return ret=%s", myPrintable(ret)), 1233 Logger::Debug); 1234 1235 return ret; 1236 } 1237 1238 QString pkcs11KeyStoreListContext::name(int id) const 1239 { 1240 QString ret; 1241 1242 QCA_logTextMessage(QString::asprintf("pkcs11KeyStoreListContext::name - entry id=%d", id), Logger::Debug); 1243 1244 if (_storesById.contains(id)) { 1245 ret = QString::fromLatin1(_storesById[id]->tokenId()->label); 1246 } 1247 1248 QCA_logTextMessage(QString::asprintf("pkcs11KeyStoreListContext::name - return ret=%s", myPrintable(ret)), 1249 Logger::Debug); 1250 1251 return ret; 1252 } 1253 1254 QList<KeyStoreEntry::Type> pkcs11KeyStoreListContext::entryTypes(int id) const 1255 { 1256 Q_UNUSED(id); 1257 1258 QCA_logTextMessage(QString::asprintf("pkcs11KeyStoreListContext::entryTypes - entry/return id=%d", id), 1259 Logger::Debug); 1260 1261 QList<KeyStoreEntry::Type> list; 1262 list += KeyStoreEntry::TypeKeyBundle; 1263 list += KeyStoreEntry::TypeCertificate; 1264 return list; 1265 } 1266 1267 QList<int> pkcs11KeyStoreListContext::keyStores() 1268 { 1269 pkcs11h_token_id_list_t tokens = nullptr; 1270 QList<int> out; 1271 1272 QCA_logTextMessage(QStringLiteral("pkcs11KeyStoreListContext::keyStores - entry"), Logger::Debug); 1273 1274 try { 1275 CK_RV rv; 1276 1277 /* 1278 * Get available tokens 1279 */ 1280 if ((rv = pkcs11h_token_enumTokenIds(PKCS11H_ENUM_METHOD_CACHE_EXIST, &tokens)) != CKR_OK) { 1281 throw pkcs11Exception(rv, QStringLiteral("Enumerating tokens")); 1282 } 1283 1284 /* 1285 * Register all tokens, unmark 1286 * them from remove list 1287 */ 1288 QList<int> to_remove = _storesById.keys(); 1289 for (pkcs11h_token_id_list_t entry = tokens; entry != nullptr; entry = entry->next) { 1290 pkcs11KeyStoreItem *item = _registerTokenId(entry->token_id); 1291 out += item->id(); 1292 to_remove.removeAll(item->id()); 1293 } 1294 1295 /* 1296 * Remove all items 1297 * that were not discovered 1298 */ 1299 { 1300 QMutexLocker l(&_mutexStores); 1301 1302 foreach (int i, to_remove) { 1303 pkcs11KeyStoreItem *item = _storesById[i]; 1304 1305 _storesById.remove(item->id()); 1306 _stores.removeAll(item); 1307 1308 delete item; 1309 item = nullptr; 1310 } 1311 } 1312 } catch (const pkcs11Exception &e) { 1313 s_keyStoreList->_emit_diagnosticText( 1314 QString::asprintf("PKCS#11: Cannot get key stores: %lu-'%s'.\n", e.rv(), myPrintable(e.message()))); 1315 } 1316 1317 if (tokens != nullptr) { 1318 pkcs11h_token_freeTokenIdList(tokens); 1319 } 1320 1321 QCA_logTextMessage( 1322 QString::asprintf("pkcs11KeyStoreListContext::keyStores - return out.size()=%d", int(out.size())), 1323 Logger::Debug); 1324 1325 return out; 1326 } 1327 1328 QList<KeyStoreEntryContext *> pkcs11KeyStoreListContext::entryList(int id) 1329 { 1330 pkcs11h_certificate_id_list_t certs = nullptr; 1331 QList<KeyStoreEntryContext *> out; 1332 1333 QCA_logTextMessage(QString::asprintf("pkcs11KeyStoreListContext::entryList - entry id=%d", id), Logger::Debug); 1334 1335 try { 1336 CK_RV rv; 1337 1338 if (_storesById.contains(id)) { 1339 pkcs11KeyStoreItem *entry = _storesById[id]; 1340 1341 pkcs11h_certificate_id_list_t issuers = nullptr; 1342 pkcs11h_certificate_id_list_t current = nullptr; 1343 QList<Certificate> listCerts; 1344 QList<Certificate> listIssuers; 1345 int i = 0; 1346 1347 if ((rv = pkcs11h_certificate_enumTokenCertificateIds(entry->tokenId(), 1348 PKCS11H_ENUM_METHOD_CACHE, 1349 nullptr, 1350 PKCS11H_PROMPT_MASK_ALLOW_ALL, 1351 &issuers, 1352 &certs)) != CKR_OK) { 1353 throw pkcs11Exception(rv, QStringLiteral("Enumerate certificates")); 1354 } 1355 1356 for (current = certs; current != nullptr; current = current->next) { 1357 if (current->certificate_id->certificate_blob_size > 0) { 1358 listCerts += Certificate::fromDER(QByteArray((char *)current->certificate_id->certificate_blob, 1359 current->certificate_id->certificate_blob_size)); 1360 } 1361 } 1362 1363 for (current = issuers; current != nullptr; current = current->next) { 1364 if (current->certificate_id->certificate_blob_size > 0) { 1365 listIssuers += Certificate::fromDER(QByteArray((char *)current->certificate_id->certificate_blob, 1366 current->certificate_id->certificate_blob_size)); 1367 } 1368 } 1369 1370 entry->registerCertificates(listIssuers + listCerts); 1371 QMap<QString, QString> friendlyNames = entry->friendlyNames(); 1372 1373 QList<Certificate> listIssuersForComplete; 1374 if (dynamic_cast<pkcs11Provider *>(provider())->_allowLoadRootCA) { 1375 listIssuersForComplete = listIssuers; 1376 } else { 1377 foreach (Certificate c, listIssuers) { 1378 if (!c.isSelfSigned()) { 1379 listIssuersForComplete += c; 1380 } 1381 } 1382 } 1383 1384 for (i = 0, current = issuers; current != nullptr; i++, current = current->next) { 1385 try { 1386 if (listIssuers[i].isNull()) { 1387 throw pkcs11Exception(CKR_ARGUMENTS_BAD, QStringLiteral("Invalid certificate")); 1388 } 1389 1390 if (listIssuers[i].isSelfSigned() && dynamic_cast<pkcs11Provider *>(provider())->_allowLoadRootCA) { 1391 CertificateChain chain = CertificateChain(listIssuers[i]).complete(listIssuersForComplete); 1392 out += _keyStoreEntryByCertificateId( 1393 current->certificate_id, false, chain, friendlyNames[certificateHash(chain.primary())]); 1394 } 1395 } catch (const pkcs11Exception &e) { 1396 s_keyStoreList->_emit_diagnosticText(QString::asprintf( 1397 "PKCS#11: Add key store entry %lu-'%s'.\n", e.rv(), myPrintable(e.message()))); 1398 } 1399 } 1400 1401 for (i = 0, current = certs; current != nullptr; i++, current = current->next) { 1402 try { 1403 if (listCerts[i].isNull()) { 1404 throw pkcs11Exception(CKR_ARGUMENTS_BAD, QStringLiteral("Invalid certificate")); 1405 } 1406 1407 CertificateChain chain = CertificateChain(listCerts[i]).complete(listIssuersForComplete); 1408 out += _keyStoreEntryByCertificateId( 1409 current->certificate_id, true, chain, friendlyNames[certificateHash(chain.primary())]); 1410 } catch (const pkcs11Exception &e) { 1411 s_keyStoreList->_emit_diagnosticText(QString::asprintf( 1412 "PKCS#11: Add key store entry %lu-'%s'.\n", e.rv(), myPrintable(e.message()))); 1413 } 1414 } 1415 } 1416 } catch (const pkcs11Exception &e) { 1417 s_keyStoreList->_emit_diagnosticText( 1418 QString::asprintf("PKCS#11: Enumerating store failed %lu-'%s'.\n", e.rv(), myPrintable(e.message()))); 1419 } 1420 1421 if (certs != nullptr) { 1422 pkcs11h_certificate_freeCertificateIdList(certs); 1423 } 1424 1425 QCA_logTextMessage( 1426 QString::asprintf("pkcs11KeyStoreListContext::entryList - return out.size()=%d", int(out.size())), 1427 Logger::Debug); 1428 1429 return out; 1430 } 1431 1432 bool pkcs11KeyStoreListContext::_tokenPrompt(void *const user_data, const pkcs11h_token_id_t token_id) 1433 { 1434 KeyStoreEntry entry; 1435 KeyStoreEntryContext *context = nullptr; 1436 QString storeId, storeName; 1437 bool ret = false; 1438 1439 QCA_logTextMessage(QString::asprintf("pkcs11KeyStoreListContext::_tokenPrompt - entry user_data=%p, token_id=%p", 1440 user_data, 1441 (void *)token_id), 1442 Logger::Debug); 1443 1444 if (user_data != nullptr) { 1445 QString *serialized = (QString *)user_data; 1446 context = entryPassive(*serialized); 1447 storeId = context->storeId(); 1448 storeName = context->storeName(); 1449 entry.change(context); 1450 } else { 1451 _registerTokenId(token_id); 1452 storeId = _tokenId2storeId(token_id); 1453 storeName = QString::fromLatin1(token_id->label); 1454 } 1455 1456 TokenAsker asker; 1457 asker.ask(KeyStoreInfo(KeyStore::SmartCard, storeId, storeName), entry, context); 1458 asker.waitForResponse(); 1459 if (asker.accepted()) { 1460 ret = true; 1461 } 1462 1463 QCA_logTextMessage(QString::asprintf("pkcs11KeyStoreListContext::_tokenPrompt - return ret=%d", ret ? 1 : 0), 1464 Logger::Debug); 1465 1466 return ret; 1467 } 1468 1469 bool pkcs11KeyStoreListContext::_pinPrompt(void *const user_data, const pkcs11h_token_id_t token_id, SecureArray &pin) 1470 { 1471 KeyStoreEntry entry; 1472 KeyStoreEntryContext *context = nullptr; 1473 QString storeId, storeName; 1474 bool ret = false; 1475 1476 QCA_logTextMessage(QString::asprintf("pkcs11KeyStoreListContext::_pinPrompt - entry user_data=%p, token_id=%p", 1477 user_data, 1478 (void *)token_id), 1479 Logger::Debug); 1480 1481 pin = SecureArray(); 1482 1483 if (user_data != nullptr) { 1484 QString *serialized = (QString *)user_data; 1485 context = entryPassive(*serialized); 1486 storeId = context->storeId(); 1487 storeName = context->storeName(); 1488 entry.change(context); 1489 } else { 1490 _registerTokenId(token_id); 1491 storeId = _tokenId2storeId(token_id); 1492 storeName = QString::fromLatin1(token_id->label); 1493 } 1494 1495 PasswordAsker asker; 1496 asker.ask(Event::StylePIN, KeyStoreInfo(KeyStore::SmartCard, storeId, storeName), entry, context); 1497 asker.waitForResponse(); 1498 if (asker.accepted()) { 1499 ret = true; 1500 pin = asker.password(); 1501 } 1502 1503 QCA_logTextMessage(QString::asprintf("pkcs11KeyStoreListContext::_pinPrompt - return ret=%d", ret ? 1 : 0), 1504 Logger::Debug); 1505 1506 return ret; 1507 } 1508 1509 void pkcs11KeyStoreListContext::_emit_diagnosticText(const QString &t) 1510 { 1511 QCA_logTextMessage( 1512 QString::asprintf("pkcs11KeyStoreListContext::_emit_diagnosticText - entry t='%s'", myPrintable(t)), 1513 Logger::Debug); 1514 1515 QCA_logTextMessage(t, Logger::Warning); 1516 1517 emit diagnosticText(t); 1518 1519 QCA_logTextMessage(QStringLiteral("pkcs11KeyStoreListContext::_emit_diagnosticText - return"), Logger::Debug); 1520 } 1521 1522 void pkcs11KeyStoreListContext::doReady() 1523 { 1524 QCA_logTextMessage(QStringLiteral("pkcs11KeyStoreListContext::doReady - entry"), Logger::Debug); 1525 1526 emit busyEnd(); 1527 1528 QCA_logTextMessage(QStringLiteral("pkcs11KeyStoreListContext::doReady - return"), Logger::Debug); 1529 } 1530 1531 void pkcs11KeyStoreListContext::doUpdated() 1532 { 1533 QCA_logTextMessage(QStringLiteral("pkcs11KeyStoreListContext::doUpdated - entry"), Logger::Debug); 1534 1535 emit updated(); 1536 1537 QCA_logTextMessage(QStringLiteral("pkcs11KeyStoreListContext::doUpdated - return"), Logger::Debug); 1538 } 1539 1540 pkcs11KeyStoreListContext::pkcs11KeyStoreItem * 1541 pkcs11KeyStoreListContext::_registerTokenId(const pkcs11h_token_id_t token_id) 1542 { 1543 QCA_logTextMessage( 1544 QString::asprintf("pkcs11KeyStoreListContext::_registerTokenId - entry token_id=%p", (void *)token_id), 1545 Logger::Debug); 1546 1547 QMutexLocker l(&_mutexStores); 1548 1549 _stores_t::iterator i = _stores.begin(); 1550 1551 while (i != _stores.end() && !pkcs11h_token_sameTokenId(token_id, (*i)->tokenId())) { 1552 i++; 1553 } 1554 1555 pkcs11KeyStoreItem *entry = nullptr; 1556 1557 if (i == _stores.end()) { 1558 /* 1559 * Deal with last_id overlap 1560 */ 1561 while (_storesById.find(++_last_id) != _storesById.end()) 1562 ; 1563 1564 entry = new pkcs11KeyStoreItem(_last_id, token_id); 1565 1566 _stores += entry; 1567 _storesById.insert(entry->id(), entry); 1568 } else { 1569 entry = (*i); 1570 } 1571 1572 QCA_logTextMessage( 1573 QString::asprintf("pkcs11KeyStoreListContext::_registerTokenId - return entry=%p", (void *)token_id), 1574 Logger::Debug); 1575 1576 return entry; 1577 } 1578 1579 void pkcs11KeyStoreListContext::_clearStores() 1580 { 1581 QCA_logTextMessage(QStringLiteral("pkcs11KeyStoreListContext::_clearStores - entry"), Logger::Debug); 1582 1583 QMutexLocker l(&_mutexStores); 1584 1585 _storesById.clear(); 1586 foreach (pkcs11KeyStoreItem *i, _stores) { 1587 delete i; 1588 } 1589 1590 _stores.clear(); 1591 1592 QCA_logTextMessage(QStringLiteral("pkcs11KeyStoreListContext::_clearStores - return"), Logger::Debug); 1593 } 1594 1595 pkcs11KeyStoreEntryContext * 1596 pkcs11KeyStoreListContext::_keyStoreEntryByCertificateId(const pkcs11h_certificate_id_t certificate_id, 1597 const bool has_private, 1598 const CertificateChain &chain, 1599 const QString &_description) const 1600 { 1601 pkcs11KeyStoreEntryContext *entry = nullptr; 1602 1603 QCA_logTextMessage(QString::asprintf("pkcs11KeyStoreListContext::_keyStoreEntryByCertificateId - entry " 1604 "certificate_id=%p, has_private=%d, chain.size()=%d", 1605 (void *)certificate_id, 1606 has_private ? 1 : 0, 1607 int(chain.size())), 1608 Logger::Debug); 1609 1610 if (certificate_id == nullptr) { 1611 throw pkcs11Exception(CKR_ARGUMENTS_BAD, QStringLiteral("Missing certificate object")); 1612 } 1613 1614 QString serialized = _serializeCertificate(certificate_id, chain, has_private); 1615 1616 QString description = _description; 1617 const Certificate &cert = chain.primary(); 1618 if (description.isEmpty()) { 1619 description = cert.subjectInfoOrdered().toString() + QStringLiteral(" by ") + 1620 cert.issuerInfo().value(CommonName, QStringLiteral("Unknown")); 1621 } 1622 1623 if (has_private) { 1624 pkcs11RSAContext *rsakey = 1625 new pkcs11RSAContext(provider(), certificate_id, serialized, cert.subjectPublicKey().toRSA()); 1626 1627 pkcs11PKeyContext *pkc = new pkcs11PKeyContext(provider()); 1628 pkc->setKey(rsakey); 1629 PrivateKey privkey; 1630 privkey.change(pkc); 1631 KeyBundle key; 1632 key.setCertificateChainAndKey(chain, privkey); 1633 1634 entry = new pkcs11KeyStoreEntryContext(key, 1635 _tokenId2storeId(certificate_id->token_id), 1636 serialized, 1637 QString::fromLatin1(certificate_id->token_id->label), 1638 description, 1639 provider()); 1640 } else { 1641 entry = new pkcs11KeyStoreEntryContext(cert, 1642 _tokenId2storeId(certificate_id->token_id), 1643 serialized, 1644 QString::fromLatin1(certificate_id->token_id->label), 1645 description, 1646 provider()); 1647 } 1648 1649 QCA_logTextMessage( 1650 QString::asprintf("pkcs11KeyStoreListContext::_keyStoreEntryByCertificateId - return entry=%p", (void *)entry), 1651 Logger::Debug); 1652 1653 return entry; 1654 } 1655 1656 QString pkcs11KeyStoreListContext::_tokenId2storeId(const pkcs11h_token_id_t token_id) const 1657 { 1658 QString storeId; 1659 size_t len; 1660 1661 QCA_logTextMessage( 1662 QString::asprintf("pkcs11KeyStoreListContext::_tokenId2storeId - entry token_id=%p", (void *)token_id), 1663 Logger::Debug); 1664 1665 if (pkcs11h_token_serializeTokenId(nullptr, &len, token_id) != CKR_OK) { 1666 throw pkcs11Exception(CKR_FUNCTION_FAILED, QStringLiteral("Cannot serialize token id")); 1667 } 1668 1669 QByteArray buf; 1670 buf.resize((int)len); 1671 1672 if (pkcs11h_token_serializeTokenId(buf.data(), &len, token_id) != CKR_OK) { 1673 throw pkcs11Exception(CKR_FUNCTION_FAILED, QStringLiteral("Cannot serialize token id")); 1674 } 1675 1676 buf.resize((int)len); 1677 1678 storeId = QStringLiteral("qca-pkcs11/") + _escapeString(QString::fromUtf8(buf)); 1679 1680 QCA_logTextMessage( 1681 QString::asprintf("pkcs11KeyStoreListContext::_tokenId2storeId - return storeId='%s'", myPrintable(storeId)), 1682 Logger::Debug); 1683 1684 return storeId; 1685 } 1686 1687 QString pkcs11KeyStoreListContext::_serializeCertificate(const pkcs11h_certificate_id_t certificate_id, 1688 const CertificateChain &chain, 1689 const bool has_private) const 1690 { 1691 QString serialized; 1692 size_t len; 1693 1694 QCA_logTextMessage( 1695 QString::asprintf( 1696 "pkcs11KeyStoreListContext::_serializeCertificate - entry certificate_id=%p, xx, has_private=%d", 1697 (void *)certificate_id, 1698 has_private ? 1 : 0), 1699 Logger::Debug); 1700 1701 if (pkcs11h_certificate_serializeCertificateId(nullptr, &len, certificate_id) != CKR_OK) { 1702 throw pkcs11Exception(CKR_FUNCTION_FAILED, QStringLiteral("Cannot serialize certificate id")); 1703 } 1704 1705 QByteArray buf; 1706 buf.resize((int)len); 1707 1708 if (pkcs11h_certificate_serializeCertificateId(buf.data(), &len, certificate_id) != CKR_OK) { 1709 throw pkcs11Exception(CKR_FUNCTION_FAILED, QStringLiteral("Cannot serialize certificate id")); 1710 } 1711 1712 buf.resize((int)len); 1713 1714 serialized = QString::asprintf( 1715 "qca-pkcs11/0/%s/%d/", myPrintable(_escapeString(QString::fromUtf8(buf))), has_private ? 1 : 0); 1716 1717 QStringList list; 1718 foreach (Certificate i, chain) { 1719 list += _escapeString(Base64().arrayToString(i.toDER())); 1720 } 1721 1722 serialized.append(list.join(QStringLiteral("/"))); 1723 1724 QCA_logTextMessage(QString::asprintf("pkcs11KeyStoreListContext::_serializeCertificate - return serialized='%s'", 1725 myPrintable(serialized)), 1726 Logger::Debug); 1727 1728 return serialized; 1729 } 1730 1731 void pkcs11KeyStoreListContext::_deserializeCertificate(const QString &from, 1732 pkcs11h_certificate_id_t *const p_certificate_id, 1733 bool *const p_has_private, 1734 CertificateChain &chain) const 1735 { 1736 pkcs11h_certificate_id_t certificate_id = nullptr; 1737 chain.clear(); 1738 1739 QCA_logTextMessage(QString::asprintf("pkcs11KeyStoreListContext::_deserializeCertificate - entry from='%s', " 1740 "p_certificate_id=%p, p_has_private=%p", 1741 myPrintable(from), 1742 (void *)p_certificate_id, 1743 (void *)p_has_private), 1744 Logger::Debug); 1745 1746 try { 1747 int n = 0; 1748 CK_RV rv; 1749 1750 *p_certificate_id = nullptr; 1751 *p_has_private = false; 1752 1753 const QStringList list = from.split(QStringLiteral("/")); 1754 1755 if (list.size() < 5) { 1756 throw pkcs11Exception(CKR_FUNCTION_FAILED, QStringLiteral("Invalid serialization")); 1757 } 1758 1759 if (list[n++] != QLatin1String("qca-pkcs11")) { 1760 throw pkcs11Exception(CKR_FUNCTION_FAILED, QStringLiteral("Invalid serialization")); 1761 } 1762 1763 if (list[n++].toInt() != 0) { 1764 throw pkcs11Exception(CKR_FUNCTION_FAILED, QStringLiteral("Invalid serialization version")); 1765 } 1766 1767 if ((rv = pkcs11h_certificate_deserializeCertificateId(&certificate_id, 1768 myPrintable(_unescapeString(list[n++])))) != CKR_OK) { 1769 throw pkcs11Exception(rv, QStringLiteral("Invalid serialization")); 1770 } 1771 1772 *p_has_private = list[n++].toInt() != 0; 1773 1774 const QByteArray endCertificateBytes = Base64().stringToArray(_unescapeString(list[n++])).toByteArray(); 1775 Certificate endCertificate = Certificate::fromDER(endCertificateBytes); 1776 1777 if (endCertificate.isNull()) { 1778 throw pkcs11Exception(rv, QStringLiteral("Invalid certificate")); 1779 } 1780 1781 if ((rv = pkcs11h_certificate_setCertificateIdCertificateBlob(certificate_id, 1782 (const unsigned char *)endCertificateBytes.data(), 1783 (size_t)endCertificateBytes.size())) != CKR_OK) { 1784 throw pkcs11Exception(rv, QStringLiteral("Invalid serialization")); 1785 } 1786 1787 chain = endCertificate; 1788 while (n < list.size()) { 1789 Certificate cert = Certificate::fromDER(Base64().stringToArray(_unescapeString(list[n++])).toByteArray()); 1790 if (cert.isNull()) { 1791 throw pkcs11Exception(rv, QStringLiteral("Invalid certificate")); 1792 } 1793 chain += cert; 1794 } 1795 1796 *p_certificate_id = certificate_id; 1797 certificate_id = nullptr; 1798 } catch (...) { 1799 if (certificate_id != nullptr) { 1800 pkcs11h_certificate_freeCertificateId(certificate_id); 1801 certificate_id = nullptr; 1802 } 1803 throw; 1804 } 1805 1806 QCA_logTextMessage( 1807 QString::asprintf( 1808 "pkcs11KeyStoreListContext::_deserializeCertificate - return *p_certificate_id=%p, chain.size()=%d", 1809 (void *)*p_certificate_id, 1810 int(chain.size())), 1811 Logger::Debug); 1812 } 1813 1814 QString pkcs11KeyStoreListContext::_escapeString(const QString &from) const 1815 { 1816 QString to; 1817 1818 foreach (QChar c, from) { 1819 if (c == QLatin1Char('/') || c == QLatin1Char('\\')) { 1820 to += QString::asprintf("\\x%04x", c.unicode()); 1821 } else { 1822 to += c; 1823 } 1824 } 1825 1826 return to; 1827 } 1828 1829 QString pkcs11KeyStoreListContext::_unescapeString(const QString &from) const 1830 { 1831 QString to; 1832 1833 for (int i = 0; i < from.size(); i++) { 1834 QChar c = from[i]; 1835 1836 if (c == QLatin1Char('\\')) { 1837 #if QT_VERSION >= QT_VERSION_CHECK(5, 15, 2) 1838 to += QChar((ushort)QStringView(from).mid(i + 2, 4).toInt(nullptr, 16)); 1839 #else 1840 to += QChar((ushort)from.midRef(i + 2, 4).toInt(nullptr, 16)); 1841 #endif 1842 i += 5; 1843 } else { 1844 to += c; 1845 } 1846 } 1847 1848 return to; 1849 } 1850 1851 } 1852 1853 using namespace pkcs11QCAPlugin; 1854 1855 const int pkcs11Provider::_CONFIG_MAX_PROVIDERS = 10; 1856 1857 //---------------------------------------------------------------------------- 1858 // pkcs11Provider 1859 //---------------------------------------------------------------------------- 1860 pkcs11Provider::pkcs11Provider() 1861 { 1862 QCA_logTextMessage(QStringLiteral("pkcs11Provider::pkcs11Provider - entry"), Logger::Debug); 1863 1864 _lowLevelInitialized = false; 1865 _slotEventsActive = false; 1866 _slotEventsLowLevelActive = false; 1867 _allowLoadRootCA = false; 1868 1869 QCA_logTextMessage(QStringLiteral("pkcs11Provider::pkcs11Provider - return"), Logger::Debug); 1870 } 1871 1872 pkcs11Provider::~pkcs11Provider() 1873 { 1874 QCA_logTextMessage(QStringLiteral("pkcs11Provider::~pkcs11Provider - entry/return"), Logger::Debug); 1875 } 1876 1877 int pkcs11Provider::qcaVersion() const 1878 { 1879 QCA_logTextMessage(QStringLiteral("pkcs11Provider::qcaVersion - entry/return"), Logger::Debug); 1880 1881 return QCA_VERSION; 1882 } 1883 1884 void pkcs11Provider::init() 1885 { 1886 QCA_logTextMessage(QStringLiteral("pkcs11Provider::init - entry"), Logger::Debug); 1887 1888 try { 1889 CK_RV rv; 1890 1891 if ((rv = pkcs11h_engine_setCrypto(&pkcs11QCACrypto::crypto)) != CKR_OK) { 1892 throw pkcs11Exception(rv, QStringLiteral("Cannot set crypto")); 1893 } 1894 1895 if ((rv = pkcs11h_initialize()) != CKR_OK) { 1896 throw pkcs11Exception(rv, QStringLiteral("Cannot initialize")); 1897 } 1898 1899 if ((rv = pkcs11h_setLogHook(__logHook, this)) != CKR_OK) { 1900 throw pkcs11Exception(rv, QStringLiteral("Cannot set hook")); 1901 } 1902 1903 pkcs11h_setLogLevel(0); 1904 1905 if ((rv = pkcs11h_setTokenPromptHook(__tokenPromptHook, this)) != CKR_OK) { 1906 throw pkcs11Exception(rv, QStringLiteral("Cannot set hook")); 1907 } 1908 1909 if ((rv = pkcs11h_setPINPromptHook(__pinPromptHook, this)) != CKR_OK) { 1910 throw pkcs11Exception(rv, QStringLiteral("Cannot set hook")); 1911 } 1912 1913 _lowLevelInitialized = true; 1914 } catch (const pkcs11Exception &e) { 1915 QCA_logTextMessage(e.message(), Logger::Error); 1916 appendPluginDiagnosticText( 1917 QString::asprintf("An error %s during initialization of qca-pkcs11 plugin\n", myPrintable(e.message()))); 1918 } catch (...) { 1919 QCA_logTextMessage(QStringLiteral("PKCS#11: Unknown error during provider initialization"), Logger::Error); 1920 appendPluginDiagnosticText(QStringLiteral("Unknown error during initialization of qca-pkcs11 plugin\n")); 1921 } 1922 1923 QCA_logTextMessage(QStringLiteral("pkcs11Provider::init - return"), Logger::Debug); 1924 } 1925 1926 void pkcs11Provider::deinit() 1927 { 1928 QCA_logTextMessage(QStringLiteral("pkcs11Provider::deinit - entry"), Logger::Debug); 1929 1930 delete s_keyStoreList; 1931 s_keyStoreList = nullptr; 1932 1933 pkcs11h_terminate(); 1934 1935 QCA_logTextMessage(QStringLiteral("pkcs11Provider::deinit - return"), Logger::Debug); 1936 } 1937 1938 QString pkcs11Provider::name() const 1939 { 1940 QCA_logTextMessage(QStringLiteral("pkcs11Provider::name - entry/return"), Logger::Debug); 1941 1942 return QStringLiteral("qca-pkcs11"); 1943 } 1944 1945 QStringList pkcs11Provider::features() const 1946 { 1947 QCA_logTextMessage(QStringLiteral("pkcs11Provider::features - entry/return"), Logger::Debug); 1948 1949 QStringList list; 1950 list += QStringLiteral("smartcard"); // indicator, not algorithm 1951 list += QStringLiteral("pkey"); 1952 list += QStringLiteral("keystorelist"); 1953 return list; 1954 } 1955 1956 Provider::Context *pkcs11Provider::createContext(const QString &type) 1957 { 1958 Provider::Context *context = nullptr; 1959 1960 QCA_logTextMessage(QString::asprintf("pkcs11Provider::createContext - entry type='%s'", myPrintable(type)), 1961 Logger::Debug); 1962 1963 if (_lowLevelInitialized) { 1964 if (type == QLatin1String("keystorelist")) { 1965 if (s_keyStoreList == nullptr) { 1966 s_keyStoreList = new pkcs11KeyStoreListContext(this); 1967 } 1968 context = s_keyStoreList; 1969 } 1970 } 1971 1972 QCA_logTextMessage(QString::asprintf("pkcs11Provider::createContext - return context=%p", (void *)context), 1973 Logger::Debug); 1974 1975 return context; 1976 } 1977 1978 void pkcs11Provider::startSlotEvents() 1979 { 1980 CK_RV rv; 1981 1982 QCA_logTextMessage(QStringLiteral("pkcs11Provider::startSlotEvents - entry"), Logger::Debug); 1983 1984 if (_lowLevelInitialized) { 1985 if (!_slotEventsLowLevelActive) { 1986 if ((rv = pkcs11h_setSlotEventHook(__slotEventHook, this)) != CKR_OK) { 1987 throw pkcs11Exception(rv, QStringLiteral("Cannot start slot events")); 1988 } 1989 1990 _slotEventsLowLevelActive = true; 1991 } 1992 1993 _slotEventsActive = true; 1994 } 1995 1996 QCA_logTextMessage(QStringLiteral("pkcs11Provider::startSlotEvents - return"), Logger::Debug); 1997 } 1998 1999 void pkcs11Provider::stopSlotEvents() 2000 { 2001 QCA_logTextMessage(QStringLiteral("pkcs11Provider::stopSlotEvents - entry/return"), Logger::Debug); 2002 2003 _slotEventsActive = false; 2004 } 2005 2006 QVariantMap pkcs11Provider::defaultConfig() const 2007 { 2008 QVariantMap mytemplate; 2009 2010 QCA_logTextMessage(QStringLiteral("pkcs11Provider::defaultConfig - entry/return"), Logger::Debug); 2011 2012 mytemplate[QStringLiteral("formtype")] = QStringLiteral("http://affinix.com/qca/forms/qca-pkcs11#1.0"); 2013 mytemplate[QStringLiteral("allow_load_rootca")] = false; 2014 mytemplate[QStringLiteral("allow_protected_authentication")] = true; 2015 mytemplate[QStringLiteral("pin_cache")] = PKCS11H_PIN_CACHE_INFINITE; 2016 mytemplate[QStringLiteral("log_level")] = 0; 2017 for (int i = 0; i < _CONFIG_MAX_PROVIDERS; i++) { 2018 mytemplate[QString::asprintf("provider_%02d_enabled", i)] = false; 2019 mytemplate[QString::asprintf("provider_%02d_name", i)] = QLatin1String(""); 2020 mytemplate[QString::asprintf("provider_%02d_library", i)] = QLatin1String(""); 2021 mytemplate[QString::asprintf("provider_%02d_allow_protected_authentication", i)] = true; 2022 mytemplate[QString::asprintf("provider_%02d_cert_private", i)] = false; 2023 mytemplate[QString::asprintf("provider_%02d_private_mask", i)] = PKCS11H_PRIVATEMODE_MASK_AUTO; 2024 mytemplate[QString::asprintf("provider_%02d_slotevent_method", i)] = QStringLiteral("auto"); 2025 mytemplate[QString::asprintf("provider_%02d_slotevent_timeout", i)] = 0; 2026 } 2027 2028 return mytemplate; 2029 } 2030 2031 void pkcs11Provider::configChanged(const QVariantMap &config) 2032 { 2033 CK_RV rv = CKR_OK; 2034 2035 QCA_logTextMessage(QStringLiteral("pkcs11Provider::configChanged - entry"), Logger::Debug); 2036 2037 if (!_lowLevelInitialized) { 2038 QCA_logTextMessage(QStringLiteral("PKCS#11: Not initialized"), Logger::Error); 2039 return; 2040 } 2041 2042 _allowLoadRootCA = config[QStringLiteral("allow_load_rootca")].toBool(); 2043 2044 pkcs11h_setLogLevel(config[QStringLiteral("log_level")].toInt()); 2045 pkcs11h_setProtectedAuthentication(config[QStringLiteral("allow_protected_authentication")].toBool() != false 2046 ? TRUE 2047 : FALSE // krazy:exclude=captruefalse 2048 ); 2049 pkcs11h_setPINCachePeriod(config[QStringLiteral("pin_cache")].toInt()); 2050 2051 /* 2052 * Remove current providers 2053 */ 2054 foreach (QString i, _providers) { 2055 pkcs11h_removeProvider(myPrintable(i)); 2056 } 2057 _providers.clear(); 2058 2059 /* 2060 * Add new providers 2061 */ 2062 for (int i = 0; i < _CONFIG_MAX_PROVIDERS; i++) { 2063 bool enabled = config[QString::asprintf("provider_%02d_enabled", i)].toBool(); 2064 QString provider = config[QString::asprintf("provider_%02d_library", i)].toString(); 2065 QString name = config[QString::asprintf("provider_%02d_name", i)].toString(); 2066 QString qslotevent = config[QString::asprintf("provider_%02d_slotevent_method", i)].toString(); 2067 unsigned slotevent = PKCS11H_SLOTEVENT_METHOD_AUTO; 2068 if (qslotevent == QLatin1String("trigger")) { 2069 slotevent = PKCS11H_SLOTEVENT_METHOD_TRIGGER; 2070 } else if (qslotevent == QLatin1String("poll")) { 2071 slotevent = PKCS11H_SLOTEVENT_METHOD_POLL; 2072 } 2073 2074 if (name.isEmpty()) { 2075 name = provider; 2076 } 2077 2078 if (enabled && !provider.isEmpty()) { 2079 QCA_logTextMessage( 2080 QString::asprintf("Loading PKCS#11 provider '%s' (%s)", myPrintable(name), myPrintable(provider)), 2081 Logger::Information); 2082 2083 if ((rv = pkcs11h_addProvider( 2084 myPrintable(name), 2085 myPrintable(provider), 2086 config[QString::asprintf("provider_%02d_allow_protected_authentication", i)].toBool() != false 2087 ? TRUE 2088 : FALSE, // krazy:exclude=captruefalse 2089 (unsigned)config[QString::asprintf("provider_%02d_private_mask", i)].toInt(), 2090 slotevent, 2091 (unsigned)config[QString::asprintf("provider_%02d_slotevent_timeout", i)].toInt(), 2092 config[QString::asprintf("provider_%02d_cert_private", i)].toBool() != false 2093 ? TRUE 2094 : FALSE // krazy:exclude=captruefalse 2095 )) != CKR_OK) { 2096 QCA_logTextMessage(QString::asprintf("PKCS#11: Cannot log provider '%s'-'%s' %lu-'%s'.\n", 2097 myPrintable(name), 2098 myPrintable(provider), 2099 rv, 2100 pkcs11h_getMessage(rv)), 2101 Logger::Error); 2102 appendPluginDiagnosticText(QString::asprintf("Cannot load PKCS#11 provider '%s'\n", myPrintable(name))); 2103 } else { 2104 _providers += provider; 2105 } 2106 } 2107 } 2108 2109 QCA_logTextMessage(QStringLiteral("pkcs11Provider::configChanged - return"), Logger::Debug); 2110 } 2111 2112 void pkcs11Provider::__logHook(void *const global_data, const unsigned flags, const char *const format, va_list args) 2113 { 2114 pkcs11Provider *me = (pkcs11Provider *)global_data; 2115 me->_logHook(flags, format, args); 2116 } 2117 2118 void pkcs11Provider::__slotEventHook(void *const global_data) 2119 { 2120 pkcs11Provider *me = (pkcs11Provider *)global_data; 2121 me->_slotEventHook(); 2122 } 2123 2124 PKCS11H_BOOL 2125 pkcs11Provider::__tokenPromptHook(void *const global_data, 2126 void *const user_data, 2127 const pkcs11h_token_id_t token, 2128 const unsigned retry) 2129 { 2130 Q_UNUSED(retry); 2131 2132 pkcs11Provider *me = (pkcs11Provider *)global_data; 2133 return me->_tokenPromptHook(user_data, token); 2134 } 2135 2136 PKCS11H_BOOL 2137 pkcs11Provider::__pinPromptHook(void *const global_data, 2138 void *const user_data, 2139 const pkcs11h_token_id_t token, 2140 const unsigned retry, 2141 char *const pin, 2142 const size_t pin_max) 2143 { 2144 Q_UNUSED(retry); 2145 2146 pkcs11Provider *me = (pkcs11Provider *)global_data; 2147 return me->_pinPromptHook(user_data, token, pin, pin_max); 2148 } 2149 2150 void pkcs11Provider::_logHook(const unsigned flags, const char *const format, va_list args) 2151 { 2152 Logger::Severity severity; 2153 2154 switch (flags) { 2155 case PKCS11H_LOG_DEBUG2: 2156 case PKCS11H_LOG_DEBUG1: 2157 severity = Logger::Debug; 2158 break; 2159 case PKCS11H_LOG_INFO: 2160 severity = Logger::Information; 2161 break; 2162 case PKCS11H_LOG_WARN: 2163 severity = Logger::Warning; 2164 break; 2165 case PKCS11H_LOG_ERROR: 2166 severity = Logger::Error; 2167 break; 2168 default: 2169 severity = Logger::Debug; 2170 break; 2171 } 2172 2173 //@BEGIN-WORKAROUND 2174 // Qt vsprintf cannot can NULL for %s as vsprintf does. 2175 // QCA_logTextMessage (QString ().vsprintf (format, args), severity); 2176 char buffer[2048]; 2177 qvsnprintf(buffer, sizeof(buffer) - 1, format, args); 2178 buffer[sizeof(buffer) - 1] = '\x0'; 2179 QCA_logTextMessage(QString::fromLatin1(buffer), severity); 2180 //@END-WORKAROUND 2181 } 2182 2183 void pkcs11Provider::_slotEventHook() 2184 { 2185 /* 2186 * This is called from a separate 2187 * thread. 2188 */ 2189 if (s_keyStoreList != nullptr && _slotEventsActive) { 2190 QMetaObject::invokeMethod(s_keyStoreList, "doUpdated", Qt::QueuedConnection); 2191 } 2192 } 2193 2194 PKCS11H_BOOL 2195 pkcs11Provider::_tokenPromptHook(void *const user_data, const pkcs11h_token_id_t token) 2196 { 2197 if (s_keyStoreList != nullptr) { 2198 return s_keyStoreList->_tokenPrompt(user_data, token) ? TRUE : FALSE; // krazy:exclude=captruefalse 2199 } 2200 2201 return FALSE; // krazy:exclude=captruefalse 2202 } 2203 2204 PKCS11H_BOOL 2205 pkcs11Provider::_pinPromptHook(void *const user_data, 2206 const pkcs11h_token_id_t token, 2207 char *const pin, 2208 const size_t pin_max) 2209 { 2210 PKCS11H_BOOL ret = FALSE; // krazy:exclude=captruefalse 2211 2212 if (s_keyStoreList != nullptr) { 2213 SecureArray qpin; 2214 2215 if (s_keyStoreList->_pinPrompt(user_data, token, qpin)) { 2216 if ((size_t)qpin.size() < pin_max - 1) { 2217 memmove(pin, qpin.constData(), qpin.size()); 2218 pin[qpin.size()] = '\0'; 2219 ret = TRUE; // krazy:exclude=captruefalse 2220 } 2221 } 2222 } 2223 2224 return ret; // krazy:exclude=captruefalse 2225 } 2226 2227 class pkcs11Plugin : public QObject, public QCAPlugin 2228 { 2229 Q_OBJECT 2230 Q_PLUGIN_METADATA(IID "com.affinix.qca.Plugin/1.0") 2231 Q_INTERFACES(QCAPlugin) 2232 2233 public: 2234 Provider *createProvider() override 2235 { 2236 return new pkcs11Provider; 2237 } 2238 }; 2239 2240 #include "qca-pkcs11.moc"