00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #include "qca_publickey.h"
00023
00024 #include "qcaprovider.h"
00025
00026 #include <QFile>
00027 #include <QTextStream>
00028
00029 namespace QCA {
00030
00031 Provider::Context *getContext(const QString &type, const QString &provider);
00032 Provider::Context *getContext(const QString &type, Provider *p);
00033
00034 bool stringToFile(const QString &fileName, const QString &content)
00035 {
00036 QFile f(fileName);
00037 if(!f.open(QFile::WriteOnly))
00038 return false;
00039 QTextStream ts(&f);
00040 ts << content;
00041 return true;
00042 }
00043
00044 bool stringFromFile(const QString &fileName, QString *s)
00045 {
00046 QFile f(fileName);
00047 if(!f.open(QFile::ReadOnly))
00048 return false;
00049 QTextStream ts(&f);
00050 *s = ts.readAll();
00051 return true;
00052 }
00053
00054 bool arrayToFile(const QString &fileName, const QByteArray &content)
00055 {
00056 QFile f(fileName);
00057 if(!f.open(QFile::WriteOnly))
00058 return false;
00059 f.write(content.data(), content.size());
00060 return true;
00061 }
00062
00063 bool arrayFromFile(const QString &fileName, QByteArray *a)
00064 {
00065 QFile f(fileName);
00066 if(!f.open(QFile::ReadOnly))
00067 return false;
00068 *a = f.readAll();
00069 return true;
00070 }
00071
00072 bool ask_passphrase(const QString &fname, void *ptr, SecureArray *answer)
00073 {
00074 PasswordAsker asker;
00075 asker.ask(Event::StylePassphrase, fname, ptr);
00076 asker.waitForResponse();
00077 if(!asker.accepted())
00078 return false;
00079 *answer = asker.password();
00080 return true;
00081 }
00082
00083 ProviderList allProviders()
00084 {
00085 ProviderList pl = providers();
00086 pl += defaultProvider();
00087 return pl;
00088 }
00089
00090 Provider *providerForName(const QString &name)
00091 {
00092 ProviderList pl = allProviders();
00093 for(int n = 0; n < pl.count(); ++n)
00094 {
00095 if(pl[n]->name() == name)
00096 return pl[n];
00097 }
00098 return 0;
00099 }
00100
00101 bool use_asker_fallback(ConvertResult r)
00102 {
00103
00104
00105 if(r != ConvertGood)
00106 return true;
00107 return false;
00108 }
00109
00110 class Getter_GroupSet
00111 {
00112 public:
00113 static QList<DLGroupSet> getList(Provider *p)
00114 {
00115 QList<DLGroupSet> list;
00116 const DLGroupContext *c = static_cast<const DLGroupContext *>(getContext("dlgroup", p));
00117 if(!c)
00118 return list;
00119 list = c->supportedGroupSets();
00120 delete c;
00121 return list;
00122 }
00123 };
00124
00125 class Getter_PBE
00126 {
00127 public:
00128 static QList<PBEAlgorithm> getList(Provider *p)
00129 {
00130 QList<PBEAlgorithm> list;
00131 const PKeyContext *c = static_cast<const PKeyContext *>(getContext("pkey", p));
00132 if(!c)
00133 return list;
00134 list = c->supportedPBEAlgorithms();
00135 delete c;
00136 return list;
00137 }
00138 };
00139
00140 class Getter_Type
00141 {
00142 public:
00143 static QList<PKey::Type> getList(Provider *p)
00144 {
00145 QList<PKey::Type> list;
00146 const PKeyContext *c = static_cast<const PKeyContext *>(getContext("pkey", p));
00147 if(!c)
00148 return list;
00149 list = c->supportedTypes();
00150 delete c;
00151 return list;
00152 }
00153 };
00154
00155 class Getter_IOType
00156 {
00157 public:
00158 static QList<PKey::Type> getList(Provider *p)
00159 {
00160 QList<PKey::Type> list;
00161 const PKeyContext *c = static_cast<const PKeyContext *>(getContext("pkey", p));
00162 if(!c)
00163 return list;
00164 list = c->supportedIOTypes();
00165 delete c;
00166 return list;
00167 }
00168 };
00169
00170 template <typename I>
00171 class Getter_PublicKey
00172 {
00173 public:
00174
00175 static ConvertResult fromData(PKeyContext *c, const QByteArray &in)
00176 {
00177 return c->publicFromDER(in);
00178 }
00179
00180
00181 static ConvertResult fromData(PKeyContext *c, const QString &in)
00182 {
00183 return c->publicFromPEM(in);
00184 }
00185
00186 static PublicKey getKey(Provider *p, const I &in, const SecureArray &, ConvertResult *result)
00187 {
00188 PublicKey k;
00189 PKeyContext *c = static_cast<PKeyContext *>(getContext("pkey", p));
00190 if(!c)
00191 {
00192 if(result)
00193 *result = ErrorDecode;
00194 return k;
00195 }
00196 ConvertResult r = fromData(c, in);
00197 if(result)
00198 *result = r;
00199 if(r == ConvertGood)
00200 k.change(c);
00201 else
00202 delete c;
00203 return k;
00204 }
00205 };
00206
00207 template <typename I>
00208 class Getter_PrivateKey
00209 {
00210 public:
00211
00212 static ConvertResult fromData(PKeyContext *c, const SecureArray &in, const SecureArray &passphrase)
00213 {
00214 return c->privateFromDER(in, passphrase);
00215 }
00216
00217
00218 static ConvertResult fromData(PKeyContext *c, const QString &in, const SecureArray &passphrase)
00219 {
00220 return c->privateFromPEM(in, passphrase);
00221 }
00222
00223 static PrivateKey getKey(Provider *p, const I &in, const SecureArray &passphrase, ConvertResult *result)
00224 {
00225 PrivateKey k;
00226 PKeyContext *c = static_cast<PKeyContext *>(getContext("pkey", p));
00227 if(!c)
00228 {
00229 if(result)
00230 *result = ErrorDecode;
00231 return k;
00232 }
00233 ConvertResult r = fromData(c, in, passphrase);
00234 if(result)
00235 *result = r;
00236 if(r == ConvertGood)
00237 k.change(c);
00238 else
00239 delete c;
00240 return k;
00241 }
00242 };
00243
00244 Provider *providerForGroupSet(DLGroupSet set)
00245 {
00246 ProviderList pl = allProviders();
00247 for(int n = 0; n < pl.count(); ++n)
00248 {
00249 if(Getter_GroupSet::getList(pl[n]).contains(set))
00250 return pl[n];
00251 }
00252 return 0;
00253 }
00254
00255 Provider *providerForPBE(PBEAlgorithm alg, PKey::Type ioType, const PKeyContext *prefer = 0)
00256 {
00257 Provider *preferProvider = 0;
00258 if(prefer)
00259 {
00260 preferProvider = prefer->provider();
00261 if(prefer->supportedPBEAlgorithms().contains(alg) && prefer->supportedIOTypes().contains(ioType))
00262 return preferProvider;
00263 }
00264
00265 ProviderList pl = allProviders();
00266 for(int n = 0; n < pl.count(); ++n)
00267 {
00268 if(preferProvider && pl[n] == preferProvider)
00269 continue;
00270
00271 if(Getter_PBE::getList(pl[n]).contains(alg) && Getter_IOType::getList(pl[n]).contains(ioType))
00272 return pl[n];
00273 }
00274 return 0;
00275 }
00276
00277 Provider *providerForIOType(PKey::Type type, const PKeyContext *prefer = 0)
00278 {
00279 Provider *preferProvider = 0;
00280 if(prefer)
00281 {
00282 preferProvider = prefer->provider();
00283 if(prefer && prefer->supportedIOTypes().contains(type))
00284 return preferProvider;
00285 }
00286
00287 ProviderList pl = allProviders();
00288 for(int n = 0; n < pl.count(); ++n)
00289 {
00290 if(preferProvider && pl[n] == preferProvider)
00291 continue;
00292
00293 if(Getter_IOType::getList(pl[n]).contains(type))
00294 return pl[n];
00295 }
00296 return 0;
00297 }
00298
00299 template <typename T, typename G>
00300 QList<T> getList(const QString &provider)
00301 {
00302 QList<T> list;
00303
00304
00305 if(!provider.isEmpty())
00306 {
00307 Provider *p = providerForName(provider);
00308 if(p)
00309 list = G::getList(p);
00310 }
00311
00312 else
00313 {
00314 ProviderList pl = allProviders();
00315 for(int n = 0; n < pl.count(); ++n)
00316 {
00317 QList<T> other = G::getList(pl[n]);
00318 for(int k = 0; k < other.count(); ++k)
00319 {
00320
00321 if(!list.contains(other[k]))
00322 list += other[k];
00323 }
00324 }
00325 }
00326
00327 return list;
00328 }
00329
00330 template <typename T, typename G, typename I>
00331 T getKey(const QString &provider, const I &in, const SecureArray &passphrase, ConvertResult *result)
00332 {
00333 T k;
00334
00335
00336 if(!provider.isEmpty())
00337 {
00338 Provider *p = providerForName(provider);
00339 if(!p)
00340 return k;
00341 k = G::getKey(p, in, passphrase, result);
00342 }
00343
00344 else
00345 {
00346 ProviderList pl = allProviders();
00347 for(int n = 0; n < pl.count(); ++n)
00348 {
00349 ConvertResult r;
00350 k = G::getKey(pl[n], in, passphrase, &r);
00351 if(result)
00352 *result = r;
00353 if(!k.isNull())
00354 break;
00355 if(r == ErrorPassphrase)
00356 break;
00357 }
00358 }
00359
00360 return k;
00361 }
00362
00363 PBEAlgorithm get_pbe_default()
00364 {
00365 return PBES2_TripleDES_SHA1;
00366 }
00367
00368 static PrivateKey get_privatekey_der(const SecureArray &der, const QString &fileName, void *ptr, const SecureArray &passphrase, ConvertResult *result, const QString &provider)
00369 {
00370 PrivateKey out;
00371 ConvertResult r;
00372 out = getKey<PrivateKey, Getter_PrivateKey<SecureArray>, SecureArray>(provider, der, passphrase, &r);
00373
00374
00375 if(use_asker_fallback(r) && passphrase.isEmpty())
00376 {
00377 SecureArray pass;
00378 if(ask_passphrase(fileName, ptr, &pass))
00379 out = getKey<PrivateKey, Getter_PrivateKey<SecureArray>, SecureArray>(provider, der, pass, &r);
00380 }
00381 if(result)
00382 *result = r;
00383 return out;
00384 }
00385
00386 static PrivateKey get_privatekey_pem(const QString &pem, const QString &fileName, void *ptr, const SecureArray &passphrase, ConvertResult *result, const QString &provider)
00387 {
00388 PrivateKey out;
00389 ConvertResult r;
00390 out = getKey<PrivateKey, Getter_PrivateKey<QString>, QString>(provider, pem, passphrase, &r);
00391
00392
00393 if(use_asker_fallback(r) && passphrase.isEmpty())
00394 {
00395 SecureArray pass;
00396 if(ask_passphrase(fileName, ptr, &pass))
00397 out = getKey<PrivateKey, Getter_PrivateKey<QString>, QString>(provider, pem, pass, &r);
00398 }
00399 if(result)
00400 *result = r;
00401 return out;
00402 }
00403
00404
00405
00406
00407
00408
00409 static const unsigned char pkcs_sha1[] =
00410 {
00411 0x30, 0x21, 0x30, 0x09, 0x06, 0x05, 0x2B, 0x0E, 0x03, 0x02,
00412 0x1A, 0x05, 0x00, 0x04, 0x14
00413 };
00414
00415 static const unsigned char pkcs_md5[] =
00416 {
00417 0x30, 0x20, 0x30, 0x0C, 0x06, 0x08, 0x2A, 0x86, 0x48, 0x86,
00418 0xF7, 0x0D, 0x02, 0x05, 0x05, 0x00, 0x04, 0x10
00419 };
00420
00421 static const unsigned char pkcs_md2[] =
00422 {
00423 0x30, 0x20, 0x30, 0x0C, 0x06, 0x08, 0x2A, 0x86, 0x48, 0x86,
00424 0xF7, 0x0D, 0x02, 0x02, 0x05, 0x00, 0x04, 0x10
00425 };
00426
00427 static const unsigned char pkcs_ripemd160[] =
00428 {
00429 0x30, 0x21, 0x30, 0x09, 0x06, 0x05, 0x2B, 0x24, 0x03, 0x02,
00430 0x01, 0x05, 0x00, 0x04, 0x14
00431 };
00432
00433 QByteArray get_hash_id(const QString &name)
00434 {
00435 if(name == "sha1")
00436 return QByteArray::fromRawData((const char *)pkcs_sha1, sizeof(pkcs_sha1));
00437 else if(name == "md5")
00438 return QByteArray::fromRawData((const char *)pkcs_md5, sizeof(pkcs_md5));
00439 else if(name == "md2")
00440 return QByteArray::fromRawData((const char *)pkcs_md2, sizeof(pkcs_md2));
00441 else if(name == "ripemd160")
00442 return QByteArray::fromRawData((const char *)pkcs_ripemd160, sizeof(pkcs_ripemd160));
00443 else
00444 return QByteArray();
00445 }
00446
00447 QByteArray emsa3Encode(const QString &hashName, const QByteArray &digest, int size)
00448 {
00449 QByteArray hash_id = get_hash_id(hashName);
00450 if(hash_id.isEmpty())
00451 return QByteArray();
00452
00453
00454 int basesize = hash_id.size() + digest.size() + 2;
00455 if(size == -1)
00456 size = basesize + 1;
00457 int padlen = size - basesize;
00458 if(padlen < 1)
00459 return QByteArray();
00460
00461 QByteArray out(size, (char)0xff);
00462 out[0] = 0x01;
00463 out[padlen + 1] = 0x00;
00464 int at = padlen + 2;
00465 memcpy(out.data() + at, hash_id.data(), hash_id.size());
00466 at += hash_id.size();
00467 memcpy(out.data() + at, digest.data(), digest.size());
00468 return out;
00469 }
00470
00471
00472
00473
00474 class DLGroup::Private
00475 {
00476 public:
00477 BigInteger p, q, g;
00478
00479 Private(const BigInteger &p1, const BigInteger &q1, const BigInteger &g1)
00480 :p(p1), q(q1), g(g1)
00481 {
00482 }
00483 };
00484
00485 DLGroup::DLGroup()
00486 {
00487 d = 0;
00488 }
00489
00490 DLGroup::DLGroup(const BigInteger &p, const BigInteger &q, const BigInteger &g)
00491 {
00492 d = new Private(p, q, g);
00493 }
00494
00495 DLGroup::DLGroup(const BigInteger &p, const BigInteger &g)
00496 {
00497 d = new Private(p, 0, g);
00498 }
00499
00500 DLGroup::DLGroup(const DLGroup &from)
00501 {
00502 d = 0;
00503 *this = from;
00504 }
00505
00506 DLGroup::~DLGroup()
00507 {
00508 delete d;
00509 }
00510
00511 DLGroup & DLGroup::operator=(const DLGroup &from)
00512 {
00513 delete d;
00514 d = 0;
00515
00516 if(from.d)
00517 d = new Private(*from.d);
00518
00519 return *this;
00520 }
00521
00522 QList<DLGroupSet> DLGroup::supportedGroupSets(const QString &provider)
00523 {
00524 return getList<DLGroupSet, Getter_GroupSet>(provider);
00525 }
00526
00527 bool DLGroup::isNull() const
00528 {
00529 return (d ? false: true);
00530 }
00531
00532 BigInteger DLGroup::p() const
00533 {
00534 return d->p;
00535 }
00536
00537 BigInteger DLGroup::q() const
00538 {
00539 return d->q;
00540 }
00541
00542 BigInteger DLGroup::g() const
00543 {
00544 return d->g;
00545 }
00546
00547
00548
00549
00550 class PKey::Private
00551 {
00552 public:
00553 };
00554
00555 PKey::PKey()
00556 {
00557 d = new Private;
00558 }
00559
00560 PKey::PKey(const QString &type, const QString &provider)
00561 :Algorithm(type, provider)
00562 {
00563 d = new Private;
00564 }
00565
00566 PKey::PKey(const PKey &from)
00567 :Algorithm(from)
00568 {
00569 d = new Private;
00570 *this = from;
00571 }
00572
00573 PKey::~PKey()
00574 {
00575 delete d;
00576 }
00577
00578 PKey & PKey::operator=(const PKey &from)
00579 {
00580 Algorithm::operator=(from);
00581 *d = *from.d;
00582 return *this;
00583 }
00584
00585 void PKey::set(const PKey &k)
00586 {
00587 *this = k;
00588 }
00589
00590 void PKey::assignToPublic(PKey *dest) const
00591 {
00592 dest->set(*this);
00593
00594
00595 if(dest->isPrivate())
00596 static_cast<PKeyContext *>(dest->context())->key()->convertToPublic();
00597 }
00598
00599 void PKey::assignToPrivate(PKey *dest) const
00600 {
00601 dest->set(*this);
00602 }
00603
00604 QList<PKey::Type> PKey::supportedTypes(const QString &provider)
00605 {
00606 return getList<Type, Getter_Type>(provider);
00607 }
00608
00609 QList<PKey::Type> PKey::supportedIOTypes(const QString &provider)
00610 {
00611 return getList<Type, Getter_IOType>(provider);
00612 }
00613
00614 bool PKey::isNull() const
00615 {
00616 return (!context() ? true : false);
00617 }
00618
00619 PKey::Type PKey::type() const
00620 {
00621 if(isNull())
00622 return RSA;
00623 return static_cast<const PKeyContext *>(context())->key()->type();
00624 }
00625
00626 int PKey::bitSize() const
00627 {
00628 return static_cast<const PKeyContext *>(context())->key()->bits();
00629 }
00630
00631 bool PKey::isRSA() const
00632 {
00633 return (type() == RSA);
00634 }
00635
00636 bool PKey::isDSA() const
00637 {
00638 return (type() == DSA);
00639 }
00640
00641 bool PKey::isDH() const
00642 {
00643 return (type() == DH);
00644 }
00645
00646 bool PKey::isPublic() const
00647 {
00648 if(isNull())
00649 return false;
00650 return !isPrivate();
00651 }
00652
00653 bool PKey::isPrivate() const
00654 {
00655 if(isNull())
00656 return false;
00657 return static_cast<const PKeyContext *>(context())->key()->isPrivate();
00658 }
00659
00660 bool PKey::canExport() const
00661 {
00662 return static_cast<const PKeyContext *>(context())->key()->canExport();
00663 }
00664
00665 bool PKey::canKeyAgree() const
00666 {
00667 return isDH();
00668 }
00669
00670 PublicKey PKey::toPublicKey() const
00671 {
00672 PublicKey k;
00673 if(!isNull())
00674 assignToPublic(&k);
00675 return k;
00676 }
00677
00678 PrivateKey PKey::toPrivateKey() const
00679 {
00680 PrivateKey k;
00681 if(!isNull() && isPrivate())
00682 assignToPrivate(&k);
00683 return k;
00684 }
00685
00686 RSAPublicKey PKey::toRSAPublicKey() const
00687 {
00688 RSAPublicKey k;
00689 if(!isNull() && isRSA())
00690 assignToPublic(&k);
00691 return k;
00692 }
00693
00694 RSAPrivateKey PKey::toRSAPrivateKey() const
00695 {
00696 RSAPrivateKey k;
00697 if(!isNull() && isRSA() && isPrivate())
00698 assignToPrivate(&k);
00699 return k;
00700 }
00701
00702 DSAPublicKey PKey::toDSAPublicKey() const
00703 {
00704 DSAPublicKey k;
00705 if(!isNull() && isDSA())
00706 assignToPublic(&k);
00707 return k;
00708 }
00709
00710 DSAPrivateKey PKey::toDSAPrivateKey() const
00711 {
00712 DSAPrivateKey k;
00713 if(!isNull() && isDSA() && isPrivate())
00714 assignToPrivate(&k);
00715 return k;
00716 }
00717
00718 DHPublicKey PKey::toDHPublicKey() const
00719 {
00720 DHPublicKey k;
00721 if(!isNull() && isDH())
00722 assignToPublic(&k);
00723 return k;
00724 }
00725
00726 DHPrivateKey PKey::toDHPrivateKey() const
00727 {
00728 DHPrivateKey k;
00729 if(!isNull() && isDH() && isPrivate())
00730 assignToPrivate(&k);
00731 return k;
00732 }
00733
00734 bool PKey::operator==(const PKey &a) const
00735 {
00736 if(isNull() || a.isNull() || type() != a.type())
00737 return false;
00738
00739 if(a.isPrivate())
00740 return (toPrivateKey().toDER() == a.toPrivateKey().toDER());
00741 else
00742 return (toPublicKey().toDER() == a.toPublicKey().toDER());
00743 }
00744
00745 bool PKey::operator!=(const PKey &a) const
00746 {
00747 return !(*this == a);
00748 }
00749
00750
00751
00752
00753 PublicKey::PublicKey()
00754 {
00755 }
00756
00757 PublicKey::PublicKey(const QString &type, const QString &provider)
00758 :PKey(type, provider)
00759 {
00760 }
00761
00762 PublicKey::PublicKey(const PrivateKey &k)
00763 {
00764 set(k.toPublicKey());
00765 }
00766
00767 PublicKey::PublicKey(const QString &fileName)
00768 {
00769 *this = fromPEMFile(fileName, 0, QString());
00770 }
00771
00772 PublicKey::PublicKey(const PublicKey &from)
00773 :PKey(from)
00774 {
00775 }
00776
00777 PublicKey::~PublicKey()
00778 {
00779 }
00780
00781 PublicKey & PublicKey::operator=(const PublicKey &from)
00782 {
00783 PKey::operator=(from);
00784 return *this;
00785 }
00786
00787 RSAPublicKey PublicKey::toRSA() const
00788 {
00789 return toRSAPublicKey();
00790 }
00791
00792 DSAPublicKey PublicKey::toDSA() const
00793 {
00794 return toDSAPublicKey();
00795 }
00796
00797 DHPublicKey PublicKey::toDH() const
00798 {
00799 return toDHPublicKey();
00800 }
00801
00802 bool PublicKey::canEncrypt() const
00803 {
00804 return isRSA();
00805 }
00806
00807 bool PublicKey::canVerify() const
00808 {
00809 return (isRSA() || isDSA());
00810 }
00811
00812 int PublicKey::maximumEncryptSize(EncryptionAlgorithm alg) const
00813 {
00814 return static_cast<const PKeyContext *>(context())->key()->maximumEncryptSize(alg);
00815 }
00816
00817 SecureArray PublicKey::encrypt(const SecureArray &a, EncryptionAlgorithm alg)
00818 {
00819 return static_cast<PKeyContext *>(context())->key()->encrypt(a, alg);
00820 }
00821
00822 void PublicKey::startVerify(SignatureAlgorithm alg, SignatureFormat format)
00823 {
00824 if(isDSA() && format == DefaultFormat)
00825 format = IEEE_1363;
00826 static_cast<PKeyContext *>(context())->key()->startVerify(alg, format);
00827 }
00828
00829 void PublicKey::update(const MemoryRegion &a)
00830 {
00831 static_cast<PKeyContext *>(context())->key()->update(a);
00832 }
00833
00834 bool PublicKey::validSignature(const QByteArray &sig)
00835 {
00836 return static_cast<PKeyContext *>(context())->key()->endVerify(sig);
00837 }
00838
00839 bool PublicKey::verifyMessage(const MemoryRegion &a, const QByteArray &sig, SignatureAlgorithm alg, SignatureFormat format)
00840 {
00841 startVerify(alg, format);
00842 update(a);
00843 return validSignature(sig);
00844 }
00845
00846 QByteArray PublicKey::toDER() const
00847 {
00848 QByteArray out;
00849 const PKeyContext *cur = static_cast<const PKeyContext *>(context());
00850 Provider *p = providerForIOType(type(), cur);
00851 if(!p)
00852 return out;
00853 if(cur->provider() == p)
00854 {
00855 out = cur->publicToDER();
00856 }
00857 else
00858 {
00859 PKeyContext *pk = static_cast<PKeyContext *>(getContext("pkey", p));
00860 if(pk->importKey(cur->key()))
00861 out = pk->publicToDER();
00862 delete pk;
00863 }
00864 return out;
00865 }
00866
00867 QString PublicKey::toPEM() const
00868 {
00869 QString out;
00870 const PKeyContext *cur = static_cast<const PKeyContext *>(context());
00871 Provider *p = providerForIOType(type(), cur);
00872 if(!p)
00873 return out;
00874 if(cur->provider() == p)
00875 {
00876 out = cur->publicToPEM();
00877 }
00878 else
00879 {
00880 PKeyContext *pk = static_cast<PKeyContext *>(getContext("pkey", p));
00881 if(pk->importKey(cur->key()))
00882 out = pk->publicToPEM();
00883 delete pk;
00884 }
00885 return out;
00886 }
00887
00888 bool PublicKey::toPEMFile(const QString &fileName) const
00889 {
00890 return stringToFile(fileName, toPEM());
00891 }
00892
00893 PublicKey PublicKey::fromDER(const QByteArray &a, ConvertResult *result, const QString &provider)
00894 {
00895 return getKey<PublicKey, Getter_PublicKey<QByteArray>, QByteArray>(provider, a, SecureArray(), result);
00896 }
00897
00898 PublicKey PublicKey::fromPEM(const QString &s, ConvertResult *result, const QString &provider)
00899 {
00900 return getKey<PublicKey, Getter_PublicKey<QString>, QString>(provider, s, SecureArray(), result);
00901 }
00902
00903 PublicKey PublicKey::fromPEMFile(const QString &fileName, ConvertResult *result, const QString &provider)
00904 {
00905 QString pem;
00906 if(!stringFromFile(fileName, &pem))
00907 {
00908 if(result)
00909 *result = ErrorFile;
00910 return PublicKey();
00911 }
00912 return fromPEM(pem, result, provider);
00913 }
00914
00915
00916
00917
00918 PrivateKey::PrivateKey()
00919 {
00920 }
00921
00922 PrivateKey::PrivateKey(const QString &type, const QString &provider)
00923 :PKey(type, provider)
00924 {
00925 }
00926
00927 PrivateKey::PrivateKey(const QString &fileName, const SecureArray &passphrase)
00928 {
00929 *this = fromPEMFile(fileName, passphrase, 0, QString());
00930 }
00931
00932 PrivateKey::PrivateKey(const PrivateKey &from)
00933 :PKey(from)
00934 {
00935 }
00936
00937 PrivateKey::~PrivateKey()
00938 {
00939 }
00940
00941 PrivateKey & PrivateKey::operator=(const PrivateKey &from)
00942 {
00943 PKey::operator=(from);
00944 return *this;
00945 }
00946
00947 RSAPrivateKey PrivateKey::toRSA() const
00948 {
00949 return toRSAPrivateKey();
00950 }
00951
00952 DSAPrivateKey PrivateKey::toDSA() const
00953 {
00954 return toDSAPrivateKey();
00955 }
00956
00957 DHPrivateKey PrivateKey::toDH() const
00958 {
00959 return toDHPrivateKey();
00960 }
00961
00962 bool PrivateKey::canDecrypt() const
00963 {
00964 return isRSA();
00965 }
00966
00967 bool PrivateKey::canSign() const
00968 {
00969 return (isRSA() || isDSA());
00970 }
00971
00972 bool PrivateKey::decrypt(const SecureArray &in, SecureArray *out, EncryptionAlgorithm alg)
00973 {
00974 return static_cast<PKeyContext *>(context())->key()->decrypt(in, out, alg);
00975 }
00976
00977 void PrivateKey::startSign(SignatureAlgorithm alg, SignatureFormat format)
00978 {
00979 if(isDSA() && format == DefaultFormat)
00980 format = IEEE_1363;
00981 static_cast<PKeyContext *>(context())->key()->startSign(alg, format);
00982 }
00983
00984 void PrivateKey::update(const MemoryRegion &a)
00985 {
00986 static_cast<PKeyContext *>(context())->key()->update(a);
00987 }
00988
00989 QByteArray PrivateKey::signature()
00990 {
00991 return static_cast<PKeyContext *>(context())->key()->endSign();
00992 }
00993
00994 QByteArray PrivateKey::signMessage(const MemoryRegion &a, SignatureAlgorithm alg, SignatureFormat format)
00995 {
00996 startSign(alg, format);
00997 update(a);
00998 return signature();
00999 }
01000
01001 SymmetricKey PrivateKey::deriveKey(const PublicKey &theirs)
01002 {
01003 const PKeyContext *theirContext = static_cast<const PKeyContext *>(theirs.context());
01004 return static_cast<PKeyContext *>(context())->key()->deriveKey(*(theirContext->key()));
01005 }
01006
01007 QList<PBEAlgorithm> PrivateKey::supportedPBEAlgorithms(const QString &provider)
01008 {
01009 return getList<PBEAlgorithm, Getter_PBE>(provider);
01010 }
01011
01012 SecureArray PrivateKey::toDER(const SecureArray &passphrase, PBEAlgorithm pbe) const
01013 {
01014 SecureArray out;
01015 if(pbe == PBEDefault)
01016 pbe = get_pbe_default();
01017 const PKeyContext *cur = static_cast<const PKeyContext *>(context());
01018 Provider *p = providerForPBE(pbe, type(), cur);
01019 if(!p)
01020 return out;
01021 if(cur->provider() == p)
01022 {
01023 out = cur->privateToDER(passphrase, pbe);
01024 }
01025 else
01026 {
01027 PKeyContext *pk = static_cast<PKeyContext *>(getContext("pkey", p));
01028 if(pk->importKey(cur->key()))
01029 out = pk->privateToDER(passphrase, pbe);
01030 delete pk;
01031 }
01032 return out;
01033 }
01034
01035 QString PrivateKey::toPEM(const SecureArray &passphrase, PBEAlgorithm pbe) const
01036 {
01037 QString out;
01038 if(pbe == PBEDefault)
01039 pbe = get_pbe_default();
01040 const PKeyContext *cur = static_cast<const PKeyContext *>(context());
01041 Provider *p = providerForPBE(pbe, type(), cur);
01042 if(!p)
01043 return out;
01044 if(cur->provider() == p)
01045 {
01046 out = cur->privateToPEM(passphrase, pbe);
01047 }
01048 else
01049 {
01050 PKeyContext *pk = static_cast<PKeyContext *>(getContext("pkey", p));
01051 if(pk->importKey(cur->key()))
01052 out = pk->privateToPEM(passphrase, pbe);
01053 delete pk;
01054 }
01055 return out;
01056 }
01057
01058 bool PrivateKey::toPEMFile(const QString &fileName, const SecureArray &passphrase, PBEAlgorithm pbe) const
01059 {
01060 return stringToFile(fileName, toPEM(passphrase, pbe));
01061 }
01062
01063 PrivateKey PrivateKey::fromDER(const SecureArray &a, const SecureArray &passphrase, ConvertResult *result, const QString &provider)
01064 {
01065 return get_privatekey_der(a, QString(), (void *)&a, passphrase, result, provider);
01066 }
01067
01068 PrivateKey PrivateKey::fromPEM(const QString &s, const SecureArray &passphrase, ConvertResult *result, const QString &provider)
01069 {
01070 return get_privatekey_pem(s, QString(), (void *)&s, passphrase, result, provider);
01071 }
01072
01073 PrivateKey PrivateKey::fromPEMFile(const QString &fileName, const SecureArray &passphrase, ConvertResult *result, const QString &provider)
01074 {
01075 QString pem;
01076 if(!stringFromFile(fileName, &pem))
01077 {
01078 if(result)
01079 *result = ErrorFile;
01080 return PrivateKey();
01081 }
01082 return get_privatekey_pem(pem, fileName, 0, passphrase, result, provider);
01083 }
01084
01085
01086
01087
01088 class KeyGenerator::Private : public QObject
01089 {
01090 Q_OBJECT
01091 public:
01092 KeyGenerator *parent;
01093 bool blocking, wasBlocking;
01094 PrivateKey key;
01095 DLGroup group;
01096
01097 PKeyBase *k;
01098 PKeyContext *dest;
01099 DLGroupContext *dc;
01100
01101 Private(KeyGenerator *_parent) : QObject(_parent), parent(_parent)
01102 {
01103 k = 0;
01104 dest = 0;
01105 dc = 0;
01106 }
01107
01108 ~Private()
01109 {
01110 delete k;
01111 delete dest;
01112 delete dc;
01113 }
01114
01115 public slots:
01116 void done()
01117 {
01118 if(!k->isNull())
01119 {
01120 if(!wasBlocking)
01121 {
01122 k->setParent(0);
01123 k->moveToThread(0);
01124 }
01125 dest->setKey(k);
01126 k = 0;
01127
01128 key.change(dest);
01129 dest = 0;
01130 }
01131 else
01132 {
01133 delete k;
01134 k = 0;
01135 delete dest;
01136 dest = 0;
01137 }
01138
01139 if(!wasBlocking)
01140 emit parent->finished();
01141 }
01142
01143 void done_group()
01144 {
01145 if(!dc->isNull())
01146 {
01147 BigInteger p, q, g;
01148 dc->getResult(&p, &q, &g);
01149 group = DLGroup(p, q, g);
01150 }
01151 delete dc;
01152 dc = 0;
01153
01154 if(!wasBlocking)
01155 emit parent->finished();
01156 }
01157 };
01158
01159 KeyGenerator::KeyGenerator(QObject *parent)
01160 :QObject(parent)
01161 {
01162 d = new Private(this);
01163 d->blocking = true;
01164 }
01165
01166 KeyGenerator::~KeyGenerator()
01167 {
01168 delete d;
01169 }
01170
01171 bool KeyGenerator::blockingEnabled() const
01172 {
01173 return d->blocking;
01174 }
01175
01176 void KeyGenerator::setBlockingEnabled(bool b)
01177 {
01178 d->blocking = b;
01179 }
01180
01181 bool KeyGenerator::isBusy() const
01182 {
01183 return (d->k ? true: false);
01184 }
01185
01186 PrivateKey KeyGenerator::createRSA(int bits, int exp, const QString &provider)
01187 {
01188 if(isBusy())
01189 return PrivateKey();
01190
01191 d->key = PrivateKey();
01192 d->wasBlocking = d->blocking;
01193 d->k = static_cast<RSAContext *>(getContext("rsa", provider));
01194 d->dest = static_cast<PKeyContext *>(getContext("pkey", d->k->provider()));
01195
01196 if(!d->blocking)
01197 {
01198 d->k->moveToThread(thread());
01199 d->k->setParent(d);
01200 connect(d->k, SIGNAL(finished()), d, SLOT(done()));
01201 static_cast<RSAContext *>(d->k)->createPrivate(bits, exp, false);
01202 }
01203 else
01204 {
01205 static_cast<RSAContext *>(d->k)->createPrivate(bits, exp, true);
01206 d->done();
01207 }
01208
01209 return d->key;
01210 }
01211
01212 PrivateKey KeyGenerator::createDSA(const DLGroup &domain, const QString &provider)
01213 {
01214 if(isBusy())
01215 return PrivateKey();
01216
01217 d->key = PrivateKey();
01218 d->wasBlocking = d->blocking;
01219 d->k = static_cast<DSAContext *>(getContext("dsa", provider));
01220 d->dest = static_cast<PKeyContext *>(getContext("pkey", d->k->provider()));
01221
01222 if(!d->blocking)
01223 {
01224 d->k->moveToThread(thread());
01225 d->k->setParent(d);
01226 connect(d->k, SIGNAL(finished()), d, SLOT(done()));
01227 static_cast<DSAContext *>(d->k)->createPrivate(domain, false);
01228 }
01229 else
01230 {
01231 static_cast<DSAContext *>(d->k)->createPrivate(domain, true);
01232 d->done();
01233 }
01234
01235 return d->key;
01236 }
01237
01238 PrivateKey KeyGenerator::createDH(const DLGroup &domain, const QString &provider)
01239 {
01240 if(isBusy())
01241 return PrivateKey();
01242
01243 d->key = PrivateKey();
01244 d->wasBlocking = d->blocking;
01245 d->k = static_cast<DHContext *>(getContext("dh", provider));
01246 d->dest = static_cast<PKeyContext *>(getContext("pkey", d->k->provider()));
01247
01248 if(!d->blocking)
01249 {
01250 d->k->moveToThread(thread());
01251 d->k->setParent(d);
01252 connect(d->k, SIGNAL(finished()), d, SLOT(done()));
01253 static_cast<DHContext *>(d->k)->createPrivate(domain, false);
01254 }
01255 else
01256 {
01257 static_cast<DHContext *>(d->k)->createPrivate(domain, true);
01258 d->done();
01259 }
01260
01261 return d->key;
01262 }
01263
01264 PrivateKey KeyGenerator::key() const
01265 {
01266 return d->key;
01267 }
01268
01269 DLGroup KeyGenerator::createDLGroup(QCA::DLGroupSet set, const QString &provider)
01270 {
01271 if(isBusy())
01272 return DLGroup();
01273
01274 Provider *p;
01275 if(!provider.isEmpty())
01276 p = providerForName(provider);
01277 else
01278 p = providerForGroupSet(set);
01279
01280 d->group = DLGroup();
01281 d->wasBlocking = d->blocking;
01282 d->dc = static_cast<DLGroupContext *>(getContext("dlgroup", p));
01283
01284 if(!d->blocking)
01285 {
01286 connect(d->dc, SIGNAL(finished()), d, SLOT(done_group()));
01287 d->dc->fetchGroup(set, false);
01288 }
01289 else
01290 {
01291 d->dc->fetchGroup(set, true);
01292 d->done_group();
01293 }
01294
01295 return d->group;
01296 }
01297
01298 DLGroup KeyGenerator::dlGroup() const
01299 {
01300 return d->group;
01301 }
01302
01303
01304
01305
01306 RSAPublicKey::RSAPublicKey()
01307 {
01308 }
01309
01310 RSAPublicKey::RSAPublicKey(const BigInteger &n, const BigInteger &e, const QString &provider)
01311 {
01312 RSAContext *k = static_cast<RSAContext *>(getContext("rsa", provider));
01313 k->createPublic(n, e);
01314 PKeyContext *c = static_cast<PKeyContext *>(getContext("pkey", k->provider()));
01315 c->setKey(k);
01316 change(c);
01317 }
01318
01319 RSAPublicKey::RSAPublicKey(const RSAPrivateKey &k)
01320 :PublicKey(k)
01321 {
01322 }
01323
01324 BigInteger RSAPublicKey::n() const
01325 {
01326 return static_cast<const RSAContext *>(static_cast<const PKeyContext *>(context())->key())->n();
01327 }
01328
01329 BigInteger RSAPublicKey::e() const
01330 {
01331 return static_cast<const RSAContext *>(static_cast<const PKeyContext *>(context())->key())->e();
01332 }
01333
01334
01335
01336
01337 RSAPrivateKey::RSAPrivateKey()
01338 {
01339 }
01340
01341 RSAPrivateKey::RSAPrivateKey(const BigInteger &n, const BigInteger &e, const BigInteger &p, const BigInteger &q, const BigInteger &d, const QString &provider)
01342 {
01343 RSAContext *k = static_cast<RSAContext *>(getContext("rsa", provider));
01344 k->createPrivate(n, e, p, q, d);
01345 PKeyContext *c = static_cast<PKeyContext *>(getContext("pkey", k->provider()));
01346 c->setKey(k);
01347 change(c);
01348 }
01349
01350 BigInteger RSAPrivateKey::n() const
01351 {
01352 return static_cast<const RSAContext *>(static_cast<const PKeyContext *>(context())->key())->n();
01353 }
01354
01355 BigInteger RSAPrivateKey::e() const
01356 {
01357 return static_cast<const RSAContext *>(static_cast<const PKeyContext *>(context())->key())->e();
01358 }
01359
01360 BigInteger RSAPrivateKey::p() const
01361 {
01362 return static_cast<const RSAContext *>(static_cast<const PKeyContext *>(context())->key())->p();
01363 }
01364
01365 BigInteger RSAPrivateKey::q() const
01366 {
01367 return static_cast<const RSAContext *>(static_cast<const PKeyContext *>(context())->key())->q();
01368 }
01369
01370 BigInteger RSAPrivateKey::d() const
01371 {
01372 return static_cast<const RSAContext *>(static_cast<const PKeyContext *>(context())->key())->d();
01373 }
01374
01375
01376
01377
01378 DSAPublicKey::DSAPublicKey()
01379 {
01380 }
01381
01382 DSAPublicKey::DSAPublicKey(const DLGroup &domain, const BigInteger &y, const QString &provider)
01383 {
01384 DSAContext *k = static_cast<DSAContext *>(getContext("dsa", provider));
01385 k->createPublic(domain, y);
01386 PKeyContext *c = static_cast<PKeyContext *>(getContext("pkey", k->provider()));
01387 c->setKey(k);
01388 change(c);
01389 }
01390
01391 DSAPublicKey::DSAPublicKey(const DSAPrivateKey &k)
01392 :PublicKey(k)
01393 {
01394 }
01395
01396 DLGroup DSAPublicKey::domain() const
01397 {
01398 return static_cast<const DSAContext *>(static_cast<const PKeyContext *>(context())->key())->domain();
01399 }
01400
01401 BigInteger DSAPublicKey::y() const
01402 {
01403 return static_cast<const DSAContext *>(static_cast<const PKeyContext *>(context())->key())->y();
01404 }
01405
01406
01407
01408
01409 DSAPrivateKey::DSAPrivateKey()
01410 {
01411 }
01412
01413 DSAPrivateKey::DSAPrivateKey(const DLGroup &domain, const BigInteger &y, const BigInteger &x, const QString &provider)
01414 {
01415 DSAContext *k = static_cast<DSAContext *>(getContext("dsa", provider));
01416 k->createPrivate(domain, y, x);
01417 PKeyContext *c = static_cast<PKeyContext *>(getContext("pkey", k->provider()));
01418 c->setKey(k);
01419 change(c);
01420 }
01421
01422 DLGroup DSAPrivateKey::domain() const
01423 {
01424 return static_cast<const DSAContext *>(static_cast<const PKeyContext *>(context())->key())->domain();
01425 }
01426
01427 BigInteger DSAPrivateKey::y() const
01428 {
01429 return static_cast<const DSAContext *>(static_cast<const PKeyContext *>(context())->key())->y();
01430 }
01431
01432 BigInteger DSAPrivateKey::x() const
01433 {
01434 return static_cast<const DSAContext *>(static_cast<const PKeyContext *>(context())->key())->x();
01435 }
01436
01437
01438
01439
01440 DHPublicKey::DHPublicKey()
01441 {
01442 }
01443
01444 DHPublicKey::DHPublicKey(const DLGroup &domain, const BigInteger &y, const QString &provider)
01445 {
01446 DHContext *k = static_cast<DHContext *>(getContext("dh", provider));
01447 k->createPublic(domain, y);
01448 PKeyContext *c = static_cast<PKeyContext *>(getContext("pkey", k->provider()));
01449 c->setKey(k);
01450 change(c);
01451 }
01452
01453 DHPublicKey::DHPublicKey(const DHPrivateKey &k)
01454 :PublicKey(k)
01455 {
01456 }
01457
01458 DLGroup DHPublicKey::domain() const
01459 {
01460 return static_cast<const DHContext *>(static_cast<const PKeyContext *>(context())->key())->domain();
01461 }
01462
01463 BigInteger DHPublicKey::y() const
01464 {
01465 return static_cast<const DHContext *>(static_cast<const PKeyContext *>(context())->key())->y();
01466 }
01467
01468
01469
01470
01471 DHPrivateKey::DHPrivateKey()
01472 {
01473 }
01474
01475 DHPrivateKey::DHPrivateKey(const DLGroup &domain, const BigInteger &y, const BigInteger &x, const QString &provider)
01476 {
01477 DHContext *k = static_cast<DHContext *>(getContext("dh", provider));
01478 k->createPrivate(domain, y, x);
01479 PKeyContext *c = static_cast<PKeyContext *>(getContext("pkey", k->provider()));
01480 c->setKey(k);
01481 change(c);
01482 }
01483
01484 DLGroup DHPrivateKey::domain() const
01485 {
01486 return static_cast<const DHContext *>(static_cast<const PKeyContext *>(context())->key())->domain();
01487 }
01488
01489 BigInteger DHPrivateKey::y() const
01490 {
01491 return static_cast<const DHContext *>(static_cast<const PKeyContext *>(context())->key())->y();
01492 }
01493
01494 BigInteger DHPrivateKey::x() const
01495 {
01496 return static_cast<const DHContext *>(static_cast<const PKeyContext *>(context())->key())->x();
01497 }
01498
01499 }
01500
01501 #include "qca_publickey.moc"