• Skip to content
  • Skip to link menu
KDE 4.4 API Reference
  • KDE API Reference
  • KDE Support
  • Sitemap
  • Contact Us
 

qca

qca_securemessage.cpp

Go to the documentation of this file.
00001 /*
00002  * Copyright (C) 2003-2007  Justin Karneges <justin@affinix.com>
00003  * Copyright (C) 2004,2005  Brad Hards <bradh@frogmouth.net>
00004  *
00005  * This library is free software; you can redistribute it and/or
00006  * modify it under the terms of the GNU Lesser General Public
00007  * License as published by the Free Software Foundation; either
00008  * version 2.1 of the License, or (at your option) any later version.
00009  *
00010  * This library is distributed in the hope that it will be useful,
00011  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00012  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00013  * Lesser General Public License for more details.
00014  *
00015  * You should have received a copy of the GNU Lesser General Public
00016  * License along with this library; if not, write to the Free Software
00017  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
00018  * 02110-1301  USA
00019  *
00020  */
00021 
00022 #include "qca_securemessage.h"
00023 
00024 #include "qcaprovider.h"
00025 #include "qca_safeobj.h"
00026 
00027 namespace QCA {
00028 
00029 Provider::Context *getContext(const QString &type, const QString &provider);
00030 
00031 //----------------------------------------------------------------------------
00032 // SecureMessageKey
00033 //----------------------------------------------------------------------------
00034 class SecureMessageKey::Private : public QSharedData
00035 {
00036 public:
00037     SecureMessageKey::Type type;
00038     PGPKey pgp_pub, pgp_sec;
00039     CertificateChain cert_pub;
00040     PrivateKey cert_sec;
00041 
00042     Private()
00043     {
00044         type = SecureMessageKey::None;
00045     }
00046 
00047     // set the proper type, and reset the opposite data structures if needed
00048     void ensureType(SecureMessageKey::Type t)
00049     {
00050         // if we were non-null and changed, we may need to reset some things
00051         if(type != SecureMessageKey::None && t != type)
00052         {
00053             if(type == SecureMessageKey::X509)
00054             {
00055                 cert_pub = CertificateChain();
00056                 cert_sec = PrivateKey();
00057             }
00058             else if(type == SecureMessageKey::PGP)
00059             {
00060                 pgp_pub = PGPKey();
00061                 pgp_sec = PGPKey();
00062             }
00063         }
00064         type = t;
00065     }
00066 };
00067 
00068 SecureMessageKey::SecureMessageKey()
00069 :d(new Private)
00070 {
00071 }
00072 
00073 SecureMessageKey::SecureMessageKey(const SecureMessageKey &from)
00074 :d(from.d)
00075 {
00076 }
00077 
00078 SecureMessageKey::~SecureMessageKey()
00079 {
00080 }
00081 
00082 SecureMessageKey & SecureMessageKey::operator=(const SecureMessageKey &from)
00083 {
00084     d = from.d;
00085     return *this;
00086 }
00087 
00088 bool SecureMessageKey::isNull() const
00089 {
00090     return (d->type == None);
00091 }
00092 
00093 SecureMessageKey::Type SecureMessageKey::type() const
00094 {
00095     return d->type;
00096 }
00097 
00098 PGPKey SecureMessageKey::pgpPublicKey() const
00099 {
00100     return d->pgp_pub;
00101 }
00102 
00103 PGPKey SecureMessageKey::pgpSecretKey() const
00104 {
00105     return d->pgp_sec;
00106 }
00107 
00108 void SecureMessageKey::setPGPPublicKey(const PGPKey &pub)
00109 {
00110     d->ensureType(SecureMessageKey::PGP);
00111     d->pgp_pub = pub;
00112 }
00113 
00114 void SecureMessageKey::setPGPSecretKey(const PGPKey &sec)
00115 {
00116     d->ensureType(SecureMessageKey::PGP);
00117     Q_ASSERT(sec.isSecret());
00118     d->pgp_sec = sec;
00119 }
00120 
00121 CertificateChain SecureMessageKey::x509CertificateChain() const
00122 {
00123     return d->cert_pub;
00124 }
00125 
00126 PrivateKey SecureMessageKey::x509PrivateKey() const
00127 {
00128     return d->cert_sec;
00129 }
00130 
00131 void SecureMessageKey::setX509CertificateChain(const CertificateChain &c)
00132 {
00133     d->ensureType(SecureMessageKey::X509);
00134     d->cert_pub = c;
00135 }
00136 
00137 void SecureMessageKey::setX509PrivateKey(const PrivateKey &k)
00138 {
00139     d->ensureType(SecureMessageKey::X509);
00140     d->cert_sec = k;
00141 }
00142 
00143 void SecureMessageKey::setX509KeyBundle(const KeyBundle &kb)
00144 {
00145     setX509CertificateChain(kb.certificateChain());
00146     setX509PrivateKey(kb.privateKey());
00147 }
00148 
00149 bool SecureMessageKey::havePrivate() const
00150 {
00151     if(d->type == SecureMessageKey::PGP && !d->pgp_sec.isNull())
00152         return true;
00153     else if(d->type == SecureMessageKey::X509 && !d->cert_sec.isNull())
00154         return true;
00155     return false;
00156 }
00157 
00158 QString SecureMessageKey::name() const
00159 {
00160     if(d->type == SecureMessageKey::PGP && !d->pgp_pub.isNull())
00161         return d->pgp_pub.primaryUserId();
00162     else if(d->type == SecureMessageKey::X509 && !d->cert_pub.isEmpty())
00163         return d->cert_pub.primary().commonName();
00164     else
00165         return QString();
00166 }
00167 
00168 //----------------------------------------------------------------------------
00169 // SecureMessageSignature
00170 //----------------------------------------------------------------------------
00171 class SecureMessageSignature::Private : public QSharedData
00172 {
00173 public:
00174     SecureMessageSignature::IdentityResult r;
00175     Validity v;
00176     SecureMessageKey key;
00177     QDateTime ts;
00178 
00179     Private()
00180     {
00181         r = SecureMessageSignature::NoKey;
00182         v = ErrorValidityUnknown;
00183     }
00184 };
00185 
00186 SecureMessageSignature::SecureMessageSignature()
00187 :d(new Private)
00188 {
00189 }
00190 
00191 SecureMessageSignature::SecureMessageSignature(IdentityResult r, Validity v, const SecureMessageKey &key, const QDateTime &ts)
00192 :d(new Private)
00193 {
00194     d->r = r;
00195     d->v = v;
00196     d->key = key;
00197     d->ts = ts;
00198 }
00199 
00200 SecureMessageSignature::SecureMessageSignature(const SecureMessageSignature &from)
00201 :d(from.d)
00202 {
00203 }
00204 
00205 SecureMessageSignature::~SecureMessageSignature()
00206 {
00207 }
00208 
00209 SecureMessageSignature & SecureMessageSignature::operator=(const SecureMessageSignature &from)
00210 {
00211     d = from.d;
00212     return *this;
00213 }
00214 
00215 SecureMessageSignature::IdentityResult SecureMessageSignature::identityResult() const
00216 {
00217     return d->r;
00218 }
00219 
00220 Validity SecureMessageSignature::keyValidity() const
00221 {
00222     return d->v;
00223 }
00224 
00225 SecureMessageKey SecureMessageSignature::key() const
00226 {
00227     return d->key;
00228 }
00229 
00230 QDateTime SecureMessageSignature::timestamp() const
00231 {
00232     return d->ts;
00233 }
00234 
00235 //----------------------------------------------------------------------------
00236 // SecureMessage
00237 //----------------------------------------------------------------------------
00238 enum ResetMode
00239 {
00240         ResetSession        = 0,
00241         ResetSessionAndData = 1,
00242         ResetAll            = 2
00243 };
00244 
00245 class SecureMessage::Private : public QObject
00246 {
00247     Q_OBJECT
00248 public:
00249     SecureMessage *q;
00250     MessageContext *c;
00251     SecureMessageSystem *system;
00252 
00253     bool bundleSigner, smime;
00254     SecureMessage::Format format;
00255     SecureMessageKeyList to;
00256     SecureMessageKeyList from;
00257 
00258     QByteArray in;
00259     bool success;
00260     SecureMessage::Error errorCode;
00261     QByteArray detachedSig;
00262     QString hashName;
00263     SecureMessageSignatureList signers;
00264     QString dtext;
00265 
00266     QList<int> bytesWrittenArgs;
00267     SafeTimer readyReadTrigger, bytesWrittenTrigger, finishedTrigger;
00268 
00269     Private(SecureMessage *_q) : readyReadTrigger(this), bytesWrittenTrigger(this), finishedTrigger(this)
00270     {
00271         q = _q;
00272         c = 0;
00273         system = 0;
00274 
00275         readyReadTrigger.setSingleShot(true);
00276         bytesWrittenTrigger.setSingleShot(true);
00277         finishedTrigger.setSingleShot(true);
00278         connect(&readyReadTrigger, SIGNAL(timeout()), SLOT(t_readyRead()));
00279         connect(&bytesWrittenTrigger, SIGNAL(timeout()), SLOT(t_bytesWritten()));
00280         connect(&finishedTrigger, SIGNAL(timeout()), SLOT(t_finished()));
00281 
00282         reset(ResetAll);
00283     }
00284 
00285     void init()
00286     {
00287         connect(c, SIGNAL(updated()), SLOT(updated()));
00288     }
00289 
00290     void reset(ResetMode mode)
00291     {
00292         if(c)
00293             c->reset();
00294 
00295         bytesWrittenArgs.clear();
00296         readyReadTrigger.stop();
00297         bytesWrittenTrigger.stop();
00298         finishedTrigger.stop();
00299 
00300         if(mode >= ResetSessionAndData)
00301         {
00302             in.clear();
00303             success = false;
00304             errorCode = SecureMessage::ErrorUnknown;
00305             detachedSig.clear();
00306             hashName = QString();
00307             signers.clear();
00308         }
00309 
00310         if(mode >= ResetAll)
00311         {
00312             bundleSigner = true;
00313             format = SecureMessage::Binary;
00314             to.clear();
00315             from.clear();
00316         }
00317     }
00318 
00319 public slots:
00320     void updated()
00321     {
00322         bool sig_read = false;
00323         bool sig_written = false;
00324         bool sig_done = false;
00325         int written = 0;
00326         {
00327             QByteArray a = c->read();
00328             if(!a.isEmpty())
00329             {
00330                 sig_read = true;
00331                 in.append(a);
00332             }
00333 
00334             int x = c->written();
00335             if(x > 0)
00336             {
00337                 sig_written = true;
00338                 written = x;
00339             }
00340         }
00341 
00342         if(c->finished())
00343         {
00344             sig_done = true;
00345 
00346             success = c->success();
00347             errorCode = c->errorCode();
00348             dtext = c->diagnosticText();
00349             if(success)
00350             {
00351                 detachedSig = c->signature();
00352                 hashName = c->hashName();
00353                 signers = c->signers();
00354             }
00355             reset(ResetSession);
00356         }
00357 
00358         if(sig_read)
00359             readyReadTrigger.start();
00360         if(sig_written)
00361         {
00362             bytesWrittenArgs += written;
00363             bytesWrittenTrigger.start();
00364         }
00365         if(sig_done)
00366             finishedTrigger.start();
00367     }
00368 
00369     void t_readyRead()
00370     {
00371         emit q->readyRead();
00372     }
00373 
00374     void t_bytesWritten()
00375     {
00376         emit q->bytesWritten(bytesWrittenArgs.takeFirst());
00377     }
00378 
00379     void t_finished()
00380     {
00381         emit q->finished();
00382     }
00383 };
00384 
00385 SecureMessage::SecureMessage(SecureMessageSystem *system)
00386 {
00387     d = new Private(this);
00388     d->system = system;
00389     d->c = static_cast<SMSContext *>(d->system->context())->createMessage();
00390     change(d->c);
00391     d->init();
00392 }
00393 
00394 SecureMessage::~SecureMessage()
00395 {
00396     delete d;
00397 }
00398 
00399 SecureMessage::Type SecureMessage::type() const
00400 {
00401     return d->c->type();
00402 }
00403 
00404 bool SecureMessage::canSignMultiple() const
00405 {
00406     return d->c->canSignMultiple();
00407 }
00408 
00409 bool SecureMessage::canClearsign() const
00410 {
00411     return (type() == OpenPGP);
00412 }
00413 
00414 bool SecureMessage::canSignAndEncrypt() const
00415 {
00416     return (type() == OpenPGP);
00417 }
00418 
00419 void SecureMessage::reset()
00420 {
00421     d->reset(ResetAll);
00422 }
00423 
00424 bool SecureMessage::bundleSignerEnabled() const
00425 {
00426     return d->bundleSigner;
00427 }
00428 
00429 bool SecureMessage::smimeAttributesEnabled() const
00430 {
00431     return d->smime;
00432 }
00433 
00434 SecureMessage::Format SecureMessage::format() const
00435 {
00436     return d->format;
00437 }
00438 
00439 SecureMessageKeyList SecureMessage::recipientKeys() const
00440 {
00441     return d->to;
00442 }
00443 
00444 SecureMessageKeyList SecureMessage::signerKeys() const
00445 {
00446     return d->from;
00447 }
00448 
00449 void SecureMessage::setBundleSignerEnabled(bool b)
00450 {
00451     d->bundleSigner = b;
00452 }
00453 
00454 void SecureMessage::setSMIMEAttributesEnabled(bool b)
00455 {
00456     d->smime = b;
00457 }
00458 
00459 void SecureMessage::setFormat(Format f)
00460 {
00461     d->format = f;
00462 }
00463 
00464 void SecureMessage::setRecipient(const SecureMessageKey &key)
00465 {
00466     d->to = SecureMessageKeyList() << key;
00467 }
00468 
00469 void SecureMessage::setRecipients(const SecureMessageKeyList &keys)
00470 {
00471     d->to = keys;
00472 }
00473 
00474 void SecureMessage::setSigner(const SecureMessageKey &key)
00475 {
00476     d->from = SecureMessageKeyList() << key;
00477 }
00478 
00479 void SecureMessage::setSigners(const SecureMessageKeyList &keys)
00480 {
00481     d->from = keys;
00482 }
00483 
00484 void SecureMessage::startEncrypt()
00485 {
00486     d->reset(ResetSessionAndData);
00487     d->c->setupEncrypt(d->to);
00488     d->c->start(d->format, MessageContext::Encrypt);
00489 }
00490 
00491 void SecureMessage::startDecrypt()
00492 {
00493     d->reset(ResetSessionAndData);
00494     d->c->start(d->format, MessageContext::Decrypt);
00495 }
00496 
00497 void SecureMessage::startSign(SignMode m)
00498 {
00499     d->reset(ResetSessionAndData);
00500     d->c->setupSign(d->from, m, d->bundleSigner, d->smime);
00501     d->c->start(d->format, MessageContext::Sign);
00502 }
00503 
00504 void SecureMessage::startVerify(const QByteArray &sig)
00505 {
00506     d->reset(ResetSessionAndData);
00507     if(!sig.isEmpty())
00508         d->c->setupVerify(sig);
00509     d->c->start(d->format, MessageContext::Verify);
00510 }
00511 
00512 void SecureMessage::startSignAndEncrypt()
00513 {
00514     d->reset(ResetSessionAndData);
00515     d->c->setupEncrypt(d->to);
00516     d->c->setupSign(d->from, Message, d->bundleSigner, d->smime);
00517     d->c->start(d->format, MessageContext::SignAndEncrypt);
00518 }
00519 
00520 void SecureMessage::update(const QByteArray &in)
00521 {
00522     d->c->update(in);
00523 }
00524 
00525 QByteArray SecureMessage::read()
00526 {
00527     QByteArray a = d->in;
00528     d->in.clear();
00529     return a;
00530 }
00531 
00532 int SecureMessage::bytesAvailable() const
00533 {
00534     return d->in.size();
00535 }
00536 
00537 void SecureMessage::end()
00538 {
00539     d->c->end();
00540 }
00541 
00542 bool SecureMessage::waitForFinished(int msecs)
00543 {
00544     d->c->waitForFinished(msecs);
00545     d->updated();
00546     return d->success;
00547 }
00548 
00549 bool SecureMessage::success() const
00550 {
00551     return d->success;
00552 }
00553 
00554 SecureMessage::Error SecureMessage::errorCode() const
00555 {
00556     return d->errorCode;
00557 }
00558 
00559 QByteArray SecureMessage::signature() const
00560 {
00561     return d->detachedSig;
00562 }
00563 
00564 QString SecureMessage::hashName() const
00565 {
00566     return d->hashName;
00567 }
00568 
00569 bool SecureMessage::wasSigned() const
00570 {
00571     return !d->signers.isEmpty();
00572 }
00573 
00574 bool SecureMessage::verifySuccess() const
00575 {
00576     // if we're not done or there were no signers, then return false
00577     if(!d->success || d->signers.isEmpty())
00578         return false;
00579 
00580     // make sure all signers have a valid signature
00581     for(int n = 0; n < d->signers.count(); ++n)
00582     {
00583         if(d->signers[n].identityResult() != SecureMessageSignature::Valid)
00584             return false;
00585     }
00586     return true;
00587 }
00588 
00589 SecureMessageSignature SecureMessage::signer() const
00590 {
00591     if(d->signers.isEmpty())
00592         return SecureMessageSignature();
00593 
00594     return d->signers.first();
00595 }
00596 
00597 SecureMessageSignatureList SecureMessage::signers() const
00598 {
00599     return d->signers;
00600 }
00601 
00602 QString SecureMessage::diagnosticText() const
00603 {
00604     return d->dtext;
00605 }
00606 
00607 //----------------------------------------------------------------------------
00608 // SecureMessageSystem
00609 //----------------------------------------------------------------------------
00610 SecureMessageSystem::SecureMessageSystem(QObject *parent, const QString &type, const QString &provider)
00611 :QObject(parent), Algorithm(type, provider)
00612 {
00613 }
00614 
00615 SecureMessageSystem::~SecureMessageSystem()
00616 {
00617 }
00618 
00619 //----------------------------------------------------------------------------
00620 // OpenPGP
00621 //----------------------------------------------------------------------------
00622 OpenPGP::OpenPGP(QObject *parent, const QString &provider)
00623 :SecureMessageSystem(parent, "openpgp", provider)
00624 {
00625 }
00626 
00627 OpenPGP::~OpenPGP()
00628 {
00629 }
00630 
00631 //----------------------------------------------------------------------------
00632 // CMS
00633 //----------------------------------------------------------------------------
00634 class CMS::Private
00635 {
00636 public:
00637     CertificateCollection trusted, untrusted;
00638     SecureMessageKeyList privateKeys;
00639 };
00640 
00641 CMS::CMS(QObject *parent, const QString &provider)
00642 :SecureMessageSystem(parent, "cms", provider)
00643 {
00644     d = new Private;
00645 }
00646 
00647 CMS::~CMS()
00648 {
00649     delete d;
00650 }
00651 
00652 CertificateCollection CMS::trustedCertificates() const
00653 {
00654     return d->trusted;
00655 }
00656 
00657 CertificateCollection CMS::untrustedCertificates() const
00658 {
00659     return d->untrusted;
00660 }
00661 
00662 SecureMessageKeyList CMS::privateKeys() const
00663 {
00664     return d->privateKeys;
00665 }
00666 
00667 void CMS::setTrustedCertificates(const CertificateCollection &trusted)
00668 {
00669     d->trusted = trusted;
00670     static_cast<SMSContext *>(context())->setTrustedCertificates(trusted);
00671 }
00672 
00673 void CMS::setUntrustedCertificates(const CertificateCollection &untrusted)
00674 {
00675     d->untrusted = untrusted;
00676     static_cast<SMSContext *>(context())->setUntrustedCertificates(untrusted);
00677 }
00678 
00679 void CMS::setPrivateKeys(const SecureMessageKeyList &keys)
00680 {
00681     d->privateKeys = keys;
00682     static_cast<SMSContext *>(context())->setPrivateKeys(keys);
00683 }
00684 
00685 }
00686 
00687 #include "qca_securemessage.moc"

qca

Skip menu "qca"
  • Main Page
  • Modules
  • Namespace List
  • Class Hierarchy
  • Alphabetical List
  • Class List
  • File List
  • Namespace Members
  • Class Members
  • Related Pages

KDE Support

Skip menu "KDE Support"
  • akonadi
  • Decibel
  • grantlee
  • kdewin
  • phonon
  •     Backend
  • polkit-qt
  • qca
  • qimageblitz
  • soprano
  • strigi
  •     searchclient
  •     streamanalyzer
  •     streams
Generated for KDE Support by doxygen 1.5.9-20090814
This website is maintained by Adriaan de Groot and Allen Winter.
KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. | Legal