1 | /* |
2 | * Copyright (C) 2003-2007 Justin Karneges <justin@affinix.com> |
3 | * Copyright (C) 2004,2005 Brad Hards <bradh@frogmouth.net> |
4 | * |
5 | * This library is free software; you can redistribute it and/or |
6 | * modify it under the terms of the GNU Lesser General Public |
7 | * License as published by the Free Software Foundation; either |
8 | * version 2.1 of the License, or (at your option) any later version. |
9 | * |
10 | * This library is distributed in the hope that it will be useful, |
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
13 | * Lesser General Public License for more details. |
14 | * |
15 | * You should have received a copy of the GNU Lesser General Public |
16 | * License along with this library; if not, write to the Free Software |
17 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA |
18 | * 02110-1301 USA |
19 | * |
20 | */ |
21 | |
22 | #include "qca_publickey.h" |
23 | |
24 | #include "qcaprovider.h" |
25 | |
26 | #include <QFile> |
27 | #include <QTextStream> |
28 | |
29 | namespace QCA { |
30 | |
31 | Provider::Context *getContext(const QString &type, const QString &provider); |
32 | Provider::Context *getContext(const QString &type, Provider *p); |
33 | |
34 | bool stringToFile(const QString &fileName, const QString &content) |
35 | { |
36 | QFile f(fileName); |
37 | if (!f.open(flags: QFile::WriteOnly)) |
38 | return false; |
39 | QTextStream ts(&f); |
40 | ts << content; |
41 | return true; |
42 | } |
43 | |
44 | bool stringFromFile(const QString &fileName, QString *s) |
45 | { |
46 | QFile f(fileName); |
47 | if (!f.open(flags: QFile::ReadOnly)) |
48 | return false; |
49 | QTextStream ts(&f); |
50 | *s = ts.readAll(); |
51 | return true; |
52 | } |
53 | |
54 | bool arrayToFile(const QString &fileName, const QByteArray &content) |
55 | { |
56 | QFile f(fileName); |
57 | if (!f.open(flags: QFile::WriteOnly)) |
58 | return false; |
59 | f.write(data: content.data(), len: content.size()); |
60 | return true; |
61 | } |
62 | |
63 | bool arrayFromFile(const QString &fileName, QByteArray *a) |
64 | { |
65 | QFile f(fileName); |
66 | if (!f.open(flags: QFile::ReadOnly)) |
67 | return false; |
68 | *a = f.readAll(); |
69 | return true; |
70 | } |
71 | |
72 | bool ask_passphrase(const QString &fname, void *ptr, SecureArray *answer) |
73 | { |
74 | PasswordAsker asker; |
75 | asker.ask(pstyle: Event::StylePassphrase, fileName: fname, ptr); |
76 | asker.waitForResponse(); |
77 | if (!asker.accepted()) |
78 | return false; |
79 | *answer = asker.password(); |
80 | return true; |
81 | } |
82 | |
83 | ProviderList allProviders() |
84 | { |
85 | ProviderList pl = providers(); |
86 | pl += defaultProvider(); |
87 | return pl; |
88 | } |
89 | |
90 | Provider *providerForName(const QString &name) |
91 | { |
92 | ProviderList pl = allProviders(); |
93 | for (int n = 0; n < pl.count(); ++n) { |
94 | if (pl[n]->name() == name) |
95 | return pl[n]; |
96 | } |
97 | return nullptr; |
98 | } |
99 | |
100 | bool use_asker_fallback(ConvertResult r) |
101 | { |
102 | // FIXME: we should only do this if we get ErrorPassphrase? |
103 | // if(r == ErrorPassphrase) |
104 | if (r != ConvertGood) |
105 | return true; |
106 | return false; |
107 | } |
108 | |
109 | class Getter_GroupSet |
110 | { |
111 | public: |
112 | static QList<DLGroupSet> getList(Provider *p) |
113 | { |
114 | QList<DLGroupSet> list; |
115 | const DLGroupContext *c = static_cast<const DLGroupContext *>(getContext(QStringLiteral("dlgroup" ), p)); |
116 | if (!c) |
117 | return list; |
118 | list = c->supportedGroupSets(); |
119 | delete c; |
120 | return list; |
121 | } |
122 | }; |
123 | |
124 | class Getter_PBE |
125 | { |
126 | public: |
127 | static QList<PBEAlgorithm> getList(Provider *p) |
128 | { |
129 | QList<PBEAlgorithm> list; |
130 | const PKeyContext *c = static_cast<const PKeyContext *>(getContext(QStringLiteral("pkey" ), p)); |
131 | if (!c) |
132 | return list; |
133 | list = c->supportedPBEAlgorithms(); |
134 | delete c; |
135 | return list; |
136 | } |
137 | }; |
138 | |
139 | class Getter_Type |
140 | { |
141 | public: |
142 | static QList<PKey::Type> getList(Provider *p) |
143 | { |
144 | QList<PKey::Type> list; |
145 | const PKeyContext *c = static_cast<const PKeyContext *>(getContext(QStringLiteral("pkey" ), p)); |
146 | if (!c) |
147 | return list; |
148 | list = c->supportedTypes(); |
149 | delete c; |
150 | return list; |
151 | } |
152 | }; |
153 | |
154 | class Getter_IOType |
155 | { |
156 | public: |
157 | static QList<PKey::Type> getList(Provider *p) |
158 | { |
159 | QList<PKey::Type> list; |
160 | const PKeyContext *c = static_cast<const PKeyContext *>(getContext(QStringLiteral("pkey" ), p)); |
161 | if (!c) |
162 | return list; |
163 | list = c->supportedIOTypes(); |
164 | delete c; |
165 | return list; |
166 | } |
167 | }; |
168 | |
169 | template<typename I> class Getter_PublicKey |
170 | { |
171 | public: |
172 | // DER |
173 | static ConvertResult fromData(PKeyContext *c, const QByteArray &in) |
174 | { |
175 | return c->publicFromDER(a: in); |
176 | } |
177 | |
178 | // PEM |
179 | static ConvertResult fromData(PKeyContext *c, const QString &in) |
180 | { |
181 | return c->publicFromPEM(s: in); |
182 | } |
183 | |
184 | static PublicKey getKey(Provider *p, const I &in, const SecureArray &, ConvertResult *result) |
185 | { |
186 | PublicKey k; |
187 | PKeyContext *c = static_cast<PKeyContext *>(getContext(QStringLiteral("pkey" ), p)); |
188 | if (!c) { |
189 | if (result) |
190 | *result = ErrorDecode; |
191 | return k; |
192 | } |
193 | ConvertResult r = fromData(c, in); |
194 | if (result) |
195 | *result = r; |
196 | if (r == ConvertGood) |
197 | k.change(c); |
198 | else |
199 | delete c; |
200 | return k; |
201 | } |
202 | }; |
203 | |
204 | template<typename I> class Getter_PrivateKey |
205 | { |
206 | public: |
207 | // DER |
208 | static ConvertResult fromData(PKeyContext *c, const SecureArray &in, const SecureArray &passphrase) |
209 | { |
210 | return c->privateFromDER(a: in, passphrase); |
211 | } |
212 | |
213 | // PEM |
214 | static ConvertResult fromData(PKeyContext *c, const QString &in, const SecureArray &passphrase) |
215 | { |
216 | return c->privateFromPEM(s: in, passphrase); |
217 | } |
218 | |
219 | static PrivateKey getKey(Provider *p, const I &in, const SecureArray &passphrase, ConvertResult *result) |
220 | { |
221 | PrivateKey k; |
222 | PKeyContext *c = static_cast<PKeyContext *>(getContext(QStringLiteral("pkey" ), p)); |
223 | if (!c) { |
224 | if (result) |
225 | *result = ErrorDecode; |
226 | return k; |
227 | } |
228 | ConvertResult r = fromData(c, in, passphrase); |
229 | if (result) |
230 | *result = r; |
231 | if (r == ConvertGood) |
232 | k.change(c); |
233 | else |
234 | delete c; |
235 | return k; |
236 | } |
237 | }; |
238 | |
239 | Provider *providerForGroupSet(DLGroupSet set) |
240 | { |
241 | ProviderList pl = allProviders(); |
242 | for (int n = 0; n < pl.count(); ++n) { |
243 | if (Getter_GroupSet::getList(p: pl[n]).contains(t: set)) |
244 | return pl[n]; |
245 | } |
246 | return nullptr; |
247 | } |
248 | |
249 | Provider *providerForPBE(PBEAlgorithm alg, PKey::Type ioType, const PKeyContext *prefer = nullptr) |
250 | { |
251 | Provider *preferProvider = nullptr; |
252 | if (prefer) { |
253 | preferProvider = prefer->provider(); |
254 | if (prefer->supportedPBEAlgorithms().contains(t: alg) && prefer->supportedIOTypes().contains(t: ioType)) |
255 | return preferProvider; |
256 | } |
257 | |
258 | ProviderList pl = allProviders(); |
259 | for (int n = 0; n < pl.count(); ++n) { |
260 | if (preferProvider && pl[n] == preferProvider) |
261 | continue; |
262 | |
263 | if (Getter_PBE::getList(p: pl[n]).contains(t: alg) && Getter_IOType::getList(p: pl[n]).contains(t: ioType)) |
264 | return pl[n]; |
265 | } |
266 | return nullptr; |
267 | } |
268 | |
269 | Provider *providerForIOType(PKey::Type type, const PKeyContext *prefer = nullptr) |
270 | { |
271 | Provider *preferProvider = nullptr; |
272 | if (prefer) { |
273 | preferProvider = prefer->provider(); |
274 | if (prefer && prefer->supportedIOTypes().contains(t: type)) |
275 | return preferProvider; |
276 | } |
277 | |
278 | ProviderList pl = allProviders(); |
279 | for (int n = 0; n < pl.count(); ++n) { |
280 | if (preferProvider && pl[n] == preferProvider) |
281 | continue; |
282 | |
283 | if (Getter_IOType::getList(p: pl[n]).contains(t: type)) |
284 | return pl[n]; |
285 | } |
286 | return nullptr; |
287 | } |
288 | |
289 | template<typename T, typename G> QList<T> getList(const QString &provider) |
290 | { |
291 | QList<T> list; |
292 | |
293 | // single |
294 | if (!provider.isEmpty()) { |
295 | Provider *p = providerForName(name: provider); |
296 | if (p) |
297 | list = G::getList(p); |
298 | } |
299 | // all |
300 | else { |
301 | ProviderList pl = allProviders(); |
302 | for (int n = 0; n < pl.count(); ++n) { |
303 | const QList<T> other = G::getList(pl[n]); |
304 | for (int k = 0; k < other.count(); ++k) { |
305 | // only add what we don't have in the list |
306 | if (!list.contains(other[k])) |
307 | list += other[k]; |
308 | } |
309 | } |
310 | } |
311 | |
312 | return list; |
313 | } |
314 | |
315 | template<typename T, typename G, typename I> |
316 | T getKey(const QString &provider, const I &in, const SecureArray &passphrase, ConvertResult *result) |
317 | { |
318 | T k; |
319 | |
320 | // single |
321 | if (!provider.isEmpty()) { |
322 | Provider *p = providerForName(name: provider); |
323 | if (!p) |
324 | return k; |
325 | k = G::getKey(p, in, passphrase, result); |
326 | } |
327 | // all |
328 | else { |
329 | ProviderList pl = allProviders(); |
330 | for (int n = 0; n < pl.count(); ++n) { |
331 | ConvertResult r; |
332 | k = G::getKey(pl[n], in, passphrase, &r); |
333 | if (result) |
334 | *result = r; |
335 | if (!k.isNull()) |
336 | break; |
337 | if (r == ErrorPassphrase) // don't loop if we get this |
338 | break; |
339 | } |
340 | } |
341 | |
342 | return k; |
343 | } |
344 | |
345 | PBEAlgorithm get_pbe_default() |
346 | { |
347 | return PBES2_TripleDES_SHA1; |
348 | } |
349 | |
350 | static PrivateKey get_privatekey_der(const SecureArray &der, |
351 | const QString &fileName, |
352 | void *ptr, |
353 | const SecureArray &passphrase, |
354 | ConvertResult *result, |
355 | const QString &provider) |
356 | { |
357 | PrivateKey out; |
358 | ConvertResult r; |
359 | out = getKey<PrivateKey, Getter_PrivateKey<SecureArray>, SecureArray>(provider, in: der, passphrase, result: &r); |
360 | |
361 | // error converting without passphrase? maybe a passphrase is needed |
362 | if (use_asker_fallback(r) && passphrase.isEmpty()) { |
363 | SecureArray pass; |
364 | if (ask_passphrase(fname: fileName, ptr, answer: &pass)) |
365 | out = getKey<PrivateKey, Getter_PrivateKey<SecureArray>, SecureArray>(provider, in: der, passphrase: pass, result: &r); |
366 | } |
367 | if (result) |
368 | *result = r; |
369 | return out; |
370 | } |
371 | |
372 | static PrivateKey get_privatekey_pem(const QString &pem, |
373 | const QString &fileName, |
374 | void *ptr, |
375 | const SecureArray &passphrase, |
376 | ConvertResult *result, |
377 | const QString &provider) |
378 | { |
379 | PrivateKey out; |
380 | ConvertResult r; |
381 | out = getKey<PrivateKey, Getter_PrivateKey<QString>, QString>(provider, in: pem, passphrase, result: &r); |
382 | |
383 | // error converting without passphrase? maybe a passphrase is needed |
384 | if (use_asker_fallback(r) && passphrase.isEmpty()) { |
385 | SecureArray pass; |
386 | if (ask_passphrase(fname: fileName, ptr, answer: &pass)) |
387 | out = getKey<PrivateKey, Getter_PrivateKey<QString>, QString>(provider, in: pem, passphrase: pass, result: &r); |
388 | } |
389 | if (result) |
390 | *result = r; |
391 | return out; |
392 | } |
393 | |
394 | //---------------------------------------------------------------------------- |
395 | // Global |
396 | //---------------------------------------------------------------------------- |
397 | |
398 | // adapted from Botan |
399 | static const unsigned char pkcs_sha1[] = |
400 | {0x30, 0x21, 0x30, 0x09, 0x06, 0x05, 0x2B, 0x0E, 0x03, 0x02, 0x1A, 0x05, 0x00, 0x04, 0x14}; |
401 | |
402 | static const unsigned char pkcs_md5[] = |
403 | {0x30, 0x20, 0x30, 0x0C, 0x06, 0x08, 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x02, 0x05, 0x05, 0x00, 0x04, 0x10}; |
404 | |
405 | static const unsigned char pkcs_md2[] = |
406 | {0x30, 0x20, 0x30, 0x0C, 0x06, 0x08, 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x02, 0x02, 0x05, 0x00, 0x04, 0x10}; |
407 | |
408 | static const unsigned char pkcs_ripemd160[] = |
409 | {0x30, 0x21, 0x30, 0x09, 0x06, 0x05, 0x2B, 0x24, 0x03, 0x02, 0x01, 0x05, 0x00, 0x04, 0x14}; |
410 | |
411 | QByteArray get_hash_id(const QString &name) |
412 | { |
413 | if (name == QLatin1String("sha1" )) |
414 | return QByteArray::fromRawData(data: (const char *)pkcs_sha1, size: sizeof(pkcs_sha1)); |
415 | else if (name == QLatin1String("md5" )) |
416 | return QByteArray::fromRawData(data: (const char *)pkcs_md5, size: sizeof(pkcs_md5)); |
417 | else if (name == QLatin1String("md2" )) |
418 | return QByteArray::fromRawData(data: (const char *)pkcs_md2, size: sizeof(pkcs_md2)); |
419 | else if (name == QLatin1String("ripemd160" )) |
420 | return QByteArray::fromRawData(data: (const char *)pkcs_ripemd160, size: sizeof(pkcs_ripemd160)); |
421 | else |
422 | return QByteArray(); |
423 | } |
424 | |
425 | QByteArray emsa3Encode(const QString &hashName, const QByteArray &digest, int size) |
426 | { |
427 | const QByteArray hash_id = get_hash_id(name: hashName); |
428 | if (hash_id.isEmpty()) |
429 | return QByteArray(); |
430 | |
431 | // logic adapted from Botan |
432 | const int basesize = hash_id.size() + digest.size() + 2; |
433 | if (size == -1) |
434 | size = basesize + 1; // default to 1-byte pad |
435 | int padlen = size - basesize; |
436 | if (padlen < 1) |
437 | return QByteArray(); |
438 | |
439 | QByteArray out(size, (char)0xff); // pad with 0xff |
440 | out[0] = 0x01; |
441 | out[padlen + 1] = 0x00; |
442 | int at = padlen + 2; |
443 | memcpy(dest: out.data() + at, src: hash_id.data(), n: hash_id.size()); |
444 | at += hash_id.size(); |
445 | memcpy(dest: out.data() + at, src: digest.data(), n: digest.size()); |
446 | return out; |
447 | } |
448 | |
449 | //---------------------------------------------------------------------------- |
450 | // DLGroup |
451 | //---------------------------------------------------------------------------- |
452 | class DLGroup::Private |
453 | { |
454 | public: |
455 | BigInteger p, q, g; |
456 | |
457 | Private(const BigInteger &p1, const BigInteger &q1, const BigInteger &g1) |
458 | : p(p1) |
459 | , q(q1) |
460 | , g(g1) |
461 | { |
462 | } |
463 | }; |
464 | |
465 | DLGroup::DLGroup() |
466 | { |
467 | d = nullptr; |
468 | } |
469 | |
470 | DLGroup::DLGroup(const BigInteger &p, const BigInteger &q, const BigInteger &g) |
471 | { |
472 | d = new Private(p, q, g); |
473 | } |
474 | |
475 | DLGroup::DLGroup(const BigInteger &p, const BigInteger &g) |
476 | { |
477 | d = new Private(p, 0, g); |
478 | } |
479 | |
480 | DLGroup::DLGroup(const DLGroup &from) |
481 | { |
482 | d = nullptr; |
483 | *this = from; |
484 | } |
485 | |
486 | DLGroup::~DLGroup() |
487 | { |
488 | delete d; |
489 | } |
490 | |
491 | DLGroup &DLGroup::operator=(const DLGroup &from) |
492 | { |
493 | delete d; |
494 | d = nullptr; |
495 | |
496 | if (from.d) |
497 | d = new Private(*from.d); |
498 | |
499 | return *this; |
500 | } |
501 | |
502 | QList<DLGroupSet> DLGroup::supportedGroupSets(const QString &provider) |
503 | { |
504 | return getList<DLGroupSet, Getter_GroupSet>(provider); |
505 | } |
506 | |
507 | bool DLGroup::isNull() const |
508 | { |
509 | return (d ? false : true); |
510 | } |
511 | |
512 | BigInteger DLGroup::p() const |
513 | { |
514 | Q_ASSERT(d); |
515 | return d->p; |
516 | } |
517 | |
518 | BigInteger DLGroup::q() const |
519 | { |
520 | Q_ASSERT(d); |
521 | return d->q; |
522 | } |
523 | |
524 | BigInteger DLGroup::g() const |
525 | { |
526 | Q_ASSERT(d); |
527 | return d->g; |
528 | } |
529 | |
530 | //---------------------------------------------------------------------------- |
531 | // PKey |
532 | //---------------------------------------------------------------------------- |
533 | class PKey::Private |
534 | { |
535 | public: |
536 | }; |
537 | |
538 | PKey::PKey() |
539 | { |
540 | d = new Private; |
541 | } |
542 | |
543 | PKey::PKey(const QString &type, const QString &provider) |
544 | : Algorithm(type, provider) |
545 | { |
546 | d = new Private; |
547 | } |
548 | |
549 | PKey::PKey(const PKey &from) |
550 | : Algorithm(from) |
551 | { |
552 | d = new Private; |
553 | *this = from; |
554 | } |
555 | |
556 | PKey::~PKey() |
557 | { |
558 | delete d; |
559 | } |
560 | |
561 | PKey &PKey::operator=(const PKey &from) |
562 | { |
563 | Algorithm::operator=(from); |
564 | *d = *from.d; |
565 | return *this; |
566 | } |
567 | |
568 | void PKey::set(const PKey &k) |
569 | { |
570 | *this = k; |
571 | } |
572 | |
573 | void PKey::assignToPublic(PKey *dest) const |
574 | { |
575 | dest->set(*this); |
576 | |
577 | // converting private to public |
578 | if (dest->isPrivate()) |
579 | static_cast<PKeyContext *>(dest->context())->key()->convertToPublic(); |
580 | } |
581 | |
582 | void PKey::assignToPrivate(PKey *dest) const |
583 | { |
584 | dest->set(*this); |
585 | } |
586 | |
587 | QList<PKey::Type> PKey::supportedTypes(const QString &provider) |
588 | { |
589 | return getList<Type, Getter_Type>(provider); |
590 | } |
591 | |
592 | QList<PKey::Type> PKey::supportedIOTypes(const QString &provider) |
593 | { |
594 | return getList<Type, Getter_IOType>(provider); |
595 | } |
596 | |
597 | bool PKey::isNull() const |
598 | { |
599 | return (!context() ? true : false); |
600 | } |
601 | |
602 | PKey::Type PKey::type() const |
603 | { |
604 | if (isNull()) |
605 | return RSA; // some default so we don't explode |
606 | return static_cast<const PKeyContext *>(context())->key()->type(); |
607 | } |
608 | |
609 | int PKey::bitSize() const |
610 | { |
611 | return static_cast<const PKeyContext *>(context())->key()->bits(); |
612 | } |
613 | |
614 | bool PKey::isRSA() const |
615 | { |
616 | return (type() == RSA); |
617 | } |
618 | |
619 | bool PKey::isDSA() const |
620 | { |
621 | return (type() == DSA); |
622 | } |
623 | |
624 | bool PKey::isDH() const |
625 | { |
626 | return (type() == DH); |
627 | } |
628 | |
629 | bool PKey::isPublic() const |
630 | { |
631 | if (isNull()) |
632 | return false; |
633 | return !isPrivate(); |
634 | } |
635 | |
636 | bool PKey::isPrivate() const |
637 | { |
638 | if (isNull()) |
639 | return false; |
640 | return static_cast<const PKeyContext *>(context())->key()->isPrivate(); |
641 | } |
642 | |
643 | bool PKey::canExport() const |
644 | { |
645 | return static_cast<const PKeyContext *>(context())->key()->canExport(); |
646 | } |
647 | |
648 | bool PKey::canKeyAgree() const |
649 | { |
650 | return isDH(); |
651 | } |
652 | |
653 | PublicKey PKey::toPublicKey() const |
654 | { |
655 | PublicKey k; |
656 | if (!isNull()) |
657 | assignToPublic(dest: &k); |
658 | return k; |
659 | } |
660 | |
661 | PrivateKey PKey::toPrivateKey() const |
662 | { |
663 | PrivateKey k; |
664 | if (!isNull() && isPrivate()) |
665 | assignToPrivate(dest: &k); |
666 | return k; |
667 | } |
668 | |
669 | RSAPublicKey PKey::toRSAPublicKey() const |
670 | { |
671 | RSAPublicKey k; |
672 | if (!isNull() && isRSA()) |
673 | assignToPublic(dest: &k); |
674 | return k; |
675 | } |
676 | |
677 | RSAPrivateKey PKey::toRSAPrivateKey() const |
678 | { |
679 | RSAPrivateKey k; |
680 | if (!isNull() && isRSA() && isPrivate()) |
681 | assignToPrivate(dest: &k); |
682 | return k; |
683 | } |
684 | |
685 | DSAPublicKey PKey::toDSAPublicKey() const |
686 | { |
687 | DSAPublicKey k; |
688 | if (!isNull() && isDSA()) |
689 | assignToPublic(dest: &k); |
690 | return k; |
691 | } |
692 | |
693 | DSAPrivateKey PKey::toDSAPrivateKey() const |
694 | { |
695 | DSAPrivateKey k; |
696 | if (!isNull() && isDSA() && isPrivate()) |
697 | assignToPrivate(dest: &k); |
698 | return k; |
699 | } |
700 | |
701 | DHPublicKey PKey::toDHPublicKey() const |
702 | { |
703 | DHPublicKey k; |
704 | if (!isNull() && isDH()) |
705 | assignToPublic(dest: &k); |
706 | return k; |
707 | } |
708 | |
709 | DHPrivateKey PKey::toDHPrivateKey() const |
710 | { |
711 | DHPrivateKey k; |
712 | if (!isNull() && isDH() && isPrivate()) |
713 | assignToPrivate(dest: &k); |
714 | return k; |
715 | } |
716 | |
717 | bool PKey::operator==(const PKey &a) const |
718 | { |
719 | if (isNull() || a.isNull() || type() != a.type()) |
720 | return false; |
721 | |
722 | if (a.isPrivate()) |
723 | return (toPrivateKey().toDER() == a.toPrivateKey().toDER()); |
724 | else |
725 | return (toPublicKey().toDER() == a.toPublicKey().toDER()); |
726 | } |
727 | |
728 | bool PKey::operator!=(const PKey &a) const |
729 | { |
730 | return !(*this == a); |
731 | } |
732 | |
733 | //---------------------------------------------------------------------------- |
734 | // PublicKey |
735 | //---------------------------------------------------------------------------- |
736 | PublicKey::PublicKey() |
737 | { |
738 | } |
739 | |
740 | PublicKey::PublicKey(const QString &type, const QString &provider) |
741 | : PKey(type, provider) |
742 | { |
743 | } |
744 | |
745 | PublicKey::PublicKey(const PrivateKey &k) |
746 | { |
747 | set(k.toPublicKey()); |
748 | } |
749 | |
750 | PublicKey::PublicKey(const QString &fileName) |
751 | { |
752 | *this = fromPEMFile(fileName, result: nullptr, provider: QString()); |
753 | } |
754 | |
755 | PublicKey::PublicKey(const PublicKey &from) |
756 | : PKey(from) |
757 | { |
758 | } |
759 | |
760 | PublicKey::~PublicKey() |
761 | { |
762 | } |
763 | |
764 | PublicKey &PublicKey::operator=(const PublicKey &from) |
765 | { |
766 | PKey::operator=(from); |
767 | return *this; |
768 | } |
769 | |
770 | RSAPublicKey PublicKey::toRSA() const |
771 | { |
772 | return toRSAPublicKey(); |
773 | } |
774 | |
775 | DSAPublicKey PublicKey::toDSA() const |
776 | { |
777 | return toDSAPublicKey(); |
778 | } |
779 | |
780 | DHPublicKey PublicKey::toDH() const |
781 | { |
782 | return toDHPublicKey(); |
783 | } |
784 | |
785 | bool PublicKey::canEncrypt() const |
786 | { |
787 | return isRSA(); |
788 | } |
789 | |
790 | bool PublicKey::canDecrypt() const |
791 | { |
792 | return isRSA(); |
793 | } |
794 | |
795 | bool PublicKey::canVerify() const |
796 | { |
797 | return (isRSA() || isDSA()); |
798 | } |
799 | |
800 | int PublicKey::maximumEncryptSize(EncryptionAlgorithm alg) const |
801 | { |
802 | const PKeyContext *ctx = qobject_cast<const PKeyContext *>(object: context()); |
803 | if (ctx) |
804 | return ctx->key()->maximumEncryptSize(alg); |
805 | else |
806 | return -1; |
807 | } |
808 | |
809 | SecureArray PublicKey::encrypt(const SecureArray &a, EncryptionAlgorithm alg) |
810 | { |
811 | PKeyContext *ctx = qobject_cast<PKeyContext *>(object: context()); |
812 | if (ctx) |
813 | return ctx->key()->encrypt(in: a, alg); |
814 | else |
815 | return SecureArray(); |
816 | } |
817 | |
818 | bool PublicKey::decrypt(const SecureArray &in, SecureArray *out, EncryptionAlgorithm alg) |
819 | { |
820 | PKeyContext *ctx = qobject_cast<PKeyContext *>(object: context()); |
821 | if (ctx) |
822 | return ctx->key()->decrypt(in, out, alg); |
823 | else |
824 | return false; |
825 | } |
826 | |
827 | void PublicKey::startVerify(SignatureAlgorithm alg, SignatureFormat format) |
828 | { |
829 | if (isDSA() && format == DefaultFormat) |
830 | format = IEEE_1363; |
831 | PKeyContext *ctx = qobject_cast<PKeyContext *>(object: context()); |
832 | if (ctx) |
833 | ctx->key()->startVerify(alg, format); |
834 | } |
835 | |
836 | void PublicKey::update(const MemoryRegion &a) |
837 | { |
838 | PKeyContext *ctx = qobject_cast<PKeyContext *>(object: context()); |
839 | if (ctx) { |
840 | ctx->key()->update(in: a); |
841 | } |
842 | } |
843 | |
844 | bool PublicKey::validSignature(const QByteArray &sig) |
845 | { |
846 | PKeyContext *ctx = qobject_cast<PKeyContext *>(object: context()); |
847 | if (ctx) |
848 | return ctx->key()->endVerify(sig); |
849 | return false; |
850 | } |
851 | |
852 | bool PublicKey::verifyMessage(const MemoryRegion &a, |
853 | const QByteArray &sig, |
854 | SignatureAlgorithm alg, |
855 | SignatureFormat format) |
856 | { |
857 | startVerify(alg, format); |
858 | update(a); |
859 | return validSignature(sig); |
860 | } |
861 | |
862 | QByteArray PublicKey::toDER() const |
863 | { |
864 | QByteArray out; |
865 | const PKeyContext *cur = static_cast<const PKeyContext *>(context()); |
866 | Provider *p = providerForIOType(type: type(), prefer: cur); |
867 | if (!p) |
868 | return out; |
869 | if (cur->provider() == p) { |
870 | out = cur->publicToDER(); |
871 | } else { |
872 | PKeyContext *pk = static_cast<PKeyContext *>(getContext(QStringLiteral("pkey" ), p)); |
873 | if (pk && pk->importKey(key: cur->key())) |
874 | out = pk->publicToDER(); |
875 | delete pk; |
876 | } |
877 | return out; |
878 | } |
879 | |
880 | QString PublicKey::toPEM() const |
881 | { |
882 | QString out; |
883 | const PKeyContext *cur = static_cast<const PKeyContext *>(context()); |
884 | if (!cur) |
885 | return out; |
886 | Provider *p = providerForIOType(type: type(), prefer: cur); |
887 | if (!p) |
888 | return out; |
889 | if (cur->provider() == p) { |
890 | out = cur->publicToPEM(); |
891 | } else { |
892 | PKeyContext *pk = static_cast<PKeyContext *>(getContext(QStringLiteral("pkey" ), p)); |
893 | if (pk && pk->importKey(key: cur->key())) |
894 | out = pk->publicToPEM(); |
895 | delete pk; |
896 | } |
897 | return out; |
898 | } |
899 | |
900 | bool PublicKey::toPEMFile(const QString &fileName) const |
901 | { |
902 | return stringToFile(fileName, content: toPEM()); |
903 | } |
904 | |
905 | PublicKey PublicKey::fromDER(const QByteArray &a, ConvertResult *result, const QString &provider) |
906 | { |
907 | return getKey<PublicKey, Getter_PublicKey<QByteArray>, QByteArray>(provider, in: a, passphrase: SecureArray(), result); |
908 | } |
909 | |
910 | PublicKey PublicKey::fromPEM(const QString &s, ConvertResult *result, const QString &provider) |
911 | { |
912 | return getKey<PublicKey, Getter_PublicKey<QString>, QString>(provider, in: s, passphrase: SecureArray(), result); |
913 | } |
914 | |
915 | PublicKey PublicKey::fromPEMFile(const QString &fileName, ConvertResult *result, const QString &provider) |
916 | { |
917 | QString pem; |
918 | if (!stringFromFile(fileName, s: &pem)) { |
919 | if (result) |
920 | *result = ErrorFile; |
921 | return PublicKey(); |
922 | } |
923 | return fromPEM(s: pem, result, provider); |
924 | } |
925 | |
926 | //---------------------------------------------------------------------------- |
927 | // PrivateKey |
928 | //---------------------------------------------------------------------------- |
929 | PrivateKey::PrivateKey() |
930 | { |
931 | } |
932 | |
933 | PrivateKey::PrivateKey(const QString &type, const QString &provider) |
934 | : PKey(type, provider) |
935 | { |
936 | } |
937 | |
938 | PrivateKey::PrivateKey(const QString &fileName, const SecureArray &passphrase) |
939 | { |
940 | *this = fromPEMFile(fileName, passphrase, result: nullptr, provider: QString()); |
941 | } |
942 | |
943 | PrivateKey::PrivateKey(const PrivateKey &from) |
944 | : PKey(from) |
945 | { |
946 | } |
947 | |
948 | PrivateKey::~PrivateKey() |
949 | { |
950 | } |
951 | |
952 | PrivateKey &PrivateKey::operator=(const PrivateKey &from) |
953 | { |
954 | PKey::operator=(from); |
955 | return *this; |
956 | } |
957 | |
958 | RSAPrivateKey PrivateKey::toRSA() const |
959 | { |
960 | return toRSAPrivateKey(); |
961 | } |
962 | |
963 | DSAPrivateKey PrivateKey::toDSA() const |
964 | { |
965 | return toDSAPrivateKey(); |
966 | } |
967 | |
968 | DHPrivateKey PrivateKey::toDH() const |
969 | { |
970 | return toDHPrivateKey(); |
971 | } |
972 | |
973 | bool PrivateKey::canDecrypt() const |
974 | { |
975 | return isRSA(); |
976 | } |
977 | |
978 | bool PrivateKey::canEncrypt() const |
979 | { |
980 | return isRSA(); |
981 | } |
982 | |
983 | bool PrivateKey::canSign() const |
984 | { |
985 | return (isRSA() || isDSA()); |
986 | } |
987 | |
988 | int PrivateKey::maximumEncryptSize(EncryptionAlgorithm alg) const |
989 | { |
990 | return static_cast<const PKeyContext *>(context())->key()->maximumEncryptSize(alg); |
991 | } |
992 | |
993 | bool PrivateKey::decrypt(const SecureArray &in, SecureArray *out, EncryptionAlgorithm alg) |
994 | { |
995 | return static_cast<PKeyContext *>(context())->key()->decrypt(in, out, alg); |
996 | } |
997 | |
998 | SecureArray PrivateKey::encrypt(const SecureArray &a, EncryptionAlgorithm alg) |
999 | { |
1000 | return static_cast<PKeyContext *>(context())->key()->encrypt(in: a, alg); |
1001 | } |
1002 | |
1003 | void PrivateKey::startSign(SignatureAlgorithm alg, SignatureFormat format) |
1004 | { |
1005 | if (isDSA() && format == DefaultFormat) |
1006 | format = IEEE_1363; |
1007 | static_cast<PKeyContext *>(context())->key()->startSign(alg, format); |
1008 | } |
1009 | |
1010 | void PrivateKey::update(const MemoryRegion &a) |
1011 | { |
1012 | static_cast<PKeyContext *>(context())->key()->update(in: a); |
1013 | } |
1014 | |
1015 | QByteArray PrivateKey::signature() |
1016 | { |
1017 | return static_cast<PKeyContext *>(context())->key()->endSign(); |
1018 | } |
1019 | |
1020 | QByteArray PrivateKey::signMessage(const MemoryRegion &a, SignatureAlgorithm alg, SignatureFormat format) |
1021 | { |
1022 | startSign(alg, format); |
1023 | update(a); |
1024 | return signature(); |
1025 | } |
1026 | |
1027 | SymmetricKey PrivateKey::deriveKey(const PublicKey &theirs) |
1028 | { |
1029 | const PKeyContext *theirContext = static_cast<const PKeyContext *>(theirs.context()); |
1030 | return static_cast<PKeyContext *>(context())->key()->deriveKey(theirs: *(theirContext->key())); |
1031 | } |
1032 | |
1033 | QList<PBEAlgorithm> PrivateKey::supportedPBEAlgorithms(const QString &provider) |
1034 | { |
1035 | return getList<PBEAlgorithm, Getter_PBE>(provider); |
1036 | } |
1037 | |
1038 | SecureArray PrivateKey::toDER(const SecureArray &passphrase, PBEAlgorithm pbe) const |
1039 | { |
1040 | SecureArray out; |
1041 | if (pbe == PBEDefault) |
1042 | pbe = get_pbe_default(); |
1043 | const PKeyContext *cur = static_cast<const PKeyContext *>(context()); |
1044 | Provider *p = providerForPBE(alg: pbe, ioType: type(), prefer: cur); |
1045 | if (!p) |
1046 | return out; |
1047 | if (cur->provider() == p) { |
1048 | out = cur->privateToDER(passphrase, pbe); |
1049 | } else { |
1050 | PKeyContext *pk = static_cast<PKeyContext *>(getContext(QStringLiteral("pkey" ), p)); |
1051 | if (pk->importKey(key: cur->key())) |
1052 | out = pk->privateToDER(passphrase, pbe); |
1053 | delete pk; |
1054 | } |
1055 | return out; |
1056 | } |
1057 | |
1058 | QString PrivateKey::toPEM(const SecureArray &passphrase, PBEAlgorithm pbe) const |
1059 | { |
1060 | QString out; |
1061 | if (pbe == PBEDefault) |
1062 | pbe = get_pbe_default(); |
1063 | const PKeyContext *cur = static_cast<const PKeyContext *>(context()); |
1064 | Provider *p = providerForPBE(alg: pbe, ioType: type(), prefer: cur); |
1065 | if (!p) |
1066 | return out; |
1067 | if (cur->provider() == p) { |
1068 | out = cur->privateToPEM(passphrase, pbe); |
1069 | } else { |
1070 | PKeyContext *pk = static_cast<PKeyContext *>(getContext(QStringLiteral("pkey" ), p)); |
1071 | if (pk->importKey(key: cur->key())) |
1072 | out = pk->privateToPEM(passphrase, pbe); |
1073 | delete pk; |
1074 | } |
1075 | return out; |
1076 | } |
1077 | |
1078 | bool PrivateKey::toPEMFile(const QString &fileName, const SecureArray &passphrase, PBEAlgorithm pbe) const |
1079 | { |
1080 | return stringToFile(fileName, content: toPEM(passphrase, pbe)); |
1081 | } |
1082 | |
1083 | PrivateKey |
1084 | PrivateKey::fromDER(const SecureArray &a, const SecureArray &passphrase, ConvertResult *result, const QString &provider) |
1085 | { |
1086 | return get_privatekey_der(der: a, fileName: QString(), ptr: (void *)&a, passphrase, result, provider); |
1087 | } |
1088 | |
1089 | PrivateKey |
1090 | PrivateKey::fromPEM(const QString &s, const SecureArray &passphrase, ConvertResult *result, const QString &provider) |
1091 | { |
1092 | return get_privatekey_pem(pem: s, fileName: QString(), ptr: (void *)&s, passphrase, result, provider); |
1093 | } |
1094 | |
1095 | PrivateKey PrivateKey::fromPEMFile(const QString &fileName, |
1096 | const SecureArray &passphrase, |
1097 | ConvertResult *result, |
1098 | const QString &provider) |
1099 | { |
1100 | QString pem; |
1101 | if (!stringFromFile(fileName, s: &pem)) { |
1102 | if (result) |
1103 | *result = ErrorFile; |
1104 | return PrivateKey(); |
1105 | } |
1106 | return get_privatekey_pem(pem, fileName, ptr: nullptr, passphrase, result, provider); |
1107 | } |
1108 | |
1109 | //---------------------------------------------------------------------------- |
1110 | // KeyGenerator |
1111 | //---------------------------------------------------------------------------- |
1112 | class KeyGenerator::Private : public QObject |
1113 | { |
1114 | Q_OBJECT |
1115 | public: |
1116 | KeyGenerator *parent; |
1117 | bool blocking, wasBlocking; |
1118 | PrivateKey key; |
1119 | DLGroup group; |
1120 | |
1121 | PKeyBase *k; |
1122 | PKeyContext *dest; |
1123 | DLGroupContext *dc; |
1124 | |
1125 | Private(KeyGenerator *_parent) |
1126 | : QObject(_parent) |
1127 | , parent(_parent) |
1128 | { |
1129 | k = nullptr; |
1130 | dest = nullptr; |
1131 | dc = nullptr; |
1132 | } |
1133 | |
1134 | ~Private() override |
1135 | { |
1136 | delete k; |
1137 | delete dest; |
1138 | delete dc; |
1139 | } |
1140 | |
1141 | public Q_SLOTS: |
1142 | void done() |
1143 | { |
1144 | if (!k->isNull()) { |
1145 | if (!wasBlocking) { |
1146 | k->setParent(nullptr); |
1147 | k->moveToThread(thread: nullptr); |
1148 | } |
1149 | dest->setKey(k); |
1150 | k = nullptr; |
1151 | |
1152 | key.change(c: dest); |
1153 | dest = nullptr; |
1154 | } else { |
1155 | delete k; |
1156 | k = nullptr; |
1157 | delete dest; |
1158 | dest = nullptr; |
1159 | } |
1160 | |
1161 | if (!wasBlocking) |
1162 | emit parent->finished(); |
1163 | } |
1164 | |
1165 | void done_group() |
1166 | { |
1167 | if (!dc->isNull()) { |
1168 | BigInteger p, q, g; |
1169 | dc->getResult(p: &p, q: &q, g: &g); |
1170 | group = DLGroup(p, q, g); |
1171 | } |
1172 | delete dc; |
1173 | dc = nullptr; |
1174 | |
1175 | if (!wasBlocking) |
1176 | emit parent->finished(); |
1177 | } |
1178 | }; |
1179 | |
1180 | KeyGenerator::KeyGenerator(QObject *parent) |
1181 | : QObject(parent) |
1182 | { |
1183 | d = new Private(this); |
1184 | d->blocking = true; |
1185 | } |
1186 | |
1187 | KeyGenerator::~KeyGenerator() |
1188 | { |
1189 | delete d; |
1190 | } |
1191 | |
1192 | bool KeyGenerator::blockingEnabled() const |
1193 | { |
1194 | return d->blocking; |
1195 | } |
1196 | |
1197 | void KeyGenerator::setBlockingEnabled(bool b) |
1198 | { |
1199 | d->blocking = b; |
1200 | } |
1201 | |
1202 | bool KeyGenerator::isBusy() const |
1203 | { |
1204 | return (d->k ? true : false); |
1205 | } |
1206 | |
1207 | PrivateKey KeyGenerator::createRSA(int bits, int exp, const QString &provider) |
1208 | { |
1209 | if (isBusy()) |
1210 | return PrivateKey(); |
1211 | |
1212 | d->key = PrivateKey(); |
1213 | d->wasBlocking = d->blocking; |
1214 | d->k = static_cast<RSAContext *>(getContext(QStringLiteral("rsa" ), provider)); |
1215 | if (!d->k) |
1216 | return PrivateKey(); |
1217 | d->dest = static_cast<PKeyContext *>(getContext(QStringLiteral("pkey" ), p: d->k->provider())); |
1218 | |
1219 | if (!d->blocking) { |
1220 | d->k->moveToThread(thread: thread()); |
1221 | d->k->setParent(d); |
1222 | connect(sender: d->k, signal: &RSAContext::finished, context: d, slot: &Private::done); |
1223 | static_cast<RSAContext *>(d->k)->createPrivate(bits, exp, block: false); |
1224 | } else { |
1225 | static_cast<RSAContext *>(d->k)->createPrivate(bits, exp, block: true); |
1226 | d->done(); |
1227 | } |
1228 | |
1229 | return d->key; |
1230 | } |
1231 | |
1232 | PrivateKey KeyGenerator::createDSA(const DLGroup &domain, const QString &provider) |
1233 | { |
1234 | if (isBusy()) |
1235 | return PrivateKey(); |
1236 | |
1237 | d->key = PrivateKey(); |
1238 | d->wasBlocking = d->blocking; |
1239 | d->k = static_cast<DSAContext *>(getContext(QStringLiteral("dsa" ), provider)); |
1240 | d->dest = static_cast<PKeyContext *>(getContext(QStringLiteral("pkey" ), p: d->k->provider())); |
1241 | |
1242 | if (!d->blocking) { |
1243 | d->k->moveToThread(thread: thread()); |
1244 | d->k->setParent(d); |
1245 | connect(sender: d->k, signal: &DSAContext::finished, context: d, slot: &Private::done); |
1246 | static_cast<DSAContext *>(d->k)->createPrivate(domain, block: false); |
1247 | } else { |
1248 | static_cast<DSAContext *>(d->k)->createPrivate(domain, block: true); |
1249 | d->done(); |
1250 | } |
1251 | |
1252 | return d->key; |
1253 | } |
1254 | |
1255 | PrivateKey KeyGenerator::createDH(const DLGroup &domain, const QString &provider) |
1256 | { |
1257 | if (isBusy()) |
1258 | return PrivateKey(); |
1259 | |
1260 | d->key = PrivateKey(); |
1261 | d->wasBlocking = d->blocking; |
1262 | d->k = static_cast<DHContext *>(getContext(QStringLiteral("dh" ), provider)); |
1263 | d->dest = static_cast<PKeyContext *>(getContext(QStringLiteral("pkey" ), p: d->k->provider())); |
1264 | |
1265 | if (!d->blocking) { |
1266 | d->k->moveToThread(thread: thread()); |
1267 | d->k->setParent(d); |
1268 | connect(sender: d->k, signal: &DHContext::finished, context: d, slot: &Private::done); |
1269 | static_cast<DHContext *>(d->k)->createPrivate(domain, block: false); |
1270 | } else { |
1271 | static_cast<DHContext *>(d->k)->createPrivate(domain, block: true); |
1272 | d->done(); |
1273 | } |
1274 | |
1275 | return d->key; |
1276 | } |
1277 | |
1278 | PrivateKey KeyGenerator::key() const |
1279 | { |
1280 | return d->key; |
1281 | } |
1282 | |
1283 | DLGroup KeyGenerator::createDLGroup(QCA::DLGroupSet set, const QString &provider) |
1284 | { |
1285 | if (isBusy()) |
1286 | return DLGroup(); |
1287 | |
1288 | Provider *p; |
1289 | if (!provider.isEmpty()) |
1290 | p = providerForName(name: provider); |
1291 | else |
1292 | p = providerForGroupSet(set); |
1293 | |
1294 | d->dc = static_cast<DLGroupContext *>(getContext(QStringLiteral("dlgroup" ), p)); |
1295 | d->group = DLGroup(); |
1296 | |
1297 | if (d->dc) { |
1298 | d->wasBlocking = d->blocking; |
1299 | if (!d->blocking) { |
1300 | connect(sender: d->dc, signal: &DLGroupContext ::finished, context: d, slot: &Private::done_group); |
1301 | d->dc->fetchGroup(set, block: false); |
1302 | } else { |
1303 | d->dc->fetchGroup(set, block: true); |
1304 | d->done_group(); |
1305 | } |
1306 | } |
1307 | |
1308 | return d->group; |
1309 | } |
1310 | |
1311 | DLGroup KeyGenerator::dlGroup() const |
1312 | { |
1313 | return d->group; |
1314 | } |
1315 | |
1316 | //---------------------------------------------------------------------------- |
1317 | // RSAPublicKey |
1318 | //---------------------------------------------------------------------------- |
1319 | RSAPublicKey::RSAPublicKey() |
1320 | { |
1321 | } |
1322 | |
1323 | RSAPublicKey::RSAPublicKey(const BigInteger &n, const BigInteger &e, const QString &provider) |
1324 | { |
1325 | RSAContext *k = static_cast<RSAContext *>(getContext(QStringLiteral("rsa" ), provider)); |
1326 | k->createPublic(n, e); |
1327 | PKeyContext *c = static_cast<PKeyContext *>(getContext(QStringLiteral("pkey" ), p: k->provider())); |
1328 | c->setKey(k); |
1329 | change(c); |
1330 | } |
1331 | |
1332 | RSAPublicKey::RSAPublicKey(const RSAPrivateKey &k) |
1333 | : PublicKey(k) |
1334 | { |
1335 | } |
1336 | |
1337 | BigInteger RSAPublicKey::n() const |
1338 | { |
1339 | return static_cast<const RSAContext *>(static_cast<const PKeyContext *>(context())->key())->n(); |
1340 | } |
1341 | |
1342 | BigInteger RSAPublicKey::e() const |
1343 | { |
1344 | return static_cast<const RSAContext *>(static_cast<const PKeyContext *>(context())->key())->e(); |
1345 | } |
1346 | |
1347 | //---------------------------------------------------------------------------- |
1348 | // RSAPrivateKey |
1349 | //---------------------------------------------------------------------------- |
1350 | RSAPrivateKey::RSAPrivateKey() |
1351 | { |
1352 | } |
1353 | |
1354 | RSAPrivateKey::RSAPrivateKey(const BigInteger &n, |
1355 | const BigInteger &e, |
1356 | const BigInteger &p, |
1357 | const BigInteger &q, |
1358 | const BigInteger &d, |
1359 | const QString &provider) |
1360 | { |
1361 | RSAContext *k = static_cast<RSAContext *>(getContext(QStringLiteral("rsa" ), provider)); |
1362 | k->createPrivate(n, e, p, q, d); |
1363 | PKeyContext *c = static_cast<PKeyContext *>(getContext(QStringLiteral("pkey" ), p: k->provider())); |
1364 | c->setKey(k); |
1365 | change(c); |
1366 | } |
1367 | |
1368 | BigInteger RSAPrivateKey::n() const |
1369 | { |
1370 | return static_cast<const RSAContext *>(static_cast<const PKeyContext *>(context())->key())->n(); |
1371 | } |
1372 | |
1373 | BigInteger RSAPrivateKey::e() const |
1374 | { |
1375 | return static_cast<const RSAContext *>(static_cast<const PKeyContext *>(context())->key())->e(); |
1376 | } |
1377 | |
1378 | BigInteger RSAPrivateKey::p() const |
1379 | { |
1380 | return static_cast<const RSAContext *>(static_cast<const PKeyContext *>(context())->key())->p(); |
1381 | } |
1382 | |
1383 | BigInteger RSAPrivateKey::q() const |
1384 | { |
1385 | return static_cast<const RSAContext *>(static_cast<const PKeyContext *>(context())->key())->q(); |
1386 | } |
1387 | |
1388 | BigInteger RSAPrivateKey::d() const |
1389 | { |
1390 | return static_cast<const RSAContext *>(static_cast<const PKeyContext *>(context())->key())->d(); |
1391 | } |
1392 | |
1393 | //---------------------------------------------------------------------------- |
1394 | // DSAPublicKey |
1395 | //---------------------------------------------------------------------------- |
1396 | DSAPublicKey::DSAPublicKey() |
1397 | { |
1398 | } |
1399 | |
1400 | DSAPublicKey::DSAPublicKey(const DLGroup &domain, const BigInteger &y, const QString &provider) |
1401 | { |
1402 | DSAContext *k = static_cast<DSAContext *>(getContext(QStringLiteral("dsa" ), provider)); |
1403 | k->createPublic(domain, y); |
1404 | PKeyContext *c = static_cast<PKeyContext *>(getContext(QStringLiteral("pkey" ), p: k->provider())); |
1405 | c->setKey(k); |
1406 | change(c); |
1407 | } |
1408 | |
1409 | DSAPublicKey::DSAPublicKey(const DSAPrivateKey &k) |
1410 | : PublicKey(k) |
1411 | { |
1412 | } |
1413 | |
1414 | DLGroup DSAPublicKey::domain() const |
1415 | { |
1416 | return static_cast<const DSAContext *>(static_cast<const PKeyContext *>(context())->key())->domain(); |
1417 | } |
1418 | |
1419 | BigInteger DSAPublicKey::y() const |
1420 | { |
1421 | return static_cast<const DSAContext *>(static_cast<const PKeyContext *>(context())->key())->y(); |
1422 | } |
1423 | |
1424 | //---------------------------------------------------------------------------- |
1425 | // DSAPrivateKey |
1426 | //---------------------------------------------------------------------------- |
1427 | DSAPrivateKey::DSAPrivateKey() |
1428 | { |
1429 | } |
1430 | |
1431 | DSAPrivateKey::DSAPrivateKey(const DLGroup &domain, const BigInteger &y, const BigInteger &x, const QString &provider) |
1432 | { |
1433 | DSAContext *k = static_cast<DSAContext *>(getContext(QStringLiteral("dsa" ), provider)); |
1434 | k->createPrivate(domain, y, x); |
1435 | PKeyContext *c = static_cast<PKeyContext *>(getContext(QStringLiteral("pkey" ), p: k->provider())); |
1436 | c->setKey(k); |
1437 | change(c); |
1438 | } |
1439 | |
1440 | DLGroup DSAPrivateKey::domain() const |
1441 | { |
1442 | return static_cast<const DSAContext *>(static_cast<const PKeyContext *>(context())->key())->domain(); |
1443 | } |
1444 | |
1445 | BigInteger DSAPrivateKey::y() const |
1446 | { |
1447 | return static_cast<const DSAContext *>(static_cast<const PKeyContext *>(context())->key())->y(); |
1448 | } |
1449 | |
1450 | BigInteger DSAPrivateKey::x() const |
1451 | { |
1452 | return static_cast<const DSAContext *>(static_cast<const PKeyContext *>(context())->key())->x(); |
1453 | } |
1454 | |
1455 | //---------------------------------------------------------------------------- |
1456 | // DHPublicKey |
1457 | //---------------------------------------------------------------------------- |
1458 | DHPublicKey::DHPublicKey() |
1459 | { |
1460 | } |
1461 | |
1462 | DHPublicKey::DHPublicKey(const DLGroup &domain, const BigInteger &y, const QString &provider) |
1463 | { |
1464 | DHContext *k = static_cast<DHContext *>(getContext(QStringLiteral("dh" ), provider)); |
1465 | k->createPublic(domain, y); |
1466 | PKeyContext *c = static_cast<PKeyContext *>(getContext(QStringLiteral("pkey" ), p: k->provider())); |
1467 | c->setKey(k); |
1468 | change(c); |
1469 | } |
1470 | |
1471 | DHPublicKey::DHPublicKey(const DHPrivateKey &k) |
1472 | : PublicKey(k) |
1473 | { |
1474 | } |
1475 | |
1476 | DLGroup DHPublicKey::domain() const |
1477 | { |
1478 | return static_cast<const DHContext *>(static_cast<const PKeyContext *>(context())->key())->domain(); |
1479 | } |
1480 | |
1481 | BigInteger DHPublicKey::y() const |
1482 | { |
1483 | return static_cast<const DHContext *>(static_cast<const PKeyContext *>(context())->key())->y(); |
1484 | } |
1485 | |
1486 | //---------------------------------------------------------------------------- |
1487 | // DHPrivateKey |
1488 | //---------------------------------------------------------------------------- |
1489 | DHPrivateKey::DHPrivateKey() |
1490 | { |
1491 | } |
1492 | |
1493 | DHPrivateKey::DHPrivateKey(const DLGroup &domain, const BigInteger &y, const BigInteger &x, const QString &provider) |
1494 | { |
1495 | DHContext *k = static_cast<DHContext *>(getContext(QStringLiteral("dh" ), provider)); |
1496 | k->createPrivate(domain, y, x); |
1497 | PKeyContext *c = static_cast<PKeyContext *>(getContext(QStringLiteral("pkey" ), p: k->provider())); |
1498 | c->setKey(k); |
1499 | change(c); |
1500 | } |
1501 | |
1502 | DLGroup DHPrivateKey::domain() const |
1503 | { |
1504 | return static_cast<const DHContext *>(static_cast<const PKeyContext *>(context())->key())->domain(); |
1505 | } |
1506 | |
1507 | BigInteger DHPrivateKey::y() const |
1508 | { |
1509 | return static_cast<const DHContext *>(static_cast<const PKeyContext *>(context())->key())->y(); |
1510 | } |
1511 | |
1512 | BigInteger DHPrivateKey::x() const |
1513 | { |
1514 | return static_cast<const DHContext *>(static_cast<const PKeyContext *>(context())->key())->x(); |
1515 | } |
1516 | |
1517 | } |
1518 | |
1519 | #include "qca_publickey.moc" |
1520 | |