Compare commits

...

236 Commits

Author SHA1 Message Date
45f2312979 remove depricated features 2021-09-09 15:14:19 +03:00
a602142dcb disable doc target 2021-09-02 11:48:08 +03:00
5b49c00168
Merge pull request #1 from KDE/master
refresh
2021-09-02 09:56:29 +03:00
Albert Astals Cid
e9fd31b4a1 Fix wrong condition protecting test execution 2021-08-06 17:15:30 +02:00
Christophe Giboudeaux
7ead054437 Don't create pkgconfig files for Qt 6 builds
Qt 6 doesn't provide pkgconfig files.
2021-06-05 08:35:27 +02:00
Albert Astals Cid
b2e54520a3 Increase version 2021-05-31 23:12:57 +02:00
Tobias Junghans
5cc26f77f0 CI: add job for Qt 6 build/test 2021-05-29 22:28:27 +00:00
Tobias Junghans
2c3992f075 Add Qt 6 build support
The Core5Compat module is still required for QTextCodec and some
difficult remaining QRegExp -> QRegularExpression migrations.
2021-05-29 22:28:27 +00:00
Tobias Junghans
0c3db8a062 Start Qt 6 port
Still a few occurrences of QRegExp and QTextCodec need to be replaced
in order to drop the dependency on the Core5Compat module. Besides this
QCA builds fine with Qt 6.1 and passes all tests.
2021-05-29 22:28:27 +00:00
Tobias Junghans
974f8ec8d0 Migrate from QScopedPointer to std::unique_ptr
QScopedPointer::take() is deprecated since Qt 6.1 so we can switch
to std::unique_ptr everywhere to be consistent.
2021-05-29 22:28:27 +00:00
Tobias Junghans
040d7d6348 Use QVariant::fromValue() for custom types 2021-05-29 22:28:27 +00:00
Tobias Junghans
d8f1e6cb9c Remove QChar::Null from latin1 strings
QString::fromLatin1(QByteArray) includes the null characters from the
byte array which makes BigInteger and Certificate tests fail since
QCOMPARE distinguishes between QString("123") and QString("123\u0000").
2021-05-29 22:28:27 +00:00
Tobias Junghans
9443ba76ba Migrate from qrand() to std::rand()
qrand() is deprecated since Qt 5.15.
2021-05-29 22:28:27 +00:00
Tobias Junghans
effbe387a0 Use QDateTime::to/fromSecsSinceEpoch()
QDateTime::to/fromTime_t() are deprecated since Qt 5.8.
2021-05-29 22:28:27 +00:00
Tobias Junghans
e6a15466ae Make retval of size()/count() match format string
Starting with Qt 6 qsizetype is returned (equals size_t).
2021-05-29 22:28:27 +00:00
Tobias Junghans
35366fea78 Use QStringView for Qt >= 5.15.2
QStringView::mid() behaves identically to QString::mid() starting with
Qt 5.15.2.
2021-05-29 22:28:27 +00:00
Tobias Junghans
3e90e13d5e Use Qt::endl 2021-05-29 22:28:27 +00:00
Tobias Junghans
91ff0aa0db Use new QAbstractSocket::errorOccurred() signal
It's in Qt 5.15 already.
2021-05-29 22:28:27 +00:00
Tobias Junghans
564e906dd1 Use QString::split(..., Qt::SplitBehavior, ...)
It's in Qt 5.14 already.
2021-05-29 22:28:27 +00:00
Tobias Junghans
d3d16fcc17 CI: switch to Ubuntu 20.10 to have Qt >= 5.14
KDE Frameworks requires Qt 5.14 already so we should adopt that. This
will also save quite a few #ifdefs when migrating to Qt 6.
2021-05-29 22:28:27 +00:00
Mark Nalimov
797b430540 Minor docs fix 2021-05-24 11:01:43 +03:00
Albert Astals Cid
ecdd0538dd Fix CMSut::signverify_message_invalid failing "randomly"
Once in a blue moon it happens that signedResult1[signedResult1.size() -
2] is a 0, so setting it to 0 doesn't break the signature validation, so
   check if it's a 0 and if it is, set it to 1
2021-02-05 16:45:07 +00:00
Albert Astals Cid
aa26b43be2 CI: give the plugin path for tests, otherwise some are not found
also run the tests on the debian:unstable CI to have testing with
different versions of dependencies
2021-02-05 16:47:13 +01:00
Albert Astals Cid
bc94cc08e1 openssl 1.1.1i made verification of empty messages always succeed
BUGS: 432519
2021-02-05 16:40:19 +01:00
Albert Astals Cid
2d7e7e8242 increase version 2021-02-02 23:51:45 +01:00
Albert Astals Cid
32275f1a74 Move moc include outside the QCA namespace
It's the right thing to do and also fixes build with gcc 11
2021-01-24 20:07:09 +00:00
Albert Astals Cid
1bcde93efc CI: Switch to new clang-format 2021-01-24 17:54:53 +00:00
Albert Astals Cid
e9e0f2085d Update the Qt requirement to what we actually test on CI 2020-12-10 19:51:38 +01:00
Albert Astals Cid
bd31ef1587 gitlab-ci: use eatmydata in apt-get
apt-get uses several fsync() calls on each package it installs, and that's
very slow, especially on non-SSD. eatmydata turns fsync into no-op, which
makes package installation much faster (it can cause corruption if there's
power loss or similar, but that doesn't matter in CI where we throw away
the whole container anyway).
2020-12-09 22:32:13 +00:00
Albert Astals Cid
7174e6ed70 Disable performance-no-automatic-move
It's too noisy with Qt classes
2020-12-09 21:33:05 +01:00
Albert Astals Cid
0684db8255 Add .git-blame-ignore-revs and some instructions for clang-format 2020-09-07 02:29:40 +02:00
Albert Astals Cid
dfb96ac596 Check clang-format at CI stage 2020-09-07 02:29:36 +02:00
Albert Astals Cid
f62a8ee8f7 Run clang-format
find . \( -name "*.cpp" -or -name "*.h"  -or -name "*.c"  -or -name "*.cc" \) -exec clang-format -i {} \;

If you reached this file doing a git blame, please see README.clang-format (added 2 commits in the future of this one)
2020-09-07 02:13:47 +02:00
Sergey Ilinykh
04dbe5ca7d Add clang-format file 2020-09-07 02:13:09 +02:00
Albert Astals Cid
db8ff052a9 Add a clang-format off marker
Otherwise clang-format unoptimizes the code
2020-09-07 02:13:09 +02:00
Albert Astals Cid
f88abb0697 Rewrite code a bit so clang-format doesn't break exceptions
clazy and clang-tidy comments needs to in the proper place
2020-09-07 02:11:39 +02:00
Sergey Ilinykh
0fd3c4cb26 Fixed windows.h auto ordering 2020-09-06 23:46:15 +02:00
Albert Astals Cid
0d174fea58 More values().contains() -> contains() 2020-09-06 23:41:53 +02:00
Albert Astals Cid
fb926ae7b2 Rewrite the values().contains() with a single contains() 2020-09-06 21:31:10 +02:00
Albert Astals Cid
6f4e01f92d qca-gcrypt: mark functions only used in one file as static 2020-07-13 18:59:28 +02:00
Alexander Volkov
71a1f95cba qca-gcrypt: Add support for HKDF 2020-07-13 16:55:56 +00:00
Larry Shaffer
f899a6aaad
Add macOS framework major version
- Use of major is like Qt, Qwt, etc.

Signed-off-by: Yurii Kolesnykov <root@yurikoles.com>
2020-07-06 14:25:24 +03:00
Albert Astals Cid
6c5486c227 Increase version 2020-07-04 10:51:52 +02:00
Albert Astals Cid
dd323fb8dc Update rootcerts.pem 2020-07-04 10:51:30 +02:00
Albert Astals Cid
6ee845ba60 ossl: Fix memory leak when querying for tls supported cipher suites 2020-06-22 22:55:29 +02:00
Albert Astals Cid
5d027c8012 tlsunittest: Fix memory leak 2020-06-22 22:53:55 +02:00
Albert Astals Cid
e23bf00919 pipeunittest: Fix memory leak 2020-06-22 22:52:44 +02:00
Albert Astals Cid
cfc80a9d6e ossl: Fix memory leak in CRL handling
ASN1_INTEGER_to_BN returns memory that needs to be freed
2020-06-22 22:46:13 +02:00
Albert Astals Cid
a014df24c5 ossl: Fix memory leak in fromPKCS12 2020-06-22 22:03:39 +02:00
Albert Astals Cid
c68a5e449f Fix memory leak in keybundle unittest 2020-06-22 22:03:39 +02:00
Albert Astals Cid
3242caee6a ossl: pkcs12: Don't crash on unknown private key type
BUGS: 423355
2020-06-22 22:03:35 +02:00
Friedrich W. H. Kossebau
ae5dec259f API dox: update some links in main page 2020-05-29 16:28:48 +02:00
Friedrich W. H. Kossebau
3b35392d13 API dox: fix generation of example tlssocket.cpp 2020-05-29 16:28:08 +02:00
Friedrich W. H. Kossebau
27dcf14de4 Add support for API docs generation with kapidox 2020-05-29 16:27:19 +02:00
Ivan Romanov
cabc7d32da Fix OpenSSL cipher names
OpenSSL provides own function to get cipher suite name by id.
No any sense to support own cipher suites list. Also now
this plugin will provide not just all available cipher suites.
But only these which enabled and can be used.

For old SSLv3 protocol ciphers have TLS variant names. It changes
prefix SSL with TLS.
2020-05-20 20:41:00 +05:00
Ivan Romanov
26af53173e Set minimum OpenSSL version in CMake 2020-05-20 19:07:01 +05:00
Ivan Romanov
b69aab2431 Fix KDE Licensing Policy problem
Added csv from https://www.iana.org/assignments/tls-parameters/tls-parameters-4.csv.
Also applied GPL license to gen-tls-parameters.sh and tls-parameters.cpp.
2020-05-19 20:08:41 +05:00
Ivan Romanov
cf929ce541 Add sh script to generate tls cipher strings 2020-05-18 14:45:48 +05:00
Ivan Romanov
bb9c771f4f Update TLS ClientCertificateType Identifiers 2020-05-18 00:18:21 +05:00
Albert Astals Cid
886d37792c Wrap char * in QStringLiteral
Compile++ for mac
2020-04-05 16:05:12 +00:00
Harald Sitter
77d127249c make memset easier to read
instead of manually calculating the size, just use sizeof on the members.
they are arrays, so the compiler can do the work for us.

Reviewers: sitter, vonreth

Reviewed By: sitter

Differential Revision: https://phabricator.kde.org/D9447

Diff By: Aleksey Nikolaev
2020-03-19 14:36:39 +01:00
Albert Astals Cid
cfea73392b Fix cross-compile under fedora mingw 2020-03-10 17:41:56 +01:00
Albert Astals Cid
02585a58e3 add a few const 2020-02-28 13:45:30 +01:00
Albert Astals Cid
4cf5d1965f Add more const qualifiers 2020-02-24 16:24:46 +01:00
Albert Astals Cid
06ad9c62b5 Increase version 2020-02-24 15:31:51 +01:00
Albert Astals Cid
30a9249dd9 Mark a few byte arrays as const 2020-02-17 17:39:40 +01:00
Albert Astals Cid
c1a028c345 Add const to a few lists 2020-02-16 12:11:57 +01:00
Albert Astals Cid
4100770e32 clang: Also enable the compile warnings
and turn some casts to reinterpret cast to make it clear "we know what
we're doing"
2020-02-15 12:29:54 +01:00
Albert Astals Cid
f944220634 Modernize cmake a bit: Remove confusing else and endif text 2020-02-15 12:29:54 +01:00
Albert Astals Cid
ad1b9e1b07 Enable QT_NO_CAST_FROM_ASCII 2020-02-15 10:21:12 +00:00
Albert Astals Cid
197b49677d openssl: Access NID_crl_number more correctly 2020-02-15 10:48:43 +01:00
Albert Astals Cid
9582a7970e openssl: Access NID_crl_reason more correctly 2020-02-15 10:47:03 +01:00
Albert Astals Cid
957e8ab4be test: Remove unused variable 2020-02-15 09:15:35 +00:00
Albert Astals Cid
8b171279e9 clazy: enable qstring allocation warning 2020-02-13 01:07:24 +01:00
Albert Astals Cid
4a98dbdcd9 Increase version for beta release 2020-02-12 18:53:56 +01:00
Albert Astals Cid
e2029649b9 clang-tidy: enable modernize-deprecated-headers and modernize-use-nullptr 2020-02-12 17:14:33 +01:00
Albert Astals Cid
c0ac498159 clazy: Enable container-anti-pattern
Except in the tests where being slow and convenient is better than fast
2020-02-12 16:55:18 +01:00
Albert Astals Cid
a29518b978 Add operator= to BigInt
Also make it just be implemented with the default as the tests
show that is enough

Fixes warning in newer gcc
2020-02-11 16:31:11 +01:00
Albert Astals Cid
001f827a4f Drop support for openssl <= 1.1 2020-02-11 14:09:19 +01:00
Albert Astals Cid
24e702e6cd Update rootcerts.pem 2020-02-10 00:36:27 +01:00
Albert Astals Cid
d26d7a7959 Add more override
And fix okular -> qca copy&paste typo ^_^
2020-02-09 01:21:32 +01:00
Albert Astals Cid
5ddf120260 More modern NSS/cmake 2020-01-30 18:23:59 +01:00
Albert Astals Cid
93336bb110 Enable more clang-tidy modernize checks 2020-01-30 18:02:17 +01:00
Albert Astals Cid
8ee19a09e2 Add a few modernize clang-tidy checks 2020-01-30 17:37:15 +01:00
Albert Astals Cid
0398e228de Add clang-tidy to the clazy CI 2020-01-30 16:55:33 +01:00
Albert Astals Cid
a177dbaae4 Remove QPROC_SIGNAL_RELAY define
It was always defined anyway, so makes the code easier to understand
2020-01-30 16:29:56 +01:00
Albert Astals Cid
4c31e0c81f static -> static const 2020-01-30 13:52:21 +01:00
Albert Astals Cid
c5f5a4c038 clazy: Enable level2 except a few checks
also a few of the manual checks
2020-01-29 17:36:23 +01:00
Albert Astals Cid
5e2751fe85 clazy: enable level1 2020-01-29 16:53:08 +01:00
Albert Astals Cid
294cf98f59 Enable all clazy level 0 tests except one
one: containter-anti-pattern, needs some bigger rework
2020-01-29 15:16:08 +01:00
Albert Astals Cid
dce16514fe Enable a clazy CI
Starting with only missing-qobject-macro check enabled
2020-01-29 14:31:55 +01:00
Albert Astals Cid
7df8f7e215 Move to the new connect syntax
QProcess::errorOccurred is since 5.6 so increase min version
2020-01-29 08:34:13 +00:00
Albert Astals Cid
9e9366bbef Add .gitlab-ci 2020-01-27 16:07:05 +01:00
Albert Astals Cid
c685525849 Fix compilation with older Qt 2020-01-27 15:21:03 +01:00
Albert Astals Cid
32c6eb989c Link only to invent as repo 2020-01-25 00:56:36 +01:00
Albert Astals Cid
e8a7e1f12b affinix.com is dead 2020-01-25 00:56:03 +01:00
Albert Astals Cid
987e447551 We don't work with Qt4 anymore 2020-01-25 00:55:47 +01:00
Albert Astals Cid
d61a1ce875 Rearrange README a bit 2020-01-25 00:54:38 +01:00
Albert Astals Cid
f9fc3f356f remove unused variables 2020-01-24 10:46:27 +01:00
Albert Astals Cid
d298a11af7 SASL_AUTH_EXTERNAL wants a char * not a char **
Reviewers: sitter

Reviewed By: sitter

Differential Revision: https://phabricator.kde.org/D26879
2020-01-23 23:33:03 +01:00
Albert Astals Cid
d3fd2d9a10 Don't store the char * of a bytearray.toLatin1().data()
It's dangling memory
2020-01-23 17:45:05 +01:00
Albert Astals Cid
d3f8ea684e QString::mid -> midRef 2020-01-23 17:40:59 +01:00
Albert Astals Cid
3d6e4e7c2e Enable QT_NO_URL_CAST_FROM_STRING 2020-01-23 17:29:27 +01:00
Albert Astals Cid
6a1d268315 Enable QT_NO_CAST_FROM_BYTEARRAY 2020-01-23 17:26:29 +01:00
Albert Astals Cid
2a988a2021 Add QT_NO_CAST_TO_ASCII 2020-01-23 17:19:49 +01:00
Albert Astals Cid
6b229c3ae2 Add QT_STRICT_ITERATORS 2020-01-23 17:18:46 +01:00
Albert Astals Cid
79af2e7fdf Enable QT_USE_QSTRINGBUILDER and QT_NO_NARROWING_CONVERSIONS_IN_CONNECT 2020-01-22 19:31:37 +01:00
Albert Astals Cid
dbef5838d4 Enable QT_NO_SIGNALS_SLOTS_KEYWORDS 2020-01-22 19:31:28 +01:00
Albert Astals Cid
80f58d05f0 Fix BotanHKDFContext::clone
And excercise it in the unittest
2020-01-21 17:41:24 +01:00
Albert Astals Cid
4449dd088b Fix KDFContex clone in botan/gcrypt
And excercise that from the unittest
2020-01-21 01:19:50 +01:00
Albert Astals Cid
29c7d98898 Fix MACContext clone in botan/gcrypt/nss
And excercise that from the unittest
2020-01-21 01:12:07 +01:00
Albert Astals Cid
0ce2b3927e Fix HashContext in botan/gcrypt/nss
And make sure the hashunittest exercises them
2020-01-21 00:54:10 +01:00
Albert Astals Cid
501a539c22 botan: Require botan2
It's already 2 years old, more than sensible to ask for uptodate crypto
stuff
2020-01-20 23:32:04 +01:00
Albert Astals Cid
156dd01575 hashunittest: Make finding the files easier 2020-01-20 23:16:15 +01:00
Albert Astals Cid
24df5ea742 hashunittest: Fail not warn if test files can't be found 2020-01-20 23:12:30 +01:00
Albert Astals Cid
c0d8f1807d botan: remove stdout here
This gets called on initialization and most people won't even probably
will be asking for this particular method so no need to be annoying
2020-01-20 23:04:36 +01:00
Albert Astals Cid
bdb0e9d37d hashunittest: test all providers 2020-01-20 23:03:31 +01:00
Albert Astals Cid
c1a4ad1ab1 botan: check md2 is supported before saying it is 2020-01-20 23:03:28 +01:00
Albert Astals Cid
61daaffee6 openssl: Reenable whirpool
If that means ancient openssl don't work, that's the problem of people
using ancient openssl
2020-01-20 22:49:09 +01:00
Albert Astals Cid
416d89268e ciphertest: Test all providers 2020-01-20 20:02:02 +01:00
Albert Astals Cid
391360f145 gcrypt: disable des, seems it fails on some cases 2020-01-20 20:02:02 +01:00
Albert Astals Cid
f429960d58 qcrypt: Fix crash on platforms where uint and size_t are different 2020-01-20 20:02:02 +01:00
Albert Astals Cid
a77ea02b8d botan: Check if ciphers are supported before saying they are
Now all tests pass :)
2020-01-20 20:02:02 +01:00
Laurent Montel
acb45eeb84 Use nullptr 2020-01-20 13:37:51 +01:00
Albert Astals Cid
694abbcafa kdfunittest: Test all the backends
and be less verbose when a backend doesn't support what we're testing,
it's fine if the some other one does
2020-01-20 01:01:02 +01:00
Albert Astals Cid
5105fc4981 botan: Make sure it supports pbkdf1(md2) before saying we to
At least my version (2.13.0) doesn't seem to support it

"Fixes" kdfunittest
2020-01-20 00:46:41 +01:00
Albert Astals Cid
b9d80939c6 botan: Fix crash if asking for something botan doesn't provide
Fixes crash in KDFUnitTest with my botan installation
2020-01-19 22:32:32 +01:00
Albert Astals Cid
1b061d63a8 gpg: use the loopback pinentry
otherwise we don't get asked back for passphrase like we want to
2020-01-19 22:17:53 +01:00
Albert Astals Cid
8adde8d9c7 Add file i forgot to commit, sorry ^_^ 2020-01-19 22:16:08 +01:00
Albert Astals Cid
a0194d7ffd qFind -> std::find 2020-01-19 18:01:15 +01:00
Albert Astals Cid
ba3fb44b49 qVariantSetValue -> QVariant::setValue 2020-01-19 17:59:03 +01:00
Albert Astals Cid
70406170f5 Cleanup Qt version checks 2020-01-19 17:57:35 +01:00
Albert Astals Cid
4ad7e911d9 QString::sprintf -> QString::asprintf 2020-01-19 17:45:25 +01:00
Albert Astals Cid
0816a04f42 qSort -> std::sort 2020-01-19 17:35:06 +01:00
Albert Astals Cid
83c23c7a3a QTime -> QElapsedTimer 2020-01-19 17:32:15 +01:00
Albert Astals Cid
d71f4c279b Drop Qt4 support 2020-01-19 17:19:23 +01:00
Albert Astals Cid
3293100c42 remove slot that was declared but never implemented 2020-01-19 17:01:19 +01:00
Albert Astals Cid
00d311d90f Add override 2020-01-19 16:28:44 +01:00
Albert Astals Cid
326399794e qca-botan: Don't crash if BotanCipherContext fails
Makes the cipher unit test at least not crash (even if it doesn't pass)
2020-01-19 16:27:09 +01:00
Albert Astals Cid
691395e193 BigInteger: Test the toArray/fromArray 2020-01-19 12:16:37 +01:00
Nicolas Fella
c167627675 Don't use obsolete qVariantFromValue
Test Plan: Same tests as before pass

Reviewers: iromanov, sitter, dfaure, #frameworks

Reviewed By: sitter

Differential Revision: https://phabricator.kde.org/D25802
2019-12-07 23:27:42 +01:00
Harald Sitter
4b11437f7a change the android condition to a getuid check
it's unclear if anyone would ever run a qca app as root on android, but
in case they do we'd still want to drop

discussed in D23289
2019-09-07 17:26:31 +02:00
Peter Petrik
2895ca34dd Fix QCA android build
Summary:
to be able to run Input App (Android), we have to avoid calls to setuid. Otherwise the application coredumps on this call during runtime.

see https://github.com/lutraconsulting/input-sdk/blob/master/android/recipes/qca/recipe.sh

Reviewers: sitter, dfaure

Reviewed By: sitter

Differential Revision: https://phabricator.kde.org/D23289
2019-09-07 17:26:28 +02:00
R.J.V. Bertin
0be2a2ced3 Call cmake_minimum_required() before project()
Also correct a typo.

Differential revision: https://phabricator.kde.org/D8510
2019-06-08 17:20:00 +02:00
R.J.V. Bertin
b614cdbd6e also set the INSTALL_NAME_DIR for regular Mac libs
Failing to do so can cause linker/loader failures when installing
the QCA library to a non-standard location (e.g. the Qt install tree).
2019-06-08 16:18:03 +02:00
Harald Sitter
db5f82be2a bump version to 2.2.1 2019-04-23 14:04:15 +02:00
Harald Sitter
b38e904a4e Partially revert "Require CMake 3.4 and use the OpenSSL imported libs"
Summary:
This reverts the QcaMacro changes of
commit 1137ed5f07d137296874f7dd1ee629f903507161 as they seem fairly
unrelated to the actual openssl change and proof to cause persistent issues
with buildability.

Further revert "unbreak build by moving away from deprecated exec_program"
This reverts commit 32419c899c77b8f5ece374d2453ee37e89af7c10.
Which was done in an attempt to remidy the build problems.

Further revert "Actually abort after the message that tells people to set CMAKE_INSTALL_PREFIX"
This reverts commit 63fd27fbce780bccb9c9b3ff6649888cfd809c6a.
Which was also done in an attempt to fix the problems.

BUG: 406353

Test Plan:
- when configuring without any arguments the qmake derived paths are used and correct
- when configuring with CMAKE_INSTALL_PREFIX the paths are accordingly reported below that

QCA prefix is /opt
Plugins will be installed to /opt/lib/qca-qt5
Binary will be installed to /opt/bin
Library will be installed to /opt/lib
Public headers will be installed to /opt/include/Qca-qt5
Private headers will be installed to /opt/include/Qca-qt5
Feature file will be installed to /opt/mkspecs/features
Documentation will be installed to /opt/share/doc/qca-qt5/html
Man page will be installed to /opt/share/man
Pkg-config file will be installed to /opt/lib/pkgconfig

Reviewers: dfaure, arojas, vonreth

Reviewed By: dfaure, arojas

Differential Revision: https://phabricator.kde.org/D20408
2019-04-23 14:03:50 +02:00
Harald Sitter
32419c899c unbreak build by moving away from deprecated exec_program
Summary:
since 1137ed5f07d137296874f7dd1ee629f903507161 which bumped cmake and
started using TARGET_FILE for the qmake calls qca failed to build for me.
I fail to understand why exactly that is but I suspect it has to do with
the fact that exec_program is deprecated and may not be working
(correctly?) with generator expressions.

moving to the not deprecated execute_process fixes clean builds on my
system and is at the very least a move away from deprecated tech with
no downsides

Test Plan: rm -rf * && cmake -DCMAKE_INSTALL_PREFIX=/usr ..

Reviewers: asturmlechner, dfaure, vonreth

Reviewed By: dfaure

Differential Revision: https://phabricator.kde.org/D20228
2019-04-08 11:32:48 +02:00
David Faure
63fd27fbce Actually abort after the message that tells people to set CMAKE_INSTALL_PREFIX
Test Plan:
`mkdir build ; cd build ; cmake ..` no longer prints out weird stuff after
the "!!!!" error message, it actually stops there as intended (AFAICS).
2019-03-29 09:17:38 +01:00
David Faure
7b03a01b18 Fix compilation error due to QByteArray/QString mixup
main.cpp:4251:35: error: no matching function for call to ‘QByteArray::indexOf(QString&)’
2019-03-17 00:09:21 +01:00
Hannah von Reth
1137ed5f07 Require CMake 3.4 and use the OpenSSL imported libs
Summary:
Fixes
 00:09:45.140 [162/278] Linking CXX shared module lib/qca-qt5/crypto/libqca-ossl.dylib
00:09:45.140 FAILED: lib/qca-qt5/crypto/libqca-ossl.dylib
00:09:45.140 : && /usr/bin/clang++ -O2 -g -DNDEBUG -isysroot /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.12.sdk -bundle -Wl,-headerpad_max_install_names  -o lib/qca-qt5/crypto/libqca-ossl.dylib plugins/qca-ossl/CMakeFiles/qca-ossl.dir/qca-ossl.cpp.o  lib/qca-qt5.framework/Versions/2.2.0/qca-qt5 /Users/packaging/Craft/BinaryCache/macos-64-clang/lib/libssl.dylib /Users/packaging/Craft/BinaryCache/macos-64-clang/lib/libcrypto.dylib -lcrypto /Users/packaging/Craft/BinaryCache/macos-64-clang/lib/QtCore.framework/QtCore -framework CoreFoundation -framework Security && :
00:09:45.140 ld: library not found for -lcrypto
00:09:45.140 clang: error: linker command failed with exit code 1 (use -v to see invocation)

Reviewers: dfaure, bcooksley, volkov

Reviewed By: dfaure

Differential Revision: https://phabricator.kde.org/D17913
2019-03-04 12:16:36 +01:00
Alexander Volkov
32343842d3 Fix build with botan < 2 and openssl < 1.1
Summary:
This commit amends f57d661416ecbdfbf9c16d8116c296cfdcbeb7d6.
HKDF support was added only in the new versions of the libs.

Reviewers: dfaure, bcooksley

Reviewed By: dfaure

Differential Revision: https://phabricator.kde.org/D16248
2018-10-17 14:54:34 +03:00
Nicolás Alvarez
ad50594cb2 Fix repeated 'the the' in comments. 2018-10-15 10:26:08 -03:00
Alexander Volkov
f57d661416 Introduce HKDF
Summary:
It's needed for implementation of Secret Service:
https://specifications.freedesktop.org/secret-service/ch07s03.html

Reviewers: iromanov, sitter, #frameworks, dfaure

Reviewed By: dfaure

Subscribers: dfaure

Differential Revision: https://phabricator.kde.org/D15510
2018-10-15 14:30:05 +03:00
Alexander Volkov
98eead0058 Add .arcconfig 2018-09-14 19:20:10 +03:00
Harald Sitter
da4d1d06d4 Openssl fix deprecation warnings
Summary:
Openssl fix deprecation warnings

Removed unused function: X509_SIG_getm

deprecated warnings for:
ASN1_STRING_data
DSA_generate_parameters
RSA_generate_key
RAND_pseudo_bytes

Tested with openssl-1.0.2l on ubuntu:14.04
Deprecation warning spotted with openssl-1.1.0.g-1

one deprecation warning left: TLSv1_client_method

Reviewers: sitter, fvogt

Reviewed By: fvogt

Differential Revision: https://phabricator.kde.org/D11616
2018-06-19 11:46:09 +02:00
Andreas Sturmlechner
e854f357f4 Make Qt5Network conditional on BUILD_TESTS
Summary: I did not find it in use somewhere else.

Reviewers: iromanov, sitter, rjvbb

Reviewed By: rjvbb

Subscribers: fvogt

Differential Revision: https://phabricator.kde.org/D12129
2018-06-06 11:21:17 +02:00
Antonio Rojas
78503bf574 Recommit botan 2 support without making botan mandatory
Differential Revision: https://phabricator.kde.org/D11997
2018-04-12 10:03:12 +02:00
Ben Cooksley
01cbb31770 Revert "Add botan 2 support"
This change adds a mandatory dependency on Botan, which is not available at this time within Craft.
As this change was not notified to Sysadmin and because it has left us in a state whereby we are unable to get the Windows CI system back up and running, this is being reverted so it can be brought back online.

Please reintroduce this change once support for having Botan as optional is restored

This reverts commit 47163784d74232e3a844fc42897bffc7eff817b4.
2018-04-12 19:48:32 +12:00
Antonio Rojas
47163784d7 Add botan 2 support
Botan 1.10 will be EOL'd this year. This patch is a rough port to botan 2 API. Also:

- Removes support for botan < 1.10 to simplify code (1.10 was released 7 years ago)
- Ports the cmake module to use pkgconfig, since botan-config doesn't exist anymore in v2.
- To minimize ifdef'd code, botan2 unique_ptr's are release'd
- Removes -ansi C(XX)FLAGS, botan 2 requires C++11

Differential Revision: https://phabricator.kde.org/D11997
2018-04-11 21:43:57 +02:00
Harald Sitter
3e6a86b6b8 Merge branch 'v2.1' 2018-03-22 12:16:44 +01:00
Harald Sitter
b1abd13319 Qca: fix cypto.prf on MacOs
Summary: Fixed crypto.prf for frameworks build with qt5

Reviewers: iromanov, sitter, rjvbb

Reviewed By: sitter, rjvbb

Differential Revision: https://phabricator.kde.org/D11480
2018-03-22 12:15:57 +01:00
Harald Sitter
ee536fd995 Merge remote-tracking branch 'origin/v2.1' 2018-03-22 12:02:31 +01:00
Fabian Vogt
d58e20ee65 Add support for OpenSSL 1.1.0
Test Plan:
Ran the testsuite with OpenSSL 1.1.0g and 1.0.2j, all passed.
Using this code with kdeconnect and okteta successfully on my system now.

Reviewers: iromanov

Subscribers: anthonyfieroni, alonbl, heikobecker, cfeck, asturmlechner, bero, rdieter

Differential Revision: https://phabricator.kde.org/D9416
2018-01-04 20:02:38 +01:00
Ivan Romanov
159e144abf Disable missed openssl cipher suites
Fedora 26 has no them.
2017-09-30 15:45:59 +05:00
Ivan Romanov
8871dcd2e1 Fix CMake warning
CMP 0020 is deprecated. Avoid using of old behaviour.
2017-09-18 22:28:00 +05:00
Ivan Romanov
df794c0181 Remove deprecated keyword 2017-07-08 09:53:45 +05:00
Alon Bar-Lev
5f18ebc705 build: fix C++11 throwing distructors
For >=C++11, explicitly mark throwing destructors `noexcept(false)`

Thanks: Peter-Levine <plevine457@gmail.com>
2017-03-21 12:34:29 +02:00
Ivan Romanov
be55b9c98d Fix Qt5.7 warning 2017-03-01 13:22:48 +05:00
Ivan Romanov
aec63cd2e6 Bump version to 2.1.3 2017-02-06 17:29:44 +05:00
Ivan Romanov
89800d4341 tlsunittest: disable some ciphers 2017-02-06 17:29:01 +05:00
Ivan Romanov
f4b2eb0ced Fix previous commit 2017-01-29 15:20:17 +05:00
Ivan Romanov
b435c1b87b Avoid @rpath on Mac OS 2017-01-29 14:06:08 +05:00
Samuel Gaist
7ba0ee591e OS X build and warning fix
Revert "Add missed file"

This reverts commit 4c9f27270e0a7c00c10cbc56ce5c6842b47e5ab2.

FindCoreFoundation.cmake is not needed since CoreFoundation
is a system framework. Its use has been removed by
commit f223ce03d4b94ffbb093fc8be5adf8d968f54434

Acked by: Ivan Čukić

REVIEW: 126285
2016-10-20 13:34:23 +02:00
Ivan Romanov
d320ef4fdb Add some missed headers to Qt Creator project 2016-10-10 21:50:18 +05:00
Ivan Romanov
28245c731e Add base64 convenience functions 2016-09-19 10:48:11 +05:00
Ivan Romanov
19ec49f89a Bump version to 2.2.0 2016-09-19 10:48:11 +05:00
Ivan Romanov
57878ff44f Add support for AES GCM and AES CCM modes
Only qca-openssl now can use GCM and CCM. CCM is not tested and
planed for future.
2016-09-19 10:48:11 +05:00
Ivan Romanov
4efa158c31 Improve documentation 2016-09-19 10:47:25 +05:00
Ivan Romanov
fdf961cfa3 Require CMake 3.0 on Mac OS X 2016-08-26 08:53:37 +05:00
Raphael Kubo da Costa
84f53aea25 qca-ossl: Remove SHA0 from all_hash_types() when it is not available.
Commit 0dbed8e ("qca-ossl: Fix build without support for SHA-0") forgot
to add an #ifdef check for SHA0 support in all_hash_types().

REVIEW: 128700
2016-08-18 08:52:57 +02:00
Ivan Romanov
6a685d6b0b Refactor cipherunittest 2016-08-09 11:26:47 +05:00
Ivan Romanov
759ff45dba Fix indents in cipherunittest 2016-08-09 10:48:36 +05:00
Rolf Eike Beer
eb5eeca609 fix the mkspecs install directory when cross-compiling using Qt5
REVIEW:128308
2016-07-02 19:05:19 +02:00
Rolf Eike Beer
601fd3a051 fix base64 decoding on ARM
This code was broken on ARM and other architectures where "char" is unsigned by
default.

First, it breaks with newer compilers with errors like:

  .../src/qca_textfilter.cpp:314:2: error: narrowing conversion of '-1' from 'int' to 'char' inside { } [-Wnarrowing]

Second, if the compiler would just allow this conversion then the unsigned char
would hold 255, which would not be sign extended when cast to an int later, so
all the checks "< 0" will never trigger, and so invalid input characters cannot
be detected.

REVIEW:128295
BUG:364495
2016-06-27 18:24:02 +02:00
Ivan Romanov
a0c9a28728 Fix imported target name 2016-05-27 15:52:47 +05:00
Ivan Romanov
9e4bf79543 Fix install framework 2016-05-27 15:41:25 +05:00
Patrizio Bekerle
583d450885 fixed a typo 2016-03-17 11:03:42 +01:00
Samuel Gaist
f223ce03d4 OS X build and warning fix
The cmake find file was missing, but CoreFoundation being a system
framework, no need to search for it.

Update code to not use deprecated functions/data structure

CSSM_DATA and SecCertificateGetData have been deprecated since 10.7.
This patch uses SecCertificateCopyData which is the official
replacement.

Reviewed at https://git.reviewboard.kde.org/r/125800/
2015-12-08 21:32:39 +01:00
Rex Dieter
1ff36f4030 use _DEFAULT_SOURCE instead of _BSD_SOURCE
the former is used in other kde software in general, and
the latter is generally deprecated on modern glibc's
2015-11-19 13:23:16 -06:00
Ivan Romanov
4c9f27270e Add missed file
This file must be a part of 4fd11c444a51e8d317b0d68c7b90a8e0f2c6af9f
commit.

REVIEW: 121703
2015-11-18 23:54:14 +05:00
Ivan Romanov
69d8e070f0 Delete dead variable
className is not used. Furthemore it leads to possible crash when no _instance.
2015-11-11 12:35:10 +05:00
Ivan Romanov
da14be6f1b Fix empty strings in pluginPaths
Empty strings lead to strange behaviour and crashes.
2015-11-11 01:54:33 +05:00
Ivan Romanov
558f819819 gnupg: use utf-8 for keys output 2015-10-29 10:52:11 +05:00
Ivan Romanov
bf61f35cb4 gnupg: fixed keys is not updating
On Windows gpg uses ANSI codepage to output homedir and keyrings
paths. No way to output in utf-8. Gpg returns utf-8 strings output
only when --with-colons option is used.
2015-10-29 10:52:11 +05:00
Ivan Romanov
7e4192b70e gnupg: resolve symbolic links
Keyrings watcher can gets paths in any format. To avoid possible
problems try to use unified names for paths.
2015-10-29 10:52:11 +05:00
Ivan Romanov
7a76a9c027 qca-gnupg: default path to keyrings
When no keys 'gpg --list-keys' doesn't return path to keyring file.
Path is needest for watching to know when keys added or removed.
Use default keyrings path based on GnuPG home directory. This
directory gets with output 'gpg --version'. Line which starts with
'Home: ' contains GnuPG home directory. I believe it is correct
for GnuPG always and won't be changed in the future.
2015-10-29 10:52:11 +05:00
Heiko Becker
0dbed8eb38 qca-ossl: Fix build without support for SHA-0
LibreSSL >= 2.3.0 removed support for SHA-0, so there's no EVP_sha
anymore.
Wikipedia says about SHA-0: "160-bit hash function published in 1993
under the name SHA. It was withdrawn shortly after publication due to
an undisclosed "significant flaw" and replaced by the slightly revised
version SHA-1.'

REVIEW: 125387
2015-10-28 22:06:21 +01:00
Heiko Becker
20a587d776 qca-ossl: Fix build without SSLv3
This fixes building with LibreSSL >= 2.3.0 which has removed support
for SSLv3 completely. As far as I know OpenSSL can be configured to
build without it, so it might be helpful there as well.

REVIEW: 125386
2015-10-28 22:05:59 +01:00
Alon Bar-Lev
db17d5969b plugins: qca-logger: README: fix typo
Signed-off-by: Alon Bar-Lev <alon.barlev@gmail.com>
2015-10-23 22:32:07 +03:00
Harald Sitter
e44d0a335e bump version to 2.1.1 2015-10-02 11:35:20 +02:00
Harald Sitter
4f966b0217 Merge branch 'master' into qt5 2015-09-24 10:49:28 +02:00
Jan Grulich
66b9754170 Use Q_SLOTS/Q_SIGNALS instead of slots/signals in all headers from include dir
REVIEW:125289
2015-09-17 16:14:24 +02:00
Harald Sitter
088ff642fc Merge branch 'master' into qt5 2015-04-22 13:07:32 +02:00
Samuel Gaist
4fd11c444a Link against CoreFoundation rather than Carbon
Currently qca links to the Carbon framework for building however the mac
specific code don't use any Carbon classes but CoreFoundation. This patch
aims to update the code and build script to link to the more generic
CoreFoundation framework which may also allow to build it on iOS (not
verified).

REVIEW: 121703
2015-04-22 13:06:26 +02:00
Hrvoje Senjan
cc418554ad Merge remote-tracking branch 'origin/master' into qt5 2015-01-17 20:13:00 +01:00
Hrvoje Senjan
7207e6285e Add missing QIODevice include
Fixes build with Qt 5.5
2015-01-17 20:12:18 +01:00
Raphael Kubo da Costa
d4e9444f9d Do not end Cipher::Mode with a comma.
This solves a build failure with compilers such as GCC 4.2:
/usr/local/include/QtCrypto/qca_basic.h:598: error: comma at end of enumerator list

REVIEW: 122107
2015-01-17 15:21:20 +02:00
Harald Sitter
e40307d108 Merge remote-tracking branch 'origin/master' into qt5 2015-01-15 00:25:32 +01:00
Raphael Kubo da Costa
19aeaedd54 cmake: Make the check for QC_CERTSTORE_PATH actually work.
The previous code (present since the file was created) mixed different
checks that required different expansions:

* `if (ENV{foo})' will always evaluate to false even if $ENV{foo} is
  set, and may even be a CMake bug.
* `if (EXISTS ...)' expects an actual string, not an variable that has
  not been expanded.

It is not clear why the code expects QC_CERTSTORE_PATH to be an
environment variable instead of a regular variable passed to CMake in
the first place, but that can be changed in another commit.

REVIEW: 122062
2015-01-15 00:31:45 +02:00
Harald Sitter
b596e937b8 Revert "Revert "initialize QCA_SUFFIX cache with the possibly previously set SUFFIX""
This reverts commit c9f85b4dcab920d97a0959336ec71bc155209ccf.
2015-01-14 13:51:10 +01:00
Harald Sitter
b7f47694f8 Revert "Revert "properly support co-existing qt4 and qt5 versions""
This reverts commit 99128312fb91bc5f8e6320fe052bbaf7648102fe.
2015-01-14 13:51:07 +01:00
Ivan Romanov
99128312fb Revert "properly support co-existing qt4 and qt5 versions"
It's not properly. Martin Klapetek is not QCA developer. So it's not
correct that he said "Ship it!".

Properly way

cmake -DQCA_SUFFIX=qt5 ...

and in CMakeLists.txt of your project.

find_package(Qca NAMES Qca-qt5)

This reverts commit c32bc6f1bc9befe5f89d3572eb28e0d591a2e3b2.
2015-01-14 15:26:33 +05:00
Ivan Romanov
c9f85b4dca Revert "initialize QCA_SUFFIX cache with the possibly previously set SUFFIX"
I don't agree with this changes see https://git.reviewboard.kde.org/r/121168/
for details.

This reverts commit 3e3533b2753c8e47f0d22b77b564a0a6332cd5b8.
2015-01-14 15:24:11 +05:00
Harald Sitter
3e3533b275 initialize QCA_SUFFIX cache with the possibly previously set SUFFIX
this prevents us from unsetting what was previously set, making sure
the suffix is applied
2015-01-13 17:22:06 +01:00
Harald Sitter
c32bc6f1bc properly support co-existing qt4 and qt5 versions
- if QT4_BUILD is not defined *and* Qt5Core is found build with soname
  qca-qt5
- rename cmake package to reflect the suffix i.e. with a Qt5 build it is
  find_package(Qca-qt5) rather than find_package(Qca)
- the imported cmake target also reflects suffix so "Qca-qt5" is the
  cmake link target for qt5 and "Qca" for qt4 builds

this retains 100% compatibility with regular qca while also offering 100%
coinstallability of the qt5 build.

REVIEW: 121633
2014-12-28 14:26:50 +01:00
Harald Sitter
ffc53703ad put headers of a suffixed build in a suffixed directory
this makes the headers co-installable between a suffixed and regular
version

reviewed as part of r121323
2014-12-22 12:50:18 +01:00
Harald Sitter
4aae2dee34 prevent filewatches from emitting changes when there is no file
(this also fixes the flaky filewatch test that would fail for example on
 ubuntu launchpad builds)

it can happen that (supposedly for filesystem reasons) there are two
changes signals arriving in the watcher code, by the time the first arrives
the file would however already be deleted, by the time the second arrives
it would thus notify of changes to a file that does not exist which is
silly and causes problems with the filewatchtest as it uses signal emission
counting to verify the behavior.
to prevent this problem from popping up there is an additional save guard
in the file_changed slot that will ignore a change if the path in question
doesn't exist AND there is no file being watched by the watcher.

REVIEW: 121588
2014-12-19 16:47:40 +01:00
Harald Sitter
3b1bb19c7c add a reviewboardrc
REVIEW: 121325
2014-12-18 12:27:04 +01:00
Ivan Romanov
e57f8e7795 fixed array size checking
BUG: 341827
2014-12-13 01:54:53 +05:00
Harald Sitter
a67d31b1ec move QCA_CONFIG_NAME_BASE definition in the regular suffix if
(reviewed as part of r121323)
2014-12-02 13:32:09 +01:00
Harald Sitter
02be30908f fix library name in prf file to use the lib name variable
the lib name might be suffixed

(reviewed as part of r121323)
2014-12-02 13:29:52 +01:00
Ivan Romanov
9a9c16dfd1 cmake: fixed cmake config module when used QCA_SUFFIX 2014-11-29 00:57:31 +05:00
Ivan Romanov
98be0a1234 docs: fixed no images in docs when build out of source 2014-11-28 23:50:13 +05:00
Ivan Romanov
95223e9ee3 cmake: fixed warnings on android
do not use -Wcast-align on arm
2014-11-27 01:57:24 +05:00
Ivan Romanov
c8008de37b simplified md5_state_t and SHA1_CONTEXT internal structs
On arm is not correct to do int* = char* and throw warning. int must
be aligned unlike i686 and x86_64 archs. Anyway the old way to init
structs is not sane.
2014-11-27 01:55:47 +05:00
Ivan Romanov
20686e955c fixed compilation on android 2014-11-27 01:55:47 +05:00
Ivan Romanov
5d311c9219 cmake: build for android
Android uses .so as shared library suffix without version
2014-11-27 01:55:46 +05:00
Ivan Romanov
66447d0454 cmake: apply QCA_SUFFIX for cmake config module names 2014-11-22 06:30:07 +05:00
Ivan Romanov
2c58be171e cmake: warn user when QCA_SUFFIX is not set
Many linux distribution provides both version of Qt: Qt4 and Qt5.
These versions are binary is incompatible and any qt-based library
compiled against such Qt versions will be binary incompatible with
one another. In common case library name must not be related with
based libraries. In our case Linux users want to have both versions
QCA installed in their system. I will do not implicity rename Qt5
based QCA but just warn user and allow him explicity set QCA_SUFFIX.
2014-11-22 06:10:16 +05:00
Ivan Romanov
25860ff244 increased minimum cmake version
INCLUDE DESTINATION in install command was introduced only in CMake 2.8.12
2014-11-14 14:32:16 +05:00
Heiko Becker
593de6855a Fix build with libressl
libressl removed the SSL Compression functionality (which might
be considered insecure) and thus also compress_meth.
SSL_SESSION_get_compress_id is just a stub in libressl which always
returns 0 and in openssl it returns compress_meth.

REVIEW: 121107
2014-11-13 14:23:54 +05:00
Ivan Romanov
f8fe237c3c cmake: dropped dead variable 2014-11-13 02:13:50 +05:00
Ivan Romanov
72457bee3a qca-ossl: fixed compilation warnings 2014-11-13 02:13:50 +05:00
Ivan Romanov
8ffb52b439 cmake: pkg-config is not REQUIRED 2014-11-13 02:13:50 +05:00
Ivan Romanov
ca1667c118 dropped unused #include 2014-11-13 02:13:50 +05:00
283 changed files with 62307 additions and 62914 deletions

3
.arcconfig Normal file
View File

@ -0,0 +1,3 @@
{
"phabricator.uri" : "https://phabricator.kde.org/"
}

99
.clang-format Normal file
View File

@ -0,0 +1,99 @@
# SPDX-License-Identifier: MIT
#
# Copyright (C) 2019 Christoph Cullmann <cullmann@kde.org>
# Copyright (C) 2019 Gernot Gebhard <gebhard@absint.com>
#
# Permission is hereby granted, free of charge, to any person obtaining
# a copy of this software and associated documentation files (the
# "Software"), to deal in the Software without restriction, including
# without limitation the rights to use, copy, modify, merge, publish,
# distribute, sublicense, and/or sell copies of the Software, and to
# permit persons to whom the Software is furnished to do so, subject to
# the following conditions:
#
# The above copyright notice and this permission notice shall be included
# in all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
# IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
# CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
# TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
# SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
# Style for C++
Language: Cpp
# base is WebKit coding style: https://webkit.org/code-style-guidelines/
# below are only things set that diverge from this style!
BasedOnStyle: WebKit
# enforce C++11 (e.g. for std::vector<std::vector<lala>>
Standard: Cpp11
# 4 spaces indent
TabWidth: 4
# good enough for 2 panes
ColumnLimit: 120
# sort includes inside line separated groups
SortIncludes: true
# Mostly 'Linux' style but with different enums
BreakBeforeBraces: Custom
BraceWrapping:
AfterEnum: true
AfterStruct: true
AfterClass: true
AfterCaseLabel: true
AfterFunction: true
# CrlInstruction *a;
PointerAlignment: Right
# horizontally aligns arguments after an open bracket.
AlignAfterOpenBracket: Align
# align trailing comments
AlignTrailingComments: true
# don't move all parameters to new line
AllowAllParametersOfDeclarationOnNextLine: false
# no single line functions
AllowShortFunctionsOnASingleLine: None
# always break before you encounter multi line strings
AlwaysBreakBeforeMultilineStrings: true
# don't move arguments to own lines if they are not all on the same
BinPackArguments: false
# don't move parameters to own lines if they are not all on the same
BinPackParameters: false
# don't break binary ops
BreakBeforeBinaryOperators: None
# format C++11 braced lists like function calls
Cpp11BracedListStyle: true
# remove empty lines
KeepEmptyLinesAtTheStartOfBlocks: false
# no namespace indentation to keep indent level low
NamespaceIndentation: None
# we use template< without space.
SpaceAfterTemplateKeyword: false
# macros for which the opening brace stays attached.
ForEachMacros: [ foreach, Q_FOREACH, BOOST_FOREACH, forever, Q_FOREVER, QBENCHMARK, QBENCHMARK_ONCE ]
# put all '=' in one column for consecutive lines
AlignConsecutiveAssignments: true
# put all the variables/constants names on the same column
AlignConsecutiveDeclarations: true

2
.git-blame-ignore-revs Normal file
View File

@ -0,0 +1,2 @@
# _clang_format added
f62a8ee8f7e81a1b573c335ded3326d8ee985ab4

50
.gitlab-ci.yml Normal file
View File

@ -0,0 +1,50 @@
build_ubuntu_20_10:
stage: build
image: ubuntu:groovy
before_script:
- sed -i -e 's/# deb-src/deb-src/g' /etc/apt/sources.list
- apt update
- apt install --yes eatmydata
- eatmydata apt build-dep --yes --no-install-recommends qca2
- eatmydata apt install --yes --no-install-recommends ninja-build libbotan-2-dev libnss3-dev libgcrypt20-dev libpkcs11-helper1-dev gnupg
script:
- mkdir -p build && cd build
- cmake -G Ninja ..
- ninja
- QT_PLUGIN_PATH=`pwd`/lib/qca-qt5/ ctest -V
build_fedora_34:
stage: build
image: fedora:34
before_script:
- dnf -y --setopt=install_weak_deps=False install git gcc-c++ make cmake ninja-build qt6-qtbase-devel qt6-qt5compat-devel botan2-devel cyrus-sasl-devel nss-devel libgcrypt-devel pkcs11-helper-devel gnupg
script:
- mkdir -p build && cd build
- cmake -G Ninja -DQT6=ON ..
- ninja
- QT_PLUGIN_PATH=`pwd`/lib/qca-qt6/ ctest -V
build_clazy_clang_tidy:
stage: build
image: debian:unstable
before_script:
- echo 'deb-src http://deb.debian.org/debian unstable main' >> /etc/apt/sources.list
- apt-get update
- apt-get install --yes eatmydata
- eatmydata apt-get build-dep --yes --no-install-recommends qca2
- eatmydata apt-get install --yes --no-install-recommends ninja-build libbotan-2-dev libnss3-dev libgcrypt20-dev libpkcs11-helper1-dev clazy clang clang-tidy jq gnupg
script:
- srcdir=`pwd` && mkdir -p /tmp/qca_build && cd /tmp/qca_build && CC=clang CXX=clazy CXXFLAGS="-Werror -Wno-deprecated-declarations" cmake -DCMAKE_EXPORT_COMPILE_COMMANDS=ON -G Ninja $srcdir && cat compile_commands.json | jq '[.[] | select(.file | contains("'"$srcdir"'"))]' > compile_commands.aux.json && mv compile_commands.aux.json compile_commands.json
- CLAZY_CHECKS="level0,level1,level2,no-copyable-polymorphic,no-ctor-missing-parent-argument,isempty-vs-count,qhash-with-char-pointer-key,qproperty-type-mismatch,qrequiredresult-candidates,signal-with-return-value,thread-with-slots,tr-non-literal,unneeded-cast" ninja
- "run-clang-tidy -header-filter='.*/qca/.*' -checks='-*,performance-*,modernize-deprecated-headers,modernize-make-unique,modernize-make-shared,modernize-use-override,modernize-use-equals-delete,modernize-use-emplace,modernize-use-bool-literals,modernize-redundant-void-arg,modernize-loop-convert,modernize-use-nullptr,-performance-no-automatic-move' -config=\"{WarningsAsErrors: '*'}\""
- QT_PLUGIN_PATH=`pwd`/lib/qca-qt5/ ctest -V
clang_format:
stage: build
image: debian:testing
before_script:
- apt-get update
- apt-get install --yes --no-install-recommends git clang-format-11
script:
- find . \( -name "*.cpp" -or -name "*.h" -or -name "*.c" -or -name "*.cc" \) -exec clang-format-11 -i {} \;
- git diff --exit-code

4
.reviewboardrc Normal file
View File

@ -0,0 +1,4 @@
REPOSITORY = "git://anongit.kde.org/qca"
REVIEWBOARD_URL = "https://git.reviewboard.kde.org"
TARGET_PEOPLE = "iromanov"
BRANCH = "master"

View File

@ -1,27 +1,29 @@
# Checking for user explicity defined CMAKE_INSTALL_PREFIX # Checking for user explicitly defined CMAKE_INSTALL_PREFIX
# It must be done before project(...) # It must be done before project(...)
if(NOT CMAKE_INSTALL_PREFIX) if(NOT CMAKE_INSTALL_PREFIX)
set(QCA_INSTALL_IN_QT_PREFIX ON) set(QCA_INSTALL_IN_QT_PREFIX ON)
# If CMAKE_INSTALL_PREFIX is set in cmake arguments # If CMAKE_INSTALL_PREFIX is set in cmake arguments
unset(CMAKE_INSTALL_PREFIX CACHE) unset(CMAKE_INSTALL_PREFIX CACHE)
endif(NOT CMAKE_INSTALL_PREFIX) endif()
# The cmake min. version should be set before calling project(...) too
cmake_minimum_required(VERSION 3.4)
project(qca) project(qca)
cmake_minimum_required(VERSION 2.6.0)
set(QCA_LIB_MAJOR_VERSION "2") set(QCA_LIB_MAJOR_VERSION "2")
set(QCA_LIB_MINOR_VERSION "1") set(QCA_LIB_MINOR_VERSION "3")
set(QCA_LIB_PATCH_VERSION "0") set(QCA_LIB_PATCH_VERSION "3")
# Do not automatically link Qt executables to qtmain target on Windows. #if(POLICY CMP0042)
# QCA exucatables use console mode only. Not need to link against # cmake_policy(SET CMP0042 OLD)
# qtmain.lib. #endif()
cmake_policy(SET CMP0020 OLD)
option(QT6 "Build with Qt 6" OFF)
option(BUILD_TESTS "Create test" ON) option(BUILD_TESTS "Create test" ON)
option(BUILD_TOOLS "Compile mozcerts and qcatool" ON) option(BUILD_TOOLS "Compile mozcerts and qcatool" ON)
set(BUILD_PLUGINS "auto" CACHE STRING "Plugins for building (also possible values: none, all and auto)") set(BUILD_PLUGINS "auto" CACHE STRING "Plugins for building (also possible values: none, all and auto)")
# BUILD_SHARED_LIBS is cmake variable. Need to change default value.
option(BUILD_SHARED_LIBS "Build shared library" ON) option(BUILD_SHARED_LIBS "Build shared library" ON)
option(DEVELOPER_MODE "Special developer mode" OFF) option(DEVELOPER_MODE "Special developer mode" OFF)
@ -36,43 +38,32 @@ find_package(Doxygen)
string(TOLOWER "${BUILD_PLUGINS}" BUILD_PLUGINS) string(TOLOWER "${BUILD_PLUGINS}" BUILD_PLUGINS)
if(NOT BUILD_PLUGINS) if(NOT BUILD_PLUGINS)
set(BUILD_PLUGINS "none") set(BUILD_PLUGINS "none")
endif(NOT BUILD_PLUGINS) endif()
set(CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake/modules" ) set(CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake/modules" )
option(QT4_BUILD "Force building with Qt4 even if Qt5 is found") # Do not automatically link Qt executables to qtmain target on Windows.
if (NOT QT4_BUILD) # QCA exucatables use console mode only. Not need to link against qtmain.lib.
find_package(Qt5Core QUIET) if(QT6)
mark_as_advanced(Qt5Core_DIR) message(STATUS "Building Qt 6 version")
find_package(Qt6 COMPONENTS Core Test Core5Compat REQUIRED)
else()
message(STATUS "Building Qt 5 version")
set(Qt5_NO_LINK_QTMAIN ON)
find_package(Qt5 5.14 REQUIRED Core)
endif() endif()
set(CMAKE_AUTOMOC ON)
include(QcaMacro) include(QcaMacro)
if (Qt5Core_FOUND)
message(STATUS "Building with Qt5 support")
# Got from ECM
# Distros have no ECM. So I just copied required cmake modules.
find_package(Qt5Transitional REQUIRED Core Network)
include(ECMQt4To5Porting)
include(GNUInstallDirs) include(GNUInstallDirs)
setup_qt5_dirs() setup_qt_dirs()
set(QCA_QT_PC_VERSION "Qt5Core") if(QT6)
set(QCA_QT_PC_VERSION "Qt6Core")
set(QCA_SUFFIX "qt6")
else() else()
set(QT_MIN_VERSION "4.7.0") set(QCA_QT_PC_VERSION "Qt5Core")
set(QT_USE_IMPORTED_TARGETS ON) set(QCA_SUFFIX "qt5")
if(BUILD_TESTS)
find_package(Qt4 REQUIRED QtCore QtNetwork QtTest)
else(BUILD_TESTS)
find_package(Qt4 REQUIRED QtCore)
endif(BUILD_TESTS)
# WORKAROUND: Seems it must be done in Qt4 find module but didn't
mark_as_advanced(QT_QMAKE_EXECUTABLE)
# properly set up compile flags (QT_DEBUG/QT_NO_DEBUG, ...)
include(${QT_USE_FILE})
setup_qt4_dirs()
set(QCA_QT_PC_VERSION "QtCore")
endif() endif()
# QCA can be shared but plugins will be static # QCA can be shared but plugins will be static
@ -81,22 +72,24 @@ if(NOT BUILD_SHARED_LIBS OR QT_IS_STATIC)
set(STATIC_PLUGINS ON) set(STATIC_PLUGINS ON)
add_definitions(-DQT_STATICPLUGIN) add_definitions(-DQT_STATICPLUGIN)
set(PLUGIN_TYPE "STATIC") set(PLUGIN_TYPE "STATIC")
else(NOT BUILD_SHARED_LIBS OR QT_IS_STATIC) else()
set(PLUGIN_TYPE "MODULE") set(PLUGIN_TYPE "MODULE")
endif(NOT BUILD_SHARED_LIBS OR QT_IS_STATIC) endif()
set(QCA_SUFFIX "" CACHE STRING "QCA common suffix") set(QCA_SUFFIX "${QCA_SUFFIX}" CACHE STRING "QCA common suffix")
if(QCA_SUFFIX) if(QCA_SUFFIX)
set(QCA_LIB_NAME qca-${QCA_SUFFIX}) set(QCA_LIB_NAME qca-${QCA_SUFFIX})
set(QCA_TOOL_NAME qcatool-${QCA_SUFFIX}) set(QCA_TOOL_NAME qcatool-${QCA_SUFFIX})
set(MOZCERTS_NAME mozcerts-${QCA_SUFFIX}) set(MOZCERTS_NAME mozcerts-${QCA_SUFFIX})
set(QCA_PC_NAME qca2-${QCA_SUFFIX}.pc) set(QCA_PC_NAME qca2-${QCA_SUFFIX}.pc)
else(QCA_SUFFIX) set(QCA_CONFIG_NAME_BASE "Qca-${QCA_SUFFIX}")
else()
set(QCA_LIB_NAME qca) set(QCA_LIB_NAME qca)
set(QCA_TOOL_NAME qcatool) set(QCA_TOOL_NAME qcatool)
set(MOZCERTS_NAME mozcerts) set(MOZCERTS_NAME mozcerts)
set(QCA_PC_NAME qca2.pc) set(QCA_PC_NAME qca2.pc)
endif(QCA_SUFFIX) set(QCA_CONFIG_NAME_BASE "Qca")
endif()
set(QCA_LIB_VERSION_STRING "${QCA_LIB_MAJOR_VERSION}.${QCA_LIB_MINOR_VERSION}.${QCA_LIB_PATCH_VERSION}") set(QCA_LIB_VERSION_STRING "${QCA_LIB_MAJOR_VERSION}.${QCA_LIB_MINOR_VERSION}.${QCA_LIB_PATCH_VERSION}")
@ -107,17 +100,42 @@ if (WIN32)
add_definitions(-DWIN32_LEAN_AND_MEAN) add_definitions(-DWIN32_LEAN_AND_MEAN)
elseif (APPLE) elseif (APPLE)
set(CMAKE_DEBUG_POSTFIX "_debug") set(CMAKE_DEBUG_POSTFIX "_debug")
endif (WIN32) endif()
if (CMAKE_COMPILER_IS_GNUCXX) if (CMAKE_CXX_COMPILER_ID MATCHES "GNU" OR CMAKE_CXX_COMPILER_ID MATCHES "Clang")
if (CMAKE_SYSTEM_NAME MATCHES Linux) if (CMAKE_SYSTEM_NAME MATCHES Linux)
add_definitions (-D_BSD_SOURCE) add_definitions (-D_DEFAULT_SOURCE)
set ( CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wno-long-long -ansi -Wundef -Wcast-align -Werror-implicit-function-declaration -Wchar-subscripts -Wall -W -Wpointer-arith -Wwrite-strings -Wformat-security -Wmissing-format-attribute -fno-common") # on arm -Wcast-align throws many internal qt warning
set ( CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wnon-virtual-dtor -Wno-long-long -ansi -Wundef -Wcast-align -Wchar-subscripts -Wall -W -Wpointer-arith -Wwrite-strings -Wformat-security -fno-check-new -fno-common") if(NOT CMAKE_SYSTEM_PROCESSOR MATCHES "^arm")
endif (CMAKE_SYSTEM_NAME MATCHES Linux) set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wcast-align")
endif (CMAKE_COMPILER_IS_GNUCXX) set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wcast-align")
endif()
set ( CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wno-long-long -Wundef -Werror-implicit-function-declaration -Wchar-subscripts -Wall -W -Wpointer-arith -Wwrite-strings -Wformat-security -Wmissing-format-attribute -fno-common")
set ( CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wnon-virtual-dtor -Wno-long-long -Wundef -Wchar-subscripts -Wall -W -Wpointer-arith -Wwrite-strings -Wformat-security -fno-check-new -fno-common")
if (CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wsuggest-override -Wlogical-op" )
endif()
endif()
endif()
add_definitions(-DQT_NO_CAST_TO_ASCII
-DQT_NO_CAST_FROM_ASCII
-DQT_NO_URL_CAST_FROM_STRING
-DQT_NO_CAST_FROM_BYTEARRAY
-DQT_NO_SIGNALS_SLOTS_KEYWORDS
-DQT_USE_QSTRINGBUILDER
-DQT_NO_NARROWING_CONVERSIONS_IN_CONNECT)
if (NOT WIN32)
# Strict iterators can't be used on Windows, they lead to a link error
# when application code iterates over a QVector<QPoint> for instance, unless
# Qt itself was also built with strict iterators.
# See example at https://bugreports.qt.io/browse/AUTOSUITE-946
add_definitions(-DQT_STRICT_ITERATORS)
endif()
add_definitions (${QT_DEFINITIONS})
include_directories("include/QtCrypto/") include_directories("include/QtCrypto/")
# for generated files # for generated files
include_directories(${CMAKE_BINARY_DIR}) include_directories(${CMAKE_BINARY_DIR})
@ -155,11 +173,16 @@ if( QCA_INSTALL_IN_QT_PREFIX )
set(QCA_BINARY_INSTALL_DIR "${QT_BINARY_DIR}" CACHE PATH "Directory where qca plugins will install") set(QCA_BINARY_INSTALL_DIR "${QT_BINARY_DIR}" CACHE PATH "Directory where qca plugins will install")
set(QCA_LIBRARY_INSTALL_DIR "${QT_LIBRARY_DIR}" CACHE PATH "Directory where qca library will install") set(QCA_LIBRARY_INSTALL_DIR "${QT_LIBRARY_DIR}" CACHE PATH "Directory where qca library will install")
set(QCA_FEATURE_INSTALL_DIR "${QT_MKSPECS_DIR}/features" CACHE PATH "Directory where qca feature file will install") set(QCA_FEATURE_INSTALL_DIR "${QT_MKSPECS_DIR}/features" CACHE PATH "Directory where qca feature file will install")
if(NOT QCA_SUFFIX)
set(QCA_INCLUDE_INSTALL_DIR "${QT_HEADERS_DIR}" CACHE PATH "Directory where qca public headers will install") set(QCA_INCLUDE_INSTALL_DIR "${QT_HEADERS_DIR}" CACHE PATH "Directory where qca public headers will install")
set(QCA_PRIVATE_INCLUDE_INSTALL_DIR "${QT_HEADERS_DIR}" CACHE PATH "Directory where qca headers will install") set(QCA_PRIVATE_INCLUDE_INSTALL_DIR "${QT_HEADERS_DIR}" CACHE PATH "Directory where qca headers will install")
else()
set(QCA_INCLUDE_INSTALL_DIR "${QT_HEADERS_DIR}/${QCA_CONFIG_NAME_BASE}" CACHE PATH "Directory where qca public headers will install")
set(QCA_PRIVATE_INCLUDE_INSTALL_DIR "${QT_HEADERS_DIR}/${QCA_CONFIG_NAME_BASE}" CACHE PATH "Directory where qca headers will install")
endif()
set(QCA_DOC_INSTALL_DIR "${QT_DOC_DIR}/html/qca/" CACHE PATH "Directory where qca documentation will install") set(QCA_DOC_INSTALL_DIR "${QT_DOC_DIR}/html/qca/" CACHE PATH "Directory where qca documentation will install")
set(QCA_MAN_INSTALL_DIR "${QT_DATA_DIR}/man" CACHE PATH "Directory where qca man pages will install") set(QCA_MAN_INSTALL_DIR "${QT_DATA_DIR}/man" CACHE PATH "Directory where qca man pages will install")
else( QCA_INSTALL_IN_QT_PREFIX ) else()
# Cmake says nothing about LIB_SUFFIX # Cmake says nothing about LIB_SUFFIX
# de facto it is a standard way to specify lib suffix on many distros # de facto it is a standard way to specify lib suffix on many distros
set(LIB_SUFFIX "" CACHE STRING "Define suffix of directory name (32/64)" ) set(LIB_SUFFIX "" CACHE STRING "Define suffix of directory name (32/64)" )
@ -170,16 +193,27 @@ else( QCA_INSTALL_IN_QT_PREFIX )
set(QCA_BINARY_INSTALL_DIR "${CMAKE_INSTALL_PREFIX}/bin" CACHE PATH "Directory where qca plugins will install") set(QCA_BINARY_INSTALL_DIR "${CMAKE_INSTALL_PREFIX}/bin" CACHE PATH "Directory where qca plugins will install")
set(QCA_LIBRARY_INSTALL_DIR "${LIB_INSTALL_DIR}" CACHE PATH "Directory where qca library will install") set(QCA_LIBRARY_INSTALL_DIR "${LIB_INSTALL_DIR}" CACHE PATH "Directory where qca library will install")
set(QCA_FEATURE_INSTALL_DIR "${CMAKE_INSTALL_PREFIX}/mkspecs/features" CACHE PATH "Directory where qca feature file will install") set(QCA_FEATURE_INSTALL_DIR "${CMAKE_INSTALL_PREFIX}/mkspecs/features" CACHE PATH "Directory where qca feature file will install")
if(NOT QCA_SUFFIX)
set(QCA_INCLUDE_INSTALL_DIR "${CMAKE_INSTALL_PREFIX}/include" CACHE PATH "Directory where qca public headers will install") set(QCA_INCLUDE_INSTALL_DIR "${CMAKE_INSTALL_PREFIX}/include" CACHE PATH "Directory where qca public headers will install")
set(QCA_PRIVATE_INCLUDE_INSTALL_DIR "${CMAKE_INSTALL_PREFIX}/include" CACHE PATH "Directory where qca headers will install") set(QCA_PRIVATE_INCLUDE_INSTALL_DIR "${CMAKE_INSTALL_PREFIX}/include" CACHE PATH "Directory where qca headers will install")
else()
set(QCA_INCLUDE_INSTALL_DIR "${CMAKE_INSTALL_PREFIX}/include/${QCA_CONFIG_NAME_BASE}" CACHE PATH "Directory where qca public headers will install")
set(QCA_PRIVATE_INCLUDE_INSTALL_DIR "${CMAKE_INSTALL_PREFIX}/include/${QCA_CONFIG_NAME_BASE}" CACHE PATH "Directory where qca headers will install")
endif()
set(QCA_DOC_INSTALL_DIR "${CMAKE_INSTALL_PREFIX}/share/doc/${QCA_LIB_NAME}/html" CACHE PATH "Directory where qca documentation will install") set(QCA_DOC_INSTALL_DIR "${CMAKE_INSTALL_PREFIX}/share/doc/${QCA_LIB_NAME}/html" CACHE PATH "Directory where qca documentation will install")
set(QCA_MAN_INSTALL_DIR "${CMAKE_INSTALL_PREFIX}/share/man" CACHE PATH "Directory where qca man pages will install") set(QCA_MAN_INSTALL_DIR "${CMAKE_INSTALL_PREFIX}/share/man" CACHE PATH "Directory where qca man pages will install")
endif( QCA_INSTALL_IN_QT_PREFIX ) endif()
set(PKGCONFIG_INSTALL_PREFIX "${QCA_LIBRARY_INSTALL_DIR}/pkgconfig" CACHE PATH "Base directory for pkgconfig files") set(PKGCONFIG_INSTALL_PREFIX "${QCA_LIBRARY_INSTALL_DIR}/pkgconfig" CACHE PATH "Base directory for pkgconfig files")
normalize_path(QCA_PREFIX_INSTALL_DIR) normalize_path(QCA_PREFIX_INSTALL_DIR)
if(OSX_FRAMEWORK)
set(QCA_FULL_INCLUDE_INSTALL_DIR "${QCA_LIBRARY_INSTALL_DIR}/${QCA_LIB_NAME}.framework/Headers")
else()
set(QCA_FULL_INCLUDE_INSTALL_DIR "${QCA_INCLUDE_INSTALL_DIR}/QtCrypto")
endif()
# check for oportunity to use relative paths # check for oportunity to use relative paths
option(USE_RELATIVE_PATHS "Try to make relocatable package") option(USE_RELATIVE_PATHS "Try to make relocatable package")
@ -205,19 +239,21 @@ endforeach()
if(NOT WIN32) if(NOT WIN32)
if(OSX_FRAMEWORK) if(OSX_FRAMEWORK)
set(PKGCONFIG_CFLAGS "-F\${libdir} -I\${libdir}/${QCA_LIB_NAME}.framework/Headers") set(PKGCONFIG_CFLAGS "-F\${libdir} -I\${includedir}")
set(PKGCONFIG_LIBS "-F\${libdir} -framework ${QCA_LIB_NAME}") set(PKGCONFIG_LIBS "-F\${libdir} -framework ${QCA_LIB_NAME}")
else() else()
set(PKGCONFIG_CFLAGS "-I\${includedir}") set(PKGCONFIG_CFLAGS "-I\${includedir}")
set(PKGCONFIG_LIBS "-L\${libdir} -l${QCA_LIB_NAME}") set(PKGCONFIG_LIBS "-L\${libdir} -l${QCA_LIB_NAME}")
endif() endif()
if(NOT QT6)
# qca2.pc uses absolute paths. So it must be there. Don't rellocate this. # qca2.pc uses absolute paths. So it must be there. Don't rellocate this.
configure_file("qca2.pc.cmake" "${CMAKE_LIBRARY_OUTPUT_DIRECTORY}/pkgconfig/${QCA_PC_NAME}" @ONLY) configure_file("qca2.pc.cmake" "${CMAKE_LIBRARY_OUTPUT_DIRECTORY}/pkgconfig/${QCA_PC_NAME}" @ONLY)
if(NOT DEVELOPER_MODE) if(NOT DEVELOPER_MODE)
install(FILES "${CMAKE_LIBRARY_OUTPUT_DIRECTORY}/pkgconfig/${QCA_PC_NAME}" DESTINATION ${PKGCONFIG_INSTALL_PREFIX}) install(FILES "${CMAKE_LIBRARY_OUTPUT_DIRECTORY}/pkgconfig/${QCA_PC_NAME}" DESTINATION ${PKGCONFIG_INSTALL_PREFIX})
endif() endif()
endif(NOT WIN32) endif()
endif()
# strip CMAKE_INSTALL_PREFIX in all paths # strip CMAKE_INSTALL_PREFIX in all paths
if(USE_RELATIVE_PATHS) if(USE_RELATIVE_PATHS)
@ -252,23 +288,19 @@ Plugins=${CMAKE_BINARY_DIR}/lib/${QCA_LIB_NAME}
endif() endif()
if (APPLE) if (APPLE)
find_package(Carbon REQUIRED)
set(CMAKE_INSTALL_NAME_DIR ${QCA_LIBRARY_INSTALL_DIR})
set(CMAKE_BUILD_WITH_INSTALL_RPATH TRUE) set(CMAKE_BUILD_WITH_INSTALL_RPATH TRUE)
endif (APPLE) endif()
message(STATUS "Checking for certstore..") message(STATUS "Checking for certstore..")
# fixme add OR mac # fixme add OR mac
if( WIN32 ) if( WIN32 )
# USE BUILTIN # USE BUILTIN
else ( WIN32 ) else()
if ( ENV{QC_CERTSTORE_PATH} ) if ( DEFINED ENV{QC_CERTSTORE_PATH} )
if(EXISTS ENV{QC_CERTSTORE_PATH}) if(EXISTS $ENV{QC_CERTSTORE_PATH})
set( qca_CERTSTORE $ENV{QC_CERTSTORE_PATH}) set( qca_CERTSTORE $ENV{QC_CERTSTORE_PATH})
else(EXISTS ENV{QC_CERTSTORE_PATH}) endif()
# path to try else()
endif(EXISTS ENV{QC_CERTSTORE_PATH})
else( ENV{QC_CERTSTORE_PATH} )
set( toTry set( toTry
"/etc/ssl/certs/ca-certificates.crt" "/etc/ssl/certs/ca-certificates.crt"
"/usr/share/ssl/cert.pem" "/usr/share/ssl/cert.pem"
@ -280,21 +312,21 @@ else ( WIN32 )
foreach (_current_try ${toTry}) foreach (_current_try ${toTry})
if(EXISTS ${_current_try}) if(EXISTS ${_current_try})
set( qca_CERTSTORE ${_current_try}) set( qca_CERTSTORE ${_current_try})
endif(EXISTS ${_current_try}) endif()
endforeach (_current_try) endforeach (_current_try)
endif( ENV{QC_CERTSTORE_PATH} ) endif()
endif(WIN32) endif()
if (qca_CERTSTORE) if (qca_CERTSTORE)
message(STATUS "Found system certstore") message(STATUS "Found system certstore")
else (qca_CERTSTORE) else()
message(STATUS "Using built in certstore.") message(STATUS "Using built in certstore.")
set( qca_CERTSTORE "${CMAKE_CURRENT_SOURCE_DIR}/certs/rootcerts.pem") set( qca_CERTSTORE "${CMAKE_CURRENT_SOURCE_DIR}/certs/rootcerts.pem")
# note that INSTALL_FILES targets are relative to the current installation prefix... # note that INSTALL_FILES targets are relative to the current installation prefix...
if(NOT DEVELOPER_MODE) if(NOT DEVELOPER_MODE)
install(FILES "${qca_CERTSTORE}" DESTINATION "${QCA_PREFIX_INSTALL_DIR}/certs") install(FILES "${qca_CERTSTORE}" DESTINATION "${QCA_PREFIX_INSTALL_DIR}/certs")
endif() endif()
endif (qca_CERTSTORE) endif()
message(STATUS "certstore path: " ${qca_CERTSTORE}) message(STATUS "certstore path: " ${qca_CERTSTORE})
add_definitions( -DQCA_SYSTEMSTORE_PATH="${qca_CERTSTORE}" ) add_definitions( -DQCA_SYSTEMSTORE_PATH="${qca_CERTSTORE}" )
@ -322,12 +354,14 @@ set( public_HEADERS
set( qca_HEADERS ${private_HEADERS} ${public_HEADERS} ) set( qca_HEADERS ${private_HEADERS} ${public_HEADERS} )
include_directories(${QT_QTCORE_INCLUDE_DIR} "${qca_INCLUDEDIR}/QtCrypto") include_directories("${qca_INCLUDEDIR}/QtCrypto")
if(NOT QT6)
configure_file("crypto.prf.cmake" "${CMAKE_BINARY_DIR}/mkspecs/features/crypto.prf" @ONLY) configure_file("crypto.prf.cmake" "${CMAKE_BINARY_DIR}/mkspecs/features/crypto.prf" @ONLY)
if(NOT DEVELOPER_MODE) if(NOT DEVELOPER_MODE)
install(FILES "${CMAKE_BINARY_DIR}/mkspecs/features/crypto.prf" DESTINATION "${QCA_FEATURE_INSTALL_DIR}") install(FILES "${CMAKE_BINARY_DIR}/mkspecs/features/crypto.prf" DESTINATION "${QCA_FEATURE_INSTALL_DIR}")
endif() endif()
endif()
configure_file(man/qcatool.1 "${CMAKE_BINARY_DIR}/share/man/man1/${QCA_TOOL_NAME}.1" COPYONLY) configure_file(man/qcatool.1 "${CMAKE_BINARY_DIR}/share/man/man1/${QCA_TOOL_NAME}.1" COPYONLY)
if(NOT DEVELOPER_MODE) if(NOT DEVELOPER_MODE)
@ -346,37 +380,37 @@ if(STATIC_PLUGINS)
if(WITH_${PLUGIN}_PLUGIN_INTERNAL) if(WITH_${PLUGIN}_PLUGIN_INTERNAL)
string(REPLACE "-" "_" IMPORT_NAME "qca-${PLUGIN}") string(REPLACE "-" "_" IMPORT_NAME "qca-${PLUGIN}")
file(APPEND "${CMAKE_BINARY_DIR}/import_plugins.h" "Q_IMPORT_PLUGIN(${IMPORT_NAME})\n") file(APPEND "${CMAKE_BINARY_DIR}/import_plugins.h" "Q_IMPORT_PLUGIN(${IMPORT_NAME})\n")
endif(WITH_${PLUGIN}_PLUGIN_INTERNAL) endif()
endforeach(PLUGIN IN LISTS PLUGINS) endforeach(PLUGIN IN LISTS PLUGINS)
endif(STATIC_PLUGINS) endif()
if(BUILD_TESTS) if(BUILD_TESTS)
enable_testing() enable_testing()
add_subdirectory(unittest) add_subdirectory(unittest)
add_subdirectory(examples) add_subdirectory(examples)
endif(BUILD_TESTS) endif()
if(BUILD_TOOLS) if(BUILD_TOOLS)
add_subdirectory(tools) add_subdirectory(tools)
endif(BUILD_TOOLS) endif()
if(DOXYGEN_FOUND) #if(DOXYGEN_FOUND)
configure_file(${CMAKE_SOURCE_DIR}/Doxyfile.in ${CMAKE_BINARY_DIR}/Doxyfile @ONLY) # configure_file(${CMAKE_SOURCE_DIR}/Doxyfile.in ${CMAKE_BINARY_DIR}/Doxyfile @ONLY)
add_custom_target(doc # add_custom_target(doc
${DOXYGEN_EXECUTABLE} ${CMAKE_BINARY_DIR}/Doxyfile # ${DOXYGEN_EXECUTABLE} ${CMAKE_BINARY_DIR}/Doxyfile
COMMAND ${CMAKE_COMMAND} -E make_directory ${CMAKE_BINARY_DIR}/images # COMMAND ${CMAKE_COMMAND} -E make_directory ${CMAKE_BINARY_DIR}/docs/pics
COMMAND ${CMAKE_COMMAND} -E copy_if_different ${CMAKE_SOURCE_DIR}/images/qca-arch.eps ${CMAKE_BINARY_DIR}/images/qca-arch.eps # COMMAND ${CMAKE_COMMAND} -E copy_if_different ${CMAKE_SOURCE_DIR}/docs/pics/qca-arch.eps ${CMAKE_BINARY_DIR}/docs/pics/qca-arch.eps
COMMAND ${CMAKE_COMMAND} -E copy_if_different ${CMAKE_SOURCE_DIR}/images/qca-arch.png ${CMAKE_BINARY_DIR}/images/qca-arch.png # COMMAND ${CMAKE_COMMAND} -E copy_if_different ${CMAKE_SOURCE_DIR}/docs/pics/qca-arch.png ${CMAKE_BINARY_DIR}/docs/pics/qca-arch.png
WORKING_DIRECTORY ${CMAKE_BINARY_DIR} # WORKING_DIRECTORY ${CMAKE_BINARY_DIR}
COMMENT "Generating API documentation with Doxygen" VERBATIM) # COMMENT "Generating API documentation with Doxygen" VERBATIM)
endif(DOXYGEN_FOUND) #endif()
include(CMakePackageConfigHelpers) include(CMakePackageConfigHelpers)
configure_package_config_file( configure_package_config_file(
"${CMAKE_CURRENT_SOURCE_DIR}/QcaConfig.cmake.in" "${CMAKE_CURRENT_SOURCE_DIR}/QcaConfig.cmake.in"
"${CMAKE_CURRENT_BINARY_DIR}/lib/cmake/Qca/QcaConfig.cmake" "${CMAKE_CURRENT_BINARY_DIR}/lib/cmake/${QCA_CONFIG_NAME_BASE}/${QCA_CONFIG_NAME_BASE}Config.cmake"
INSTALL_DESTINATION ${QCA_LIBRARY_INSTALL_DIR}/cmake/Qca INSTALL_DESTINATION ${QCA_LIBRARY_INSTALL_DIR}/cmake/${QCA_CONFIG_NAME_BASE}
) )
write_basic_config_version_file("${CMAKE_CURRENT_BINARY_DIR}/lib/cmake/Qca/QcaConfigVersion.cmake" VERSION ${QCA_LIB_VERSION_STRING} COMPATIBILITY AnyNewerVersion) write_basic_config_version_file("${CMAKE_CURRENT_BINARY_DIR}/lib/cmake/${QCA_CONFIG_NAME_BASE}/${QCA_CONFIG_NAME_BASE}ConfigVersion.cmake" VERSION ${QCA_LIB_VERSION_STRING} COMPATIBILITY AnyNewerVersion)
if(NOT DEVELOPER_MODE) if(NOT DEVELOPER_MODE)
@ -398,7 +432,7 @@ if(NOT DEVELOPER_MODE)
message("!! you MUST explicity define CMAKE_INSTALL_PREFIX !!") message("!! you MUST explicity define CMAKE_INSTALL_PREFIX !!")
message("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!") message("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!")
message("${ESCAPE}[0m") message("${ESCAPE}[0m")
endif(QCA_INSTALL_IN_QT_PREFIX) endif()
message("") message("")
if(USE_RELATIVE_PATHS) if(USE_RELATIVE_PATHS)
@ -434,10 +468,25 @@ if(NOT DEVELOPER_MODE)
endif() endif()
message("") message("")
install(EXPORT QCATargets DESTINATION ${QCA_LIBRARY_INSTALL_DIR}/cmake/Qca FILE QcaTargets.cmake) if(UNIX AND NOT APPLE)
if(NOT QCA_SUFFIX)
message("${ESCAPE}[31mYou don't have QCA_SUFFIX set. Please note that the recommended way of")
if(QT6)
message("building Qt6 version of qca for Linux distributions is to set")
message("QCA_SUFFIX to qt6 (-DQCA_SUFFIX=qt6).")
else()
message("building Qt5 version of qca for Linux distributions is to set")
message("QCA_SUFFIX to qt5 (-DQCA_SUFFIX=qt5).")
endif()
message("${ESCAPE}[0m")
endif()
endif()
install(EXPORT ${QCA_CONFIG_NAME_BASE}Targets DESTINATION ${QCA_LIBRARY_INSTALL_DIR}/cmake/${QCA_CONFIG_NAME_BASE} FILE ${QCA_CONFIG_NAME_BASE}Targets.cmake)
install(FILES install(FILES
"${CMAKE_CURRENT_BINARY_DIR}/lib/cmake/Qca/QcaConfig.cmake" "${CMAKE_CURRENT_BINARY_DIR}/lib/cmake/${QCA_CONFIG_NAME_BASE}/${QCA_CONFIG_NAME_BASE}Config.cmake"
"${CMAKE_CURRENT_BINARY_DIR}/lib/cmake/Qca/QcaConfigVersion.cmake" "${CMAKE_CURRENT_BINARY_DIR}/lib/cmake/${QCA_CONFIG_NAME_BASE}/${QCA_CONFIG_NAME_BASE}ConfigVersion.cmake"
DESTINATION ${QCA_LIBRARY_INSTALL_DIR}/cmake/Qca DESTINATION ${QCA_LIBRARY_INSTALL_DIR}/cmake/${QCA_CONFIG_NAME_BASE}
) )
endif() endif()

View File

@ -567,7 +567,7 @@ EXAMPLE_RECURSIVE = NO
# directories that contain image that are included in the documentation (see # directories that contain image that are included in the documentation (see
# the \image command). # the \image command).
IMAGE_PATH = images IMAGE_PATH = @CMAKE_SOURCE_DIR@/docs/pics
# The INPUT_FILTER tag can be used to specify a program that doxygen should # The INPUT_FILTER tag can be used to specify a program that doxygen should
# invoke to filter for each input file. Doxygen will invoke the filter program # invoke to filter for each input file. Doxygen will invoke the filter program
@ -1070,7 +1070,7 @@ PREDEFINED = DOXYGEN_SHOULD_SKIP_THIS \
# The macro definition that is found in the sources will be used. # The macro definition that is found in the sources will be used.
# Use the PREDEFINED tag if you want to use a different macro definition. # Use the PREDEFINED tag if you want to use a different macro definition.
EXPAND_AS_DEFINED = QCA_EXPORT EXPAND_AS_DEFINED = QCA_EXPORT QCA_NOEXCEPT
# If the SKIP_FUNCTION_MACROS tag is set to YES (the default) then # If the SKIP_FUNCTION_MACROS tag is set to YES (the default) then
# doxygen's preprocessor will remove all function-like macros that are alone # doxygen's preprocessor will remove all function-like macros that are alone

11
INSTALL
View File

@ -1,7 +1,7 @@
Installing QCA Installing QCA
-------------- --------------
QCA requires Qt 4.7 or greater. QCA requires Qt 5.5 or greater.
For Unix/Linux/Mac/Windows: For Unix/Linux/Mac/Windows:
@ -17,7 +17,6 @@ Notes
CMAKE_INSTALL_PREFIX - must be defined otherwise QCA will be installed CMAKE_INSTALL_PREFIX - must be defined otherwise QCA will be installed
in Qt prefix (by default: "") in Qt prefix (by default: "")
QT4_BUILD - forced Qt4 building (by default: OFF)
BUILD_TESTS - build unittests (by default: ON) BUILD_TESTS - build unittests (by default: ON)
BUILD_TOOLS - build mozcerts and qcatool (by default: ON) BUILD_TOOLS - build mozcerts and qcatool (by default: ON)
QCA_SUFFIX - suffix will be used for library, qcatool binary, QCA_SUFFIX - suffix will be used for library, qcatool binary,
@ -53,10 +52,4 @@ Please report problems to:
http://bugs.kde.org http://bugs.kde.org
Official git repo: Official git repo:
http://quickgit.kde.org/?p=qca.git https://invent.kde.org/kde/qca
KDE Projects page:
http://projects.kde.org/projects/kdesupport/qca
Official homepage:
http://delta.affinix.com/qca/

View File

@ -150,9 +150,9 @@
\subsection qca2code Releases \subsection qca2code Releases
The latest release packages can be found in the The latest release packages can be found in the
<a href="http://delta.affinix.com/download/qca/2.0/">%QCA 2.0 download area</a>. <a href="https://download.kde.org/stable/qca/">%QCA 2.x download area</a>.
See the <a href="http://delta.affinix.com/qca/">project web site</a> for See the <a href="https://userbase.kde.org/QCA/">project web site</a> for
further information about %QCA releases. further information about %QCA releases.
\subsection qca2dev Current development \subsection qca2dev Current development
@ -163,12 +163,12 @@
to build and use %QCA. to build and use %QCA.
The Git code can be browsed The Git code can be browsed
<a href="http://quickgit.kde.org/?p=qca.git"> <a href="https://commits.kde.org/qca">
via the web</a> via the web</a>
Use Use
\verbatim \verbatim
git clone git://anongit.kde.org/qca.git git clone https://invent.kde.org/libraries/qca.git
\endverbatim \endverbatim
to get the latest sources. to get the latest sources.
*/ */

View File

@ -1,7 +1,7 @@
@PACKAGE_INIT@ @PACKAGE_INIT@
if(NOT TARGET qca) if(NOT TARGET @QCA_LIB_NAME@)
include("${CMAKE_CURRENT_LIST_DIR}/QcaTargets.cmake") include("${CMAKE_CURRENT_LIST_DIR}/@QCA_CONFIG_NAME_BASE@Targets.cmake")
endif() endif()
set(Qca_LIBRARY qca) set(Qca_LIBRARY @QCA_LIB_NAME@)

77
README
View File

@ -1,26 +1,19 @@
Qt Cryptographic Architecture (QCA) version 2.1.0 Qt Cryptographic Architecture (QCA)
------------------------------------------------- -----------------------------------
Date: November 6th, 2014
Website: http://delta.affinix.com/qca/
Mailing List: Delta Project <delta@lists.affinix.com>
Project Lead/Maintainer (2003-current): Description
Justin Karneges <justin@affinix.com> -----------
(March 2007 - August 2007 under Barracuda Networks employment)
Development, Documentation, Unittests (2004-2009): QCA is a library that provides an easy API for a range of cryptographic
Brad Hards <bradh@frogmouth.net> features, including SSL/TLS, X.509 certificates, SASL, OpenPGP, smartcards,
and much more.
Development (2013-current) Functionality is supplied via plugins. This is useful for avoiding
Ivan Romanov <drizt@land.ru> dependence on a particular crypto library and makes upgrading easier,
as there is no need to recompile your application when adding or
upgrading a crypto plugin.
Special Thanks: In order for QCA to be of much use, you'll want to install some plugins.
Portugal Telecom (SAPO division), for sponsorship
Alon Bar-Lev, for smart card and design assistance
Jack Lloyd, for Botan and X.509 mentoring
L. Peter Deutsch, for the public domain MD5 implementation
Steve Reid, for the public domain SHA1 implementation
Jason Kim, for the CMS Signer graphics
Install Install
@ -34,10 +27,18 @@ License
the COPYING file for more information. the COPYING file for more information.
Changes History
------- -------
QCA was originally created to support the security needs of the
Psi XMPP/Jabber client project ( http://psi-im.org/ ).
Old Changes list
----------------
New in 2.1.0 New in 2.1.0
- Ported to Qt5 (Qt4 alsa supported) - Ported to Qt5 (Qt4 also supported)
- New building system. CMake instead of qmake - New building system. CMake instead of qmake
- Added CTR symetric cipher support to qca core - Added CTR symetric cipher support to qca core
- Added no padding encryption algorithm to qca core - Added no padding encryption algorithm to qca core
@ -90,25 +91,23 @@ Changes
- Windows version can be configured/installed using paths with spaces - Windows version can be configured/installed using paths with spaces
Description Old Developer list
----------- ------------------
QCA is a library that provides an easy API for a range of cryptographic Project Lead/Maintainer (2003-2012):
features, including SSL/TLS, X.509 certificates, SASL, OpenPGP, smartcards, Justin Karneges <justin@affinix.com>
and much more. (March 2007 - August 2007 under Barracuda Networks employment)
Functionality is supplied via plugins. This is useful for avoiding Development, Documentation, Unittests (2004-2009):
dependence on a particular crypto library and makes upgrading easier, Brad Hards <bradh@frogmouth.net>
as there is no need to recompile your application when adding or
upgrading a crypto plugin.
In order for QCA to be of much use, you'll want to install some plugins. Development (2013-2017)
Ivan Romanov <drizt@land.ru>
QCA was originally created to support the security needs of the Special Thanks:
Psi XMPP/Jabber client project ( http://psi-im.org/ ). Portugal Telecom (SAPO division), for sponsorship
Alon Bar-Lev, for smart card and design assistance
API Documentation is located in the 'apidocs' subdirectory. Jack Lloyd, for Botan and X.509 mentoring
L. Peter Deutsch, for the public domain MD5 implementation
Steve Reid, for the public domain SHA1 implementation
Have fun, Jason Kim, for the CMS Signer graphics
-Justin

14
README.clang-format Normal file
View File

@ -0,0 +1,14 @@
We introduced clang-format mandatory usage in September 2020.
If you want git blame to ignore the revision in which we did the mass change you can do
git config blame.ignoreRevsFile .git-blame-ignore-revs
on your clone
To get the clang-format warnings locally instead at CI time we recommend you
to copy the hooks/pre-commit to your .git
cp hooks/pre-commit .git/hooks/
We are using clang-format 11 on CI. Unfortunately clang-format is not totally
compatible with older versions of itself. If CI gives you trouble but your local
clang-format disagrees, just apply the changes suggested by CI and then commit
with the --no-verify flag. If you get stuck, don't hesitate to ask the reviewer
to help and they will reformat your commits :)

View File

@ -1,5 +1,5 @@
rootcerts.pem is created by qca/tools/mozcerts rootcerts.pem is created by qca/tools/mozcerts
File: mozilla/security/nss/lib/ckfw/builtins/certdata.txt File: https://hg.mozilla.org/mozilla-central/log/tip/security/nss/lib/ckfw/builtins/certdata.txt
Date: January 15th, 2009 Date: July 4, 2020

File diff suppressed because it is too large Load Diff

View File

@ -1,238 +0,0 @@
#=============================================================================
# Copyright 2005-2011 Kitware, Inc.
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
#
# * Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
#
# * Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution.
#
# * Neither the name of Kitware, Inc. nor the names of its
# contributors may be used to endorse or promote products derived
# from this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
# HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#=============================================================================
# The automoc_qt4 macro is superceded by CMAKE_AUTOMOC from CMake 2.8.6
# A Qt 5 version is not provided by CMake or Qt.
include(MacroAddFileDependencies)
MACRO (QT4_GET_MOC_FLAGS _moc_flags)
SET(${_moc_flags})
GET_DIRECTORY_PROPERTY(_inc_DIRS INCLUDE_DIRECTORIES)
FOREACH(_current ${_inc_DIRS})
IF("${_current}" MATCHES "\\.framework/?$")
STRING(REGEX REPLACE "/[^/]+\\.framework" "" framework_path "${_current}")
SET(${_moc_flags} ${${_moc_flags}} "-F${framework_path}")
ELSE("${_current}" MATCHES "\\.framework/?$")
SET(${_moc_flags} ${${_moc_flags}} "-I${_current}")
ENDIF("${_current}" MATCHES "\\.framework/?$")
ENDFOREACH(_current ${_inc_DIRS})
GET_DIRECTORY_PROPERTY(_defines COMPILE_DEFINITIONS)
FOREACH(_current ${_defines})
SET(${_moc_flags} ${${_moc_flags}} "-D${_current}")
ENDFOREACH(_current ${_defines})
IF(Q_WS_WIN)
SET(${_moc_flags} ${${_moc_flags}} -DWIN32)
ENDIF(Q_WS_WIN)
ENDMACRO(QT4_GET_MOC_FLAGS)
# helper macro to set up a moc rule
MACRO (QT4_CREATE_MOC_COMMAND infile outfile moc_flags moc_options)
# For Windows, create a parameters file to work around command line length limit
IF (WIN32)
# Pass the parameters in a file. Set the working directory to
# be that containing the parameters file and reference it by
# just the file name. This is necessary because the moc tool on
# MinGW builds does not seem to handle spaces in the path to the
# file given with the @ syntax.
GET_FILENAME_COMPONENT(_moc_outfile_name "${outfile}" NAME)
GET_FILENAME_COMPONENT(_moc_outfile_dir "${outfile}" PATH)
IF(_moc_outfile_dir)
SET(_moc_working_dir WORKING_DIRECTORY ${_moc_outfile_dir})
ENDIF(_moc_outfile_dir)
SET (_moc_parameters_file ${outfile}_parameters)
SET (_moc_parameters ${moc_flags} ${moc_options} -o "${outfile}" "${infile}")
STRING (REPLACE ";" "\n" _moc_parameters "${_moc_parameters}")
FILE (WRITE ${_moc_parameters_file} "${_moc_parameters}")
ADD_CUSTOM_COMMAND(OUTPUT ${outfile}
COMMAND ${QT_MOC_EXECUTABLE} @${_moc_outfile_name}_parameters
DEPENDS ${infile}
${_moc_working_dir}
VERBATIM)
ELSE (WIN32)
ADD_CUSTOM_COMMAND(OUTPUT ${outfile}
COMMAND ${QT_MOC_EXECUTABLE}
ARGS ${moc_flags} ${moc_options} -o ${outfile} ${infile}
DEPENDS ${infile} VERBATIM)
ENDIF (WIN32)
ENDMACRO (QT4_CREATE_MOC_COMMAND)
MACRO(QT4_AUTOMOC)
QT4_GET_MOC_FLAGS(_moc_INCS)
SET(_matching_FILES )
FOREACH (_current_FILE ${ARGN})
GET_FILENAME_COMPONENT(_abs_FILE ${_current_FILE} ABSOLUTE)
# if "SKIP_AUTOMOC" is set to true, we will not handle this file here.
# This is required to make uic work correctly:
# we need to add generated .cpp files to the sources (to compile them),
# but we cannot let automoc handle them, as the .cpp files don't exist yet when
# cmake is run for the very first time on them -> however the .cpp files might
# exist at a later run. at that time we need to skip them, so that we don't add two
# different rules for the same moc file
GET_SOURCE_FILE_PROPERTY(_skip ${_abs_FILE} SKIP_AUTOMOC)
IF ( NOT _skip AND EXISTS ${_abs_FILE} )
FILE(READ ${_abs_FILE} _contents)
GET_FILENAME_COMPONENT(_abs_PATH ${_abs_FILE} PATH)
STRING(REGEX MATCHALL "# *include +[^ ]+\\.moc[\">]" _match "${_contents}")
IF(_match)
FOREACH (_current_MOC_INC ${_match})
STRING(REGEX MATCH "[^ <\"]+\\.moc" _current_MOC "${_current_MOC_INC}")
GET_FILENAME_COMPONENT(_basename ${_current_MOC} NAME_WE)
IF(EXISTS ${_abs_PATH}/${_basename}.hpp)
SET(_header ${_abs_PATH}/${_basename}.hpp)
ELSE(EXISTS ${_abs_PATH}/${_basename}.hpp)
SET(_header ${_abs_PATH}/${_basename}.h)
ENDIF(EXISTS ${_abs_PATH}/${_basename}.hpp)
SET(_moc ${CMAKE_CURRENT_BINARY_DIR}/${_current_MOC})
QT4_CREATE_MOC_COMMAND(${_header} ${_moc} "${_moc_INCS}" "")
MACRO_ADD_FILE_DEPENDENCIES(${_abs_FILE} ${_moc})
ENDFOREACH (_current_MOC_INC)
ENDIF(_match)
ENDIF ( NOT _skip AND EXISTS ${_abs_FILE} )
ENDFOREACH (_current_FILE)
ENDMACRO(QT4_AUTOMOC)
# Portability helpers.
set(QT_QTGUI_LIBRARIES
${Qt5Gui_LIBRARIES}
${Qt5Widgets_LIBRARIES}
${Qt5PrintSupport_LIBRARIES}
${Qt5Svg_LIBRARIES}
)
set(QT_INCLUDES
${Qt5Gui_INCLUDE_DIRS}
${Qt5Widgets_INCLUDE_DIRS}
${Qt5PrintSupport_INCLUDE_DIRS}
${Qt5Svg_INCLUDE_DIRS}
)
set(QT_QTGUI_LIBRARY ${QT_QTGUI_LIBRARIES})
set(_qt_modules
Core
Declarative
Widgets
Script
ScriptTools
DBus
Network
Test
Designer
Concurrent
Xml
UiTools
Qml
Quick1
WebKit
WebKitWidgets
Sql
OpenGL
)
foreach(_module ${_qt_modules})
string(TOUPPER ${_module} _module_upper)
set(QT_QT${_module_upper}_LIBRARIES ${Qt5${_module}_LIBRARIES})
set(QT_QT${_module_upper}_LIBRARY ${QT_QT${_module_upper}_LIBRARIES})
list(APPEND QT_INCLUDES ${Qt5${_module}_INCLUDE_DIRS})
set(QT_QT${_module_upper}_FOUND ${Qt5${_module}_FOUND})
endforeach()
list(APPEND QT_QTCORE_LIBRARIES ${Qt5Concurrent_LIBRARIES})
list(APPEND QT_QTCORE_LIBRARY ${Qt5Concurrent_LIBRARIES})
list(APPEND QT_QTWEBKIT_LIBRARIES ${Qt5WebKitWidgets_LIBRARIES})
list(APPEND QT_QTWEBKIT_LIBRARY ${Qt5WebKitWidgets_LIBRARIES})
set(QT_QTDECLARATIVE_LIBRARIES ${Qt5Quick1_LIBRARIES})
set(QT_QTDECLARATIVE_LIBRARY ${Qt5Quick1_LIBRARIES})
get_target_property(QT_QMAKE_EXECUTABLE Qt5::qmake LOCATION)
get_target_property(QT_RCC_EXECUTABLE Qt5::rcc LOCATION)
if (TARGET Qt5::uic)
get_target_property(QT_UIC_EXECUTABLE Qt5::uic LOCATION)
endif()
if (TARGET Qt5::qdbuscpp2xml)
get_target_property(QT_QDBUSCPP2XML_EXECUTABLE Qt5::qdbuscpp2xml LOCATION)
endif()
if (TARGET Qt5::qdbusxml2cpp)
get_target_property(QT_QDBUSXML2CPP_EXECUTABLE Qt5::qdbusxml2cpp LOCATION)
endif()
add_definitions(-DQT_DISABLE_DEPRECATED_BEFORE=0)
macro(qt4_wrap_ui)
qt5_wrap_ui(${ARGN})
endmacro()
macro(qt4_wrap_cpp)
qt5_wrap_cpp(${ARGN})
endmacro()
macro(qt4_generate_moc)
qt5_generate_moc(${ARGN})
endmacro()
macro(qt4_add_dbus_adaptor)
qt5_add_dbus_adaptor(${ARGN})
endmacro()
macro(qt4_add_dbus_interfaces)
qt5_add_dbus_interfaces(${ARGN})
endmacro()
macro(qt4_add_dbus_interface)
qt5_add_dbus_interface(${ARGN})
endmacro()
macro(qt4_generate_dbus_interface)
qt5_generate_dbus_interface(${ARGN})
endmacro()
macro(qt4_add_resources)
qt5_add_resources(${ARGN})
endmacro()

View File

@ -1,49 +0,0 @@
# - Try to find the Gcrypt library
# Once run this will define
#
# BOTAN_FOUND - set if the system has the gcrypt library
# BOTAN_CFLAGS - the required gcrypt compilation flags
# BOTAN_LIBRARIES - the linker libraries needed to use the gcrypt library
#
# Copyright (c) 2006 Brad Hards <bradh@kde.org>
#
# Redistribution and use is allowed according to the terms of the BSD license.
# For details see the accompanying COPYING-CMAKE-SCRIPTS file.
# libgcrypt is moving to pkg-config, but earlier version don't have it
#search in typical paths for libgcrypt-config
FIND_PROGRAM(BOTANCONFIG_EXECUTABLE NAMES botan-config botan-config-1.10)
mark_as_advanced(BOTANCONFIG_EXECUTABLE)
#reset variables
set(BOTAN_LIBRARIES)
set(BOTAN_CFLAGS)
# if botan-config has been found
IF(BOTANCONFIG_EXECUTABLE)
EXEC_PROGRAM(${BOTANCONFIG_EXECUTABLE} ARGS --libs RETURN_VALUE _return_VALUE OUTPUT_VARIABLE BOTAN_LIBRARIES)
EXEC_PROGRAM(${BOTANCONFIG_EXECUTABLE} ARGS --cflags RETURN_VALUE _return_VALUE OUTPUT_VARIABLE BOTAN_CFLAGS)
IF(BOTAN_LIBRARIES)
SET(BOTAN_FOUND TRUE)
ENDIF(BOTAN_LIBRARIES)
MARK_AS_ADVANCED(BOTAN_CFLAGS BOTAN_LIBRARIES)
ENDIF(BOTANCONFIG_EXECUTABLE)
if (BOTAN_FOUND)
if (NOT Botan_FIND_QUIETLY)
message(STATUS "Found Botan: ${BOTAN_LIBRARIES}")
endif (NOT Botan_FIND_QUIETLY)
else (BOTAN_FOUND)
if (Botan_FIND_REQUIRED)
message(FATAL_ERROR "Could not find Botan libraries")
endif (Botan_FIND_REQUIRED)
endif (BOTAN_FOUND)

View File

@ -1,13 +0,0 @@
# Copyright (c) 2006, Benjamin Reed, <ranger@befunk.com>
#
# Redistribution and use is allowed according to the terms of the BSD license.
# For details see the accompanying COPYING-CMAKE-SCRIPTS file.
INCLUDE(CMakeFindFrameworks)
CMAKE_FIND_FRAMEWORKS(Carbon)
if (Carbon_FRAMEWORKS)
set(CARBON_LIBRARY "-framework Carbon" CACHE FILEPATH "Carbon framework" FORCE)
set(CARBON_FOUND 1)
endif (Carbon_FRAMEWORKS)

View File

@ -42,11 +42,11 @@ ENDIF(LIBGCRYPTCONFIG_EXECUTABLE)
if (LIBGCRYPT_FOUND) if (LIBGCRYPT_FOUND)
if (NOT LibGcrypt_FIND_QUIETLY) if (NOT LibGcrypt_FIND_QUIETLY)
message(STATUS "Found libgcrypt: ${LIBGCRYPT_LIBRARIES}") message(STATUS "Found libgcrypt: ${LIBGCRYPT_LIBRARIES}")
endif (NOT LibGcrypt_FIND_QUIETLY) endif()
else (LIBGCRYPT_FOUND) else()
if (LibGcrypt_FIND_REQUIRED) if (LibGcrypt_FIND_REQUIRED)
message(FATAL_ERROR "Could not find libgcrypt libraries") message(FATAL_ERROR "Could not find libgcrypt libraries")
endif (LibGcrypt_FIND_REQUIRED) endif()
endif (LIBGCRYPT_FOUND) endif()
MARK_AS_ADVANCED(LIBGCRYPT_CFLAGS LIBGCRYPT_LIBRARIES) MARK_AS_ADVANCED(LIBGCRYPT_CFLAGS LIBGCRYPT_LIBRARIES)

View File

@ -1,37 +0,0 @@
# - Try to find the NSS library
# Once done this will define
#
# NSS_FOUND - system has mozilla-nss lib
# NSS_INCLUDE_DIRS - the mozilla-nss include directories
# NSS_LDFLAGS - Link these to use mozilla-nss
# NSS_CFLAGS_OTHER - Compiler switches required for using NSS
#
# Copyright (c) 2006, Laurent Montel, <montel@kde.org>
#
# Redistribution and use is allowed according to the terms of the BSD license.
# For details see the accompanying COPYING-CMAKE-SCRIPTS file.
if(NSS_INCLUDE_DIRS AND NSS_LDFLAGS)
# in cache already
SET(NSS_FOUND TRUE)
else()
if(NOT WIN32)
find_package(PkgConfig REQUIRED)
pkg_search_module(NSS nss)
endif(NOT WIN32)
if (NSS_FOUND)
if (NOT Nss_FIND_QUIETLY)
message(STATUS "Found NSS: ${NSS_LDFLAGS}")
endif (NOT Nss_FIND_QUIETLY)
else (NSS_FOUND)
if (Nss_FIND_REQUIRED)
message(FATAL_ERROR "Could NOT find NSS")
endif (Nss_FIND_REQUIRED)
endif (NSS_FOUND)
mark_as_advanced(NSS_INCLUDE_DIRS NSS_LDFLAGS NSS_CFLAGS_OTHER)
endif()

View File

@ -21,19 +21,19 @@ if(PKCS11H_INCLUDE_DIRS AND PKCS11H_LDFLAGS)
else() else()
if(NOT WIN32) if(NOT WIN32)
find_package(PkgConfig REQUIRED) find_package(PkgConfig)
pkg_search_module(PKCS11H libpkcs11-helper-1) pkg_search_module(PKCS11H libpkcs11-helper-1)
endif(NOT WIN32) endif()
if (PKCS11H_FOUND) if (PKCS11H_FOUND)
if (NOT Pkcs11Helper_FIND_QUIETLY) if (NOT Pkcs11Helper_FIND_QUIETLY)
message(STATUS "Found pkcs11-helper: ${PKCS11H_LDFLAGS}") message(STATUS "Found pkcs11-helper: ${PKCS11H_LDFLAGS}")
endif (NOT Pkcs11Helper_FIND_QUIETLY) endif()
else (PKCS11H_FOUND) else()
if (Pkcs11Helper_FIND_REQUIRED) if (Pkcs11Helper_FIND_REQUIRED)
message(FATAL_ERROR "Could NOT find pkcs11-helper") message(FATAL_ERROR "Could NOT find pkcs11-helper")
endif (Pkcs11Helper_FIND_REQUIRED) endif()
endif (PKCS11H_FOUND) endif()
mark_as_advanced(PKCS11H_INCLUDE_DIRS PKCS11H_LDFLAGS PKCS11H_CFLAGS_OTHER) mark_as_advanced(PKCS11H_INCLUDE_DIRS PKCS11H_LDFLAGS PKCS11H_CFLAGS_OTHER)

View File

@ -1,125 +0,0 @@
find_package(Qt5Core QUIET)
mark_as_advanced(Qt5Core_DIR)
if (Qt5Core_FOUND)
if (NOT Qt5Transitional_FIND_COMPONENTS)
set(_components
Core
Gui
DBus
Designer
Declarative
Script
ScriptTools
Network
Test
Xml
Svg
Sql
Widgets
PrintSupport
Concurrent
UiTools
WebKit
WebKitWidgets
OpenGL
)
foreach(_component ${_components})
find_package(Qt5${_component})
mark_as_advanced(Qt5${_component}_DIR)
list(APPEND QT_LIBRARIES ${Qt5${_component}_LIBRARIES})
endforeach()
else()
set(_components ${Qt5Transitional_FIND_COMPONENTS})
foreach(_component ${Qt5Transitional_FIND_COMPONENTS})
find_package(Qt5${_component} REQUIRED)
mark_as_advanced(Qt5${_component}_DIR)
if ("${_component}" STREQUAL "WebKit")
find_package(Qt5WebKitWidgets REQUIRED)
mark_as_advanced(Qt5WebKitWidgets_DIR)
list(APPEND QT_LIBRARIES ${Qt5WebKitWidgets_LIBRARIES} )
endif()
if ("${_component}" STREQUAL "Gui")
find_package(Qt5Widgets REQUIRED)
find_package(Qt5PrintSupport REQUIRED)
find_package(Qt5Svg REQUIRED)
mark_as_advanced(Qt5Widgets_DIR Qt5PrintSupport_DIR Qt5Svg_DIR)
list(APPEND QT_LIBRARIES ${Qt5Widgets_LIBRARIES}
${Qt5PrintSupport_LIBRARIES}
${Qt5Svg_LIBRARIES} )
endif()
# Core module was separated to Core and Concurrent in Qt5.
# But QCA doesn't use any classes from QtConcurrent.
# So QtConcurrent mustn't be used in QCA.
# Uncomment this if Concurrent support will be added.
# if ("${_component}" STREQUAL "Core")
# find_package(Qt5Concurrent REQUIRED)
# list(APPEND QT_LIBRARIES ${Qt5Concurrent_LIBRARIES} )
# endif()
endforeach()
endif()
set(Qt5Transitional_FOUND TRUE)
set(QT5_BUILD TRUE)
# Temporary until upstream does this:
foreach(_component ${_components})
if (TARGET Qt5::${_component})
set_property(TARGET Qt5::${_component}
APPEND PROPERTY
INTERFACE_INCLUDE_DIRECTORIES ${Qt5${_component}_INCLUDE_DIRS})
set_property(TARGET Qt5::${_component}
APPEND PROPERTY
INTERFACE_COMPILE_DEFINITIONS ${Qt5${_component}_COMPILE_DEFINITIONS})
endif()
endforeach()
set_property(TARGET Qt5::Core
PROPERTY
INTERFACE_POSITION_INDEPENDENT_CODE ON
)
if (WIN32 AND NOT Qt5_NO_LINK_QTMAIN)
set(_isExe $<STREQUAL:$<TARGET_PROPERTY:TYPE>,EXECUTABLE>)
set(_isWin32 $<BOOL:$<TARGET_PROPERTY:WIN32_EXECUTABLE>>)
set(_isNotExcluded $<NOT:$<BOOL:$<TARGET_PROPERTY:Qt5_NO_LINK_QTMAIN>>>)
get_target_property(_configs Qt5::Core IMPORTED_CONFIGURATIONS)
foreach(_config ${_configs})
set_property(TARGET Qt5::Core APPEND PROPERTY
IMPORTED_LINK_INTERFACE_LIBRARIES_${_config}
$<$<AND:${_isExe},${_isWin32},${_isNotExcluded}>:Qt5::WinMain>
)
endforeach()
unset(_configs)
unset(_isExe)
unset(_isWin32)
unset(_isNotExcluded)
endif()
# End upstreamed stuff.
get_filename_component(_modules_dir "${CMAKE_CURRENT_LIST_DIR}/../modules" ABSOLUTE)
include("${_modules_dir}/ECMQt4To5Porting.cmake") # TODO: Port away from this.
include_directories(${QT_INCLUDES}) # TODO: Port away from this.
if (Qt5_POSITION_INDEPENDENT_CODE)
set(CMAKE_POSITION_INDEPENDENT_CODE ON)
endif()
else()
foreach(_component ${Qt5Transitional_FIND_COMPONENTS})
if("${_component}" STREQUAL "Widgets") # new in Qt5
set(_component Gui)
elseif("${_component}" STREQUAL "Concurrent") # new in Qt5
set(_component Core)
endif()
list(APPEND _components Qt${_component})
endforeach()
find_package(Qt4 ${QT_MIN_VERSION} REQUIRED ${_components})
include_directories(${QT_INCLUDES})
if(QT4_FOUND)
set(Qt5Transitional_FOUND TRUE)
endif()
endif()

View File

@ -14,7 +14,7 @@
if (SASL2_INCLUDE_DIR) if (SASL2_INCLUDE_DIR)
# Already in cache, be silent # Already in cache, be silent
set(SASL2_FIND_QUIETLY TRUE) set(SASL2_FIND_QUIETLY TRUE)
endif (SASL2_INCLUDE_DIR) endif()
FIND_PATH(SASL2_INCLUDE_DIR sasl/sasl.h) FIND_PATH(SASL2_INCLUDE_DIR sasl/sasl.h)
@ -23,18 +23,18 @@ FIND_LIBRARY(SASL2_LIBRARIES NAMES sasl2)
if (SASL2_INCLUDE_DIR AND SASL2_LIBRARIES) if (SASL2_INCLUDE_DIR AND SASL2_LIBRARIES)
set(SASL2_FOUND TRUE) set(SASL2_FOUND TRUE)
endif (SASL2_INCLUDE_DIR AND SASL2_LIBRARIES) endif()
if (SASL2_FOUND) if (SASL2_FOUND)
if (NOT Sasl2_FIND_QUIETLY) if (NOT Sasl2_FIND_QUIETLY)
message(STATUS "Found Sasl2: ${SASL2_LIBRARIES}") message(STATUS "Found Sasl2: ${SASL2_LIBRARIES}")
endif (NOT Sasl2_FIND_QUIETLY) endif()
else (SASL2_FOUND) else()
if (Sasl2_FIND_REQUIRED) if (Sasl2_FIND_REQUIRED)
message(FATAL_ERROR "Could not find sasl2 libraries") message(FATAL_ERROR "Could not find sasl2 libraries")
endif (Sasl2_FIND_REQUIRED) endif()
endif (SASL2_FOUND) endif()
MARK_AS_ADVANCED(SASL2_INCLUDE_DIR SASL2_LIBRARIES) MARK_AS_ADVANCED(SASL2_INCLUDE_DIR SASL2_LIBRARIES)

View File

@ -1,17 +1,10 @@
IF (Qt5Core_FOUND) MACRO(SETUP_QT_DIRS)
# FindQt4.cmake wasn't used, so define it here if(QT6)
MACRO (QT4_GET_MOC_INC_DIRS _moc_INC_DIRS) GET_TARGET_PROPERTY(QMAKE_EXECUTABLE Qt6::qmake LOCATION)
SET(${_moc_INC_DIRS}) else()
GET_DIRECTORY_PROPERTY(_inc_DIRS INCLUDE_DIRECTORIES)
FOREACH(_current ${_inc_DIRS})
SET(${_moc_INC_DIRS} ${${_moc_INC_DIRS}} "-I" ${_current})
ENDFOREACH(_current ${_inc_DIRS})
ENDMACRO(QT4_GET_MOC_INC_DIRS)
MACRO(SETUP_QT5_DIRS)
GET_TARGET_PROPERTY(QMAKE_EXECUTABLE ${Qt5Core_QMAKE_EXECUTABLE} LOCATION) GET_TARGET_PROPERTY(QMAKE_EXECUTABLE ${Qt5Core_QMAKE_EXECUTABLE} LOCATION)
endif()
EXEC_PROGRAM( ${QMAKE_EXECUTABLE} ARGS "-query QT_INSTALL_LIBS" OUTPUT_VARIABLE QT_LIBRARY_DIR ) EXEC_PROGRAM( ${QMAKE_EXECUTABLE} ARGS "-query QT_INSTALL_LIBS" OUTPUT_VARIABLE QT_LIBRARY_DIR )
EXEC_PROGRAM( ${QMAKE_EXECUTABLE} ARGS "-query QT_INSTALL_PREFIX" OUTPUT_VARIABLE QT_PREFIX_DIR ) EXEC_PROGRAM( ${QMAKE_EXECUTABLE} ARGS "-query QT_INSTALL_PREFIX" OUTPUT_VARIABLE QT_PREFIX_DIR )
EXEC_PROGRAM( ${QMAKE_EXECUTABLE} ARGS "-query QT_INSTALL_PLUGINS" OUTPUT_VARIABLE QT_PLUGINS_DIR ) EXEC_PROGRAM( ${QMAKE_EXECUTABLE} ARGS "-query QT_INSTALL_PLUGINS" OUTPUT_VARIABLE QT_PLUGINS_DIR )
@ -19,45 +12,17 @@ IF (Qt5Core_FOUND)
EXEC_PROGRAM( ${QMAKE_EXECUTABLE} ARGS "-query QT_INSTALL_HEADERS" OUTPUT_VARIABLE QT_HEADERS_DIR ) EXEC_PROGRAM( ${QMAKE_EXECUTABLE} ARGS "-query QT_INSTALL_HEADERS" OUTPUT_VARIABLE QT_HEADERS_DIR )
EXEC_PROGRAM( ${QMAKE_EXECUTABLE} ARGS "-query QT_INSTALL_DOCS" OUTPUT_VARIABLE QT_DOC_DIR ) EXEC_PROGRAM( ${QMAKE_EXECUTABLE} ARGS "-query QT_INSTALL_DOCS" OUTPUT_VARIABLE QT_DOC_DIR )
EXEC_PROGRAM( ${QMAKE_EXECUTABLE} ARGS "-query QT_INSTALL_DATA" OUTPUT_VARIABLE QT_DATA_DIR ) EXEC_PROGRAM( ${QMAKE_EXECUTABLE} ARGS "-query QT_INSTALL_DATA" OUTPUT_VARIABLE QT_DATA_DIR )
EXEC_PROGRAM( ${QMAKE_EXECUTABLE} ARGS "-query QT_INSTALL_ARCHDATA" OUTPUT_VARIABLE QT_ARCHDATA_DIR ) EXEC_PROGRAM( ${QMAKE_EXECUTABLE} ARGS "-query QT_HOST_DATA" OUTPUT_VARIABLE QT_ARCHDATA_DIR )
SET( QT_MKSPECS_DIR "${QT_ARCHDATA_DIR}/mkspecs" ) SET( QT_MKSPECS_DIR "${QT_ARCHDATA_DIR}/mkspecs" )
ENDMACRO(SETUP_QT5_DIRS) ENDMACRO(SETUP_QT_DIRS)
ELSE (Qt5Core_FOUND)
# Cmake FindQt4 module doesn't provide QT_INSTALL_PREFIX and QT_INSTALL_DATA vars
# It will be done here
MACRO(SETUP_QT4_DIRS)
_qt4_query_qmake(QT_INSTALL_PREFIX QT_PREFIX_DIR)
_qt4_query_qmake(QT_INSTALL_DATA QT_DATA_DIR)
ENDMACRO(SETUP_QT4_DIRS)
ENDIF()
MACRO(MY_AUTOMOC _srcsList)
# QT4_GET_MOC_INC_DIRS(_moc_INCS)
FOREACH (_current_FILE ${${_srcsList}})
GET_FILENAME_COMPONENT(_abs_FILE ${_current_FILE} ABSOLUTE)
GET_FILENAME_COMPONENT(_basename ${_current_FILE} NAME_WE)
SET(_moc ${CMAKE_CURRENT_BINARY_DIR}/${_basename}.moc)
# SET(extra_moc_argument)
# if(WIN32)
# SET(extra_moc_argument -DWIN32)
# endif(WIN32)
QT4_GENERATE_MOC(${_abs_FILE} ${_moc})
# ADD_CUSTOM_COMMAND(OUTPUT ${_moc}
# COMMAND ${QT_MOC_EXECUTABLE}
# ARGS ${extra_moc_argument} ${_moc_INCS} -o ${_moc} ${_abs_FILE}
# DEPENDS ${_current_FILE}
# )
LIST(APPEND ${_srcsList} ${_moc})
ENDFOREACH (_current_FILE)
ENDMACRO(MY_AUTOMOC)
macro(set_enabled_plugin PLUGIN ENABLED) macro(set_enabled_plugin PLUGIN ENABLED)
# To nice looks # To nice looks
if(ENABLED) if(ENABLED)
set(ENABLED "on") set(ENABLED "on")
else(ENABLED) else()
set(ENABLED "off") set(ENABLED "off")
endif(ENABLED) endif()
set(WITH_${PLUGIN}_PLUGIN_INTERNAL ${ENABLED} CACHE INTERNAL "") set(WITH_${PLUGIN}_PLUGIN_INTERNAL ${ENABLED} CACHE INTERNAL "")
endmacro(set_enabled_plugin) endmacro(set_enabled_plugin)
@ -72,7 +37,6 @@ endmacro(disable_plugin)
# it used to build examples and tools # it used to build examples and tools
macro(target_link_qca_libraries TARGET) macro(target_link_qca_libraries TARGET)
# Link with QCA library # Link with QCA library
target_link_libraries(${TARGET} ${QT_QTCORE_LIBRARY})
target_link_libraries(${TARGET} ${QCA_LIB_NAME}) target_link_libraries(${TARGET} ${QCA_LIB_NAME})
# Statically link with all enabled QCA plugins # Statically link with all enabled QCA plugins
@ -82,15 +46,19 @@ macro(target_link_qca_libraries TARGET)
# Check plugin for enabled # Check plugin for enabled
if(WITH_${PLUGIN}_PLUGIN_INTERNAL) if(WITH_${PLUGIN}_PLUGIN_INTERNAL)
target_link_libraries(${TARGET} qca-${PLUGIN}) target_link_libraries(${TARGET} qca-${PLUGIN})
endif(WITH_${PLUGIN}_PLUGIN_INTERNAL) endif()
endforeach(PLUGIN) endforeach(PLUGIN)
endif(STATIC_PLUGINS) endif()
endmacro(target_link_qca_libraries) endmacro(target_link_qca_libraries)
# it used to build unittests # it used to build unittests
macro(target_link_qca_test_libraries TARGET) macro(target_link_qca_test_libraries TARGET)
target_link_qca_libraries(${TARGET}) target_link_qca_libraries(${TARGET})
target_link_libraries(${TARGET} ${QT_QTTEST_LIBRARY}) if(QT6)
target_link_libraries(${TARGET} Qt6::Test)
else()
target_link_libraries(${TARGET} Qt5::Test)
endif()
endmacro(target_link_qca_test_libraries) endmacro(target_link_qca_test_libraries)
# it used to build unittests # it used to build unittests
@ -109,7 +77,7 @@ macro(install_pdb TARGET INSTALL_PATH)
get_target_property(LOCATION ${TARGET} LOCATION_RELWITHDEBINFO) get_target_property(LOCATION ${TARGET} LOCATION_RELWITHDEBINFO)
string(REGEX REPLACE "\\.[^.]*$" ".pdb" LOCATION "${LOCATION}") string(REGEX REPLACE "\\.[^.]*$" ".pdb" LOCATION "${LOCATION}")
install(FILES ${LOCATION} DESTINATION ${INSTALL_PATH} CONFIGURATIONS RelWithDebInfo) install(FILES ${LOCATION} DESTINATION ${INSTALL_PATH} CONFIGURATIONS RelWithDebInfo)
endif(MSVC) endif()
endmacro(install_pdb) endmacro(install_pdb)
macro(normalize_path PATH) macro(normalize_path PATH)

View File

@ -4,7 +4,7 @@ cmake_policy(SET CMP0007 OLD)
if (NOT EXISTS "@CMAKE_CURRENT_BINARY_DIR@/install_manifest.txt") if (NOT EXISTS "@CMAKE_CURRENT_BINARY_DIR@/install_manifest.txt")
message(FATAL_ERROR "Cannot find install manifest: \"@CMAKE_CURRENT_BINARY_DIR@/install_manifest.txt\"") message(FATAL_ERROR "Cannot find install manifest: \"@CMAKE_CURRENT_BINARY_DIR@/install_manifest.txt\"")
endif(NOT EXISTS "@CMAKE_CURRENT_BINARY_DIR@/install_manifest.txt") endif()
file(READ "@CMAKE_CURRENT_BINARY_DIR@/install_manifest.txt" files) file(READ "@CMAKE_CURRENT_BINARY_DIR@/install_manifest.txt" files)
string(REGEX REPLACE "\n" ";" files "${files}") string(REGEX REPLACE "\n" ";" files "${files}")
@ -19,8 +19,8 @@ foreach (file ${files})
) )
if(NOT ${rm_retval} EQUAL 0) if(NOT ${rm_retval} EQUAL 0)
message(FATAL_ERROR "Problem when removing \"$ENV{DESTDIR}${file}\"") message(FATAL_ERROR "Problem when removing \"$ENV{DESTDIR}${file}\"")
endif (NOT ${rm_retval} EQUAL 0) endif()
else (EXISTS "$ENV{DESTDIR}${file}") else()
message(STATUS "File \"$ENV{DESTDIR}${file}\" does not exist.") message(STATUS "File \"$ENV{DESTDIR}${file}\" does not exist.")
endif (EXISTS "$ENV{DESTDIR}${file}") endif()
endforeach(file) endforeach(file)

View File

@ -5,21 +5,21 @@ CONFIG *= qt
LINKAGE = LINKAGE =
exists($$QCA_LIBDIR/qca.framework) { exists($$QCA_LIBDIR/@QCA_LIB_NAME@.framework) {
QMAKE_CXXFLAGS += -F$$QCA_LIBDIR QMAKE_CXXFLAGS += -F$$QCA_LIBDIR
LIBS *= -F$$QCA_LIBDIR LIBS *= -F$$QCA_LIBDIR
INCLUDEPATH += $$QCA_LIBDIR/qca.framework/Headers INCLUDEPATH += $$QCA_LIBDIR/@QCA_LIB_NAME@.framework/Headers
LINKAGE = -framework qca LINKAGE = -framework @QCA_LIB_NAME@
} }
# else, link normally # else, link normally
isEmpty(LINKAGE) { isEmpty(LINKAGE) {
INCLUDEPATH += $$QCA_INCDIR/QtCrypto INCLUDEPATH += $$QCA_INCDIR/QtCrypto
LIBS += -L$$QCA_LIBDIR LIBS += -L$$QCA_LIBDIR
LINKAGE = -lqca LINKAGE = -l@QCA_LIB_NAME@
CONFIG(debug, debug|release) { CONFIG(debug, debug|release) {
windows:LINKAGE = -lqcad windows:LINKAGE = -l@QCA_LIB_NAME@d
mac:LINKAGE = -lqca_debug mac:LINKAGE = -l@QCA_LIB_NAME@_debug
} }
} }

3
docs/Doxyfile.local Normal file
View File

@ -0,0 +1,3 @@
### KApiDox Project-specific Overrides File
FILE_PATTERNS += *.doco

View File

Before

Width:  |  Height:  |  Size: 18 KiB

After

Width:  |  Height:  |  Size: 18 KiB

View File

Before

Width:  |  Height:  |  Size: 13 KiB

After

Width:  |  Height:  |  Size: 13 KiB

View File

@ -1,5 +1,8 @@
if(Qt5Core_FOUND) if(QT6)
find_package(Qt6 REQUIRED Network)
else()
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${Qt5Core_EXECUTABLE_COMPILE_FLAGS}") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${Qt5Core_EXECUTABLE_COMPILE_FLAGS}")
find_package(Qt5 REQUIRED Network)
endif() endif()
add_subdirectory(aes-cmac) add_subdirectory(aes-cmac)
add_subdirectory(base64test) add_subdirectory(base64test)

View File

@ -31,16 +31,13 @@
class AESCMACContext : public QCA::MACContext class AESCMACContext : public QCA::MACContext
{ {
Q_OBJECT
public: public:
AESCMACContext(QCA::Provider *p) : QCA::MACContext(p, "cmac(aes)") AESCMACContext(QCA::Provider *p)
: QCA::MACContext(p, QStringLiteral("cmac(aes)"))
{ {
} }
~AESCMACContext()
{
}
// Helper to left shift an arbitrary length array // Helper to left shift an arbitrary length array
// This is heavily based on the example in the I-D. // This is heavily based on the example in the I-D.
QCA::SecureArray leftShift(const QCA::SecureArray &array) QCA::SecureArray leftShift(const QCA::SecureArray &array)
@ -64,10 +61,8 @@ public:
return out; return out;
} }
// Helper to XOR two arrays - must be same length // Helper to XOR two arrays - must be same length
QCA::SecureArray xorArray(const QCA::SecureArray &array1, QCA::SecureArray xorArray(const QCA::SecureArray &array1, const QCA::SecureArray &array2)
const QCA::SecureArray &array2)
{ {
if (array1.size() != array2.size()) if (array1.size() != array2.size())
// empty array // empty array
@ -81,8 +76,7 @@ public:
return result; return result;
} }
void setup(const QCA::SymmetricKey &key) override
void setup(const QCA::SymmetricKey &key)
{ {
// We might not have a real key, since this can get called // We might not have a real key, since this can get called
// from the constructor. // from the constructor.
@ -99,9 +93,7 @@ public:
m_residual = QCA::SecureArray(); m_residual = QCA::SecureArray();
// Figure 2.2, step 1. // Figure 2.2, step 1.
QCA::Cipher aesObj(QString("aes128"), QCA::Cipher aesObj(QStringLiteral("aes128"), QCA::Cipher::ECB, QCA::Cipher::DefaultPadding, QCA::Encode, key);
QCA::Cipher::ECB, QCA::Cipher::DefaultPadding,
QCA::Encode, key);
QCA::SecureArray L = aesObj.process(const_Zero); QCA::SecureArray L = aesObj.process(const_Zero);
// Figure 2.2, step 2 // Figure 2.2, step 2
@ -117,7 +109,7 @@ public:
m_k2 = xorArray(leftShift(m_k1), const_Rb); m_k2 = xorArray(leftShift(m_k1), const_Rb);
} }
QCA::Provider::Context *clone() const QCA::Provider::Context *clone() const override
{ {
return new AESCMACContext(*this); return new AESCMACContext(*this);
} }
@ -127,14 +119,14 @@ public:
setup(m_key); setup(m_key);
} }
QCA::KeyLength keyLength() const QCA::KeyLength keyLength() const override
{ {
return QCA::KeyLength(16, 16, 1); return QCA::KeyLength(16, 16, 1);
} }
// This is a bit different to the way the I-D does it, // This is a bit different to the way the I-D does it,
// to allow for multiple update() calls. // to allow for multiple update() calls.
void update(const QCA::MemoryRegion &a) void update(const QCA::MemoryRegion &a) override
{ {
QCA::SecureArray bytesToProcess = m_residual + a; QCA::SecureArray bytesToProcess = m_residual + a;
int blockNum; int blockNum;
@ -148,9 +140,8 @@ public:
m_Y = xorArray(m_X, thisBlock); m_Y = xorArray(m_X, thisBlock);
QCA::Cipher aesObj(QString("aes128"), QCA::Cipher aesObj(
QCA::Cipher::ECB, QCA::Cipher::DefaultPadding, QStringLiteral("aes128"), QCA::Cipher::ECB, QCA::Cipher::DefaultPadding, QCA::Encode, m_key);
QCA::Encode, m_key);
m_X = aesObj.process(m_Y); m_X = aesObj.process(m_Y);
} }
// This can be between 1 and 16 // This can be between 1 and 16
@ -161,7 +152,7 @@ public:
m_residual[yalv] = bytesToProcess[blockNum * 16 + yalv]; m_residual[yalv] = bytesToProcess[blockNum * 16 + yalv];
} }
void final( QCA::MemoryRegion *out) void final(QCA::MemoryRegion *out) override
{ {
QCA::SecureArray lastBlock; QCA::SecureArray lastBlock;
int numBytesLeft = m_residual.size(); int numBytesLeft = m_residual.size();
@ -176,11 +167,8 @@ public:
lastBlock = xorArray(m_residual, m_k1); lastBlock = xorArray(m_residual, m_k1);
} }
m_Y = xorArray(m_X, lastBlock); m_Y = xorArray(m_X, lastBlock);
QCA::Cipher aesObj(QString("aes128"), QCA::Cipher aesObj(QStringLiteral("aes128"), QCA::Cipher::ECB, QCA::Cipher::DefaultPadding, QCA::Encode, m_key);
QCA::Cipher::ECB, QCA::Cipher::DefaultPadding,
QCA::Encode, m_key);
*out = aesObj.process(m_Y); *out = aesObj.process(m_Y);
} }
protected: protected:
@ -202,49 +190,47 @@ protected:
class ClientSideProvider : public QCA::Provider class ClientSideProvider : public QCA::Provider
{ {
public: public:
int qcaVersion() const int qcaVersion() const override
{ {
return QCA_VERSION; return QCA_VERSION;
} }
QString name() const QString name() const override
{ {
return "exampleClientSideProvider"; return QStringLiteral("exampleClientSideProvider");
} }
QStringList features() const QStringList features() const override
{ {
QStringList list; QStringList list;
list += "cmac(aes)"; list += QStringLiteral("cmac(aes)");
// you can add more features in here, if you have some. // you can add more features in here, if you have some.
return list; return list;
} }
Provider::Context *createContext(const QString &type) Provider::Context *createContext(const QString &type) override
{ {
if(type == "cmac(aes)") if (type == QLatin1String("cmac(aes)"))
return new AESCMACContext(this); return new AESCMACContext(this);
// else if (type == some other feature) // else if (type == some other feature)
// return some other context. // return some other context.
else else
return 0; return nullptr;
} }
}; };
// AES CMAC is a Message Authentication Code based on a block cipher // AES CMAC is a Message Authentication Code based on a block cipher
// instead of the more normal keyed hash. // instead of the more normal keyed hash.
// See RFC 4493 "The AES-CMAC Algorithm" // See RFC 4493 "The AES-CMAC Algorithm"
class AES_CMAC : public QCA::MessageAuthenticationCode class AES_CMAC : public QCA::MessageAuthenticationCode
{ {
public: public:
AES_CMAC(const QCA::SymmetricKey &key = QCA::SymmetricKey(), AES_CMAC(const QCA::SymmetricKey &key = QCA::SymmetricKey(), const QString &provider = QString())
const QString &provider = QString()): : QCA::MessageAuthenticationCode(QStringLiteral("cmac(aes)"), key, provider)
QCA::MessageAuthenticationCode( "cmac(aes)", key, provider) {
{} }
}; };
int main(int argc, char **argv) int main(int argc, char **argv)
{ {
// the Initializer object sets things up, and // the Initializer object sets things up, and
@ -272,15 +258,16 @@ int main(int argc, char **argv)
AES_CMAC cmacObject; AES_CMAC cmacObject;
// create the key // create the key
QCA::SymmetricKey key(QCA::hexToArray("2b7e151628aed2a6abf7158809cf4f3c")); QCA::SymmetricKey key(QCA::hexToArray(QStringLiteral("2b7e151628aed2a6abf7158809cf4f3c")));
// set the MAC to use the key // set the MAC to use the key
cmacObject.setup(key); cmacObject.setup(key);
QCA::SecureArray message = QCA::hexToArray("6bc1bee22e409f96e93d7e117393172a" QCA::SecureArray message =
QCA::hexToArray(QStringLiteral("6bc1bee22e409f96e93d7e117393172a"
"ae2d8a571e03ac9c9eb76fac45af8e51" "ae2d8a571e03ac9c9eb76fac45af8e51"
"30c81c46a35ce411e5fbc1191a0a52ef" "30c81c46a35ce411e5fbc1191a0a52ef"
"f69f2445df4f9b17ad2b417be66c3710"); "f69f2445df4f9b17ad2b417be66c3710"));
QCA::SecureArray message1(message); QCA::SecureArray message1(message);
message1.resize(0); message1.resize(0);
qDebug(); qDebug();
@ -316,3 +303,4 @@ int main(int argc, char **argv)
return 0; return 0;
} }
#include "aes-cmac.moc"

View File

@ -68,4 +68,3 @@ int main(int argc, char **argv)
return 0; return 0;
} }

View File

@ -20,10 +20,10 @@
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/ */
#include <QtCrypto> #include <QtCrypto>
#include <QCoreApplication> #include <QCoreApplication>
#include <QFile>
#include <iostream> #include <iostream>
@ -34,7 +34,7 @@
// dump out information about some part of the certificate // dump out information about some part of the certificate
// we use this same approach for information about the subject // we use this same approach for information about the subject
// of the certificate, and also about the issuer of the certificate // of the certificate, and also about the issuer of the certificate
static void dumpCertificateInfo( QCA::CertificateInfo info) static void dumpCertificateInfo(const QCA::CertificateInfo &info)
{ {
std::cout << " Organization: " << std::endl; std::cout << " Organization: " << std::endl;
@ -55,29 +55,27 @@ static void dumpCertificateInfo( QCA::CertificateInfo info)
std::cout << " Country: " << std::endl; std::cout << " Country: " << std::endl;
// As above, however this shows a more compact way to represent // As above, however this shows a more compact way to represent
// the iteration and output. // the iteration and output.
foreach( QString country, info.values(QCA::Country) ) { foreach (QString country, info.values(QCA::Country)) { // clazy:exclude=container-anti-pattern
std::cout << " " << qPrintable(country) << std::endl; std::cout << " " << qPrintable(country) << std::endl;
} }
} }
// This is just a convenience routine // This is just a convenience routine
static void dumpSubjectInfo( QCA::CertificateInfo subject) static void dumpSubjectInfo(const QCA::CertificateInfo &subject)
{ {
std::cout << "Subject: " << std::endl; std::cout << "Subject: " << std::endl;
dumpCertificateInfo(subject); dumpCertificateInfo(subject);
} }
// This is just a convenience routine // This is just a convenience routine
static void dumpIssuerInfo( QCA::CertificateInfo issuer) static void dumpIssuerInfo(const QCA::CertificateInfo &issuer)
{ {
std::cout << "Issuer: " << std::endl; std::cout << "Issuer: " << std::endl;
dumpCertificateInfo(issuer); dumpCertificateInfo(issuer);
} }
int main(int argc, char **argv) int main(int argc, char **argv)
{ {
// the Initializer object sets things up, and // the Initializer object sets things up, and
@ -108,7 +106,7 @@ int main(int argc, char** argv)
QCA::ConvertResult importResult; QCA::ConvertResult importResult;
// This imports all the PEM encoded certificates from the file specified as the argument // This imports all the PEM encoded certificates from the file specified as the argument
// Note that you pass in a pointer to the result argument. // Note that you pass in a pointer to the result argument.
filecerts = QCA::CertificateCollection::fromFlatTextFile( argv[1], &importResult ); filecerts = QCA::CertificateCollection::fromFlatTextFile(QFile::decodeName(argv[1]), &importResult);
if (QCA::ConvertGood == importResult) { if (QCA::ConvertGood == importResult) {
std::cout << "Import succeeded" << std::endl; std::cout << "Import succeeded" << std::endl;
// this turns the CertificateCollection into a QList of Certificate objects // this turns the CertificateCollection into a QList of Certificate objects
@ -173,4 +171,3 @@ int main(int argc, char** argv)
return 0; return 0;
} }

View File

@ -22,7 +22,7 @@
// QtCrypto has the declarations for all of QCA // QtCrypto has the declarations for all of QCA
#include <QtCrypto> #include <QtCrypto>
#include <stdio.h> #include <cstdio>
#include <QCoreApplication> #include <QCoreApplication>
@ -56,12 +56,14 @@ int main(int argc, char **argv)
QCA::InitializationVector iv(16); QCA::InitializationVector iv(16);
// create a 128 bit AES cipher object using Cipher Block Chaining (CBC) mode // create a 128 bit AES cipher object using Cipher Block Chaining (CBC) mode
QCA::Cipher cipher(QString("aes128"),QCA::Cipher::CBC, QCA::Cipher cipher(QStringLiteral("aes128"),
QCA::Cipher::CBC,
// use Default padding, which is equivalent to PKCS7 for CBC // use Default padding, which is equivalent to PKCS7 for CBC
QCA::Cipher::DefaultPadding, QCA::Cipher::DefaultPadding,
// this object will encrypt // this object will encrypt
QCA::Encode, QCA::Encode,
key, iv); key,
iv);
// we use the cipher object to encrypt the argument we passed in // we use the cipher object to encrypt the argument we passed in
// the result of that is returned - note that if there is less than // the result of that is returned - note that if there is less than
@ -74,10 +76,7 @@ int main(int argc, char **argv)
printf("Update failed\n"); printf("Update failed\n");
} }
// output the results of that stage // output the results of that stage
printf("AES128 encryption of %s is [%s]\n", printf("AES128 encryption of %s is [%s]\n", arg.data(), qPrintable(QCA::arrayToHex(u.toByteArray())));
arg.data(),
qPrintable(QCA::arrayToHex(u.toByteArray())) );
// Because we are using PKCS7 padding, we need to output the final (padded) block // Because we are using PKCS7 padding, we need to output the final (padded) block
// Note that we should always call final() even with no padding, to clean up // Note that we should always call final() even with no padding, to clean up
@ -109,7 +108,8 @@ int main(int argc, char **argv)
// output results // output results
printf("Decryption using AES128 of [0x%s] is %s\n", printf("Decryption using AES128 of [0x%s] is %s\n",
qPrintable(QCA::arrayToHex(cipherText.toByteArray())), plainText.data()); qPrintable(QCA::arrayToHex(cipherText.toByteArray())),
plainText.data());
// Again we need to call final(), to get the last block (with its padding removed) // Again we need to call final(), to get the last block (with its padding removed)
plainText = cipher.final(); plainText = cipher.final();
@ -123,11 +123,8 @@ int main(int argc, char **argv)
printf("Final decryption block using AES128 is %s\n", plainText.data()); printf("Final decryption block using AES128 is %s\n", plainText.data());
// instead of update() and final(), you can do the whole thing // instead of update() and final(), you can do the whole thing
// in one step, using process() // in one step, using process()
printf("One step decryption using AES128: %s\n", printf("One step decryption using AES128: %s\n", QCA::SecureArray(cipher.process(cipherText)).data());
QCA::SecureArray(cipher.process(cipherText)).data() );
} }
return 0; return 0;
} }

View File

@ -20,7 +20,6 @@
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/ */
#include <QtCrypto> #include <QtCrypto>
#include <QCoreApplication> #include <QCoreApplication>
@ -46,7 +45,7 @@ int main(int argc, char** argv)
// Read in a public key cert // Read in a public key cert
// you could also build this using the fromPEMFile() method // you could also build this using the fromPEMFile() method
QCA::Certificate pubCert( "User.pem" ); QCA::Certificate pubCert(QStringLiteral("User.pem"));
if (pubCert.isNull()) { if (pubCert.isNull()) {
qWarning() << "Sorry, could not import public key certificate"; qWarning() << "Sorry, could not import public key certificate";
return 1; return 1;
@ -78,8 +77,7 @@ int main(int argc, char** argv)
msg.waitForFinished(1000); msg.waitForFinished(1000);
// check to see if it worked // check to see if it worked
if(!msg.success()) if (!msg.success()) {
{
qWarning() << "Error encrypting: " << msg.errorCode(); qWarning() << "Error encrypting: " << msg.errorCode();
return 1; return 1;
} }
@ -98,7 +96,7 @@ int main(int argc, char** argv)
QCA::PrivateKey privKey; QCA::PrivateKey privKey;
QCA::ConvertResult convRes; QCA::ConvertResult convRes;
QCA::SecureArray passPhrase = "start"; QCA::SecureArray passPhrase = "start";
privKey = QCA::PrivateKey::fromPEMFile( "Userkey.pem", passPhrase, &convRes ); privKey = QCA::PrivateKey::fromPEMFile(QStringLiteral("Userkey.pem"), passPhrase, &convRes);
if (convRes != QCA::ConvertGood) { if (convRes != QCA::ConvertGood) {
qWarning() << "Sorry, could not import Private Key"; qWarning() << "Sorry, could not import Private Key";
return 1; return 1;
@ -128,21 +126,17 @@ int main(int argc, char** argv)
msg2.waitForFinished(1000); msg2.waitForFinished(1000);
// check to see if it worked // check to see if it worked
if(!msg2.success()) if (!msg2.success()) {
{
qWarning() << "Error encrypting: " << msg2.errorCode(); qWarning() << "Error encrypting: " << msg2.errorCode();
return 1; return 1;
} }
QCA::SecureArray plainTextResult = msg2.read(); QCA::SecureArray plainTextResult = msg2.read();
qDebug() << enc.arrayToString( cipherText ) qDebug() << enc.arrayToString(cipherText) << " (in base 64) decrypts to: " << plainTextResult.data();
<< " (in base 64) decrypts to: "
<< plainTextResult.data();
if (msg2.wasSigned()) { if (msg2.wasSigned()) {
qDebug() << "Message was signed at " qDebug() << "Message was signed at " << msg2.signer().timestamp();
<< msg2.signer().timestamp();
} else { } else {
qDebug() << "Message was not signed"; qDebug() << "Message was not signed";
} }
@ -166,8 +160,7 @@ int main(int argc, char** argv)
signing.waitForFinished(1000); signing.waitForFinished(1000);
// check to see if it worked // check to see if it worked
if(!signing.success()) if (!signing.success()) {
{
qWarning() << "Error signing: " << signing.errorCode(); qWarning() << "Error signing: " << signing.errorCode();
return 1; return 1;
} }
@ -180,7 +173,6 @@ int main(int argc, char** argv)
qDebug() << "Message uses" << signing.hashName() << "hashing algorithm"; qDebug() << "Message uses" << signing.hashName() << "hashing algorithm";
qDebug(); qDebug();
// Now we go back to the first CMS, and re-use that. // Now we go back to the first CMS, and re-use that.
QCA::SecureMessage verifying(&cms); QCA::SecureMessage verifying(&cms);
@ -193,8 +185,7 @@ int main(int argc, char** argv)
verifying.waitForFinished(1000); verifying.waitForFinished(1000);
// check to see if it worked // check to see if it worked
if(!verifying.success()) if (!verifying.success()) {
{
qWarning() << "Error verifying: " << verifying.errorCode(); qWarning() << "Error verifying: " << verifying.errorCode();
return 1; return 1;
} }
@ -203,8 +194,7 @@ int main(int argc, char** argv)
sign = verifying.signer(); sign = verifying.signer();
// todo: dump some data out about the signer // todo: dump some data out about the signer
if(verifying.verifySuccess()) if (verifying.verifySuccess()) {
{
qDebug() << "Message verified"; qDebug() << "Message verified";
} else { } else {
qDebug() << "Message failed to verify:" << verifying.errorCode(); qDebug() << "Message failed to verify:" << verifying.errorCode();
@ -212,4 +202,3 @@ int main(int argc, char** argv)
return 0; return 0;
} }

View File

@ -21,11 +21,11 @@
#include "certitem.h" #include "certitem.h"
#include <QtCore>
#include <QtGui>
#include <QtCrypto>
#include <QMessageBox>
#include "prompter.h" #include "prompter.h"
#include <QMessageBox>
#include <QtCore>
#include <QtCrypto>
#include <QtGui>
typedef QMap<CertItemStore::IconType, QPixmap> CertItemIconset; typedef QMap<CertItemStore::IconType, QPixmap> CertItemIconset;
@ -40,15 +40,14 @@ private:
QMap<QString, QCA::SecureArray> maybe; QMap<QString, QCA::SecureArray> maybe;
public: public:
MyPrompter(QObject *parent = 0) : MyPrompter(QObject *parent = 0)
Prompter(parent) : Prompter(parent)
{ {
} }
void fileSuccess(const QString &fileName) void fileSuccess(const QString &fileName)
{ {
if(maybe.contains(fileName)) if (maybe.contains(fileName)) {
{
known[fileName] = maybe[fileName]; known[fileName] = maybe[fileName];
maybe.remove(fileName); maybe.remove(fileName);
} }
@ -82,8 +81,7 @@ protected:
static QString escape(const QString &in) static QString escape(const QString &in)
{ {
QString out; QString out;
for(int n = 0; n < in.length(); ++n) for (int n = 0; n < in.length(); ++n) {
{
if (in[n] == '\\') if (in[n] == '\\')
out += "\\\\"; out += "\\\\";
else if (in[n] == ':') else if (in[n] == ':')
@ -99,12 +97,9 @@ static QString escape(const QString &in)
static QString unescape(const QString &in) static QString unescape(const QString &in)
{ {
QString out; QString out;
for(int n = 0; n < in.length(); ++n) for (int n = 0; n < in.length(); ++n) {
{ if (in[n] == '\\') {
if(in[n] == '\\') if (n + 1 < in.length()) {
{
if(n + 1 < in.length())
{
++n; ++n;
if (in[n] == '\\') if (in[n] == '\\')
out += '\\'; out += '\\';
@ -113,8 +108,7 @@ static QString unescape(const QString &in)
else if (in[n] == 'n') else if (in[n] == 'n')
out += '\n'; out += '\n';
} }
} } else
else
out += in[n]; out += in[n];
} }
return out; return out;
@ -133,10 +127,10 @@ public:
QCA::KeyStoreEntry keyStoreEntry; QCA::KeyStoreEntry keyStoreEntry;
QString keyStoreEntryString; QString keyStoreEntryString;
Private() : Private()
havePrivate(false), : havePrivate(false)
storageType(File), , storageType(File)
usable(false) , usable(false)
{ {
} }
@ -149,14 +143,11 @@ public:
foreach (const QCA::Certificate &cert, chain) foreach (const QCA::Certificate &cert, chain)
parts += QCA::Base64().arrayToString(cert.toDER()); parts += QCA::Base64().arrayToString(cert.toDER());
if(havePrivate) if (havePrivate) {
{ if (storageType == File) {
if(storageType == File)
{
parts += "privateFile"; parts += "privateFile";
parts += fileName; parts += fileName;
} } else // KeyStoreEntry
else // KeyStoreEntry
{ {
parts += "privateEntry"; parts += "privateEntry";
if (!keyStoreEntry.isNull()) if (!keyStoreEntry.isNull())
@ -173,7 +164,7 @@ public:
bool fromString(const QString &in) bool fromString(const QString &in)
{ {
QStringList parts = in.split(':'); const QStringList parts = in.split(':');
for (int n = 0; n < parts.count(); ++n) for (int n = 0; n < parts.count(); ++n)
parts[n] = unescape(parts[n]); parts[n] = unescape(parts[n]);
@ -185,8 +176,7 @@ public:
if (chainCount < 1 || chainCount > parts.count() - 2) if (chainCount < 1 || chainCount > parts.count() - 2)
return false; return false;
chain.clear(); chain.clear();
for(int n = 0; n < chainCount; ++n) for (int n = 0; n < chainCount; ++n) {
{
QCA::Certificate cert = QCA::Certificate::fromDER(QCA::Base64().stringToArray(parts[n + 2]).toByteArray()); QCA::Certificate cert = QCA::Certificate::fromDER(QCA::Base64().stringToArray(parts[n + 2]).toByteArray());
if (cert.isNull()) if (cert.isNull())
return false; return false;
@ -194,27 +184,22 @@ public:
} }
int at = chain.count() + 2; int at = chain.count() + 2;
if(at < parts.count()) if (at < parts.count()) {
{
havePrivate = true; havePrivate = true;
usable = false; usable = false;
if(parts[at] == "privateFile") if (parts[at] == "privateFile") {
{
storageType = File; storageType = File;
fileName = parts[at + 1]; fileName = parts[at + 1];
if (QFile::exists(fileName)) if (QFile::exists(fileName))
usable = true; usable = true;
} } else if (parts[at] == "privateEntry") {
else if(parts[at] == "privateEntry")
{
storageType = KeyStore; storageType = KeyStore;
keyStoreEntryString = parts[at + 1]; keyStoreEntryString = parts[at + 1];
keyStoreEntry = QCA::KeyStoreEntry(keyStoreEntryString); keyStoreEntry = QCA::KeyStoreEntry(keyStoreEntryString);
if (!keyStoreEntry.isNull()) if (!keyStoreEntry.isNull())
usable = true; usable = true;
} } else
else
return false; return false;
} }
@ -226,8 +211,8 @@ CertItem::CertItem()
{ {
} }
CertItem::CertItem(const CertItem &from) : CertItem::CertItem(const CertItem &from)
d(from.d) : d(from.d)
{ {
} }
@ -294,18 +279,16 @@ public:
QList<LoaderItem> loaders; QList<LoaderItem> loaders;
CertItemStorePrivate(CertItemStore *_q) : CertItemStorePrivate(CertItemStore *_q)
QObject(_q), : QObject(_q)
q(_q), , q(_q)
next_id(0), , next_id(0)
next_req_id(0) , next_req_id(0)
{
if(!g_prompter)
{ {
if (!g_prompter) {
g_prompter = new MyPrompter; g_prompter = new MyPrompter;
g_prompter_refs = 1; g_prompter_refs = 1;
} } else
else
++g_prompter_refs; ++g_prompter_refs;
prompter = g_prompter; prompter = g_prompter;
@ -317,8 +300,7 @@ public:
delete i.keyLoader; delete i.keyLoader;
--g_prompter_refs; --g_prompter_refs;
if(g_prompter_refs == 0) if (g_prompter_refs == 0) {
{
delete g_prompter; delete g_prompter;
g_prompter = 0; g_prompter = 0;
} }
@ -327,8 +309,7 @@ public:
QString getUniqueName(const QString &name) QString getUniqueName(const QString &name)
{ {
int num = 1; int num = 1;
while(1) while (1) {
{
QString tryname; QString tryname;
if (num == 1) if (num == 1)
tryname = name; tryname = name;
@ -336,10 +317,8 @@ public:
tryname = name + QString(" (%1)").arg(num); tryname = name + QString(" (%1)").arg(num);
bool found = false; bool found = false;
foreach(const CertItem &i, list) foreach (const CertItem &i, list) {
{ if (i.name() == tryname) {
if(i.name() == tryname)
{
found = true; found = true;
break; break;
} }
@ -354,26 +333,27 @@ public:
static QString convertErrorToString(QCA::ConvertResult r) static QString convertErrorToString(QCA::ConvertResult r)
{ {
QString str; QString str;
switch(r) switch (r) {
{ case QCA::ConvertGood:
case QCA::ConvertGood: break; break;
case QCA::ErrorPassphrase: str = tr("Incorrect passphrase."); case QCA::ErrorPassphrase:
case QCA::ErrorFile: str = tr("Unable to open or read file."); str = tr("Incorrect passphrase.");
case QCA::ErrorFile:
str = tr("Unable to open or read file.");
case QCA::ErrorDecode: case QCA::ErrorDecode:
default: str = tr("Unable to decode format."); default:
str = tr("Unable to decode format.");
} }
return str; return str;
} }
public slots: public Q_SLOTS:
void loader_finished() void loader_finished()
{ {
QCA::KeyLoader *keyLoader = (QCA::KeyLoader *)sender(); QCA::KeyLoader *keyLoader = (QCA::KeyLoader *)sender();
int at = -1; int at = -1;
for(int n = 0; n < loaders.count(); ++n) for (int n = 0; n < loaders.count(); ++n) {
{ if (loaders[n].keyLoader == keyLoader) {
if(loaders[n].keyLoader == keyLoader)
{
at = n; at = n;
break; break;
} }
@ -385,11 +365,12 @@ public slots:
loaders.removeAt(at); loaders.removeAt(at);
QCA::ConvertResult r = keyLoader->convertResult(); QCA::ConvertResult r = keyLoader->convertResult();
if(r != QCA::ConvertGood) if (r != QCA::ConvertGood) {
{
delete keyLoader; delete keyLoader;
prompter->fileFailed(fileName); prompter->fileFailed(fileName);
QMessageBox::information(0, tr("Error"), QMessageBox::information(
0,
tr("Error"),
tr("Error importing certificate and private key.\nReason: %1").arg(convertErrorToString(r))); tr("Error importing certificate and private key.\nReason: %1").arg(convertErrorToString(r)));
emit q->addFailed(req_id); emit q->addFailed(req_id);
return; return;
@ -425,8 +406,8 @@ public slots:
} }
}; };
CertItemStore::CertItemStore(QObject *parent) : CertItemStore::CertItemStore(QObject *parent)
QAbstractListModel(parent) : QAbstractListModel(parent)
{ {
d = new CertItemStorePrivate(this); d = new CertItemStorePrivate(this);
} }
@ -443,8 +424,7 @@ int CertItemStore::idFromRow(int row) const
int CertItemStore::rowFromId(int id) const int CertItemStore::rowFromId(int id) const
{ {
for(int n = 0; n < d->idList.count(); ++n) for (int n = 0; n < d->idList.count(); ++n) {
{
if (d->idList[n] == id) if (d->idList[n] == id)
return n; return n;
} }
@ -478,12 +458,10 @@ bool CertItemStore::load(const QStringList &in)
{ {
QList<CertItem> addList; QList<CertItem> addList;
QList<int> addIdList; QList<int> addIdList;
foreach(const QString &s, in) foreach (const QString &s, in) {
{
CertItem i; CertItem i;
i.d = new CertItem::Private; i.d = new CertItem::Private;
if(i.d->fromString(s)) if (i.d->fromString(s)) {
{
addList += i; addList += i;
addIdList += d->next_id++; addIdList += d->next_id++;
} }
@ -603,23 +581,19 @@ QVariant CertItemStore::data(const QModelIndex &index, int role) const
if (at >= list.count()) if (at >= list.count())
return QVariant(); return QVariant();
if(role == Qt::DisplayRole) if (role == Qt::DisplayRole) {
{
QString str = list[at].name(); QString str = list[at].name();
if (list[at].havePrivate() && !list[at].isUsable()) if (list[at].havePrivate() && !list[at].isUsable())
str += QString(" ") + tr("(not usable)"); str += QString(" ") + tr("(not usable)");
return str; return str;
} } else if (role == Qt::EditRole)
else if(role == Qt::EditRole)
return list[at].name(); return list[at].name();
else if(role == Qt::DecorationRole) else if (role == Qt::DecorationRole) {
{
if (list[at].havePrivate()) if (list[at].havePrivate())
return d->iconset[CertItemStore::IconKeyBundle]; return d->iconset[CertItemStore::IconKeyBundle];
else else
return d->iconset[CertItemStore::IconCert]; return d->iconset[CertItemStore::IconCert];
} } else
else
return QVariant(); return QVariant();
} }
@ -633,8 +607,7 @@ Qt::ItemFlags CertItemStore::flags(const QModelIndex &index) const
bool CertItemStore::setData(const QModelIndex &index, const QVariant &value, int role) bool CertItemStore::setData(const QModelIndex &index, const QVariant &value, int role)
{ {
if(index.isValid() && role == Qt::EditRole) if (index.isValid() && role == Qt::EditRole) {
{
QString str = value.toString(); QString str = value.toString();
d->list[index.row()].d->name = str; d->list[index.row()].d->name = str;
emit dataChanged(index, index); emit dataChanged(index, index);
@ -656,22 +629,23 @@ public:
QString fileName; QString fileName;
QCA::PrivateKey key; QCA::PrivateKey key;
CertItemPrivateLoaderPrivate(CertItemPrivateLoader *_q) : CertItemPrivateLoaderPrivate(CertItemPrivateLoader *_q)
QObject(_q), : QObject(_q)
q(_q) , q(_q)
{ {
} }
public slots: public Q_SLOTS:
void loader_finished() void loader_finished()
{ {
QCA::ConvertResult r = loader->convertResult(); QCA::ConvertResult r = loader->convertResult();
if(r != QCA::ConvertGood) if (r != QCA::ConvertGood) {
{
delete loader; delete loader;
loader = 0; loader = 0;
store->d->prompter->fileFailed(fileName); store->d->prompter->fileFailed(fileName);
QMessageBox::information(0, tr("Error"), QMessageBox::information(
0,
tr("Error"),
tr("Error accessing private key.\nReason: %1").arg(CertItemStorePrivate::convertErrorToString(r))); tr("Error accessing private key.\nReason: %1").arg(CertItemStorePrivate::convertErrorToString(r)));
emit q->finished(); emit q->finished();
return; return;
@ -686,8 +660,8 @@ public slots:
} }
}; };
CertItemPrivateLoader::CertItemPrivateLoader(CertItemStore *store, QObject *parent) : CertItemPrivateLoader::CertItemPrivateLoader(CertItemStore *store, QObject *parent)
QObject(parent) : QObject(parent)
{ {
d = new CertItemPrivateLoaderPrivate(this); d = new CertItemPrivateLoaderPrivate(this);
d->store = store; d->store = store;
@ -702,8 +676,7 @@ void CertItemPrivateLoader::start(int id)
{ {
CertItem i = d->store->itemFromId(id); CertItem i = d->store->itemFromId(id);
if(i.storageType() == CertItem::KeyStore) if (i.storageType() == CertItem::KeyStore) {
{
d->key = i.d->keyStoreEntry.keyBundle().privateKey(); d->key = i.d->keyStoreEntry.keyBundle().privateKey();
QMetaObject::invokeMethod(this, "finished", Qt::QueuedConnection); QMetaObject::invokeMethod(this, "finished", Qt::QueuedConnection);
return; return;

View File

@ -28,8 +28,7 @@
class QString; class QString;
class QStringList; class QStringList;
namespace QCA namespace QCA {
{
class PrivateKey; class PrivateKey;
class CertificateChain; class CertificateChain;
class KeyStoreEntry; class KeyStoreEntry;
@ -82,7 +81,7 @@ public:
IconPgpSec IconPgpSec
}; };
CertItemStore(QObject *parent = 0); CertItemStore(QObject *parent = nullptr);
~CertItemStore(); ~CertItemStore();
int idFromRow(int row) const; int idFromRow(int row) const;
@ -112,7 +111,7 @@ public:
Qt::ItemFlags flags(const QModelIndex &index) const; Qt::ItemFlags flags(const QModelIndex &index) const;
bool setData(const QModelIndex &index, const QVariant &value, int role); bool setData(const QModelIndex &index, const QVariant &value, int role);
signals: Q_SIGNALS:
void addSuccess(int reqId, int id); void addSuccess(int reqId, int id);
void addFailed(int reqId); void addFailed(int reqId);
@ -128,14 +127,14 @@ class CertItemPrivateLoader : public QObject
{ {
Q_OBJECT Q_OBJECT
public: public:
explicit CertItemPrivateLoader(CertItemStore *store, QObject *parent = 0); explicit CertItemPrivateLoader(CertItemStore *store, QObject *parent = nullptr);
~CertItemPrivateLoader(); ~CertItemPrivateLoader();
void start(int id); void start(int id);
QCA::PrivateKey privateKey() const; QCA::PrivateKey privateKey() const;
signals: Q_SIGNALS:
void finished(); void finished();
private: private:

View File

@ -21,10 +21,10 @@
#include "certviewdlg.h" #include "certviewdlg.h"
#include <QtCore>
#include <QtGui>
#include <QtCrypto>
#include "ui_certview.h" #include "ui_certview.h"
#include <QtCore>
#include <QtCrypto>
#include <QtGui>
// from qcatool // from qcatool
class InfoType class InfoType
@ -40,12 +40,16 @@ public:
{ {
} }
InfoType(QCA::CertificateInfoType _type, const QString &_varname, const QString &_shortname, const QString &_name, const QString &_desc) : InfoType(QCA::CertificateInfoType _type,
type(_type), const QString & _varname,
varname(_varname), const QString & _shortname,
shortname(_shortname), const QString & _name,
name(_name), const QString & _desc)
desc(_desc) : type(_type)
, varname(_varname)
, shortname(_shortname)
, name(_name)
, desc(_desc)
{ {
} }
}; };
@ -53,18 +57,35 @@ public:
static QList<InfoType> makeInfoTypeList(bool legacyEmail = false) static QList<InfoType> makeInfoTypeList(bool legacyEmail = false)
{ {
QList<InfoType> out; QList<InfoType> out;
out += InfoType(QCA::CommonName, "CommonName", "CN", CertViewDlg::tr("Common Name (CN)"), "Full name, domain, anything"); out += InfoType(
QCA::CommonName, "CommonName", "CN", CertViewDlg::tr("Common Name (CN)"), "Full name, domain, anything");
out += InfoType(QCA::Email, "Email", "", CertViewDlg::tr("Email Address"), ""); out += InfoType(QCA::Email, "Email", "", CertViewDlg::tr("Email Address"), "");
if (legacyEmail) if (legacyEmail)
out += InfoType(QCA::EmailLegacy, "EmailLegacy", "", CertViewDlg::tr("PKCS#9 Email Address"), ""); out += InfoType(QCA::EmailLegacy, "EmailLegacy", "", CertViewDlg::tr("PKCS#9 Email Address"), "");
out += InfoType(QCA::Organization, "Organization", "O", CertViewDlg::tr("Organization (O)"), "Company, group, etc"); out += InfoType(QCA::Organization, "Organization", "O", CertViewDlg::tr("Organization (O)"), "Company, group, etc");
out += InfoType(QCA::OrganizationalUnit, "OrganizationalUnit", "OU", CertViewDlg::tr("Organizational Unit (OU)"), "Division/branch of organization"); out += InfoType(QCA::OrganizationalUnit,
"OrganizationalUnit",
"OU",
CertViewDlg::tr("Organizational Unit (OU)"),
"Division/branch of organization");
out += InfoType(QCA::Locality, "Locality", "", CertViewDlg::tr("Locality (L)"), "City, shire, part of a state"); out += InfoType(QCA::Locality, "Locality", "", CertViewDlg::tr("Locality (L)"), "City, shire, part of a state");
out += InfoType(QCA::State, "State", "", CertViewDlg::tr("State (ST)"), "State within the country"); out += InfoType(QCA::State, "State", "", CertViewDlg::tr("State (ST)"), "State within the country");
out += InfoType(QCA::Country, "Country", "C", CertViewDlg::tr("Country Code (C)"), "2-letter code"); out += InfoType(QCA::Country, "Country", "C", CertViewDlg::tr("Country Code (C)"), "2-letter code");
out += InfoType(QCA::IncorporationLocality, "IncorporationLocality", "", CertViewDlg::tr("Incorporation Locality"), "For EV certificates"); out += InfoType(QCA::IncorporationLocality,
out += InfoType(QCA::IncorporationState, "IncorporationState", "", CertViewDlg::tr("Incorporation State"), "For EV certificates"); "IncorporationLocality",
out += InfoType(QCA::IncorporationCountry, "IncorporationCountry", "", CertViewDlg::tr("Incorporation Country"), "For EV certificates"); "",
CertViewDlg::tr("Incorporation Locality"),
"For EV certificates");
out += InfoType(QCA::IncorporationState,
"IncorporationState",
"",
CertViewDlg::tr("Incorporation State"),
"For EV certificates");
out += InfoType(QCA::IncorporationCountry,
"IncorporationCountry",
"",
CertViewDlg::tr("Incorporation Country"),
"For EV certificates");
out += InfoType(QCA::URI, "URI", "", CertViewDlg::tr("URI"), ""); out += InfoType(QCA::URI, "URI", "", CertViewDlg::tr("URI"), "");
out += InfoType(QCA::DNS, "DNS", "", CertViewDlg::tr("Domain Name"), "Domain (dnsName)"); out += InfoType(QCA::DNS, "DNS", "", CertViewDlg::tr("Domain Name"), "Domain (dnsName)");
out += InfoType(QCA::IPAddress, "IPAddress", "", CertViewDlg::tr("IP Adddress"), ""); out += InfoType(QCA::IPAddress, "IPAddress", "", CertViewDlg::tr("IP Adddress"), "");
@ -75,8 +96,7 @@ static QList<InfoType> makeInfoTypeList(bool legacyEmail = false)
static QString try_print_info(const QString &name, const QStringList &values) static QString try_print_info(const QString &name, const QStringList &values)
{ {
QString out; QString out;
if(!values.isEmpty()) if (!values.isEmpty()) {
{
QString value = values.join(", "); QString value = values.join(", ");
out = QString(" ") + CertViewDlg::tr("%1: %2").arg(name, value) + '\n'; out = QString(" ") + CertViewDlg::tr("%1: %2").arg(name, value) + '\n';
} }
@ -113,9 +133,9 @@ public:
Ui_CertView ui; Ui_CertView ui;
QCA::CertificateChain chain; QCA::CertificateChain chain;
Private(CertViewDlg *_q) : Private(CertViewDlg *_q)
QObject(_q), : QObject(_q)
q(_q) , q(_q)
{ {
ui.setupUi(q); ui.setupUi(q);
connect(ui.cb_chain, SIGNAL(activated(int)), SLOT(cb_activated(int))); connect(ui.cb_chain, SIGNAL(activated(int)), SLOT(cb_activated(int)));
@ -134,8 +154,7 @@ public:
void updateInfo() void updateInfo()
{ {
int x = ui.cb_chain->currentIndex(); int x = ui.cb_chain->currentIndex();
if(x == -1) if (x == -1) {
{
ui.lb_info->setText(""); ui.lb_info->setText("");
return; return;
} }
@ -143,15 +162,15 @@ public:
ui.lb_info->setText(cert_info_string(chain[x])); ui.lb_info->setText(cert_info_string(chain[x]));
} }
private slots: private Q_SLOTS:
void cb_activated(int) void cb_activated(int)
{ {
updateInfo(); updateInfo();
} }
}; };
CertViewDlg::CertViewDlg(const QCA::CertificateChain &chain, QWidget *parent) : CertViewDlg::CertViewDlg(const QCA::CertificateChain &chain, QWidget *parent)
QDialog(parent) : QDialog(parent)
{ {
d = new Private(this); d = new Private(this);
d->chain = chain; d->chain = chain;

View File

@ -24,8 +24,7 @@
#include <QDialog> #include <QDialog>
namespace QCA namespace QCA {
{
class CertificateChain; class CertificateChain;
} }

View File

@ -21,13 +21,13 @@
#include "keyselectdlg.h" #include "keyselectdlg.h"
#include <QtCore> #include "ui_keyselect.h"
#include <QtGui>
#include <QtCrypto>
#include <QPushButton>
#include <QMenu> #include <QMenu>
#include <QMessageBox> #include <QMessageBox>
#include "ui_keyselect.h" #include <QPushButton>
#include <QtCore>
#include <QtCrypto>
#include <QtGui>
#define ONLY_SHOW_KEYBUNDLE #define ONLY_SHOW_KEYBUNDLE
@ -63,14 +63,24 @@ public:
if (!_shared) if (!_shared)
return out; return out;
const KeyStoreIconset &iconset = _shared->iconset; const KeyStoreIconset &iconset = _shared->iconset;
switch(type) switch (type) {
{ case QCA::KeyStoreEntry::TypeKeyBundle:
case QCA::KeyStoreEntry::TypeKeyBundle: out = iconset[KeySelectDlg::IconKeyBundle]; break; out = iconset[KeySelectDlg::IconKeyBundle];
case QCA::KeyStoreEntry::TypeCertificate: out = iconset[KeySelectDlg::IconCert]; break; break;
case QCA::KeyStoreEntry::TypeCRL: out = iconset[KeySelectDlg::IconCrl]; break; case QCA::KeyStoreEntry::TypeCertificate:
case QCA::KeyStoreEntry::TypePGPSecretKey: out = iconset[KeySelectDlg::IconPgpSec]; break; out = iconset[KeySelectDlg::IconCert];
case QCA::KeyStoreEntry::TypePGPPublicKey: out = iconset[KeySelectDlg::IconPgpPub]; break; break;
default: break; case QCA::KeyStoreEntry::TypeCRL:
out = iconset[KeySelectDlg::IconCrl];
break;
case QCA::KeyStoreEntry::TypePGPSecretKey:
out = iconset[KeySelectDlg::IconPgpSec];
break;
case QCA::KeyStoreEntry::TypePGPPublicKey:
out = iconset[KeySelectDlg::IconPgpPub];
break;
default:
break;
} }
return out; return out;
} }
@ -81,9 +91,9 @@ public:
QCA::KeyStore * keyStore; QCA::KeyStore * keyStore;
QCA::KeyStoreEntry keyStoreEntry; QCA::KeyStoreEntry keyStoreEntry;
KeyStoreItem(Type type, KeyStoreItemShared *shared) : KeyStoreItem(Type type, KeyStoreItemShared *shared)
_type(type), : _type(type)
_shared(shared) , _shared(shared)
{ {
setFlags(Qt::ItemIsEnabled | Qt::ItemIsSelectable); setFlags(Qt::ItemIsEnabled | Qt::ItemIsSelectable);
} }
@ -104,33 +114,23 @@ public:
virtual QVariant data(int role) const virtual QVariant data(int role) const
{ {
if(role == Qt::DisplayRole) if (role == Qt::DisplayRole) {
{ if (_type == Store) {
if(_type == Store)
{
return data(NameRole).toString(); return data(NameRole).toString();
} } else if (_type == Entry) {
else if(_type == Entry)
{
QString str = data(NameRole).toString(); QString str = data(NameRole).toString();
if (_shared && !data(AvailabilityRole).toBool()) if (_shared && !data(AvailabilityRole).toBool())
str += QString(" ") + _shared->notAvailableString; str += QString(" ") + _shared->notAvailableString;
return str; return str;
} } else
else
return QStandardItem::data(role); return QStandardItem::data(role);
} } else if (role == Qt::DecorationRole) {
else if(role == Qt::DecorationRole) if (_type == Entry) {
{
if(_type == Entry)
{
QCA::KeyStoreEntry::Type type = (QCA::KeyStoreEntry::Type)data(SubTypeRole).toInt(); QCA::KeyStoreEntry::Type type = (QCA::KeyStoreEntry::Type)data(SubTypeRole).toInt();
return entryTypeToIcon(type); return entryTypeToIcon(type);
} } else
else
return QStandardItem::data(role); return QStandardItem::data(role);
} } else
else
return QStandardItem::data(role); return QStandardItem::data(role);
} }
@ -153,8 +153,9 @@ public:
QCA::KeyStoreManager ksm; QCA::KeyStoreManager ksm;
KeyStoreModel(QObject *parent = 0) : KeyStoreModel(QObject *parent = 0)
QStandardItemModel(parent), ksm(this) : QStandardItemModel(parent)
, ksm(this)
{ {
shared.notAvailableString = tr("(not available)"); shared.notAvailableString = tr("(not available)");
@ -171,8 +172,7 @@ public:
KeyStoreItem *itemFromStore(QCA::KeyStore *ks) const KeyStoreItem *itemFromStore(QCA::KeyStore *ks) const
{ {
for(int n = 0; n < rowCount(); ++n) for (int n = 0; n < rowCount(); ++n) {
{
KeyStoreItem *i = (KeyStoreItem *)item(n); KeyStoreItem *i = (KeyStoreItem *)item(n);
if (i->keyStore == ks) if (i->keyStore == ks)
return i; return i;
@ -180,7 +180,7 @@ public:
return 0; return 0;
} }
private slots: private Q_SLOTS:
void ks_available(const QString &keyStoreId) void ks_available(const QString &keyStoreId)
{ {
QCA::KeyStore *ks = new QCA::KeyStore(keyStoreId, &ksm); QCA::KeyStore *ks = new QCA::KeyStore(keyStoreId, &ksm);
@ -211,10 +211,8 @@ private slots:
#ifdef ONLY_SHOW_KEYBUNDLE #ifdef ONLY_SHOW_KEYBUNDLE
// ignore entries that are not keybundles // ignore entries that are not keybundles
for(int n = 0; n < newEntries.count(); ++n) for (int n = 0; n < newEntries.count(); ++n) {
{ if (newEntries[n].type() != QCA::KeyStoreEntry::TypeKeyBundle) {
if(newEntries[n].type() != QCA::KeyStoreEntry::TypeKeyBundle)
{
newEntries.removeAt(n); newEntries.removeAt(n);
--n; // adjust position --n; // adjust position
} }
@ -225,57 +223,48 @@ private slots:
store_item->setStore(ks->name(), ks->type()); store_item->setStore(ks->name(), ks->type());
// handle removed child entries // handle removed child entries
for(int n = 0; n < store_item->rowCount(); ++n) for (int n = 0; n < store_item->rowCount(); ++n) {
{
KeyStoreItem *i = (KeyStoreItem *)store_item->child(n); KeyStoreItem *i = (KeyStoreItem *)store_item->child(n);
// is the existing entry in the new list? // is the existing entry in the new list?
bool found = false; bool found = false;
foreach(const QCA::KeyStoreEntry &ne, newEntries) foreach (const QCA::KeyStoreEntry &ne, newEntries) {
{ if (ne.id() == i->keyStoreEntry.id()) {
if(ne.id() == i->keyStoreEntry.id())
{
found = true; found = true;
break; break;
} }
} }
// if not, remove it // if not, remove it
if(!found) if (!found) {
{
store_item->removeRow(n); store_item->removeRow(n);
--n; // adjust position --n; // adjust position
} }
} }
// handle added/updated child entries // handle added/updated child entries
for(int n = 0; n < newEntries.count(); ++n) for (int n = 0; n < newEntries.count(); ++n) {
{
const QCA::KeyStoreEntry &ne = newEntries[n]; const QCA::KeyStoreEntry &ne = newEntries[n];
// was this entry in the original list? // was this entry in the original list?
KeyStoreItem *entry_item = 0; KeyStoreItem *entry_item = 0;
for(int k = 0; k < store_item->rowCount(); ++k) for (int k = 0; k < store_item->rowCount(); ++k) {
{
KeyStoreItem *i = (KeyStoreItem *)store_item->child(k); KeyStoreItem *i = (KeyStoreItem *)store_item->child(k);
if(i->keyStoreEntry.id() == ne.id()) if (i->keyStoreEntry.id() == ne.id()) {
{
entry_item = i; entry_item = i;
break; break;
} }
} }
// if not, add it // if not, add it
if(!entry_item) if (!entry_item) {
{
entry_item = new KeyStoreItem(KeyStoreItem::Entry, &shared); entry_item = new KeyStoreItem(KeyStoreItem::Entry, &shared);
entry_item->keyStoreEntry = ne; entry_item->keyStoreEntry = ne;
entry_item->setEntry(newEntries[n].name(), newEntries[n].type(), newEntries[n].isAvailable(), n); entry_item->setEntry(newEntries[n].name(), newEntries[n].type(), newEntries[n].isAvailable(), n);
store_item->appendRow(entry_item); store_item->appendRow(entry_item);
} }
// if so, update it // if so, update it
else else {
{
entry_item->keyStoreEntry = ne; entry_item->keyStoreEntry = ne;
entry_item->setEntry(newEntries[n].name(), newEntries[n].type(), newEntries[n].isAvailable(), n); entry_item->setEntry(newEntries[n].name(), newEntries[n].type(), newEntries[n].isAvailable(), n);
} }
@ -306,9 +295,9 @@ public:
QCA::KeyStoreEntry cur_entry; QCA::KeyStoreEntry cur_entry;
QAction * actionView; QAction * actionView;
Private(KeySelectDlg *_q) : Private(KeySelectDlg *_q)
QObject(_q), : QObject(_q)
q(_q) , q(_q)
{ {
ui.setupUi(q); ui.setupUi(q);
@ -322,15 +311,19 @@ public:
ui.buttonBox->button(QDialogButtonBox::Ok)->setEnabled(false); ui.buttonBox->button(QDialogButtonBox::Ok)->setEnabled(false);
ui.lv_stores->setModel(model); ui.lv_stores->setModel(model);
ui.lv_stores->setContextMenuPolicy(Qt::CustomContextMenu); ui.lv_stores->setContextMenuPolicy(Qt::CustomContextMenu);
connect(ui.lv_stores->selectionModel(), SIGNAL(selectionChanged(const QItemSelection &, const QItemSelection &)), SLOT(stores_selectionChanged(const QItemSelection &, const QItemSelection &))); connect(ui.lv_stores->selectionModel(),
connect(ui.lv_stores, SIGNAL(customContextMenuRequested(const QPoint &)), SLOT(stores_customContextMenuRequested(const QPoint &))); SIGNAL(selectionChanged(const QItemSelection &, const QItemSelection &)),
SLOT(stores_selectionChanged(const QItemSelection &, const QItemSelection &)));
connect(ui.lv_stores,
SIGNAL(customContextMenuRequested(const QPoint &)),
SLOT(stores_customContextMenuRequested(const QPoint &)));
actionView = new QAction(tr("&View"), this); actionView = new QAction(tr("&View"), this);
connect(actionView, SIGNAL(triggered()), SLOT(view())); connect(actionView, SIGNAL(triggered()), SLOT(view()));
actionView->setEnabled(false); actionView->setEnabled(false);
} }
private slots: private Q_SLOTS:
void ksm_busyStarted() void ksm_busyStarted()
{ {
ui.lb_busy->setText(tr("Looking for devices...")); ui.lb_busy->setText(tr("Looking for devices..."));
@ -346,19 +339,16 @@ private slots:
Q_UNUSED(deselected); Q_UNUSED(deselected);
KeyStoreItem *i = 0; KeyStoreItem *i = 0;
if(!selected.indexes().isEmpty()) if (!selected.indexes().isEmpty()) {
{
QModelIndex index = selected.indexes().first(); QModelIndex index = selected.indexes().first();
i = (KeyStoreItem *)model->itemFromIndex(index); i = (KeyStoreItem *)model->itemFromIndex(index);
} }
bool viewable = false; bool viewable = false;
bool choosable = false; bool choosable = false;
if(i && i->type() == KeyStoreItem::Entry) if (i && i->type() == KeyStoreItem::Entry) {
{
QCA::KeyStoreEntry entry = i->keyStoreEntry; QCA::KeyStoreEntry entry = i->keyStoreEntry;
if(entry.type() == QCA::KeyStoreEntry::TypeKeyBundle) if (entry.type() == QCA::KeyStoreEntry::TypeKeyBundle) {
{
viewable = true; viewable = true;
choosable = true; choosable = true;
cur_entry = entry; cur_entry = entry;
@ -385,8 +375,7 @@ private slots:
QModelIndex index = selection.indexes().first(); QModelIndex index = selection.indexes().first();
KeyStoreItem *i = (KeyStoreItem *)model->itemFromIndex(index); KeyStoreItem *i = (KeyStoreItem *)model->itemFromIndex(index);
if(i && i->type() == KeyStoreItem::Entry) if (i && i->type() == KeyStoreItem::Entry) {
{
QMenu menu(q); QMenu menu(q);
menu.addAction(actionView); menu.addAction(actionView);
menu.exec(ui.lv_stores->viewport()->mapToGlobal(pos)); menu.exec(ui.lv_stores->viewport()->mapToGlobal(pos));
@ -399,8 +388,8 @@ private slots:
} }
}; };
KeySelectDlg::KeySelectDlg(QWidget *parent) : KeySelectDlg::KeySelectDlg(QWidget *parent)
QDialog(parent) : QDialog(parent)
{ {
d = new Private(this); d = new Private(this);
} }

View File

@ -26,8 +26,7 @@
class QPixmap; class QPixmap;
namespace QCA namespace QCA {
{
class CertificateChain; class CertificateChain;
class KeyStoreEntry; class KeyStoreEntry;
} }
@ -50,7 +49,7 @@ public:
void setIcon(IconType type, const QPixmap &icon); void setIcon(IconType type, const QPixmap &icon);
signals: Q_SIGNALS:
void selected(const QCA::KeyStoreEntry &entry); void selected(const QCA::KeyStoreEntry &entry);
void viewCertificate(const QCA::CertificateChain &chain); void viewCertificate(const QCA::CertificateChain &chain);

View File

@ -19,17 +19,17 @@
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/ */
#include <QtCore>
#include <QtGui>
#include <QtCrypto>
#include <QMessageBox>
#include <QFileDialog> #include <QFileDialog>
#include <QMessageBox>
#include <QtCore>
#include <QtCrypto>
#include <QtGui>
#include "ui_mainwin.h" #include "certitem.h"
#include "certviewdlg.h" #include "certviewdlg.h"
#include "keyselectdlg.h" #include "keyselectdlg.h"
#include "pkcs11configdlg/pkcs11configdlg.h" #include "pkcs11configdlg/pkcs11configdlg.h"
#include "certitem.h" #include "ui_mainwin.h"
#ifdef QT_STATICPLUGIN #ifdef QT_STATICPLUGIN
#include "import_plugins.h" #include "import_plugins.h"
@ -52,20 +52,19 @@ class Operation : public QObject
{ {
Q_OBJECT Q_OBJECT
public: public:
Operation(QObject *parent = 0) : Operation(QObject *parent = 0)
QObject(parent) : QObject(parent)
{ {
} }
signals: Q_SIGNALS:
void error(const QString &str); void error(const QString &str);
}; };
static QString validityToString(QCA::Validity v) static QString validityToString(QCA::Validity v)
{ {
QString s; QString s;
switch(v) switch (v) {
{
case QCA::ValidityGood: case QCA::ValidityGood:
s = Operation::tr("Validated"); s = Operation::tr("Validated");
break; break;
@ -110,8 +109,7 @@ static QString validityToString(QCA::Validity v)
static QString smErrorToString(QCA::SecureMessage::Error e) static QString smErrorToString(QCA::SecureMessage::Error e)
{ {
QString s; QString s;
switch(e) switch (e) {
{
case QCA::SecureMessage::ErrorPassphrase: case QCA::SecureMessage::ErrorPassphrase:
s = Operation::tr("Invalid passphrase."); s = Operation::tr("Invalid passphrase.");
break; break;
@ -150,8 +148,7 @@ static QString smErrorToString(QCA::SecureMessage::Error e)
static QString smsIdentityToString(const QCA::SecureMessageSignature &sig) static QString smsIdentityToString(const QCA::SecureMessageSignature &sig)
{ {
QString s; QString s;
switch(sig.identityResult()) switch (sig.identityResult()) {
{
case QCA::SecureMessageSignature::Valid: case QCA::SecureMessageSignature::Valid:
break; break;
case QCA::SecureMessageSignature::InvalidSignature: case QCA::SecureMessageSignature::InvalidSignature:
@ -183,32 +180,31 @@ private:
int pending; int pending;
public: public:
SignOperation(const QByteArray &_in, CertItemStore *_store, int _id, QCA::CMS *_cms, QObject *parent = 0) : SignOperation(const QByteArray &_in, CertItemStore *_store, int _id, QCA::CMS *_cms, QObject *parent = 0)
Operation(parent), : Operation(parent)
in(_in), , in(_in)
store(_store), , store(_store)
id(_id), , id(_id)
cms(_cms), , cms(_cms)
msg(0) , msg(0)
{ {
loader = new CertItemPrivateLoader(store, this); loader = new CertItemPrivateLoader(store, this);
connect(loader, SIGNAL(finished()), SLOT(loader_finished())); connect(loader, SIGNAL(finished()), SLOT(loader_finished()));
loader->start(id); loader->start(id);
} }
signals: Q_SIGNALS:
void loadError(); void loadError();
void finished(const QString &sig); void finished(const QString &sig);
private slots: private Q_SLOTS:
void loader_finished() void loader_finished()
{ {
QCA::PrivateKey privateKey = loader->privateKey(); QCA::PrivateKey privateKey = loader->privateKey();
delete loader; delete loader;
loader = 0; loader = 0;
if(privateKey.isNull()) if (privateKey.isNull()) {
{
emit loadError(); emit loadError();
return; return;
} }
@ -250,8 +246,7 @@ private slots:
void msg_finished() void msg_finished()
{ {
if(!msg->success()) if (!msg->success()) {
{
QString str = smErrorToString(msg->errorCode()); QString str = smErrorToString(msg->errorCode());
delete msg; delete msg;
msg = 0; msg = 0;
@ -278,12 +273,12 @@ private:
public: public:
QCA::SecureMessageSignature signer; QCA::SecureMessageSignature signer;
VerifyOperation(const QByteArray &_in, const QByteArray &_sig, QCA::CMS *_cms, QObject *parent = 0) : VerifyOperation(const QByteArray &_in, const QByteArray &_sig, QCA::CMS *_cms, QObject *parent = 0)
Operation(parent), : Operation(parent)
in(_in), , in(_in)
sig(_sig), , sig(_sig)
cms(_cms), , cms(_cms)
msg(0) , msg(0)
{ {
msg = new QCA::SecureMessage(cms); msg = new QCA::SecureMessage(cms);
connect(msg, SIGNAL(bytesWritten(int)), SLOT(msg_bytesWritten(int))); connect(msg, SIGNAL(bytesWritten(int)), SLOT(msg_bytesWritten(int)));
@ -295,10 +290,10 @@ public:
update(); update();
} }
signals: Q_SIGNALS:
void finished(); void finished();
private slots: private Q_SLOTS:
void update() void update()
{ {
QByteArray buf = in.mid(0, 16384 - pending); // 16k chunks QByteArray buf = in.mid(0, 16384 - pending); // 16k chunks
@ -319,8 +314,7 @@ private slots:
void msg_finished() void msg_finished()
{ {
if(!msg->success()) if (!msg->success()) {
{
QString str = smErrorToString(msg->errorCode()); QString str = smErrorToString(msg->errorCode());
delete msg; delete msg;
msg = 0; msg = 0;
@ -332,8 +326,7 @@ private slots:
delete msg; delete msg;
msg = 0; msg = 0;
if(signer.identityResult() != QCA::SecureMessageSignature::Valid) if (signer.identityResult() != QCA::SecureMessageSignature::Valid) {
{
QString str = smsIdentityToString(signer); QString str = smsIdentityToString(signer);
emit error(tr("Verification failed!\nReason: %1").arg(str)); emit error(tr("Verification failed!\nReason: %1").arg(str));
return; return;
@ -350,8 +343,7 @@ static QString get_fingerprint(const QCA::Certificate &cert)
{ {
QString hex = QCA::Hash("sha1").hashToString(cert.toDER()); QString hex = QCA::Hash("sha1").hashToString(cert.toDER());
QString out; QString out;
for(int n = 0; n < hex.count(); ++n) for (int n = 0; n < hex.count(); ++n) {
{
if (n != 0 && n % 2 == 0) if (n != 0 && n % 2 == 0)
out += ':'; out += ':';
out += hex[n]; out += hex[n];
@ -372,10 +364,10 @@ private:
int auto_import_req_id; int auto_import_req_id;
public: public:
MainWin(QWidget *parent = 0) : MainWin(QWidget *parent = 0)
QMainWindow(parent), : QMainWindow(parent)
op(0), , op(0)
auto_import_req_id(-1) , auto_import_req_id(-1)
{ {
ui.setupUi(this); ui.setupUi(this);
@ -385,7 +377,8 @@ public:
g_icons->keybundle = QPixmap(":/gfx/icons/keybundle16.png"); g_icons->keybundle = QPixmap(":/gfx/icons/keybundle16.png");
g_icons->pgppub = QPixmap(":/gfx/icons/publickey16.png"); g_icons->pgppub = QPixmap(":/gfx/icons/publickey16.png");
g_icons->pgpsec = QPixmap(":/gfx/icons/keypair16.png"); g_icons->pgpsec = QPixmap(":/gfx/icons/keypair16.png");
if(g_icons->cert.isNull() || g_icons->crl.isNull() || g_icons->keybundle.isNull() || g_icons->pgppub.isNull() || g_icons->pgpsec.isNull()) if (g_icons->cert.isNull() || g_icons->crl.isNull() || g_icons->keybundle.isNull() ||
g_icons->pgppub.isNull() || g_icons->pgpsec.isNull())
printf("Warning: not all icons loaded\n"); printf("Warning: not all icons loaded\n");
users = new CertItemStore(this); users = new CertItemStore(this);
@ -417,15 +410,21 @@ public:
ui.pb_sign->setEnabled(false); ui.pb_sign->setEnabled(false);
ui.lv_users->setModel(users); ui.lv_users->setModel(users);
connect(ui.lv_users->selectionModel(), SIGNAL(selectionChanged(const QItemSelection &, const QItemSelection &)), SLOT(users_selectionChanged(const QItemSelection &, const QItemSelection &))); connect(ui.lv_users->selectionModel(),
SIGNAL(selectionChanged(const QItemSelection &, const QItemSelection &)),
SLOT(users_selectionChanged(const QItemSelection &, const QItemSelection &)));
ui.lv_users->setContextMenuPolicy(Qt::CustomContextMenu); ui.lv_users->setContextMenuPolicy(Qt::CustomContextMenu);
connect(ui.lv_users, SIGNAL(customContextMenuRequested(const QPoint &)), SLOT(users_customContextMenuRequested(const QPoint &))); connect(ui.lv_users,
SIGNAL(customContextMenuRequested(const QPoint &)),
SLOT(users_customContextMenuRequested(const QPoint &)));
ui.lv_authorities->setModel(roots); ui.lv_authorities->setModel(roots);
ui.lv_authorities->setContextMenuPolicy(Qt::CustomContextMenu); ui.lv_authorities->setContextMenuPolicy(Qt::CustomContextMenu);
connect(ui.lv_authorities, SIGNAL(customContextMenuRequested(const QPoint &)), SLOT(roots_customContextMenuRequested(const QPoint &))); connect(ui.lv_authorities,
SIGNAL(customContextMenuRequested(const QPoint &)),
SLOT(roots_customContextMenuRequested(const QPoint &)));
cms = new QCA::CMS(this); cms = new QCA::CMS(this);
@ -474,8 +473,7 @@ public:
col.addCertificate(i.certificateChain().primary()); col.addCertificate(i.certificateChain().primary());
// user chains // user chains
foreach(const CertItem &i, users->items()) foreach (const CertItem &i, users->items()) {
{
foreach (const QCA::Certificate &cert, i.certificateChain()) foreach (const QCA::Certificate &cert, i.certificateChain())
col.addCertificate(cert); col.addCertificate(cert);
} }
@ -488,10 +486,11 @@ public:
return chain.complete(allCerts().certificates()); return chain.complete(allCerts().certificates());
} }
private slots: private Q_SLOTS:
void load_file() void load_file()
{ {
QString fileName = QFileDialog::getOpenFileName(this, tr("Open File"), QString(), tr("X.509 Identities (*.p12 *.pfx)")); QString fileName =
QFileDialog::getOpenFileName(this, tr("Open File"), QString(), tr("X.509 Identities (*.p12 *.pfx)"));
if (fileName.isEmpty()) if (fileName.isEmpty())
return; return;
@ -504,8 +503,11 @@ private slots:
KeySelectDlg *w = new KeySelectDlg(this); KeySelectDlg *w = new KeySelectDlg(this);
w->setAttribute(Qt::WA_DeleteOnClose, true); w->setAttribute(Qt::WA_DeleteOnClose, true);
w->setWindowModality(Qt::WindowModal); w->setWindowModality(Qt::WindowModal);
connect(w, SIGNAL(selected(const QCA::KeyStoreEntry &)), SLOT(load_device_finished(const QCA::KeyStoreEntry &))); connect(
connect(w, SIGNAL(viewCertificate(const QCA::CertificateChain &)), SLOT(keyselect_viewCertificate(const QCA::CertificateChain &))); w, SIGNAL(selected(const QCA::KeyStoreEntry &)), SLOT(load_device_finished(const QCA::KeyStoreEntry &)));
connect(w,
SIGNAL(viewCertificate(const QCA::CertificateChain &)),
SLOT(keyselect_viewCertificate(const QCA::CertificateChain &)));
w->setIcon(KeySelectDlg::IconCert, g_icons->cert); w->setIcon(KeySelectDlg::IconCert, g_icons->cert);
w->setIcon(KeySelectDlg::IconCrl, g_icons->crl); w->setIcon(KeySelectDlg::IconCrl, g_icons->crl);
w->setIcon(KeySelectDlg::IconKeyBundle, g_icons->keybundle); w->setIcon(KeySelectDlg::IconKeyBundle, g_icons->keybundle);
@ -521,13 +523,13 @@ private slots:
void load_root() void load_root()
{ {
QString fileName = QFileDialog::getOpenFileName(this, tr("Open File"), QString(), tr("X.509 Certificates (*.pem *.crt)")); QString fileName =
QFileDialog::getOpenFileName(this, tr("Open File"), QString(), tr("X.509 Certificates (*.pem *.crt)"));
if (fileName.isEmpty()) if (fileName.isEmpty())
return; return;
QCA::Certificate cert = QCA::Certificate::fromPEMFile(fileName); QCA::Certificate cert = QCA::Certificate::fromPEMFile(fileName);
if(cert.isNull()) if (cert.isNull()) {
{
QMessageBox::information(this, tr("Error"), tr("Error opening certificate file.")); QMessageBox::information(this, tr("Error"), tr("Error opening certificate file."));
return; return;
} }
@ -537,22 +539,24 @@ private slots:
void users_addSuccess(int req_id, int id) void users_addSuccess(int req_id, int id)
{ {
if(req_id == auto_import_req_id) if (req_id == auto_import_req_id) {
{
auto_import_req_id = -1; auto_import_req_id = -1;
CertItem i = users->itemFromId(id); CertItem i = users->itemFromId(id);
QMessageBox::information(this, tr("User added"), tr( QMessageBox::information(this,
"This signature was made by a previously unknown user, and so the " tr("User added"),
"user has now been added to the keyring as \"%1\"." tr("This signature was made by a previously unknown user, and so the "
).arg(i.name())); "user has now been added to the keyring as \"%1\".")
.arg(i.name()));
verify_next(); verify_next();
return; return;
} }
ui.lv_users->selectionModel()->select(users->index(users->rowFromId(id)), QItemSelectionModel::Clear | QItemSelectionModel::Select | QItemSelectionModel::Current); ui.lv_users->selectionModel()->select(users->index(users->rowFromId(id)),
QItemSelectionModel::Clear | QItemSelectionModel::Select |
QItemSelectionModel::Current);
setEnabled(true); setEnabled(true);
} }
@ -566,9 +570,9 @@ private slots:
void mod_config() void mod_config()
{ {
if(!Pkcs11ConfigDlg::isSupported()) if (!Pkcs11ConfigDlg::isSupported()) {
{ QMessageBox::information(
QMessageBox::information(this, tr("Error"), tr("No provider available supporting standard PKCS#11 configuration.")); this, tr("Error"), tr("No provider available supporting standard PKCS#11 configuration."));
return; return;
} }
@ -583,8 +587,7 @@ private slots:
Q_UNUSED(deselected); Q_UNUSED(deselected);
int at = -1; int at = -1;
if(!selected.indexes().isEmpty()) if (!selected.indexes().isEmpty()) {
{
QModelIndex index = selected.indexes().first(); QModelIndex index = selected.indexes().first();
at = index.row(); at = index.row();
} }
@ -601,15 +604,13 @@ private slots:
void item_view() void item_view()
{ {
if(ui.lv_users->hasFocus()) if (ui.lv_users->hasFocus()) {
{
QItemSelection selection = ui.lv_users->selectionModel()->selection(); QItemSelection selection = ui.lv_users->selectionModel()->selection();
if (selection.indexes().isEmpty()) if (selection.indexes().isEmpty())
return; return;
QModelIndex index = selection.indexes().first(); QModelIndex index = selection.indexes().first();
users_view(index.row()); users_view(index.row());
} } else // lv_authorities
else // lv_authorities
{ {
QItemSelection selection = ui.lv_authorities->selectionModel()->selection(); QItemSelection selection = ui.lv_authorities->selectionModel()->selection();
if (selection.indexes().isEmpty()) if (selection.indexes().isEmpty())
@ -621,15 +622,13 @@ private slots:
void item_rename() void item_rename()
{ {
if(ui.lv_users->hasFocus()) if (ui.lv_users->hasFocus()) {
{
QItemSelection selection = ui.lv_users->selectionModel()->selection(); QItemSelection selection = ui.lv_users->selectionModel()->selection();
if (selection.indexes().isEmpty()) if (selection.indexes().isEmpty())
return; return;
QModelIndex index = selection.indexes().first(); QModelIndex index = selection.indexes().first();
users_rename(index.row()); users_rename(index.row());
} } else // lv_authorities
else // lv_authorities
{ {
QItemSelection selection = ui.lv_authorities->selectionModel()->selection(); QItemSelection selection = ui.lv_authorities->selectionModel()->selection();
if (selection.indexes().isEmpty()) if (selection.indexes().isEmpty())
@ -641,15 +640,13 @@ private slots:
void item_remove() void item_remove()
{ {
if(ui.lv_users->hasFocus()) if (ui.lv_users->hasFocus()) {
{
QItemSelection selection = ui.lv_users->selectionModel()->selection(); QItemSelection selection = ui.lv_users->selectionModel()->selection();
if (selection.indexes().isEmpty()) if (selection.indexes().isEmpty())
return; return;
QModelIndex index = selection.indexes().first(); QModelIndex index = selection.indexes().first();
users_remove(index.row()); users_remove(index.row());
} } else // lv_authorities
else // lv_authorities
{ {
QItemSelection selection = ui.lv_authorities->selectionModel()->selection(); QItemSelection selection = ui.lv_authorities->selectionModel()->selection();
if (selection.indexes().isEmpty()) if (selection.indexes().isEmpty())
@ -672,7 +669,8 @@ private slots:
QModelIndex index = users->index(at); QModelIndex index = users->index(at);
ui.lv_users->setFocus(); ui.lv_users->setFocus();
ui.lv_users->setCurrentIndex(index); ui.lv_users->setCurrentIndex(index);
ui.lv_users->selectionModel()->select(index, QItemSelectionModel::Clear | QItemSelectionModel::Select | QItemSelectionModel::Current); ui.lv_users->selectionModel()->select(
index, QItemSelectionModel::Clear | QItemSelectionModel::Select | QItemSelectionModel::Current);
ui.lv_users->edit(index); ui.lv_users->edit(index);
} }
@ -694,7 +692,8 @@ private slots:
QModelIndex index = roots->index(at); QModelIndex index = roots->index(at);
ui.lv_authorities->setFocus(); ui.lv_authorities->setFocus();
ui.lv_authorities->setCurrentIndex(index); ui.lv_authorities->setCurrentIndex(index);
ui.lv_authorities->selectionModel()->select(index, QItemSelectionModel::Clear | QItemSelectionModel::Select | QItemSelectionModel::Current); ui.lv_authorities->selectionModel()->select(
index, QItemSelectionModel::Clear | QItemSelectionModel::Select | QItemSelectionModel::Current);
ui.lv_authorities->edit(index); ui.lv_authorities->edit(index);
} }
@ -767,16 +766,14 @@ private slots:
// consider self-signed users as roots // consider self-signed users as roots
// (it is therefore not possible with this application to // (it is therefore not possible with this application to
// have people in your keyring that you don't trust) // have people in your keyring that you don't trust)
foreach(const CertItem &i, users->items()) foreach (const CertItem &i, users->items()) {
{
QCA::Certificate cert = i.certificateChain().primary(); QCA::Certificate cert = i.certificateChain().primary();
if (cert.isSelfSigned()) if (cert.isSelfSigned())
col.addCertificate(cert); col.addCertificate(cert);
} }
// the self signed verify cert, if applicable // the self signed verify cert, if applicable
if(!self_signed_verify_cert.isNull()) if (!self_signed_verify_cert.isNull()) {
{
col.addCertificate(self_signed_verify_cert); col.addCertificate(self_signed_verify_cert);
self_signed_verify_cert = QCA::Certificate(); self_signed_verify_cert = QCA::Certificate();
} }
@ -808,11 +805,9 @@ private slots:
str += tr("Icons by Jason Kim") + '\n'; str += tr("Icons by Jason Kim") + '\n';
QCA::ProviderList list = QCA::providers(); QCA::ProviderList list = QCA::providers();
foreach(QCA::Provider *p, list) foreach (QCA::Provider *p, list) {
{
QString credit = p->credit(); QString credit = p->credit();
if(!credit.isEmpty()) if (!credit.isEmpty()) {
{
str += '\n'; str += '\n';
str += credit; str += credit;
} }
@ -857,31 +852,26 @@ private slots:
// import the cert? // import the cert?
QCA::SecureMessageKey skey = signer.key(); QCA::SecureMessageKey skey = signer.key();
if(!skey.isNull()) if (!skey.isNull()) {
{
QCA::CertificateChain chain = skey.x509CertificateChain(); QCA::CertificateChain chain = skey.x509CertificateChain();
int at = -1; int at = -1;
QList<CertItem> items = users->items(); QList<CertItem> items = users->items();
for(int n = 0; n < items.count(); ++n) for (int n = 0; n < items.count(); ++n) {
{
const CertItem &i = items[n]; const CertItem &i = items[n];
if(i.certificateChain().primary() == chain.primary()) if (i.certificateChain().primary() == chain.primary()) {
{
at = n; at = n;
break; break;
} }
} }
// add // add
if(at == -1) if (at == -1) {
{
auto_import_req_id = users->addUser(chain); auto_import_req_id = users->addUser(chain);
return; return;
} }
// update // update
else else {
{
users->updateChain(users->idFromRow(at), chain); users->updateChain(users->idFromRow(at), chain);
} }
} }
@ -903,26 +893,25 @@ private slots:
op = 0; op = 0;
QCA::SecureMessageKey skey = signer.key(); QCA::SecureMessageKey skey = signer.key();
if(signer.keyValidity() == QCA::ErrorSelfSigned && !skey.isNull()) if (signer.keyValidity() == QCA::ErrorSelfSigned && !skey.isNull()) {
{
QCA::CertificateChain chain = skey.x509CertificateChain(); QCA::CertificateChain chain = skey.x509CertificateChain();
if(chain.count() == 1 && chain.primary().isSelfSigned()) if (chain.count() == 1 && chain.primary().isSelfSigned()) {
{
QCA::Certificate cert = chain.primary(); QCA::Certificate cert = chain.primary();
int ret = QMessageBox::warning(this, tr("Self-signed certificate"), tr( int ret = QMessageBox::warning(
"<qt>The signature is made by an unknown user, and the certificate is self-signed.<br>\n" this,
tr("Self-signed certificate"),
tr("<qt>The signature is made by an unknown user, and the certificate is self-signed.<br>\n"
"<br>\n" "<br>\n"
"<nobr>Common Name: %1</nobr><br>\n" "<nobr>Common Name: %1</nobr><br>\n"
"<nobr>SHA1 Fingerprint: %2</nobr><br>\n" "<nobr>SHA1 Fingerprint: %2</nobr><br>\n"
"<br>\n" "<br>\n"
"Trust the certificate?</qt>" "Trust the certificate?</qt>")
).arg(cert.commonName(), get_fingerprint(cert)), .arg(cert.commonName(), get_fingerprint(cert)),
QMessageBox::Yes | QMessageBox::No, QMessageBox::Yes | QMessageBox::No,
QMessageBox::No); QMessageBox::No);
if(ret == QMessageBox::Yes) if (ret == QMessageBox::Yes) {
{
self_signed_verify_cert = cert; self_signed_verify_cert = cert;
do_verify(); do_verify();
return; return;
@ -943,10 +932,12 @@ int main(int argc, char **argv)
qapp.setApplicationName(MainWin::tr("CMS Signer")); qapp.setApplicationName(MainWin::tr("CMS Signer"));
if(!QCA::isSupported("cert,crl,cms")) if (!QCA::isSupported("cert,crl,cms")) {
{ QMessageBox::critical(
QMessageBox::critical(0, qapp.applicationName() + ": " + MainWin::tr("Error"), 0,
MainWin::tr("No support for CMS is available. Please install an appropriate QCA plugin, such as qca-ossl.")); qapp.applicationName() + ": " + MainWin::tr("Error"),
MainWin::tr(
"No support for CMS is available. Please install an appropriate QCA plugin, such as qca-ossl."));
return 1; return 1;
} }

View File

@ -21,12 +21,12 @@
#include "pkcs11configdlg.h" #include "pkcs11configdlg.h"
#include <QtCore>
#include <QtGui>
#include <QtCrypto>
#include <QMessageBox>
#include <QFileDialog>
#include "ui_pkcs11config.h" #include "ui_pkcs11config.h"
#include <QFileDialog>
#include <QMessageBox>
#include <QtCore>
#include <QtCrypto>
#include <QtGui>
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
// Pkcs11ProviderConfig // Pkcs11ProviderConfig
@ -43,13 +43,13 @@ public:
QString slotevent_method; QString slotevent_method;
int slotevent_timeout; int slotevent_timeout;
Pkcs11ProviderConfig() : Pkcs11ProviderConfig()
allow_protected_authentication(true), : allow_protected_authentication(true)
cert_private(false), , cert_private(false)
enabled(false), , enabled(false)
private_mask(0), , private_mask(0)
slotevent_method("auto"), , slotevent_method("auto")
slotevent_timeout(0) , slotevent_timeout(0)
{ {
} }
@ -95,11 +95,11 @@ public:
QVariantMap orig_config; QVariantMap orig_config;
Pkcs11Config() : Pkcs11Config()
allow_load_rootca(false), : allow_load_rootca(false)
allow_protected_authentication(true), , allow_protected_authentication(true)
log_level(0), , log_level(0)
pin_cache(-1) , pin_cache(-1)
{ {
} }
@ -117,8 +117,7 @@ public:
out["pin_cache"] = pin_cache; out["pin_cache"] = pin_cache;
// provider settings (always write at least 10 providers) // provider settings (always write at least 10 providers)
for(int n = 0; n < 10 || n < providers.count(); ++n) for (int n = 0; n < 10 || n < providers.count(); ++n) {
{
QString prefix = QString().sprintf("provider_%02d_", n); QString prefix = QString().sprintf("provider_%02d_", n);
Pkcs11ProviderConfig provider; Pkcs11ProviderConfig provider;
@ -127,8 +126,7 @@ public:
QVariantMap subconfig = provider.toVariantMap(); QVariantMap subconfig = provider.toVariantMap();
QMapIterator<QString, QVariant> it(subconfig); QMapIterator<QString, QVariant> it(subconfig);
while(it.hasNext()) while (it.hasNext()) {
{
it.next(); it.next();
out.insert(prefix + it.key(), it.value()); out.insert(prefix + it.key(), it.value());
} }
@ -147,8 +145,7 @@ public:
log_level = in["log_level"].toInt(); log_level = in["log_level"].toInt();
pin_cache = in["pin_cache"].toInt(); pin_cache = in["pin_cache"].toInt();
for(int n = 0;; ++n) for (int n = 0;; ++n) {
{
QString prefix = QString().sprintf("provider_%02d_", n); QString prefix = QString().sprintf("provider_%02d_", n);
// collect all key/values with this prefix into a // collect all key/values with this prefix into a
@ -156,8 +153,7 @@ public:
// from the keys. // from the keys.
QVariantMap subconfig; QVariantMap subconfig;
QMapIterator<QString, QVariant> it(in); QMapIterator<QString, QVariant> it(in);
while(it.hasNext()) while (it.hasNext()) {
{
it.next(); it.next();
if (it.key().startsWith(prefix)) if (it.key().startsWith(prefix))
subconfig.insert(it.key().mid(prefix.length()), it.value()); subconfig.insert(it.key().mid(prefix.length()), it.value());
@ -177,10 +173,8 @@ public:
// skip duplicate entries // skip duplicate entries
bool have_name_already = false; bool have_name_already = false;
foreach(const Pkcs11ProviderConfig &i, providers) foreach (const Pkcs11ProviderConfig &i, providers) {
{ if (i.name == provider.name) {
if(i.name == provider.name)
{
have_name_already = true; have_name_already = true;
break; break;
} }
@ -205,8 +199,8 @@ class ModuleListModel : public QAbstractListModel
public: public:
QList<Pkcs11ProviderConfig> list; QList<Pkcs11ProviderConfig> list;
ModuleListModel(QObject *parent = 0) : ModuleListModel(QObject *parent = 0)
QAbstractListModel(parent) : QAbstractListModel(parent)
{ {
} }
@ -242,34 +236,29 @@ public:
bool setData(const QModelIndex &index, const QVariant &value, int role) bool setData(const QModelIndex &index, const QVariant &value, int role)
{ {
if(index.isValid() && role == Qt::EditRole) if (index.isValid() && role == Qt::EditRole) {
{
QString str = value.toString(); QString str = value.toString();
if(str.isEmpty()) if (str.isEmpty()) {
{
emit editFailed(index, tr("Module name cannot be blank.")); emit editFailed(index, tr("Module name cannot be blank."));
return false; return false;
} }
bool have_name_already = false; bool have_name_already = false;
int at = index.row(); int at = index.row();
for(int n = 0; n < list.count(); ++n) for (int n = 0; n < list.count(); ++n) {
{
const Pkcs11ProviderConfig &i = list[n]; const Pkcs11ProviderConfig &i = list[n];
// skip self // skip self
if (n == at) if (n == at)
continue; continue;
if(i.name == str) if (i.name == str) {
{
have_name_already = true; have_name_already = true;
break; break;
} }
} }
if(have_name_already) if (have_name_already) {
{
emit editFailed(index, tr("There is already a module with this name.")); emit editFailed(index, tr("There is already a module with this name."));
return false; return false;
} }
@ -305,7 +294,7 @@ public:
endRemoveRows(); endRemoveRows();
} }
signals: Q_SIGNALS:
void editFailed(const QModelIndex &index, const QString &reasonString); void editFailed(const QModelIndex &index, const QString &reasonString);
}; };
@ -319,11 +308,9 @@ static QCA::Provider *get_pkcs11_provider(QVariantMap *_config = 0)
QCA::Provider *provider = 0; QCA::Provider *provider = 0;
QVariantMap config; QVariantMap config;
foreach(QCA::Provider *p, providers) foreach (QCA::Provider *p, providers) {
{
config = QCA::getProviderConfig(p->name()); config = QCA::getProviderConfig(p->name());
if(!config.isEmpty() && config["formtype"] == "http://affinix.com/qca/forms/qca-pkcs11#1.0") if (!config.isEmpty() && config["formtype"] == "http://affinix.com/qca/forms/qca-pkcs11#1.0") {
{
provider = p; provider = p;
break; break;
} }
@ -353,14 +340,14 @@ public:
// for ignoring modifications that we cause when populating fields // for ignoring modifications that we cause when populating fields
bool ignore_dataChanged; bool ignore_dataChanged;
Private(Pkcs11ConfigDlg *_q, const QString &_providerName, const QVariantMap &configmap) : Private(Pkcs11ConfigDlg *_q, const QString &_providerName, const QVariantMap &configmap)
QObject(_q), : QObject(_q)
q(_q), , q(_q)
providerName(_providerName), , providerName(_providerName)
dirty(false), , dirty(false)
allow_close(true), , allow_close(true)
done(false), , done(false)
ignore_dataChanged(true) , ignore_dataChanged(true)
{ {
ui.setupUi(q); ui.setupUi(q);
q->resize(q->minimumSize()); q->resize(q->minimumSize());
@ -385,7 +372,8 @@ public:
ui.sb_pincache_time->setEnabled(false); ui.sb_pincache_time->setEnabled(false);
ui.sb_pincache_time->setValue(300); ui.sb_pincache_time->setValue(300);
ui.lv_modules->setModel(model); ui.lv_modules->setModel(model);
ui.lv_modules->setEditTriggers(QAbstractItemView::DoubleClicked | QAbstractItemView::SelectedClicked | QAbstractItemView::EditKeyPressed); ui.lv_modules->setEditTriggers(QAbstractItemView::DoubleClicked | QAbstractItemView::SelectedClicked |
QAbstractItemView::EditKeyPressed);
ui.pb_remove->setEnabled(false); ui.pb_remove->setEnabled(false);
ui.tb_details->setEnabled(false); ui.tb_details->setEnabled(false);
ui.gb_poll->setEnabled(false); ui.gb_poll->setEnabled(false);
@ -409,7 +397,9 @@ public:
// modules // modules
connect(model, SIGNAL(dataChanged(const QModelIndex &, const QModelIndex &)), SLOT(dataChanged())); connect(model, SIGNAL(dataChanged(const QModelIndex &, const QModelIndex &)), SLOT(dataChanged()));
connect(ui.lv_modules->selectionModel(), SIGNAL(selectionChanged(const QItemSelection &, const QItemSelection &)), SLOT(module_selectionChanged(const QItemSelection &, const QItemSelection &))); connect(ui.lv_modules->selectionModel(),
SIGNAL(selectionChanged(const QItemSelection &, const QItemSelection &)),
SLOT(module_selectionChanged(const QItemSelection &, const QItemSelection &)));
connect(ui.pb_add, SIGNAL(clicked()), SLOT(module_add())); connect(ui.pb_add, SIGNAL(clicked()), SLOT(module_add()));
connect(ui.pb_remove, SIGNAL(clicked()), SLOT(module_remove())); connect(ui.pb_remove, SIGNAL(clicked()), SLOT(module_remove()));
connect(ui.le_library, SIGNAL(textChanged(const QString &)), SLOT(dataChanged())); connect(ui.le_library, SIGNAL(textChanged(const QString &)), SLOT(dataChanged()));
@ -428,36 +418,31 @@ public:
connect(ui.ck_modeunwrap, SIGNAL(toggled(bool)), SLOT(modenonauto_toggled(bool))); connect(ui.ck_modeunwrap, SIGNAL(toggled(bool)), SLOT(modenonauto_toggled(bool)));
// is this a valid config? // is this a valid config?
if(!providerName.isEmpty() && config.fromVariantMap(configmap)) if (!providerName.isEmpty() && config.fromVariantMap(configmap)) {
{
// if so, load everything up // if so, load everything up
ui.ck_allowroot->setChecked(config.allow_load_rootca); ui.ck_allowroot->setChecked(config.allow_load_rootca);
ui.ck_allowprotected->setChecked(config.allow_protected_authentication); ui.ck_allowprotected->setChecked(config.allow_protected_authentication);
ui.sb_loglevel->setValue(config.log_level); ui.sb_loglevel->setValue(config.log_level);
if(config.pin_cache != 0) if (config.pin_cache != 0) {
{
ui.gb_pincache->setChecked(true); ui.gb_pincache->setChecked(true);
if (config.pin_cache <= -1) if (config.pin_cache <= -1)
ui.rb_pincache_nolimit->setChecked(true); ui.rb_pincache_nolimit->setChecked(true);
else else {
{
ui.rb_pincache_time->setChecked(true); ui.rb_pincache_time->setChecked(true);
ui.sb_pincache_time->setValue(config.pin_cache); ui.sb_pincache_time->setValue(config.pin_cache);
} }
} }
model->addItems(config.providers); model->addItems(config.providers);
if(!model->list.isEmpty()) if (!model->list.isEmpty()) {
{
QModelIndex index = model->index(0); QModelIndex index = model->index(0);
ui.lv_modules->setCurrentIndex(index); ui.lv_modules->setCurrentIndex(index);
ui.lv_modules->selectionModel()->select(index, QItemSelectionModel::Clear | QItemSelectionModel::Select | QItemSelectionModel::Current); ui.lv_modules->selectionModel()->select(
index, QItemSelectionModel::Clear | QItemSelectionModel::Select | QItemSelectionModel::Current);
} }
ui.buttonBox->setFocus(); ui.buttonBox->setFocus();
ui.buttonBox->button(QDialogButtonBox::Cancel)->setFocus(); ui.buttonBox->button(QDialogButtonBox::Cancel)->setFocus();
} } else {
else
{
// otherwise, disable everything // otherwise, disable everything
ui.gb_general->setEnabled(false); ui.gb_general->setEnabled(false);
ui.gb_modules->setEnabled(false); ui.gb_modules->setEnabled(false);
@ -483,14 +468,12 @@ public:
i.slotevent_method = "trigger"; i.slotevent_method = "trigger";
else // 2 else // 2
i.slotevent_method = "poll"; i.slotevent_method = "poll";
if(x == 2) if (x == 2) {
{
if (ui.rb_polldefault->isChecked()) if (ui.rb_polldefault->isChecked())
i.slotevent_timeout = 0; i.slotevent_timeout = 0;
else else
i.slotevent_timeout = ui.sb_pollcustom->value(); i.slotevent_timeout = ui.sb_pollcustom->value();
} } else
else
i.slotevent_timeout = 0; i.slotevent_timeout = 0;
i.allow_protected_authentication = ui.ck_modallowprotected->isChecked(); i.allow_protected_authentication = ui.ck_modallowprotected->isChecked();
@ -511,8 +494,7 @@ public:
{ {
// save currently selected module, which may not be saved yet // save currently selected module, which may not be saved yet
QItemSelection selection = ui.lv_modules->selectionModel()->selection(); QItemSelection selection = ui.lv_modules->selectionModel()->selection();
if(!selection.indexes().isEmpty()) if (!selection.indexes().isEmpty()) {
{
QModelIndex index = selection.indexes().first(); QModelIndex index = selection.indexes().first();
save_module(index.row()); save_module(index.row());
} }
@ -520,14 +502,12 @@ public:
config.allow_load_rootca = ui.ck_allowroot->isChecked(); config.allow_load_rootca = ui.ck_allowroot->isChecked();
config.allow_protected_authentication = ui.ck_allowprotected->isChecked(); config.allow_protected_authentication = ui.ck_allowprotected->isChecked();
config.log_level = ui.sb_loglevel->value(); config.log_level = ui.sb_loglevel->value();
if(ui.gb_pincache->isChecked()) if (ui.gb_pincache->isChecked()) {
{
if (ui.rb_pincache_nolimit->isChecked()) if (ui.rb_pincache_nolimit->isChecked())
config.pin_cache = -1; config.pin_cache = -1;
else else
config.pin_cache = ui.sb_pincache_time->value(); config.pin_cache = ui.sb_pincache_time->value();
} } else
else
config.pin_cache = 0; config.pin_cache = 0;
config.providers = model->list; config.providers = model->list;
@ -537,7 +517,7 @@ public:
QCA::saveProviderConfig(providerName); QCA::saveProviderConfig(providerName);
} }
private slots: private Q_SLOTS:
void model_editFailed(const QModelIndex &index, const QString &reasonString) void model_editFailed(const QModelIndex &index, const QString &reasonString)
{ {
// if the dialog has already been dismissed, then don't // if the dialog has already been dismissed, then don't
@ -546,7 +526,7 @@ private slots:
return; return;
// show error dialog, and don't allow dimissing the dialog // show error dialog, and don't allow dimissing the dialog
// during. we need this, because the the dismiss request // during. we need this, because the dismiss request
// can be queued, and end up being invoked during the // can be queued, and end up being invoked during the
// QMessageBox nested eventloop. // QMessageBox nested eventloop.
allow_close = false; allow_close = false;
@ -556,7 +536,8 @@ private slots:
// return to edit mode for the item // return to edit mode for the item
ui.lv_modules->setFocus(); ui.lv_modules->setFocus();
ui.lv_modules->setCurrentIndex(index); ui.lv_modules->setCurrentIndex(index);
ui.lv_modules->selectionModel()->select(index, QItemSelectionModel::Clear | QItemSelectionModel::Select | QItemSelectionModel::Current); ui.lv_modules->selectionModel()->select(
index, QItemSelectionModel::Clear | QItemSelectionModel::Select | QItemSelectionModel::Current);
ui.lv_modules->edit(index); ui.lv_modules->edit(index);
} }
@ -574,18 +555,15 @@ private slots:
void module_selectionChanged(const QItemSelection &selected, const QItemSelection &deselected) void module_selectionChanged(const QItemSelection &selected, const QItemSelection &deselected)
{ {
if(!deselected.indexes().isEmpty()) if (!deselected.indexes().isEmpty()) {
{
QModelIndex index = deselected.indexes().first(); QModelIndex index = deselected.indexes().first();
save_module(index.row()); save_module(index.row());
} }
ignore_dataChanged = true; ignore_dataChanged = true;
if(!selected.indexes().isEmpty()) if (!selected.indexes().isEmpty()) {
{ if (deselected.indexes().isEmpty()) {
if(deselected.indexes().isEmpty())
{
ui.pb_remove->setEnabled(true); ui.pb_remove->setEnabled(true);
ui.tb_details->setEnabled(true); ui.tb_details->setEnabled(true);
} }
@ -597,21 +575,17 @@ private slots:
if (i.slotevent_method == "trigger") if (i.slotevent_method == "trigger")
ui.cb_slotmethod->setCurrentIndex(1); ui.cb_slotmethod->setCurrentIndex(1);
else if(i.slotevent_method == "poll") else if (i.slotevent_method == "poll") {
{
ui.cb_slotmethod->setCurrentIndex(2); ui.cb_slotmethod->setCurrentIndex(2);
if (i.slotevent_timeout <= 0) if (i.slotevent_timeout <= 0)
ui.rb_polldefault->setChecked(true); ui.rb_polldefault->setChecked(true);
else else {
{
ui.rb_pollcustom->setChecked(true); ui.rb_pollcustom->setChecked(true);
ui.sb_pollcustom->setValue(i.slotevent_timeout); ui.sb_pollcustom->setValue(i.slotevent_timeout);
} }
} } else // auto
else // auto
ui.cb_slotmethod->setCurrentIndex(0); ui.cb_slotmethod->setCurrentIndex(0);
if(i.slotevent_method != "poll") if (i.slotevent_method != "poll") {
{
ui.rb_polldefault->setChecked(true); ui.rb_polldefault->setChecked(true);
ui.sb_pollcustom->setValue(5); ui.sb_pollcustom->setValue(5);
} }
@ -621,16 +595,13 @@ private slots:
if (i.private_mask == 0) if (i.private_mask == 0)
ui.ck_modeauto->setChecked(true); ui.ck_modeauto->setChecked(true);
else else {
{
ui.ck_modesign->setChecked(i.private_mask & 1); ui.ck_modesign->setChecked(i.private_mask & 1);
ui.ck_modesignrecover->setChecked(i.private_mask & 2); ui.ck_modesignrecover->setChecked(i.private_mask & 2);
ui.ck_modedecrypt->setChecked(i.private_mask & 4); ui.ck_modedecrypt->setChecked(i.private_mask & 4);
ui.ck_modeunwrap->setChecked(i.private_mask & 8); ui.ck_modeunwrap->setChecked(i.private_mask & 8);
} }
} } else if (selected.indexes().isEmpty() && !deselected.indexes().isEmpty()) {
else if(selected.indexes().isEmpty() && !deselected.indexes().isEmpty())
{
// restore defaults for all details widgets // restore defaults for all details widgets
ui.le_library->setText(QString()); ui.le_library->setText(QString());
ui.cb_slotmethod->setCurrentIndex(0); ui.cb_slotmethod->setCurrentIndex(0);
@ -653,19 +624,16 @@ private slots:
{ {
// find unused default name // find unused default name
QString name; QString name;
for(int n = 1;; ++n) for (int n = 1;; ++n) {
{
if (n == 1) if (n == 1)
name = tr("New Module"); name = tr("New Module");
else else
name = tr("New Module (%1)").arg(n); name = tr("New Module (%1)").arg(n);
bool have_name_already = false; bool have_name_already = false;
for(int n = 0; n < model->list.count(); ++n) for (int n = 0; n < model->list.count(); ++n) {
{
const Pkcs11ProviderConfig &i = model->list[n]; const Pkcs11ProviderConfig &i = model->list[n];
if(i.name == name) if (i.name == name) {
{
have_name_already = true; have_name_already = true;
break; break;
} }
@ -689,7 +657,8 @@ private slots:
// edit this item // edit this item
ui.lv_modules->setFocus(); ui.lv_modules->setFocus();
ui.lv_modules->setCurrentIndex(index); ui.lv_modules->setCurrentIndex(index);
ui.lv_modules->selectionModel()->select(index, QItemSelectionModel::Clear | QItemSelectionModel::Select | QItemSelectionModel::Current); ui.lv_modules->selectionModel()->select(
index, QItemSelectionModel::Clear | QItemSelectionModel::Select | QItemSelectionModel::Current);
ui.lv_modules->edit(index); ui.lv_modules->edit(index);
} }
@ -706,7 +675,8 @@ private slots:
void library_browse() void library_browse()
{ {
QString fileName = QFileDialog::getOpenFileName(q, tr("Select PKCS#11 Module"), QString(), tr("PKCS#11 Modules (*.*)")); QString fileName =
QFileDialog::getOpenFileName(q, tr("Select PKCS#11 Module"), QString(), tr("PKCS#11 Modules (*.*)"));
if (fileName.isEmpty()) if (fileName.isEmpty())
return; return;
@ -725,8 +695,7 @@ private slots:
void modeauto_toggled(bool checked) void modeauto_toggled(bool checked)
{ {
if(checked) if (checked) {
{
if (ui.ck_modesign->isChecked()) if (ui.ck_modesign->isChecked())
ui.ck_modesign->setChecked(false); ui.ck_modesign->setChecked(false);
if (ui.ck_modesignrecover->isChecked()) if (ui.ck_modesignrecover->isChecked())
@ -735,14 +704,9 @@ private slots:
ui.ck_modedecrypt->setChecked(false); ui.ck_modedecrypt->setChecked(false);
if (ui.ck_modeunwrap->isChecked()) if (ui.ck_modeunwrap->isChecked())
ui.ck_modeunwrap->setChecked(false); ui.ck_modeunwrap->setChecked(false);
} } else {
else if (!ui.ck_modesign->isChecked() && !ui.ck_modesignrecover->isChecked() &&
{ !ui.ck_modedecrypt->isChecked() && !ui.ck_modeunwrap->isChecked()) {
if(!ui.ck_modesign->isChecked()
&& !ui.ck_modesignrecover->isChecked()
&& !ui.ck_modedecrypt->isChecked()
&& !ui.ck_modeunwrap->isChecked())
{
ui.ck_modesign->setChecked(true); ui.ck_modesign->setChecked(true);
ui.ck_modesignrecover->setChecked(true); ui.ck_modesignrecover->setChecked(true);
ui.ck_modedecrypt->setChecked(true); ui.ck_modedecrypt->setChecked(true);
@ -755,18 +719,12 @@ private slots:
void modenonauto_toggled(bool checked) void modenonauto_toggled(bool checked)
{ {
if(checked) if (checked) {
{
if (ui.ck_modeauto->isChecked()) if (ui.ck_modeauto->isChecked())
ui.ck_modeauto->setChecked(false); ui.ck_modeauto->setChecked(false);
} } else {
else if (!ui.ck_modesign->isChecked() && !ui.ck_modesignrecover->isChecked() &&
{ !ui.ck_modedecrypt->isChecked() && !ui.ck_modeunwrap->isChecked()) {
if(!ui.ck_modesign->isChecked()
&& !ui.ck_modesignrecover->isChecked()
&& !ui.ck_modedecrypt->isChecked()
&& !ui.ck_modeunwrap->isChecked())
{
ui.ck_modeauto->setChecked(true); ui.ck_modeauto->setChecked(true);
} }
} }
@ -775,8 +733,8 @@ private slots:
} }
}; };
Pkcs11ConfigDlg::Pkcs11ConfigDlg(QWidget *parent) : Pkcs11ConfigDlg::Pkcs11ConfigDlg(QWidget *parent)
QDialog(parent) : QDialog(parent)
{ {
QVariantMap config; QVariantMap config;
QCA::Provider *p = get_pkcs11_provider(&config); QCA::Provider *p = get_pkcs11_provider(&config);
@ -786,8 +744,8 @@ Pkcs11ConfigDlg::Pkcs11ConfigDlg(QWidget *parent) :
d = new Private(this, QString(), QVariantMap()); d = new Private(this, QString(), QVariantMap());
} }
Pkcs11ConfigDlg::Pkcs11ConfigDlg(const QString &providerName, const QVariantMap &config, QWidget *parent) : Pkcs11ConfigDlg::Pkcs11ConfigDlg(const QString &providerName, const QVariantMap &config, QWidget *parent)
QDialog(parent) : QDialog(parent)
{ {
d = new Private(this, providerName, config); d = new Private(this, providerName, config);
} }

View File

@ -21,12 +21,12 @@
#include "prompter.h" #include "prompter.h"
#include <QtCore>
#include <QtGui>
#include <QtCrypto>
#include <QMessageBox>
#include <QInputDialog>
#include <QApplication> #include <QApplication>
#include <QInputDialog>
#include <QMessageBox>
#include <QtCore>
#include <QtCrypto>
#include <QtGui>
class Prompter::Private : public QObject class Prompter::Private : public QObject
{ {
@ -50,13 +50,13 @@ public:
QCA::KeyStoreManager ksm; QCA::KeyStoreManager ksm;
QList<QCA::KeyStore *> keyStores; QList<QCA::KeyStore *> keyStores;
Private(Prompter *_q) : Private(Prompter *_q)
QObject(_q), : QObject(_q)
q(_q), , q(_q)
handler(this), , handler(this)
prompting(false), , prompting(false)
token_prompt(0), , token_prompt(0)
ksm(this) , ksm(this)
{ {
connect(&handler, SIGNAL(eventReady(int, const QCA::Event &)), SLOT(ph_eventReady(int, const QCA::Event &))); connect(&handler, SIGNAL(eventReady(int, const QCA::Event &)), SLOT(ph_eventReady(int, const QCA::Event &)));
handler.start(); handler.start();
@ -74,7 +74,7 @@ public:
handler.reject(pending.takeFirst().id); handler.reject(pending.takeFirst().id);
} }
private slots: private Q_SLOTS:
void ph_eventReady(int id, const QCA::Event &event) void ph_eventReady(int id, const QCA::Event &event)
{ {
Item i; Item i;
@ -95,11 +95,9 @@ private slots:
const int & id = i.id; const int & id = i.id;
const QCA::Event &event = i.event; const QCA::Event &event = i.event;
if(event.type() == QCA::Event::Password) if (event.type() == QCA::Event::Password) {
{
QCA::SecureArray known = q->knownPassword(event); QCA::SecureArray known = q->knownPassword(event);
if(!known.isEmpty()) if (!known.isEmpty()) {
{
handler.submitPassword(id, known); handler.submitPassword(id, known);
goto end; goto end;
} }
@ -111,90 +109,74 @@ private slots:
type = Prompter::tr("PIN"); type = Prompter::tr("PIN");
QString str; QString str;
if(event.source() == QCA::Event::KeyStore) if (event.source() == QCA::Event::KeyStore) {
{
QString name; QString name;
QCA::KeyStoreEntry entry = event.keyStoreEntry(); QCA::KeyStoreEntry entry = event.keyStoreEntry();
if(!entry.isNull()) if (!entry.isNull()) {
{
name = entry.name(); name = entry.name();
} } else {
else
{
if (event.keyStoreInfo().type() == QCA::KeyStore::SmartCard) if (event.keyStoreInfo().type() == QCA::KeyStore::SmartCard)
name = Prompter::tr("the '%1' token").arg(event.keyStoreInfo().name()); name = Prompter::tr("the '%1' token").arg(event.keyStoreInfo().name());
else else
name = event.keyStoreInfo().name(); name = event.keyStoreInfo().name();
} }
str = Prompter::tr("Enter %1 for %2").arg(type, name); str = Prompter::tr("Enter %1 for %2").arg(type, name);
} } else if (!event.fileName().isEmpty()) {
else if(!event.fileName().isEmpty())
{
QFileInfo fi(event.fileName()); QFileInfo fi(event.fileName());
str = Prompter::tr("Enter %1 for %2:").arg(type, fi.fileName()); str = Prompter::tr("Enter %1 for %2:").arg(type, fi.fileName());
} } else
else
str = Prompter::tr("Enter %1:").arg(type); str = Prompter::tr("Enter %1:").arg(type);
bool ok; bool ok;
QString pass = QInputDialog::getText(0, QApplication::instance()->applicationName() + ": " + tr("Prompt"), str, QLineEdit::Password, QString(), &ok); QString pass = QInputDialog::getText(0,
if(ok) QApplication::instance()->applicationName() + ": " + tr("Prompt"),
{ str,
QLineEdit::Password,
QString(),
&ok);
if (ok) {
QCA::SecureArray password = pass.toUtf8(); QCA::SecureArray password = pass.toUtf8();
q->userSubmitted(password, event); q->userSubmitted(password, event);
handler.submitPassword(id, password); handler.submitPassword(id, password);
} } else
else
handler.reject(id); handler.reject(id);
} } else if (event.type() == QCA::Event::Token) {
else if(event.type() == QCA::Event::Token)
{
// even though we're being prompted for a missing token, // even though we're being prompted for a missing token,
// we should still check if the token is present, due to // we should still check if the token is present, due to
// a possible race between insert and token request. // a possible race between insert and token request.
bool found = false; bool found = false;
// token-only // token-only
if(event.keyStoreEntry().isNull()) if (event.keyStoreEntry().isNull()) {
{ foreach (QCA::KeyStore *ks, keyStores) {
foreach(QCA::KeyStore *ks, keyStores) if (ks->id() == event.keyStoreInfo().id()) {
{
if(ks->id() == event.keyStoreInfo().id())
{
found = true; found = true;
break; break;
} }
} }
} }
// token-entry // token-entry
else else {
{
QCA::KeyStoreEntry kse = event.keyStoreEntry(); QCA::KeyStoreEntry kse = event.keyStoreEntry();
QCA::KeyStore *ks = 0; QCA::KeyStore *ks = 0;
foreach(QCA::KeyStore *i, keyStores) foreach (QCA::KeyStore *i, keyStores) {
{ if (i->id() == event.keyStoreInfo().id()) {
if(i->id() == event.keyStoreInfo().id())
{
ks = i; ks = i;
break; break;
} }
} }
if(ks) if (ks) {
{
QList<QCA::KeyStoreEntry> list = ks->entryList(); QList<QCA::KeyStoreEntry> list = ks->entryList();
foreach(const QCA::KeyStoreEntry &e, list) foreach (const QCA::KeyStoreEntry &e, list) {
{ if (e.id() == kse.id() && kse.isAvailable()) {
if(e.id() == kse.id() && kse.isAvailable())
{
found = true; found = true;
break; break;
} }
} }
} }
} }
if(found) if (found) {
{
// auto-accept // auto-accept
handler.tokenOkay(id); handler.tokenOkay(id);
return; return;
@ -202,18 +184,19 @@ private slots:
QCA::KeyStoreEntry entry = event.keyStoreEntry(); QCA::KeyStoreEntry entry = event.keyStoreEntry();
QString name; QString name;
if(!entry.isNull()) if (!entry.isNull()) {
{
name = Prompter::tr("Please make %1 (of %2) available").arg(entry.name(), entry.storeName()); name = Prompter::tr("Please make %1 (of %2) available").arg(entry.name(), entry.storeName());
} } else {
else
{
name = Prompter::tr("Please insert the '%1' token").arg(event.keyStoreInfo().name()); name = Prompter::tr("Please insert the '%1' token").arg(event.keyStoreInfo().name());
} }
QString str = Prompter::tr("%1 and click OK.").arg(name); QString str = Prompter::tr("%1 and click OK.").arg(name);
QMessageBox msgBox(QMessageBox::Information, QApplication::instance()->applicationName() + ": " + tr("Prompt"), str, QMessageBox::Ok | QMessageBox::Cancel, 0); QMessageBox msgBox(QMessageBox::Information,
QApplication::instance()->applicationName() + ": " + tr("Prompt"),
str,
QMessageBox::Ok | QMessageBox::Cancel,
0);
token_prompt = &msgBox; token_prompt = &msgBox;
auto_accept = false; auto_accept = false;
if (msgBox.exec() == QMessageBox::Ok || auto_accept) if (msgBox.exec() == QMessageBox::Ok || auto_accept)
@ -221,8 +204,7 @@ private slots:
else else
handler.reject(id); handler.reject(id);
token_prompt = 0; token_prompt = 0;
} } else
else
handler.reject(id); handler.reject(id);
end: end:
@ -242,11 +224,10 @@ private slots:
ks->startAsynchronousMode(); ks->startAsynchronousMode();
// are we currently in a token-only prompt? // are we currently in a token-only prompt?
if(token_prompt && pending.first().event.type() == QCA::Event::Token && pending.first().event.keyStoreEntry().isNull()) if (token_prompt && pending.first().event.type() == QCA::Event::Token &&
{ pending.first().event.keyStoreEntry().isNull()) {
// was the token we're looking for just inserted? // was the token we're looking for just inserted?
if(pending.first().event.keyStoreInfo().id() == keyStoreId) if (pending.first().event.keyStoreInfo().id() == keyStoreId) {
{
// auto-accept // auto-accept
auto_accept = true; auto_accept = true;
token_prompt->accept(); token_prompt->accept();
@ -266,26 +247,22 @@ private slots:
QCA::KeyStore *ks = (QCA::KeyStore *)sender(); QCA::KeyStore *ks = (QCA::KeyStore *)sender();
// are we currently in a token-entry prompt? // are we currently in a token-entry prompt?
if(token_prompt && pending.first().event.type() == QCA::Event::Token && !pending.first().event.keyStoreEntry().isNull()) if (token_prompt && pending.first().event.type() == QCA::Event::Token &&
{ !pending.first().event.keyStoreEntry().isNull()) {
QCA::KeyStoreEntry kse = pending.first().event.keyStoreEntry(); QCA::KeyStoreEntry kse = pending.first().event.keyStoreEntry();
// was the token of the entry we're looking for updated? // was the token of the entry we're looking for updated?
if(pending.first().event.keyStoreInfo().id() == ks->id()) if (pending.first().event.keyStoreInfo().id() == ks->id()) {
{
// is the entry available? // is the entry available?
bool avail = false; bool avail = false;
QList<QCA::KeyStoreEntry> list = ks->entryList(); QList<QCA::KeyStoreEntry> list = ks->entryList();
foreach(const QCA::KeyStoreEntry &e, list) foreach (const QCA::KeyStoreEntry &e, list) {
{ if (e.id() == kse.id()) {
if(e.id() == kse.id())
{
avail = kse.isAvailable(); avail = kse.isAvailable();
break; break;
} }
} }
if(avail) if (avail) {
{
// auto-accept // auto-accept
auto_accept = true; auto_accept = true;
token_prompt->accept(); token_prompt->accept();
@ -295,8 +272,8 @@ private slots:
} }
}; };
Prompter::Prompter(QObject *parent) : Prompter::Prompter(QObject *parent)
QObject(parent) : QObject(parent)
{ {
d = new Private(this); d = new Private(this);
} }

View File

@ -24,8 +24,7 @@
#include <QObject> #include <QObject>
namespace QCA namespace QCA {
{
class SecureArray; class SecureArray;
class Event; class Event;
} }
@ -34,7 +33,7 @@ class Prompter : public QObject
{ {
Q_OBJECT Q_OBJECT
public: public:
Prompter(QObject *parent = 0); Prompter(QObject *parent = nullptr);
~Prompter(); ~Prompter();
protected: protected:

View File

@ -1,7 +1,5 @@
set(eventhandlerdemo_bin_SRCS eventhandlerdemo.cpp) set(eventhandlerdemo_bin_SRCS eventhandlerdemo.cpp)
MY_AUTOMOC( eventhandlerdemo_bin_SRCS)
add_executable(eventhandlerdemo ${eventhandlerdemo_bin_SRCS}) add_executable(eventhandlerdemo ${eventhandlerdemo_bin_SRCS})
target_link_qca_libraries(eventhandlerdemo) target_link_qca_libraries(eventhandlerdemo)

View File

@ -37,20 +37,20 @@ class ClientPassphraseHandler: public QObject
{ {
Q_OBJECT Q_OBJECT
public: public:
ClientPassphraseHandler(QObject *parent = 0) : QObject( parent ) ClientPassphraseHandler(QObject *parent = nullptr)
: QObject(parent)
{ {
// When the PasswordAsker or TokenAsker needs to interact // When the PasswordAsker or TokenAsker needs to interact
// with the user, it raises a signal. We connect that to a // with the user, it raises a signal. We connect that to a
// local slot to get the required information. // local slot to get the required information.
connect( &m_handler, SIGNAL( eventReady(int, const QCA::Event &) ), connect(&m_handler, &QCA::EventHandler::eventReady, this, &ClientPassphraseHandler::my_eventReady);
SLOT( my_eventReady(int, const QCA::Event &) ) );
// Now that we are set up, we can start the EventHandler. Nothing // Now that we are set up, we can start the EventHandler. Nothing
// will happen if you don't call this method. // will happen if you don't call this method.
m_handler.start(); m_handler.start();
} }
private slots: private Q_SLOTS:
// This slot gets called when the provider needs a token inserted, // This slot gets called when the provider needs a token inserted,
// or to get a passphrase / password / PIN. // or to get a passphrase / password / PIN.
void my_eventReady(int id, const QCA::Event &event) void my_eventReady(int id, const QCA::Event &event)
@ -101,9 +101,9 @@ private slots:
std::cout << "Unexpected event type" << std::endl; std::cout << "Unexpected event type" << std::endl;
} }
} }
private: private:
QCA::EventHandler m_handler; QCA::EventHandler m_handler;
}; };
void asker_procedure(); void asker_procedure();
@ -112,7 +112,7 @@ class AskerThread : public QThread
{ {
Q_OBJECT Q_OBJECT
protected: protected:
virtual void run() void run() override
{ {
asker_procedure(); asker_procedure();
} }
@ -130,7 +130,7 @@ int main(int argc, char **argv)
// handler and asker cannot occur in the same thread // handler and asker cannot occur in the same thread
AskerThread askerThread; AskerThread askerThread;
QObject::connect(&askerThread, SIGNAL(finished()), &exampleApp, SLOT(quit())); QObject::connect(&askerThread, &AskerThread::finished, &exampleApp, &QCoreApplication::quit);
askerThread.start(); askerThread.start();
exampleApp.exec(); exampleApp.exec();
@ -141,7 +141,7 @@ void asker_procedure()
{ {
QCA::PasswordAsker pwAsker; QCA::PasswordAsker pwAsker;
pwAsker.ask( QCA::Event::StylePassword, "foo.tmp", 0 ); pwAsker.ask(QCA::Event::StylePassword, QStringLiteral("foo.tmp"), nullptr);
pwAsker.waitForResponse(); pwAsker.waitForResponse();
@ -151,7 +151,10 @@ void asker_procedure()
QCA::TokenAsker tokenAsker; QCA::TokenAsker tokenAsker;
tokenAsker.ask( QCA::KeyStoreInfo( QCA::KeyStore::SmartCard, "Token Id", "Token Name" ), QCA::KeyStoreEntry(), 0 ); tokenAsker.ask(
QCA::KeyStoreInfo(QCA::KeyStore::SmartCard, QStringLiteral("Token Id"), QStringLiteral("Token Name")),
QCA::KeyStoreEntry(),
nullptr);
tokenAsker.waitForResponse(); tokenAsker.waitForResponse();

View File

@ -169,7 +169,7 @@ The code below shows how to create an SSL client
*/ */
/* \example tlssocket.cpp /** \example tlssocket.cpp
The code below shows how to create a socket that can operate The code below shows how to create a socket that can operate
over an Transport Layer Security (TLS, also known as SSL) connection. over an Transport Layer Security (TLS, also known as SSL) connection.

View File

@ -24,7 +24,7 @@
#include <QCoreApplication> #include <QCoreApplication>
#include <stdio.h> #include <cstdio>
#ifdef QT_STATICPLUGIN #ifdef QT_STATICPLUGIN
#include "import_plugins.h" #include "import_plugins.h"
@ -47,7 +47,7 @@ int main(int argc, char **argv)
printf("SHA1 not supported!\n"); printf("SHA1 not supported!\n");
else { else {
// this shows the "all in one" approach // this shows the "all in one" approach
QString result = QCA::Hash("sha1").hashToString(arg); QString result = QCA::Hash(QStringLiteral("sha1")).hashToString(arg);
printf("sha1(\"%s\") = [%s]\n", arg.data(), qPrintable(result)); printf("sha1(\"%s\") = [%s]\n", arg.data(), qPrintable(result));
} }
@ -62,7 +62,7 @@ int main(int argc, char **argv)
QCA::SecureArray part2(arg.toByteArray().mid(3)); // the rest - "lo" QCA::SecureArray part2(arg.toByteArray().mid(3)); // the rest - "lo"
// create the required object. // create the required object.
QCA::Hash hashObject("md5"); QCA::Hash hashObject(QStringLiteral("md5"));
// we split it into two parts to show incremental update // we split it into two parts to show incremental update
hashObject.update(part1); hashObject.update(part1);
hashObject.update(part2); hashObject.update(part2);
@ -75,4 +75,3 @@ int main(int argc, char **argv)
return 0; return 0;
} }

View File

@ -67,4 +67,3 @@ int main(int argc, char **argv)
return 0; return 0;
} }

View File

@ -1,7 +1,5 @@
set(keyloader_bin_SRCS keyloader.cpp) set(keyloader_bin_SRCS keyloader.cpp)
MY_AUTOMOC( keyloader_bin_SRCS )
add_executable(keyloader ${keyloader_bin_SRCS}) add_executable(keyloader ${keyloader_bin_SRCS})
target_link_qca_libraries(keyloader) target_link_qca_libraries(keyloader)

View File

@ -23,9 +23,10 @@
#include <QtCrypto> #include <QtCrypto>
#include <QCoreApplication> #include <QCoreApplication>
#include <QFile>
#include <QTimer> #include <QTimer>
#include <stdio.h> #include <cstdio>
#ifdef QT_STATICPLUGIN #ifdef QT_STATICPLUGIN
#include "import_plugins.h" #include "import_plugins.h"
@ -37,26 +38,24 @@ class PassphraseHandler: public QObject
public: public:
QCA::EventHandler handler; QCA::EventHandler handler;
PassphraseHandler(QObject *parent = 0) : QObject(parent) PassphraseHandler(QObject *parent = nullptr)
: QObject(parent)
{ {
connect(&handler, SIGNAL(eventReady(int, const QCA::Event &)), connect(&handler, &QCA::EventHandler::eventReady, this, &PassphraseHandler::eh_eventReady);
SLOT(eh_eventReady(int, const QCA::Event &)));
handler.start(); handler.start();
} }
private slots: private Q_SLOTS:
void eh_eventReady(int id, const QCA::Event &event) void eh_eventReady(int id, const QCA::Event &event)
{ {
if(event.type() == QCA::Event::Password) if (event.type() == QCA::Event::Password) {
{
QCA::SecureArray pass; QCA::SecureArray pass;
QCA::ConsolePrompt prompt; QCA::ConsolePrompt prompt;
prompt.getHidden("Passphrase"); prompt.getHidden(QStringLiteral("Passphrase"));
prompt.waitForFinished(); prompt.waitForFinished();
pass = prompt.result(); pass = prompt.result();
handler.submitPassword(id, pass); handler.submitPassword(id, pass);
} } else
else
handler.reject(id); handler.reject(id);
} }
}; };
@ -70,27 +69,25 @@ public:
App() App()
{ {
connect(&keyLoader, SIGNAL(finished()), SLOT(kl_finished())); connect(&keyLoader, &QCA::KeyLoader::finished, this, &App::kl_finished);
} }
public slots: public Q_SLOTS:
void start() void start()
{ {
keyLoader.loadPrivateKeyFromPEMFile(str); keyLoader.loadPrivateKeyFromPEMFile(str);
} }
signals: Q_SIGNALS:
void quit(); void quit();
private slots: private Q_SLOTS:
void kl_finished() void kl_finished()
{ {
if(keyLoader.convertResult() == QCA::ConvertGood) if (keyLoader.convertResult() == QCA::ConvertGood) {
{
QCA::PrivateKey key = keyLoader.privateKey(); QCA::PrivateKey key = keyLoader.privateKey();
printf("Loaded successfully. Bits: %d\n", key.bitSize()); printf("Loaded successfully. Bits: %d\n", key.bitSize());
} } else
else
printf("Unable to load.\n"); printf("Unable to load.\n");
emit quit(); emit quit();
@ -102,17 +99,16 @@ int main(int argc, char **argv)
QCA::Initializer init; QCA::Initializer init;
QCoreApplication qapp(argc, argv); QCoreApplication qapp(argc, argv);
if(argc < 2) if (argc < 2) {
{
printf("usage: keyloader [privatekey.pem]\n"); printf("usage: keyloader [privatekey.pem]\n");
return 0; return 0;
} }
PassphraseHandler passphraseHandler; PassphraseHandler passphraseHandler;
App app; App app;
app.str = argv[1]; app.str = QFile::decodeName(argv[1]);
QObject::connect(&app, SIGNAL(quit()), &qapp, SLOT(quit())); QObject::connect(&app, &App::quit, &qapp, QCoreApplication::quit);
QTimer::singleShot(0, &app, SLOT(start())); QTimer::singleShot(0, &app, &App::start);
qapp.exec(); qapp.exec();
return 0; return 0;
} }

View File

@ -26,7 +26,7 @@
#include <QDebug> #include <QDebug>
// needed for printf // needed for printf
#include<stdio.h> #include <cstdio>
#ifdef QT_STATICPLUGIN #ifdef QT_STATICPLUGIN
#include "import_plugins.h" #include "import_plugins.h"
@ -57,7 +57,7 @@ int main(int argc, char **argv)
} else { } else {
// create the required object using HMAC with SHA-1, and an // create the required object using HMAC with SHA-1, and an
// empty key. // empty key.
QCA::MessageAuthenticationCode hmacObject( "hmac(sha1)", QCA::SecureArray() ); QCA::MessageAuthenticationCode hmacObject(QStringLiteral("hmac(sha1)"), QCA::SecureArray());
// create the key // create the key
QCA::SymmetricKey keyObject(key); QCA::SymmetricKey keyObject(key);
@ -83,4 +83,3 @@ int main(int argc, char **argv)
return 0; return 0;
} }

View File

@ -25,10 +25,10 @@
(http://www-128.ibm.com/developerworks/linux/library/l-md5crypt/) (http://www-128.ibm.com/developerworks/linux/library/l-md5crypt/)
*/ */
#include <QtCrypto>
#include <QCoreApplication> #include <QCoreApplication>
#include <QtCrypto>
#include <QtDebug> #include <QtDebug>
#include <stdio.h> #include <cstdio>
#ifdef QT_STATICPLUGIN #ifdef QT_STATICPLUGIN
#include "import_plugins.h" #include "import_plugins.h"
@ -36,29 +36,23 @@
QString to64(long v, int size) QString to64(long v, int size)
{ {
// Character set of the encrypted password: A-Za-z0-9./ // Character set of the encrypted password: A-Za-z0-9./
QString itoa64 = "./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"; QString itoa64 = QStringLiteral("./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz");
QString result; QString result;
while ( --size >= 0 ) while (--size >= 0) {
{
result.append(itoa64.at((int)(v & 0x3f))); result.append(itoa64.at((int)(v & 0x3f)));
v = v >> 6; v = v >> 6;
} }
return result; return result;
} }
int byte2unsigned(int byteValue) int byte2unsigned(int byteValue)
{ {
int integerToReturn; int integerToReturn;
integerToReturn = (int)byteValue & 0xff; integerToReturn = (int)byteValue & 0xff;
return integerToReturn; return integerToReturn;
} }
QString qca_md5crypt(const QCA::SecureArray &password, const QCA::SecureArray &salt) QString qca_md5crypt(const QCA::SecureArray &password, const QCA::SecureArray &salt)
@ -66,8 +60,8 @@ QString qca_md5crypt( const QCA::SecureArray &password, const QCA::SecureArray &
QCA::SecureArray finalState, magic_string = "$1$"; QCA::SecureArray finalState, magic_string = "$1$";
// The md5crypt algorithm uses two separate hashes // The md5crypt algorithm uses two separate hashes
QCA::Hash hash1( "md5" ); QCA::Hash hash1(QStringLiteral("md5"));
QCA::Hash hash2( "md5" ); QCA::Hash hash2(QStringLiteral("md5"));
// MD5 Hash #1: pwd, magic string and salt // MD5 Hash #1: pwd, magic string and salt
hash1.update(password); hash1.update(password);
@ -82,8 +76,7 @@ QString qca_md5crypt( const QCA::SecureArray &password, const QCA::SecureArray &
finalState = hash2.final(); finalState = hash2.final();
// Two sets of transformations based on the length of the password // Two sets of transformations based on the length of the password
for ( int i = password.size() ; i > 0 ; i -= 16 ) for (int i = password.size(); i > 0; i -= 16) {
{
// Update hash1 from offset value (i > 16 ? 16 : i) // Update hash1 from offset value (i > 16 ? 16 : i)
hash1.update(finalState.toByteArray().left(i > 16 ? 16 : i)); hash1.update(finalState.toByteArray().left(i > 16 ? 16 : i));
} }
@ -91,14 +84,10 @@ QString qca_md5crypt( const QCA::SecureArray &password, const QCA::SecureArray &
// Clear array bits // Clear array bits
finalState.fill(0); finalState.fill(0);
for ( int i = password.size() ; i != 0 ; i = i >> 1 ) for (int i = password.size(); i != 0; i = i >> 1) {
{ if ((i & 1) != 0) {
if ( ( i & 1 ) != 0 )
{
hash1.update(finalState.toByteArray().left(1)); hash1.update(finalState.toByteArray().left(1));
} } else {
else
{
hash1.update(password.toByteArray().left(1)); hash1.update(password.toByteArray().left(1));
} }
} }
@ -106,36 +95,26 @@ QString qca_md5crypt( const QCA::SecureArray &password, const QCA::SecureArray &
finalState = hash1.final(); finalState = hash1.final();
// Now build a 1000 entry dictionary... // Now build a 1000 entry dictionary...
for ( int i = 0 ; i < 1000 ; i++ ) for (int i = 0; i < 1000; i++) {
{
hash2.clear(); hash2.clear();
if ((i & 1) != 0) if ((i & 1) != 0) {
{
hash2.update(password); hash2.update(password);
} } else {
else
{
hash2.update(finalState.toByteArray().left(16)); hash2.update(finalState.toByteArray().left(16));
} }
if ((i % 3) != 0) if ((i % 3) != 0) {
{
hash2.update(salt); hash2.update(salt);
} }
if ((i % 7) != 0) if ((i % 7) != 0) {
{
hash2.update(password); hash2.update(password);
} }
if ((i & 1) != 0) if ((i & 1) != 0) {
{
hash2.update(finalState.toByteArray().left(16)); hash2.update(finalState.toByteArray().left(16));
} } else {
else
{
hash2.update(password); hash2.update(password);
} }
@ -146,34 +125,29 @@ QString qca_md5crypt( const QCA::SecureArray &password, const QCA::SecureArray &
// Salt is part of the encoded password ($1$<string>$) // Salt is part of the encoded password ($1$<string>$)
QString encodedString; QString encodedString;
encodedString.append ( magic_string.toByteArray() ); encodedString.append(QString::fromLatin1(magic_string.toByteArray()));
encodedString.append ( salt.toByteArray() ); encodedString.append(QString::fromLatin1(salt.toByteArray()));
encodedString.append ( "$" ); encodedString.append(QStringLiteral("$"));
long l; long l;
l = ( byte2unsigned (finalState.toByteArray().at(0) ) << 16 | l = (byte2unsigned(finalState.toByteArray().at(0)) << 16 | (byte2unsigned(finalState.toByteArray().at(6))) << 8 |
( byte2unsigned (finalState.toByteArray().at(6)) ) << 8 |
byte2unsigned(finalState.toByteArray().at(12))); byte2unsigned(finalState.toByteArray().at(12)));
encodedString.append(to64(l, 4)); encodedString.append(to64(l, 4));
l = ( byte2unsigned (finalState.toByteArray().at(1)) << 16 | l = (byte2unsigned(finalState.toByteArray().at(1)) << 16 | (byte2unsigned(finalState.toByteArray().at(7))) << 8 |
( byte2unsigned (finalState.toByteArray().at(7))) << 8 |
byte2unsigned(finalState.toByteArray().at(13))); byte2unsigned(finalState.toByteArray().at(13)));
encodedString.append(to64(l, 4)); encodedString.append(to64(l, 4));
l = ( byte2unsigned (finalState.toByteArray().at(2)) << 16 | l = (byte2unsigned(finalState.toByteArray().at(2)) << 16 | (byte2unsigned(finalState.toByteArray().at(8))) << 8 |
( byte2unsigned (finalState.toByteArray().at(8))) << 8 |
byte2unsigned(finalState.toByteArray().at(14))); byte2unsigned(finalState.toByteArray().at(14)));
encodedString.append(to64(l, 4)); encodedString.append(to64(l, 4));
l = ( byte2unsigned (finalState.toByteArray().at(3)) << 16 | l = (byte2unsigned(finalState.toByteArray().at(3)) << 16 | (byte2unsigned(finalState.toByteArray().at(9))) << 8 |
( byte2unsigned (finalState.toByteArray().at(9))) << 8 |
byte2unsigned(finalState.toByteArray().at(15))); byte2unsigned(finalState.toByteArray().at(15)));
encodedString.append(to64(l, 4)); encodedString.append(to64(l, 4));
l = ( byte2unsigned (finalState.toByteArray().at(4)) << 16 | l = (byte2unsigned(finalState.toByteArray().at(4)) << 16 | (byte2unsigned(finalState.toByteArray().at(10))) << 8 |
( byte2unsigned (finalState.toByteArray().at(10))) << 8 |
byte2unsigned(finalState.toByteArray().at(5))); byte2unsigned(finalState.toByteArray().at(5)));
encodedString.append(to64(l, 4)); encodedString.append(to64(l, 4));
@ -185,7 +159,6 @@ QString qca_md5crypt( const QCA::SecureArray &password, const QCA::SecureArray &
int main(int argc, char **argv) int main(int argc, char **argv)
{ {
// the Initializer object sets things up, and // the Initializer object sets things up, and
// also does cleanup when it goes out of scope // also does cleanup when it goes out of scope
QCA::Initializer init; QCA::Initializer init;
@ -194,8 +167,7 @@ int main(int argc, char **argv)
QCA::SecureArray password, salt; QCA::SecureArray password, salt;
if ( argc < 3 ) if (argc < 3) {
{
printf("Usage: %s password salt (salt without $1$)\n", argv[0]); printf("Usage: %s password salt (salt without $1$)\n", argv[0]);
return 1; return 1;
} }
@ -207,19 +179,15 @@ int main(int argc, char **argv)
// must always check that an algorithm is supported before using it // must always check that an algorithm is supported before using it
if (!QCA::isSupported("md5")) if (!QCA::isSupported("md5"))
printf("MD5 hash not supported!\n"); printf("MD5 hash not supported!\n");
else else {
{
QString result = qca_md5crypt(password, salt); QString result = qca_md5crypt(password, salt);
printf("md5crypt [ %s , %s ] = '%s'\n", password.data(), salt.data(), qPrintable(result)); printf("md5crypt [ %s , %s ] = '%s'\n", password.data(), salt.data(), qPrintable(result));
// this is equivalent if you have GNU libc 2.0 // this is equivalent if you have GNU libc 2.0
// printf( "GNU md5crypt [ %s , %s ] = '%s'\n", password.data(), salt.data(), crypt( password.data(), ( "$1$"+salt ).data() ) ); // printf( "GNU md5crypt [ %s , %s ] = '%s'\n", password.data(), salt.data(), crypt( password.data(), (
// "$1$"+salt ).data() ) );
} }
return 0; return 0;
} }

View File

@ -20,8 +20,8 @@
*/ */
// QtCrypto has the declarations for all of QCA // QtCrypto has the declarations for all of QCA
#include <QtCrypto>
#include <QCoreApplication> #include <QCoreApplication>
#include <QtCrypto>
#include <iostream> #include <iostream>
#include <qstringlist.h> #include <qstringlist.h>
@ -44,15 +44,15 @@ int main(int argc, char **argv)
QCA::scanForPlugins(); QCA::scanForPlugins();
// this gives us all the plugin providers as a list // this gives us all the plugin providers as a list
QCA::ProviderList qcaProviders = QCA::providers(); const QCA::ProviderList qcaProviders = QCA::providers();
for (int i = 0; i < qcaProviders.size(); ++i) { for (const QCA::Provider *provider : qcaProviders) {
// each provider has a name, which we can display // each provider has a name, which we can display
std::cout << qcaProviders[i]->name().toLatin1().data() << ": "; std::cout << provider->name().toLatin1().data() << ": ";
// ... and also a list of features // ... and also a list of features
QStringList capabilities = qcaProviders[i]->features(); QStringList capabilities = provider->features();
// we turn the string list back into a single string, // we turn the string list back into a single string,
// and display it as well // and display it as well
std::cout << capabilities.join(", ").toLatin1().data() << std::endl; std::cout << capabilities.join(QStringLiteral(", ")).toLatin1().data() << std::endl;
} }
// Note that the default provider isn't included in // Note that the default provider isn't included in
@ -61,7 +61,6 @@ int main(int argc, char **argv)
// However it is still possible to get the features // However it is still possible to get the features
// supported by the default provider // supported by the default provider
QStringList capabilities = QCA::defaultFeatures(); QStringList capabilities = QCA::defaultFeatures();
std::cout << capabilities.join(", ").toLatin1().data() << std::endl; std::cout << capabilities.join(QStringLiteral(", ")).toLatin1().data() << std::endl;
return 0; return 0;
} }

View File

@ -20,7 +20,6 @@
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/ */
#include <QtCrypto> #include <QtCrypto>
#include <QCoreApplication> #include <QCoreApplication>
@ -49,7 +48,7 @@ int main(int argc, char** argv)
QCA::PrivateKey privKey; QCA::PrivateKey privKey;
QCA::ConvertResult convRes; QCA::ConvertResult convRes;
QCA::SecureArray passPhrase = "start"; QCA::SecureArray passPhrase = "start";
privKey = QCA::PrivateKey::fromPEMFile( "Userkey.pem", passPhrase, &convRes ); privKey = QCA::PrivateKey::fromPEMFile(QStringLiteral("Userkey.pem"), passPhrase, &convRes);
if (convRes != QCA::ConvertGood) { if (convRes != QCA::ConvertGood) {
std::cout << "Sorry, could not import Private Key" << std::endl; std::cout << "Sorry, could not import Private Key" << std::endl;
return 1; return 1;
@ -57,7 +56,7 @@ int main(int argc, char** argv)
// Read in a matching public key cert // Read in a matching public key cert
// you could also build this using the fromPEMFile() method // you could also build this using the fromPEMFile() method
QCA::Certificate pubCert( "User.pem" ); QCA::Certificate pubCert(QStringLiteral("User.pem"));
if (pubCert.isNull()) { if (pubCert.isNull()) {
std::cout << "Sorry, could not import public key certificate" << std::endl; std::cout << "Sorry, could not import public key certificate" << std::endl;
return 1; return 1;
@ -85,8 +84,7 @@ int main(int argc, char** argv)
msg.waitForFinished(1000); msg.waitForFinished(1000);
// check to see if it worked // check to see if it worked
if(!msg.success()) if (!msg.success()) {
{
std::cout << "Error encrypting: " << msg.errorCode() << std::endl; std::cout << "Error encrypting: " << msg.errorCode() << std::endl;
return 1; return 1;
} }
@ -114,4 +112,3 @@ int main(int argc, char** argv)
return 0; return 0;
} }

View File

@ -70,4 +70,3 @@ int main(int argc, char **argv)
tenBytes = myRandomObject.nextBytes(10); tenBytes = myRandomObject.nextBytes(10);
return 0; return 0;
} }

View File

@ -20,8 +20,8 @@
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/ */
#include <QtCrypto>
#include <QCoreApplication> #include <QCoreApplication>
#include <QtCrypto>
#include <iostream> #include <iostream>
@ -43,8 +43,7 @@ int main(int argc, char **argv)
// We demonstrate PEM usage here, so we need to test for // We demonstrate PEM usage here, so we need to test for
// supportedIOTypes, not just supportedTypes // supportedIOTypes, not just supportedTypes
if(!QCA::isSupported("pkey") || if (!QCA::isSupported("pkey") || !QCA::PKey::supportedIOTypes().contains(QCA::PKey::RSA))
!QCA::PKey::supportedIOTypes().contains(QCA::PKey::RSA))
std::cout << "RSA not supported!\n"; std::cout << "RSA not supported!\n";
else { else {
// When creating a public / private key pair, you make the // When creating a public / private key pair, you make the
@ -86,13 +85,12 @@ int main(int argc, char **argv)
// somewhere secure and has a good pass phrase // somewhere secure and has a good pass phrase
// You can use the same technique with the public key too. // You can use the same technique with the public key too.
QCA::SecureArray passPhrase = "pass phrase"; QCA::SecureArray passPhrase = "pass phrase";
seckey.toPEMFile("keyprivate.pem", passPhrase); seckey.toPEMFile(QStringLiteral("keyprivate.pem"), passPhrase);
// Read that key back in, checking if the read succeeded // Read that key back in, checking if the read succeeded
QCA::ConvertResult conversionResult; QCA::ConvertResult conversionResult;
QCA::PrivateKey privateKey = QCA::PrivateKey::fromPEMFile( "keyprivate.pem", QCA::PrivateKey privateKey =
passPhrase, QCA::PrivateKey::fromPEMFile(QStringLiteral("keyprivate.pem"), passPhrase, &conversionResult);
&conversionResult);
if (!(QCA::ConvertGood == conversionResult)) { if (!(QCA::ConvertGood == conversionResult)) {
std::cout << "Private key read failed" << std::endl; std::cout << "Private key read failed" << std::endl;
} }
@ -109,7 +107,6 @@ int main(int argc, char **argv)
std::cout << "\"" << qPrintable(rstr) << "\" decrypted with RSA is \""; std::cout << "\"" << qPrintable(rstr) << "\" decrypted with RSA is \"";
std::cout << decrypt.data() << "\"" << std::endl; std::cout << decrypt.data() << "\"" << std::endl;
// Some private keys can also be used for producing signatures // Some private keys can also be used for producing signatures
if (!privateKey.canSign()) { if (!privateKey.canSign()) {
std::cout << "Error: this kind of key cannot sign" << std::endl; std::cout << "Error: this kind of key cannot sign" << std::endl;
@ -143,15 +140,12 @@ int main(int argc, char **argv)
// We can also do the verification in a single step if we // We can also do the verification in a single step if we
// have all the message // have all the message
if ( pubkey.canVerify() && if (pubkey.canVerify() && pubkey.verifyMessage(arg, argSig, QCA::EMSA3_MD5)) {
pubkey.verifyMessage( arg, argSig, QCA::EMSA3_MD5 ) ) {
std::cout << "Signature is valid" << std::endl; std::cout << "Signature is valid" << std::endl;
} else { } else {
std::cout << "Signature could not be verified" << std::endl; std::cout << "Signature could not be verified" << std::endl;
} }
} }
return 0; return 0;
} }

View File

@ -1,8 +1,10 @@
set(saslclient_bin_SRCS saslclient.cpp) set(saslclient_bin_SRCS saslclient.cpp)
MY_AUTOMOC( saslclient_bin_SRCS)
add_executable(saslclient ${saslclient_bin_SRCS}) add_executable(saslclient ${saslclient_bin_SRCS})
target_link_qca_libraries(saslclient) target_link_qca_libraries(saslclient)
target_link_libraries(saslclient ${QT_QTNETWORK_LIBRARY}) if(QT6)
target_link_libraries(saslclient Qt6::Network)
else()
target_link_libraries(saslclient Qt5::Network)
endif()

View File

@ -21,10 +21,10 @@
*/ */
#include <QCoreApplication> #include <QCoreApplication>
#include <QTimer>
#include <QTcpSocket>
#include <QTcpServer> #include <QTcpServer>
#include <stdio.h> #include <QTcpSocket>
#include <QTimer>
#include <cstdio>
// QtCrypto has the declarations for all of QCA // QtCrypto has the declarations for all of QCA
#include <QtCrypto> #include <QtCrypto>
@ -39,8 +39,8 @@ static QString prompt(const QString &s)
fflush(stdout); fflush(stdout);
char line[256]; char line[256];
fgets(line, 255, stdin); fgets(line, 255, stdin);
QString result = line; QString result = QString::fromLatin1(line);
if(result[result.length()-1] == '\n') if (result[result.length() - 1] == QLatin1Char('\n'))
result.truncate(result.length() - 1); result.truncate(result.length() - 1);
return result; return result;
} }
@ -48,32 +48,43 @@ static QString prompt(const QString &s)
static QString socketErrorToString(QAbstractSocket::SocketError x) static QString socketErrorToString(QAbstractSocket::SocketError x)
{ {
QString s; QString s;
switch(x) switch (x) {
{
case QAbstractSocket::ConnectionRefusedError: case QAbstractSocket::ConnectionRefusedError:
s = "connection refused or timed out"; break; s = QStringLiteral("connection refused or timed out");
break;
case QAbstractSocket::RemoteHostClosedError: case QAbstractSocket::RemoteHostClosedError:
s = "remote host closed the connection"; break; s = QStringLiteral("remote host closed the connection");
break;
case QAbstractSocket::HostNotFoundError: case QAbstractSocket::HostNotFoundError:
s = "host not found"; break; s = QStringLiteral("host not found");
break;
case QAbstractSocket::SocketAccessError: case QAbstractSocket::SocketAccessError:
s = "access error"; break; s = QStringLiteral("access error");
break;
case QAbstractSocket::SocketResourceError: case QAbstractSocket::SocketResourceError:
s = "too many sockets"; break; s = QStringLiteral("too many sockets");
break;
case QAbstractSocket::SocketTimeoutError: case QAbstractSocket::SocketTimeoutError:
s = "operation timed out"; break; s = QStringLiteral("operation timed out");
break;
case QAbstractSocket::DatagramTooLargeError: case QAbstractSocket::DatagramTooLargeError:
s = "datagram was larger than system limit"; break; s = QStringLiteral("datagram was larger than system limit");
break;
case QAbstractSocket::NetworkError: case QAbstractSocket::NetworkError:
s = "network error"; break; s = QStringLiteral("network error");
break;
case QAbstractSocket::AddressInUseError: case QAbstractSocket::AddressInUseError:
s = "address is already in use"; break; s = QStringLiteral("address is already in use");
break;
case QAbstractSocket::SocketAddressNotAvailableError: case QAbstractSocket::SocketAddressNotAvailableError:
s = "address does not belong to the host"; break; s = QStringLiteral("address does not belong to the host");
break;
case QAbstractSocket::UnsupportedSocketOperationError: case QAbstractSocket::UnsupportedSocketOperationError:
s = "operation is not supported by the local operating system"; break; s = QStringLiteral("operation is not supported by the local operating system");
break;
default: default:
s = "unknown socket error"; break; s = QStringLiteral("unknown socket error");
break;
} }
return s; return s;
} }
@ -81,17 +92,20 @@ static QString socketErrorToString(QAbstractSocket::SocketError x)
static QString saslAuthConditionToString(QCA::SASL::AuthCondition x) static QString saslAuthConditionToString(QCA::SASL::AuthCondition x)
{ {
QString s; QString s;
switch(x) switch (x) {
{
case QCA::SASL::NoMechanism: case QCA::SASL::NoMechanism:
s = "no appropriate mechanism could be negotiated"; break; s = QStringLiteral("no appropriate mechanism could be negotiated");
break;
case QCA::SASL::BadProtocol: case QCA::SASL::BadProtocol:
s = "bad SASL protocol"; break; s = QStringLiteral("bad SASL protocol");
break;
case QCA::SASL::BadServer: case QCA::SASL::BadServer:
s = "server failed mutual authentication"; break; s = QStringLiteral("server failed mutual authentication");
break;
// AuthFail or unknown (including those defined for server only) // AuthFail or unknown (including those defined for server only)
default: default:
s = "generic authentication failure"; break; s = QStringLiteral("generic authentication failure");
break;
}; };
return s; return s;
} }
@ -112,35 +126,47 @@ private:
int waitCycles; int waitCycles;
public: public:
ClientTest(const QString &_host, int _port, const QString &_proto, const QString &_authzid, const QString &_realm, const QString &_user, const QString &_pass, bool _no_authzid, bool _no_realm) : ClientTest(const QString &_host,
host(_host), int _port,
proto(_proto), const QString &_proto,
authzid(_authzid), const QString &_authzid,
realm(_realm), const QString &_realm,
user(_user), const QString &_user,
pass(_pass), const QString &_pass,
port(_port), bool _no_authzid,
no_authzid(_no_authzid), bool _no_realm)
no_realm(_no_realm), : host(_host)
sock_done(false), , proto(_proto)
waitCycles(0) , authzid(_authzid)
, realm(_realm)
, user(_user)
, pass(_pass)
, port(_port)
, no_authzid(_no_authzid)
, no_realm(_no_realm)
, sock_done(false)
, waitCycles(0)
{ {
sock = new QTcpSocket(this); sock = new QTcpSocket(this);
connect(sock, SIGNAL(connected()), SLOT(sock_connected())); connect(sock, &QTcpSocket::connected, this, &ClientTest::sock_connected);
connect(sock, SIGNAL(readyRead()), SLOT(sock_readyRead())); connect(sock, &QTcpSocket::readyRead, this, &ClientTest::sock_readyRead);
connect(sock, SIGNAL(error(QAbstractSocket::SocketError)), SLOT(sock_error(QAbstractSocket::SocketError))); #if QT_VERSION >= QT_VERSION_CHECK(5, 15, 0)
connect(sock, &QTcpSocket::errorOccurred, this, &ClientTest::sock_error);
#else
connect(sock, QOverload<QAbstractSocket::SocketError>::of(&QTcpSocket::error), this, &ClientTest::sock_error);
#endif
sasl = new QCA::SASL(this); sasl = new QCA::SASL(this);
connect(sasl, SIGNAL(clientStarted(bool, const QByteArray &)), SLOT(sasl_clientFirstStep(bool, const QByteArray &))); connect(sasl, &QCA::SASL::clientStarted, this, &ClientTest::sasl_clientFirstStep);
connect(sasl, SIGNAL(nextStep(const QByteArray &)), SLOT(sasl_nextStep(const QByteArray &))); connect(sasl, &QCA::SASL::nextStep, this, &ClientTest::sasl_nextStep);
connect(sasl, SIGNAL(needParams(const QCA::SASL::Params &)), SLOT(sasl_needParams(const QCA::SASL::Params &))); connect(sasl, &QCA::SASL::needParams, this, &ClientTest::sasl_needParams);
connect(sasl, SIGNAL(authenticated()), SLOT(sasl_authenticated())); connect(sasl, &QCA::SASL::authenticated, this, &ClientTest::sasl_authenticated);
connect(sasl, SIGNAL(readyRead()), SLOT(sasl_readyRead())); connect(sasl, &QCA::SASL::readyRead, this, &ClientTest::sasl_readyRead);
connect(sasl, SIGNAL(readyReadOutgoing()), SLOT(sasl_readyReadOutgoing())); connect(sasl, &QCA::SASL::readyReadOutgoing, this, &ClientTest::sasl_readyReadOutgoing);
connect(sasl, SIGNAL(error()), SLOT(sasl_error())); connect(sasl, &QCA::SASL::error, this, &ClientTest::sasl_error);
} }
public slots: public Q_SLOTS:
void start() void start()
{ {
mode = 0; // mech list mode mode = 0; // mech list mode
@ -163,10 +189,10 @@ public slots:
sock->connectToHost(host, port); sock->connectToHost(host, port);
} }
signals: Q_SIGNALS:
void quit(); void quit();
private slots: private Q_SLOTS:
void sock_connected() void sock_connected()
{ {
printf("Connected to server. Awaiting mechanism list...\n"); printf("Connected to server. Awaiting mechanism list...\n");
@ -174,15 +200,13 @@ private slots:
void sock_error(QAbstractSocket::SocketError x) void sock_error(QAbstractSocket::SocketError x)
{ {
if(x == QAbstractSocket::RemoteHostClosedError) if (x == QAbstractSocket::RemoteHostClosedError) {
{
if (mode == 2) // app mode, where disconnect means completion if (mode == 2) // app mode, where disconnect means completion
{ {
sock_done = true; sock_done = true;
tryFinished(); tryFinished();
return; return;
} } else // any other mode, where disconnect is an error
else // any other mode, where disconnect is an error
{ {
printf("Error: server closed connection unexpectedly.\n"); printf("Error: server closed connection unexpectedly.\n");
emit quit(); emit quit();
@ -199,7 +223,7 @@ private slots:
if (mode == 2) // app mode if (mode == 2) // app mode
{ {
QByteArray a = sock->readAll(); QByteArray a = sock->readAll();
printf("Read %d bytes\n", a.size()); printf("Read %d bytes\n", int(a.size()));
// there is a possible flaw in the qca 2.0 api, in // there is a possible flaw in the qca 2.0 api, in
// that if sasl data is received from the peer // that if sasl data is received from the peer
@ -224,19 +248,16 @@ private slots:
// protocols that have no close message of their // protocols that have no close message of their
// own, and rely on the tcp-level close. examples // own, and rely on the tcp-level close. examples
// are http, and of course this qcatest protocol. // are http, and of course this qcatest protocol.
if(waitCycles == 0) if (waitCycles == 0) {
{
waitCycles = 3; waitCycles = 3;
QMetaObject::invokeMethod(this, "waitWriteIncoming", Qt::QueuedConnection); QMetaObject::invokeMethod(this, "waitWriteIncoming", Qt::QueuedConnection);
} }
sasl->writeIncoming(a); sasl->writeIncoming(a);
} } else // mech list or sasl negotiation mode
else // mech list or sasl negotiation mode
{ {
if(sock->canReadLine()) if (sock->canReadLine()) {
{ QString line = QString::fromLatin1(sock->readLine());
QString line = sock->readLine();
line.truncate(line.length() - 1); // chop the newline line.truncate(line.length() - 1); // chop the newline
handleLine(line); handleLine(line);
} }
@ -247,9 +268,8 @@ private slots:
{ {
printf("Choosing mech: %s\n", qPrintable(sasl->mechanism())); printf("Choosing mech: %s\n", qPrintable(sasl->mechanism()));
QString line = sasl->mechanism(); QString line = sasl->mechanism();
if(clientInit) if (clientInit) {
{ line += QLatin1Char(' ');
line += ' ';
line += arrayToString(clientInitData); line += arrayToString(clientInitData);
} }
sendLine(line); sendLine(line);
@ -257,10 +277,9 @@ private slots:
void sasl_nextStep(const QByteArray &stepData) void sasl_nextStep(const QByteArray &stepData)
{ {
QString line = "C"; QString line = QStringLiteral("C");
if(!stepData.isEmpty()) if (!stepData.isEmpty()) {
{ line += QLatin1Char(',');
line += ',';
line += arrayToString(stepData); line += arrayToString(stepData);
} }
sendLine(line); sendLine(line);
@ -268,37 +287,33 @@ private slots:
void sasl_needParams(const QCA::SASL::Params &params) void sasl_needParams(const QCA::SASL::Params &params)
{ {
if(params.needUsername()) if (params.needUsername()) {
{ user = prompt(QStringLiteral("Username:"));
user = prompt("Username:");
sasl->setUsername(user); sasl->setUsername(user);
} }
if(params.canSendAuthzid() && !no_authzid) if (params.canSendAuthzid() && !no_authzid) {
{ authzid = prompt(QStringLiteral("Authorize As (enter to skip):"));
authzid = prompt("Authorize As (enter to skip):");
if (!authzid.isEmpty()) if (!authzid.isEmpty())
sasl->setAuthzid(authzid); sasl->setAuthzid(authzid);
} }
if(params.needPassword()) if (params.needPassword()) {
{
QCA::ConsolePrompt prompt; QCA::ConsolePrompt prompt;
prompt.getHidden("* Password"); prompt.getHidden(QStringLiteral("* Password"));
prompt.waitForFinished(); prompt.waitForFinished();
QCA::SecureArray pass = prompt.result(); QCA::SecureArray pass = prompt.result();
sasl->setPassword(pass); sasl->setPassword(pass);
} }
if(params.canSendRealm() && !no_realm) if (params.canSendRealm() && !no_realm) {
{
QStringList realms = sasl->realmList(); QStringList realms = sasl->realmList();
printf("Available realms:\n"); printf("Available realms:\n");
if (realms.isEmpty()) if (realms.isEmpty())
printf(" (none specified)\n"); printf(" (none specified)\n");
foreach (const QString &s, realms) foreach (const QString &s, realms)
printf(" %s\n", qPrintable(s)); printf(" %s\n", qPrintable(s));
realm = prompt("Realm (enter to skip):"); realm = prompt(QStringLiteral("Realm (enter to skip):"));
if (!realm.isEmpty()) if (!realm.isEmpty())
sasl->setRealm(realm); sasl->setRealm(realm);
} }
@ -343,8 +358,7 @@ private slots:
void waitWriteIncoming() void waitWriteIncoming()
{ {
--waitCycles; --waitCycles;
if(waitCycles > 0) if (waitCycles > 0) {
{
QMetaObject::invokeMethod(this, "waitWriteIncoming", Qt::QueuedConnection); QMetaObject::invokeMethod(this, "waitWriteIncoming", Qt::QueuedConnection);
return; return;
} }
@ -355,8 +369,7 @@ private slots:
private: private:
void tryFinished() void tryFinished()
{ {
if(sock_done && waitCycles == 0) if (sock_done && waitCycles == 0) {
{
printf("Finished, server closed connection.\n"); printf("Finished, server closed connection.\n");
// if we give up on waiting for a response to // if we give up on waiting for a response to
@ -388,7 +401,7 @@ private:
void sendLine(const QString &line) void sendLine(const QString &line)
{ {
printf("Writing: {%s}\n", qPrintable(line)); printf("Writing: {%s}\n", qPrintable(line));
QString s = line + '\n'; QString s = line + QLatin1Char('\n');
QByteArray a = s.toUtf8(); QByteArray a = s.toUtf8();
if (mode == 2) // app mode if (mode == 2) // app mode
sasl->write(a); // write to sasl sasl->write(a); // write to sasl
@ -401,8 +414,7 @@ private:
// collect completed lines from inbuf // collect completed lines from inbuf
QStringList list; QStringList list;
int at; int at;
while((at = inbuf.indexOf('\n')) != -1) while ((at = inbuf.indexOf('\n')) != -1) {
{
list += QString::fromUtf8(inbuf.mid(0, at)); list += QString::fromUtf8(inbuf.mid(0, at));
inbuf = inbuf.mid(at + 1); inbuf = inbuf.mid(at + 1);
} }
@ -415,40 +427,30 @@ private:
void handleLine(const QString &line) void handleLine(const QString &line)
{ {
printf("Reading: [%s]\n", qPrintable(line)); printf("Reading: [%s]\n", qPrintable(line));
if(mode == 0) if (mode == 0) {
{
// first line is the method list // first line is the method list
QStringList mechlist = line.split(' '); const QStringList mechlist = line.split(QLatin1Char(' '));
mode = 1; // switch to sasl negotiation mode mode = 1; // switch to sasl negotiation mode
sasl->startClient(proto, host, mechlist); sasl->startClient(proto, host, mechlist);
} } else if (mode == 1) {
else if(mode == 1)
{
QString type, rest; QString type, rest;
int n = line.indexOf(','); int n = line.indexOf(QLatin1Char(','));
if(n != -1) if (n != -1) {
{
type = line.mid(0, n); type = line.mid(0, n);
rest = line.mid(n + 1); rest = line.mid(n + 1);
} } else
else
type = line; type = line;
if(type == "C") if (type == QLatin1String("C")) {
{
sasl->putStep(stringToArray(rest)); sasl->putStep(stringToArray(rest));
} } else if (type == QLatin1String("E")) {
else if(type == "E")
{
if (!rest.isEmpty()) if (!rest.isEmpty())
printf("Error: server says: %s.\n", qPrintable(rest)); printf("Error: server says: %s.\n", qPrintable(rest));
else else
printf("Error: server error, unspecified.\n"); printf("Error: server error, unspecified.\n");
emit quit(); emit quit();
return; return;
} } else if (type == QLatin1String("A")) {
else if(type == "A")
{
printf("Authentication success.\n"); printf("Authentication success.\n");
mode = 2; // switch to app mode mode = 2; // switch to app mode
@ -457,9 +459,7 @@ private:
sock_readyRead(); // any extra data? sock_readyRead(); // any extra data?
return; return;
} } else {
else
{
printf("Error: Bad format from peer, closing.\n"); printf("Error: Bad format from peer, closing.\n");
emit quit(); emit quit();
return; return;
@ -483,40 +483,32 @@ int main(int argc, char **argv)
args.removeFirst(); args.removeFirst();
// options // options
QString proto = "qcatest"; // default protocol QString proto = QStringLiteral("qcatest"); // default protocol
QString authzid, realm; QString authzid, realm;
bool no_authzid = false; bool no_authzid = false;
bool no_realm = false; bool no_realm = false;
for(int n = 0; n < args.count(); ++n) for (int n = 0; n < args.count(); ++n) {
{ if (!args[n].startsWith(QLatin1String("--")))
if(!args[n].startsWith("--"))
continue; continue;
QString opt = args[n].mid(2); QString opt = args[n].mid(2);
QString var, val; QString var, val;
int at = opt.indexOf('='); int at = opt.indexOf(QLatin1Char('='));
if(at != -1) if (at != -1) {
{
var = opt.mid(0, at); var = opt.mid(0, at);
val = opt.mid(at + 1); val = opt.mid(at + 1);
} } else
else
var = opt; var = opt;
if(var == "proto") if (var == QLatin1String("proto")) {
{
proto = val; proto = val;
} } else if (var == QLatin1String("authzid")) {
else if(var == "authzid")
{
// specifying empty authzid means force unspecified // specifying empty authzid means force unspecified
if (val.isEmpty()) if (val.isEmpty())
no_authzid = true; no_authzid = true;
else else
authzid = val; authzid = val;
} } else if (var == QLatin1String("realm")) {
else if(var == "realm")
{
// specifying empty realm means force unspecified // specifying empty realm means force unspecified
if (val.isEmpty()) if (val.isEmpty())
no_realm = true; no_realm = true;
@ -528,8 +520,7 @@ int main(int argc, char **argv)
--n; // adjust position --n; // adjust position
} }
if(args.count() < 1) if (args.count() < 1) {
{
usage(); usage();
return 0; return 0;
} }
@ -543,24 +534,25 @@ int main(int argc, char **argv)
if (args.count() >= 3) if (args.count() >= 3)
pass = args[2]; pass = args[2];
int at = hostinput.indexOf(':'); int at = hostinput.indexOf(QLatin1Char(':'));
if(at != -1) if (at != -1) {
{
host = hostinput.mid(0, at); host = hostinput.mid(0, at);
port = hostinput.mid(at + 1).toInt(); #if QT_VERSION >= QT_VERSION_CHECK(5, 15, 2)
} port = QStringView(hostinput).mid(at + 1).toInt();
else #else
port = hostinput.midRef(at + 1).toInt();
#endif
} else
host = hostinput; host = hostinput;
if(!QCA::isSupported("sasl")) if (!QCA::isSupported("sasl")) {
{
printf("Error: SASL support not found.\n"); printf("Error: SASL support not found.\n");
return 1; return 1;
} }
ClientTest client(host, port, proto, authzid, realm, user, pass, no_authzid, no_realm); ClientTest client(host, port, proto, authzid, realm, user, pass, no_authzid, no_realm);
QObject::connect(&client, SIGNAL(quit()), &qapp, SLOT(quit())); QObject::connect(&client, &ClientTest::quit, &qapp, &QCoreApplication::quit);
QTimer::singleShot(0, &client, SLOT(start())); QTimer::singleShot(0, &client, &ClientTest::start);
qapp.exec(); qapp.exec();
return 0; return 0;

View File

@ -1,8 +1,10 @@
set(saslserver_bin_SRCS saslserver.cpp) set(saslserver_bin_SRCS saslserver.cpp)
MY_AUTOMOC( saslserver_bin_SRCS)
add_executable(saslserver ${saslserver_bin_SRCS}) add_executable(saslserver ${saslserver_bin_SRCS})
target_link_qca_libraries(saslserver) target_link_qca_libraries(saslserver)
target_link_libraries(saslserver ${QT_QTNETWORK_LIBRARY}) if(QT6)
target_link_libraries(saslserver Qt6::Network)
else()
target_link_libraries(saslserver Qt5::Network)
endif()

View File

@ -21,10 +21,10 @@
*/ */
#include <QCoreApplication> #include <QCoreApplication>
#include <QTimer>
#include <QTcpSocket>
#include <QTcpServer> #include <QTcpServer>
#include <stdio.h> #include <QTcpSocket>
#include <QTimer>
#include <cstdio>
// QtCrypto has the declarations for all of QCA // QtCrypto has the declarations for all of QCA
#include <QtCrypto> #include <QtCrypto>
@ -36,32 +36,43 @@
static QString socketErrorToString(QAbstractSocket::SocketError x) static QString socketErrorToString(QAbstractSocket::SocketError x)
{ {
QString s; QString s;
switch(x) switch (x) {
{
case QAbstractSocket::ConnectionRefusedError: case QAbstractSocket::ConnectionRefusedError:
s = "connection refused or timed out"; break; s = QStringLiteral("connection refused or timed out");
break;
case QAbstractSocket::RemoteHostClosedError: case QAbstractSocket::RemoteHostClosedError:
s = "remote host closed the connection"; break; s = QStringLiteral("remote host closed the connection");
break;
case QAbstractSocket::HostNotFoundError: case QAbstractSocket::HostNotFoundError:
s = "host not found"; break; s = QStringLiteral("host not found");
break;
case QAbstractSocket::SocketAccessError: case QAbstractSocket::SocketAccessError:
s = "access error"; break; s = QStringLiteral("access error");
break;
case QAbstractSocket::SocketResourceError: case QAbstractSocket::SocketResourceError:
s = "too many sockets"; break; s = QStringLiteral("too many sockets");
break;
case QAbstractSocket::SocketTimeoutError: case QAbstractSocket::SocketTimeoutError:
s = "operation timed out"; break; s = QStringLiteral("operation timed out");
break;
case QAbstractSocket::DatagramTooLargeError: case QAbstractSocket::DatagramTooLargeError:
s = "datagram was larger than system limit"; break; s = QStringLiteral("datagram was larger than system limit");
break;
case QAbstractSocket::NetworkError: case QAbstractSocket::NetworkError:
s = "network error"; break; s = QStringLiteral("network error");
break;
case QAbstractSocket::AddressInUseError: case QAbstractSocket::AddressInUseError:
s = "address is already in use"; break; s = QStringLiteral("address is already in use");
break;
case QAbstractSocket::SocketAddressNotAvailableError: case QAbstractSocket::SocketAddressNotAvailableError:
s = "address does not belong to the host"; break; s = QStringLiteral("address does not belong to the host");
break;
case QAbstractSocket::UnsupportedSocketOperationError: case QAbstractSocket::UnsupportedSocketOperationError:
s = "operation is not supported by the local operating system"; break; s = QStringLiteral("operation is not supported by the local operating system");
break;
default: default:
s = "unknown socket error"; break; s = QStringLiteral("unknown socket error");
break;
} }
return s; return s;
} }
@ -69,31 +80,41 @@ static QString socketErrorToString(QAbstractSocket::SocketError x)
static QString saslAuthConditionToString(QCA::SASL::AuthCondition x) static QString saslAuthConditionToString(QCA::SASL::AuthCondition x)
{ {
QString s; QString s;
switch(x) switch (x) {
{
case QCA::SASL::NoMechanism: case QCA::SASL::NoMechanism:
s = "no appropriate mechanism could be negotiated"; break; s = QStringLiteral("no appropriate mechanism could be negotiated");
break;
case QCA::SASL::BadProtocol: case QCA::SASL::BadProtocol:
s = "bad SASL protocol"; break; s = QStringLiteral("bad SASL protocol");
break;
case QCA::SASL::BadAuth: case QCA::SASL::BadAuth:
s = "authentication failed"; break; s = QStringLiteral("authentication failed");
break;
case QCA::SASL::NoAuthzid: case QCA::SASL::NoAuthzid:
s = "authorization failed"; break; s = QStringLiteral("authorization failed");
break;
case QCA::SASL::TooWeak: case QCA::SASL::TooWeak:
s = "mechanism too weak for this user"; break; s = QStringLiteral("mechanism too weak for this user");
break;
case QCA::SASL::NeedEncrypt: case QCA::SASL::NeedEncrypt:
s = "encryption is needed to use this mechanism"; break; s = QStringLiteral("encryption is needed to use this mechanism");
break;
case QCA::SASL::Expired: case QCA::SASL::Expired:
s = "passphrase expired"; break; s = QStringLiteral("passphrase expired");
break;
case QCA::SASL::Disabled: case QCA::SASL::Disabled:
s = "account is disabled"; break; s = QStringLiteral("account is disabled");
break;
case QCA::SASL::NoUser: case QCA::SASL::NoUser:
s = "user not found"; break; s = QStringLiteral("user not found");
break;
case QCA::SASL::RemoteUnavailable: case QCA::SASL::RemoteUnavailable:
s = "needed remote service is unavailable"; break; s = QStringLiteral("needed remote service is unavailable");
break;
// AuthFail or unknown (including those defined for client only) // AuthFail or unknown (including those defined for client only)
default: default:
s = "generic authentication failure"; break; s = QStringLiteral("generic authentication failure");
break;
}; };
return s; return s;
} }
@ -116,13 +137,13 @@ public:
int reserveId(); int reserveId();
void releaseId(int id); void releaseId(int id);
public slots: public Q_SLOTS:
void start(); void start();
signals: Q_SIGNALS:
void quit(); void quit();
private slots: private Q_SLOTS:
void server_newConnection(); void server_newConnection();
}; };
@ -142,30 +163,42 @@ private:
int toWrite; int toWrite;
public: public:
ServerTestHandler(ServerTest *_serverTest, QTcpSocket *_sock, const QString &_host, const QString &_proto, const QString &_realm, const QString &_str) : ServerTestHandler(ServerTest * _serverTest,
serverTest(_serverTest), QTcpSocket * _sock,
sock(_sock), const QString &_host,
host(_host), const QString &_proto,
proto(_proto), const QString &_realm,
realm(_realm), const QString &_str)
str(_str) : serverTest(_serverTest)
, sock(_sock)
, host(_host)
, proto(_proto)
, realm(_realm)
, str(_str)
{ {
id = serverTest->reserveId(); id = serverTest->reserveId();
sock->setParent(this); sock->setParent(this);
connect(sock, SIGNAL(disconnected()), SLOT(sock_disconnected())); connect(sock, &QTcpSocket::disconnected, this, &ServerTestHandler::sock_disconnected);
connect(sock, SIGNAL(readyRead()), SLOT(sock_readyRead())); connect(sock, &QTcpSocket::readyRead, this, &ServerTestHandler::sock_readyRead);
connect(sock, SIGNAL(error(QAbstractSocket::SocketError)), SLOT(sock_error(QAbstractSocket::SocketError))); #if QT_VERSION >= QT_VERSION_CHECK(5, 15, 0)
connect(sock, SIGNAL(bytesWritten(qint64)), SLOT(sock_bytesWritten(qint64))); connect(sock, &QTcpSocket::errorOccurred, this, &ServerTestHandler::sock_error);
#else
connect(sock,
QOverload<QAbstractSocket::SocketError>::of(&QTcpSocket::error),
this,
&ServerTestHandler::sock_error);
#endif
connect(sock, &QTcpSocket::bytesWritten, this, &ServerTestHandler::sock_bytesWritten);
sasl = new QCA::SASL(this); sasl = new QCA::SASL(this);
connect(sasl, SIGNAL(authCheck(const QString &, const QString &)), SLOT(sasl_authCheck(const QString &, const QString &))); connect(sasl, &QCA::SASL::authCheck, this, &ServerTestHandler::sasl_authCheck);
connect(sasl, SIGNAL(nextStep(const QByteArray &)), SLOT(sasl_nextStep(const QByteArray &))); connect(sasl, &QCA::SASL::nextStep, this, &ServerTestHandler::sasl_nextStep);
connect(sasl, SIGNAL(authenticated()), SLOT(sasl_authenticated())); connect(sasl, &QCA::SASL::authenticated, this, &ServerTestHandler::sasl_authenticated);
connect(sasl, SIGNAL(readyRead()), SLOT(sasl_readyRead())); connect(sasl, &QCA::SASL::readyRead, this, &ServerTestHandler::sasl_readyRead);
connect(sasl, SIGNAL(readyReadOutgoing()), SLOT(sasl_readyReadOutgoing())); connect(sasl, &QCA::SASL::readyReadOutgoing, this, &ServerTestHandler::sasl_readyReadOutgoing);
connect(sasl, SIGNAL(error()), SLOT(sasl_error())); connect(sasl, &QCA::SASL::error, this, &ServerTestHandler::sasl_error);
connect(sasl, SIGNAL(serverStarted()), SLOT(sasl_serverStarted())); connect(sasl, &QCA::SASL::serverStarted, this, &ServerTestHandler::sasl_serverStarted);
mode = 0; // mech list mode mode = 0; // mech list mode
toWrite = 0; toWrite = 0;
@ -179,15 +212,15 @@ public:
sasl->startServer(proto, host, realm); sasl->startServer(proto, host, realm);
} }
~ServerTestHandler() ~ServerTestHandler() override
{ {
serverTest->releaseId(id); serverTest->releaseId(id);
} }
private slots: private Q_SLOTS:
void sasl_serverStarted() void sasl_serverStarted()
{ {
sendLine(sasl->mechanismList().join(" ")); sendLine(sasl->mechanismList().join(QStringLiteral(" ")));
} }
void sock_disconnected() void sock_disconnected()
@ -198,8 +231,7 @@ private slots:
void sock_error(QAbstractSocket::SocketError x) void sock_error(QAbstractSocket::SocketError x)
{ {
if(x == QAbstractSocket::RemoteHostClosedError) if (x == QAbstractSocket::RemoteHostClosedError) {
{
printf("%d: Error: client closed connection unexpectedly.\n", id); printf("%d: Error: client closed connection unexpectedly.\n", id);
discard(); discard();
return; return;
@ -211,9 +243,8 @@ private slots:
void sock_readyRead() void sock_readyRead()
{ {
if(sock->canReadLine()) if (sock->canReadLine()) {
{ QString line = QString::fromLatin1(sock->readLine());
QString line = sock->readLine();
line.truncate(line.length() - 1); // chop the newline line.truncate(line.length() - 1); // chop the newline
handleLine(line); handleLine(line);
} }
@ -224,8 +255,7 @@ private slots:
if (mode == 2) // app mode if (mode == 2) // app mode
{ {
toWrite -= sasl->convertBytesWritten(x); toWrite -= sasl->convertBytesWritten(x);
if(toWrite == 0) if (toWrite == 0) {
{
printf("%d: Sent, closing.\n", id); printf("%d: Sent, closing.\n", id);
sock->close(); sock->close();
} }
@ -234,10 +264,9 @@ private slots:
void sasl_nextStep(const QByteArray &stepData) void sasl_nextStep(const QByteArray &stepData)
{ {
QString line = "C"; QString line = QStringLiteral("C");
if(!stepData.isEmpty()) if (!stepData.isEmpty()) {
{ line += QLatin1Char(',');
line += ',';
line += arrayToString(stepData); line += arrayToString(stepData);
} }
sendLine(line); sendLine(line);
@ -263,7 +292,7 @@ private slots:
void sasl_authenticated() void sasl_authenticated()
{ {
sendLine("A"); sendLine(QStringLiteral("A"));
printf("%d: Authentication success.\n", id); printf("%d: Authentication success.\n", id);
mode = 2; // switch to app mode mode = 2; // switch to app mode
printf("%d: SSF: %d\n", id, sasl->ssf()); printf("%d: SSF: %d\n", id, sasl->ssf());
@ -273,7 +302,7 @@ private slots:
void sasl_readyRead() void sasl_readyRead()
{ {
QByteArray a = sasl->read(); QByteArray a = sasl->read();
printf("%d: Warning, client sent %d bytes unexpectedly.\n", id, a.size()); printf("%d: Warning, client sent %d bytes unexpectedly.\n", id, int(a.size()));
} }
void sasl_readyReadOutgoing() void sasl_readyReadOutgoing()
@ -284,22 +313,15 @@ private slots:
void sasl_error() void sasl_error()
{ {
int e = sasl->errorCode(); int e = sasl->errorCode();
if(e == QCA::SASL::ErrorInit) if (e == QCA::SASL::ErrorInit) {
{
printf("%d: Error: sasl: initialization failed.\n", id); printf("%d: Error: sasl: initialization failed.\n", id);
} } else if (e == QCA::SASL::ErrorHandshake) {
else if(e == QCA::SASL::ErrorHandshake)
{
QString errstr = saslAuthConditionToString(sasl->authCondition()); QString errstr = saslAuthConditionToString(sasl->authCondition());
sendLine(QString("E,") + errstr); sendLine(QStringLiteral("E,") + errstr);
printf("%d: Error: sasl: %s.\n", id, qPrintable(errstr)); printf("%d: Error: sasl: %s.\n", id, qPrintable(errstr));
} } else if (e == QCA::SASL::ErrorCrypt) {
else if(e == QCA::SASL::ErrorCrypt)
{
printf("%d: Error: sasl: broken security layer.\n", id); printf("%d: Error: sasl: broken security layer.\n", id);
} } else {
else
{
printf("%d: Error: sasl: unknown error.\n", id); printf("%d: Error: sasl: unknown error.\n", id);
} }
@ -315,40 +337,29 @@ private:
void handleLine(const QString &line) void handleLine(const QString &line)
{ {
printf("%d: Reading: [%s]\n", id, qPrintable(line)); printf("%d: Reading: [%s]\n", id, qPrintable(line));
if(mode == 0) if (mode == 0) {
{ int n = line.indexOf(QLatin1Char(' '));
int n = line.indexOf(' '); if (n != -1) {
if(n != -1)
{
QString mech = line.mid(0, n); QString mech = line.mid(0, n);
QString rest = line.mid(n + 1).toUtf8(); QString rest = QString::fromLatin1(line.mid(n + 1).toUtf8());
sasl->putServerFirstStep(mech, stringToArray(rest)); sasl->putServerFirstStep(mech, stringToArray(rest));
} } else
else
sasl->putServerFirstStep(line); sasl->putServerFirstStep(line);
++mode; ++mode;
} } else if (mode == 1) {
else if(mode == 1)
{
QString type, rest; QString type, rest;
int n = line.indexOf(','); int n = line.indexOf(QLatin1Char(','));
if(n != -1) if (n != -1) {
{
type = line.mid(0, n); type = line.mid(0, n);
rest = line.mid(n + 1); rest = line.mid(n + 1);
} } else {
else
{
type = line; type = line;
rest = ""; rest = QLatin1String("");
} }
if(type == "C") if (type == QLatin1String("C")) {
{
sasl->putStep(stringToArray(rest)); sasl->putStep(stringToArray(rest));
} } else {
else
{
printf("%d: Bad format from peer, closing.\n", id); printf("%d: Bad format from peer, closing.\n", id);
sock->close(); sock->close();
return; return;
@ -371,29 +382,32 @@ private:
void sendLine(const QString &line) void sendLine(const QString &line)
{ {
printf("%d: Writing: {%s}\n", id, qPrintable(line)); printf("%d: Writing: {%s}\n", id, qPrintable(line));
QString s = line + '\n'; QString s = line + QLatin1Char('\n');
QByteArray a = s.toUtf8(); QByteArray a = s.toUtf8();
if (mode == 2) // app mode if (mode == 2) // app mode
{ {
toWrite += a.size(); toWrite += a.size();
sasl->write(a); // write to sasl sasl->write(a); // write to sasl
} } else // mech list or sasl negotiation
else // mech list or sasl negotiation
sock->write(a); // write to socket sock->write(a); // write to socket
} }
}; };
// --- ServerTest implementation // --- ServerTest implementation
ServerTest::ServerTest(const QString &_host, int _port, const QString &_proto, const QString &_realm, const QString &_str) : ServerTest::ServerTest(const QString &_host,
host(_host), int _port,
proto(_proto), const QString &_proto,
realm(_realm), const QString &_realm,
str(_str), const QString &_str)
port(_port) : host(_host)
, proto(_proto)
, realm(_realm)
, str(_str)
, port(_port)
{ {
tcpServer = new QTcpServer(this); tcpServer = new QTcpServer(this);
connect(tcpServer, SIGNAL(newConnection()), SLOT(server_newConnection())); connect(tcpServer, &QTcpServer::newConnection, this, &ServerTest::server_newConnection);
} }
int ServerTest::reserveId() int ServerTest::reserveId()
@ -412,8 +426,7 @@ void ServerTest::releaseId(int id)
void ServerTest::start() void ServerTest::start()
{ {
if(!tcpServer->listen(QHostAddress::Any, port)) if (!tcpServer->listen(QHostAddress::Any, port)) {
{
printf("Error: unable to bind to port %d.\n", port); printf("Error: unable to bind to port %d.\n", port);
emit quit(); emit quit();
return; return;
@ -441,41 +454,37 @@ int main(int argc, char **argv)
QCA::Initializer init; QCA::Initializer init;
QCoreApplication qapp(argc, argv); QCoreApplication qapp(argc, argv);
QCA::setAppName("saslserver"); QCA::setAppName(QStringLiteral("saslserver"));
QStringList args = qapp.arguments(); QStringList args = qapp.arguments();
args.removeFirst(); args.removeFirst();
// options // options
QString proto = "qcatest"; // default protocol QString proto = QStringLiteral("qcatest"); // default protocol
QString realm; QString realm;
for(int n = 0; n < args.count(); ++n) for (int n = 0; n < args.count(); ++n) {
{ if (!args[n].startsWith(QLatin1String("--")))
if(!args[n].startsWith("--"))
continue; continue;
QString opt = args[n].mid(2); QString opt = args[n].mid(2);
QString var, val; QString var, val;
int at = opt.indexOf('='); int at = opt.indexOf(QLatin1Char('='));
if(at != -1) if (at != -1) {
{
var = opt.mid(0, at); var = opt.mid(0, at);
val = opt.mid(at + 1); val = opt.mid(at + 1);
} } else
else
var = opt; var = opt;
if(var == "proto") if (var == QLatin1String("proto"))
proto = val; proto = val;
else if(var == "realm") else if (var == QLatin1String("realm"))
realm = val; realm = val;
args.removeAt(n); args.removeAt(n);
--n; // adjust position --n; // adjust position
} }
if(args.count() < 1) if (args.count() < 1) {
{
usage(); usage();
return 0; return 0;
} }
@ -484,28 +493,29 @@ int main(int argc, char **argv)
int port = 8001; // default port int port = 8001; // default port
QString hostinput = args[0]; QString hostinput = args[0];
QString str = "Hello, World"; QString str = QStringLiteral("Hello, World");
if (args.count() >= 2) if (args.count() >= 2)
str = args[1]; str = args[1];
int at = hostinput.indexOf(':'); int at = hostinput.indexOf(QLatin1Char(':'));
if(at != -1) if (at != -1) {
{
host = hostinput.mid(0, at); host = hostinput.mid(0, at);
port = hostinput.mid(at + 1).toInt(); #if QT_VERSION >= QT_VERSION_CHECK(5, 15, 2)
} port = QStringView(hostinput).mid(at + 1).toInt();
else #else
port = hostinput.midRef(at + 1).toInt();
#endif
} else
host = hostinput; host = hostinput;
if(!QCA::isSupported("sasl")) if (!QCA::isSupported("sasl")) {
{
printf("Error: SASL support not found.\n"); printf("Error: SASL support not found.\n");
return 1; return 1;
} }
ServerTest server(host, port, proto, realm, str); ServerTest server(host, port, proto, realm, str);
QObject::connect(&server, SIGNAL(quit()), &qapp, SLOT(quit())); QObject::connect(&server, &ServerTest::quit, &qapp, &QCoreApplication::quit);
QTimer::singleShot(0, &server, SLOT(start())); QTimer::singleShot(0, &server, &ServerTest::start);
qapp.exec(); qapp.exec();
return 0; return 0;

View File

@ -1,8 +1,10 @@
set(sslservtest_bin_SRCS sslservtest.cpp) set(sslservtest_bin_SRCS sslservtest.cpp)
MY_AUTOMOC( sslservtest_bin_SRCS )
add_executable(sslservtest ${sslservtest_bin_SRCS}) add_executable(sslservtest ${sslservtest_bin_SRCS})
target_link_qca_libraries(sslservtest) target_link_qca_libraries(sslservtest)
target_link_libraries(sslservtest ${QT_QTNETWORK_LIBRARY}) if(QT6)
target_link_libraries(sslservtest Qt6::Network)
else()
target_link_libraries(sslservtest Qt5::Network)
endif()

View File

@ -74,27 +74,34 @@ class SecureServer : public QObject
Q_OBJECT Q_OBJECT
public: public:
enum { Idle, Handshaking, Active, Closing }; enum
{
Idle,
Handshaking,
Active,
Closing
};
SecureServer(quint16 _port) : port(_port) SecureServer(quint16 _port)
: port(_port)
{ {
server = new QTcpServer; server = new QTcpServer;
connect( server, SIGNAL(newConnection()), SLOT(server_handleConnection()) ); connect(server, &QTcpServer::newConnection, this, &SecureServer::server_handleConnection);
ssl = new QCA::TLS; ssl = new QCA::TLS;
connect(ssl, SIGNAL(handshaken()), SLOT(ssl_handshaken())); connect(ssl, &QCA::TLS::handshaken, this, &SecureServer::ssl_handshaken);
connect(ssl, SIGNAL(readyRead()), SLOT(ssl_readyRead())); connect(ssl, &QCA::TLS::readyRead, this, &SecureServer::ssl_readyRead);
connect(ssl, SIGNAL(readyReadOutgoing()), SLOT(ssl_readyReadOutgoing())); connect(ssl, &QCA::TLS::readyReadOutgoing, this, &SecureServer::ssl_readyReadOutgoing);
connect(ssl, SIGNAL(closed()), SLOT(ssl_closed())); connect(ssl, &QCA::TLS::closed, this, &SecureServer::ssl_closed);
connect(ssl, SIGNAL(error()), SLOT(ssl_error())); connect(ssl, &QCA::TLS::error, this, &SecureServer::ssl_error);
cert = QCA::Certificate::fromPEM(pemdata_cert); cert = QCA::Certificate::fromPEM(QString::fromLatin1(pemdata_cert));
privkey = QCA::PrivateKey::fromPEM(pemdata_privkey); privkey = QCA::PrivateKey::fromPEM(QString::fromLatin1(pemdata_privkey));
mode = Idle; mode = Idle;
} }
~SecureServer() ~SecureServer() override
{ {
delete ssl; delete ssl;
delete server; delete server;
@ -104,26 +111,26 @@ public:
{ {
if (cert.isNull()) { if (cert.isNull()) {
qDebug() << "Error loading cert!"; qDebug() << "Error loading cert!";
QTimer::singleShot(0, this, SIGNAL(quit())); QTimer::singleShot(0, this, &SecureServer::quit);
return; return;
} }
if (privkey.isNull()) { if (privkey.isNull()) {
qDebug() << "Error loading private key!"; qDebug() << "Error loading private key!";
QTimer::singleShot(0, this, SIGNAL(quit())); QTimer::singleShot(0, this, &SecureServer::quit);
return; return;
} }
if (false == server->listen(QHostAddress::Any, port)) { if (false == server->listen(QHostAddress::Any, port)) {
qDebug() << "Error binding to port " << port; qDebug() << "Error binding to port " << port;
QTimer::singleShot(0, this, SIGNAL(quit())); QTimer::singleShot(0, this, &SecureServer::quit);
return; return;
} }
qDebug() << "Listening on port" << port; qDebug() << "Listening on port" << port;
} }
signals: Q_SIGNALS:
void quit(); void quit();
private slots: private Q_SLOTS:
void sock_readyRead() void sock_readyRead()
{ {
QByteArray buf(sock->bytesAvailable(), 0x00); QByteArray buf(sock->bytesAvailable(), 0x00);
@ -145,17 +152,20 @@ private slots:
if (mode != Idle) { if (mode != Idle) {
QTcpSocket *tmp = server->nextPendingConnection(); QTcpSocket *tmp = server->nextPendingConnection();
tmp->close(); tmp->close();
connect(tmp, SIGNAL(disconnected()), tmp, SLOT(deleteLater())); connect(tmp, &QTcpSocket::disconnected, tmp, &QTcpSocket::deleteLater);
qDebug() << "throwing away extra connection"; qDebug() << "throwing away extra connection";
return; return;
} }
mode = Handshaking; mode = Handshaking;
sock = server->nextPendingConnection(); sock = server->nextPendingConnection();
connect(sock, SIGNAL(readyRead()), SLOT(sock_readyRead())); connect(sock, &QTcpSocket::readyRead, this, &SecureServer::sock_readyRead);
connect(sock, SIGNAL(disconnected()), SLOT(sock_disconnected())); connect(sock, &QTcpSocket::disconnected, this, &SecureServer::sock_disconnected);
connect(sock, SIGNAL(error(QAbstractSocket::SocketError)), #if QT_VERSION >= QT_VERSION_CHECK(5, 15, 0)
SLOT(sock_error(QAbstractSocket::SocketError))); connect(sock, &QTcpSocket::errorOccurred, this, &SecureServer::sock_error);
connect(sock, SIGNAL(bytesWritten(qint64)), SLOT(sock_bytesWritten(qint64))); #else
connect(sock, QOverload<QAbstractSocket::SocketError>::of(&QTcpSocket::error), this, &SecureServer::sock_error);
#endif
connect(sock, &QTcpSocket::bytesWritten, this, &SecureServer::sock_bytesWritten);
qDebug() << "Connection received! Starting TLS handshake."; qDebug() << "Connection received! Starting TLS handshake.";
ssl->setCertificate(cert, privkey); ssl->setCertificate(cert, privkey);
@ -197,7 +207,7 @@ private slots:
void ssl_readyRead() void ssl_readyRead()
{ {
QByteArray a = ssl->read(); ssl->read();
QByteArray b = QByteArray b =
"<html>\n" "<html>\n"
"<head><title>Test</title></head>\n" "<head><title>Test</title></head>\n"
@ -228,8 +238,7 @@ private slots:
if (ssl->errorCode() == QCA::TLS::ErrorHandshake) { if (ssl->errorCode() == QCA::TLS::ErrorHandshake) {
qDebug() << "SSL Handshake Error! Closing."; qDebug() << "SSL Handshake Error! Closing.";
sock->close(); sock->close();
} } else {
else {
qDebug() << "SSL Error! Closing."; qDebug() << "SSL Error! Closing.";
sock->close(); sock->close();
} }
@ -256,7 +265,7 @@ int main(int argc, char **argv)
QCA::Initializer init; QCA::Initializer init;
QCoreApplication app(argc, argv); QCoreApplication app(argc, argv);
int port = argc > 1 ? QString(argv[1]).toInt() : 8000; int port = argc > 1 ? QString::fromLatin1(argv[1]).toInt() : 8000;
if (!QCA::isSupported("tls")) { if (!QCA::isSupported("tls")) {
qDebug() << "TLS not supported!"; qDebug() << "TLS not supported!";
@ -264,7 +273,7 @@ int main(int argc, char **argv)
} }
SecureServer *server = new SecureServer(port); SecureServer *server = new SecureServer(port);
QObject::connect(server, SIGNAL(quit()), &app, SLOT(quit())); QObject::connect(server, &SecureServer::quit, &app, &QCoreApplication::quit);
server->start(); server->start();
app.exec(); app.exec();
delete server; delete server;

View File

@ -1,8 +1,10 @@
set(ssltest_bin_SRCS ssltest.cpp) set(ssltest_bin_SRCS ssltest.cpp)
MY_AUTOMOC( ssltest_bin_SRCS)
add_executable(ssltest ${ssltest_bin_SRCS}) add_executable(ssltest ${ssltest_bin_SRCS})
target_link_qca_libraries(ssltest) target_link_qca_libraries(ssltest)
target_link_libraries(ssltest ${QT_QTNETWORK_LIBRARY}) if(QT6)
target_link_libraries(ssltest Qt6::Network)
else()
target_link_libraries(ssltest Qt5::Network)
endif()

View File

@ -58,44 +58,43 @@ void showCertInfo(const QCA::Certificate &cert)
static QString validityToString(QCA::Validity v) static QString validityToString(QCA::Validity v)
{ {
QString s; QString s;
switch(v) switch (v) {
{
case QCA::ValidityGood: case QCA::ValidityGood:
s = "Validated"; s = QStringLiteral("Validated");
break; break;
case QCA::ErrorRejected: case QCA::ErrorRejected:
s = "Root CA is marked to reject the specified purpose"; s = QStringLiteral("Root CA is marked to reject the specified purpose");
break; break;
case QCA::ErrorUntrusted: case QCA::ErrorUntrusted:
s = "Certificate not trusted for the required purpose"; s = QStringLiteral("Certificate not trusted for the required purpose");
break; break;
case QCA::ErrorSignatureFailed: case QCA::ErrorSignatureFailed:
s = "Invalid signature"; s = QStringLiteral("Invalid signature");
break; break;
case QCA::ErrorInvalidCA: case QCA::ErrorInvalidCA:
s = "Invalid CA certificate"; s = QStringLiteral("Invalid CA certificate");
break; break;
case QCA::ErrorInvalidPurpose: case QCA::ErrorInvalidPurpose:
s = "Invalid certificate purpose"; s = QStringLiteral("Invalid certificate purpose");
break; break;
case QCA::ErrorSelfSigned: case QCA::ErrorSelfSigned:
s = "Certificate is self-signed"; s = QStringLiteral("Certificate is self-signed");
break; break;
case QCA::ErrorRevoked: case QCA::ErrorRevoked:
s = "Certificate has been revoked"; s = QStringLiteral("Certificate has been revoked");
break; break;
case QCA::ErrorPathLengthExceeded: case QCA::ErrorPathLengthExceeded:
s = "Maximum certificate chain length exceeded"; s = QStringLiteral("Maximum certificate chain length exceeded");
break; break;
case QCA::ErrorExpired: case QCA::ErrorExpired:
s = "Certificate has expired"; s = QStringLiteral("Certificate has expired");
break; break;
case QCA::ErrorExpiredCA: case QCA::ErrorExpiredCA:
s = "CA has expired"; s = QStringLiteral("CA has expired");
break; break;
case QCA::ErrorValidityUnknown: case QCA::ErrorValidityUnknown:
default: default:
s = "General certificate validation error"; s = QStringLiteral("General certificate validation error");
break; break;
} }
return s; return s;
@ -111,22 +110,24 @@ public:
ssl_done = false; ssl_done = false;
sock = new QTcpSocket; sock = new QTcpSocket;
connect(sock, SIGNAL(connected()), SLOT(sock_connected())); connect(sock, &QTcpSocket::connected, this, &SecureTest::sock_connected);
connect(sock, SIGNAL(readyRead()), SLOT(sock_readyRead())); connect(sock, &QTcpSocket::readyRead, this, &SecureTest::sock_readyRead);
connect(sock, SIGNAL(error(QAbstractSocket::SocketError)), #if QT_VERSION >= QT_VERSION_CHECK(5, 15, 0)
SLOT(sock_error(QAbstractSocket::SocketError))); connect(sock, &QTcpSocket::errorOccurred, this, &SecureTest::sock_error);
#else
connect(sock, QOverload<QAbstractSocket::SocketError>::of(&QTcpSocket::error), this, &SecureTest::sock_error);
#endif
ssl = new QCA::TLS; ssl = new QCA::TLS;
connect(ssl, SIGNAL(certificateRequested()), SLOT(ssl_certificateRequested())); connect(ssl, &QCA::TLS::certificateRequested, this, &SecureTest::ssl_certificateRequested);
connect(ssl, SIGNAL(handshaken()), SLOT(ssl_handshaken())); connect(ssl, &QCA::TLS::handshaken, this, &SecureTest::ssl_handshaken);
connect(ssl, SIGNAL(readyRead()), SLOT(ssl_readyRead())); connect(ssl, &QCA::TLS::readyRead, this, &SecureTest::ssl_readyRead);
connect(ssl, SIGNAL(readyReadOutgoing()), connect(ssl, &QCA::TLS::readyReadOutgoing, this, &SecureTest::ssl_readyReadOutgoing);
SLOT(ssl_readyReadOutgoing())); connect(ssl, &QCA::TLS::closed, this, &SecureTest::ssl_closed);
connect(ssl, SIGNAL(closed()), SLOT(ssl_closed())); connect(ssl, &QCA::TLS::error, this, &SecureTest::ssl_error);
connect(ssl, SIGNAL(error()), SLOT(ssl_error()));
} }
~SecureTest() ~SecureTest() override
{ {
delete ssl; delete ssl;
delete sock; delete sock;
@ -134,15 +135,16 @@ public:
void start(const QString &_host) void start(const QString &_host)
{ {
int n = _host.indexOf(':'); int n = _host.indexOf(QLatin1Char(':'));
int port; int port;
if(n != -1) if (n != -1) {
{
host = _host.mid(0, n); host = _host.mid(0, n);
port = _host.mid(n+1).toInt(); #if QT_VERSION >= QT_VERSION_CHECK(5, 15, 0)
} port = QStringView(_host).mid(n + 1).toInt();
else #else
{ port = _host.midRef(n + 1).toInt();
#endif
} else {
host = _host; host = _host;
port = 443; port = 443;
} }
@ -151,10 +153,10 @@ public:
sock->connectToHost(host, port); sock->connectToHost(host, port);
} }
signals: Q_SIGNALS:
void quit(); void quit();
private slots: private Q_SLOTS:
void sock_connected() void sock_connected()
{ {
// We just do this to help doxygen... // We just do this to help doxygen...
@ -166,7 +168,7 @@ private slots:
// We add this one to show how, and to make it work with // We add this one to show how, and to make it work with
// the server example. // the server example.
rootCerts.addCertificate(QCA::Certificate::fromPEM(exampleCA_cert)); rootCerts.addCertificate(QCA::Certificate::fromPEM(QString::fromLatin1(exampleCA_cert)));
if (!QCA::haveSystemStore()) if (!QCA::haveSystemStore())
printf("Warning: no root certs\n"); printf("Warning: no root certs\n");
@ -195,8 +197,7 @@ private slots:
void sock_error(QAbstractSocket::SocketError x) void sock_error(QAbstractSocket::SocketError x)
{ {
if(x == QAbstractSocket::RemoteHostClosedError) if (x == QAbstractSocket::RemoteHostClosedError) {
{
sock_connectionClosed(); sock_connectionClosed();
return; return;
} }
@ -216,29 +217,28 @@ private slots:
qPrintable(ssl->cipherSuite()), qPrintable(ssl->cipherSuite()),
ssl->cipherBits(), ssl->cipherBits(),
ssl->cipherMaxBits()); ssl->cipherMaxBits());
if(r != QCA::TLS::NoCertificate) if (r != QCA::TLS::NoCertificate) {
{
cert = ssl->peerCertificateChain().primary(); cert = ssl->peerCertificateChain().primary();
if (!cert.isNull()) if (!cert.isNull())
showCertInfo(cert); showCertInfo(cert);
} }
QString str = "Peer Identity: "; QString str = QStringLiteral("Peer Identity: ");
if (r == QCA::TLS::Valid) if (r == QCA::TLS::Valid)
str += "Valid"; str += QStringLiteral("Valid");
else if (r == QCA::TLS::HostMismatch) else if (r == QCA::TLS::HostMismatch)
str += "Error: Wrong certificate"; str += QStringLiteral("Error: Wrong certificate");
else if (r == QCA::TLS::InvalidCertificate) else if (r == QCA::TLS::InvalidCertificate)
str += "Error: Invalid certificate.\n -> Reason: " + str += QStringLiteral("Error: Invalid certificate.\n -> Reason: ") +
validityToString(ssl->peerCertificateValidity()); validityToString(ssl->peerCertificateValidity());
else else
str += "Error: No certificate"; str += QStringLiteral("Error: No certificate");
printf("%s\n", qPrintable(str)); printf("%s\n", qPrintable(str));
ssl->continueAfterStep(); ssl->continueAfterStep();
printf("Let's try a GET request now.\n"); printf("Let's try a GET request now.\n");
QString req = "GET / HTTP/1.0\nHost: " + host + "\n\n"; QString req = QStringLiteral("GET / HTTP/1.0\nHost: ") + host + QStringLiteral("\n\n");
ssl->write(req.toLatin1()); ssl->write(req.toLatin1());
} }
@ -249,8 +249,7 @@ private slots:
printf("Server requested client certificate.\n"); printf("Server requested client certificate.\n");
QList<QCA::CertificateInfoOrdered> issuerList = ssl->issuerList(); QList<QCA::CertificateInfoOrdered> issuerList = ssl->issuerList();
if(!issuerList.isEmpty()) if (!issuerList.isEmpty()) {
{
printf("Allowed issuers:\n"); printf("Allowed issuers:\n");
foreach (QCA::CertificateInfoOrdered i, issuerList) foreach (QCA::CertificateInfoOrdered i, issuerList)
printf(" %s\n", qPrintable(i.toString())); printf(" %s\n", qPrintable(i.toString()));
@ -291,13 +290,10 @@ private slots:
QCA::TLS *ssl = SecureTest::ssl; QCA::TLS *ssl = SecureTest::ssl;
int x = ssl->errorCode(); int x = ssl->errorCode();
if(x == QCA::TLS::ErrorHandshake) if (x == QCA::TLS::ErrorHandshake) {
{
printf("SSL Handshake Error!\n"); printf("SSL Handshake Error!\n");
emit quit(); emit quit();
} } else {
else
{
printf("SSL Error!\n"); printf("SSL Error!\n");
emit quit(); emit quit();
} }
@ -318,16 +314,15 @@ int main(int argc, char **argv)
QCA::Initializer init; QCA::Initializer init;
QCoreApplication app(argc, argv); QCoreApplication app(argc, argv);
QString host = argc > 1 ? argv[1] : "andbit.net"; QString host = argc > 1 ? QString::fromLocal8Bit(argv[1]) : QStringLiteral("andbit.net");
if(!QCA::isSupported("tls")) if (!QCA::isSupported("tls")) {
{
printf("TLS not supported!\n"); printf("TLS not supported!\n");
return 1; return 1;
} }
SecureTest *s = new SecureTest; SecureTest *s = new SecureTest;
QObject::connect(s, SIGNAL(quit()), &app, SLOT(quit())); QObject::connect(s, &SecureTest::quit, &app, &QCoreApplication::quit);
s->start(host); s->start(host);
app.exec(); app.exec();
delete s; delete s;

View File

@ -1,9 +1,8 @@
set(tlssocket_bin_moc_SRCS tlssocket.cpp) add_executable(tlssocket tlssocket.cpp main.cpp)
set(tlssocket_bin_nonmoc_SRCS main.cpp)
MY_AUTOMOC( tlssocket_bin_moc_SRCS)
add_executable(tlssocket ${tlssocket_bin_moc_SRCS} ${tlssocket_bin_nonmoc_SRCS})
target_link_qca_libraries(tlssocket) target_link_qca_libraries(tlssocket)
target_link_libraries(tlssocket ${QT_QTNETWORK_LIBRARY}) if(QT6)
target_link_libraries(tlssocket Qt6::Network)
else()
target_link_libraries(tlssocket Qt5::Network)
endif()

View File

@ -29,10 +29,10 @@ int main(int argc, char **argv)
QCoreApplication qapp(argc, argv); QCoreApplication qapp(argc, argv);
TLSSocket socket; TLSSocket socket;
socket.connectToHostEncrypted("www.paypal.com", 443); socket.connectToHostEncrypted(QStringLiteral("www.paypal.com"), 443);
socket.write("GET / HTTP/1.0\r\n\r\n"); socket.write("GET / HTTP/1.0\r\n\r\n");
while (socket.waitForReadyRead()) while (socket.waitForReadyRead())
printf("%s", socket.readAll().data()); printf("%s", socket.readAll().constData());
return 0; return 0;
} }

View File

@ -39,20 +39,30 @@ public:
QCA::Synchronizer sync; QCA::Synchronizer sync;
bool waiting; bool waiting;
Private(TLSSocket *_q) : QObject(_q), q(_q), sync(_q) Private(TLSSocket *_q)
: QObject(_q)
, q(_q)
, sync(_q)
{ {
sock = new QTcpSocket(this); sock = new QTcpSocket(this);
connect(sock, SIGNAL(connected()), SLOT(sock_connected())); connect(sock, &QTcpSocket::connected, this, &TLSSocket::Private::sock_connected);
connect(sock, SIGNAL(readyRead()), SLOT(sock_readyRead())); connect(sock, &QTcpSocket::readyRead, this, &TLSSocket::Private::sock_readyRead);
connect(sock, SIGNAL(bytesWritten(qint64)), SLOT(sock_bytesWritten(qint64))); connect(sock, &QTcpSocket::bytesWritten, this, &TLSSocket::Private::sock_bytesWritten);
connect(sock, SIGNAL(error(QAbstractSocket::SocketError)), SLOT(sock_error(QAbstractSocket::SocketError))); #if QT_VERSION >= QT_VERSION_CHECK(5, 15, 0)
connect(sock, &QTcpSocket::errorOccurred, this, &TLSSocket::Private::sock_error);
#else
connect(sock,
QOverload<QAbstractSocket::SocketError>::of(&QTcpSocket::error),
this,
&TLSSocket::Private::sock_error);
#endif
tls = new QCA::TLS(this); tls = new QCA::TLS(this);
connect(tls, SIGNAL(handshaken()), SLOT(tls_handshaken())); connect(tls, &QCA::TLS::handshaken, this, &TLSSocket::Private::tls_handshaken);
connect(tls, SIGNAL(readyRead()), SLOT(tls_readyRead())); connect(tls, &QCA::TLS::readyRead, this, &TLSSocket::Private::tls_readyRead);
connect(tls, SIGNAL(readyReadOutgoing()), SLOT(tls_readyReadOutgoing())); connect(tls, &QCA::TLS::readyReadOutgoing, this, &TLSSocket::Private::tls_readyReadOutgoing);
connect(tls, SIGNAL(closed()), SLOT(tls_closed())); connect(tls, &QCA::TLS::closed, this, &TLSSocket::Private::tls_closed);
connect(tls, SIGNAL(error()), SLOT(tls_error())); connect(tls, &QCA::TLS::error, this, &TLSSocket::Private::tls_error);
tls->setTrustedCertificates(QCA::systemStore()); tls->setTrustedCertificates(QCA::systemStore());
encrypted = false; encrypted = false;
error = false; error = false;
@ -72,7 +82,7 @@ public:
return ok; return ok;
} }
private slots: private Q_SLOTS:
void sock_connected() void sock_connected()
{ {
// printf("sock connected\n"); // printf("sock connected\n");
@ -105,20 +115,16 @@ private slots:
void tls_handshaken() void tls_handshaken()
{ {
// printf("tls handshaken\n"); // printf("tls handshaken\n");
if(tls->peerIdentityResult() != QCA::TLS::Valid) if (tls->peerIdentityResult() != QCA::TLS::Valid) {
{
printf("not valid\n"); printf("not valid\n");
sock->abort(); sock->abort();
tls->reset(); tls->reset();
error = true; error = true;
} } else {
else
{
// printf("valid\n"); // printf("valid\n");
encrypted = true; encrypted = true;
// printf("%d bytes in writebuf\n", writebuf.size()); // printf("%d bytes in writebuf\n", writebuf.size());
if(!writebuf.isEmpty()) if (!writebuf.isEmpty()) {
{
// printf("[%s]\n", writebuf.data()); // printf("[%s]\n", writebuf.data());
tls->write(writebuf); tls->write(writebuf);
writebuf.clear(); writebuf.clear();
@ -158,7 +164,6 @@ TLSSocket::TLSSocket(QObject *parent)
: QTcpSocket(parent) : QTcpSocket(parent)
{ {
d = new Private(this); d = new Private(this);
} }
TLSSocket::~TLSSocket() TLSSocket::~TLSSocket()

View File

@ -21,24 +21,25 @@
#ifndef TLSSOCKET_H #ifndef TLSSOCKET_H
#include <QtCrypto>
#include <QTcpSocket> #include <QTcpSocket>
#include <QtCrypto>
class TLSSocket : public QTcpSocket class TLSSocket : public QTcpSocket
{ {
Q_OBJECT
public: public:
TLSSocket(QObject *parent = 0); TLSSocket(QObject *parent = nullptr);
~TLSSocket(); ~TLSSocket() override;
void connectToHostEncrypted(const QString &host, quint16 port); void connectToHostEncrypted(const QString &host, quint16 port);
QCA::TLS *tls(); QCA::TLS *tls();
bool waitForReadyRead(int msecs = -1); bool waitForReadyRead(int msecs = -1) override;
protected: protected:
// from qiodevice // from qiodevice
virtual qint64 readData(char *data, qint64 maxlen); qint64 readData(char *data, qint64 maxlen) override;
virtual qint64 writeData(const char *data, qint64 len); qint64 writeData(const char *data, qint64 len) override;
private: private:
class Private; class Private;

10
hooks/pre-commit Normal file
View File

@ -0,0 +1,10 @@
#!/usr/bin/env bash
readonly output=$(git clang-format -v --diff)
if [[ "$output" == *"no modified files to format"* ]]; then exit 0; fi
if [[ "$output" == *"clang-format did not modify any files"* ]]; then exit 0; fi
echo "ERROR: you need to run git clang-format on your commit"
echo " git clang-format -f is potentially what you want"
exit 1

View File

@ -33,16 +33,16 @@
#ifndef QCA_H #ifndef QCA_H
#define QCA_H #define QCA_H
#include "qca_core.h"
#include "qca_textfilter.h"
#include "qca_basic.h" #include "qca_basic.h"
#include "qca_publickey.h"
#include "qca_cert.h" #include "qca_cert.h"
#include "qca_core.h"
#include "qca_keystore.h" #include "qca_keystore.h"
#include "qca_publickey.h"
#include "qca_safetimer.h"
#include "qca_securelayer.h" #include "qca_securelayer.h"
#include "qca_securemessage.h" #include "qca_securemessage.h"
#include "qca_textfilter.h"
#include "qcaprovider.h" #include "qcaprovider.h"
#include "qpipe.h" #include "qpipe.h"
#include "qca_safetimer.h"
#endif #endif

View File

@ -2,6 +2,7 @@
* qca_basic.h - Qt Cryptographic Architecture * qca_basic.h - Qt Cryptographic Architecture
* Copyright (C) 2003-2007 Justin Karneges <justin@affinix.com> * Copyright (C) 2003-2007 Justin Karneges <justin@affinix.com>
* Copyright (C) 2004-2007 Brad Hards <bradh@frogmouth.net> * Copyright (C) 2004-2007 Brad Hards <bradh@frogmouth.net>
* Copyright (C) 2013-2016 Ivan Romanov <drizt@land.ru>
* *
* This library is free software; you can redistribute it and/or * This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public * modify it under the terms of the GNU Lesser General Public
@ -35,12 +36,7 @@
#include "qca_core.h" #include "qca_core.h"
// Qt5 comes with QStringLiteral for wrapping string literals, which Qt4 does #include <QIODevice>
// not have. It is needed if the headers are built with QT_NO_CAST_FROM_ASCII.
// Defining it here as QString::fromUtf8 for convenience.
#ifndef QStringLiteral
#define QStringLiteral(str) QString::fromUtf8(str)
#endif
namespace QCA { namespace QCA {
@ -84,7 +80,7 @@ public:
*/ */
Random(const Random &from); Random(const Random &from);
~Random(); ~Random() override;
/** /**
Assignment operator Assignment operator
@ -119,7 +115,7 @@ public:
Provide a random character (byte) Provide a random character (byte)
This is the normal way of obtaining a single random char This is the normal way of obtaining a single random char
(ie. 8 bit byte), as shown below: (i.e. 8 bit byte), as shown below:
\code \code
myRandomChar = QCA::Random::randomChar(); myRandomChar = QCA::Random::randomChar();
\endcode \endcode
@ -229,7 +225,7 @@ public:
*/ */
Hash(const Hash &from); Hash(const Hash &from);
~Hash(); ~Hash() override;
/** /**
Assignment operator Assignment operator
@ -262,7 +258,7 @@ public:
a Hash sub-class object to calculate additional a Hash sub-class object to calculate additional
hashes. hashes.
*/ */
virtual void clear(); void clear() override;
/** /**
Update a hash, adding more of the message contents Update a hash, adding more of the message contents
@ -275,7 +271,7 @@ public:
\param a the byte array to add to the hash \param a the byte array to add to the hash
*/ */
virtual void update(const MemoryRegion &a); void update(const MemoryRegion &a) override;
/** /**
\overload \overload
@ -337,7 +333,7 @@ if ( f.open( QIODevice::ReadOnly ) )
reuse the Hash object, you should call clear() and reuse the Hash object, you should call clear() and
start to update() again. start to update() again.
*/ */
virtual MemoryRegion final(); MemoryRegion final() override;
/** /**
%Hash a byte array, returning it as another %Hash a byte array, returning it as another
@ -530,7 +526,9 @@ private:
The most common padding scheme is known as PKCS#7 (also PKCS#1), and The most common padding scheme is known as PKCS#7 (also PKCS#1), and
it specifies that the pad bytes are all equal to the length of the it specifies that the pad bytes are all equal to the length of the
padding ( for example, if you need three pad bytes to complete the block, padding ( for example, if you need three pad bytes to complete the block,
then the padding is 0x03 0x03 0x03 ). then the padding is 0x03 0x03 0x03 ). PKCS#5 padding is a subset of
PKCS#7 padding for 8 byte block sizes. For explanation, see
http://crypto.stackexchange.com/questions/9043/what-is-the-difference-between-pkcs5-padding-and-pkcs7-padding/9044#9044.
On encryption, for algorithm / mode combinations that require On encryption, for algorithm / mode combinations that require
padding, you will get a block of ciphertext when the input plain padding, you will get a block of ciphertext when the input plain
@ -579,6 +577,7 @@ private:
\ingroup UserAPI \ingroup UserAPI
*/ */
class QCA_EXPORT Cipher : public Algorithm, public Filter class QCA_EXPORT Cipher : public Algorithm, public Filter
{ {
public: public:
@ -596,6 +595,8 @@ public:
ECB, ///< operate in Electronic Code Book mode ECB, ///< operate in Electronic Code Book mode
OFB, ///< operate in Output FeedBack Mode OFB, ///< operate in Output FeedBack Mode
CTR, ///< operate in CounTer Mode CTR, ///< operate in CounTer Mode
GCM, ///< operate in Galois Counter Mode
CCM ///< operate in Counter with CBC-MAC
}; };
/** /**
@ -627,11 +628,40 @@ public:
\note Padding only applies to CBC and ECB modes. CFB and OFB \note Padding only applies to CBC and ECB modes. CFB and OFB
ciphertext is always the length of the plaintext. ciphertext is always the length of the plaintext.
*/ */
Cipher(const QString &type, Mode mode, Padding pad = DefaultPadding, Cipher(const QString & type,
Direction dir = Encode, const SymmetricKey &key = SymmetricKey(), Mode mode,
Padding pad = DefaultPadding,
Direction dir = Encode,
const SymmetricKey & key = SymmetricKey(),
const InitializationVector &iv = InitializationVector(), const InitializationVector &iv = InitializationVector(),
const QString & provider = QString()); const QString & provider = QString());
/**
Standard constructor
\param type the name of the cipher specialisation to use (e.g.
"aes128")
\param mode the operating Mode to use (e.g. QCA::Cipher::CBC)
\param pad the type of Padding to use
\param dir the Direction that this Cipher should use (Encode for
encryption, Decode for decryption)
\param key the SymmetricKey array that is the key
\param iv the InitializationVector to use (not used for ECB mode)
\param tag the AuthTag to use (only for GCM and CCM modes)
\param provider the name of the Provider to use
\note Padding only applies to CBC and ECB modes. CFB and OFB
ciphertext is always the length of the plaintext.
*/
Cipher(const QString & type,
Mode mode,
Padding pad,
Direction dir,
const SymmetricKey & key,
const InitializationVector &iv,
const AuthTag & tag,
const QString & provider = QString());
/** /**
Standard copy constructor Standard copy constructor
@ -639,7 +669,7 @@ public:
*/ */
Cipher(const Cipher &from); Cipher(const Cipher &from);
~Cipher(); ~Cipher() override;
/** /**
Assignment operator Assignment operator
@ -695,10 +725,15 @@ public:
*/ */
int blockSize() const; int blockSize() const;
/**
return the authentication tag for the cipher object
*/
AuthTag tag() const;
/** /**
reset the cipher object, to allow re-use reset the cipher object, to allow re-use
*/ */
virtual void clear(); void clear() override;
/** /**
pass in a byte array of data, which will be encrypted or decrypted pass in a byte array of data, which will be encrypted or decrypted
@ -707,20 +742,20 @@ public:
\param a the array of data to encrypt / decrypt \param a the array of data to encrypt / decrypt
*/ */
virtual MemoryRegion update(const MemoryRegion &a); MemoryRegion update(const MemoryRegion &a) override;
/** /**
complete the block of data, padding as required, and returning complete the block of data, padding as required, and returning
the completed block the completed block
*/ */
virtual MemoryRegion final(); MemoryRegion final() override;
/** /**
Test if an update() or final() call succeeded. Test if an update() or final() call succeeded.
\return true if the previous call succeeded \return true if the previous call succeeded
*/ */
virtual bool ok() const; bool ok() const override;
/** /**
Reset / reconfigure the Cipher Reset / reconfigure the Cipher
@ -737,6 +772,22 @@ public:
*/ */
void setup(Direction dir, const SymmetricKey &key, const InitializationVector &iv = InitializationVector()); void setup(Direction dir, const SymmetricKey &key, const InitializationVector &iv = InitializationVector());
/**
Reset / reconfigure the Cipher
You can use this to re-use an existing Cipher, rather than creating
a new object with a slightly different configuration.
\param dir the Direction that this Cipher should use (Encode for
encryption, Decode for decryption)
\param key the SymmetricKey array that is the key
\param iv the InitializationVector to use (not used for ECB Mode)
\param tag the AuthTag to use (only for GCM and CCM modes)
\note You should not leave iv empty for any Mode except ECB.
*/
void setup(Direction dir, const SymmetricKey &key, const InitializationVector &iv, const AuthTag &tag);
/** /**
Construct a Cipher type string Construct a Cipher type string
@ -797,7 +848,7 @@ public:
*/ */
MessageAuthenticationCode(const MessageAuthenticationCode &from); MessageAuthenticationCode(const MessageAuthenticationCode &from);
~MessageAuthenticationCode(); ~MessageAuthenticationCode() override;
/** /**
Assignment operator. Assignment operator.
@ -849,7 +900,7 @@ public:
doesn't need to be changed, you don't need to call doesn't need to be changed, you don't need to call
setup() again, since the key can just be reused. setup() again, since the key can just be reused.
*/ */
virtual void clear(); void clear() override;
/** /**
Update the MAC, adding more of the message contents Update the MAC, adding more of the message contents
@ -858,7 +909,7 @@ public:
\param array the message contents \param array the message contents
*/ */
virtual void update(const MemoryRegion &array); void update(const MemoryRegion &array) override;
/** /**
Finalises input and returns the MAC result Finalises input and returns the MAC result
@ -871,7 +922,7 @@ public:
reuse the %MessageAuthenticationCode object, you reuse the %MessageAuthenticationCode object, you
should call clear() and start to update() again. should call clear() and start to update() again.
*/ */
virtual MemoryRegion final(); MemoryRegion final() override;
/** /**
Initialise the MAC algorithm Initialise the MAC algorithm
@ -909,7 +960,7 @@ public:
*/ */
KeyDerivationFunction(const KeyDerivationFunction &from); KeyDerivationFunction(const KeyDerivationFunction &from);
~KeyDerivationFunction(); ~KeyDerivationFunction() override;
/** /**
Assignment operator Assignment operator
@ -933,7 +984,10 @@ public:
\return the derived key \return the derived key
*/ */
SymmetricKey makeKey(const SecureArray &secret, const InitializationVector &salt, unsigned int keyLength, unsigned int iterationCount); SymmetricKey makeKey(const SecureArray & secret,
const InitializationVector &salt,
unsigned int keyLength,
unsigned int iterationCount);
/** /**
Generate the key from a specified secret and salt value Generate the key from a specified secret and salt value
@ -1002,7 +1056,9 @@ public:
\param provider the name of the provider to use, if available \param provider the name of the provider to use, if available
*/ */
explicit PBKDF1(const QString &algorithm = QStringLiteral("sha1"), const QString &provider = QString()) explicit PBKDF1(const QString &algorithm = QStringLiteral("sha1"), const QString &provider = QString())
: KeyDerivationFunction(withAlgorithm(QStringLiteral("pbkdf1"), algorithm), provider) {} : KeyDerivationFunction(withAlgorithm(QStringLiteral("pbkdf1"), algorithm), provider)
{
}
}; };
/** /**
@ -1025,7 +1081,68 @@ public:
\param provider the name of the provider to use, if available \param provider the name of the provider to use, if available
*/ */
explicit PBKDF2(const QString &algorithm = QStringLiteral("sha1"), const QString &provider = QString()) explicit PBKDF2(const QString &algorithm = QStringLiteral("sha1"), const QString &provider = QString())
: KeyDerivationFunction(withAlgorithm(QStringLiteral("pbkdf2"), algorithm), provider) {} : KeyDerivationFunction(withAlgorithm(QStringLiteral("pbkdf2"), algorithm), provider)
{
}
};
/**
\class HKDF qca_basic.h QtCrypto
\since 2.3
HMAC-based extract-and-expand key derivation function
This class implements HMAC-based Extract-and-Expand Key Derivation Function,
as specified in RFC5869.
\ingroup UserAPI
*/
class QCA_EXPORT HKDF : public Algorithm
{
public:
/**
Standard constructor
\param algorithm the name of the hashing algorithm to use
\param provider the name of the provider to use, if available
*/
explicit HKDF(const QString &algorithm = QStringLiteral("sha256"), const QString &provider = QString());
/**
Standard copy constructor
\param from the KeyDerivationFunction to copy from
*/
HKDF(const HKDF &from);
~HKDF() override;
/**
Assignment operator
Copies the state (including key) from one HKDF
to another
\param from the HKDF to assign from
*/
HKDF &operator=(const HKDF &from);
/**
Generate the key from a specified secret, salt value, and an additional info
\note key length is ignored for some functions
\param secret the secret (password or passphrase)
\param salt the salt to use
\param info the info to use
\param keyLength the length of key to return
\return the derived key
*/
SymmetricKey makeKey(const SecureArray & secret,
const InitializationVector &salt,
const InitializationVector &info,
unsigned int keyLength);
}; };
} }

View File

@ -33,10 +33,9 @@
#ifndef QCA_CERT_H #ifndef QCA_CERT_H
#define QCA_CERT_H #define QCA_CERT_H
#include <QMap>
#include <QDateTime>
#include "qca_core.h" #include "qca_core.h"
#include "qca_publickey.h" #include "qca_publickey.h"
#include <QDateTime>
namespace QCA { namespace QCA {
@ -48,7 +47,6 @@ class CRL;
class CertificateCollection; class CertificateCollection;
class CertificateChain; class CertificateChain;
/** /**
Certificate Request Format Certificate Request Format
*/ */
@ -310,7 +308,6 @@ private:
QSharedDataPointer<Private> d; QSharedDataPointer<Private> d;
}; };
/** /**
Known types of certificate constraints Known types of certificate constraints
@ -330,15 +327,24 @@ enum ConstraintTypeKnown
DecipherOnly, ///< %Certificate can only be used for decryption, id = "KeyUsage.decipherOnly" DecipherOnly, ///< %Certificate can only be used for decryption, id = "KeyUsage.decipherOnly"
// ExtKeyUsage // ExtKeyUsage
ServerAuth, ///< %Certificate can be used for server authentication (e.g. web server), id = "1.3.6.1.5.5.7.3.1". This is an extended usage constraint. ServerAuth, ///< %Certificate can be used for server authentication (e.g. web server), id = "1.3.6.1.5.5.7.3.1".
ClientAuth, ///< %Certificate can be used for client authentication (e.g. web browser), id = "1.3.6.1.5.5.7.3.2". This is an extended usage constraint. ///< This is an extended usage constraint.
CodeSigning, ///< %Certificate can be used to sign code, id = "1.3.6.1.5.5.7.3.3". This is an extended usage constraint. ClientAuth, ///< %Certificate can be used for client authentication (e.g. web browser), id = "1.3.6.1.5.5.7.3.2".
EmailProtection, ///< %Certificate can be used to sign / encrypt email, id = "1.3.6.1.5.5.7.3.4". This is an extended usage constraint. ///< This is an extended usage constraint.
IPSecEndSystem, ///< %Certificate can be used to authenticate a endpoint in IPSEC, id = "1.3.6.1.5.5.7.3.5". This is an extended usage constraint. CodeSigning, ///< %Certificate can be used to sign code, id = "1.3.6.1.5.5.7.3.3". This is an extended usage
IPSecTunnel, ///< %Certificate can be used to authenticate a tunnel in IPSEC, id = "1.3.6.1.5.5.7.3.6". This is an extended usage constraint. ///< constraint.
IPSecUser, ///< %Certificate can be used to authenticate a user in IPSEC, id = "1.3.6.1.5.5.7.3.7". This is an extended usage constraint. EmailProtection, ///< %Certificate can be used to sign / encrypt email, id = "1.3.6.1.5.5.7.3.4". This is an
TimeStamping, ///< %Certificate can be used to create a "time stamp" signature, id = "1.3.6.1.5.5.7.3.8". This is an extended usage constraint. ///< extended usage constraint.
OCSPSigning ///< %Certificate can be used to sign an Online %Certificate Status Protocol (OCSP) assertion, id = "1.3.6.1.5.5.7.3.9". This is an extended usage constraint. IPSecEndSystem, ///< %Certificate can be used to authenticate a endpoint in IPSEC, id = "1.3.6.1.5.5.7.3.5". This is
///< an extended usage constraint.
IPSecTunnel, ///< %Certificate can be used to authenticate a tunnel in IPSEC, id = "1.3.6.1.5.5.7.3.6". This is an
///< extended usage constraint.
IPSecUser, ///< %Certificate can be used to authenticate a user in IPSEC, id = "1.3.6.1.5.5.7.3.7". This is an
///< extended usage constraint.
TimeStamping, ///< %Certificate can be used to create a "time stamp" signature, id = "1.3.6.1.5.5.7.3.8". This is an
///< extended usage constraint.
OCSPSigning ///< %Certificate can be used to sign an Online %Certificate Status Protocol (OCSP) assertion, id =
///< "1.3.6.1.5.5.7.3.9". This is an extended usage constraint.
}; };
/** /**
@ -498,7 +504,8 @@ enum Validity
ErrorSelfSigned, ///< The certificate is self-signed, and is not found in the list of trusted certificates ErrorSelfSigned, ///< The certificate is self-signed, and is not found in the list of trusted certificates
ErrorRevoked, ///< The certificate has been revoked ErrorRevoked, ///< The certificate has been revoked
ErrorPathLengthExceeded, ///< The path length from the root CA to this certificate is too long ErrorPathLengthExceeded, ///< The path length from the root CA to this certificate is too long
ErrorExpired, ///< The certificate has expired, or is not yet valid (e.g. current time is earlier than notBefore time) ErrorExpired, ///< The certificate has expired, or is not yet valid (e.g. current time is earlier than notBefore
///< time)
ErrorExpiredCA, ///< The Certificate Authority has expired ErrorExpiredCA, ///< The Certificate Authority has expired
ErrorValidityUnknown = 64 ///< Validity is unknown ErrorValidityUnknown = 64 ///< Validity is unknown
}; };
@ -747,7 +754,7 @@ public:
void setChallenge(const QString &s); void setChallenge(const QString &s);
/** /**
Specify information for the the subject associated with the Specify information for the subject associated with the
certificate certificate
\param info the information for the subject \param info the information for the subject
@ -757,7 +764,7 @@ public:
void setInfo(const CertificateInfo &info); void setInfo(const CertificateInfo &info);
/** /**
Specify information for the the subject associated with the Specify information for the subject associated with the
certificate certificate
\param info the information for the subject \param info the information for the subject
@ -880,7 +887,7 @@ public:
*/ */
Certificate(const Certificate &from); Certificate(const Certificate &from);
~Certificate(); ~Certificate() override;
/** /**
Standard assignment operator Standard assignment operator
@ -1016,9 +1023,9 @@ CertificateInfoOrdered info = cert.subjectInfoOrdered();
PublicKey subjectPublicKey() const; PublicKey subjectPublicKey() const;
/** /**
Test if the Certificate is valid as a Certificate Authority Test if the Certificate is valid as a %Certificate Authority
\return true if the Certificate is valid as a Certificate Authority \return true if the Certificate is valid as a %Certificate Authority
*/ */
bool isCA() const; bool isCA() const;
@ -1071,7 +1078,10 @@ CertificateInfoOrdered info = cert.subjectInfoOrdered();
\note This function may block \note This function may block
*/ */
Validity validate(const CertificateCollection &trusted, const CertificateCollection &untrusted, UsageMode u = UsageAny, ValidateFlags vf = ValidateAll) const; Validity validate(const CertificateCollection &trusted,
const CertificateCollection &untrusted,
UsageMode u = UsageAny,
ValidateFlags vf = ValidateAll) const;
/** /**
Export the Certificate into a DER format Export the Certificate into a DER format
@ -1102,7 +1112,8 @@ CertificateInfoOrdered info = cert.subjectInfoOrdered();
\return the Certificate corresponding to the certificate in the \return the Certificate corresponding to the certificate in the
provided array provided array
*/ */
static Certificate fromDER(const QByteArray &a, ConvertResult *result = 0, const QString &provider = QString()); static Certificate
fromDER(const QByteArray &a, ConvertResult *result = nullptr, const QString &provider = QString());
/** /**
Import the certificate from PEM format Import the certificate from PEM format
@ -1116,7 +1127,7 @@ CertificateInfoOrdered info = cert.subjectInfoOrdered();
\return the Certificate corresponding to the certificate in the \return the Certificate corresponding to the certificate in the
provided string provided string
*/ */
static Certificate fromPEM(const QString &s, ConvertResult *result = 0, const QString &provider = QString()); static Certificate fromPEM(const QString &s, ConvertResult *result = nullptr, const QString &provider = QString());
/** /**
Import the certificate from a file Import the certificate from a file
@ -1131,7 +1142,8 @@ CertificateInfoOrdered info = cert.subjectInfoOrdered();
\return the Certificate corresponding to the certificate in the \return the Certificate corresponding to the certificate in the
provided string provided string
*/ */
static Certificate fromPEMFile(const QString &fileName, ConvertResult *result = 0, const QString &provider = QString()); static Certificate
fromPEMFile(const QString &fileName, ConvertResult *result = nullptr, const QString &provider = QString());
/** /**
Test if the subject of the certificate matches a specified host Test if the subject of the certificate matches a specified host
@ -1179,8 +1191,13 @@ private:
QSharedDataPointer<Private> d; QSharedDataPointer<Private> d;
friend class CertificateChain; friend class CertificateChain;
Validity chain_validate(const CertificateChain &chain, const CertificateCollection &trusted, const QList<CRL> &untrusted_crls, UsageMode u, ValidateFlags vf) const; Validity chain_validate(const CertificateChain & chain,
CertificateChain chain_complete(const CertificateChain &chain, const QList<Certificate> &issuers, Validity *result) const; const CertificateCollection &trusted,
const QList<CRL> & untrusted_crls,
UsageMode u,
ValidateFlags vf) const;
CertificateChain
chain_complete(const CertificateChain &chain, const QList<Certificate> &issuers, Validity *result) const;
}; };
/** /**
@ -1195,7 +1212,7 @@ private:
The normal use of a CertificateChain is from a end-user Certificate (called The normal use of a CertificateChain is from a end-user Certificate (called
the primary, equivalent to QList::first()) through some intermediate the primary, equivalent to QList::first()) through some intermediate
Certificates to some other Certificate (QList::last()), which might be a Certificates to some other Certificate (QList::last()), which might be a
root Certificate Authority, but does not need to be. root %Certificate Authority, but does not need to be.
You can build up the chain using normal QList operations, such as You can build up the chain using normal QList operations, such as
QList::append(). QList::append().
@ -1211,7 +1228,9 @@ public:
/** /**
Create an empty certificate chain Create an empty certificate chain
*/ */
inline CertificateChain() {} inline CertificateChain()
{
}
/** /**
Create a certificate chain, starting at the specified certificate Create a certificate chain, starting at the specified certificate
@ -1219,12 +1238,18 @@ public:
\param primary the end-user certificate that forms one end of the \param primary the end-user certificate that forms one end of the
chain chain
*/ */
inline CertificateChain(const Certificate &primary) { append(primary); } inline CertificateChain(const Certificate &primary)
{
append(primary);
}
/** /**
Return the primary (end-user) Certificate Return the primary (end-user) Certificate
*/ */
inline const Certificate & primary() const { return first(); } inline const Certificate &primary() const
{
return first();
}
/** /**
Check the validity of a certificate chain Check the validity of a certificate chain
@ -1239,7 +1264,10 @@ public:
\sa Certificate::validate() \sa Certificate::validate()
*/ */
inline Validity validate(const CertificateCollection &trusted, const QList<CRL> &untrusted_crls = QList<CRL>(), UsageMode u = UsageAny, ValidateFlags vf = ValidateAll) const; inline Validity validate(const CertificateCollection &trusted,
const QList<CRL> & untrusted_crls = QList<CRL>(),
UsageMode u = UsageAny,
ValidateFlags vf = ValidateAll) const;
/** /**
Complete a certificate chain for the primary certificate, using the Complete a certificate chain for the primary certificate, using the
@ -1264,10 +1292,14 @@ public:
\sa validate \sa validate
*/ */
inline CertificateChain complete(const QList<Certificate> &issuers = QList<Certificate>(), Validity *result = 0) const; inline CertificateChain complete(const QList<Certificate> &issuers = QList<Certificate>(),
Validity * result = nullptr) const;
}; };
inline Validity CertificateChain::validate(const CertificateCollection &trusted, const QList<CRL> &untrusted_crls, UsageMode u, ValidateFlags vf) const inline Validity CertificateChain::validate(const CertificateCollection &trusted,
const QList<CRL> & untrusted_crls,
UsageMode u,
ValidateFlags vf) const
{ {
if (isEmpty()) if (isEmpty())
return ErrorValidityUnknown; return ErrorValidityUnknown;
@ -1324,7 +1356,7 @@ public:
*/ */
CertificateRequest(const CertificateRequest &from); CertificateRequest(const CertificateRequest &from);
~CertificateRequest(); ~CertificateRequest() override;
/** /**
Standard assignment operator Standard assignment operator
@ -1399,7 +1431,7 @@ public:
PublicKey subjectPublicKey() const; PublicKey subjectPublicKey() const;
/** /**
Test if this Certificate Request is for a Certificate Authority Test if this %Certificate Request is for a %Certificate Authority
certificate certificate
\note this only applies to PKCS#10 format certificate requests \note this only applies to PKCS#10 format certificate requests
@ -1407,7 +1439,7 @@ public:
bool isCA() const; bool isCA() const;
/** /**
The path limit for the certificate in this Certificate Request The path limit for the certificate in this %Certificate Request
\note this only applies to PKCS#10 format certificate requests \note this only applies to PKCS#10 format certificate requests
*/ */
@ -1444,14 +1476,14 @@ public:
} }
/** /**
Export the Certificate Request into a DER format Export the %Certificate Request into a DER format
\note this only applies to PKCS#10 format certificate requests \note this only applies to PKCS#10 format certificate requests
*/ */
QByteArray toDER() const; QByteArray toDER() const;
/** /**
Export the Certificate Request into a PEM format Export the %Certificate Request into a PEM format
\note this only applies to PKCS#10 format certificate requests \note this only applies to PKCS#10 format certificate requests
*/ */
@ -1480,7 +1512,8 @@ public:
\note this only applies to PKCS#10 format certificate requests \note this only applies to PKCS#10 format certificate requests
*/ */
static CertificateRequest fromDER(const QByteArray &a, ConvertResult *result = 0, const QString &provider = QString()); static CertificateRequest
fromDER(const QByteArray &a, ConvertResult *result = nullptr, const QString &provider = QString());
/** /**
Import the certificate request from PEM format Import the certificate request from PEM format
@ -1497,7 +1530,8 @@ public:
\note this only applies to PKCS#10 format certificate requests \note this only applies to PKCS#10 format certificate requests
*/ */
static CertificateRequest fromPEM(const QString &s, ConvertResult *result = 0, const QString &provider = QString()); static CertificateRequest
fromPEM(const QString &s, ConvertResult *result = nullptr, const QString &provider = QString());
/** /**
Import the certificate request from a file Import the certificate request from a file
@ -1514,7 +1548,8 @@ public:
\note this only applies to PKCS#10 format certificate requests \note this only applies to PKCS#10 format certificate requests
*/ */
static CertificateRequest fromPEMFile(const QString &fileName, ConvertResult *result = 0, const QString &provider = QString()); static CertificateRequest
fromPEMFile(const QString &fileName, ConvertResult *result = nullptr, const QString &provider = QString());
/** /**
Export the CertificateRequest to a string Export the CertificateRequest to a string
@ -1539,7 +1574,8 @@ public:
\note this only applies to SPKAC format certificate requests \note this only applies to SPKAC format certificate requests
*/ */
static CertificateRequest fromString(const QString &s, ConvertResult *result = 0, const QString &provider = QString()); static CertificateRequest
fromString(const QString &s, ConvertResult *result = nullptr, const QString &provider = QString());
/** /**
\internal \internal
@ -1712,7 +1748,7 @@ public:
*/ */
CRL(const CRL &from); CRL(const CRL &from);
~CRL(); ~CRL() override;
/** /**
Standard assignment operator Standard assignment operator
@ -1724,7 +1760,7 @@ public:
/** /**
Test if the CRL is empty Test if the CRL is empty
\return true if the CRL is entry, otherwise return false \return true if the CRL is empty, otherwise return false
*/ */
bool isNull() const; bool isNull() const;
@ -1833,7 +1869,7 @@ public:
\return the CRL corresponding to the contents of the array \return the CRL corresponding to the contents of the array
*/ */
static CRL fromDER(const QByteArray &a, ConvertResult *result = 0, const QString &provider = QString()); static CRL fromDER(const QByteArray &a, ConvertResult *result = nullptr, const QString &provider = QString());
/** /**
Import a PEM encoded %Certificate Revocation List (CRL) Import a PEM encoded %Certificate Revocation List (CRL)
@ -1846,7 +1882,7 @@ public:
\return the CRL corresponding to the contents of the string \return the CRL corresponding to the contents of the string
*/ */
static CRL fromPEM(const QString &s, ConvertResult *result = 0, const QString &provider = QString()); static CRL fromPEM(const QString &s, ConvertResult *result = nullptr, const QString &provider = QString());
/** /**
Import a PEM encoded %Certificate Revocation List (CRL) from a file Import a PEM encoded %Certificate Revocation List (CRL) from a file
@ -1860,7 +1896,8 @@ public:
\return the CRL in the file \return the CRL in the file
*/ */
static CRL fromPEMFile(const QString &fileName, ConvertResult *result = 0, const QString &provider = QString()); static CRL
fromPEMFile(const QString &fileName, ConvertResult *result = nullptr, const QString &provider = QString());
/** /**
\internal \internal
@ -2005,7 +2042,8 @@ public:
\return the CertificateCollection corresponding to the contents of \return the CertificateCollection corresponding to the contents of
the file specified in fileName the file specified in fileName
*/ */
static CertificateCollection fromFlatTextFile(const QString &fileName, ConvertResult *result = 0, const QString &provider = QString()); static CertificateCollection
fromFlatTextFile(const QString &fileName, ConvertResult *result = nullptr, const QString &provider = QString());
/** /**
import a CertificateCollection from a PKCS#7 file import a CertificateCollection from a PKCS#7 file
@ -2020,7 +2058,8 @@ public:
\return the CertificateCollection corresponding to the contents of \return the CertificateCollection corresponding to the contents of
the file specified in fileName the file specified in fileName
*/ */
static CertificateCollection fromPKCS7File(const QString &fileName, ConvertResult *result = 0, const QString &provider = QString()); static CertificateCollection
fromPKCS7File(const QString &fileName, ConvertResult *result = nullptr, const QString &provider = QString());
private: private:
class Private; class Private;
@ -2055,7 +2094,7 @@ public:
*/ */
CertificateAuthority(const CertificateAuthority &from); CertificateAuthority(const CertificateAuthority &from);
~CertificateAuthority(); ~CertificateAuthority() override;
/** /**
Standard assignment operator Standard assignment operator
@ -2090,7 +2129,7 @@ public:
Certificate createCertificate(const PublicKey &key, const CertificateOptions &opts) const; Certificate createCertificate(const PublicKey &key, const CertificateOptions &opts) const;
/** /**
Create a new Certificate Revocation List (CRL) Create a new %Certificate Revocation List (CRL)
\param nextUpdate the date that the CRL will be updated \param nextUpdate the date that the CRL will be updated
@ -2305,7 +2344,10 @@ else
\note This synchronous operation may require event handling, and so \note This synchronous operation may require event handling, and so
it must not be called from the same thread as an EventHandler. it must not be called from the same thread as an EventHandler.
*/ */
static KeyBundle fromArray(const QByteArray &a, const SecureArray &passphrase = SecureArray(), ConvertResult *result = 0, const QString &provider = QString()); static KeyBundle fromArray(const QByteArray & a,
const SecureArray &passphrase = SecureArray(),
ConvertResult * result = nullptr,
const QString & provider = QString());
/** /**
Import the key bundle from a file in PKCS12 (.p12) format Import the key bundle from a file in PKCS12 (.p12) format
@ -2337,7 +2379,10 @@ else
\note This synchronous operation may require event handling, and so \note This synchronous operation may require event handling, and so
it must not be called from the same thread as an EventHandler. it must not be called from the same thread as an EventHandler.
*/ */
static KeyBundle fromFile(const QString &fileName, const SecureArray &passphrase = SecureArray(), ConvertResult *result = 0, const QString &provider = QString()); static KeyBundle fromFile(const QString & fileName,
const SecureArray &passphrase = SecureArray(),
ConvertResult * result = nullptr,
const QString & provider = QString());
private: private:
class Private; class Private;
@ -2384,7 +2429,7 @@ public:
*/ */
PGPKey(const PGPKey &from); PGPKey(const PGPKey &from);
~PGPKey(); ~PGPKey() override;
/** /**
Standard assignment operator Standard assignment operator
@ -2494,7 +2539,7 @@ public:
\param provider the provider to use, if a particular provider is \param provider the provider to use, if a particular provider is
required required
*/ */
static PGPKey fromArray(const QByteArray &a, ConvertResult *result = 0, const QString &provider = QString()); static PGPKey fromArray(const QByteArray &a, ConvertResult *result = nullptr, const QString &provider = QString());
/** /**
Import the key from a string Import the key from a string
@ -2505,7 +2550,7 @@ public:
\param provider the provider to use, if a particular provider is \param provider the provider to use, if a particular provider is
required required
*/ */
static PGPKey fromString(const QString &s, ConvertResult *result = 0, const QString &provider = QString()); static PGPKey fromString(const QString &s, ConvertResult *result = nullptr, const QString &provider = QString());
/** /**
Import the key from a file Import the key from a file
@ -2517,7 +2562,8 @@ public:
\param provider the provider to use, if a particular provider is \param provider the provider to use, if a particular provider is
required required
*/ */
static PGPKey fromFile(const QString &fileName, ConvertResult *result = 0, const QString &provider = QString()); static PGPKey
fromFile(const QString &fileName, ConvertResult *result = nullptr, const QString &provider = QString());
private: private:
class Private; class Private;
@ -2572,8 +2618,8 @@ public:
\param parent the parent object for this object \param parent the parent object for this object
*/ */
KeyLoader(QObject *parent = 0); KeyLoader(QObject *parent = nullptr);
~KeyLoader(); ~KeyLoader() override;
/** /**
Initiate an asynchronous loading of a PrivateKey from a PEM format Initiate an asynchronous loading of a PrivateKey from a PEM format

View File

@ -2,6 +2,7 @@
* qca_core.h - Qt Cryptographic Architecture * qca_core.h - Qt Cryptographic Architecture
* Copyright (C) 2003-2007 Justin Karneges <justin@affinix.com> * Copyright (C) 2003-2007 Justin Karneges <justin@affinix.com>
* Copyright (C) 2004,2005 Brad Hards <bradh@frogmouth.net> * Copyright (C) 2004,2005 Brad Hards <bradh@frogmouth.net>
* Copyright (C) 2014-2016 Ivan Romanov <drizt@land.ru>
* *
* This library is free software; you can redistribute it and/or * This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public * modify it under the terms of the GNU Lesser General Public
@ -33,15 +34,15 @@
#ifndef QCA_CORE_H #ifndef QCA_CORE_H
#define QCA_CORE_H #define QCA_CORE_H
#include <QString>
#include <QStringList>
#include <QList>
#include <QSharedData>
#include <QSharedDataPointer>
#include "qca_export.h" #include "qca_export.h"
#include "qca_support.h" #include "qca_support.h"
#include "qca_tools.h" #include "qca_tools.h"
#include "qca_version.h" #include "qca_version.h"
#include <QList>
#include <QSharedData>
#include <QSharedDataPointer>
#include <QString>
#include <QStringList>
/** /**
The current version of %QCA. The current version of %QCA.
@ -491,8 +492,8 @@ QCA_EXPORT Logger *logger();
*/ */
#define QCA_logTextMessage(message, severity) \ #define QCA_logTextMessage(message, severity) \
do { \ do { \
register QCA::Logger::Severity s = severity; \ QCA::Logger::Severity s = severity; \
register QCA::Logger *l = QCA::logger (); \ QCA::Logger * l = QCA::logger(); \
if (s <= l->level()) { \ if (s <= l->level()) { \
l->logTextMessage(message, s); \ l->logTextMessage(message, s); \
} \ } \
@ -510,8 +511,8 @@ QCA_EXPORT Logger *logger();
*/ */
#define QCA_logBinaryMessage(blob, severity) \ #define QCA_logBinaryMessage(blob, severity) \
do { \ do { \
register QCA::Logger::Severity s = severity; \ QCA::Logger::Severity s = severity; \
register QCA::Logger *l = QCA::logger (); \ QCA::Logger * l = QCA::logger(); \
if (s <= l->level()) { \ if (s <= l->level()) { \
l->logBinaryMessage(blob, s); \ l->logBinaryMessage(blob, s); \
} \ } \
@ -618,6 +619,32 @@ if (QCA::hexToArray(QString("62626262626262006262") ) == test )
*/ */
QCA_EXPORT QByteArray hexToArray(const QString &hexString); QCA_EXPORT QByteArray hexToArray(const QString &hexString);
/**
Convert a byte array to printable base64
representation.
This is a convenience function to convert an arbitrary
QByteArray to a printable representation.
\param array the array to be converted
\return a printable representation
*/
QCA_EXPORT QString arrayToBase64(const QByteArray &array);
/**
Convert a QString containing a base64 representation
of a byte array into a QByteArray
This is a convenience function to convert a printable
representation into a QByteArray - effectively the inverse
of QCA::arrayToBase64.
\param base64String the string containing a printable
representation to be converted
\return the equivalent QByteArray
*/
QCA_EXPORT QByteArray base64ToArray(const QString &base64String);
/** /**
\class Initializer qca_core.h QtCrypto \class Initializer qca_core.h QtCrypto
@ -641,6 +668,9 @@ public:
*/ */
explicit Initializer(MemoryMode m = Practical, int prealloc = 64); explicit Initializer(MemoryMode m = Practical, int prealloc = 64);
~Initializer(); ~Initializer();
Initializer(const Initializer &) = delete;
Initializer &operator=(const Initializer &) = delete;
}; };
/** /**
@ -679,18 +709,27 @@ public:
multiple of. multiple of.
*/ */
KeyLength(int min, int max, int multiple) KeyLength(int min, int max, int multiple)
: _min( min ), _max(max), _multiple( multiple ) : _min(min)
{ } , _max(max)
, _multiple(multiple)
{
}
/** /**
Obtain the minimum length for the key, in bytes Obtain the minimum length for the key, in bytes
*/ */
int minimum() const { return _min; } int minimum() const
{
return _min;
}
/** /**
Obtain the maximum length for the key, in bytes Obtain the maximum length for the key, in bytes
*/ */
int maximum() const { return _max; } int maximum() const
{
return _max;
}
/** /**
Return the number of bytes that the key must be a multiple of Return the number of bytes that the key must be a multiple of
@ -698,7 +737,10 @@ public:
If this is one, then anything between minimum and maximum (inclusive) If this is one, then anything between minimum and maximum (inclusive)
is acceptable. is acceptable.
*/ */
int multiple() const { return _multiple; } int multiple() const
{
return _multiple;
}
private: private:
const int _min, _max, _multiple; const int _min, _max, _multiple;
@ -898,7 +940,7 @@ class QCA_EXPORT Provider::Context : public QObject
{ {
Q_OBJECT Q_OBJECT
public: public:
virtual ~Context(); ~Context() override;
/** /**
The Provider associated with this Context The Provider associated with this Context
@ -968,7 +1010,7 @@ class QCA_EXPORT BasicContext : public Provider::Context
{ {
Q_OBJECT Q_OBJECT
public: public:
~BasicContext(); ~BasicContext() override;
protected: protected:
/** /**
@ -1268,32 +1310,69 @@ class QCA_EXPORT InitializationVector : public SecureArray
{ {
public: public:
/** /**
Construct an empty (zero length) initisation vector Construct an empty (zero length) initialization vector
*/ */
InitializationVector(); InitializationVector();
/** /**
Construct an initialisation vector of the specified size Construct an initialization vector of the specified size
\param size the length of the initialisation vector, in bytes \param size the length of the initialization vector, in bytes
*/ */
InitializationVector(int size); InitializationVector(int size);
/** /**
Construct an initialisation vector from a provided byte array Construct an initialization vector from a provided byte array
\param a the byte array to copy \param a the byte array to copy
*/ */
InitializationVector(const SecureArray &a); InitializationVector(const SecureArray &a);
/** /**
Construct an initialisation vector from a provided byte array Construct an initialization vector from a provided byte array
\param a the byte array to copy \param a the byte array to copy
*/ */
InitializationVector(const QByteArray &a); InitializationVector(const QByteArray &a);
}; };
/**
\class AuthTag qca_core.h QtCrypto
Container for authentication tag
\ingroup UserAPI
*/
class QCA_EXPORT AuthTag : public SecureArray
{
public:
/**
Construct an empty authentication tag
*/
AuthTag();
/**
Construct an empty authentication tag of the specified size
\param size the length of the authentication tag, in bytes
*/
AuthTag(int size);
/**
Construct an authentication tag from a provided byte array
\param a the byte array to copy
*/
AuthTag(const SecureArray &a);
/**
Construct an authentication tag from a provided byte array
\param a the byte array to copy
*/
AuthTag(const QByteArray &a);
};
/** /**
\class Event qca_core.h QtCrypto \class Event qca_core.h QtCrypto
@ -1443,7 +1522,10 @@ public:
information is required for information is required for
\param ptr opaque data \param ptr opaque data
*/ */
void setPasswordKeyStore(PasswordStyle pstyle, const KeyStoreInfo &keyStoreInfo, const KeyStoreEntry &keyStoreEntry, void *ptr); void setPasswordKeyStore(PasswordStyle pstyle,
const KeyStoreInfo & keyStoreInfo,
const KeyStoreEntry &keyStoreEntry,
void * ptr);
/** /**
Set the values for this Event Set the values for this Event
@ -1502,8 +1584,8 @@ public:
\param parent the parent object for this object \param parent the parent object for this object
*/ */
EventHandler(QObject *parent = 0); EventHandler(QObject *parent = nullptr);
~EventHandler(); ~EventHandler() override;
/** /**
mandatory function to call after connecting the mandatory function to call after connecting the
@ -1584,8 +1666,8 @@ public:
\param parent the parent object for this QObject \param parent the parent object for this QObject
*/ */
PasswordAsker(QObject *parent = 0); PasswordAsker(QObject *parent = nullptr);
~PasswordAsker(); ~PasswordAsker() override;
/** /**
queue a password / passphrase request associated with a key store queue a password / passphrase request associated with a key store
@ -1598,7 +1680,8 @@ public:
information is required for (if applicable) information is required for (if applicable)
\param ptr opaque data \param ptr opaque data
*/ */
void ask(Event::PasswordStyle pstyle, const KeyStoreInfo &keyStoreInfo, const KeyStoreEntry &keyStoreEntry, void *ptr); void
ask(Event::PasswordStyle pstyle, const KeyStoreInfo &keyStoreInfo, const KeyStoreEntry &keyStoreEntry, void *ptr);
/** /**
queue a password / passphrase request associated with a file queue a password / passphrase request associated with a file
@ -1676,8 +1759,8 @@ public:
\param parent the parent object for this QObject \param parent the parent object for this QObject
*/ */
TokenAsker(QObject *parent = 0); TokenAsker(QObject *parent = nullptr);
~TokenAsker(); ~TokenAsker() override;
/** /**
queue a token request associated with a key store queue a token request associated with a key store

View File

@ -33,8 +33,8 @@
#ifndef QCA_KEYSTORE_H #ifndef QCA_KEYSTORE_H
#define QCA_KEYSTORE_H #define QCA_KEYSTORE_H
#include "qca_core.h"
#include "qca_cert.h" #include "qca_cert.h"
#include "qca_core.h"
namespace QCA { namespace QCA {
@ -90,7 +90,7 @@ if(entry.ensureAvailable())
\code \code
KeyStoreEntryWatcher *watcher = new KeyStoreEntryWatcher(entry); KeyStoreEntryWatcher *watcher = new KeyStoreEntryWatcher(entry);
connect(watcher, SIGNAL(available()), SLOT(entry_available())); connect(watcher, &KeyStoreEntryWatcher::available, this, &YourClass::entry_available);
... ...
void entry_available() void entry_available()
{ {
@ -174,7 +174,7 @@ public:
*/ */
KeyStoreEntry(const KeyStoreEntry &from); KeyStoreEntry(const KeyStoreEntry &from);
~KeyStoreEntry(); ~KeyStoreEntry() override;
/** /**
Standard assignment operator Standard assignment operator
@ -361,9 +361,9 @@ public:
\param e the KeyStoreEntry to monitor \param e the KeyStoreEntry to monitor
\param parent the parent object for this object \param parent the parent object for this object
*/ */
explicit KeyStoreEntryWatcher(const KeyStoreEntry &e, QObject *parent = 0); explicit KeyStoreEntryWatcher(const KeyStoreEntry &e, QObject *parent = nullptr);
~KeyStoreEntryWatcher(); ~KeyStoreEntryWatcher() override;
/** /**
The KeyStoreEntry that is being monitored The KeyStoreEntry that is being monitored
@ -437,7 +437,7 @@ public:
*/ */
KeyStore(const QString &id, KeyStoreManager *keyStoreManager); KeyStore(const QString &id, KeyStoreManager *keyStoreManager);
~KeyStore(); ~KeyStore() override;
/** /**
Check if this KeyStore is valid Check if this KeyStore is valid
@ -715,8 +715,8 @@ public:
\param parent the parent for this object \param parent the parent for this object
*/ */
KeyStoreManager(QObject *parent = 0); KeyStoreManager(QObject *parent = nullptr);
~KeyStoreManager(); ~KeyStoreManager() override;
/** /**
Initialize all key store providers Initialize all key store providers

View File

@ -33,8 +33,8 @@
#ifndef QCA_PUBLICKEY_H #ifndef QCA_PUBLICKEY_H
#define QCA_PUBLICKEY_H #define QCA_PUBLICKEY_H
#include <QObject>
#include "qca_core.h" #include "qca_core.h"
#include <QObject>
namespace QCA { namespace QCA {
@ -78,7 +78,8 @@ enum SignatureAlgorithm
EMSA3_MD5, ///< MD5, with EMSA3 (ie PKCS#1 Version 1.5) encoding (this is the usual RSA algorithm) EMSA3_MD5, ///< MD5, with EMSA3 (ie PKCS#1 Version 1.5) encoding (this is the usual RSA algorithm)
EMSA3_MD2, ///< MD2, with EMSA3 (ie PKCS#1 Version 1.5) encoding EMSA3_MD2, ///< MD2, with EMSA3 (ie PKCS#1 Version 1.5) encoding
EMSA3_RIPEMD160, ///< RIPEMD160, with EMSA3 (ie PKCS#1 Version 1.5) encoding EMSA3_RIPEMD160, ///< RIPEMD160, with EMSA3 (ie PKCS#1 Version 1.5) encoding
EMSA3_Raw, ///< EMSA3 without computing a message digest or a DigestInfo encoding (identical to PKCS#11's CKM_RSA_PKCS mechanism) EMSA3_Raw, ///< EMSA3 without computing a message digest or a DigestInfo encoding (identical to PKCS#11's
///< CKM_RSA_PKCS mechanism)
EMSA3_SHA224, ///< SHA224, with EMSA3 (ie PKCS#1 Version 1.5) encoding EMSA3_SHA224, ///< SHA224, with EMSA3 (ie PKCS#1 Version 1.5) encoding
EMSA3_SHA256, ///< SHA256, with EMSA3 (ie PKCS#1 Version 1.5) encoding EMSA3_SHA256, ///< SHA256, with EMSA3 (ie PKCS#1 Version 1.5) encoding
EMSA3_SHA384, ///< SHA384, with EMSA3 (ie PKCS#1 Version 1.5) encoding EMSA3_SHA384, ///< SHA384, with EMSA3 (ie PKCS#1 Version 1.5) encoding
@ -252,7 +253,8 @@ public:
/** /**
Types of public key cryptography keys supported by QCA Types of public key cryptography keys supported by QCA
*/ */
enum Type { enum Type
{
RSA, ///< RSA key RSA, ///< RSA key
DSA, ///< DSA key DSA, ///< DSA key
DH ///< Diffie Hellman key DH ///< Diffie Hellman key
@ -270,7 +272,7 @@ public:
*/ */
PKey(const PKey &from); PKey(const PKey &from);
~PKey(); ~PKey() override;
/** /**
Standard assignment operator Standard assignment operator
@ -554,7 +556,7 @@ public:
*/ */
PublicKey(const PublicKey &from); PublicKey(const PublicKey &from);
~PublicKey(); ~PublicKey() override;
/** /**
Assignment operator Assignment operator
@ -691,7 +693,10 @@ if( pubkey.canVerify() )
\return true if the signature is valid for the message \return true if the signature is valid for the message
*/ */
bool verifyMessage(const MemoryRegion &a, const QByteArray &sig, SignatureAlgorithm alg, SignatureFormat format = DefaultFormat); bool verifyMessage(const MemoryRegion &a,
const QByteArray & sig,
SignatureAlgorithm alg,
SignatureFormat format = DefaultFormat);
/** /**
Export the key in Distinguished Encoding Rules (DER) format Export the key in Distinguished Encoding Rules (DER) format
@ -743,7 +748,7 @@ if (! QCA::ConvertGood == conversionResult)
conversion succeeded (ConvertGood) or not conversion succeeded (ConvertGood) or not
\param provider the name of the provider to use for the import. \param provider the name of the provider to use for the import.
*/ */
static PublicKey fromDER(const QByteArray &a, ConvertResult *result = 0, const QString &provider = QString()); static PublicKey fromDER(const QByteArray &a, ConvertResult *result = nullptr, const QString &provider = QString());
/** /**
Import a key in Privacy Enhanced Mail (PEM) format Import a key in Privacy Enhanced Mail (PEM) format
@ -770,7 +775,7 @@ if (! QCA::ConvertGood == conversionResult)
\sa toPEM, which provides an inverse of fromPEM() \sa toPEM, which provides an inverse of fromPEM()
\sa fromPEMFile, which provides an import direct from a file. \sa fromPEMFile, which provides an import direct from a file.
*/ */
static PublicKey fromPEM(const QString &s, ConvertResult *result = 0, const QString &provider = QString()); static PublicKey fromPEM(const QString &s, ConvertResult *result = nullptr, const QString &provider = QString());
/** /**
Import a key in Privacy Enhanced Mail (PEM) format from a file Import a key in Privacy Enhanced Mail (PEM) format from a file
@ -799,7 +804,8 @@ if (! QCA::ConvertGood == conversionResult)
\note there is also a constructor form that can import from a file \note there is also a constructor form that can import from a file
*/ */
static PublicKey fromPEMFile(const QString &fileName, ConvertResult *result = 0, const QString &provider = QString()); static PublicKey
fromPEMFile(const QString &fileName, ConvertResult *result = nullptr, const QString &provider = QString());
protected: protected:
/** /**
@ -851,7 +857,7 @@ public:
*/ */
PrivateKey(const PrivateKey &from); PrivateKey(const PrivateKey &from);
~PrivateKey(); ~PrivateKey() override;
/** /**
Assignment operator Assignment operator
@ -1025,7 +1031,9 @@ public:
\sa fromPEM provides an inverse of toPEM, converting the PEM \sa fromPEM provides an inverse of toPEM, converting the PEM
encoded key back to a PrivateKey encoded key back to a PrivateKey
*/ */
bool toPEMFile(const QString &fileName, const SecureArray &passphrase = SecureArray(), PBEAlgorithm pbe = PBEDefault) const; bool toPEMFile(const QString & fileName,
const SecureArray &passphrase = SecureArray(),
PBEAlgorithm pbe = PBEDefault) const;
/** /**
Import the key from Distinguished Encoding Rules (DER) format Import the key from Distinguished Encoding Rules (DER) format
@ -1045,7 +1053,10 @@ public:
\note This synchronous operation may require event handling, and so \note This synchronous operation may require event handling, and so
it must not be called from the same thread as an EventHandler. it must not be called from the same thread as an EventHandler.
*/ */
static PrivateKey fromDER(const SecureArray &a, const SecureArray &passphrase = SecureArray(), ConvertResult *result = 0, const QString &provider = QString()); static PrivateKey fromDER(const SecureArray &a,
const SecureArray &passphrase = SecureArray(),
ConvertResult * result = nullptr,
const QString & provider = QString());
/** /**
Import the key from Privacy Enhanced Mail (PEM) format Import the key from Privacy Enhanced Mail (PEM) format
@ -1065,7 +1076,10 @@ public:
\note This synchronous operation may require event handling, and so \note This synchronous operation may require event handling, and so
it must not be called from the same thread as an EventHandler. it must not be called from the same thread as an EventHandler.
*/ */
static PrivateKey fromPEM(const QString &s, const SecureArray &passphrase = SecureArray(), ConvertResult *result = 0, const QString &provider = QString()); static PrivateKey fromPEM(const QString & s,
const SecureArray &passphrase = SecureArray(),
ConvertResult * result = nullptr,
const QString & provider = QString());
/** /**
Import the key in Privacy Enhanced Mail (PEM) format from a file Import the key in Privacy Enhanced Mail (PEM) format from a file
@ -1089,7 +1103,10 @@ public:
\note This synchronous operation may require event handling, and so \note This synchronous operation may require event handling, and so
it must not be called from the same thread as an EventHandler. it must not be called from the same thread as an EventHandler.
*/ */
static PrivateKey fromPEMFile(const QString &fileName, const SecureArray &passphrase = SecureArray(), ConvertResult *result = 0, const QString &provider = QString()); static PrivateKey fromPEMFile(const QString & fileName,
const SecureArray &passphrase = SecureArray(),
ConvertResult * result = nullptr,
const QString & provider = QString());
protected: protected:
/** /**
@ -1126,9 +1143,9 @@ public:
\param parent the parent object, if applicable \param parent the parent object, if applicable
*/ */
KeyGenerator(QObject *parent = 0); KeyGenerator(QObject *parent = nullptr);
~KeyGenerator(); ~KeyGenerator() override;
/** /**
Test whether the key generator is set to operate in blocking mode, Test whether the key generator is set to operate in blocking mode,
@ -1325,7 +1342,12 @@ public:
\param provider the provider to use, if a particular provider is \param provider the provider to use, if a particular provider is
required required
*/ */
RSAPrivateKey(const BigInteger &n, const BigInteger &e, const BigInteger &p, const BigInteger &q, const BigInteger &d, const QString &provider = QString()); RSAPrivateKey(const BigInteger &n,
const BigInteger &e,
const BigInteger &p,
const BigInteger &q,
const BigInteger &d,
const QString & provider = QString());
/** /**
The public key value The public key value

View File

@ -34,8 +34,8 @@ class QCA_EXPORT SafeTimer : public QObject
{ {
Q_OBJECT Q_OBJECT
public: public:
SafeTimer(QObject *parent = 0); SafeTimer(QObject *parent = nullptr);
~SafeTimer(); ~SafeTimer() override;
int interval() const; int interval() const;
bool isActive() const; bool isActive() const;
@ -44,22 +44,26 @@ public:
void setSingleShot(bool singleShot); void setSingleShot(bool singleShot);
int timerId() const; int timerId() const;
public slots: public Q_SLOTS:
void start(int msec); void start(int msec);
void start(); void start();
void stop(); void stop();
signals: Q_SIGNALS:
void timeout(); void timeout();
protected: protected:
bool event(QEvent *event); bool event(QEvent *event) override;
void timerEvent(QTimerEvent *event); void timerEvent(QTimerEvent *event) override;
private: private:
// Functions is used internally. Outer world mustn't have access them. // Functions is used internally. Outer world mustn't have access them.
void startTimer() {} void startTimer()
void killTimer(int) {} {
}
void killTimer(int)
{
}
class Private; class Private;
Private *d; Private *d;

View File

@ -32,10 +32,10 @@
#ifndef QCA_SECURELAYER_H #ifndef QCA_SECURELAYER_H
#define QCA_SECURELAYER_H #define QCA_SECURELAYER_H
#include <QObject> #include "qca_cert.h"
#include "qca_core.h" #include "qca_core.h"
#include "qca_publickey.h" #include "qca_publickey.h"
#include "qca_cert.h" #include <QObject>
namespace QCA { namespace QCA {
@ -80,7 +80,7 @@ enum SecurityLevel
implementation, and that data is encrypted (or otherwise implementation, and that data is encrypted (or otherwise
protected, depending on the setup). The SecureLayer protected, depending on the setup). The SecureLayer
implementation then emits the readyReadOutgoing() signal, implementation then emits the readyReadOutgoing() signal,
and the application uses readOutgoing() to retrieve the the and the application uses readOutgoing() to retrieve the
encrypted data from the SecureLayer implementation. The encrypted data from the SecureLayer implementation. The
encrypted data is then sent out on the network. encrypted data is then sent out on the network.
@ -111,7 +111,7 @@ public:
\param parent the parent object for this object \param parent the parent object for this object
*/ */
SecureLayer(QObject *parent = 0); SecureLayer(QObject *parent = nullptr);
/** /**
Returns true if the layer has a meaningful "close". Returns true if the layer has a meaningful "close".
@ -176,7 +176,7 @@ public:
\param plainBytes the number of bytes that were read. \param plainBytes the number of bytes that were read.
*/ */
virtual QByteArray readOutgoing(int *plainBytes = 0) = 0; virtual QByteArray readOutgoing(int *plainBytes = nullptr) = 0;
/** /**
This allows you to read data without having it This allows you to read data without having it
@ -247,7 +247,7 @@ public:
*/ */
TLSSession(const TLSSession &from); TLSSession(const TLSSession &from);
~TLSSession(); ~TLSSession() override;
/** /**
Assignment operator Assignment operator
@ -345,7 +345,7 @@ public:
\param provider the name of the provider, if a specific provider \param provider the name of the provider, if a specific provider
is required is required
*/ */
explicit TLS(QObject *parent = 0, const QString &provider = QString()); explicit TLS(QObject *parent = nullptr, const QString &provider = QString());
/** /**
Constructor for Transport Layer Security connection. Constructor for Transport Layer Security connection.
@ -358,12 +358,12 @@ public:
\param provider the name of the provider, if a specific provider is \param provider the name of the provider, if a specific provider is
required required
*/ */
explicit TLS(Mode mode, QObject *parent = 0, const QString &provider = QString()); explicit TLS(Mode mode, QObject *parent = nullptr, const QString &provider = QString());
/** /**
Destructor Destructor
*/ */
~TLS(); ~TLS() override;
/** /**
Reset the connection Reset the connection
@ -381,7 +381,7 @@ public:
\param version the protocol Version that the cipher \param version the protocol Version that the cipher
suites are required for suites are required for
\return list of the the names of the cipher suites \return list of the names of the cipher suites
supported. supported.
*/ */
QStringList supportedCipherSuites(const Version &version = TLS_v1) const; QStringList supportedCipherSuites(const Version &version = TLS_v1) const;
@ -681,16 +681,16 @@ foreach(const CertificateInfoOrdered &info, tls->issuerList())
CertificateChain peerCertificateChain() const; CertificateChain peerCertificateChain() const;
// reimplemented // reimplemented
virtual bool isClosable() const; bool isClosable() const override;
virtual int bytesAvailable() const; int bytesAvailable() const override;
virtual int bytesOutgoingAvailable() const; int bytesOutgoingAvailable() const override;
virtual void close(); void close() override;
virtual void write(const QByteArray &a); void write(const QByteArray &a) override;
virtual QByteArray read(); QByteArray read() override;
virtual void writeIncoming(const QByteArray &a); void writeIncoming(const QByteArray &a) override;
virtual QByteArray readOutgoing(int *plainBytes = 0); QByteArray readOutgoing(int *plainBytes = nullptr) override;
virtual QByteArray readUnprocessed(); QByteArray readUnprocessed() override;
virtual int convertBytesWritten(qint64 encryptedBytes); int convertBytesWritten(qint64 encryptedBytes) override;
/** /**
Determine the number of packets available to be Determine the number of packets available to be
@ -783,11 +783,7 @@ protected:
\param signal the name of the signal that has been \param signal the name of the signal that has been
connected to. connected to.
*/ */
#if QT_VERSION >= 0x050000 void connectNotify(const QMetaMethod &signal) override;
void connectNotify(const QMetaMethod &signal);
#else
void connectNotify(const char *signal);
#endif
/** /**
Called when a connection is removed from a particular signal Called when a connection is removed from a particular signal
@ -795,11 +791,7 @@ protected:
\param signal the name of the signal that has been \param signal the name of the signal that has been
disconnected from. disconnected from.
*/ */
#if QT_VERSION >= 0x050000 void disconnectNotify(const QMetaMethod &signal) override;
void disconnectNotify(const QMetaMethod &signal);
#else
void disconnectNotify(const char *signal);
#endif
private: private:
Q_DISABLE_COPY(TLS) Q_DISABLE_COPY(TLS)
@ -977,9 +969,9 @@ public:
specified, or specified as empty, then any provider is specified, or specified as empty, then any provider is
acceptable. acceptable.
*/ */
explicit SASL(QObject *parent = 0, const QString &provider = QString()); explicit SASL(QObject *parent = nullptr, const QString &provider = QString());
~SASL(); ~SASL() override;
/** /**
Reset the %SASL mechanism Reset the %SASL mechanism
@ -1059,7 +1051,10 @@ public:
\param mechlist the list of mechanisms which can be used \param mechlist the list of mechanisms which can be used
\param mode the mode to use on the client side \param mode the mode to use on the client side
*/ */
void startClient(const QString &service, const QString &host, const QStringList &mechlist, ClientSendMode mode = AllowClientSendFirst); void startClient(const QString & service,
const QString & host,
const QStringList &mechlist,
ClientSendMode mode = AllowClientSendFirst);
/** /**
Initialise the server side of the connection Initialise the server side of the connection
@ -1072,7 +1067,10 @@ public:
\param realm the realm to use \param realm the realm to use
\param mode which mode to use on the server side \param mode which mode to use on the server side
*/ */
void startServer(const QString &service, const QString &host, const QString &realm, ServerSendMode mode = DisableServerSendLast); void startServer(const QString &service,
const QString &host,
const QString &realm,
ServerSendMode mode = DisableServerSendLast);
/** /**
Process the first step in server mode (server) Process the first step in server mode (server)
@ -1177,13 +1175,13 @@ public:
void continueAfterAuthCheck(); void continueAfterAuthCheck();
// reimplemented // reimplemented
virtual int bytesAvailable() const; int bytesAvailable() const override;
virtual int bytesOutgoingAvailable() const; int bytesOutgoingAvailable() const override;
virtual void write(const QByteArray &a); void write(const QByteArray &a) override;
virtual QByteArray read(); QByteArray read() override;
virtual void writeIncoming(const QByteArray &a); void writeIncoming(const QByteArray &a) override;
virtual QByteArray readOutgoing(int *plainBytes = 0); QByteArray readOutgoing(int *plainBytes = nullptr) override;
virtual int convertBytesWritten(qint64 encryptedBytes); int convertBytesWritten(qint64 encryptedBytes) override;
Q_SIGNALS: Q_SIGNALS:
/** /**

View File

@ -33,10 +33,10 @@
#ifndef QCA_SECUREMESSAGE_H #ifndef QCA_SECUREMESSAGE_H
#define QCA_SECUREMESSAGE_H #define QCA_SECUREMESSAGE_H
#include <QObject> #include "qca_cert.h"
#include "qca_core.h" #include "qca_core.h"
#include "qca_publickey.h" #include "qca_publickey.h"
#include "qca_cert.h" #include <QObject>
class QDateTime; class QDateTime;
@ -262,7 +262,6 @@ private:
*/ */
typedef QList<SecureMessageSignature> SecureMessageSignatureList; typedef QList<SecureMessageSignature> SecureMessageSignatureList;
/** /**
\class SecureMessage qca_securemessage.h QtCrypto \class SecureMessage qca_securemessage.h QtCrypto
@ -381,7 +380,7 @@ public:
object object
*/ */
SecureMessage(SecureMessageSystem *system); SecureMessage(SecureMessageSystem *system);
~SecureMessage(); ~SecureMessage() override;
/** /**
The Type of secure message The Type of secure message
@ -804,7 +803,7 @@ class QCA_EXPORT SecureMessageSystem : public QObject, public Algorithm
{ {
Q_OBJECT Q_OBJECT
public: public:
~SecureMessageSystem(); ~SecureMessageSystem() override;
protected: protected:
/** /**
@ -848,8 +847,8 @@ public:
\param provider the provider to use, if a specific \param provider the provider to use, if a specific
provider is required provider is required
*/ */
explicit OpenPGP(QObject *parent = 0, const QString &provider = QString()); explicit OpenPGP(QObject *parent = nullptr, const QString &provider = QString());
~OpenPGP(); ~OpenPGP() override;
private: private:
Q_DISABLE_COPY(OpenPGP) Q_DISABLE_COPY(OpenPGP)
@ -894,8 +893,8 @@ public:
\param provider the provider to use, if a specific \param provider the provider to use, if a specific
provider is required provider is required
*/ */
explicit CMS(QObject *parent = 0, const QString &provider = QString()); explicit CMS(QObject *parent = nullptr, const QString &provider = QString());
~CMS(); ~CMS() override;
/** /**
Return the trusted certificates set for this object Return the trusted certificates set for this object

View File

@ -36,17 +36,17 @@
#ifndef QCA_SUPPORT_H #ifndef QCA_SUPPORT_H
#define QCA_SUPPORT_H #define QCA_SUPPORT_H
#include <QByteArray>
#include <QString>
#include <QObject>
#include <QVariant>
#include <QVariantList>
#include <QStringList>
#include <QList>
#include <QMetaObject>
#include <QThread>
#include "qca_export.h" #include "qca_export.h"
#include "qca_tools.h" #include "qca_tools.h"
#include <QByteArray>
#include <QList>
#include <QMetaObject>
#include <QObject>
#include <QString>
#include <QStringList>
#include <QThread>
#include <QVariant>
#include <QVariantList>
namespace QCA { namespace QCA {
@ -98,7 +98,13 @@ myTypeName = QCA::methodReturnType( testClass.metaObject(), QByteArray( "boolMet
\relates SyncThread \relates SyncThread
*/ */
QCA_EXPORT QByteArray methodReturnType(const QMetaObject *obj, const QByteArray &method, const QList<QByteArray> argTypes); #if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
QCA_EXPORT int methodReturnType(const QMetaObject *obj, const QByteArray &method, const QList<QByteArray> &argTypes);
#else
QCA_EXPORT QByteArray methodReturnType(const QMetaObject * obj,
const QByteArray & method,
const QList<QByteArray> argTypes);
#endif
/** /**
Convenience method to invoke a method by name, using a variant Convenience method to invoke a method by name, using a variant
@ -141,7 +147,11 @@ ret = QCA::invokeMethodWithVariants( testClass1, QByteArray( "boolMethod" ), arg
\relates SyncThread \relates SyncThread
*/ */
QCA_EXPORT bool invokeMethodWithVariants(QObject *obj, const QByteArray &method, const QVariantList &args, QVariant *ret, Qt::ConnectionType type = Qt::AutoConnection); QCA_EXPORT bool invokeMethodWithVariants(QObject * obj,
const QByteArray & method,
const QVariantList &args,
QVariant * ret,
Qt::ConnectionType type = Qt::AutoConnection);
/** /**
\class SyncThread qca_support.h QtCrypto \class SyncThread qca_support.h QtCrypto
@ -179,7 +189,7 @@ public:
Counter() : timer(this) Counter() : timer(this)
{ {
x = 0; x = 0;
connect(&timer, SIGNAL(timeout()), SLOT(t_timeout())); connect(&timer, &QTimer::timeout, this, &Counter::t_timeout);
} }
public slots: public slots:
@ -194,7 +204,7 @@ public slots:
return x; return x;
} }
private slots: private Q_SLOTS:
void t_timeout() void t_timeout()
{ {
++x; ++x;
@ -260,9 +270,6 @@ int x = thread->call(thread->counter, "value").toInt();
delete thread; delete thread;
\endcode \endcode
Do you see a mutex anywhere? I didn't think so.<br>
---
Even without the call() function, SyncThread is still very useful Even without the call() function, SyncThread is still very useful
for preparing objects in another thread, which you can then for preparing objects in another thread, which you can then
QObject::connect() to and use signals and slots like normal. QObject::connect() to and use signals and slots like normal.
@ -278,14 +285,14 @@ public:
\param parent the parent object for this parent. \param parent the parent object for this parent.
*/ */
SyncThread(QObject *parent = 0); SyncThread(QObject *parent = nullptr);
/** /**
Calls stop() and then destructs Calls stop() and then destructs
\note Subclasses should call stop() in their own destructor \note Subclasses should call stop() in their own destructor
*/ */
~SyncThread(); ~SyncThread() override;
/** /**
Starts the thread, begins the event loop the thread, and then Starts the thread, begins the event loop the thread, and then
@ -319,7 +326,8 @@ public:
\param ok if not 0, true is stored here if the call succeeds, \param ok if not 0, true is stored here if the call succeeds,
otherwise false is stored here. otherwise false is stored here.
*/ */
QVariant call(QObject *obj, const QByteArray &method, const QVariantList &args = QVariantList(), bool *ok = 0); QVariant
call(QObject *obj, const QByteArray &method, const QVariantList &args = QVariantList(), bool *ok = nullptr);
protected: protected:
/** /**
@ -335,7 +343,7 @@ protected:
/** /**
Starts the event loop and calls atStart and atStop as necessary Starts the event loop and calls atStart and atStop as necessary
*/ */
virtual void run(); void run() override;
private: private:
Q_DISABLE_COPY(SyncThread) Q_DISABLE_COPY(SyncThread)
@ -360,7 +368,7 @@ public:
\param parent the parent object to this object \param parent the parent object to this object
*/ */
Synchronizer(QObject *parent); Synchronizer(QObject *parent);
~Synchronizer(); ~Synchronizer() override;
/** /**
Call to pause execution in this thread. This function Call to pause execution in this thread. This function
@ -409,8 +417,8 @@ public:
set in the constructor, you can set it using setDirName() set in the constructor, you can set it using setDirName()
\param parent the parent object for this object \param parent the parent object for this object
*/ */
explicit DirWatch(const QString &dir = QString(), QObject *parent = 0); explicit DirWatch(const QString &dir = QString(), QObject *parent = nullptr);
~DirWatch(); ~DirWatch() override;
/** /**
The name of the directory that is being monitored The name of the directory that is being monitored
@ -427,7 +435,7 @@ public:
Q_SIGNALS: Q_SIGNALS:
/** /**
The changed signal is emitted when the directory is The changed signal is emitted when the directory is
changed (e.g. modified by addition or deletion of a changed (e.g.\ modified by addition or deletion of a
file within the directory, or the deletion of the file within the directory, or the deletion of the
directory) directory)
*/ */
@ -467,8 +475,8 @@ public:
in this object, you can set it using setFileName() in this object, you can set it using setFileName()
\param parent the parent object for this object \param parent the parent object for this object
*/ */
explicit FileWatch(const QString &file = QString(), QObject *parent = 0); explicit FileWatch(const QString &file = QString(), QObject *parent = nullptr);
~FileWatch(); ~FileWatch() override;
/** /**
The name of the file that is being monitored The name of the file that is being monitored
@ -596,8 +604,8 @@ public:
you to test whether there is already a Console object of the you to test whether there is already a Console object of the
required Type, and if there is, obtain a reference to that object. required Type, and if there is, obtain a reference to that object.
*/ */
Console(Type type, ChannelMode cmode, TerminalMode tmode, QObject *parent = 0); Console(Type type, ChannelMode cmode, TerminalMode tmode, QObject *parent = nullptr);
~Console(); ~Console() override;
/** /**
The Type of this Console object The Type of this Console object
@ -699,8 +707,8 @@ public:
\param parent the parent object for this object \param parent the parent object for this object
*/ */
ConsoleReference(QObject *parent = 0); ConsoleReference(QObject *parent = nullptr);
~ConsoleReference(); ~ConsoleReference() override;
/** /**
Set the Console object to be managed, and start processing. Set the Console object to be managed, and start processing.
@ -861,8 +869,8 @@ public:
\param parent the parent object for this object \param parent the parent object for this object
*/ */
ConsolePrompt(QObject *parent = 0); ConsolePrompt(QObject *parent = nullptr);
~ConsolePrompt(); ~ConsolePrompt() override;
/** /**
Allow the user to enter data without it being echo'd to Allow the user to enter data without it being echo'd to
@ -979,7 +987,10 @@ public:
\return Current level \return Current level
*/ */
inline Severity level() const { return m_logLevel; } inline Severity level() const
{
return m_logLevel;
}
/** /**
Set the current logging level Set the current logging level
@ -1039,7 +1050,7 @@ private:
*/ */
Logger(); Logger();
~Logger(); ~Logger() override;
QStringList m_loggerNames; QStringList m_loggerNames;
QList<AbstractLogDevice *> m_loggers; QList<AbstractLogDevice *> m_loggers;
@ -1093,9 +1104,9 @@ protected:
\param name the name of this log device \param name the name of this log device
\param parent the parent for this logger \param parent the parent for this logger
*/ */
explicit AbstractLogDevice(const QString &name, QObject *parent = 0); explicit AbstractLogDevice(const QString &name, QObject *parent = nullptr);
virtual ~AbstractLogDevice() = 0; ~AbstractLogDevice() override = 0;
private: private:
Q_DISABLE_COPY(AbstractLogDevice) Q_DISABLE_COPY(AbstractLogDevice)

View File

@ -179,7 +179,7 @@ public:
This is useful to reuse an existing Hex object This is useful to reuse an existing Hex object
*/ */
virtual void clear(); void clear() override;
/** /**
Process more data, returning the corresponding Process more data, returning the corresponding
@ -195,7 +195,7 @@ public:
\param a the array containing data to process \param a the array containing data to process
*/ */
virtual MemoryRegion update(const MemoryRegion &a); MemoryRegion update(const MemoryRegion &a) override;
/** /**
Complete the algorithm Complete the algorithm
@ -205,14 +205,14 @@ public:
zero length array - any output will have been returned zero length array - any output will have been returned
from the update() call. from the update() call.
*/ */
virtual MemoryRegion final(); MemoryRegion final() override;
/** /**
Test if an update() or final() call succeeded. Test if an update() or final() call succeeded.
\return true if the previous call succeeded \return true if the previous call succeeded
*/ */
virtual bool ok() const; bool ok() const override;
private: private:
Q_DISABLE_COPY(Hex) Q_DISABLE_COPY(Hex)
@ -274,7 +274,7 @@ public:
Reset the internal state. This is useful to Reset the internal state. This is useful to
reuse an existing Base64 object reuse an existing Base64 object
*/ */
virtual void clear(); void clear() override;
/** /**
Process more data, returning the corresponding Process more data, returning the corresponding
@ -290,7 +290,7 @@ public:
\param a the array containing data to process \param a the array containing data to process
*/ */
virtual MemoryRegion update(const MemoryRegion &a); MemoryRegion update(const MemoryRegion &a) override;
/** /**
Complete the algorithm Complete the algorithm
@ -300,14 +300,14 @@ public:
empty array, or an array containing one or two empty array, or an array containing one or two
"=" (equals, 0x3D) characters. "=" (equals, 0x3D) characters.
*/ */
virtual MemoryRegion final(); MemoryRegion final() override;
/** /**
Test if an update() or final() call succeeded. Test if an update() or final() call succeeded.
\return true if the previous call succeeded \return true if the previous call succeeded
*/ */
virtual bool ok() const; bool ok() const override;
private: private:
Q_DISABLE_COPY(Base64) Q_DISABLE_COPY(Base64)

View File

@ -36,10 +36,10 @@
#ifndef QCA_TOOLS_H #ifndef QCA_TOOLS_H
#define QCA_TOOLS_H #define QCA_TOOLS_H
#include "qca_export.h"
#include <QMetaType>
#include <QSharedData> #include <QSharedData>
#include <QSharedDataPointer> #include <QSharedDataPointer>
#include <QMetaType>
#include "qca_export.h"
class QString; class QString;
class QByteArray; class QByteArray;
@ -835,8 +835,6 @@ private:
QSharedDataPointer<Private> d; QSharedDataPointer<Private> d;
}; };
/** /**
Stream operator Stream operator
@ -847,7 +845,6 @@ private:
*/ */
QCA_EXPORT QTextStream &operator<<(QTextStream &stream, const BigInteger &b); QCA_EXPORT QTextStream &operator<<(QTextStream &stream, const BigInteger &b);
} }
#endif #endif

View File

@ -33,11 +33,11 @@
#ifndef QCAPROVIDER_H #ifndef QCAPROVIDER_H
#define QCAPROVIDER_H #define QCAPROVIDER_H
#include "qca_core.h"
#include "qca_basic.h" #include "qca_basic.h"
#include "qca_publickey.h"
#include "qca_cert.h" #include "qca_cert.h"
#include "qca_core.h"
#include "qca_keystore.h" #include "qca_keystore.h"
#include "qca_publickey.h"
#include "qca_securelayer.h" #include "qca_securelayer.h"
#include "qca_securemessage.h" #include "qca_securemessage.h"
@ -85,7 +85,9 @@ public:
/** /**
Destructs the object Destructs the object
*/ */
virtual ~QCAPlugin() {} virtual ~QCAPlugin()
{
}
/** /**
Returns a newly allocated Provider instance. Returns a newly allocated Provider instance.
@ -116,7 +118,10 @@ public:
\param p the provider associated with this context \param p the provider associated with this context
*/ */
InfoContext(Provider *p) : BasicContext(p, QStringLiteral("info") ) {} InfoContext(Provider *p)
: BasicContext(p, QStringLiteral("info"))
{
}
/** /**
The hash algorithms supported by the provider The hash algorithms supported by the provider
@ -153,7 +158,10 @@ public:
\param p the provider associated with this context \param p the provider associated with this context
*/ */
RandomContext(Provider *p) : BasicContext(p, QStringLiteral("random")) {} RandomContext(Provider *p)
: BasicContext(p, QStringLiteral("random"))
{
}
/** /**
Return an array of random bytes Return an array of random bytes
@ -183,7 +191,10 @@ public:
\param p the provider associated with this context \param p the provider associated with this context
\param type the name of the type of hash provided by this context \param type the name of the type of hash provided by this context
*/ */
HashContext(Provider *p, const QString &type) : BasicContext(p, type) {} HashContext(Provider *p, const QString &type)
: BasicContext(p, type)
{
}
/** /**
Reset the object to its initial state Reset the object to its initial state
@ -226,7 +237,10 @@ public:
\note type includes the name of the cipher (e.g. "aes256"), the operating \note type includes the name of the cipher (e.g. "aes256"), the operating
mode (e.g. "cbc" or "ofb") and the padding type (e.g. "pkcs7") if any. mode (e.g. "cbc" or "ofb") and the padding type (e.g. "pkcs7") if any.
*/ */
CipherContext(Provider *p, const QString &type) : BasicContext(p, type) {} CipherContext(Provider *p, const QString &type)
: BasicContext(p, type)
{
}
/** /**
Set up the object for encrypt/decrypt Set up the object for encrypt/decrypt
@ -234,8 +248,9 @@ public:
\param dir the direction for the cipher (encryption/decryption) \param dir the direction for the cipher (encryption/decryption)
\param key the symmetric key to use for the cipher \param key the symmetric key to use for the cipher
\param iv the initialization vector to use for the cipher (not used in ECB mode) \param iv the initialization vector to use for the cipher (not used in ECB mode)
\param tag the AuthTag to use (only for GCM and CCM modes)
*/ */
virtual void setup(Direction dir, const SymmetricKey &key, const InitializationVector &iv) = 0; virtual void setup(Direction dir, const SymmetricKey &key, const InitializationVector &iv, const AuthTag &tag) = 0;
/** /**
Returns the KeyLength for this cipher Returns the KeyLength for this cipher
@ -247,6 +262,11 @@ public:
*/ */
virtual int blockSize() const = 0; virtual int blockSize() const = 0;
/**
Returns the authentication tag for this cipher
*/
virtual AuthTag tag() const = 0;
/** /**
Process a chunk of data. Returns true if successful. Process a chunk of data. Returns true if successful.
@ -283,7 +303,10 @@ public:
\param p the provider associated with this context \param p the provider associated with this context
\param type the name of the type of MAC algorithm provided by this context \param type the name of the type of MAC algorithm provided by this context
*/ */
MACContext(Provider *p, const QString &type) : BasicContext(p, type) {} MACContext(Provider *p, const QString &type)
: BasicContext(p, type)
{
}
/** /**
Set up the object for hashing Set up the object for hashing
@ -345,7 +368,10 @@ public:
\param p the provider associated with this context \param p the provider associated with this context
\param type the name of the KDF provided by this context (including algorithm) \param type the name of the KDF provided by this context (including algorithm)
*/ */
KDFContext(Provider *p, const QString &type) : BasicContext(p, type) {} KDFContext(Provider *p, const QString &type)
: BasicContext(p, type)
{
}
/** /**
Create a key and return it Create a key and return it
@ -353,9 +379,12 @@ public:
\param secret the secret part (typically password) \param secret the secret part (typically password)
\param salt the salt / initialization vector \param salt the salt / initialization vector
\param keyLength the length of the key to be produced \param keyLength the length of the key to be produced
\param iterationCount the number of iterations of the derivation algorith, \param iterationCount the number of iterations of the derivation algorithm
*/ */
virtual SymmetricKey makeKey(const SecureArray &secret, const InitializationVector &salt, unsigned int keyLength, unsigned int iterationCount) = 0; virtual SymmetricKey makeKey(const SecureArray & secret,
const InitializationVector &salt,
unsigned int keyLength,
unsigned int iterationCount) = 0;
/** /**
Create a key and return it Create a key and return it
@ -364,7 +393,7 @@ public:
\param salt the salt / initialization vector \param salt the salt / initialization vector
\param keyLength the length of the key to be produced \param keyLength the length of the key to be produced
\param msecInterval the maximum time to compute the key, in milliseconds \param msecInterval the maximum time to compute the key, in milliseconds
\param iterationCount a pointer to store the number of iterations of the derivation algorithm, \param iterationCount a pointer to store the number of iterations of the derivation algorithm
*/ */
virtual SymmetricKey makeKey(const SecureArray & secret, virtual SymmetricKey makeKey(const SecureArray & secret,
const InitializationVector &salt, const InitializationVector &salt,
@ -373,6 +402,45 @@ public:
unsigned int * iterationCount) = 0; unsigned int * iterationCount) = 0;
}; };
/**
\class HKDFContext qcaprovider.h QtCrypto
HKDF provider
\note This class is part of the provider plugin interface and should not
be used directly by applications. You probably want HKDF instead.
\ingroup ProviderAPI
*/
class QCA_EXPORT HKDFContext : public BasicContext
{
Q_OBJECT
public:
/**
Standard constructor
\param p the provider associated with this context
\param type the name of the HKDF provided by this context (including algorithm)
*/
HKDFContext(Provider *p, const QString &type)
: BasicContext(p, type)
{
}
/**
Create a key and return it
\param secret the secret part (typically password)
\param salt the salt / initialization vector
\param info the info / initialization vector
\param keyLength the length of the key to be produced
*/
virtual SymmetricKey makeKey(const SecureArray & secret,
const InitializationVector &salt,
const InitializationVector &info,
unsigned int keyLength) = 0;
};
/** /**
\class DLGroupContext qcaprovider.h QtCrypto \class DLGroupContext qcaprovider.h QtCrypto
@ -392,7 +460,10 @@ public:
\param p the provider associated with this context \param p the provider associated with this context
*/ */
DLGroupContext(Provider *p) : Provider::Context(p, QStringLiteral("dlgroup")) {} DLGroupContext(Provider *p)
: Provider::Context(p, QStringLiteral("dlgroup"))
{
}
/** /**
The DLGroupSets supported by this object The DLGroupSets supported by this object
@ -601,7 +672,10 @@ public:
\param p the provider associated with this context \param p the provider associated with this context
*/ */
RSAContext(Provider *p) : PKeyBase(p, QStringLiteral("rsa")) {} RSAContext(Provider *p)
: PKeyBase(p, QStringLiteral("rsa"))
{
}
/** /**
Generate an RSA private key Generate an RSA private key
@ -628,7 +702,11 @@ public:
\param q the Q parameter \param q the Q parameter
\param d the D parameter \param d the D parameter
*/ */
virtual void createPrivate(const BigInteger &n, const BigInteger &e, const BigInteger &p, const BigInteger &q, const BigInteger &d) = 0; virtual void createPrivate(const BigInteger &n,
const BigInteger &e,
const BigInteger &p,
const BigInteger &q,
const BigInteger &d) = 0;
/** /**
Create an RSA public key based on the two public components Create an RSA public key based on the two public components
@ -684,7 +762,10 @@ public:
\param p the provider associated with this context \param p the provider associated with this context
*/ */
DSAContext(Provider *p) : PKeyBase(p, QStringLiteral("dsa")) {} DSAContext(Provider *p)
: PKeyBase(p, QStringLiteral("dsa"))
{
}
/** /**
Generate a DSA private key Generate a DSA private key
@ -754,7 +835,10 @@ public:
\param p the provider associated with this context \param p the provider associated with this context
*/ */
DHContext(Provider *p) : PKeyBase(p, QStringLiteral("dh")) {} DHContext(Provider *p)
: PKeyBase(p, QStringLiteral("dh"))
{
}
/** /**
Generate a Diffie-Hellman private key Generate a Diffie-Hellman private key
@ -830,7 +914,10 @@ public:
\param p the provider associated with this context \param p the provider associated with this context
*/ */
PKeyContext(Provider *p) : BasicContext(p, QStringLiteral("pkey")) {} PKeyContext(Provider *p)
: BasicContext(p, QStringLiteral("pkey"))
{
}
/** /**
Returns a list of supported public key types Returns a list of supported public key types
@ -981,7 +1068,10 @@ public:
\param p the provider associated with this context \param p the provider associated with this context
\param type the type of certificate-like object provided by this context \param type the type of certificate-like object provided by this context
*/ */
CertBase(Provider *p, const QString &type) : BasicContext(p, type) {} CertBase(Provider *p, const QString &type)
: BasicContext(p, type)
{
}
/** /**
Convert this object to DER format, and return the value Convert this object to DER format, and return the value
@ -1240,7 +1330,10 @@ public:
\param p the provider associated with this context \param p the provider associated with this context
*/ */
CertContext(Provider *p) : CertBase(p, QStringLiteral("cert")) {} CertContext(Provider *p)
: CertBase(p, QStringLiteral("cert"))
{
}
/** /**
Create a self-signed certificate based on the given options and Create a self-signed certificate based on the given options and
@ -1293,7 +1386,11 @@ public:
\param u the desired usage for this certificate \param u the desired usage for this certificate
\param vf validation options \param vf validation options
*/ */
virtual Validity validate(const QList<CertContext*> &trusted, const QList<CertContext*> &untrusted, const QList<CRLContext*> &crls, UsageMode u, ValidateFlags vf) const = 0; virtual Validity validate(const QList<CertContext *> &trusted,
const QList<CertContext *> &untrusted,
const QList<CRLContext *> & crls,
UsageMode u,
ValidateFlags vf) const = 0;
/** /**
Validate a certificate chain. This function makes no use of the Validate a certificate chain. This function makes no use of the
@ -1310,7 +1407,11 @@ public:
\param u the desired usage for the user certificate in the chain \param u the desired usage for the user certificate in the chain
\param vf validation options \param vf validation options
*/ */
virtual Validity validate_chain(const QList<CertContext*> &chain, const QList<CertContext*> &trusted, const QList<CRLContext*> &crls, UsageMode u, ValidateFlags vf) const = 0; virtual Validity validate_chain(const QList<CertContext *> &chain,
const QList<CertContext *> &trusted,
const QList<CRLContext *> & crls,
UsageMode u,
ValidateFlags vf) const = 0;
}; };
/** /**
@ -1333,7 +1434,10 @@ public:
\param p the provider associated with this context \param p the provider associated with this context
*/ */
CSRContext(Provider *p) : CertBase(p, QStringLiteral("csr")) {} CSRContext(Provider *p)
: CertBase(p, QStringLiteral("csr"))
{
}
/** /**
Returns true if the provider of this object supports the specified Returns true if the provider of this object supports the specified
@ -1414,7 +1518,10 @@ public:
\param p the provider associated with this context \param p the provider associated with this context
*/ */
CRLContext(Provider *p) : CertBase(p, QStringLiteral("crl")) {} CRLContext(Provider *p)
: CertBase(p, QStringLiteral("crl"))
{
}
/** /**
Returns a pointer to the properties of this CRL Returns a pointer to the properties of this CRL
@ -1449,7 +1556,10 @@ public:
\param p the provider associated with this context \param p the provider associated with this context
*/ */
CertCollectionContext(Provider *p) : BasicContext(p, QStringLiteral("certcollection")) {} CertCollectionContext(Provider *p)
: BasicContext(p, QStringLiteral("certcollection"))
{
}
/** /**
Create PKCS#7 DER output based on the input certificates and CRLs Create PKCS#7 DER output based on the input certificates and CRLs
@ -1474,7 +1584,8 @@ public:
\param certs the destination list for the certificates \param certs the destination list for the certificates
\param crls the destination list for the CRLs \param crls the destination list for the CRLs
*/ */
virtual ConvertResult fromPKCS7(const QByteArray &a, QList<CertContext*> *certs, QList<CRLContext*> *crls) const = 0; virtual ConvertResult
fromPKCS7(const QByteArray &a, QList<CertContext *> *certs, QList<CRLContext *> *crls) const = 0;
}; };
/** /**
@ -1497,7 +1608,10 @@ public:
\param p the Provider associated with this context \param p the Provider associated with this context
*/ */
CAContext(Provider *p) : BasicContext(p, QStringLiteral("ca")) {} CAContext(Provider *p)
: BasicContext(p, QStringLiteral("ca"))
{
}
/** /**
Prepare the object for usage Prepare the object for usage
@ -1552,7 +1666,8 @@ public:
\param entries the list of revoked entries \param entries the list of revoked entries
\param nextUpdate the expiration date of the new CRL \param nextUpdate the expiration date of the new CRL
*/ */
virtual CRLContext *updateCRL(const CRLContext &crl, const QList<CRLEntry> &entries, const QDateTime &nextUpdate) const = 0; virtual CRLContext *
updateCRL(const CRLContext &crl, const QList<CRLEntry> &entries, const QDateTime &nextUpdate) const = 0;
}; };
/** /**
@ -1574,7 +1689,10 @@ public:
\param p the Provider associated with this context \param p the Provider associated with this context
*/ */
PKCS12Context(Provider *p) : BasicContext(p, QStringLiteral("pkcs12")) {} PKCS12Context(Provider *p)
: BasicContext(p, QStringLiteral("pkcs12"))
{
}
/** /**
Create PKCS#12 DER output based on a set of input items Create PKCS#12 DER output based on a set of input items
@ -1586,7 +1704,10 @@ public:
\param priv the private key to store \param priv the private key to store
\param passphrase the passphrase to encrypt the PKCS#12 data with \param passphrase the passphrase to encrypt the PKCS#12 data with
*/ */
virtual QByteArray toPKCS12(const QString &name, const QList<const CertContext*> &chain, const PKeyContext &priv, const SecureArray &passphrase) const = 0; virtual QByteArray toPKCS12(const QString & name,
const QList<const CertContext *> &chain,
const PKeyContext & priv,
const SecureArray & passphrase) const = 0;
/** /**
Read PKCS#12 DER input and convert it into a set of output items Read PKCS#12 DER input and convert it into a set of output items
@ -1602,7 +1723,11 @@ public:
\param chain the destination list for the certificate chain \param chain the destination list for the certificate chain
\param priv address of a pointer to accept the private key \param priv address of a pointer to accept the private key
*/ */
virtual ConvertResult fromPKCS12(const QByteArray &in, const SecureArray &passphrase, QString *name, QList<CertContext*> *chain, PKeyContext **priv) const = 0; virtual ConvertResult fromPKCS12(const QByteArray & in,
const SecureArray & passphrase,
QString * name,
QList<CertContext *> *chain,
PKeyContext ** priv) const = 0;
}; };
/** /**
@ -1685,7 +1810,10 @@ public:
\param p the Provider associated with this context \param p the Provider associated with this context
*/ */
PGPKeyContext(Provider *p) : BasicContext(p, QStringLiteral("pgpkey")) {} PGPKeyContext(Provider *p)
: BasicContext(p, QStringLiteral("pgpkey"))
{
}
/** /**
Returns a pointer to the properties of this key Returns a pointer to the properties of this key
@ -1743,7 +1871,10 @@ public:
\param p the Provider associated with this context \param p the Provider associated with this context
*/ */
KeyStoreEntryContext(Provider *p) : BasicContext(p, QStringLiteral("keystoreentry")) {} KeyStoreEntryContext(Provider *p)
: BasicContext(p, QStringLiteral("keystoreentry"))
{
}
/** /**
Returns the entry type Returns the entry type
@ -1848,7 +1979,10 @@ public:
\param p the Provider associated with this context \param p the Provider associated with this context
*/ */
KeyStoreListContext(Provider *p) : Provider::Context(p, QStringLiteral("keystorelist")) {} KeyStoreListContext(Provider *p)
: Provider::Context(p, QStringLiteral("keystorelist"))
{
}
/** /**
Starts the keystore provider Starts the keystore provider
@ -2086,7 +2220,10 @@ public:
\param p the Provider associated with this context \param p the Provider associated with this context
*/ */
TLSSessionContext(Provider *p) : BasicContext(p, QStringLiteral("tlssession")) {} TLSSessionContext(Provider *p)
: BasicContext(p, QStringLiteral("tlssession"))
{
}
}; };
/** /**
@ -2166,7 +2303,10 @@ public:
\param p the Provider associated with this context \param p the Provider associated with this context
\param type the name of the type of feature that supported by this context \param type the name of the type of feature that supported by this context
*/ */
TLSContext(Provider *p, const QString &type) : Provider::Context(p, type) {} TLSContext(Provider *p, const QString &type)
: Provider::Context(p, type)
{
}
/** /**
Reset the object to its initial state Reset the object to its initial state
@ -2502,7 +2642,10 @@ public:
\param p the Provider associated with this context \param p the Provider associated with this context
*/ */
SASLContext(Provider *p) : Provider::Context(p, QStringLiteral("sasl")) {} SASLContext(Provider *p)
: Provider::Context(p, QStringLiteral("sasl"))
{
}
/** /**
Reset the object to its initial state Reset the object to its initial state
@ -2530,7 +2673,12 @@ public:
\param ext_ssf the SSF of the external authentication channel \param ext_ssf the SSF of the external authentication channel
(client only) (client only)
*/ */
virtual void setup(const QString &service, const QString &host, const HostPort *local, const HostPort *remote, const QString &ext_id, int ext_ssf) = 0; virtual void setup(const QString & service,
const QString & host,
const HostPort *local,
const HostPort *remote,
const QString & ext_id,
int ext_ssf) = 0;
/** /**
Set the constraints of the session using SSF values Set the constraints of the session using SSF values
@ -2717,7 +2865,8 @@ public:
\param pass the password \param pass the password
\param realm the realm to authenticate in \param realm the realm to authenticate in
*/ */
virtual void setClientParams(const QString *user, const QString *authzid, const SecureArray *pass, const QString *realm) = 0; virtual void
setClientParams(const QString *user, const QString *authzid, const SecureArray *pass, const QString *realm) = 0;
/** /**
Returns the realm list (client mode only) Returns the realm list (client mode only)
@ -2782,7 +2931,10 @@ public:
\param p the Provider associated with this context \param p the Provider associated with this context
\param type the name of the type of secure message to be created \param type the name of the type of secure message to be created
*/ */
MessageContext(Provider *p, const QString &type) : Provider::Context(p, type) {} MessageContext(Provider *p, const QString &type)
: Provider::Context(p, type)
{
}
/** /**
Returns true if the provider supports multiple signers for Returns true if the provider supports multiple signers for
@ -2815,7 +2967,8 @@ public:
\param bundleSigner whether to bundle the signing keys (true) or not (false) \param bundleSigner whether to bundle the signing keys (true) or not (false)
\param smime whether to use smime format (true) or not (false) \param smime whether to use smime format (true) or not (false)
*/ */
virtual void setupSign(const SecureMessageKeyList &keys, SecureMessage::SignMode m, bool bundleSigner, bool smime) = 0; virtual void
setupSign(const SecureMessageKeyList &keys, SecureMessage::SignMode m, bool bundleSigner, bool smime) = 0;
/** /**
Configure a new verify operation Configure a new verify operation
@ -2955,7 +3108,10 @@ public:
\param p the provider associated with this context \param p the provider associated with this context
\param type the name of the type of secure message system \param type the name of the type of secure message system
*/ */
SMSContext(Provider *p, const QString &type) : BasicContext(p, type) {} SMSContext(Provider *p, const QString &type)
: BasicContext(p, type)
{
}
/** /**
Set the trusted certificates and for this secure message system, Set the trusted certificates and for this secure message system,

View File

@ -61,7 +61,6 @@ typedef int Q_PIPE_ID;
namespace QCA { namespace QCA {
/** /**
\class QPipeDevice qpipe.h QtCrypto \class QPipeDevice qpipe.h QtCrypto
@ -90,8 +89,8 @@ public:
\param parent the parent object to this object \param parent the parent object to this object
*/ */
QPipeDevice(QObject *parent = 0); QPipeDevice(QObject *parent = nullptr);
~QPipeDevice(); ~QPipeDevice() override;
/** /**
The Type of the pipe device (that is, read or write) The Type of the pipe device (that is, read or write)
@ -219,7 +218,6 @@ class QCA_EXPORT QPipeEnd : public QObject
{ {
Q_OBJECT Q_OBJECT
public: public:
/** /**
The type of error The type of error
*/ */
@ -234,9 +232,9 @@ public:
\param parent the parent object for this object \param parent the parent object for this object
*/ */
QPipeEnd(QObject *parent = 0); QPipeEnd(QObject *parent = nullptr);
~QPipeEnd(); ~QPipeEnd() override;
/** /**
Reset the pipe end to an inactive state Reset the pipe end to an inactive state
@ -487,7 +485,7 @@ public:
\param parent the parent object for this object \param parent the parent object for this object
*/ */
QPipe(QObject *parent = 0); QPipe(QObject *parent = nullptr);
~QPipe(); ~QPipe();
@ -516,12 +514,18 @@ public:
/** /**
The read end of the pipe. The read end of the pipe.
*/ */
QPipeEnd & readEnd() { return i; } QPipeEnd &readEnd()
{
return i;
}
/** /**
The write end of the pipe. The write end of the pipe.
*/ */
QPipeEnd & writeEnd() { return o; } QPipeEnd &writeEnd()
{
return o;
}
private: private:
Q_DISABLE_COPY(QPipe) Q_DISABLE_COPY(QPipe)

40
metainfo.yaml Normal file
View File

@ -0,0 +1,40 @@
maintainer: sitter
fancyname: QCA
description: QCA (Qt Cryptographic Architecture) provides a straightforward and cross-platform crypto API
platforms:
- name: Linux
- name: FreeBSD
- name: Windows
# - name: MacOSX
# - name: Android
release: true
public_lib: true
public_source_dirs:
- include/QtCrypto
- examples
public_doc_dir:
- docs
public_example_dirs:
- examples/aes-cmac
- examples/base64test
- examples/certtest
- examples/ciphertest
- examples/cms
- examples/cmssigner
- examples/eventhandlerdemo
- examples/hashtest
- examples/hextest
- examples/keyloader
- examples/mactest
- examples/md5crypt
- examples/providertest
- examples/publickeyexample
- examples/randomtest
- examples/rsatest
- examples/saslclient
- examples/saslserver
- examples/ssltest
- examples/sslservtest
- examples/tlssocket
irc: kde-devel
mailinglist: kde-core-devel

View File

@ -22,36 +22,36 @@ if(NOT_PLUGIN_LIST)
set(WITH_${PLUGIN}_PLUGIN "yes") set(WITH_${PLUGIN}_PLUGIN "yes")
elseif("${BUILD_PLUGINS}" STREQUAL "auto") elseif("${BUILD_PLUGINS}" STREQUAL "auto")
set(WITH_${PLUGIN}_PLUGIN "auto") set(WITH_${PLUGIN}_PLUGIN "auto")
else("${BUILD_PLUGINS}" STREQUAL "all") else()
set(WITH_${PLUGIN}_PLUGIN "no") set(WITH_${PLUGIN}_PLUGIN "no")
endif("${BUILD_PLUGINS}" STREQUAL "all") endif()
elseif(NOT WITH_${PLUGIN}_PLUGIN) elseif(NOT WITH_${PLUGIN}_PLUGIN)
set(WITH_${PLUGIN}_PLUGIN "no") set(WITH_${PLUGIN}_PLUGIN "no")
elseif("${WITH_${PLUGIN}_PLUGIN}" STREQUAL "auto") elseif("${WITH_${PLUGIN}_PLUGIN}" STREQUAL "auto")
set(WITH_${PLUGIN}_PLUGIN "auto") set(WITH_${PLUGIN}_PLUGIN "auto")
else("${WITH_${PLUGIN}_PLUGIN}" STREQUAL "") else()
set(WITH_${PLUGIN}_PLUGIN "yes") set(WITH_${PLUGIN}_PLUGIN "yes")
endif("${WITH_${PLUGIN}_PLUGIN}" STREQUAL "") endif()
# Build plugin if yes or auto # Build plugin if yes or auto
if(WITH_${PLUGIN}_PLUGIN) if(WITH_${PLUGIN}_PLUGIN)
add_subdirectory("qca-${PLUGIN}") add_subdirectory("qca-${PLUGIN}")
else(WITH_${PLUGIN}_PLUGIN) else()
disable_plugin(${PLUGIN}) disable_plugin(${PLUGIN})
endif(WITH_${PLUGIN}_PLUGIN) endif()
endforeach(PLUGIN IN LISTS PLUGINS) endforeach(PLUGIN IN LISTS PLUGINS)
else(NOT_PLUGIN_LIST) else()
# BUILD_PLUGINS has list plugins to builds # BUILD_PLUGINS has list plugins to builds
foreach(PLUGIN IN LISTS PLUGINS) foreach(PLUGIN IN LISTS PLUGINS)
list(FIND BUILD_PLUGINS "${PLUGIN}" PLUGIN_INDEX) list(FIND BUILD_PLUGINS "${PLUGIN}" PLUGIN_INDEX)
if(PLUGIN_INDEX GREATER -1) if(PLUGIN_INDEX GREATER -1)
set(WITH_${PLUGIN}_PLUGIN "yes") set(WITH_${PLUGIN}_PLUGIN "yes")
add_subdirectory("qca-${PLUGIN}") add_subdirectory("qca-${PLUGIN}")
else(PLUGIN_INDEX GREATER -1) else()
disable_plugin(${PLUGIN}) disable_plugin(${PLUGIN})
endif(PLUGIN_INDEX GREATER -1) endif()
endforeach(PLUGIN IN LISTS PLUGINS) endforeach(PLUGIN IN LISTS PLUGINS)
endif(NOT_PLUGIN_LIST) endif()
message("") message("")
message("Plugins:") message("Plugins:")

View File

@ -1,22 +1,25 @@
find_package(PkgConfig REQUIRED)
if(WITH_botan_PLUGIN STREQUAL "yes") if(WITH_botan_PLUGIN STREQUAL "yes")
find_package(Botan REQUIRED) pkg_check_modules(BOTAN REQUIRED IMPORTED_TARGET botan-2)
else(WITH_botan_PLUGIN STREQUAL "yes") else()
find_package(Botan) pkg_check_modules(BOTAN IMPORTED_TARGET botan-2)
endif(WITH_botan_PLUGIN STREQUAL "yes") endif()
if(BOTAN_FOUND) if(BOTAN_FOUND)
enable_plugin("botan") enable_plugin("botan")
set(QCA_BOTAN_SOURCES qca-botan.cpp) set(QCA_BOTAN_SOURCES qca-botan.cpp)
add_definitions(${BOTAN_CFLAGS})
my_automoc(QCA_BOTAN_SOURCES)
add_library(qca-botan ${PLUGIN_TYPE} ${QCA_BOTAN_SOURCES}) add_library(qca-botan ${PLUGIN_TYPE} ${QCA_BOTAN_SOURCES})
if(APPLE AND ${PLUGIN_TYPE} STREQUAL "MODULE") if(APPLE AND ${PLUGIN_TYPE} STREQUAL "MODULE")
set_property(TARGET qca-botan PROPERTY SUFFIX ".dylib") set_property(TARGET qca-botan PROPERTY SUFFIX ".dylib")
endif() endif()
target_link_libraries(qca-botan ${QT_QTCORE_LIBRARY} ${QCA_LIB_NAME} ${BOTAN_LIBRARIES}) if(QT6)
target_link_libraries(qca-botan Qt6::Core ${QCA_LIB_NAME} PkgConfig::BOTAN)
else()
target_link_libraries(qca-botan Qt5::Core ${QCA_LIB_NAME} PkgConfig::BOTAN)
endif()
if(NOT DEVELOPER_MODE) if(NOT DEVELOPER_MODE)
install(TARGETS qca-botan install(TARGETS qca-botan
@ -27,6 +30,6 @@ if(BOTAN_FOUND)
install_pdb(qca-botan ${QCA_CRYPTO_INSTALL_DIR}) install_pdb(qca-botan ${QCA_CRYPTO_INSTALL_DIR})
endif() endif()
else(BOTAN_FOUND) else()
disable_plugin("botan") disable_plugin("botan")
endif(BOTAN_FOUND) endif()

View File

@ -17,89 +17,111 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
* *
*/ */
#include <QElapsedTimer>
#include <QtCrypto> #include <QtCrypto>
#include <QTime>
#include <QtPlugin> #include <QtPlugin>
#include <qstringlist.h> #include <qstringlist.h>
#include <botan/botan.h> #include <botan/auto_rng.h>
#include <botan/block_cipher.h>
#include <botan/filters.h>
#include <botan/hash.h>
#include <botan/hkdf.h>
#include <botan/hmac.h> #include <botan/hmac.h>
#if BOTAN_VERSION_CODE < BOTAN_VERSION_CODE_FOR(1,9,0) #include <botan/pbkdf.h>
#include <botan/s2k.h> #include <botan/stream_cipher.h>
#endif #include <botan/version.h>
#if BOTAN_VERSION_CODE >= BOTAN_VERSION_CODE_FOR(1,8,0)
#include <botan/algo_factory.h>
#endif
#include <stdlib.h> #include <cstdlib>
#include <iostream> #include <iostream>
//----------------------------------------------------------- //-----------------------------------------------------------
class botanRandomContext : public QCA::RandomContext class botanRandomContext : public QCA::RandomContext
{ {
Q_OBJECT
public: public:
botanRandomContext(QCA::Provider *p) : RandomContext(p) botanRandomContext(QCA::Provider *p)
: RandomContext(p)
{ {
} }
Context *clone() const Context *clone() const override
{ {
return new botanRandomContext(*this); return new botanRandomContext(*this);
} }
QCA::SecureArray nextBytes(int size) QCA::SecureArray nextBytes(int size) override
{ {
QCA::SecureArray buf(size); QCA::SecureArray buf(size);
#if BOTAN_VERSION_CODE < BOTAN_VERSION_CODE_FOR(1,5,0)
Botan::Global_RNG::randomize( (Botan::byte*)buf.data(), buf.size(), Botan::SessionKey );
#elif BOTAN_VERSION_CODE < BOTAN_VERSION_CODE_FOR(1,7,6)
Botan::Global_RNG::randomize( (Botan::byte*)buf.data(), buf.size() );
#else
Botan::AutoSeeded_RNG rng; Botan::AutoSeeded_RNG rng;
rng.randomize(reinterpret_cast<Botan::byte *>(buf.data()), buf.size()); rng.randomize(reinterpret_cast<Botan::byte *>(buf.data()), buf.size());
#endif
return buf; return buf;
} }
}; };
static QString qcaHashToBotanHash(const QString &type)
{
if (type == QLatin1String("md2"))
return QStringLiteral("MD2");
else if (type == QLatin1String("md4"))
return QStringLiteral("MD4");
else if (type == QLatin1String("md5"))
return QStringLiteral("MD5");
else if (type == QLatin1String("sha1"))
return QStringLiteral("SHA-1");
else if (type == QLatin1String("sha256"))
return QStringLiteral("SHA-256");
else if (type == QLatin1String("sha384"))
return QStringLiteral("SHA-384");
else if (type == QLatin1String("sha512"))
return QStringLiteral("SHA-512");
else if (type == QLatin1String("ripemd160"))
return QStringLiteral("RIPEMD-160");
return {};
}
//----------------------------------------------------------- //-----------------------------------------------------------
class BotanHashContext : public QCA::HashContext class BotanHashContext : public QCA::HashContext
{ {
Q_OBJECT
public: public:
BotanHashContext( const QString &hashName, QCA::Provider *p, const QString &type) : QCA::HashContext(p, type) BotanHashContext(QCA::Provider *p, const QString &type)
: QCA::HashContext(p, type)
{ {
m_hashObj = Botan::get_hash(hashName.toStdString()); const QString hashName = qcaHashToBotanHash(type);
m_hashObj = Botan::HashFunction::create(hashName.toStdString()).release();
} }
~BotanHashContext() ~BotanHashContext() override
{ {
delete m_hashObj; delete m_hashObj;
} }
Context *clone() const bool isOk() const
{ {
return new BotanHashContext(*this); return m_hashObj;
} }
void clear() Context *clone() const override
{
return new BotanHashContext(provider(), type());
}
void clear() override
{ {
m_hashObj->clear(); m_hashObj->clear();
} }
void update(const QCA::MemoryRegion &a) void update(const QCA::MemoryRegion &a) override
{ {
m_hashObj->update((const Botan::byte *)a.data(), a.size()); m_hashObj->update((const Botan::byte *)a.data(), a.size());
} }
QCA::MemoryRegion final() QCA::MemoryRegion final() override
{ {
#if BOTAN_VERSION_CODE < BOTAN_VERSION_CODE_FOR(1,9,0)
QCA::SecureArray a( m_hashObj->OUTPUT_LENGTH );
#else
QCA::SecureArray a(m_hashObj->output_length()); QCA::SecureArray a(m_hashObj->output_length());
#endif
m_hashObj->final((Botan::byte *)a.data()); m_hashObj->final((Botan::byte *)a.data());
return a; return a;
} }
@ -108,28 +130,45 @@ private:
Botan::HashFunction *m_hashObj; Botan::HashFunction *m_hashObj;
}; };
static QString qcaHmacToBotanHmac(const QString &type)
{
if (type == QLatin1String("hmac(md5)"))
return QStringLiteral("MD5");
else if (type == QLatin1String("hmac(sha1)"))
return QStringLiteral("SHA-1");
else if (type == QLatin1String("hmac(sha256)"))
return QStringLiteral("SHA-256");
else if (type == QLatin1String("hmac(sha384)"))
return QStringLiteral("SHA-384");
else if (type == QLatin1String("hmac(sha512)"))
return QStringLiteral("SHA-512");
else if (type == QLatin1String("hmac(ripemd160)"))
return QStringLiteral("RIPEMD-160");
return {};
}
//----------------------------------------------------------- //-----------------------------------------------------------
class BotanHMACContext : public QCA::MACContext class BotanHMACContext : public QCA::MACContext
{ {
Q_OBJECT
public: public:
BotanHMACContext( const QString &hashName, QCA::Provider *p, const QString &type) : QCA::MACContext(p, type) BotanHMACContext(QCA::Provider *p, const QString &type)
: QCA::MACContext(p, type)
{ {
#if BOTAN_VERSION_CODE < BOTAN_VERSION_CODE_FOR(1,8,0) const QString hashName = qcaHmacToBotanHmac(type);
m_hashObj = new Botan::HMAC(hashName.toStdString()); m_hashObj = new Botan::HMAC(Botan::HashFunction::create_or_throw(hashName.toStdString()).release());
#else if (nullptr == m_hashObj) {
m_hashObj = new Botan::HMAC(Botan::global_state().algorithm_factory().make_hash_function(hashName.toStdString()));
#endif
if (0 == m_hashObj) {
std::cout << "null context object" << std::endl; std::cout << "null context object" << std::endl;
} }
} }
~BotanHMACContext() ~BotanHMACContext() override
{ {
delete m_hashObj;
} }
void setup(const QCA::SymmetricKey &key) void setup(const QCA::SymmetricKey &key) override
{ {
// this often gets called with an empty key, because that is the default // this often gets called with an empty key, because that is the default
// in the QCA MessageAuthenticationCode constructor. Botan doesn't like // in the QCA MessageAuthenticationCode constructor. Botan doesn't like
@ -139,9 +178,9 @@ public:
} }
} }
Context *clone() const Context *clone() const override
{ {
return new BotanHMACContext(*this); return new BotanHMACContext(provider(), type());
} }
void clear() void clear()
@ -149,23 +188,19 @@ public:
m_hashObj->clear(); m_hashObj->clear();
} }
QCA::KeyLength keyLength() const QCA::KeyLength keyLength() const override
{ {
return anyKeyLength(); return anyKeyLength();
} }
void update(const QCA::MemoryRegion &a) void update(const QCA::MemoryRegion &a) override
{ {
m_hashObj->update((const Botan::byte *)a.data(), a.size()); m_hashObj->update((const Botan::byte *)a.data(), a.size());
} }
void final( QCA::MemoryRegion *out) void final(QCA::MemoryRegion *out) override
{ {
#if BOTAN_VERSION_CODE < BOTAN_VERSION_CODE_FOR(1,9,0)
QCA::SecureArray sa( m_hashObj->OUTPUT_LENGTH, 0 );
#else
QCA::SecureArray sa(m_hashObj->output_length(), 0); QCA::SecureArray sa(m_hashObj->output_length(), 0);
#endif
m_hashObj->final((Botan::byte *)sa.data()); m_hashObj->final((Botan::byte *)sa.data());
*out = sa; *out = sa;
} }
@ -174,39 +209,61 @@ protected:
Botan::HMAC *m_hashObj; Botan::HMAC *m_hashObj;
}; };
static QString qcaPbkdfToBotanPbkdf(const QString &pbkdf)
{
if (pbkdf == QLatin1String("pbkdf1(sha1)"))
return QStringLiteral("PBKDF1(SHA-1)");
else if (pbkdf == QLatin1String("pbkdf1(md2)"))
return QStringLiteral("PBKDF1(MD2)");
else if (pbkdf == QLatin1String("pbkdf2(sha1)"))
return QStringLiteral("PBKDF2(SHA-1)");
return {};
}
//----------------------------------------------------------- //-----------------------------------------------------------
class BotanPBKDFContext : public QCA::KDFContext class BotanPBKDFContext : public QCA::KDFContext
{ {
Q_OBJECT
public: public:
BotanPBKDFContext( const QString &kdfName, QCA::Provider *p, const QString &type) : QCA::KDFContext(p, type) BotanPBKDFContext(QCA::Provider *p, const QString &type)
: QCA::KDFContext(p, type)
{ {
try {
const QString kdfName = qcaPbkdfToBotanPbkdf(type);
m_s2k = Botan::get_s2k(kdfName.toStdString()); m_s2k = Botan::get_s2k(kdfName.toStdString());
} catch (Botan::Exception &e) {
m_s2k = nullptr;
}
} }
~BotanPBKDFContext() ~BotanPBKDFContext() override
{ {
delete m_s2k; delete m_s2k;
} }
Context *clone() const bool isOk() const
{ {
return new BotanPBKDFContext( *this ); return m_s2k;
} }
QCA::SymmetricKey makeKey(const QCA::SecureArray &secret, const QCA::InitializationVector &salt, Context *clone() const override
unsigned int keyLength, unsigned int iterationCount)
{ {
#if BOTAN_VERSION_CODE < BOTAN_VERSION_CODE_FOR(1,9,0) return new BotanPBKDFContext(provider(), type());
m_s2k->set_iterations(iterationCount); }
m_s2k->change_salt((const Botan::byte*)salt.data(), salt.size());
std::string secretString(secret.data(), secret.size() ); QCA::SymmetricKey makeKey(const QCA::SecureArray & secret,
Botan::OctetString key = m_s2k->derive_key(keyLength, secretString); const QCA::InitializationVector &salt,
#else unsigned int keyLength,
std::string secretString(secret.data(), secret.size() ); unsigned int iterationCount) override
Botan::OctetString key = m_s2k->derive_key(keyLength, secretString, (const Botan::byte*)salt.data(), salt.size(), iterationCount); {
#endif if (!m_s2k)
QCA::SecureArray retval(QByteArray((const char*)key.begin(), key.length())); return {};
const std::string secretString(secret.data(), secret.size());
const Botan::OctetString key =
m_s2k->derive_key(keyLength, secretString, (const Botan::byte *)salt.data(), salt.size(), iterationCount);
const QCA::SecureArray retval(QByteArray((const char *)key.begin(), key.length()));
return QCA::SymmetricKey(retval); return QCA::SymmetricKey(retval);
} }
@ -214,33 +271,19 @@ public:
const QCA::InitializationVector &salt, const QCA::InitializationVector &salt,
unsigned int keyLength, unsigned int keyLength,
int msecInterval, int msecInterval,
unsigned int *iterationCount) unsigned int * iterationCount) override
{ {
Q_ASSERT(iterationCount != NULL); Q_ASSERT(iterationCount != nullptr);
Botan::OctetString key; Botan::OctetString key;
QTime timer; QElapsedTimer timer;
std::string secretString(secret.data(), secret.size() ); const std::string secretString(secret.data(), secret.size());
*iterationCount = 0; *iterationCount = 0;
#if BOTAN_VERSION_CODE < BOTAN_VERSION_CODE_FOR(1,9,0)
m_s2k->set_iterations(1);
m_s2k->change_salt((const Botan::byte*)salt.data(), salt.size());
timer.start(); timer.start();
while (timer.elapsed() < msecInterval) { while (timer.elapsed() < msecInterval) {
key = m_s2k->derive_key(keyLength, secretString); key = m_s2k->derive_key(keyLength, secretString, (const Botan::byte *)salt.data(), salt.size(), 1);
++(*iterationCount); ++(*iterationCount);
} }
#else
timer.start();
while (timer.elapsed() < msecInterval) {
key = m_s2k->derive_key(keyLength,
secretString,
(const Botan::byte*)salt.data(),
salt.size(),
1);
++(*iterationCount);
}
#endif
return makeKey(secret, salt, keyLength, *iterationCount); return makeKey(secret, salt, keyLength, *iterationCount);
} }
@ -248,108 +291,272 @@ protected:
Botan::S2K *m_s2k; Botan::S2K *m_s2k;
}; };
static QString qcaHkdfToBotanHkdf(const QString &type)
{
if (type == QLatin1String("hkdf(sha256)"))
return QStringLiteral("SHA-256");
return {};
}
//-----------------------------------------------------------
class BotanHKDFContext : public QCA::HKDFContext
{
Q_OBJECT
public:
BotanHKDFContext(QCA::Provider *p, const QString &type)
: QCA::HKDFContext(p, type)
{
const QString hashName = qcaHkdfToBotanHkdf(type);
Botan::HMAC * hashObj;
hashObj = new Botan::HMAC(Botan::HashFunction::create_or_throw(hashName.toStdString()).release());
m_hkdf = new Botan::HKDF(hashObj);
}
~BotanHKDFContext() override
{
delete m_hkdf;
}
Context *clone() const override
{
return new BotanHKDFContext(provider(), type());
}
QCA::SymmetricKey makeKey(const QCA::SecureArray & secret,
const QCA::InitializationVector &salt,
const QCA::InitializationVector &info,
unsigned int keyLength) override
{
Botan::secure_vector<uint8_t> key(keyLength);
m_hkdf->kdf(key.data(),
keyLength,
reinterpret_cast<const Botan::byte *>(secret.data()),
secret.size(),
reinterpret_cast<const Botan::byte *>(salt.data()),
salt.size(),
reinterpret_cast<const Botan::byte *>(info.data()),
info.size());
QCA::SecureArray retval(QByteArray::fromRawData(reinterpret_cast<const char *>(key.data()), key.size()));
return QCA::SymmetricKey(retval);
}
protected:
Botan::HKDF *m_hkdf;
};
static void
qcaCipherToBotanCipher(const QString &type, std::string *algoName, std::string *algoMode, std::string *algoPadding)
{
if (type == QLatin1String("aes128-ecb")) {
*algoName = "AES-128";
*algoMode = "ECB";
*algoPadding = "NoPadding";
} else if (type == QLatin1String("aes128-cbc")) {
*algoName = "AES-128";
*algoMode = "CBC";
*algoPadding = "NoPadding";
} else if (type == QLatin1String("aes128-cfb")) {
*algoName = "AES-128";
*algoMode = "CFB";
*algoPadding = "NoPadding";
} else if (type == QLatin1String("aes128-ofb")) {
*algoName = "AES-128";
*algoMode = "OFB";
*algoPadding = "NoPadding";
} else if (type == QLatin1String("aes192-ecb")) {
*algoName = "AES-192";
*algoMode = "ECB";
*algoPadding = "NoPadding";
} else if (type == QLatin1String("aes192-cbc")) {
*algoName = "AES-192";
*algoMode = "CBC";
*algoPadding = "NoPadding";
} else if (type == QLatin1String("aes192-cfb")) {
*algoName = "AES-192";
*algoMode = "CFB";
*algoPadding = "NoPadding";
} else if (type == QLatin1String("aes192-ofb")) {
*algoName = "AES-192";
*algoMode = "OFB";
*algoPadding = "NoPadding";
} else if (type == QLatin1String("aes256-ecb")) {
*algoName = "AES-256";
*algoMode = "ECB";
*algoPadding = "NoPadding";
} else if (type == QLatin1String("aes256-cbc")) {
*algoName = "AES-256";
*algoMode = "CBC";
*algoPadding = "NoPadding";
} else if (type == QLatin1String("aes256-cfb")) {
*algoName = "AES-256";
*algoMode = "CFB";
*algoPadding = "NoPadding";
} else if (type == QLatin1String("aes256-ofb")) {
*algoName = "AES-256";
*algoMode = "OFB";
*algoPadding = "NoPadding";
} else if (type == QLatin1String("blowfish-ecb")) {
*algoName = "Blowfish";
*algoMode = "ECB";
*algoPadding = "NoPadding";
} else if (type == QLatin1String("blowfish-cbc")) {
*algoName = "Blowfish";
*algoMode = "CBC";
*algoPadding = "NoPadding";
} else if (type == QLatin1String("blowfish-cbc-pkcs7")) {
*algoName = "Blowfish";
*algoMode = "CBC";
*algoPadding = "PKCS7";
} else if (type == QLatin1String("blowfish-cfb")) {
*algoName = "Blowfish";
*algoMode = "CFB";
*algoPadding = "NoPadding";
} else if (type == QLatin1String("blowfish-ofb")) {
*algoName = "Blowfish";
*algoMode = "OFB";
*algoPadding = "NoPadding";
} else if (type == QLatin1String("des-ecb")) {
*algoName = "DES";
*algoMode = "ECB";
*algoPadding = "NoPadding";
} else if (type == QLatin1String("des-ecb-pkcs7")) {
*algoName = "DES";
*algoMode = "ECB";
*algoPadding = "PKCS7";
} else if (type == QLatin1String("des-cbc")) {
*algoName = "DES";
*algoMode = "CBC";
*algoPadding = "NoPadding";
} else if (type == QLatin1String("des-cbc-pkcs7")) {
*algoName = "DES";
*algoMode = "CBC";
*algoPadding = "PKCS7";
} else if (type == QLatin1String("des-cfb")) {
*algoName = "DES";
*algoMode = "CFB";
*algoPadding = "NoPadding";
} else if (type == QLatin1String("des-ofb")) {
*algoName = "DES";
*algoMode = "OFB";
*algoPadding = "NoPadding";
} else if (type == QLatin1String("tripledes-ecb")) {
*algoName = "TripleDES";
*algoMode = "ECB";
*algoPadding = "NoPadding";
}
}
static std::string qcaCipherToBotanCipher(const QString &qcaCipher)
{
std::string algoName, algoMode, algoPadding;
qcaCipherToBotanCipher(qcaCipher, &algoName, &algoMode, &algoPadding);
return algoName + '/' + algoMode + '/' + algoPadding; // NOLINT(performance-inefficient-string-concatenation)
}
//----------------------------------------------------------- //-----------------------------------------------------------
class BotanCipherContext : public QCA::CipherContext class BotanCipherContext : public QCA::CipherContext
{ {
Q_OBJECT
public: public:
BotanCipherContext( const QString &algo, const QString &mode, const QString &padding, BotanCipherContext(QCA::Provider *p, const QString &type)
QCA::Provider *p, const QString &type) : QCA::CipherContext(p, type) : QCA::CipherContext(p, type)
{ {
m_algoName = algo.toStdString(); qcaCipherToBotanCipher(type, &m_algoName, &m_algoMode, &m_algoPadding);
m_algoMode = mode.toStdString();
m_algoPadding = padding.toStdString();
} }
void setup(QCA::Direction dir, void setup(QCA::Direction dir,
const QCA::SymmetricKey & key, const QCA::SymmetricKey & key,
const QCA::InitializationVector &iv) const QCA::InitializationVector &iv,
const QCA::AuthTag & tag) override
{ {
Q_UNUSED(tag);
try { try {
m_dir = dir; m_dir = dir;
Botan::SymmetricKey keyCopy((Botan::byte*)key.data(), key.size()); const Botan::SymmetricKey keyCopy((Botan::byte *)key.data(), key.size());
if (iv.size() == 0) { if (iv.size() == 0) {
if (QCA::Encode == dir) { if (QCA::Encode == dir) {
m_crypter = new Botan::Pipe(Botan::get_cipher(m_algoName+'/'+m_algoMode+'/'+m_algoPadding, m_crypter = new Botan::Pipe(Botan::get_cipher(
keyCopy, Botan::ENCRYPTION)); m_algoName + '/' + m_algoMode + '/' + m_algoPadding, keyCopy, Botan::ENCRYPTION));
} } else {
else { m_crypter = new Botan::Pipe(Botan::get_cipher(
m_crypter = new Botan::Pipe(Botan::get_cipher(m_algoName+'/'+m_algoMode+'/'+m_algoPadding, m_algoName + '/' + m_algoMode + '/' + m_algoPadding, keyCopy, Botan::DECRYPTION));
keyCopy, Botan::DECRYPTION));
} }
} else { } else {
Botan::InitializationVector ivCopy((Botan::byte*)iv.data(), iv.size()); const Botan::InitializationVector ivCopy((Botan::byte *)iv.data(), iv.size());
if (QCA::Encode == dir) { if (QCA::Encode == dir) {
m_crypter = new Botan::Pipe(Botan::get_cipher(m_algoName+'/'+m_algoMode+'/'+m_algoPadding, m_crypter = new Botan::Pipe(Botan::get_cipher(
keyCopy, ivCopy, Botan::ENCRYPTION)); m_algoName + '/' + m_algoMode + '/' + m_algoPadding, keyCopy, ivCopy, Botan::ENCRYPTION));
} } else {
else { m_crypter = new Botan::Pipe(Botan::get_cipher(
m_crypter = new Botan::Pipe(Botan::get_cipher(m_algoName+'/'+m_algoMode+'/'+m_algoPadding, m_algoName + '/' + m_algoMode + '/' + m_algoPadding, keyCopy, ivCopy, Botan::DECRYPTION));
keyCopy, ivCopy, Botan::DECRYPTION));
} }
} }
m_crypter->start_msg(); m_crypter->start_msg();
} catch (Botan::Exception &e) { } catch (Botan::Exception &e) {
m_crypter = nullptr;
std::cout << "caught: " << e.what() << std::endl; std::cout << "caught: " << e.what() << std::endl;
} }
} }
Context *clone() const Context *clone() const override
{ {
return new BotanCipherContext(*this); return new BotanCipherContext(*this);
} }
int blockSize() const int blockSize() const override
{ {
return Botan::block_size_of(m_algoName); if (const std::unique_ptr<Botan::BlockCipher> bc = Botan::BlockCipher::create(m_algoName))
return bc->block_size();
throw Botan::Algorithm_Not_Found(m_algoName);
} }
bool update(const QCA::SecureArray &in, QCA::SecureArray *out) QCA::AuthTag tag() const override
{ {
// For future implementation
return QCA::AuthTag();
}
bool update(const QCA::SecureArray &in, QCA::SecureArray *out) override
{
if (!m_crypter)
return false;
m_crypter->write((Botan::byte *)in.data(), in.size()); m_crypter->write((Botan::byte *)in.data(), in.size());
QCA::SecureArray result(m_crypter->remaining()); QCA::SecureArray result(m_crypter->remaining());
// Perhaps bytes_read is redundant and can be dropped // Perhaps bytes_read is redundant and can be dropped
size_t bytes_read = m_crypter->read((Botan::byte*)result.data(), result.size()); const size_t bytes_read = m_crypter->read((Botan::byte *)result.data(), result.size());
result.resize(bytes_read); result.resize(bytes_read);
*out = result; *out = result;
return true; return true;
} }
bool final(QCA::SecureArray *out) bool final(QCA::SecureArray *out) override
{ {
m_crypter->end_msg(); m_crypter->end_msg();
QCA::SecureArray result(m_crypter->remaining()); QCA::SecureArray result(m_crypter->remaining());
// Perhaps bytes_read is redundant and can be dropped // Perhaps bytes_read is redundant and can be dropped
size_t bytes_read = m_crypter->read((Botan::byte*)result.data(), result.size()); const size_t bytes_read = m_crypter->read((Botan::byte *)result.data(), result.size());
result.resize(bytes_read); result.resize(bytes_read);
*out = result; *out = result;
return true; return true;
} }
QCA::KeyLength keyLength() const QCA::KeyLength keyLength() const override
{ {
#if BOTAN_VERSION_CODE < BOTAN_VERSION_CODE_FOR(1,9,0)
return QCA::KeyLength( Botan::min_keylength_of(m_algoName),
Botan::max_keylength_of(m_algoName),
Botan::keylength_multiple_of(m_algoName) );
#else
Botan::Algorithm_Factory &af = Botan::global_state().algorithm_factory();
Botan::Key_Length_Specification kls(0); Botan::Key_Length_Specification kls(0);
if(const Botan::BlockCipher *bc = af.prototype_block_cipher(m_algoName)) if (const std::unique_ptr<Botan::BlockCipher> bc = Botan::BlockCipher::create(m_algoName))
kls = bc->key_spec(); kls = bc->key_spec();
else if(const Botan::StreamCipher *sc = af.prototype_stream_cipher(m_algoName)) else if (const std::unique_ptr<Botan::StreamCipher> sc = Botan::StreamCipher::create(m_algoName))
kls = sc->key_spec(); kls = sc->key_spec();
else if(const Botan::MessageAuthenticationCode *mac = af.prototype_mac(m_algoName)) else if (const std::unique_ptr<Botan::MessageAuthenticationCode> mac =
Botan::MessageAuthenticationCode::create(m_algoName))
kls = mac->key_spec(); kls = mac->key_spec();
return QCA::KeyLength( kls.minimum_keylength(), return QCA::KeyLength(kls.minimum_keylength(), kls.maximum_keylength(), kls.keylength_multiple());
kls.maximum_keylength(),
kls.keylength_multiple() );
#endif
} }
~BotanCipherContext() override
~BotanCipherContext()
{ {
delete m_crypter; delete m_crypter;
} }
@ -363,190 +570,180 @@ protected:
Botan::Pipe * m_crypter; Botan::Pipe * m_crypter;
}; };
//========================================================== //==========================================================
class botanProvider : public QCA::Provider class botanProvider : public QCA::Provider
{ {
public: public:
void init() void init() override
{ {
m_init = new Botan::LibraryInitializer;
} }
~botanProvider() ~botanProvider() override
{ {
// We should be cleaning up there, but // We should be cleaning up there, but
// this causes the unit tests to segfault // this causes the unit tests to segfault
// delete m_init; // delete m_init;
} }
int qcaVersion() const int qcaVersion() const override
{ {
return QCA_VERSION; return QCA_VERSION;
} }
QString name() const QString name() const override
{ {
return "qca-botan"; return QStringLiteral("qca-botan");
} }
QStringList features() const const QStringList &pbkdfTypes() const
{ {
QStringList list; static QStringList list;
list += "random"; if (list.isEmpty()) {
list += "md2"; list += QStringLiteral("pbkdf1(sha1)");
list += "md4"; std::unique_ptr<BotanPBKDFContext> pbkdf1md2(new BotanPBKDFContext(nullptr, QStringLiteral("pbkdf1(md2)")));
list += "md5"; if (pbkdf1md2->isOk())
list += "sha1"; list += QStringLiteral("pbkdf1(md2)");
list += "sha256"; list += QStringLiteral("pbkdf2(sha1)");
list += "sha384"; }
list += "sha512";
list += "ripemd160";
list += "hmac(md5)";
list += "hmac(sha1)";
// HMAC with SHA2 doesn't appear to work correctly in Botan.
// list += "hmac(sha256)";
// list += "hmac(sha384)";
// list += "hmac(sha512)";
list += "hmac(ripemd160)";
list += "pbkdf1(sha1)";
list += "pbkdf1(md2)";
list += "pbkdf2(sha1)";
list += "aes128-ecb";
list += "aes128-cbc";
list += "aes128-cfb";
list += "aes128-ofb";
list += "aes192-ecb";
list += "aes192-cbc";
list += "aes192-cfb";
list += "aes192-ofb";
list += "aes256-ecb";
list += "aes256-cbc";
list += "aes256-cfb";
list += "aes256-ofb";
list += "des-ecb";
list += "des-ecb-pkcs7";
list += "des-cbc";
list += "des-cbc-pkcs7";
list += "des-cfb";
list += "des-ofb";
list += "tripledes-ecb";
list += "blowfish-ecb";
list += "blowfish-cbc";
list += "blowfish-cbc-pkcs7";
list += "blowfish-cfb";
list += "blowfish-ofb";
return list; return list;
} }
Context *createContext(const QString &type) const QStringList &hashTypes() const
{ {
if ( type == "random" ) static QStringList supported;
return new botanRandomContext( this ); if (supported.isEmpty()) {
else if ( type == "md2" ) QStringList list;
return new BotanHashContext( QString("MD2"), this, type ); list += QStringLiteral("md2");
else if ( type == "md4" ) list += QStringLiteral("md4");
return new BotanHashContext( QString("MD4"), this, type ); list += QStringLiteral("md5");
else if ( type == "md5" ) list += QStringLiteral("sha1");
return new BotanHashContext( QString("MD5"), this, type ); list += QStringLiteral("sha256");
else if ( type == "sha1" ) list += QStringLiteral("sha384");
return new BotanHashContext( QString("SHA-1"), this, type ); list += QStringLiteral("sha512");
else if ( type == "sha256" ) list += QStringLiteral("ripemd160");
return new BotanHashContext( QString("SHA-256"), this, type );
else if ( type == "sha384" )
return new BotanHashContext( QString("SHA-384"), this, type );
else if ( type == "sha512" )
return new BotanHashContext( QString("SHA-512"), this, type );
else if ( type == "ripemd160" )
return new BotanHashContext( QString("RIPEMD-160"), this, type );
else if ( type == "hmac(md5)" )
return new BotanHMACContext( QString("MD5"), this, type );
else if ( type == "hmac(sha1)" )
return new BotanHMACContext( QString("SHA-1"), this, type );
else if ( type == "hmac(sha256)" )
return new BotanHMACContext( QString("SHA-256"), this, type );
else if ( type == "hmac(sha384)" )
return new BotanHMACContext( QString("SHA-384"), this, type );
else if ( type == "hmac(sha512)" )
return new BotanHMACContext( QString("SHA-512"), this, type );
else if ( type == "hmac(ripemd160)" )
return new BotanHMACContext( QString("RIPEMD-160"), this, type );
else if ( type == "pbkdf1(sha1)" )
return new BotanPBKDFContext( QString("PBKDF1(SHA-1)"), this, type );
else if ( type == "pbkdf1(md2)" )
return new BotanPBKDFContext( QString("PBKDF1(MD2)"), this, type );
else if ( type == "pbkdf2(sha1)" )
return new BotanPBKDFContext( QString("PBKDF2(SHA-1)"), this, type );
else if ( type == "aes128-ecb" )
return new BotanCipherContext( QString("AES-128"), QString("ECB"), QString("NoPadding"), this, type );
else if ( type == "aes128-cbc" )
return new BotanCipherContext( QString("AES-128"), QString("CBC"), QString("NoPadding"), this, type );
else if ( type == "aes128-cfb" )
return new BotanCipherContext( QString("AES-128"), QString("CFB"), QString("NoPadding"), this, type );
else if ( type == "aes128-ofb" )
return new BotanCipherContext( QString("AES-128"), QString("OFB"), QString("NoPadding"), this, type );
else if ( type == "aes192-ecb" )
return new BotanCipherContext( QString("AES-192"), QString("ECB"), QString("NoPadding"), this, type );
else if ( type == "aes192-cbc" )
return new BotanCipherContext( QString("AES-192"), QString("CBC"), QString("NoPadding"), this, type );
else if ( type == "aes192-cfb" )
return new BotanCipherContext( QString("AES-192"), QString("CFB"), QString("NoPadding"), this, type );
else if ( type == "aes192-ofb" )
return new BotanCipherContext( QString("AES-192"), QString("OFB"), QString("NoPadding"), this, type );
else if ( type == "aes256-ecb" )
return new BotanCipherContext( QString("AES-256"), QString("ECB"), QString("NoPadding"), this, type );
else if ( type == "aes256-cbc" )
return new BotanCipherContext( QString("AES-256"), QString("CBC"), QString("NoPadding"), this, type );
else if ( type == "aes256-cfb" )
return new BotanCipherContext( QString("AES-256"), QString("CFB"), QString("NoPadding"), this, type );
else if ( type == "aes256-ofb" )
return new BotanCipherContext( QString("AES-256"), QString("OFB"), QString("NoPadding"), this, type );
else if ( type == "blowfish-ecb" )
return new BotanCipherContext( QString("Blowfish"), QString("ECB"), QString("NoPadding"), this, type );
else if ( type == "blowfish-cbc" )
return new BotanCipherContext( QString("Blowfish"), QString("CBC"), QString("NoPadding"), this, type );
else if ( type == "blowfish-cbc-pkcs7" )
return new BotanCipherContext( QString("Blowfish"), QString("CBC"), QString("PKCS7"), this, type );
else if ( type == "blowfish-cfb" )
return new BotanCipherContext( QString("Blowfish"), QString("CFB"), QString("NoPadding"), this, type );
else if ( type == "blowfish-ofb" )
return new BotanCipherContext( QString("Blowfish"), QString("OFB"), QString("NoPadding"), this, type );
else if ( type == "des-ecb" )
return new BotanCipherContext( QString("DES"), QString("ECB"), QString("NoPadding"), this, type );
else if ( type == "des-ecb-pkcs7" )
return new BotanCipherContext( QString("DES"), QString("ECB"), QString("PKCS7"), this, type );
else if ( type == "des-cbc" )
return new BotanCipherContext( QString("DES"), QString("CBC"), QString("NoPadding"), this, type );
else if ( type == "des-cbc-pkcs7" )
return new BotanCipherContext( QString("DES"), QString("CBC"), QString("PKCS7"), this, type );
else if ( type == "des-cfb" )
return new BotanCipherContext( QString("DES"), QString("CFB"), QString("NoPadding"), this, type );
else if ( type == "des-ofb" )
return new BotanCipherContext( QString("DES"), QString("OFB"), QString("NoPadding"), this, type );
else if ( type == "tripledes-ecb" )
return new BotanCipherContext( QString("TripleDES"), QString("ECB"), QString("NoPadding"), this, type );
else
return 0;
}
private:
Botan::LibraryInitializer *m_init;
for (const QString &hash : qAsConst(list)) {
std::unique_ptr<BotanHashContext> hashContext(new BotanHashContext(nullptr, hash));
if (hashContext->isOk()) {
supported << hash;
}
}
}
return supported;
}
const QStringList &cipherTypes() const
{
static QStringList supported;
if (supported.isEmpty()) {
QStringList list;
list += QStringLiteral("aes128-ecb");
list += QStringLiteral("aes128-cbc");
list += QStringLiteral("aes128-cfb");
list += QStringLiteral("aes128-ofb");
list += QStringLiteral("aes192-ecb");
list += QStringLiteral("aes192-cbc");
list += QStringLiteral("aes192-cfb");
list += QStringLiteral("aes192-ofb");
list += QStringLiteral("aes256-ecb");
list += QStringLiteral("aes256-cbc");
list += QStringLiteral("aes256-cfb");
list += QStringLiteral("aes256-ofb");
list += QStringLiteral("des-ecb");
list += QStringLiteral("des-ecb-pkcs7");
list += QStringLiteral("des-cbc");
list += QStringLiteral("des-cbc-pkcs7");
list += QStringLiteral("des-cfb");
list += QStringLiteral("des-ofb");
list += QStringLiteral("tripledes-ecb");
list += QStringLiteral("blowfish-ecb");
list += QStringLiteral("blowfish-cbc");
list += QStringLiteral("blowfish-cbc-pkcs7");
list += QStringLiteral("blowfish-cfb");
list += QStringLiteral("blowfish-ofb");
for (const QString &cipher : qAsConst(list)) {
const std::string bothanCipher = qcaCipherToBotanCipher(cipher);
try {
std::unique_ptr<Botan::Keyed_Filter> enc(Botan::get_cipher(bothanCipher, Botan::ENCRYPTION));
std::unique_ptr<Botan::Keyed_Filter> dec(Botan::get_cipher(bothanCipher, Botan::DECRYPTION));
supported += cipher;
} catch (Botan::Exception &e) {
}
}
}
return supported;
}
const QStringList &hmacTypes() const
{
static QStringList list;
if (list.isEmpty()) {
list += QStringLiteral("hmac(md5)");
list += QStringLiteral("hmac(sha1)");
// HMAC with SHA2 doesn't appear to work correctly in Botan.
// list += QStringLiteral("hmac(sha256)");
// list += QStringLiteral("hmac(sha384)");
// list += QStringLiteral("hmac(sha512)");
list += QStringLiteral("hmac(ripemd160)");
}
return list;
}
QStringList hkdfTypes() const
{
static QStringList list;
if (list.isEmpty()) {
list += QStringLiteral("hkdf(sha256)");
}
return list;
}
QStringList features() const override
{
static QStringList list;
if (list.isEmpty()) {
list += QStringLiteral("random");
list += hmacTypes();
list += pbkdfTypes();
list += hkdfTypes();
list += cipherTypes();
list += hashTypes();
}
return list;
}
Context *createContext(const QString &type) override
{
if (type == QLatin1String("random"))
return new botanRandomContext(this);
else if (hashTypes().contains(type))
return new BotanHashContext(this, type);
else if (hmacTypes().contains(type))
return new BotanHMACContext(this, type);
else if (pbkdfTypes().contains(type))
return new BotanPBKDFContext(this, type);
else if (hkdfTypes().contains(type))
return new BotanHKDFContext(this, type);
else if (cipherTypes().contains(type))
return new BotanCipherContext(this, type);
else
return nullptr;
}
private:
}; };
class botanPlugin : public QObject, public QCAPlugin class botanPlugin : public QObject, public QCAPlugin
{ {
Q_OBJECT Q_OBJECT
#if QT_VERSION >= 0x050000
Q_PLUGIN_METADATA(IID "com.affinix.qca.Plugin/1.0") Q_PLUGIN_METADATA(IID "com.affinix.qca.Plugin/1.0")
#endif
Q_INTERFACES(QCAPlugin) Q_INTERFACES(QCAPlugin)
public: public:
virtual QCA::Provider *createProvider() { return new botanProvider; } QCA::Provider *createProvider() override
{
return new botanProvider;
}
}; };
#include "qca-botan.moc" #include "qca-botan.moc"
#if QT_VERSION < 0x050000
Q_EXPORT_PLUGIN2(qca_botan, botanPlugin);
#endif

View File

@ -1,22 +1,25 @@
if(WITH_cyrus-sasl_PLUGIN STREQUAL "yes") if(WITH_cyrus-sasl_PLUGIN STREQUAL "yes")
find_package(Sasl2 REQUIRED) find_package(Sasl2 REQUIRED)
else(WITH_cyrus-sasl_PLUGIN STREQUAL "yes") else()
find_package(Sasl2) find_package(Sasl2)
endif(WITH_cyrus-sasl_PLUGIN STREQUAL "yes") endif()
if(SASL2_FOUND) if(SASL2_FOUND)
enable_plugin("cyrus-sasl") enable_plugin("cyrus-sasl")
set(QCA_SASL_SOURCES qca-cyrus-sasl.cpp) set(QCA_SASL_SOURCES qca-cyrus-sasl.cpp)
include_directories( ${SASL2_INCLUDE_DIR} ) include_directories( ${SASL2_INCLUDE_DIR} )
my_automoc( QCA_SASL_SOURCES )
add_library(qca-cyrus-sasl ${PLUGIN_TYPE} ${QCA_SASL_SOURCES}) add_library(qca-cyrus-sasl ${PLUGIN_TYPE} ${QCA_SASL_SOURCES})
if(APPLE AND ${PLUGIN_TYPE} STREQUAL "MODULE") if(APPLE AND ${PLUGIN_TYPE} STREQUAL "MODULE")
set_property(TARGET qca-cyrus-sasl PROPERTY SUFFIX ".dylib") set_property(TARGET qca-cyrus-sasl PROPERTY SUFFIX ".dylib")
endif() endif()
target_link_libraries(qca-cyrus-sasl ${QT_QTCORE_LIBRARY} ${QCA_LIB_NAME} ${SASL2_LIBRARIES}) if(QT6)
target_link_libraries(qca-cyrus-sasl Qt6::Core ${QCA_LIB_NAME} ${SASL2_LIBRARIES})
else()
target_link_libraries(qca-cyrus-sasl Qt5::Core ${QCA_LIB_NAME} ${SASL2_LIBRARIES})
endif()
if(NOT DEVELOPER_MODE) if(NOT DEVELOPER_MODE)
install(TARGETS qca-cyrus-sasl install(TARGETS qca-cyrus-sasl
@ -26,6 +29,6 @@ if(SASL2_FOUND)
install_pdb(qca-cyrus-sasl ${QCA_CRYPTO_INSTALL_DIR}) install_pdb(qca-cyrus-sasl ${QCA_CRYPTO_INSTALL_DIR})
endif() endif()
else(SASL2_FOUND) else()
disable_plugin("cyrus-sasl") disable_plugin("cyrus-sasl")
endif(SASL2_FOUND) endif()

View File

@ -19,19 +19,18 @@
* *
*/ */
#include <QtCrypto>
#include <qcaprovider.h>
#include <QDebug> #include <QDebug>
#include <QtCrypto>
#include <QtPlugin> #include <QtPlugin>
#include <qcaprovider.h>
extern "C" extern "C" {
{
#include <sasl/sasl.h> #include <sasl/sasl.h>
} }
#include <QStringList>
#include <QList>
#include <QFile> #include <QFile>
#include <QList>
#include <QStringList>
#define SASL_BUFSIZE 8192 #define SASL_BUFSIZE 8192
#define SASL_APP "qca" #define SASL_APP "qca"
@ -44,13 +43,13 @@ class saslProvider : public Provider
{ {
public: public:
saslProvider(); saslProvider();
void init(); void init() override;
~saslProvider(); ~saslProvider() override;
int qcaVersion() const; int qcaVersion() const override;
QString name() const; QString name() const override;
QString credit() const; QString credit() const override;
QStringList features() const; QStringList features() const override;
Context *createContext(const QString &type); Context * createContext(const QString &type) override;
bool client_init; bool client_init;
bool server_init; bool server_init;
@ -154,7 +153,8 @@ public:
bool missingAny() const bool missingAny() const
{ {
if((need.user && !have.user) /*|| (need.authzid && !have.authzid)*/ || (need.pass && !have.pass) /*|| (need.realm && !have.realm)*/) if ((need.user && !have.user) /*|| (need.authzid && !have.authzid)*/ ||
(need.pass && !have.pass) /*|| (need.realm && !have.realm)*/)
return true; return true;
return false; return false;
} }
@ -177,8 +177,8 @@ public:
{ {
if (i->result) if (i->result)
return; return;
QByteArray cs = s.toUtf8(); const QByteArray cs = s.toUtf8();
int len = cs.length(); const int len = cs.length();
char * p = new char[len + 1]; char * p = new char[len + 1];
memcpy(p, cs.data(), len); memcpy(p, cs.data(), len);
p[len] = 0; p[len] = 0;
@ -204,7 +204,7 @@ static QByteArray makeByteArray(const void *in, unsigned int len)
static QString addrString(const SASLContext::HostPort &hp) static QString addrString(const SASLContext::HostPort &hp)
{ {
return (hp.addr + ';' + QString::number(hp.port)); return (hp.addr + QLatin1Char(';') + QString::number(hp.port));
} }
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
@ -213,6 +213,7 @@ static QString addrString(const SASLContext::HostPort &hp)
class saslContext : public SASLContext class saslContext : public SASLContext
{ {
Q_OBJECT
saslProvider *g; saslProvider *g;
// core props // core props
@ -262,19 +263,19 @@ private:
{ {
if (con) { if (con) {
sasl_dispose(&con); sasl_dispose(&con);
con = 0; con = nullptr;
} }
need = 0; need = nullptr;
if (callbacks) { if (callbacks) {
delete callbacks; delete callbacks;
callbacks = 0; callbacks = nullptr;
} }
localAddr = ""; localAddr = QLatin1String("");
remoteAddr = ""; remoteAddr = QLatin1String("");
maxoutbuf = 128; maxoutbuf = 128;
sc_username = ""; sc_username = QLatin1String("");
sc_authzid = ""; sc_authzid = QLatin1String("");
result_authCondition = SASL::AuthFail; result_authCondition = SASL::AuthFail;
result_haveClientInit = false; result_haveClientInit = false;
@ -291,7 +292,7 @@ private:
secflags = 0; secflags = 0;
ssf_min = 0; ssf_min = 0;
ssf_max = 0; ssf_max = 0;
ext_authid = ""; ext_authid = QLatin1String("");
ext_ssf = 0; ext_ssf = 0;
} }
@ -301,20 +302,21 @@ private:
secprops.min_ssf = ssf_min; secprops.min_ssf = ssf_min;
secprops.max_ssf = ssf_max; secprops.max_ssf = ssf_max;
secprops.maxbufsize = SASL_BUFSIZE; secprops.maxbufsize = SASL_BUFSIZE;
secprops.property_names = NULL; secprops.property_names = nullptr;
secprops.property_values = NULL; secprops.property_values = nullptr;
secprops.security_flags = secflags; secprops.security_flags = secflags;
int r = sasl_setprop(con, SASL_SEC_PROPS, &secprops); int r = sasl_setprop(con, SASL_SEC_PROPS, &secprops);
if (r != SASL_OK) if (r != SASL_OK)
return false; return false;
if (!ext_authid.isEmpty()) { if (!ext_authid.isEmpty()) {
const char *authid = ext_authid.toLatin1().data(); const QByteArray ext_authidBA = ext_authid.toLatin1();
const char * authid = ext_authidBA.data();
sasl_ssf_t ssf = ext_ssf; sasl_ssf_t ssf = ext_ssf;
r = sasl_setprop(con, SASL_SSF_EXTERNAL, &ssf); r = sasl_setprop(con, SASL_SSF_EXTERNAL, &ssf);
if (r != SASL_OK) if (r != SASL_OK)
return false; return false;
r = sasl_setprop(con, SASL_AUTH_EXTERNAL, &authid); r = sasl_setprop(con, SASL_AUTH_EXTERNAL, authid);
if (r != SASL_OK) if (r != SASL_OK)
return false; return false;
} }
@ -328,23 +330,47 @@ private:
SASL::AuthCondition x; SASL::AuthCondition x;
switch (r) { switch (r) {
// common // common
case SASL_NOMECH: x = SASL::NoMechanism; break; case SASL_NOMECH:
case SASL_BADPROT: x = SASL::BadProtocol; break; x = SASL::NoMechanism;
break;
case SASL_BADPROT:
x = SASL::BadProtocol;
break;
// client // client
case SASL_BADSERV: x = SASL::BadServer; break; case SASL_BADSERV:
x = SASL::BadServer;
break;
// server // server
case SASL_BADAUTH: x = SASL::BadAuth; break; case SASL_BADAUTH:
case SASL_NOAUTHZ: x = SASL::NoAuthzid; break; x = SASL::BadAuth;
case SASL_TOOWEAK: x = SASL::TooWeak; break; break;
case SASL_ENCRYPT: x = SASL::NeedEncrypt; break; case SASL_NOAUTHZ:
case SASL_EXPIRED: x = SASL::Expired; break; x = SASL::NoAuthzid;
case SASL_DISABLED: x = SASL::Disabled; break; break;
case SASL_NOUSER: x = SASL::NoUser; break; case SASL_TOOWEAK:
case SASL_UNAVAIL: x = SASL::RemoteUnavailable; break; x = SASL::TooWeak;
break;
case SASL_ENCRYPT:
x = SASL::NeedEncrypt;
break;
case SASL_EXPIRED:
x = SASL::Expired;
break;
case SASL_DISABLED:
x = SASL::Disabled;
break;
case SASL_NOUSER:
x = SASL::NoUser;
break;
case SASL_UNAVAIL:
x = SASL::RemoteUnavailable;
break;
default: x = SASL::AuthFail; break; default:
x = SASL::AuthFail;
break;
} }
result_authCondition = x; result_authCondition = x;
} }
@ -360,11 +386,19 @@ private:
maxoutbuf = *(const int *)maybe_maxoutbuf; maxoutbuf = *(const int *)maybe_maxoutbuf;
} }
static int scb_checkauth(sasl_conn_t *, void *context, const char *requested_user, unsigned, const char *auth_identity, unsigned, const char *, unsigned, struct propctx *) static int scb_checkauth(sasl_conn_t *,
void * context,
const char *requested_user,
unsigned,
const char *auth_identity,
unsigned,
const char *,
unsigned,
struct propctx *)
{ {
saslContext *that = (saslContext *)context; saslContext *that = (saslContext *)context;
that->sc_username = auth_identity; // yeah yeah, it looks that->sc_username = QString::fromLatin1(auth_identity); // yeah yeah, it looks
that->sc_authzid = requested_user; // backwards, but it is right that->sc_authzid = QString::fromLatin1(requested_user); // backwards, but it is right
that->ca_flag = true; that->ca_flag = true;
return SASL_OK; return SASL_OK;
} }
@ -377,22 +411,22 @@ private:
const char * clientout, *m; const char * clientout, *m;
unsigned int clientoutlen; unsigned int clientoutlen;
need = 0; need = nullptr;
QString list = result_mechlist.join(" "); const QString list = result_mechlist.join(QStringLiteral(" "));
int r; int r;
while(1) { while (true) {
if (need) if (need)
params.extractHave(need); params.extractHave(need);
if (in_sendFirst) if (in_sendFirst)
r = sasl_client_start(con, list.toLatin1().data(), &need, &clientout, &clientoutlen, &m); r = sasl_client_start(con, list.toLatin1().data(), &need, &clientout, &clientoutlen, &m);
else else
r = sasl_client_start(con, list.toLatin1().data(), &need, NULL, NULL, &m); r = sasl_client_start(con, list.toLatin1().data(), &need, nullptr, nullptr, &m);
if (r != SASL_INTERACT) if (r != SASL_INTERACT)
break; break;
params.applyInteract(need); params.applyInteract(need);
if (params.missingAny()) { if (params.missingAny()) {
out_mech = m; out_mech = QString::fromLatin1(m);
result_result = Params; result_result = Params;
return; return;
} }
@ -403,7 +437,7 @@ private:
return; return;
} }
out_mech = m; out_mech = QString::fromLatin1(m);
if (in_sendFirst && clientout) { if (in_sendFirst && clientout) {
out_buf = makeByteArray(clientout, clientoutlen); out_buf = makeByteArray(clientout, clientoutlen);
result_haveClientInit = true; result_haveClientInit = true;
@ -418,15 +452,15 @@ private:
} }
result_result = Continue; result_result = Continue;
return; return;
} } else {
else {
const char * clientout; const char * clientout;
unsigned int clientoutlen; unsigned int clientoutlen;
int r; int r;
while(1) { while (true) {
if (need) if (need)
params.extractHave(need); params.extractHave(need);
//printf("sasl_client_step(con, {%s}, %d, &need, &clientout, &clientoutlen);\n", in_buf.data(), in_buf.size()); // printf("sasl_client_step(con, {%s}, %d, &need, &clientout, &clientoutlen);\n", in_buf.data(),
// in_buf.size());
r = sasl_client_step(con, in_buf.data(), in_buf.size(), &need, &clientout, &clientoutlen); r = sasl_client_step(con, in_buf.data(), in_buf.size(), &need, &clientout, &clientoutlen);
// printf("returned: %d\n", r); // printf("returned: %d\n", r);
if (r != SASL_INTERACT) if (r != SASL_INTERACT)
@ -458,7 +492,7 @@ private:
{ {
if (step == 0) { if (step == 0) {
if (!ca_skip) { if (!ca_skip) {
const char *clientin = 0; const char * clientin = nullptr;
unsigned int clientinlen = 0; unsigned int clientinlen = 0;
if (in_useClientInit) { if (in_useClientInit) {
clientin = in_clientInit.data(); clientin = in_clientInit.data();
@ -467,7 +501,8 @@ private:
const char * serverout; const char * serverout;
unsigned int serveroutlen; unsigned int serveroutlen;
ca_flag = false; ca_flag = false;
int r = sasl_server_start(con, in_mech.toLatin1().data(), clientin, clientinlen, &serverout, &serveroutlen); const int r =
sasl_server_start(con, in_mech.toLatin1().data(), clientin, clientinlen, &serverout, &serveroutlen);
if (r != SASL_OK && r != SASL_CONTINUE) { if (r != SASL_OK && r != SASL_CONTINUE) {
setAuthCondition(r); setAuthCondition(r);
result_result = Error; result_result = Error;
@ -492,12 +527,11 @@ private:
} }
result_result = Continue; result_result = Continue;
return; return;
} } else {
else {
if (!ca_skip) { if (!ca_skip) {
const char * serverout; const char * serverout;
unsigned int serveroutlen; unsigned int serveroutlen;
int r = sasl_server_step(con, in_buf.data(), in_buf.size(), &serverout, &serveroutlen); const int r = sasl_server_step(con, in_buf.data(), in_buf.size(), &serverout, &serveroutlen);
if (r != SASL_OK && r != SASL_CONTINUE) { if (r != SASL_OK && r != SASL_CONTINUE) {
setAuthCondition(r); setAuthCondition(r);
result_result = Error; result_result = Error;
@ -536,7 +570,7 @@ private:
int at = 0; int at = 0;
out->resize(0); out->resize(0);
while(1) { while (true) {
int size = in.size() - at; int size = in.size() - at;
if (size == 0) if (size == 0)
break; break;
@ -551,7 +585,7 @@ private:
r = sasl_decode(con, in.data() + at, size, &outbuf, &len); r = sasl_decode(con, in.data() + at, size, &outbuf, &len);
if (r != SASL_OK) if (r != SASL_OK)
return false; return false;
int oldsize = out->size(); const int oldsize = out->size();
out->resize(oldsize + len); out->resize(oldsize + len);
memcpy(out->data() + oldsize, outbuf, len); memcpy(out->data() + oldsize, outbuf, len);
at += size; at += size;
@ -570,92 +604,102 @@ public:
{ {
result_result = Success; result_result = Success;
g = _g; g = _g;
con = 0; con = nullptr;
callbacks = 0; callbacks = nullptr;
reset(); reset();
} }
~saslContext() ~saslContext() override
{ {
reset(); reset();
} }
virtual Provider::Context *clone() const Provider::Context *clone() const override
{ {
return 0; return nullptr;
} }
virtual Result result() const Result result() const override
{ {
return result_result; return result_result;
} }
virtual void reset() void reset() override
{ {
resetState(); resetState();
resetParams(); resetParams();
} }
virtual void setup(const QString &_service, const QString &_host, const HostPort *local, const HostPort *remote, const QString &ext_id, int _ext_ssf) void setup(const QString & _service,
const QString & _host,
const HostPort *local,
const HostPort *remote,
const QString & ext_id,
int _ext_ssf) override
{ {
service = _service; service = _service;
host = _host; host = _host;
localAddr = local ? addrString(*local) : ""; localAddr = local ? addrString(*local) : QLatin1String("");
remoteAddr = remote ? addrString(*remote) : ""; remoteAddr = remote ? addrString(*remote) : QLatin1String("");
ext_authid = ext_id; ext_authid = ext_id;
ext_ssf = _ext_ssf; ext_ssf = _ext_ssf;
} }
virtual int ssf() const int ssf() const override
{ {
return result_ssf; return result_ssf;
} }
virtual void startClient(const QStringList &mechlist, bool allowClientSendFirst) void startClient(const QStringList &mechlist, bool allowClientSendFirst) override
{ {
resetState(); resetState();
in_sendFirst = allowClientSendFirst; in_sendFirst = allowClientSendFirst;
if (!g->client_init) { if (!g->client_init) {
sasl_client_init(NULL); sasl_client_init(nullptr);
g->client_init = true; g->client_init = true;
} }
callbacks = new sasl_callback_t[5]; callbacks = new sasl_callback_t[5];
callbacks[0].id = SASL_CB_GETREALM; callbacks[0].id = SASL_CB_GETREALM;
callbacks[0].proc = 0; callbacks[0].proc = nullptr;
callbacks[0].context = 0; callbacks[0].context = nullptr;
callbacks[1].id = SASL_CB_USER; callbacks[1].id = SASL_CB_USER;
callbacks[1].proc = 0; callbacks[1].proc = nullptr;
callbacks[1].context = 0; callbacks[1].context = nullptr;
callbacks[2].id = SASL_CB_AUTHNAME; callbacks[2].id = SASL_CB_AUTHNAME;
callbacks[2].proc = 0; callbacks[2].proc = nullptr;
callbacks[2].context = 0; callbacks[2].context = nullptr;
callbacks[3].id = SASL_CB_PASS; callbacks[3].id = SASL_CB_PASS;
callbacks[3].proc = 0; callbacks[3].proc = nullptr;
callbacks[3].context = 0; callbacks[3].context = nullptr;
callbacks[4].id = SASL_CB_LIST_END; callbacks[4].id = SASL_CB_LIST_END;
callbacks[4].proc = 0; callbacks[4].proc = nullptr;
callbacks[4].context = 0; callbacks[4].context = nullptr;
result_result = Error; result_result = Error;
int r = sasl_client_new(service.toLatin1().data(), host.toLatin1().data(), localAddr.isEmpty() ? 0 : localAddr.toLatin1().data(), remoteAddr.isEmpty() ? 0 : remoteAddr.toLatin1().data(), callbacks, 0, &con); const int r = sasl_client_new(service.toLatin1().data(),
host.toLatin1().data(),
localAddr.isEmpty() ? nullptr : localAddr.toLatin1().data(),
remoteAddr.isEmpty() ? nullptr : remoteAddr.toLatin1().data(),
callbacks,
0,
&con);
if (r != SASL_OK) { if (r != SASL_OK) {
setAuthCondition(r); setAuthCondition(r);
doResultsReady(); doResultsReady();
return; return;
} }
if(!setsecprops()) if (!setsecprops()) {
{
doResultsReady(); doResultsReady();
return; return;
} }
@ -670,14 +714,14 @@ public:
} }
// TODO: make use of disableServerSendLast // TODO: make use of disableServerSendLast
virtual void startServer(const QString &realm, bool disableServerSendLast) void startServer(const QString &realm, bool disableServerSendLast) override
{ {
Q_UNUSED(disableServerSendLast); Q_UNUSED(disableServerSendLast);
resetState(); resetState();
g->appname = SASL_APP; g->appname = QStringLiteral(SASL_APP);
if (!g->server_init) { if (!g->server_init) {
sasl_server_init(NULL, QFile::encodeName(g->appname)); sasl_server_init(nullptr, QFile::encodeName(g->appname).constData());
g->server_init = true; g->server_init = true;
} }
@ -688,29 +732,35 @@ public:
callbacks[0].context = this; callbacks[0].context = this;
callbacks[1].id = SASL_CB_LIST_END; callbacks[1].id = SASL_CB_LIST_END;
callbacks[1].proc = 0; callbacks[1].proc = nullptr;
callbacks[1].context = 0; callbacks[1].context = nullptr;
result_result = Error; result_result = Error;
int r = sasl_server_new(service.toLatin1().data(), host.toLatin1().data(), !realm.isEmpty() ? realm.toLatin1().data() : 0, localAddr.isEmpty() ? 0 : localAddr.toLatin1().data(), remoteAddr.isEmpty() ? 0 : remoteAddr.toLatin1().data(), callbacks, 0, &con); int r = sasl_server_new(service.toLatin1().data(),
host.toLatin1().data(),
!realm.isEmpty() ? realm.toLatin1().data() : nullptr,
localAddr.isEmpty() ? nullptr : localAddr.toLatin1().data(),
remoteAddr.isEmpty() ? nullptr : remoteAddr.toLatin1().data(),
callbacks,
0,
&con);
if (r != SASL_OK) { if (r != SASL_OK) {
setAuthCondition(r); setAuthCondition(r);
doResultsReady(); doResultsReady();
return; return;
} }
if(!setsecprops()) if (!setsecprops()) {
{
doResultsReady(); doResultsReady();
return; return;
} }
const char *ml; const char *ml;
r = sasl_listmech(con, 0, 0, " ", 0, &ml, 0, 0); r = sasl_listmech(con, nullptr, nullptr, " ", nullptr, &ml, nullptr, nullptr);
if (r != SASL_OK) if (r != SASL_OK)
return; return;
result_mechlist = QString::fromUtf8(ml).split(' '); result_mechlist = QString::fromUtf8(ml).split(QLatin1Char(' '));
servermode = true; servermode = true;
step = 0; step = 0;
@ -721,26 +771,26 @@ public:
return; return;
} }
virtual void serverFirstStep(const QString &mech, const QByteArray *clientInit) void serverFirstStep(const QString &mech, const QByteArray *clientInit) override
{ {
in_mech = mech; in_mech = mech;
if (clientInit) { if (clientInit) {
in_useClientInit = true; in_useClientInit = true;
in_clientInit = *clientInit; in_clientInit = *clientInit;
} } else
else
in_useClientInit = false; in_useClientInit = false;
serverTryAgain(); serverTryAgain();
doResultsReady(); doResultsReady();
} }
virtual SASL::Params clientParams() const SASL::Params clientParams() const override
{ {
SASLParams::SParams sparams = params.missing(); const SASLParams::SParams sparams = params.missing();
return SASL::Params(sparams.user, sparams.authzid, sparams.pass, sparams.realm); return SASL::Params(sparams.user, sparams.authzid, sparams.pass, sparams.realm);
} }
virtual void setClientParams(const QString *user, const QString *authzid, const SecureArray *pass, const QString *realm) void
setClientParams(const QString *user, const QString *authzid, const SecureArray *pass, const QString *realm) override
{ {
if (user) if (user)
params.setUsername(*user); params.setUsername(*user);
@ -752,23 +802,23 @@ public:
params.setRealm(*realm); params.setRealm(*realm);
} }
virtual QString username() const QString username() const override
{ {
return sc_username; return sc_username;
} }
virtual QString authzid() const QString authzid() const override
{ {
return sc_authzid; return sc_authzid;
} }
virtual void nextStep(const QByteArray &from_net) void nextStep(const QByteArray &from_net) override
{ {
in_buf = from_net; in_buf = from_net;
tryAgain(); tryAgain();
} }
virtual void tryAgain() void tryAgain() override
{ {
if (servermode) if (servermode)
serverTryAgain(); serverTryAgain();
@ -777,7 +827,7 @@ public:
doResultsReady(); doResultsReady();
} }
virtual QString mech() const QString mech() const override
{ {
if (servermode) if (servermode)
return in_mech; return in_mech;
@ -785,18 +835,18 @@ public:
return out_mech; return out_mech;
} }
virtual QStringList mechlist() const QStringList mechlist() const override
{ {
return result_mechlist; return result_mechlist;
} }
virtual QStringList realmlist() const QStringList realmlist() const override
{ {
// TODO // TODO
return QStringList(); return QStringList();
} }
virtual void setConstraints(SASL::AuthFlags f, int minSSF, int maxSSF) void setConstraints(SASL::AuthFlags f, int minSSF, int maxSSF) override
{ {
int sf = 0; int sf = 0;
if (!(f & SASL::AllowPlain)) if (!(f & SASL::AllowPlain))
@ -819,14 +869,14 @@ public:
ssf_max = maxSSF; ssf_max = maxSSF;
} }
virtual bool waitForResultsReady(int msecs) bool waitForResultsReady(int msecs) override
{ {
// TODO: for now, all operations block anyway // TODO: for now, all operations block anyway
Q_UNUSED(msecs); Q_UNUSED(msecs);
return true; return true;
} }
virtual void update(const QByteArray &from_net, const QByteArray &from_app) void update(const QByteArray &from_net, const QByteArray &from_app) override
{ {
bool ok = true; bool ok = true;
if (!from_app.isEmpty()) if (!from_app.isEmpty())
@ -836,41 +886,42 @@ public:
result_result = ok ? Success : Error; result_result = ok ? Success : Error;
result_encoded = from_app.size(); result_encoded = from_app.size();
//printf("update (from_net=%d, to_net=%d, from_app=%d, to_app=%d)\n", from_net.size(), result_to_net.size(), from_app.size(), result_plain.size()); // printf("update (from_net=%d, to_net=%d, from_app=%d, to_app=%d)\n", from_net.size(), result_to_net.size(),
// from_app.size(), result_plain.size());
doResultsReady(); doResultsReady();
} }
virtual bool haveClientInit() const bool haveClientInit() const override
{ {
return result_haveClientInit; return result_haveClientInit;
} }
virtual QByteArray stepData() const QByteArray stepData() const override
{ {
return out_buf; return out_buf;
} }
virtual QByteArray to_net() QByteArray to_net() override
{ {
QByteArray a = result_to_net; const QByteArray a = result_to_net;
result_to_net.clear(); result_to_net.clear();
return a; return a;
} }
virtual int encoded() const int encoded() const override
{ {
return result_encoded; return result_encoded;
} }
virtual QByteArray to_app() QByteArray to_app() override
{ {
QByteArray a = result_plain; const QByteArray a = result_plain;
result_plain.clear(); result_plain.clear();
return a; return a;
} }
virtual SASL::AuthCondition authCondition() const SASL::AuthCondition authCondition() const override
{ {
return result_authCondition; return result_authCondition;
} }
@ -902,7 +953,7 @@ int saslProvider::qcaVersion() const
QString saslProvider::name() const QString saslProvider::name() const
{ {
return "qca-cyrus-sasl"; return QStringLiteral("qca-cyrus-sasl");
} }
QString saslProvider::credit() const QString saslProvider::credit() const
@ -913,17 +964,17 @@ QString saslProvider::credit() const
QStringList saslProvider::features() const QStringList saslProvider::features() const
{ {
QStringList list; QStringList list;
list += "sasl"; list += QStringLiteral("sasl");
return list; return list;
} }
Provider::Context *saslProvider::createContext(const QString &type) Provider::Context *saslProvider::createContext(const QString &type)
{ {
if ( type == "sasl" ) if (type == QLatin1String("sasl"))
return new saslContext(this); return new saslContext(this);
return 0; return nullptr;
} }
} // namespace saslQCAPlugin } // namespace saslQCAPlugin
@ -937,16 +988,13 @@ using namespace saslQCAPlugin;
class saslPlugin : public QObject, public QCAPlugin class saslPlugin : public QObject, public QCAPlugin
{ {
Q_OBJECT Q_OBJECT
#if QT_VERSION >= 0x050000
Q_PLUGIN_METADATA(IID "com.affinix.qca.Plugin/1.0") Q_PLUGIN_METADATA(IID "com.affinix.qca.Plugin/1.0")
#endif
Q_INTERFACES(QCAPlugin) Q_INTERFACES(QCAPlugin)
public: public:
virtual Provider *createProvider() { return new saslProvider; } Provider *createProvider() override
{
return new saslProvider;
}
}; };
#include "qca-cyrus-sasl.moc" #include "qca-cyrus-sasl.moc"
#if QT_VERSION < 0x050000
Q_EXPORT_PLUGIN2(qca_cyrus_sasl, saslPlugin)
#endif

View File

@ -1,8 +1,8 @@
if(WITH_gcrypt_PLUGIN STREQUAL "yes") if(WITH_gcrypt_PLUGIN STREQUAL "yes")
find_package(LibGcrypt REQUIRED) find_package(LibGcrypt REQUIRED)
else(WITH_gcrypt_PLUGIN STREQUAL "yes") else()
find_package(LibGcrypt) find_package(LibGcrypt)
endif(WITH_gcrypt_PLUGIN STREQUAL "yes") endif()
if(LIBGCRYPT_FOUND) if(LIBGCRYPT_FOUND)
include(CheckTypeSize) include(CheckTypeSize)
@ -19,14 +19,17 @@ if(LIBGCRYPT_FOUND)
set(QCA_GCRYPT_SOURCES qca-gcrypt.cpp) set(QCA_GCRYPT_SOURCES qca-gcrypt.cpp)
add_definitions(${LIBGCRYPT_CFLAGS}) add_definitions(${LIBGCRYPT_CFLAGS})
my_automoc(QCA_GCRYPT_SOURCES)
add_library(qca-gcrypt ${PLUGIN_TYPE} ${QCA_GCRYPT_SOURCES}) add_library(qca-gcrypt ${PLUGIN_TYPE} ${QCA_GCRYPT_SOURCES})
if(APPLE AND ${PLUGIN_TYPE} STREQUAL "MODULE") if(APPLE AND ${PLUGIN_TYPE} STREQUAL "MODULE")
set_property(TARGET qca-gcrypt PROPERTY SUFFIX ".dylib") set_property(TARGET qca-gcrypt PROPERTY SUFFIX ".dylib")
endif() endif()
target_link_libraries(qca-gcrypt ${QT_QTCORE_LIBRARY} ${QCA_LIB_NAME} ${LIBGCRYPT_LIBRARIES}) if(QT6)
target_link_libraries(qca-gcrypt Qt6::Core ${QCA_LIB_NAME} ${LIBGCRYPT_LIBRARIES})
else()
target_link_libraries(qca-gcrypt Qt5::Core ${QCA_LIB_NAME} ${LIBGCRYPT_LIBRARIES})
endif()
if(NOT DEVELOPER_MODE) if(NOT DEVELOPER_MODE)
install(TARGETS qca-gcrypt install(TARGETS qca-gcrypt
@ -36,10 +39,10 @@ if(LIBGCRYPT_FOUND)
install_pdb(qca-gcrypt ${QCA_CRYPTO_INSTALL_DIR}) install_pdb(qca-gcrypt ${QCA_CRYPTO_INSTALL_DIR})
endif() endif()
else(HAVE_GCRY_ERROR_T) else()
message(STATUS "libgcrypt seems to be too old") message(STATUS "libgcrypt seems to be too old")
disable_plugin("gcrypt") disable_plugin("gcrypt")
endif(HAVE_GCRY_ERROR_T) endif()
else(LIBGCRYPT_FOUND) else()
disable_plugin("gcrypt") disable_plugin("gcrypt")
endif(LIBGCRYPT_FOUND) endif()

120
plugins/qca-gcrypt/hkdf.c Normal file
View File

@ -0,0 +1,120 @@
/*
* Copyright (C) 2011 Collabora Ltd.
* Copyright (C) 2018 Alexander Volkov <a.volkov@rusbitech.ru>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation; either version 2.1 of
* the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
* MA 02110-1301 USA
*
* Author: Stef Walter <stefw@collabora.co.uk>
*/
#include <gcrypt.h>
static gcry_error_t gcry_hkdf(int algo,
const char *input,
size_t n_input,
const char *salt,
size_t n_salt,
const char *info,
size_t n_info,
char * output,
size_t n_output)
{
void * alloc = nullptr;
void * buffer = nullptr;
gcry_md_hd_t md1, md2;
unsigned int hash_len;
int i;
size_t step, n_buffer;
char * at;
gcry_error_t gcry;
hash_len = gcry_md_get_algo_dlen(algo);
if (hash_len == 0) {
return GPG_ERR_UNSUPPORTED_ALGORITHM;
}
if (n_output > 255 * hash_len) {
return GPG_ERR_TOO_LARGE;
}
/* Buffer we need to for intermediate stuff */
buffer = gcry_malloc_secure(hash_len);
if (!buffer) {
return GPG_ERR_ENOMEM;
}
n_buffer = 0;
/* Salt defaults to hash_len zeros */
if (!salt) {
alloc = gcry_calloc_secure(hash_len, 1);
if (!alloc) {
return GPG_ERR_ENOMEM;
}
salt = (const char *)alloc;
n_salt = hash_len;
}
/* Step 1: Extract */
gcry = gcry_md_open(&md1, algo, GCRY_MD_FLAG_HMAC | GCRY_MD_FLAG_SECURE);
if (gcry != GPG_ERR_NO_ERROR) {
goto done;
}
gcry = gcry_md_setkey(md1, salt, n_salt);
if (gcry != GPG_ERR_NO_ERROR) {
gcry_md_close(md1);
goto done;
}
gcry_md_write(md1, input, n_input);
/* Step 2: Expand */
gcry = gcry_md_open(&md2, algo, GCRY_MD_FLAG_HMAC | GCRY_MD_FLAG_SECURE);
if (gcry != GPG_ERR_NO_ERROR) {
gcry_md_close(md1);
goto done;
}
gcry = gcry_md_setkey(md2, gcry_md_read(md1, algo), hash_len);
if (gcry != GPG_ERR_NO_ERROR) {
gcry_md_close(md2);
gcry_md_close(md1);
goto done;
}
gcry_md_close(md1);
at = output;
for (i = 1; i < 256; ++i) {
gcry_md_reset(md2);
gcry_md_write(md2, buffer, n_buffer);
gcry_md_write(md2, info, n_info);
gcry_md_putc(md2, i);
n_buffer = hash_len;
memcpy(buffer, gcry_md_read(md2, algo), n_buffer);
step = n_buffer < n_output ? n_buffer : n_output;
memcpy(at, buffer, step);
n_output -= step;
at += step;
if (!n_output)
break;
}
gcry_md_close(md2);
done:
gcry_free(alloc);
gcry_free(buffer);
return gcry;
}

View File

@ -45,9 +45,14 @@
* Output: DK derived key, a dkLen-octet string * Output: DK derived key, a dkLen-octet string
*/ */
gcry_error_t static gcry_error_t gcry_pbkdf2(int PRF,
gcry_pbkdf2 (int PRF, const char *P, size_t Plen, const char *S, const char * P,
size_t Slen, unsigned int c, unsigned int dkLen, char *DK) size_t Plen,
const char * S,
size_t Slen,
unsigned int c,
unsigned int dkLen,
char * DK)
{ {
gcry_md_hd_t prf; gcry_md_hd_t prf;
gcry_error_t rc; gcry_error_t rc;
@ -144,26 +149,22 @@ gcry_pbkdf2 (int PRF, const char *P, size_t Plen, const char *S,
return rc; return rc;
U = (char *)gcry_malloc(hLen); U = (char *)gcry_malloc(hLen);
if (!U) if (!U) {
{
rc = GPG_ERR_ENOMEM; rc = GPG_ERR_ENOMEM;
goto done; goto done;
} }
for (i = 1; i <= l; i++) for (i = 1; i <= l; i++) {
{
memset(DK + (i - 1) * hLen, 0, i == l ? r : hLen); memset(DK + (i - 1) * hLen, 0, i == l ? r : hLen);
for (u = 1; u <= c; u++) for (u = 1; u <= c; u++) {
{
gcry_md_reset(prf); gcry_md_reset(prf);
rc = gcry_md_setkey(prf, P, Plen); rc = gcry_md_setkey(prf, P, Plen);
if (rc != GPG_ERR_NO_ERROR) { if (rc != GPG_ERR_NO_ERROR) {
goto done; goto done;
} }
if (u == 1) if (u == 1) {
{
char tmp[4]; char tmp[4];
gcry_md_write(prf, S, Slen); gcry_md_write(prf, S, Slen);
tmp[0] = (i & 0xff000000) >> 24; tmp[0] = (i & 0xff000000) >> 24;
@ -171,13 +172,11 @@ gcry_pbkdf2 (int PRF, const char *P, size_t Plen, const char *S,
tmp[2] = (i & 0x0000ff00) >> 8; tmp[2] = (i & 0x0000ff00) >> 8;
tmp[3] = (i & 0x000000ff) >> 0; tmp[3] = (i & 0x000000ff) >> 0;
gcry_md_write(prf, tmp, 4); gcry_md_write(prf, tmp, 4);
} } else
else
gcry_md_write(prf, U, hLen); gcry_md_write(prf, U, hLen);
p = gcry_md_read(prf, PRF); p = gcry_md_read(prf, PRF);
if (p == NULL) if (p == nullptr) {
{
rc = GPG_ERR_CONFIGURATION; rc = GPG_ERR_CONFIGURATION;
goto done; goto done;
} }
@ -194,4 +193,3 @@ gcry_pbkdf2 (int PRF, const char *P, size_t Plen, const char *S,
gcry_free(U); gcry_free(U);
return rc; return rc;
} }

View File

@ -21,22 +21,23 @@
#include <QtCore/qplugin.h> #include <QtCore/qplugin.h>
#include <QTime> #include <QElapsedTimer>
#include <qstringlist.h>
#include <gcrypt.h> #include <gcrypt.h>
#include <iostream> #include <iostream>
#include <qstringlist.h>
namespace gcryptQCAPlugin { namespace gcryptQCAPlugin {
#include "hkdf.c"
#include "pkcs5.c" #include "pkcs5.c"
void check_error( const QString &label, gcry_error_t err ) void check_error(const char *label, gcry_error_t err)
{ {
// we ignore the case where it is not an error, and // we ignore the case where it is not an error, and
// we also don't flag weak keys. // we also don't flag weak keys.
if ((GPG_ERR_NO_ERROR != err) && (GPG_ERR_WEAK_KEY != gpg_err_code(err))) { if ((GPG_ERR_NO_ERROR != err) && (GPG_ERR_WEAK_KEY != gpg_err_code(err))) {
std::cout << "Failure (" << qPrintable(label) << "): "; std::cout << "Failure (" << label << "): ";
std::cout << gcry_strsource(err) << "/"; std::cout << gcry_strsource(err) << "/";
std::cout << gcry_strerror(err) << std::endl; std::cout << gcry_strerror(err) << std::endl;
} }
@ -44,8 +45,10 @@ void check_error( const QString &label, gcry_error_t err )
class gcryHashContext : public QCA::HashContext class gcryHashContext : public QCA::HashContext
{ {
Q_OBJECT
public: public:
gcryHashContext(int hashAlgorithm, QCA::Provider *p, const QString &type) : QCA::HashContext(p, type) gcryHashContext(int hashAlgorithm, QCA::Provider *p, const QString &type)
: QCA::HashContext(p, type)
{ {
m_hashAlgorithm = hashAlgorithm; m_hashAlgorithm = hashAlgorithm;
err = gcry_md_open(&context, m_hashAlgorithm, 0); err = gcry_md_open(&context, m_hashAlgorithm, 0);
@ -56,27 +59,27 @@ public:
} }
} }
~gcryHashContext() ~gcryHashContext() override
{ {
gcry_md_close(context); gcry_md_close(context);
} }
Context *clone() const Context *clone() const override
{ {
return new gcryHashContext(*this); return new gcryHashContext(m_hashAlgorithm, provider(), type());
} }
void clear() void clear() override
{ {
gcry_md_reset(context); gcry_md_reset(context);
} }
void update(const QCA::MemoryRegion &a) void update(const QCA::MemoryRegion &a) override
{ {
gcry_md_write(context, a.data(), a.size()); gcry_md_write(context, a.data(), a.size());
} }
QCA::MemoryRegion final() QCA::MemoryRegion final() override
{ {
unsigned char * md; unsigned char * md;
QCA::SecureArray a(gcry_md_get_algo_dlen(m_hashAlgorithm)); QCA::SecureArray a(gcry_md_get_algo_dlen(m_hashAlgorithm));
@ -93,8 +96,10 @@ protected:
class gcryHMACContext : public QCA::MACContext class gcryHMACContext : public QCA::MACContext
{ {
Q_OBJECT
public: public:
gcryHMACContext(int hashAlgorithm, QCA::Provider *p, const QString &type) : QCA::MACContext(p, type) gcryHMACContext(int hashAlgorithm, QCA::Provider *p, const QString &type)
: QCA::MACContext(p, type)
{ {
m_hashAlgorithm = hashAlgorithm; m_hashAlgorithm = hashAlgorithm;
err = gcry_md_open(&context, m_hashAlgorithm, GCRY_MD_FLAG_HMAC); err = gcry_md_open(&context, m_hashAlgorithm, GCRY_MD_FLAG_HMAC);
@ -105,19 +110,19 @@ public:
} }
} }
~gcryHMACContext() ~gcryHMACContext() override
{ {
gcry_md_close(context); gcry_md_close(context);
} }
void setup(const QCA::SymmetricKey &key) void setup(const QCA::SymmetricKey &key) override
{ {
gcry_md_setkey(context, key.data(), key.size()); gcry_md_setkey(context, key.data(), key.size());
} }
Context *clone() const Context *clone() const override
{ {
return new gcryHMACContext(*this); return new gcryHMACContext(m_hashAlgorithm, provider(), type());
} }
void clear() void clear()
@ -125,17 +130,17 @@ public:
gcry_md_reset(context); gcry_md_reset(context);
} }
QCA::KeyLength keyLength() const QCA::KeyLength keyLength() const override
{ {
return anyKeyLength(); return anyKeyLength();
} }
void update(const QCA::MemoryRegion &a) void update(const QCA::MemoryRegion &a) override
{ {
gcry_md_write(context, a.data(), a.size()); gcry_md_write(context, a.data(), a.size());
} }
void final( QCA::MemoryRegion *out) void final(QCA::MemoryRegion *out) override
{ {
QCA::SecureArray sa(gcry_md_get_algo_dlen(m_hashAlgorithm), 0); QCA::SecureArray sa(gcry_md_get_algo_dlen(m_hashAlgorithm), 0);
unsigned char * md; unsigned char * md;
@ -150,11 +155,12 @@ protected:
int m_hashAlgorithm; int m_hashAlgorithm;
}; };
class gcryCipherContext : public QCA::CipherContext class gcryCipherContext : public QCA::CipherContext
{ {
Q_OBJECT
public: public:
gcryCipherContext(int algorithm, int mode, bool pad, QCA::Provider *p, const QString &type) : QCA::CipherContext(p, type) gcryCipherContext(int algorithm, int mode, bool pad, QCA::Provider *p, const QString &type)
: QCA::CipherContext(p, type)
{ {
m_cryptoAlgorithm = algorithm; m_cryptoAlgorithm = algorithm;
m_mode = mode; m_mode = mode;
@ -163,8 +169,10 @@ public:
void setup(QCA::Direction dir, void setup(QCA::Direction dir,
const QCA::SymmetricKey & key, const QCA::SymmetricKey & key,
const QCA::InitializationVector &iv) const QCA::InitializationVector &iv,
const QCA::AuthTag & tag) override
{ {
Q_UNUSED(tag);
m_direction = dir; m_direction = dir;
err = gcry_cipher_open(&context, m_cryptoAlgorithm, m_mode, 0); err = gcry_cipher_open(&context, m_cryptoAlgorithm, m_mode, 0);
check_error("gcry_cipher_open", err); check_error("gcry_cipher_open", err);
@ -183,25 +191,33 @@ public:
check_error("gcry_cipher_setiv", err); check_error("gcry_cipher_setiv", err);
} }
Context *clone() const Context *clone() const override
{ {
return new gcryCipherContext(*this); return new gcryCipherContext(*this);
} }
int blockSize() const int blockSize() const override
{ {
unsigned int blockSize; size_t blockSize;
gcry_cipher_algo_info( m_cryptoAlgorithm, GCRYCTL_GET_BLKLEN, 0, (size_t*)&blockSize ); gcry_cipher_algo_info(m_cryptoAlgorithm, GCRYCTL_GET_BLKLEN, nullptr, &blockSize);
return blockSize; return blockSize;
} }
bool update(const QCA::SecureArray &in, QCA::SecureArray *out) QCA::AuthTag tag() const override
{
// For future implementation
return QCA::AuthTag();
}
bool update(const QCA::SecureArray &in, QCA::SecureArray *out) override
{ {
QCA::SecureArray result(in.size()); QCA::SecureArray result(in.size());
if (QCA::Encode == m_direction) { if (QCA::Encode == m_direction) {
err = gcry_cipher_encrypt( context, (unsigned char*)result.data(), result.size(), (unsigned char*)in.data(), in.size() ); err = gcry_cipher_encrypt(
context, (unsigned char *)result.data(), result.size(), (unsigned char *)in.data(), in.size());
} else { } else {
err = gcry_cipher_decrypt( context, (unsigned char*)result.data(), result.size(), (unsigned char*)in.data(), in.size() ); err = gcry_cipher_decrypt(
context, (unsigned char *)result.data(), result.size(), (unsigned char *)in.data(), in.size());
} }
check_error("update cipher encrypt/decrypt", err); check_error("update cipher encrypt/decrypt", err);
result.resize(in.size()); result.resize(in.size());
@ -209,15 +225,15 @@ public:
return true; return true;
} }
bool final(QCA::SecureArray *out) bool final(QCA::SecureArray *out) override
{ {
QCA::SecureArray result; QCA::SecureArray result;
if (m_pad) { if (m_pad) {
result.resize(blockSize()); result.resize(blockSize());
if (QCA::Encode == m_direction) { if (QCA::Encode == m_direction) {
err = gcry_cipher_encrypt( context, (unsigned char*)result.data(), result.size(), NULL, 0 ); err = gcry_cipher_encrypt(context, (unsigned char *)result.data(), result.size(), nullptr, 0);
} else { } else {
err = gcry_cipher_decrypt( context, (unsigned char*)result.data(), result.size(), NULL, 0 ); err = gcry_cipher_decrypt(context, (unsigned char *)result.data(), result.size(), nullptr, 0);
} }
check_error("final cipher encrypt/decrypt", err); check_error("final cipher encrypt/decrypt", err);
} else { } else {
@ -227,10 +243,9 @@ public:
return true; return true;
} }
QCA::KeyLength keyLength() const QCA::KeyLength keyLength() const override
{
switch (m_cryptoAlgorithm)
{ {
switch (m_cryptoAlgorithm) {
case GCRY_CIPHER_DES: case GCRY_CIPHER_DES:
return QCA::KeyLength(8, 8, 1); return QCA::KeyLength(8, 8, 1);
case GCRY_CIPHER_AES128: case GCRY_CIPHER_AES128:
@ -250,7 +265,6 @@ public:
} }
} }
protected: protected:
gcry_cipher_hd_t context; gcry_cipher_hd_t context;
gcry_error_t err; gcry_error_t err;
@ -260,11 +274,12 @@ protected:
bool m_pad; bool m_pad;
}; };
class pbkdf1Context : public QCA::KDFContext class pbkdf1Context : public QCA::KDFContext
{ {
Q_OBJECT
public: public:
pbkdf1Context(int algorithm, QCA::Provider *p, const QString &type) : QCA::KDFContext(p, type) pbkdf1Context(int algorithm, QCA::Provider *p, const QString &type)
: QCA::KDFContext(p, type)
{ {
m_hashAlgorithm = algorithm; m_hashAlgorithm = algorithm;
err = gcry_md_open(&context, m_hashAlgorithm, 0); err = gcry_md_open(&context, m_hashAlgorithm, 0);
@ -275,18 +290,20 @@ public:
} }
} }
~pbkdf1Context() ~pbkdf1Context() override
{ {
gcry_md_close(context); gcry_md_close(context);
} }
Context *clone() const Context *clone() const override
{ {
return new pbkdf1Context( *this ); return new pbkdf1Context(m_hashAlgorithm, provider(), type());
} }
QCA::SymmetricKey makeKey(const QCA::SecureArray &secret, const QCA::InitializationVector &salt, QCA::SymmetricKey makeKey(const QCA::SecureArray & secret,
unsigned int keyLength, unsigned int iterationCount) const QCA::InitializationVector &salt,
unsigned int keyLength,
unsigned int iterationCount) override
{ {
/* from RFC2898: /* from RFC2898:
Steps: Steps:
@ -339,10 +356,10 @@ public:
const QCA::InitializationVector &salt, const QCA::InitializationVector &salt,
unsigned int keyLength, unsigned int keyLength,
int msecInterval, int msecInterval,
unsigned int *iterationCount) unsigned int * iterationCount) override
{ {
Q_ASSERT(iterationCount != NULL); Q_ASSERT(iterationCount != nullptr);
QTime timer; QElapsedTimer timer;
/* /*
from RFC2898: from RFC2898:
@ -404,27 +421,35 @@ protected:
int m_hashAlgorithm; int m_hashAlgorithm;
}; };
class pbkdf2Context : public QCA::KDFContext class pbkdf2Context : public QCA::KDFContext
{ {
Q_OBJECT
public: public:
pbkdf2Context(int algorithm, QCA::Provider *p, const QString &type) : QCA::KDFContext(p, type) pbkdf2Context(int algorithm, QCA::Provider *p, const QString &type)
: QCA::KDFContext(p, type)
{ {
m_algorithm = algorithm; m_algorithm = algorithm;
} }
Context *clone() const Context *clone() const override
{ {
return new pbkdf2Context(*this); return new pbkdf2Context(*this);
} }
QCA::SymmetricKey makeKey(const QCA::SecureArray &secret, const QCA::InitializationVector &salt, QCA::SymmetricKey makeKey(const QCA::SecureArray & secret,
unsigned int keyLength, unsigned int iterationCount) const QCA::InitializationVector &salt,
unsigned int keyLength,
unsigned int iterationCount) override
{ {
QCA::SymmetricKey result(keyLength); QCA::SymmetricKey result(keyLength);
gcry_error_t retval = gcry_pbkdf2(m_algorithm, secret.data(), secret.size(), gcry_error_t retval = gcry_pbkdf2(m_algorithm,
salt.data(), salt.size(), secret.data(),
iterationCount, keyLength, result.data()); secret.size(),
salt.data(),
salt.size(),
iterationCount,
keyLength,
result.data());
if (retval == GPG_ERR_NO_ERROR) { if (retval == GPG_ERR_NO_ERROR) {
return result; return result;
} else { } else {
@ -437,24 +462,18 @@ public:
const QCA::InitializationVector &salt, const QCA::InitializationVector &salt,
unsigned int keyLength, unsigned int keyLength,
int msecInterval, int msecInterval,
unsigned int *iterationCount) unsigned int * iterationCount) override
{ {
Q_ASSERT(iterationCount != NULL); Q_ASSERT(iterationCount != nullptr);
QCA::SymmetricKey result(keyLength); QCA::SymmetricKey result(keyLength);
QTime timer; QElapsedTimer timer;
*iterationCount = 0; *iterationCount = 0;
timer.start(); timer.start();
while (timer.elapsed() < msecInterval) { while (timer.elapsed() < msecInterval) {
gcry_pbkdf2(m_algorithm, gcry_pbkdf2(
secret.data(), m_algorithm, secret.data(), secret.size(), salt.data(), salt.size(), 1, keyLength, result.data());
secret.size(),
salt.data(),
salt.size(),
1,
keyLength,
result.data());
++(*iterationCount); ++(*iterationCount);
} }
@ -465,10 +484,50 @@ protected:
int m_algorithm; int m_algorithm;
}; };
class hkdfContext : public QCA::HKDFContext
{
Q_OBJECT
public:
hkdfContext(int algorithm, QCA::Provider *p, const QString &type)
: QCA::HKDFContext(p, type)
{
m_algorithm = algorithm;
} }
extern "C" Context *clone() const override
{ {
return new hkdfContext(*this);
}
QCA::SymmetricKey makeKey(const QCA::SecureArray & secret,
const QCA::InitializationVector &salt,
const QCA::InitializationVector &info,
unsigned int keyLength) override
{
QCA::SymmetricKey result(keyLength);
gcry_error_t retval = gcry_hkdf(m_algorithm,
secret.data(),
secret.size(),
salt.data(),
salt.size(),
info.data(),
info.size(),
result.data(),
result.size());
if (retval == GPG_ERR_NO_ERROR) {
return result;
} else {
return QCA::SymmetricKey();
}
}
protected:
int m_algorithm;
};
}
extern "C" {
static void *qca_func_malloc(size_t n) static void *qca_func_malloc(size_t n)
{ {
@ -499,193 +558,192 @@ int qca_func_secure_check (const void *)
class gcryptProvider : public QCA::Provider class gcryptProvider : public QCA::Provider
{ {
public: public:
void init() void init() override
{ {
if (!gcry_control (GCRYCTL_ANY_INITIALIZATION_P)) if (!gcry_control(GCRYCTL_ANY_INITIALIZATION_P)) { /* No other library has already initialized libgcrypt. */
{ /* No other library has already initialized libgcrypt. */
if (!gcry_check_version (GCRYPT_VERSION) ) if (!gcry_check_version(GCRYPT_VERSION)) {
{
std::cout << "libgcrypt is too old (need " << GCRYPT_VERSION; std::cout << "libgcrypt is too old (need " << GCRYPT_VERSION;
std::cout << ", have " << gcry_check_version(NULL) << ")" << std::endl; std::cout << ", have " << gcry_check_version(nullptr) << ")" << std::endl;
} }
gcry_set_allocation_handler (qca_func_malloc, gcry_set_allocation_handler(
qca_func_secure_malloc, qca_func_malloc, qca_func_secure_malloc, qca_func_secure_check, qca_func_realloc, qca_func_free);
qca_func_secure_check,
qca_func_realloc,
qca_func_free);
gcry_control(GCRYCTL_INITIALIZATION_FINISHED); gcry_control(GCRYCTL_INITIALIZATION_FINISHED);
} }
} }
int qcaVersion() const int qcaVersion() const override
{ {
return QCA_VERSION; return QCA_VERSION;
} }
QString name() const QString name() const override
{ {
return "qca-gcrypt"; return QStringLiteral("qca-gcrypt");
} }
QStringList features() const QStringList features() const override
{ {
QStringList list; QStringList list;
list += "sha1"; list += QStringLiteral("sha1");
list += "md4"; list += QStringLiteral("md4");
list += "md5"; list += QStringLiteral("md5");
list += "ripemd160"; list += QStringLiteral("ripemd160");
#ifdef GCRY_MD_SHA224 #ifdef GCRY_MD_SHA224
list += "sha224"; list += QStringLiteral("sha224");
#endif #endif
list += "sha256"; list += QStringLiteral("sha256");
list += "sha384"; list += QStringLiteral("sha384");
list += "sha512"; list += QStringLiteral("sha512");
list += "hmac(md5)"; list += QStringLiteral("hmac(md5)");
list += "hmac(sha1)"; list += QStringLiteral("hmac(sha1)");
#ifdef GCRY_MD_SHA224 #ifdef GCRY_MD_SHA224
list += "hmac(sha224)"; list += QStringLiteral("hmac(sha224)");
#endif #endif
list += "hmac(sha256)"; list += QStringLiteral("hmac(sha256)");
if ( ! ( NULL == gcry_check_version("1.3.0") ) ) { if (!(nullptr == gcry_check_version("1.3.0"))) {
// 1.2 and earlier have broken implementation // 1.2 and earlier have broken implementation
list += "hmac(sha384)"; list += QStringLiteral("hmac(sha384)");
list += "hmac(sha512)"; list += QStringLiteral("hmac(sha512)");
} }
list += "hmac(ripemd160)"; list += QStringLiteral("hmac(ripemd160)");
list += "aes128-ecb"; list += QStringLiteral("aes128-ecb");
list += "aes128-cfb"; list += QStringLiteral("aes128-cfb");
list += "aes128-cbc"; list += QStringLiteral("aes128-cbc");
list += "aes192-ecb"; list += QStringLiteral("aes192-ecb");
list += "aes192-cfb"; list += QStringLiteral("aes192-cfb");
list += "aes192-cbc"; list += QStringLiteral("aes192-cbc");
list += "aes256-ecb"; list += QStringLiteral("aes256-ecb");
list += "aes256-cfb"; list += QStringLiteral("aes256-cfb");
list += "aes256-cbc"; list += QStringLiteral("aes256-cbc");
list += "blowfish-ecb"; list += QStringLiteral("blowfish-ecb");
list += "blowfish-cbc"; list += QStringLiteral("blowfish-cbc");
list += "blowfish-cfb"; list += QStringLiteral("blowfish-cfb");
list += "tripledes-ecb"; list += QStringLiteral("tripledes-ecb");
list += "des-ecb"; // list += QStringLiteral("des-ecb");
list += "des-cbc"; list += QStringLiteral("des-cbc");
list += "des-cfb"; list += QStringLiteral("des-cfb");
if ( ! ( NULL == gcry_check_version("1.3.0") ) ) { if (!(nullptr == gcry_check_version("1.3.0"))) {
// 1.2 branch and earlier doesn't support OFB mode // 1.2 branch and earlier doesn't support OFB mode
list += "aes128-ofb"; list += QStringLiteral("aes128-ofb");
list += "aes192-ofb"; list += QStringLiteral("aes192-ofb");
list += "aes256-ofb"; list += QStringLiteral("aes256-ofb");
list += "des-ofb"; list += QStringLiteral("des-ofb");
list += "tripledes-ofb"; list += QStringLiteral("tripledes-ofb");
list += "blowfish-ofb"; list += QStringLiteral("blowfish-ofb");
} }
list += "pbkdf1(sha1)"; list += QStringLiteral("pbkdf1(sha1)");
list += "pbkdf2(sha1)"; list += QStringLiteral("pbkdf2(sha1)");
list += QStringLiteral("hkdf(sha256)");
return list; return list;
} }
Context *createContext(const QString &type) Context *createContext(const QString &type) override
{ {
// std::cout << "type: " << qPrintable(type) << std::endl; // std::cout << "type: " << qPrintable(type) << std::endl;
if ( type == "sha1" ) if (type == QLatin1String("sha1"))
return new gcryptQCAPlugin::gcryHashContext(GCRY_MD_SHA1, this, type); return new gcryptQCAPlugin::gcryHashContext(GCRY_MD_SHA1, this, type);
else if ( type == "md4" ) else if (type == QLatin1String("md4"))
return new gcryptQCAPlugin::gcryHashContext(GCRY_MD_MD4, this, type); return new gcryptQCAPlugin::gcryHashContext(GCRY_MD_MD4, this, type);
else if ( type == "md5" ) else if (type == QLatin1String("md5"))
return new gcryptQCAPlugin::gcryHashContext(GCRY_MD_MD5, this, type); return new gcryptQCAPlugin::gcryHashContext(GCRY_MD_MD5, this, type);
else if ( type == "ripemd160" ) else if (type == QLatin1String("ripemd160"))
return new gcryptQCAPlugin::gcryHashContext(GCRY_MD_RMD160, this, type); return new gcryptQCAPlugin::gcryHashContext(GCRY_MD_RMD160, this, type);
#ifdef GCRY_MD_SHA224 #ifdef GCRY_MD_SHA224
else if ( type == "sha224" ) else if (type == QLatin1String("sha224"))
return new gcryptQCAPlugin::gcryHashContext(GCRY_MD_SHA224, this, type); return new gcryptQCAPlugin::gcryHashContext(GCRY_MD_SHA224, this, type);
#endif #endif
else if ( type == "sha256" ) else if (type == QLatin1String("sha256"))
return new gcryptQCAPlugin::gcryHashContext(GCRY_MD_SHA256, this, type); return new gcryptQCAPlugin::gcryHashContext(GCRY_MD_SHA256, this, type);
else if ( type == "sha384" ) else if (type == QLatin1String("sha384"))
return new gcryptQCAPlugin::gcryHashContext(GCRY_MD_SHA384, this, type); return new gcryptQCAPlugin::gcryHashContext(GCRY_MD_SHA384, this, type);
else if ( type == "sha512" ) else if (type == QLatin1String("sha512"))
return new gcryptQCAPlugin::gcryHashContext(GCRY_MD_SHA512, this, type); return new gcryptQCAPlugin::gcryHashContext(GCRY_MD_SHA512, this, type);
else if ( type == "hmac(md5)" ) else if (type == QLatin1String("hmac(md5)"))
return new gcryptQCAPlugin::gcryHMACContext(GCRY_MD_MD5, this, type); return new gcryptQCAPlugin::gcryHMACContext(GCRY_MD_MD5, this, type);
else if ( type == "hmac(sha1)" ) else if (type == QLatin1String("hmac(sha1)"))
return new gcryptQCAPlugin::gcryHMACContext(GCRY_MD_SHA1, this, type); return new gcryptQCAPlugin::gcryHMACContext(GCRY_MD_SHA1, this, type);
#ifdef GCRY_MD_SHA224 #ifdef GCRY_MD_SHA224
else if ( type == "hmac(sha224)" ) else if (type == QLatin1String("hmac(sha224)"))
return new gcryptQCAPlugin::gcryHMACContext(GCRY_MD_SHA224, this, type); return new gcryptQCAPlugin::gcryHMACContext(GCRY_MD_SHA224, this, type);
#endif #endif
else if ( type == "hmac(sha256)" ) else if (type == QLatin1String("hmac(sha256)"))
return new gcryptQCAPlugin::gcryHMACContext(GCRY_MD_SHA256, this, type); return new gcryptQCAPlugin::gcryHMACContext(GCRY_MD_SHA256, this, type);
else if ( type == "hmac(sha384)" ) else if (type == QLatin1String("hmac(sha384)"))
return new gcryptQCAPlugin::gcryHMACContext(GCRY_MD_SHA384, this, type); return new gcryptQCAPlugin::gcryHMACContext(GCRY_MD_SHA384, this, type);
else if ( type == "hmac(sha512)" ) else if (type == QLatin1String("hmac(sha512)"))
return new gcryptQCAPlugin::gcryHMACContext(GCRY_MD_SHA512, this, type); return new gcryptQCAPlugin::gcryHMACContext(GCRY_MD_SHA512, this, type);
else if ( type == "hmac(ripemd160)" ) else if (type == QLatin1String("hmac(ripemd160)"))
return new gcryptQCAPlugin::gcryHMACContext(GCRY_MD_RMD160, this, type); return new gcryptQCAPlugin::gcryHMACContext(GCRY_MD_RMD160, this, type);
else if ( type == "aes128-ecb" ) else if (type == QLatin1String("aes128-ecb"))
return new gcryptQCAPlugin::gcryCipherContext(GCRY_CIPHER_AES128, GCRY_CIPHER_MODE_ECB, false, this, type); return new gcryptQCAPlugin::gcryCipherContext(GCRY_CIPHER_AES128, GCRY_CIPHER_MODE_ECB, false, this, type);
else if ( type == "aes128-cfb" ) else if (type == QLatin1String("aes128-cfb"))
return new gcryptQCAPlugin::gcryCipherContext(GCRY_CIPHER_AES128, GCRY_CIPHER_MODE_CFB, false, this, type); return new gcryptQCAPlugin::gcryCipherContext(GCRY_CIPHER_AES128, GCRY_CIPHER_MODE_CFB, false, this, type);
else if ( type == "aes128-ofb" ) else if (type == QLatin1String("aes128-ofb"))
return new gcryptQCAPlugin::gcryCipherContext(GCRY_CIPHER_AES128, GCRY_CIPHER_MODE_OFB, false, this, type); return new gcryptQCAPlugin::gcryCipherContext(GCRY_CIPHER_AES128, GCRY_CIPHER_MODE_OFB, false, this, type);
else if ( type == "aes128-cbc" ) else if (type == QLatin1String("aes128-cbc"))
return new gcryptQCAPlugin::gcryCipherContext(GCRY_CIPHER_AES128, GCRY_CIPHER_MODE_CBC, false, this, type); return new gcryptQCAPlugin::gcryCipherContext(GCRY_CIPHER_AES128, GCRY_CIPHER_MODE_CBC, false, this, type);
else if ( type == "aes192-ecb" ) else if (type == QLatin1String("aes192-ecb"))
return new gcryptQCAPlugin::gcryCipherContext(GCRY_CIPHER_AES192, GCRY_CIPHER_MODE_ECB, false, this, type); return new gcryptQCAPlugin::gcryCipherContext(GCRY_CIPHER_AES192, GCRY_CIPHER_MODE_ECB, false, this, type);
else if ( type == "aes192-cfb" ) else if (type == QLatin1String("aes192-cfb"))
return new gcryptQCAPlugin::gcryCipherContext(GCRY_CIPHER_AES192, GCRY_CIPHER_MODE_CFB, false, this, type); return new gcryptQCAPlugin::gcryCipherContext(GCRY_CIPHER_AES192, GCRY_CIPHER_MODE_CFB, false, this, type);
else if ( type == "aes192-ofb" ) else if (type == QLatin1String("aes192-ofb"))
return new gcryptQCAPlugin::gcryCipherContext(GCRY_CIPHER_AES192, GCRY_CIPHER_MODE_OFB, false, this, type); return new gcryptQCAPlugin::gcryCipherContext(GCRY_CIPHER_AES192, GCRY_CIPHER_MODE_OFB, false, this, type);
else if ( type == "aes192-cbc" ) else if (type == QLatin1String("aes192-cbc"))
return new gcryptQCAPlugin::gcryCipherContext(GCRY_CIPHER_AES192, GCRY_CIPHER_MODE_CBC, false, this, type); return new gcryptQCAPlugin::gcryCipherContext(GCRY_CIPHER_AES192, GCRY_CIPHER_MODE_CBC, false, this, type);
else if ( type == "aes256-ecb" ) else if (type == QLatin1String("aes256-ecb"))
return new gcryptQCAPlugin::gcryCipherContext(GCRY_CIPHER_AES256, GCRY_CIPHER_MODE_ECB, false, this, type); return new gcryptQCAPlugin::gcryCipherContext(GCRY_CIPHER_AES256, GCRY_CIPHER_MODE_ECB, false, this, type);
else if ( type == "aes256-cfb" ) else if (type == QLatin1String("aes256-cfb"))
return new gcryptQCAPlugin::gcryCipherContext(GCRY_CIPHER_AES256, GCRY_CIPHER_MODE_CFB, false, this, type); return new gcryptQCAPlugin::gcryCipherContext(GCRY_CIPHER_AES256, GCRY_CIPHER_MODE_CFB, false, this, type);
else if ( type == "aes256-ofb" ) else if (type == QLatin1String("aes256-ofb"))
return new gcryptQCAPlugin::gcryCipherContext(GCRY_CIPHER_AES256, GCRY_CIPHER_MODE_OFB, false, this, type); return new gcryptQCAPlugin::gcryCipherContext(GCRY_CIPHER_AES256, GCRY_CIPHER_MODE_OFB, false, this, type);
else if ( type == "aes256-cbc" ) else if (type == QLatin1String("aes256-cbc"))
return new gcryptQCAPlugin::gcryCipherContext(GCRY_CIPHER_AES256, GCRY_CIPHER_MODE_CBC, false, this, type); return new gcryptQCAPlugin::gcryCipherContext(GCRY_CIPHER_AES256, GCRY_CIPHER_MODE_CBC, false, this, type);
else if ( type == "blowfish-ecb" ) else if (type == QLatin1String("blowfish-ecb"))
return new gcryptQCAPlugin::gcryCipherContext( GCRY_CIPHER_BLOWFISH, GCRY_CIPHER_MODE_ECB, false, this, type ); return new gcryptQCAPlugin::gcryCipherContext(
else if ( type == "blowfish-cbc" ) GCRY_CIPHER_BLOWFISH, GCRY_CIPHER_MODE_ECB, false, this, type);
return new gcryptQCAPlugin::gcryCipherContext( GCRY_CIPHER_BLOWFISH, GCRY_CIPHER_MODE_CBC, false, this, type ); else if (type == QLatin1String("blowfish-cbc"))
else if ( type == "blowfish-cfb" ) return new gcryptQCAPlugin::gcryCipherContext(
return new gcryptQCAPlugin::gcryCipherContext( GCRY_CIPHER_BLOWFISH, GCRY_CIPHER_MODE_CFB, false, this, type ); GCRY_CIPHER_BLOWFISH, GCRY_CIPHER_MODE_CBC, false, this, type);
else if ( type == "blowfish-ofb" ) else if (type == QLatin1String("blowfish-cfb"))
return new gcryptQCAPlugin::gcryCipherContext( GCRY_CIPHER_BLOWFISH, GCRY_CIPHER_MODE_OFB, false, this, type ); return new gcryptQCAPlugin::gcryCipherContext(
else if ( type == "tripledes-ecb" ) GCRY_CIPHER_BLOWFISH, GCRY_CIPHER_MODE_CFB, false, this, type);
else if (type == QLatin1String("blowfish-ofb"))
return new gcryptQCAPlugin::gcryCipherContext(
GCRY_CIPHER_BLOWFISH, GCRY_CIPHER_MODE_OFB, false, this, type);
else if (type == QLatin1String("tripledes-ecb"))
return new gcryptQCAPlugin::gcryCipherContext(GCRY_CIPHER_3DES, GCRY_CIPHER_MODE_ECB, false, this, type); return new gcryptQCAPlugin::gcryCipherContext(GCRY_CIPHER_3DES, GCRY_CIPHER_MODE_ECB, false, this, type);
else if ( type == "tripledes-ofb" ) else if (type == QLatin1String("tripledes-ofb"))
return new gcryptQCAPlugin::gcryCipherContext(GCRY_CIPHER_3DES, GCRY_CIPHER_MODE_OFB, false, this, type); return new gcryptQCAPlugin::gcryCipherContext(GCRY_CIPHER_3DES, GCRY_CIPHER_MODE_OFB, false, this, type);
else if ( type == "des-ecb" ) else if (type == QLatin1String("des-ecb"))
return new gcryptQCAPlugin::gcryCipherContext(GCRY_CIPHER_DES, GCRY_CIPHER_MODE_ECB, false, this, type); return new gcryptQCAPlugin::gcryCipherContext(GCRY_CIPHER_DES, GCRY_CIPHER_MODE_ECB, false, this, type);
else if ( type == "des-cbc" ) else if (type == QLatin1String("des-cbc"))
return new gcryptQCAPlugin::gcryCipherContext(GCRY_CIPHER_DES, GCRY_CIPHER_MODE_CBC, false, this, type); return new gcryptQCAPlugin::gcryCipherContext(GCRY_CIPHER_DES, GCRY_CIPHER_MODE_CBC, false, this, type);
else if ( type == "des-cfb" ) else if (type == QLatin1String("des-cfb"))
return new gcryptQCAPlugin::gcryCipherContext(GCRY_CIPHER_DES, GCRY_CIPHER_MODE_CFB, false, this, type); return new gcryptQCAPlugin::gcryCipherContext(GCRY_CIPHER_DES, GCRY_CIPHER_MODE_CFB, false, this, type);
else if ( type == "des-ofb" ) else if (type == QLatin1String("des-ofb"))
return new gcryptQCAPlugin::gcryCipherContext(GCRY_CIPHER_DES, GCRY_CIPHER_MODE_OFB, false, this, type); return new gcryptQCAPlugin::gcryCipherContext(GCRY_CIPHER_DES, GCRY_CIPHER_MODE_OFB, false, this, type);
else if ( type == "pbkdf1(sha1)" ) else if (type == QLatin1String("pbkdf1(sha1)"))
return new gcryptQCAPlugin::pbkdf1Context(GCRY_MD_SHA1, this, type); return new gcryptQCAPlugin::pbkdf1Context(GCRY_MD_SHA1, this, type);
else if ( type == "pbkdf2(sha1)" ) else if (type == QLatin1String("pbkdf2(sha1)"))
return new gcryptQCAPlugin::pbkdf2Context(GCRY_MD_SHA1, this, type); return new gcryptQCAPlugin::pbkdf2Context(GCRY_MD_SHA1, this, type);
else if (type == QLatin1String("hkdf(sha256)"))
return new gcryptQCAPlugin::hkdfContext(GCRY_MD_SHA256, this, type);
else else
return 0; return nullptr;
} }
}; };
class gcryptPlugin : public QObject, public QCAPlugin class gcryptPlugin : public QObject, public QCAPlugin
{ {
Q_OBJECT Q_OBJECT
#if QT_VERSION >= 0x050000
Q_PLUGIN_METADATA(IID "com.affinix.qca.Plugin/1.0") Q_PLUGIN_METADATA(IID "com.affinix.qca.Plugin/1.0")
#endif
Q_INTERFACES(QCAPlugin) Q_INTERFACES(QCAPlugin)
public: public:
virtual QCA::Provider *createProvider() { return new gcryptProvider; } QCA::Provider *createProvider() override
{
return new gcryptProvider;
}
}; };
#include "qca-gcrypt.moc" #include "qca-gcrypt.moc"
#if QT_VERSION < 0x050000
Q_EXPORT_PLUGIN2(qca_gcrypt, gcryptPlugin)
#endif

View File

@ -2,11 +2,8 @@
enable_plugin("gnupg") enable_plugin("gnupg")
set(QCA_GNUPG_MOC_SOURCES set(QCA_GNUPG_SOURCES
qca-gnupg.cpp qca-gnupg.cpp
)
set(QCA_GNUPG_NONMOC_SOURCES
gpgop.cpp gpgop.cpp
utils.cpp utils.cpp
gpgproc/sprocess.cpp gpgproc/sprocess.cpp
@ -21,30 +18,39 @@ set(QCA_GNUPG_NONMOC_SOURCES
gpgproc/gpgproc.cpp gpgproc/gpgproc.cpp
) )
my_automoc(QCA_GNUPG_MOC_SOURCES) set(QCA_GNUPG_HEADERS
gpgaction.h
ringwatch.h
gpgop.h
gpgop_p.h
lineconverter.h
mypgpkeycontext.h
mykeystoreentry.h
mykeystorelist.h
gpgproc/gpgproc_p.h
gpgproc/sprocess.h
gpgproc/gpgproc.h
utils.h
mymessagecontext.h
myopenpgpcontext.h
)
qt4_wrap_cpp(EXTRA_GNUPG_SOURCES gpgop.h) add_library(qca-gnupg ${PLUGIN_TYPE} ${QCA_GNUPG_SOURCES} ${EXTRA_GNUPG_SOURCES} ${QCA_GNUPG_HEADERS})
qt4_wrap_cpp(EXTRA_GNUPG_SOURCES gpgop_p.h)
qt4_wrap_cpp(EXTRA_GNUPG_SOURCES gpgproc/gpgproc.h)
qt4_wrap_cpp(EXTRA_GNUPG_SOURCES gpgproc/gpgproc_p.h)
qt4_wrap_cpp(EXTRA_GNUPG_SOURCES gpgproc/sprocess.h)
qt4_wrap_cpp(EXTRA_GNUPG_SOURCES ringwatch.h)
qt4_wrap_cpp(EXTRA_GNUPG_SOURCES mykeystorelist.h)
qt4_wrap_cpp(EXTRA_GNUPG_SOURCES mymessagecontext.h)
qt4_wrap_cpp(EXTRA_GNUPG_SOURCES gpgaction.h)
add_library(qca-gnupg ${PLUGIN_TYPE} ${QCA_GNUPG_MOC_SOURCES} ${QCA_GNUPG_NONMOC_SOURCES} ${EXTRA_GNUPG_SOURCES})
if(APPLE AND ${PLUGIN_TYPE} STREQUAL "MODULE") if(APPLE AND ${PLUGIN_TYPE} STREQUAL "MODULE")
set_property(TARGET qca-gnupg PROPERTY SUFFIX ".dylib") set_property(TARGET qca-gnupg PROPERTY SUFFIX ".dylib")
endif() endif()
include_directories(gpgproc) include_directories(gpgproc)
target_link_libraries(qca-gnupg ${QT_QTCORE_LIBRARY} ${QCA_LIB_NAME}) if(QT6)
target_link_libraries(qca-gnupg Qt6::Core ${QCA_LIB_NAME})
else()
target_link_libraries(qca-gnupg Qt5::Core ${QCA_LIB_NAME})
endif()
if (WIN32) if (WIN32)
target_link_libraries(qca-gnupg advapi32) target_link_libraries(qca-gnupg advapi32)
endif (WIN32) endif()
if(NOT DEVELOPER_MODE) if(NOT DEVELOPER_MODE)
install(TARGETS qca-gnupg DESTINATION install(TARGETS qca-gnupg DESTINATION

View File

@ -32,15 +32,10 @@ static QDateTime getTimestamp(const QString &s)
if (s.isEmpty()) if (s.isEmpty())
return QDateTime(); return QDateTime();
if(s.contains('T')) if (s.contains(QLatin1Char('T'))) {
{
return QDateTime::fromString(s, Qt::ISODate); return QDateTime::fromString(s, Qt::ISODate);
} } else {
else return QDateTime::fromSecsSinceEpoch(s.toInt());
{
QDateTime dt;
dt.setTime_t(s.toInt());
return dt;
} }
} }
@ -49,37 +44,27 @@ static QByteArray getCString(const QByteArray &a)
QByteArray out; QByteArray out;
// convert the "backslash" C-string syntax // convert the "backslash" C-string syntax
for(int n = 0; n < a.size(); ++n) for (int n = 0; n < a.size(); ++n) {
{ if (a[n] == '\\' && n + 1 < a.size()) {
if(a[n] == '\\' && n + 1 < a.size())
{
++n; ++n;
unsigned char c = (unsigned char)a[n]; unsigned char c = (unsigned char)a[n];
if(c == '\\') if (c == '\\') {
{
out += '\\'; out += '\\';
} } else if (c == 'x' && n + 2 < a.size()) {
else if(c == 'x' && n + 2 < a.size())
{
++n; ++n;
QByteArray hex = a.mid(n, 2); const QByteArray hex = a.mid(n, 2);
++n; // only skip one, loop will skip the next ++n; // only skip one, loop will skip the next
bool ok; bool ok;
uint val = hex.toInt(&ok, 16); uint val = hex.toInt(&ok, 16);
if(ok) if (ok) {
{
out += (unsigned char)val; out += (unsigned char)val;
} } else {
else
{
out += "\\x"; out += "\\x";
out += hex; out += hex;
} }
} }
} } else {
else
{
out += a[n]; out += a[n];
} }
} }
@ -90,7 +75,7 @@ static QByteArray getCString(const QByteArray &a)
static bool stringToKeyList(const QString &outstr, GpgOp::KeyList *_keylist, QString *_keyring) static bool stringToKeyList(const QString &outstr, GpgOp::KeyList *_keylist, QString *_keyring)
{ {
GpgOp::KeyList keyList; GpgOp::KeyList keyList;
QStringList lines = outstr.split('\n'); const QStringList lines = outstr.split(QLatin1Char('\n'));
if (lines.count() < 1) if (lines.count() < 1)
return false; return false;
@ -103,22 +88,18 @@ static bool stringToKeyList(const QString &outstr, GpgOp::KeyList *_keylist, QSt
// if the second line isn't a divider, we are dealing // if the second line isn't a divider, we are dealing
// with a new version of gnupg that doesn't give us // with a new version of gnupg that doesn't give us
// the keyring file on gpg --list-keys --with-colons // the keyring file on gpg --list-keys --with-colons
if(it == lines.constEnd() || (*it).isEmpty() || (*it).at(0) != '-') if (it == lines.constEnd() || (*it).isEmpty() || (*it).at(0) != QLatin1Char('-')) {
{
// first line wasn't the keyring name... // first line wasn't the keyring name...
keyring.clear(); keyring.clear();
// ...so read the first line again // ...so read the first line again
it--; it--;
} } else {
else
{
// this was the divider line - skip it // this was the divider line - skip it
it++; it++;
} }
for(; it != lines.constEnd(); ++it) for (; it != lines.constEnd(); ++it) {
{ const QStringList f = (*it).split(QLatin1Char(':'));
QStringList f = (*it).split(':');
if (f.count() < 1) if (f.count() < 1)
continue; continue;
QString type = f[0]; QString type = f[0];
@ -127,40 +108,31 @@ static bool stringToKeyList(const QString &outstr, GpgOp::KeyList *_keylist, QSt
bool primary = false; // primary key or sub key bool primary = false; // primary key or sub key
// bool sec = false; // private key or not // bool sec = false; // private key or not
if(type == "pub") if (type == QLatin1String("pub")) {
{
key = true; key = true;
primary = true; primary = true;
} } else if (type == QLatin1String("sec")) {
else if(type == "sec")
{
key = true; key = true;
primary = true; primary = true;
// sec = true; // sec = true;
} } else if (type == QLatin1String("sub")) {
else if(type == "sub")
{
key = true; key = true;
} } else if (type == QLatin1String("ssb")) {
else if(type == "ssb")
{
key = true; key = true;
// sec = true; // sec = true;
} }
if(key) if (key) {
{ if (primary) {
if(primary)
{
keyList += GpgOp::Key(); keyList += GpgOp::Key();
QString trust = f[1]; QString trust = f[1];
if(trust == "f" || trust == "u") if (trust == QLatin1String("f") || trust == QLatin1String("u"))
keyList.last().isTrusted = true; keyList.last().isTrusted = true;
} }
int key_type = f[3].toInt(); const int key_type = f[3].toInt();
QString caps = f[11]; const QString caps = f[11];
GpgOp::KeyItem item; GpgOp::KeyItem item;
item.bits = f[2].toInt(); item.bits = f[2].toInt();
@ -175,24 +147,20 @@ static bool stringToKeyList(const QString &outstr, GpgOp::KeyList *_keylist, QSt
item.id = f[4]; item.id = f[4];
item.creationDate = getTimestamp(f[5]); item.creationDate = getTimestamp(f[5]);
item.expirationDate = getTimestamp(f[6]); item.expirationDate = getTimestamp(f[6]);
if(caps.contains('e')) if (caps.contains(QLatin1Char('e')))
item.caps |= GpgOp::KeyItem::Encrypt; item.caps |= GpgOp::KeyItem::Encrypt;
if(caps.contains('s')) if (caps.contains(QLatin1Char('s')))
item.caps |= GpgOp::KeyItem::Sign; item.caps |= GpgOp::KeyItem::Sign;
if(caps.contains('c')) if (caps.contains(QLatin1Char('c')))
item.caps |= GpgOp::KeyItem::Certify; item.caps |= GpgOp::KeyItem::Certify;
if(caps.contains('a')) if (caps.contains(QLatin1Char('a')))
item.caps |= GpgOp::KeyItem::Auth; item.caps |= GpgOp::KeyItem::Auth;
keyList.last().keyItems += item; keyList.last().keyItems += item;
} } else if (type == QLatin1String("uid")) {
else if(type == "uid") const QByteArray uid = getCString(f[9].toUtf8());
{
QByteArray uid = getCString(f[9].toUtf8());
keyList.last().userIds.append(QString::fromUtf8(uid)); keyList.last().userIds.append(QString::fromUtf8(uid));
} } else if (type == QLatin1String("fpr")) {
else if(type == "fpr")
{
QString s = f[9]; QString s = f[9];
keyList.last().keyItems.last().fingerprint = s; keyList.last().keyItems.last().fingerprint = s;
} }
@ -208,7 +176,7 @@ static bool stringToKeyList(const QString &outstr, GpgOp::KeyList *_keylist, QSt
static bool findKeyringFilename(const QString &outstr, QString *_keyring) static bool findKeyringFilename(const QString &outstr, QString *_keyring)
{ {
QStringList lines = outstr.split('\n'); const QStringList lines = outstr.split(QLatin1Char('\n'));
if (lines.count() < 1) if (lines.count() < 1)
return false; return false;
@ -220,19 +188,20 @@ GpgAction::GpgAction(QObject *parent)
: QObject(parent) : QObject(parent)
, proc(this) , proc(this)
, dtextTimer(this) , dtextTimer(this)
, utf8Output(false)
{ {
dtextTimer.setSingleShot(true); dtextTimer.setSingleShot(true);
connect(&proc, SIGNAL(error(gpgQCAPlugin::GPGProc::Error)), SLOT(proc_error(gpgQCAPlugin::GPGProc::Error))); connect(&proc, &GPGProc::error, this, &GpgAction::proc_error);
connect(&proc, SIGNAL(finished(int)), SLOT(proc_finished(int))); connect(&proc, &GPGProc::finished, this, &GpgAction::proc_finished);
connect(&proc, SIGNAL(readyReadStdout()), SLOT(proc_readyReadStdout())); connect(&proc, &GPGProc::readyReadStdout, this, &GpgAction::proc_readyReadStdout);
connect(&proc, SIGNAL(readyReadStderr()), SLOT(proc_readyReadStderr())); connect(&proc, &GPGProc::readyReadStderr, this, &GpgAction::proc_readyReadStderr);
connect(&proc, SIGNAL(readyReadStatusLines()), SLOT(proc_readyReadStatusLines())); connect(&proc, &GPGProc::readyReadStatusLines, this, &GpgAction::proc_readyReadStatusLines);
connect(&proc, SIGNAL(bytesWrittenStdin(int)), SLOT(proc_bytesWrittenStdin(int))); connect(&proc, &GPGProc::bytesWrittenStdin, this, &GpgAction::proc_bytesWrittenStdin);
connect(&proc, SIGNAL(bytesWrittenAux(int)), SLOT(proc_bytesWrittenAux(int))); connect(&proc, &GPGProc::bytesWrittenAux, this, &GpgAction::proc_bytesWrittenAux);
connect(&proc, SIGNAL(bytesWrittenCommand(int)), SLOT(proc_bytesWrittenCommand(int))); connect(&proc, &GPGProc::bytesWrittenCommand, this, &GpgAction::proc_bytesWrittenCommand);
connect(&proc, SIGNAL(debug(const QString &)), SLOT(proc_debug(const QString &))); connect(&proc, &GPGProc::debug, this, &GpgAction::proc_debug);
connect(&dtextTimer, SIGNAL(timeout()), SLOT(t_dtext())); connect(&dtextTimer, &QCA::SafeTimer::timeout, this, &GpgAction::t_dtext);
reset(); reset();
} }
@ -275,72 +244,77 @@ void GpgAction::start()
bool extra = false; bool extra = false;
if (input.opt_ascii) if (input.opt_ascii)
args += "--armor"; args += QStringLiteral("--armor");
if (input.opt_noagent) if (input.opt_noagent)
args += "--no-use-agent"; args += QStringLiteral("--no-use-agent");
if (input.opt_alwaystrust) if (input.opt_alwaystrust)
args += "--always-trust"; args += QStringLiteral("--always-trust");
if(!input.opt_pubfile.isEmpty() && !input.opt_secfile.isEmpty()) if (!input.opt_pubfile.isEmpty() && !input.opt_secfile.isEmpty()) {
{ args += QStringLiteral("--no-default-keyring");
args += "--no-default-keyring"; args += QStringLiteral("--keyring");
args += "--keyring";
args += input.opt_pubfile; args += input.opt_pubfile;
args += "--secret-keyring"; args += QStringLiteral("--secret-keyring");
args += input.opt_secfile; args += input.opt_secfile;
} }
switch(input.op) switch (input.op) {
{
case GpgOp::Check: case GpgOp::Check:
{ {
args += "--version"; args += QStringLiteral("--version");
readText = true; readText = true;
break; break;
} }
case GpgOp::SecretKeyringFile: case GpgOp::SecretKeyringFile:
{ {
args += "--list-secret-keys"; #ifndef Q_OS_WIN
args += QStringLiteral("--display-charset=utf-8");
#endif
args += QStringLiteral("--list-secret-keys");
readText = true; readText = true;
break; break;
} }
case GpgOp::PublicKeyringFile: case GpgOp::PublicKeyringFile:
{ {
args += "--list-public-keys"; #ifndef Q_OS_WIN
args += QStringLiteral("--display-charset=utf-8");
#endif
args += QStringLiteral("--list-public-keys");
readText = true; readText = true;
break; break;
} }
case GpgOp::SecretKeys: case GpgOp::SecretKeys:
{ {
args += "--fixed-list-mode"; args += QStringLiteral("--fixed-list-mode");
args += "--with-colons"; args += QStringLiteral("--with-colons");
args += "--with-fingerprint"; args += QStringLiteral("--with-fingerprint");
args += "--with-fingerprint"; args += QStringLiteral("--with-fingerprint");
args += "--list-secret-keys"; args += QStringLiteral("--list-secret-keys");
utf8Output = true;
readText = true; readText = true;
break; break;
} }
case GpgOp::PublicKeys: case GpgOp::PublicKeys:
{ {
args += "--fixed-list-mode"; args += QStringLiteral("--fixed-list-mode");
args += "--with-colons"; args += QStringLiteral("--with-colons");
args += "--with-fingerprint"; args += QStringLiteral("--with-fingerprint");
args += "--with-fingerprint"; args += QStringLiteral("--with-fingerprint");
args += "--list-public-keys"; args += QStringLiteral("--list-public-keys");
utf8Output = true;
readText = true; readText = true;
break; break;
} }
case GpgOp::Encrypt: case GpgOp::Encrypt:
{ {
args += "--encrypt"; args += QStringLiteral("--encrypt");
// recipients // recipients
for(QStringList::ConstIterator it = input.recip_ids.constBegin(); it != input.recip_ids.constEnd(); ++it) for (QStringList::ConstIterator it = input.recip_ids.constBegin(); it != input.recip_ids.constEnd(); ++it) {
{ args += QStringLiteral("--recipient");
args += "--recipient"; args += QStringLiteral("0x") + *it;
args += QString("0x") + *it;
} }
extra = true; extra = true;
collectOutput = false; collectOutput = false;
@ -351,7 +325,7 @@ void GpgAction::start()
} }
case GpgOp::Decrypt: case GpgOp::Decrypt:
{ {
args += "--decrypt"; args += QStringLiteral("--decrypt");
extra = true; extra = true;
collectOutput = false; collectOutput = false;
allowInput = true; allowInput = true;
@ -361,9 +335,9 @@ void GpgAction::start()
} }
case GpgOp::Sign: case GpgOp::Sign:
{ {
args += "--default-key"; args += QStringLiteral("--default-key");
args += QString("0x") + input.signer_id; args += QStringLiteral("0x") + input.signer_id;
args += "--sign"; args += QStringLiteral("--sign");
extra = true; extra = true;
collectOutput = false; collectOutput = false;
allowInput = true; allowInput = true;
@ -374,16 +348,15 @@ void GpgAction::start()
} }
case GpgOp::SignAndEncrypt: case GpgOp::SignAndEncrypt:
{ {
args += "--default-key"; args += QStringLiteral("--default-key");
args += QString("0x") + input.signer_id; args += QStringLiteral("0x") + input.signer_id;
args += "--sign"; args += QStringLiteral("--sign");
args += "--encrypt"; args += QStringLiteral("--encrypt");
// recipients // recipients
for(QStringList::ConstIterator it = input.recip_ids.constBegin(); it != input.recip_ids.constEnd(); ++it) for (QStringList::ConstIterator it = input.recip_ids.constBegin(); it != input.recip_ids.constEnd(); ++it) {
{ args += QStringLiteral("--recipient");
args += "--recipient"; args += QStringLiteral("0x") + *it;
args += QString("0x") + *it;
} }
extra = true; extra = true;
collectOutput = false; collectOutput = false;
@ -395,9 +368,9 @@ void GpgAction::start()
} }
case GpgOp::SignClearsign: case GpgOp::SignClearsign:
{ {
args += "--default-key"; args += QStringLiteral("--default-key");
args += QString("0x") + input.signer_id; args += QStringLiteral("0x") + input.signer_id;
args += "--clearsign"; args += QStringLiteral("--clearsign");
extra = true; extra = true;
collectOutput = false; collectOutput = false;
allowInput = true; allowInput = true;
@ -408,9 +381,9 @@ void GpgAction::start()
} }
case GpgOp::SignDetached: case GpgOp::SignDetached:
{ {
args += "--default-key"; args += QStringLiteral("--default-key");
args += QString("0x") + input.signer_id; args += QStringLiteral("0x") + input.signer_id;
args += "--detach-sign"; args += QStringLiteral("--detach-sign");
extra = true; extra = true;
collectOutput = false; collectOutput = false;
allowInput = true; allowInput = true;
@ -421,8 +394,8 @@ void GpgAction::start()
} }
case GpgOp::Verify: case GpgOp::Verify:
{ {
args += "--verify"; args += QStringLiteral("--verify");
args += "-"; //krazy:exclude=doublequote_chars args += QStringLiteral("-"); // krazy:exclude=doublequote_chars
extra = true; extra = true;
allowInput = true; allowInput = true;
if (input.opt_ascii) if (input.opt_ascii)
@ -431,9 +404,9 @@ void GpgAction::start()
} }
case GpgOp::VerifyDetached: case GpgOp::VerifyDetached:
{ {
args += "--verify"; args += QStringLiteral("--verify");
args += "-"; //krazy:exclude=doublequote_chars args += QStringLiteral("-"); // krazy:exclude=doublequote_chars
args += "-&?"; args += QStringLiteral("-&?");
extra = true; extra = true;
allowInput = true; allowInput = true;
useAux = true; useAux = true;
@ -441,7 +414,7 @@ void GpgAction::start()
} }
case GpgOp::Import: case GpgOp::Import:
{ {
args += "--import"; args += QStringLiteral("--import");
readText = true; readText = true;
if (input.opt_ascii) if (input.opt_ascii)
writeText = true; writeText = true;
@ -449,8 +422,8 @@ void GpgAction::start()
} }
case GpgOp::Export: case GpgOp::Export:
{ {
args += "--export"; args += QStringLiteral("--export");
args += QString("0x") + input.export_key_id; args += QStringLiteral("0x") + input.export_key_id;
collectOutput = false; collectOutput = false;
if (input.opt_ascii) if (input.opt_ascii)
readText = true; readText = true;
@ -458,9 +431,9 @@ void GpgAction::start()
} }
case GpgOp::DeleteKey: case GpgOp::DeleteKey:
{ {
args += "--batch"; args += QStringLiteral("--batch");
args += "--delete-key"; args += QStringLiteral("--delete-key");
args += QString("0x") + input.delete_key_fingerprint; args += QStringLiteral("0x") + input.delete_key_fingerprint;
break; break;
} }
} }
@ -472,11 +445,9 @@ void GpgAction::start()
proc.start(input.bin, args, extra ? GPGProc::ExtendedMode : GPGProc::NormalMode); proc.start(input.bin, args, extra ? GPGProc::ExtendedMode : GPGProc::NormalMode);
// detached sig // detached sig
if(input.op == GpgOp::VerifyDetached) if (input.op == GpgOp::VerifyDetached) {
{
QByteArray a = input.sig; QByteArray a = input.sig;
if(input.opt_ascii) if (input.opt_ascii) {
{
LineConverter conv; LineConverter conv;
conv.setup(LineConverter::Write); conv.setup(LineConverter::Write);
a = conv.process(a); a = conv.process(a);
@ -486,11 +457,9 @@ void GpgAction::start()
} }
// import // import
if(input.op == GpgOp::Import) if (input.op == GpgOp::Import) {
{
QByteArray a = input.inkey; QByteArray a = input.inkey;
if(writeText) if (writeText) {
{
LineConverter conv; LineConverter conv;
conv.setup(LineConverter::Write); conv.setup(LineConverter::Write);
a = conv.process(a); a = conv.process(a);
@ -520,8 +489,7 @@ void GpgAction::submitPassphrase(const QCA::SecureArray &a)
// to indicate a submitted passphrase // to indicate a submitted passphrase
b.resize(a.size()); b.resize(a.size());
int at = 0; int at = 0;
for(int n = 0; n < a.size(); ++n) for (int n = 0; n < a.size(); ++n) {
{
if (a[n] != '\n') if (a[n] != '\n')
b[at++] = a[n]; b[at++] = a[n];
} }
@ -574,8 +542,7 @@ void GpgAction::endWrite()
void GpgAction::cardOkay() void GpgAction::cardOkay()
{ {
if(need_cardOkay) if (need_cardOkay) {
{
need_cardOkay = false; need_cardOkay = false;
submitCommand("\n"); submitCommand("\n");
} }
@ -596,16 +563,12 @@ void GpgAction::submitCommand(const QByteArray &a)
// since str is taken as a value, it is ok to use the same variable for 'rest' // since str is taken as a value, it is ok to use the same variable for 'rest'
QString GpgAction::nextArg(QString str, QString *rest) QString GpgAction::nextArg(QString str, QString *rest)
{ {
QString out; int n = str.indexOf(QLatin1Char(' '));
int n = str.indexOf(' '); if (n == -1) {
if(n == -1)
{
if (rest) if (rest)
*rest = QString(); *rest = QString();
return str; return str;
} } else {
else
{
if (rest) if (rest)
*rest = str.mid(n + 1); *rest = str.mid(n + 1);
return str.mid(0, n); return str.mid(0, n);
@ -614,7 +577,7 @@ QString GpgAction::nextArg(QString str, QString *rest)
void GpgAction::processStatusLine(const QString &line) void GpgAction::processStatusLine(const QString &line)
{ {
appendDiagnosticText("{" + line + "}"); appendDiagnosticText(QStringLiteral("{") + line + QStringLiteral("}"));
ensureDTextEmit(); ensureDTextEmit();
if (!proc.isActive()) if (!proc.isActive())
@ -623,35 +586,23 @@ void GpgAction::processStatusLine(const QString &line)
QString s, rest; QString s, rest;
s = nextArg(line, &rest); s = nextArg(line, &rest);
if(s == "NODATA") if (s == QLatin1String("NODATA")) {
{
// only set this if it'll make it better // only set this if it'll make it better
if (curError == GpgOp::ErrorUnknown) if (curError == GpgOp::ErrorUnknown)
curError = GpgOp::ErrorFormat; curError = GpgOp::ErrorFormat;
} } else if (s == QLatin1String("UNEXPECTED")) {
else if(s == "UNEXPECTED")
{
if (curError == GpgOp::ErrorUnknown) if (curError == GpgOp::ErrorUnknown)
curError = GpgOp::ErrorFormat; curError = GpgOp::ErrorFormat;
} } else if (s == QLatin1String("EXPKEYSIG")) {
else if(s == "EXPKEYSIG")
{
curError = GpgOp::ErrorSignerExpired; curError = GpgOp::ErrorSignerExpired;
} } else if (s == QLatin1String("REVKEYSIG")) {
else if(s == "REVKEYSIG")
{
curError = GpgOp::ErrorSignerRevoked; curError = GpgOp::ErrorSignerRevoked;
} } else if (s == QLatin1String("EXPSIG")) {
else if(s == "EXPSIG")
{
curError = GpgOp::ErrorSignatureExpired; curError = GpgOp::ErrorSignatureExpired;
} } else if (s == QLatin1String("INV_RECP")) {
else if(s == "INV_RECP") const int r = nextArg(rest).toInt();
{
int r = nextArg(rest).toInt();
if(curError == GpgOp::ErrorUnknown) if (curError == GpgOp::ErrorUnknown) {
{
if (r == 10) if (r == 10)
curError = GpgOp::ErrorEncryptUntrusted; curError = GpgOp::ErrorEncryptUntrusted;
else if (r == 4) else if (r == 4)
@ -666,88 +617,60 @@ void GpgAction::processStatusLine(const QString &line)
// defaulting to this // defaulting to this
curError = GpgOp::ErrorEncryptInvalid; curError = GpgOp::ErrorEncryptInvalid;
} }
} } else if (s == QLatin1String("NO_SECKEY")) {
else if(s == "NO_SECKEY")
{
output.encryptedToId = nextArg(rest); output.encryptedToId = nextArg(rest);
if (curError == GpgOp::ErrorUnknown) if (curError == GpgOp::ErrorUnknown)
curError = GpgOp::ErrorDecryptNoKey; curError = GpgOp::ErrorDecryptNoKey;
} } else if (s == QLatin1String("DECRYPTION_OKAY")) {
else if(s == "DECRYPTION_OKAY")
{
decryptGood = true; decryptGood = true;
// message could be encrypted with several keys // message could be encrypted with several keys
if (curError == GpgOp::ErrorDecryptNoKey) if (curError == GpgOp::ErrorDecryptNoKey)
curError = GpgOp::ErrorUnknown; curError = GpgOp::ErrorUnknown;
} } else if (s == QLatin1String("SIG_CREATED")) {
else if(s == "SIG_CREATED")
{
signGood = true; signGood = true;
} } else if (s == QLatin1String("USERID_HINT")) {
else if(s == "USERID_HINT")
{
passphraseKeyId = nextArg(rest); passphraseKeyId = nextArg(rest);
} } else if (s == QLatin1String("GET_HIDDEN")) {
else if(s == "GET_HIDDEN")
{
QString arg = nextArg(rest); QString arg = nextArg(rest);
if(arg == "passphrase.enter" || arg == "passphrase.pin.ask") if (arg == QLatin1String("passphrase.enter") || arg == QLatin1String("passphrase.pin.ask")) {
{
need_submitPassphrase = true; need_submitPassphrase = true;
// for signal-safety, emit later // for signal-safety, emit later
QMetaObject::invokeMethod(this, "needPassphrase", Qt::QueuedConnection, Q_ARG(QString, passphraseKeyId)); QMetaObject::invokeMethod(this, "needPassphrase", Qt::QueuedConnection, Q_ARG(QString, passphraseKeyId));
} }
} } else if (s == QLatin1String("GET_LINE")) {
else if(s == "GET_LINE")
{
QString arg = nextArg(rest); QString arg = nextArg(rest);
if(arg == "cardctrl.insert_card.okay") if (arg == QLatin1String("cardctrl.insert_card.okay")) {
{
need_cardOkay = true; need_cardOkay = true;
QMetaObject::invokeMethod(this, "needCard", Qt::QueuedConnection); QMetaObject::invokeMethod(this, "needCard", Qt::QueuedConnection);
} }
} } else if (s == QLatin1String("GET_BOOL")) {
else if(s == "GET_BOOL")
{
QString arg = nextArg(rest); QString arg = nextArg(rest);
if(arg == "untrusted_key.override") if (arg == QLatin1String("untrusted_key.override"))
submitCommand("no\n"); submitCommand("no\n");
} } else if (s == QLatin1String("GOOD_PASSPHRASE")) {
else if(s == "GOOD_PASSPHRASE")
{
badPassphrase = false; badPassphrase = false;
} } else if (s == QLatin1String("BAD_PASSPHRASE")) {
else if(s == "BAD_PASSPHRASE")
{
badPassphrase = true; badPassphrase = true;
} } else if (s == QLatin1String("GOODSIG")) {
else if(s == "GOODSIG")
{
output.wasSigned = true; output.wasSigned = true;
output.signerId = nextArg(rest); output.signerId = nextArg(rest);
output.verifyResult = GpgOp::VerifyGood; output.verifyResult = GpgOp::VerifyGood;
} } else if (s == QLatin1String("BADSIG")) {
else if(s == "BADSIG")
{
output.wasSigned = true; output.wasSigned = true;
output.signerId = nextArg(rest); output.signerId = nextArg(rest);
output.verifyResult = GpgOp::VerifyBad; output.verifyResult = GpgOp::VerifyBad;
} } else if (s == QLatin1String("ERRSIG")) {
else if(s == "ERRSIG")
{
output.wasSigned = true; output.wasSigned = true;
QStringList list = rest.split(' ', QString::SkipEmptyParts); const QStringList list = rest.split(QLatin1Char(' '), Qt::SkipEmptyParts);
output.signerId = list[0]; output.signerId = list[0];
output.timestamp = getTimestamp(list[4]); output.timestamp = getTimestamp(list[4]);
output.verifyResult = GpgOp::VerifyNoKey; output.verifyResult = GpgOp::VerifyNoKey;
} } else if (s == QLatin1String("VALIDSIG")) {
else if(s == "VALIDSIG") const QStringList list = rest.split(QLatin1Char(' '), Qt::SkipEmptyParts);
{
QStringList list = rest.split(' ', QString::SkipEmptyParts);
output.timestamp = getTimestamp(list[2]); output.timestamp = getTimestamp(list[2]);
} }
} }
@ -760,45 +683,50 @@ void GpgAction::processResult(int code)
// put stdout and stderr into QStrings // put stdout and stderr into QStrings
// FIXME: on Windows gpg returns --with-colons in QString outstr;
// utf-8 charset but for -k or -K it uses QString errstr;
// console output charset (which may will be differs
// then system charse). Will be wait a resolving of #ifdef Q_OS_WIN
// QTBUG-13303 https://bugreports.qt-project.org/browse/QTBUG-13303 if (!utf8Output) {
// After it need to make some changes. outstr = QString::fromLocal8Bit(buf_stdout);
QString outstr = QString::fromUtf8(buf_stdout); errstr = QString::fromLocal8Bit(buf_stderr);
QString errstr = QString::fromUtf8(buf_stderr); } else {
#endif
outstr = QString::fromUtf8(buf_stdout);
errstr = QString::fromUtf8(buf_stderr);
#ifdef Q_OS_WIN
}
#endif
if (collectOutput) if (collectOutput)
appendDiagnosticText(QString("stdout: [%1]").arg(outstr)); appendDiagnosticText(QStringLiteral("stdout: [%1]").arg(outstr));
appendDiagnosticText(QString("stderr: [%1]").arg(errstr)); appendDiagnosticText(QStringLiteral("stderr: [%1]").arg(errstr));
ensureDTextEmit(); ensureDTextEmit();
if(badPassphrase) if (badPassphrase) {
{
output.errorCode = GpgOp::ErrorPassphrase; output.errorCode = GpgOp::ErrorPassphrase;
} } else if (curError != GpgOp::ErrorUnknown) {
else if(curError != GpgOp::ErrorUnknown)
{
output.errorCode = curError; output.errorCode = curError;
} else if (code == 0) {
if (input.op == GpgOp::Check) {
const QStringList strList = outstr.split(QStringLiteral("\n"));
foreach (const QString &str, strList) {
if (!str.startsWith(QLatin1String("Home: ")))
continue;
output.homeDir = str.section(QLatin1Char(' '), 1);
break;
} }
else if(code == 0) output.success = true;
{ } else if (input.op == GpgOp::SecretKeyringFile || input.op == GpgOp::PublicKeyringFile) {
if(input.op == GpgOp::SecretKeyringFile || input.op == GpgOp::PublicKeyringFile)
{
if (findKeyringFilename(outstr, &output.keyringFile)) if (findKeyringFilename(outstr, &output.keyringFile))
output.success = true; output.success = true;
} } else if (input.op == GpgOp::SecretKeys || input.op == GpgOp::PublicKeys) {
else if(input.op == GpgOp::SecretKeys || input.op == GpgOp::PublicKeys)
{
if (stringToKeyList(outstr, &output.keys, &output.keyringFile)) if (stringToKeyList(outstr, &output.keys, &output.keyringFile))
output.success = true; output.success = true;
} } else
else
output.success = true; output.success = true;
} } else {
else
{
// decrypt and sign success based on status only. // decrypt and sign success based on status only.
// this is mainly because gpg uses fatal return // this is mainly because gpg uses fatal return
// values if there is trouble with gpg-agent, even // values if there is trouble with gpg-agent, even
@ -838,13 +766,13 @@ void GpgAction::proc_error(gpgQCAPlugin::GPGProc::Error e)
{ {
QString str; QString str;
if (e == GPGProc::FailedToStart) if (e == GPGProc::FailedToStart)
str = "FailedToStart"; str = QStringLiteral("FailedToStart");
else if (e == GPGProc::UnexpectedExit) else if (e == GPGProc::UnexpectedExit)
str = "UnexpectedExit"; str = QStringLiteral("UnexpectedExit");
else if (e == GPGProc::ErrorWrite) else if (e == GPGProc::ErrorWrite)
str = "ErrorWrite"; str = QStringLiteral("ErrorWrite");
appendDiagnosticText(QString("GPG Process Error: %1").arg(str)); appendDiagnosticText(QStringLiteral("GPG Process Error: %1").arg(str));
ensureDTextEmit(); ensureDTextEmit();
output.errorCode = GpgOp::ErrorProcess; output.errorCode = GpgOp::ErrorProcess;
@ -853,7 +781,7 @@ void GpgAction::proc_error(gpgQCAPlugin::GPGProc::Error e)
void GpgAction::proc_finished(int exitCode) void GpgAction::proc_finished(int exitCode)
{ {
appendDiagnosticText(QString("GPG Process Finished: exitStatus=%1").arg(exitCode)); appendDiagnosticText(QStringLiteral("GPG Process Finished: exitStatus=%1").arg(exitCode));
ensureDTextEmit(); ensureDTextEmit();
processResult(exitCode); processResult(exitCode);
@ -861,14 +789,12 @@ void GpgAction::proc_finished(int exitCode)
void GpgAction::proc_readyReadStdout() void GpgAction::proc_readyReadStdout()
{ {
if(collectOutput) if (collectOutput) {
{
QByteArray a = proc.readStdout(); QByteArray a = proc.readStdout();
if (readText) if (readText)
a = readConv.update(a); a = readConv.update(a);
buf_stdout.append(a); buf_stdout.append(a);
} } else
else
emit readyRead(); emit readyRead();
} }
@ -879,15 +805,14 @@ void GpgAction::proc_readyReadStderr()
void GpgAction::proc_readyReadStatusLines() void GpgAction::proc_readyReadStatusLines()
{ {
QStringList lines = proc.readStatusLines(); const QStringList lines = proc.readStatusLines();
for (int n = 0; n < lines.count(); ++n) for (int n = 0; n < lines.count(); ++n)
processStatusLine(lines[n]); processStatusLine(lines[n]);
} }
void GpgAction::proc_bytesWrittenStdin(int bytes) void GpgAction::proc_bytesWrittenStdin(int bytes)
{ {
if(!useAux) if (!useAux) {
{
int actual = writeConv.writtenToActual(bytes); int actual = writeConv.writtenToActual(bytes);
emit bytesWritten(actual); emit bytesWritten(actual);
} }
@ -895,8 +820,7 @@ void GpgAction::proc_bytesWrittenStdin(int bytes)
void GpgAction::proc_bytesWrittenAux(int bytes) void GpgAction::proc_bytesWrittenAux(int bytes)
{ {
if(useAux) if (useAux) {
{
int actual = writeConv.writtenToActual(bytes); int actual = writeConv.writtenToActual(bytes);
emit bytesWritten(actual); emit bytesWritten(actual);
} }
@ -909,7 +833,7 @@ void GpgAction::proc_bytesWrittenCommand(int)
void GpgAction::proc_debug(const QString &str) void GpgAction::proc_debug(const QString &str)
{ {
appendDiagnosticText("GPGProc: " + str); appendDiagnosticText(QStringLiteral("GPGProc: ") + str);
ensureDTextEmit(); ensureDTextEmit();
} }

View File

@ -19,13 +19,13 @@
#pragma once #pragma once
#include "lineconverter.h"
#include "qca_safetimer.h"
#include "gpgop.h" #include "gpgop.h"
#include "gpgproc.h" #include "gpgproc.h"
#include "lineconverter.h"
#include "qca_safetimer.h"
#include <QByteArray>
#include <QObject> #include <QObject>
#include <QStringList> #include <QStringList>
#include <QByteArray>
#ifdef GPG_PROFILE #ifdef GPG_PROFILE
#include <QTime> #include <QTime>
@ -50,7 +50,12 @@ public:
QString export_key_id; QString export_key_id;
QString delete_key_fingerprint; QString delete_key_fingerprint;
Input() : opt_ascii(false), opt_noagent(false), opt_alwaystrust(false) {} Input()
: opt_ascii(false)
, opt_noagent(false)
, opt_alwaystrust(false)
{
}
}; };
struct Output struct Output
@ -64,15 +69,21 @@ public:
QString signerId; QString signerId;
QDateTime timestamp; QDateTime timestamp;
GpgOp::VerifyResult verifyResult; GpgOp::VerifyResult verifyResult;
QString homeDir;
Output() : success(false), errorCode(GpgOp::ErrorUnknown), wasSigned(false) {} Output()
: success(false)
, errorCode(GpgOp::ErrorUnknown)
, wasSigned(false)
{
}
}; };
Input input; Input input;
Output output; Output output;
GpgAction(QObject *parent = 0); GpgAction(QObject *parent = nullptr);
~GpgAction(); ~GpgAction() override;
void reset(); void reset();
void start(); void start();
#ifdef QPIPE_SECURE #ifdef QPIPE_SECURE
@ -81,14 +92,14 @@ public:
void submitPassphrase(const QByteArray &a); void submitPassphrase(const QByteArray &a);
#endif #endif
public slots: public Q_SLOTS:
QByteArray read(); QByteArray read();
void write(const QByteArray &in); void write(const QByteArray &in);
void endWrite(); void endWrite();
void cardOkay(); void cardOkay();
QString readDiagnosticText(); QString readDiagnosticText();
signals: Q_SIGNALS:
void readyRead(); void readyRead();
void bytesWritten(int bytes); void bytesWritten(int bytes);
void finished(); void finished();
@ -100,7 +111,7 @@ private:
void submitCommand(const QByteArray &a); void submitCommand(const QByteArray &a);
// since str is taken as a value, it is ok to use the same variable for 'rest' // since str is taken as a value, it is ok to use the same variable for 'rest'
QString nextArg(QString str, QString *rest = 0); QString nextArg(QString str, QString *rest = nullptr);
void processStatusLine(const QString &line); void processStatusLine(const QString &line);
void processResult(int code); void processResult(int code);
void ensureDTextEmit(); void ensureDTextEmit();
@ -118,12 +129,13 @@ private:
bool need_submitPassphrase, need_cardOkay; bool need_submitPassphrase, need_cardOkay;
QString diagnosticText; QString diagnosticText;
QCA::SafeTimer dtextTimer; QCA::SafeTimer dtextTimer;
bool utf8Output;
#ifdef GPG_PROFILE #ifdef GPG_PROFILE
QTime timer; QTime timer;
#endif #endif
private slots: private Q_SLOTS:
void t_dtext(); void t_dtext();
void proc_error(gpgQCAPlugin::GPGProc::Error e); void proc_error(gpgQCAPlugin::GPGProc::Error e);
void proc_finished(int exitCode); void proc_finished(int exitCode);
@ -137,5 +149,4 @@ private slots:
void appendDiagnosticText(const QString &line); void appendDiagnosticText(const QString &line);
}; };
} // end namespace gpgQCAPlugin } // end namespace gpgQCAPlugin

View File

@ -17,9 +17,9 @@
* *
*/ */
#include "gpgop_p.h"
#include "gpgop.h" #include "gpgop.h"
#include "gpgaction.h" #include "gpgaction.h"
#include "gpgop_p.h"
namespace gpgQCAPlugin { namespace gpgQCAPlugin {
@ -30,7 +30,7 @@ GpgOp::Private::Private(GpgOp *_q)
: QObject(_q) : QObject(_q)
, sync(_q) , sync(_q)
, q(_q) , q(_q)
, act(0) , act(nullptr)
, waiting(false) , waiting(false)
{ {
reset(ResetAll); reset(ResetAll);
@ -43,25 +43,22 @@ GpgOp::Private::~Private()
void GpgOp::Private::reset(ResetMode mode) void GpgOp::Private::reset(ResetMode mode)
{ {
if(act) if (act) {
{
act->disconnect(this); act->disconnect(this);
act->setParent(0); act->setParent(nullptr);
act->deleteLater(); act->deleteLater();
act = 0; act = nullptr;
} }
if(mode >= ResetSessionAndData) if (mode >= ResetSessionAndData) {
{
output = GpgAction::Output(); output = GpgAction::Output();
result.clear(); result.clear();
diagnosticText = QString(); diagnosticText = QString();
eventList.clear(); eventList.clear();
} }
if(mode >= ResetAll) if (mode >= ResetAll) {
{
opt_ascii = false; opt_ascii = false;
opt_noagent = false; opt_noagent = false;
opt_alwaystrust = false; opt_alwaystrust = false;
@ -78,12 +75,12 @@ void GpgOp::Private::make_act(GpgOp::Type _op)
act = new GpgAction(this); act = new GpgAction(this);
connect(act, SIGNAL(readyRead()), SLOT(act_readyRead())); connect(act, &GpgAction::readyRead, this, &GpgOp::Private::act_readyRead);
connect(act, SIGNAL(bytesWritten(int)), SLOT(act_bytesWritten(int))); connect(act, &GpgAction::bytesWritten, this, &GpgOp::Private::act_bytesWritten);
connect(act, SIGNAL(needPassphrase(const QString &)), SLOT(act_needPassphrase(const QString &))); connect(act, &GpgAction::needPassphrase, this, &GpgOp::Private::act_needPassphrase);
connect(act, SIGNAL(needCard()), SLOT(act_needCard())); connect(act, &GpgAction::needCard, this, &GpgOp::Private::act_needCard);
connect(act, SIGNAL(finished()), SLOT(act_finished())); connect(act, &GpgAction::finished, this, &GpgOp::Private::act_finished);
connect(act, SIGNAL(readyReadDiagnosticText()), SLOT(act_readyReadDiagnosticText())); connect(act, &GpgAction::readyReadDiagnosticText, this, &GpgOp::Private::act_readyReadDiagnosticText);
act->input.bin = bin; act->input.bin = bin;
act->input.op = op; act->input.op = op;
@ -157,7 +154,7 @@ void GpgOp::Private::act_needCard()
void GpgOp::Private::act_readyReadDiagnosticText() void GpgOp::Private::act_readyReadDiagnosticText()
{ {
QString s = act->readDiagnosticText(); const QString s = act->readDiagnosticText();
// printf("dtext ready: [%s]\n", qPrintable(s)); // printf("dtext ready: [%s]\n", qPrintable(s));
diagnosticText += s; diagnosticText += s;
@ -179,30 +176,29 @@ void GpgOp::Private::act_finished()
output = act->output; output = act->output;
QMap<int, QString> errmap; QMap<int, QString> errmap;
errmap[GpgOp::ErrorProcess] = "ErrorProcess"; errmap[GpgOp::ErrorProcess] = QStringLiteral("ErrorProcess");
errmap[GpgOp::ErrorPassphrase] = "ErrorPassphrase"; errmap[GpgOp::ErrorPassphrase] = QStringLiteral("ErrorPassphrase");
errmap[GpgOp::ErrorFormat] = "ErrorFormat"; errmap[GpgOp::ErrorFormat] = QStringLiteral("ErrorFormat");
errmap[GpgOp::ErrorSignerExpired] = "ErrorSignerExpired"; errmap[GpgOp::ErrorSignerExpired] = QStringLiteral("ErrorSignerExpired");
errmap[GpgOp::ErrorEncryptExpired] = "ErrorEncryptExpired"; errmap[GpgOp::ErrorEncryptExpired] = QStringLiteral("ErrorEncryptExpired");
errmap[GpgOp::ErrorEncryptUntrusted] = "ErrorEncryptUntrusted"; errmap[GpgOp::ErrorEncryptUntrusted] = QStringLiteral("ErrorEncryptUntrusted");
errmap[GpgOp::ErrorEncryptInvalid] = "ErrorEncryptInvalid"; errmap[GpgOp::ErrorEncryptInvalid] = QStringLiteral("ErrorEncryptInvalid");
errmap[GpgOp::ErrorDecryptNoKey] = "ErrorDecryptNoKey"; errmap[GpgOp::ErrorDecryptNoKey] = QStringLiteral("ErrorDecryptNoKey");
errmap[GpgOp::ErrorUnknown] = "ErrorUnknown"; errmap[GpgOp::ErrorUnknown] = QStringLiteral("ErrorUnknown");
if (output.success) if (output.success)
diagnosticText += "GpgAction success\n"; diagnosticText += QStringLiteral("GpgAction success\n");
else else
diagnosticText += QString("GpgAction error: %1\n").arg(errmap[output.errorCode]); diagnosticText += QStringLiteral("GpgAction error: %1\n").arg(errmap[output.errorCode]);
if(output.wasSigned) if (output.wasSigned) {
{
QString s; QString s;
if (output.verifyResult == GpgOp::VerifyGood) if (output.verifyResult == GpgOp::VerifyGood)
s = "VerifyGood"; s = QStringLiteral("VerifyGood");
else if (output.verifyResult == GpgOp::VerifyBad) else if (output.verifyResult == GpgOp::VerifyBad)
s = "VerifyBad"; s = QStringLiteral("VerifyBad");
else else
s = "VerifyNoKey"; s = QStringLiteral("VerifyNoKey");
diagnosticText += QString("wasSigned: verifyResult: %1\n").arg(s); diagnosticText += QStringLiteral("wasSigned: verifyResult: %1\n").arg(s);
} }
// printf("diagnosticText:\n%s", qPrintable(diagnosticText)); // printf("diagnosticText:\n%s", qPrintable(diagnosticText));
@ -390,13 +386,10 @@ void GpgOp::cardOkay()
QByteArray GpgOp::read() QByteArray GpgOp::read()
{ {
if(d->act) if (d->act) {
{
return d->act->read(); return d->act->read();
} } else {
else const QByteArray a = d->result;
{
QByteArray a = d->result;
d->result.clear(); d->result.clear();
return a; return a;
} }
@ -456,6 +449,11 @@ QString GpgOp::keyringFile() const
return d->output.keyringFile; return d->output.keyringFile;
} }
QString GpgOp::homeDir() const
{
return d->output.homeDir;
}
QString GpgOp::encryptedToId() const QString GpgOp::encryptedToId() const
{ {
return d->output.encryptedToId; return d->output.encryptedToId;

View File

@ -20,8 +20,8 @@
#ifndef GPGOP_H #ifndef GPGOP_H
#define GPGOP_H #define GPGOP_H
#include <QtCrypto>
#include "qpipe.h" #include "qpipe.h"
#include <QtCrypto>
namespace gpgQCAPlugin { namespace gpgQCAPlugin {
@ -90,7 +90,11 @@ public:
int written; // BytesWritten int written; // BytesWritten
QString keyId; // NeedPassphrase QString keyId; // NeedPassphrase
Event() : type(None), written(0) {} Event()
: type(None)
, written(0)
{
}
}; };
class KeyItem class KeyItem
@ -120,7 +124,12 @@ public:
int caps; // flags OR'd together int caps; // flags OR'd together
QString fingerprint; QString fingerprint;
KeyItem() : type(Unknown), bits(0), caps(0) {} KeyItem()
: type(Unknown)
, bits(0)
, caps(0)
{
}
}; };
class Key class Key
@ -130,12 +139,15 @@ public:
QStringList userIds; QStringList userIds;
bool isTrusted; bool isTrusted;
Key() : isTrusted(false) {} Key()
: isTrusted(false)
{
}
}; };
typedef QList<Key> KeyList; typedef QList<Key> KeyList;
explicit GpgOp(const QString &bin, QObject *parent = 0); explicit GpgOp(const QString &bin, QObject *parent = nullptr);
~GpgOp(); ~GpgOp() override;
void reset(); void reset();
@ -186,6 +198,7 @@ public:
Error errorCode() const; Error errorCode() const;
KeyList keys() const; // Keys KeyList keys() const; // Keys
QString keyringFile() const; // KeyringFile QString keyringFile() const; // KeyringFile
QString homeDir() const; // GnuPG home directory
QString encryptedToId() const; // Decrypt (for ErrorDecryptNoKey) QString encryptedToId() const; // Decrypt (for ErrorDecryptNoKey)
bool wasSigned() const; // Decrypt bool wasSigned() const; // Decrypt
QString signerId() const; // Verify QString signerId() const; // Verify

Some files were not shown because too many files have changed in this diff Show More