File indexing completed on 2024-11-10 07:20:44

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"