qca
qca_securemessage.cpp
Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
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
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
00048 void ensureType(SecureMessageKey::Type t)
00049 {
00050
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
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
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
00577 if(!d->success || d->signers.isEmpty())
00578 return false;
00579
00580
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
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
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
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"