File indexing completed on 2024-12-08 04:20:08
0001 /* 0002 * Copyright (C) 2003-2007 Justin Karneges <justin@affinix.com> 0003 * Copyright (C) 2004,2005 Brad Hards <bradh@frogmouth.net> 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 WITHOUT ANY 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 0018 * 02110-1301 USA 0019 * 0020 */ 0021 0022 #include "qca_securemessage.h" 0023 0024 #include "qca_safeobj.h" 0025 #include "qca_safetimer.h" 0026 #include "qcaprovider.h" 0027 0028 namespace QCA { 0029 0030 Provider::Context *getContext(const QString &type, const QString &provider); 0031 0032 //---------------------------------------------------------------------------- 0033 // SecureMessageKey 0034 //---------------------------------------------------------------------------- 0035 class SecureMessageKey::Private : public QSharedData 0036 { 0037 public: 0038 SecureMessageKey::Type type; 0039 PGPKey pgp_pub, pgp_sec; 0040 CertificateChain cert_pub; 0041 PrivateKey cert_sec; 0042 0043 Private() 0044 { 0045 type = SecureMessageKey::None; 0046 } 0047 0048 // set the proper type, and reset the opposite data structures if needed 0049 void ensureType(SecureMessageKey::Type t) 0050 { 0051 // if we were non-null and changed, we may need to reset some things 0052 if (type != SecureMessageKey::None && t != type) { 0053 if (type == SecureMessageKey::X509) { 0054 cert_pub = CertificateChain(); 0055 cert_sec = PrivateKey(); 0056 } else if (type == SecureMessageKey::PGP) { 0057 pgp_pub = PGPKey(); 0058 pgp_sec = PGPKey(); 0059 } 0060 } 0061 type = t; 0062 } 0063 }; 0064 0065 SecureMessageKey::SecureMessageKey() 0066 : d(new Private) 0067 { 0068 } 0069 0070 SecureMessageKey::SecureMessageKey(const SecureMessageKey &from) 0071 : d(from.d) 0072 { 0073 } 0074 0075 SecureMessageKey::~SecureMessageKey() 0076 { 0077 } 0078 0079 SecureMessageKey &SecureMessageKey::operator=(const SecureMessageKey &from) 0080 { 0081 d = from.d; 0082 return *this; 0083 } 0084 0085 bool SecureMessageKey::isNull() const 0086 { 0087 return (d->type == None); 0088 } 0089 0090 SecureMessageKey::Type SecureMessageKey::type() const 0091 { 0092 return d->type; 0093 } 0094 0095 PGPKey SecureMessageKey::pgpPublicKey() const 0096 { 0097 return d->pgp_pub; 0098 } 0099 0100 PGPKey SecureMessageKey::pgpSecretKey() const 0101 { 0102 return d->pgp_sec; 0103 } 0104 0105 void SecureMessageKey::setPGPPublicKey(const PGPKey &pub) 0106 { 0107 d->ensureType(SecureMessageKey::PGP); 0108 d->pgp_pub = pub; 0109 } 0110 0111 void SecureMessageKey::setPGPSecretKey(const PGPKey &sec) 0112 { 0113 d->ensureType(SecureMessageKey::PGP); 0114 Q_ASSERT(sec.isSecret()); 0115 d->pgp_sec = sec; 0116 } 0117 0118 CertificateChain SecureMessageKey::x509CertificateChain() const 0119 { 0120 return d->cert_pub; 0121 } 0122 0123 PrivateKey SecureMessageKey::x509PrivateKey() const 0124 { 0125 return d->cert_sec; 0126 } 0127 0128 void SecureMessageKey::setX509CertificateChain(const CertificateChain &c) 0129 { 0130 d->ensureType(SecureMessageKey::X509); 0131 d->cert_pub = c; 0132 } 0133 0134 void SecureMessageKey::setX509PrivateKey(const PrivateKey &k) 0135 { 0136 d->ensureType(SecureMessageKey::X509); 0137 d->cert_sec = k; 0138 } 0139 0140 void SecureMessageKey::setX509KeyBundle(const KeyBundle &kb) 0141 { 0142 setX509CertificateChain(kb.certificateChain()); 0143 setX509PrivateKey(kb.privateKey()); 0144 } 0145 0146 bool SecureMessageKey::havePrivate() const 0147 { 0148 if (d->type == SecureMessageKey::PGP && !d->pgp_sec.isNull()) 0149 return true; 0150 else if (d->type == SecureMessageKey::X509 && !d->cert_sec.isNull()) 0151 return true; 0152 return false; 0153 } 0154 0155 QString SecureMessageKey::name() const 0156 { 0157 if (d->type == SecureMessageKey::PGP && !d->pgp_pub.isNull()) 0158 return d->pgp_pub.primaryUserId(); 0159 else if (d->type == SecureMessageKey::X509 && !d->cert_pub.isEmpty()) 0160 return d->cert_pub.primary().commonName(); 0161 else 0162 return QString(); 0163 } 0164 0165 //---------------------------------------------------------------------------- 0166 // SecureMessageSignature 0167 //---------------------------------------------------------------------------- 0168 class SecureMessageSignature::Private : public QSharedData 0169 { 0170 public: 0171 SecureMessageSignature::IdentityResult r; 0172 Validity v; 0173 SecureMessageKey key; 0174 QDateTime ts; 0175 0176 Private() 0177 { 0178 r = SecureMessageSignature::NoKey; 0179 v = ErrorValidityUnknown; 0180 } 0181 }; 0182 0183 SecureMessageSignature::SecureMessageSignature() 0184 : d(new Private) 0185 { 0186 } 0187 0188 SecureMessageSignature::SecureMessageSignature(IdentityResult r, 0189 Validity v, 0190 const SecureMessageKey &key, 0191 const QDateTime &ts) 0192 : d(new Private) 0193 { 0194 d->r = r; 0195 d->v = v; 0196 d->key = key; 0197 d->ts = ts; 0198 } 0199 0200 SecureMessageSignature::SecureMessageSignature(const SecureMessageSignature &from) 0201 : d(from.d) 0202 { 0203 } 0204 0205 SecureMessageSignature::~SecureMessageSignature() 0206 { 0207 } 0208 0209 SecureMessageSignature &SecureMessageSignature::operator=(const SecureMessageSignature &from) 0210 { 0211 d = from.d; 0212 return *this; 0213 } 0214 0215 SecureMessageSignature::IdentityResult SecureMessageSignature::identityResult() const 0216 { 0217 return d->r; 0218 } 0219 0220 Validity SecureMessageSignature::keyValidity() const 0221 { 0222 return d->v; 0223 } 0224 0225 SecureMessageKey SecureMessageSignature::key() const 0226 { 0227 return d->key; 0228 } 0229 0230 QDateTime SecureMessageSignature::timestamp() const 0231 { 0232 return d->ts; 0233 } 0234 0235 //---------------------------------------------------------------------------- 0236 // SecureMessage 0237 //---------------------------------------------------------------------------- 0238 enum ResetMode 0239 { 0240 ResetSession = 0, 0241 ResetSessionAndData = 1, 0242 ResetAll = 2 0243 }; 0244 0245 class SecureMessage::Private : public QObject 0246 { 0247 Q_OBJECT 0248 public: 0249 SecureMessage *q; 0250 MessageContext *c; 0251 SecureMessageSystem *system; 0252 0253 bool bundleSigner, smime; 0254 SecureMessage::Format format; 0255 SecureMessageKeyList to; 0256 SecureMessageKeyList from; 0257 0258 QByteArray in; 0259 bool success; 0260 SecureMessage::Error errorCode; 0261 QByteArray detachedSig; 0262 QString hashName; 0263 SecureMessageSignatureList signers; 0264 QString dtext; 0265 0266 QList<int> bytesWrittenArgs; 0267 SafeTimer readyReadTrigger, bytesWrittenTrigger, finishedTrigger; 0268 0269 Private(SecureMessage *_q) 0270 : readyReadTrigger(this) 0271 , bytesWrittenTrigger(this) 0272 , finishedTrigger(this) 0273 { 0274 q = _q; 0275 c = nullptr; 0276 system = nullptr; 0277 0278 readyReadTrigger.setSingleShot(true); 0279 bytesWrittenTrigger.setSingleShot(true); 0280 finishedTrigger.setSingleShot(true); 0281 connect(&readyReadTrigger, &SafeTimer::timeout, this, &Private::t_readyRead); 0282 connect(&bytesWrittenTrigger, &SafeTimer::timeout, this, &Private::t_bytesWritten); 0283 connect(&finishedTrigger, &SafeTimer::timeout, this, &Private::t_finished); 0284 0285 reset(ResetAll); 0286 } 0287 0288 void init() 0289 { 0290 connect(c, &MessageContext::updated, this, &Private::updated); 0291 } 0292 0293 void reset(ResetMode mode) 0294 { 0295 if (c) 0296 c->reset(); 0297 0298 bytesWrittenArgs.clear(); 0299 readyReadTrigger.stop(); 0300 bytesWrittenTrigger.stop(); 0301 finishedTrigger.stop(); 0302 0303 if (mode >= ResetSessionAndData) { 0304 in.clear(); 0305 success = false; 0306 errorCode = SecureMessage::ErrorUnknown; 0307 detachedSig.clear(); 0308 hashName = QString(); 0309 signers.clear(); 0310 } 0311 0312 if (mode >= ResetAll) { 0313 bundleSigner = true; 0314 format = SecureMessage::Binary; 0315 to.clear(); 0316 from.clear(); 0317 } 0318 } 0319 0320 public Q_SLOTS: 0321 void updated() 0322 { 0323 bool sig_read = false; 0324 bool sig_written = false; 0325 bool sig_done = false; 0326 int written = 0; 0327 { 0328 const QByteArray a = c->read(); 0329 if (!a.isEmpty()) { 0330 sig_read = true; 0331 in.append(a); 0332 } 0333 0334 const int x = c->written(); 0335 if (x > 0) { 0336 sig_written = true; 0337 written = x; 0338 } 0339 } 0340 0341 if (c->finished()) { 0342 sig_done = true; 0343 0344 success = c->success(); 0345 errorCode = c->errorCode(); 0346 dtext = c->diagnosticText(); 0347 if (success) { 0348 detachedSig = c->signature(); 0349 hashName = c->hashName(); 0350 signers = c->signers(); 0351 } 0352 reset(ResetSession); 0353 } 0354 0355 if (sig_read) 0356 readyReadTrigger.start(); 0357 if (sig_written) { 0358 bytesWrittenArgs += written; 0359 bytesWrittenTrigger.start(); 0360 } 0361 if (sig_done) 0362 finishedTrigger.start(); 0363 } 0364 0365 void t_readyRead() 0366 { 0367 emit q->readyRead(); 0368 } 0369 0370 void t_bytesWritten() 0371 { 0372 emit q->bytesWritten(bytesWrittenArgs.takeFirst()); 0373 } 0374 0375 void t_finished() 0376 { 0377 emit q->finished(); 0378 } 0379 }; 0380 0381 SecureMessage::SecureMessage(SecureMessageSystem *system) 0382 { 0383 d = new Private(this); 0384 d->system = system; 0385 d->c = static_cast<SMSContext *>(d->system->context())->createMessage(); 0386 change(d->c); 0387 d->init(); 0388 } 0389 0390 SecureMessage::~SecureMessage() 0391 { 0392 delete d; 0393 } 0394 0395 SecureMessage::Type SecureMessage::type() const 0396 { 0397 return d->c->type(); 0398 } 0399 0400 bool SecureMessage::canSignMultiple() const 0401 { 0402 return d->c->canSignMultiple(); 0403 } 0404 0405 bool SecureMessage::canClearsign() const 0406 { 0407 return (type() == OpenPGP); 0408 } 0409 0410 bool SecureMessage::canSignAndEncrypt() const 0411 { 0412 return (type() == OpenPGP); 0413 } 0414 0415 void SecureMessage::reset() 0416 { 0417 d->reset(ResetAll); 0418 } 0419 0420 bool SecureMessage::bundleSignerEnabled() const 0421 { 0422 return d->bundleSigner; 0423 } 0424 0425 bool SecureMessage::smimeAttributesEnabled() const 0426 { 0427 return d->smime; 0428 } 0429 0430 SecureMessage::Format SecureMessage::format() const 0431 { 0432 return d->format; 0433 } 0434 0435 SecureMessageKeyList SecureMessage::recipientKeys() const 0436 { 0437 return d->to; 0438 } 0439 0440 SecureMessageKeyList SecureMessage::signerKeys() const 0441 { 0442 return d->from; 0443 } 0444 0445 void SecureMessage::setBundleSignerEnabled(bool b) 0446 { 0447 d->bundleSigner = b; 0448 } 0449 0450 void SecureMessage::setSMIMEAttributesEnabled(bool b) 0451 { 0452 d->smime = b; 0453 } 0454 0455 void SecureMessage::setFormat(Format f) 0456 { 0457 d->format = f; 0458 } 0459 0460 void SecureMessage::setRecipient(const SecureMessageKey &key) 0461 { 0462 d->to = SecureMessageKeyList() << key; 0463 } 0464 0465 void SecureMessage::setRecipients(const SecureMessageKeyList &keys) 0466 { 0467 d->to = keys; 0468 } 0469 0470 void SecureMessage::setSigner(const SecureMessageKey &key) 0471 { 0472 d->from = SecureMessageKeyList() << key; 0473 } 0474 0475 void SecureMessage::setSigners(const SecureMessageKeyList &keys) 0476 { 0477 d->from = keys; 0478 } 0479 0480 void SecureMessage::startEncrypt() 0481 { 0482 d->reset(ResetSessionAndData); 0483 d->c->setupEncrypt(d->to); 0484 d->c->start(d->format, MessageContext::Encrypt); 0485 } 0486 0487 void SecureMessage::startDecrypt() 0488 { 0489 d->reset(ResetSessionAndData); 0490 d->c->start(d->format, MessageContext::Decrypt); 0491 } 0492 0493 void SecureMessage::startSign(SignMode m) 0494 { 0495 d->reset(ResetSessionAndData); 0496 d->c->setupSign(d->from, m, d->bundleSigner, d->smime); 0497 d->c->start(d->format, MessageContext::Sign); 0498 } 0499 0500 void SecureMessage::startVerify(const QByteArray &sig) 0501 { 0502 d->reset(ResetSessionAndData); 0503 if (!sig.isEmpty()) 0504 d->c->setupVerify(sig); 0505 d->c->start(d->format, MessageContext::Verify); 0506 } 0507 0508 void SecureMessage::startSignAndEncrypt() 0509 { 0510 d->reset(ResetSessionAndData); 0511 d->c->setupEncrypt(d->to); 0512 d->c->setupSign(d->from, Message, d->bundleSigner, d->smime); 0513 d->c->start(d->format, MessageContext::SignAndEncrypt); 0514 } 0515 0516 void SecureMessage::update(const QByteArray &in) 0517 { 0518 d->c->update(in); 0519 } 0520 0521 QByteArray SecureMessage::read() 0522 { 0523 const QByteArray a = d->in; 0524 d->in.clear(); 0525 return a; 0526 } 0527 0528 int SecureMessage::bytesAvailable() const 0529 { 0530 return d->in.size(); 0531 } 0532 0533 void SecureMessage::end() 0534 { 0535 d->c->end(); 0536 } 0537 0538 bool SecureMessage::waitForFinished(int msecs) 0539 { 0540 d->c->waitForFinished(msecs); 0541 d->updated(); 0542 return d->success; 0543 } 0544 0545 bool SecureMessage::success() const 0546 { 0547 return d->success; 0548 } 0549 0550 SecureMessage::Error SecureMessage::errorCode() const 0551 { 0552 return d->errorCode; 0553 } 0554 0555 QByteArray SecureMessage::signature() const 0556 { 0557 return d->detachedSig; 0558 } 0559 0560 QString SecureMessage::hashName() const 0561 { 0562 return d->hashName; 0563 } 0564 0565 bool SecureMessage::wasSigned() const 0566 { 0567 return !d->signers.isEmpty(); 0568 } 0569 0570 bool SecureMessage::verifySuccess() const 0571 { 0572 // if we're not done or there were no signers, then return false 0573 if (!d->success || d->signers.isEmpty()) 0574 return false; 0575 0576 // make sure all signers have a valid signature 0577 for (int n = 0; n < d->signers.count(); ++n) { 0578 if (d->signers[n].identityResult() != SecureMessageSignature::Valid) 0579 return false; 0580 } 0581 return true; 0582 } 0583 0584 SecureMessageSignature SecureMessage::signer() const 0585 { 0586 if (d->signers.isEmpty()) 0587 return SecureMessageSignature(); 0588 0589 return d->signers.first(); 0590 } 0591 0592 SecureMessageSignatureList SecureMessage::signers() const 0593 { 0594 return d->signers; 0595 } 0596 0597 QString SecureMessage::diagnosticText() const 0598 { 0599 return d->dtext; 0600 } 0601 0602 //---------------------------------------------------------------------------- 0603 // SecureMessageSystem 0604 //---------------------------------------------------------------------------- 0605 SecureMessageSystem::SecureMessageSystem(QObject *parent, const QString &type, const QString &provider) 0606 : QObject(parent) 0607 , Algorithm(type, provider) 0608 { 0609 } 0610 0611 SecureMessageSystem::~SecureMessageSystem() 0612 { 0613 } 0614 0615 //---------------------------------------------------------------------------- 0616 // OpenPGP 0617 //---------------------------------------------------------------------------- 0618 OpenPGP::OpenPGP(QObject *parent, const QString &provider) 0619 : SecureMessageSystem(parent, QStringLiteral("openpgp"), provider) 0620 { 0621 } 0622 0623 OpenPGP::~OpenPGP() 0624 { 0625 } 0626 0627 //---------------------------------------------------------------------------- 0628 // CMS 0629 //---------------------------------------------------------------------------- 0630 class CMS::Private 0631 { 0632 public: 0633 CertificateCollection trusted, untrusted; 0634 SecureMessageKeyList privateKeys; 0635 }; 0636 0637 CMS::CMS(QObject *parent, const QString &provider) 0638 : SecureMessageSystem(parent, QStringLiteral("cms"), provider) 0639 { 0640 d = new Private; 0641 } 0642 0643 CMS::~CMS() 0644 { 0645 delete d; 0646 } 0647 0648 CertificateCollection CMS::trustedCertificates() const 0649 { 0650 return d->trusted; 0651 } 0652 0653 CertificateCollection CMS::untrustedCertificates() const 0654 { 0655 return d->untrusted; 0656 } 0657 0658 SecureMessageKeyList CMS::privateKeys() const 0659 { 0660 return d->privateKeys; 0661 } 0662 0663 void CMS::setTrustedCertificates(const CertificateCollection &trusted) 0664 { 0665 d->trusted = trusted; 0666 static_cast<SMSContext *>(context())->setTrustedCertificates(trusted); 0667 } 0668 0669 void CMS::setUntrustedCertificates(const CertificateCollection &untrusted) 0670 { 0671 d->untrusted = untrusted; 0672 static_cast<SMSContext *>(context())->setUntrustedCertificates(untrusted); 0673 } 0674 0675 void CMS::setPrivateKeys(const SecureMessageKeyList &keys) 0676 { 0677 d->privateKeys = keys; 0678 static_cast<SMSContext *>(context())->setPrivateKeys(keys); 0679 } 0680 0681 } 0682 0683 #include "qca_securemessage.moc"