Compare commits

...

145 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
277 changed files with 61910 additions and 64039 deletions

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

View File

@ -1,23 +1,25 @@
# Checking for user explicity defined CMAKE_INSTALL_PREFIX
# Checking for user explicitly defined CMAKE_INSTALL_PREFIX
# It must be done before project(...)
if(NOT CMAKE_INSTALL_PREFIX)
set(QCA_INSTALL_IN_QT_PREFIX ON)
# If CMAKE_INSTALL_PREFIX is set in cmake arguments
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)
cmake_minimum_required(VERSION 3.4)
set(QCA_LIB_MAJOR_VERSION "2")
set(QCA_LIB_MINOR_VERSION "2")
set(QCA_LIB_PATCH_VERSION "1")
set(QCA_LIB_MINOR_VERSION "3")
set(QCA_LIB_PATCH_VERSION "3")
if(POLICY CMP0042)
cmake_policy(SET CMP0042 OLD)
endif()
#if(POLICY CMP0042)
# cmake_policy(SET CMP0042 OLD)
#endif()
option(QT6 "Build with Qt 6" OFF)
option(BUILD_TESTS "Create test" 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)")
@ -36,54 +38,32 @@ find_package(Doxygen)
string(TOLOWER "${BUILD_PLUGINS}" BUILD_PLUGINS)
if(NOT BUILD_PLUGINS)
set(BUILD_PLUGINS "none")
endif(NOT BUILD_PLUGINS)
endif()
set(CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake/modules" )
option(QT4_BUILD "Force building with Qt4 even if Qt5 is found")
if (NOT QT4_BUILD)
# Do not automatically link Qt executables to qtmain target on Windows.
# QCA exucatables use console mode only. Not need to link against qtmain.lib.
if(QT6)
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(Qt5Core QUIET)
mark_as_advanced(Qt5Core_DIR)
find_package(Qt5 5.14 REQUIRED Core)
endif()
set(CMAKE_AUTOMOC ON)
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.
if(BUILD_TESTS)
find_package(Qt5Transitional REQUIRED Core Network)
else()
find_package(Qt5Transitional REQUIRED Core)
endif()
include(ECMQt4To5Porting)
include(GNUInstallDirs)
setup_qt5_dirs()
setup_qt_dirs()
if(QT6)
set(QCA_QT_PC_VERSION "Qt6Core")
set(QCA_SUFFIX "qt6")
else()
set(QCA_QT_PC_VERSION "Qt5Core")
set(QCA_SUFFIX "qt5")
else()
set(QT_MIN_VERSION "4.7.0")
set(QT_USE_IMPORTED_TARGETS ON)
# Do not automatically link Qt executables to qtmain target on Windows.
# QCA exucatables use console mode only. Not need to link against qtmain.lib.
set(QT4_NO_LINK_QTMAIN ON)
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()
# QCA can be shared but plugins will be static
@ -92,9 +72,9 @@ if(NOT BUILD_SHARED_LIBS OR QT_IS_STATIC)
set(STATIC_PLUGINS ON)
add_definitions(-DQT_STATICPLUGIN)
set(PLUGIN_TYPE "STATIC")
else(NOT BUILD_SHARED_LIBS OR QT_IS_STATIC)
else()
set(PLUGIN_TYPE "MODULE")
endif(NOT BUILD_SHARED_LIBS OR QT_IS_STATIC)
endif()
set(QCA_SUFFIX "${QCA_SUFFIX}" CACHE STRING "QCA common suffix")
if(QCA_SUFFIX)
@ -103,13 +83,13 @@ if(QCA_SUFFIX)
set(MOZCERTS_NAME mozcerts-${QCA_SUFFIX})
set(QCA_PC_NAME qca2-${QCA_SUFFIX}.pc)
set(QCA_CONFIG_NAME_BASE "Qca-${QCA_SUFFIX}")
else(QCA_SUFFIX)
else()
set(QCA_LIB_NAME qca)
set(QCA_TOOL_NAME qcatool)
set(MOZCERTS_NAME mozcerts)
set(QCA_PC_NAME qca2.pc)
set(QCA_CONFIG_NAME_BASE "Qca")
endif(QCA_SUFFIX)
endif()
set(QCA_LIB_VERSION_STRING "${QCA_LIB_MAJOR_VERSION}.${QCA_LIB_MINOR_VERSION}.${QCA_LIB_PATCH_VERSION}")
@ -120,9 +100,9 @@ if (WIN32)
add_definitions(-DWIN32_LEAN_AND_MEAN)
elseif (APPLE)
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)
add_definitions (-D_DEFAULT_SOURCE)
# on arm -Wcast-align throws many internal qt warning
@ -133,10 +113,29 @@ if (CMAKE_COMPILER_IS_GNUCXX)
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")
endif (CMAKE_SYSTEM_NAME MATCHES Linux)
endif (CMAKE_COMPILER_IS_GNUCXX)
add_definitions (${QT_DEFINITIONS})
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()
include_directories("include/QtCrypto/")
# for generated files
include_directories(${CMAKE_BINARY_DIR})
@ -183,7 +182,7 @@ if( QCA_INSTALL_IN_QT_PREFIX )
endif()
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")
else( QCA_INSTALL_IN_QT_PREFIX )
else()
# Cmake says nothing about LIB_SUFFIX
# 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)" )
@ -203,7 +202,7 @@ else( QCA_INSTALL_IN_QT_PREFIX )
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_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")
@ -247,12 +246,14 @@ if(NOT WIN32)
set(PKGCONFIG_LIBS "-L\${libdir} -l${QCA_LIB_NAME}")
endif()
if(NOT QT6)
# 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)
if(NOT DEVELOPER_MODE)
install(FILES "${CMAKE_LIBRARY_OUTPUT_DIRECTORY}/pkgconfig/${QCA_PC_NAME}" DESTINATION ${PKGCONFIG_INSTALL_PREFIX})
endif()
endif(NOT WIN32)
endif()
endif()
# strip CMAKE_INSTALL_PREFIX in all paths
if(USE_RELATIVE_PATHS)
@ -288,20 +289,18 @@ endif()
if (APPLE)
set(CMAKE_BUILD_WITH_INSTALL_RPATH TRUE)
endif (APPLE)
endif()
message(STATUS "Checking for certstore..")
# fixme add OR mac
if( WIN32 )
# USE BUILTIN
else ( WIN32 )
else()
if ( DEFINED ENV{QC_CERTSTORE_PATH} )
if(EXISTS $ENV{QC_CERTSTORE_PATH})
set( qca_CERTSTORE $ENV{QC_CERTSTORE_PATH})
else(EXISTS $ENV{QC_CERTSTORE_PATH})
# path to try
endif(EXISTS $ENV{QC_CERTSTORE_PATH})
else( DEFINED ENV{QC_CERTSTORE_PATH} )
endif()
else()
set( toTry
"/etc/ssl/certs/ca-certificates.crt"
"/usr/share/ssl/cert.pem"
@ -313,21 +312,21 @@ else ( WIN32 )
foreach (_current_try ${toTry})
if(EXISTS ${_current_try})
set( qca_CERTSTORE ${_current_try})
endif(EXISTS ${_current_try})
endif()
endforeach (_current_try)
endif( DEFINED ENV{QC_CERTSTORE_PATH} )
endif(WIN32)
endif()
endif()
if (qca_CERTSTORE)
message(STATUS "Found system certstore")
else (qca_CERTSTORE)
else()
message(STATUS "Using built in certstore.")
set( qca_CERTSTORE "${CMAKE_CURRENT_SOURCE_DIR}/certs/rootcerts.pem")
# note that INSTALL_FILES targets are relative to the current installation prefix...
if(NOT DEVELOPER_MODE)
install(FILES "${qca_CERTSTORE}" DESTINATION "${QCA_PREFIX_INSTALL_DIR}/certs")
endif()
endif (qca_CERTSTORE)
endif()
message(STATUS "certstore path: " ${qca_CERTSTORE})
add_definitions( -DQCA_SYSTEMSTORE_PATH="${qca_CERTSTORE}" )
@ -355,12 +354,14 @@ set( 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)
if(NOT DEVELOPER_MODE)
install(FILES "${CMAKE_BINARY_DIR}/mkspecs/features/crypto.prf" DESTINATION "${QCA_FEATURE_INSTALL_DIR}")
endif()
endif()
configure_file(man/qcatool.1 "${CMAKE_BINARY_DIR}/share/man/man1/${QCA_TOOL_NAME}.1" COPYONLY)
if(NOT DEVELOPER_MODE)
@ -379,29 +380,29 @@ if(STATIC_PLUGINS)
if(WITH_${PLUGIN}_PLUGIN_INTERNAL)
string(REPLACE "-" "_" IMPORT_NAME "qca-${PLUGIN}")
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)
endif(STATIC_PLUGINS)
endif()
if(BUILD_TESTS)
enable_testing()
add_subdirectory(unittest)
add_subdirectory(examples)
endif(BUILD_TESTS)
endif()
if(BUILD_TOOLS)
add_subdirectory(tools)
endif(BUILD_TOOLS)
endif()
if(DOXYGEN_FOUND)
configure_file(${CMAKE_SOURCE_DIR}/Doxyfile.in ${CMAKE_BINARY_DIR}/Doxyfile @ONLY)
add_custom_target(doc
${DOXYGEN_EXECUTABLE} ${CMAKE_BINARY_DIR}/Doxyfile
COMMAND ${CMAKE_COMMAND} -E make_directory ${CMAKE_BINARY_DIR}/images
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}/images/qca-arch.png ${CMAKE_BINARY_DIR}/images/qca-arch.png
WORKING_DIRECTORY ${CMAKE_BINARY_DIR}
COMMENT "Generating API documentation with Doxygen" VERBATIM)
endif(DOXYGEN_FOUND)
#if(DOXYGEN_FOUND)
# configure_file(${CMAKE_SOURCE_DIR}/Doxyfile.in ${CMAKE_BINARY_DIR}/Doxyfile @ONLY)
# add_custom_target(doc
# ${DOXYGEN_EXECUTABLE} ${CMAKE_BINARY_DIR}/Doxyfile
# COMMAND ${CMAKE_COMMAND} -E make_directory ${CMAKE_BINARY_DIR}/docs/pics
# 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}/docs/pics/qca-arch.png ${CMAKE_BINARY_DIR}/docs/pics/qca-arch.png
# WORKING_DIRECTORY ${CMAKE_BINARY_DIR}
# COMMENT "Generating API documentation with Doxygen" VERBATIM)
#endif()
include(CMakePackageConfigHelpers)
configure_package_config_file(
@ -431,7 +432,7 @@ if(NOT DEVELOPER_MODE)
message("!! you MUST explicity define CMAKE_INSTALL_PREFIX !!")
message("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!")
message("${ESCAPE}[0m")
endif(QCA_INSTALL_IN_QT_PREFIX)
endif()
message("")
if(USE_RELATIVE_PATHS)
@ -468,11 +469,16 @@ if(NOT DEVELOPER_MODE)
message("")
if(UNIX AND NOT APPLE)
if(NOT QCA_SUFFIX AND NOT QT4_BUILD)
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()

View File

@ -567,7 +567,7 @@ EXAMPLE_RECURSIVE = NO
# directories that contain image that are included in the documentation (see
# the \image command).
IMAGE_PATH = @CMAKE_SOURCE_DIR@/images
IMAGE_PATH = @CMAKE_SOURCE_DIR@/docs/pics
# 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

11
INSTALL
View File

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

View File

@ -150,9 +150,9 @@
\subsection qca2code Releases
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.
\subsection qca2dev Current development
@ -163,12 +163,12 @@
to build and use %QCA.
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>
Use
\verbatim
git clone git://anongit.kde.org/qca.git
git clone https://invent.kde.org/libraries/qca.git
\endverbatim
to get the latest sources.
*/

75
README
View File

@ -1,26 +1,19 @@
Qt Cryptographic Architecture (QCA) version 2.1.0
-------------------------------------------------
Date: November 6th, 2014
Website: http://delta.affinix.com/qca/
Mailing List: Delta Project <delta@lists.affinix.com>
Qt Cryptographic Architecture (QCA)
-----------------------------------
Project Lead/Maintainer (2003-current):
Justin Karneges <justin@affinix.com>
(March 2007 - August 2007 under Barracuda Networks employment)
Description
-----------
Development, Documentation, Unittests (2004-2009):
Brad Hards <bradh@frogmouth.net>
QCA is a library that provides an easy API for a range of cryptographic
features, including SSL/TLS, X.509 certificates, SASL, OpenPGP, smartcards,
and much more.
Development (2013-current)
Ivan Romanov <drizt@land.ru>
Functionality is supplied via plugins. This is useful for avoiding
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:
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
In order for QCA to be of much use, you'll want to install some plugins.
Install
@ -34,8 +27,16 @@ License
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
- Ported to Qt5 (Qt4 also supported)
- New building system. CMake instead of qmake
@ -90,25 +91,23 @@ Changes
- 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
features, including SSL/TLS, X.509 certificates, SASL, OpenPGP, smartcards,
and much more.
Project Lead/Maintainer (2003-2012):
Justin Karneges <justin@affinix.com>
(March 2007 - August 2007 under Barracuda Networks employment)
Functionality is supplied via plugins. This is useful for avoiding
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.
Development, Documentation, Unittests (2004-2009):
Brad Hards <bradh@frogmouth.net>
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
Psi XMPP/Jabber client project ( http://psi-im.org/ ).
API Documentation is located in the 'apidocs' subdirectory.
Have fun,
-Justin
Special Thanks:
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

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
File: mozilla/security/nss/lib/ckfw/builtins/certdata.txt
Date: January 15th, 2009
File: https://hg.mozilla.org/mozilla-central/log/tip/security/nss/lib/ckfw/builtins/certdata.txt
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,31 +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.
#reset variables
set(BOTAN_LIBRARIES)
set(BOTAN_CFLAGS)
find_package(PkgConfig)
pkg_search_module(BOTAN botan>=1.10 botan-1.10 botan-2)
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

@ -42,11 +42,11 @@ ENDIF(LIBGCRYPTCONFIG_EXECUTABLE)
if (LIBGCRYPT_FOUND)
if (NOT LibGcrypt_FIND_QUIETLY)
message(STATUS "Found libgcrypt: ${LIBGCRYPT_LIBRARIES}")
endif (NOT LibGcrypt_FIND_QUIETLY)
else (LIBGCRYPT_FOUND)
endif()
else()
if (LibGcrypt_FIND_REQUIRED)
message(FATAL_ERROR "Could not find libgcrypt libraries")
endif (LibGcrypt_FIND_REQUIRED)
endif (LIBGCRYPT_FOUND)
endif()
endif()
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)
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

@ -23,17 +23,17 @@ else()
if(NOT WIN32)
find_package(PkgConfig)
pkg_search_module(PKCS11H libpkcs11-helper-1)
endif(NOT WIN32)
endif()
if (PKCS11H_FOUND)
if (NOT Pkcs11Helper_FIND_QUIETLY)
message(STATUS "Found pkcs11-helper: ${PKCS11H_LDFLAGS}")
endif (NOT Pkcs11Helper_FIND_QUIETLY)
else (PKCS11H_FOUND)
endif()
else()
if (Pkcs11Helper_FIND_REQUIRED)
message(FATAL_ERROR "Could NOT find pkcs11-helper")
endif (Pkcs11Helper_FIND_REQUIRED)
endif (PKCS11H_FOUND)
endif()
endif()
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)
# Already in cache, be silent
set(SASL2_FIND_QUIETLY TRUE)
endif (SASL2_INCLUDE_DIR)
endif()
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)
set(SASL2_FOUND TRUE)
endif (SASL2_INCLUDE_DIR AND SASL2_LIBRARIES)
endif()
if (SASL2_FOUND)
if (NOT Sasl2_FIND_QUIETLY)
message(STATUS "Found Sasl2: ${SASL2_LIBRARIES}")
endif (NOT Sasl2_FIND_QUIETLY)
else (SASL2_FOUND)
endif()
else()
if (Sasl2_FIND_REQUIRED)
message(FATAL_ERROR "Could not find sasl2 libraries")
endif (Sasl2_FIND_REQUIRED)
endif (SASL2_FOUND)
endif()
endif()
MARK_AS_ADVANCED(SASL2_INCLUDE_DIR SASL2_LIBRARIES)

View File

@ -1,17 +1,10 @@
IF (Qt5Core_FOUND)
# FindQt4.cmake wasn't used, so define it here
MACRO (QT4_GET_MOC_INC_DIRS _moc_INC_DIRS)
SET(${_moc_INC_DIRS})
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)
MACRO(SETUP_QT_DIRS)
if(QT6)
GET_TARGET_PROPERTY(QMAKE_EXECUTABLE Qt6::qmake LOCATION)
else()
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_PREFIX" OUTPUT_VARIABLE QT_PREFIX_DIR )
EXEC_PROGRAM( ${QMAKE_EXECUTABLE} ARGS "-query QT_INSTALL_PLUGINS" OUTPUT_VARIABLE QT_PLUGINS_DIR )
@ -21,43 +14,15 @@ IF (Qt5Core_FOUND)
EXEC_PROGRAM( ${QMAKE_EXECUTABLE} ARGS "-query QT_INSTALL_DATA" OUTPUT_VARIABLE QT_DATA_DIR )
EXEC_PROGRAM( ${QMAKE_EXECUTABLE} ARGS "-query QT_HOST_DATA" OUTPUT_VARIABLE QT_ARCHDATA_DIR )
SET( QT_MKSPECS_DIR "${QT_ARCHDATA_DIR}/mkspecs" )
ENDMACRO(SETUP_QT5_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)
ENDMACRO(SETUP_QT_DIRS)
macro(set_enabled_plugin PLUGIN ENABLED)
# To nice looks
if(ENABLED)
set(ENABLED "on")
else(ENABLED)
else()
set(ENABLED "off")
endif(ENABLED)
endif()
set(WITH_${PLUGIN}_PLUGIN_INTERNAL ${ENABLED} CACHE INTERNAL "")
endmacro(set_enabled_plugin)
@ -72,7 +37,6 @@ endmacro(disable_plugin)
# it used to build examples and tools
macro(target_link_qca_libraries TARGET)
# Link with QCA library
target_link_libraries(${TARGET} ${QT_QTCORE_LIBRARY})
target_link_libraries(${TARGET} ${QCA_LIB_NAME})
# Statically link with all enabled QCA plugins
@ -82,15 +46,19 @@ macro(target_link_qca_libraries TARGET)
# Check plugin for enabled
if(WITH_${PLUGIN}_PLUGIN_INTERNAL)
target_link_libraries(${TARGET} qca-${PLUGIN})
endif(WITH_${PLUGIN}_PLUGIN_INTERNAL)
endif()
endforeach(PLUGIN)
endif(STATIC_PLUGINS)
endif()
endmacro(target_link_qca_libraries)
# it used to build unittests
macro(target_link_qca_test_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)
# it used to build unittests
@ -109,7 +77,7 @@ macro(install_pdb TARGET INSTALL_PATH)
get_target_property(LOCATION ${TARGET} LOCATION_RELWITHDEBINFO)
string(REGEX REPLACE "\\.[^.]*$" ".pdb" LOCATION "${LOCATION}")
install(FILES ${LOCATION} DESTINATION ${INSTALL_PATH} CONFIGURATIONS RelWithDebInfo)
endif(MSVC)
endif()
endmacro(install_pdb)
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")
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)
string(REGEX REPLACE "\n" ";" files "${files}")
@ -19,8 +19,8 @@ foreach (file ${files})
)
if(NOT ${rm_retval} EQUAL 0)
message(FATAL_ERROR "Problem when removing \"$ENV{DESTDIR}${file}\"")
endif (NOT ${rm_retval} EQUAL 0)
else (EXISTS "$ENV{DESTDIR}${file}")
endif()
else()
message(STATUS "File \"$ENV{DESTDIR}${file}\" does not exist.")
endif (EXISTS "$ENV{DESTDIR}${file}")
endif()
endforeach(file)

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}")
find_package(Qt5 REQUIRED Network)
endif()
add_subdirectory(aes-cmac)
add_subdirectory(base64test)

View File

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

View File

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

View File

@ -20,10 +20,10 @@
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#include <QtCrypto>
#include <QCoreApplication>
#include <QFile>
#include <iostream>
@ -34,7 +34,7 @@
// dump out information about some part of the certificate
// we use this same approach for information about the subject
// 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;
@ -55,29 +55,27 @@ static void dumpCertificateInfo( QCA::CertificateInfo info)
std::cout << " Country: " << std::endl;
// As above, however this shows a more compact way to represent
// 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;
}
}
// This is just a convenience routine
static void dumpSubjectInfo( QCA::CertificateInfo subject)
static void dumpSubjectInfo(const QCA::CertificateInfo &subject)
{
std::cout << "Subject: " << std::endl;
dumpCertificateInfo(subject);
}
// This is just a convenience routine
static void dumpIssuerInfo( QCA::CertificateInfo issuer)
static void dumpIssuerInfo(const QCA::CertificateInfo &issuer)
{
std::cout << "Issuer: " << std::endl;
dumpCertificateInfo(issuer);
}
int main(int argc, char **argv)
{
// the Initializer object sets things up, and
@ -108,7 +106,7 @@ int main(int argc, char** argv)
QCA::ConvertResult importResult;
// 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.
filecerts = QCA::CertificateCollection::fromFlatTextFile( argv[1], &importResult );
filecerts = QCA::CertificateCollection::fromFlatTextFile(QFile::decodeName(argv[1]), &importResult);
if (QCA::ConvertGood == importResult) {
std::cout << "Import succeeded" << std::endl;
// this turns the CertificateCollection into a QList of Certificate objects
@ -173,4 +171,3 @@ int main(int argc, char** argv)
return 0;
}

View File

@ -22,7 +22,7 @@
// QtCrypto has the declarations for all of QCA
#include <QtCrypto>
#include <stdio.h>
#include <cstdio>
#include <QCoreApplication>
@ -56,12 +56,14 @@ int main(int argc, char **argv)
QCA::InitializationVector iv(16);
// 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
QCA::Cipher::DefaultPadding,
// this object will encrypt
QCA::Encode,
key, iv);
key,
iv);
// 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
@ -74,10 +76,7 @@ int main(int argc, char **argv)
printf("Update failed\n");
}
// output the results of that stage
printf("AES128 encryption of %s is [%s]\n",
arg.data(),
qPrintable(QCA::arrayToHex(u.toByteArray())) );
printf("AES128 encryption of %s is [%s]\n", arg.data(), qPrintable(QCA::arrayToHex(u.toByteArray())));
// 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
@ -109,7 +108,8 @@ int main(int argc, char **argv)
// output results
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)
plainText = cipher.final();
@ -123,11 +123,8 @@ int main(int argc, char **argv)
printf("Final decryption block using AES128 is %s\n", plainText.data());
// instead of update() and final(), you can do the whole thing
// in one step, using process()
printf("One step decryption using AES128: %s\n",
QCA::SecureArray(cipher.process(cipherText)).data() );
printf("One step decryption using AES128: %s\n", QCA::SecureArray(cipher.process(cipherText)).data());
}
return 0;
}

View File

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

View File

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

View File

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

View File

@ -21,10 +21,10 @@
#include "certviewdlg.h"
#include <QtCore>
#include <QtGui>
#include <QtCrypto>
#include "ui_certview.h"
#include <QtCore>
#include <QtCrypto>
#include <QtGui>
// from qcatool
class InfoType
@ -40,12 +40,16 @@ public:
{
}
InfoType(QCA::CertificateInfoType _type, const QString &_varname, const QString &_shortname, const QString &_name, const QString &_desc) :
type(_type),
varname(_varname),
shortname(_shortname),
name(_name),
desc(_desc)
InfoType(QCA::CertificateInfoType _type,
const QString & _varname,
const QString & _shortname,
const QString & _name,
const QString & _desc)
: type(_type)
, varname(_varname)
, shortname(_shortname)
, name(_name)
, desc(_desc)
{
}
};
@ -53,18 +57,35 @@ public:
static QList<InfoType> makeInfoTypeList(bool legacyEmail = false)
{
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"), "");
if (legacyEmail)
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::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::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::IncorporationLocality, "IncorporationLocality", "", 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::IncorporationLocality,
"IncorporationLocality",
"",
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::DNS, "DNS", "", CertViewDlg::tr("Domain Name"), "Domain (dnsName)");
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)
{
QString out;
if(!values.isEmpty())
{
if (!values.isEmpty()) {
QString value = values.join(", ");
out = QString(" ") + CertViewDlg::tr("%1: %2").arg(name, value) + '\n';
}
@ -113,9 +133,9 @@ public:
Ui_CertView ui;
QCA::CertificateChain chain;
Private(CertViewDlg *_q) :
QObject(_q),
q(_q)
Private(CertViewDlg *_q)
: QObject(_q)
, q(_q)
{
ui.setupUi(q);
connect(ui.cb_chain, SIGNAL(activated(int)), SLOT(cb_activated(int)));
@ -134,8 +154,7 @@ public:
void updateInfo()
{
int x = ui.cb_chain->currentIndex();
if(x == -1)
{
if (x == -1) {
ui.lb_info->setText("");
return;
}
@ -143,15 +162,15 @@ public:
ui.lb_info->setText(cert_info_string(chain[x]));
}
private slots:
private Q_SLOTS:
void cb_activated(int)
{
updateInfo();
}
};
CertViewDlg::CertViewDlg(const QCA::CertificateChain &chain, QWidget *parent) :
QDialog(parent)
CertViewDlg::CertViewDlg(const QCA::CertificateChain &chain, QWidget *parent)
: QDialog(parent)
{
d = new Private(this);
d->chain = chain;

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

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
over an Transport Layer Security (TLS, also known as SSL) connection.

View File

@ -24,7 +24,7 @@
#include <QCoreApplication>
#include <stdio.h>
#include <cstdio>
#ifdef QT_STATICPLUGIN
#include "import_plugins.h"
@ -47,7 +47,7 @@ int main(int argc, char **argv)
printf("SHA1 not supported!\n");
else {
// 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));
}
@ -62,7 +62,7 @@ int main(int argc, char **argv)
QCA::SecureArray part2(arg.toByteArray().mid(3)); // the rest - "lo"
// create the required object.
QCA::Hash hashObject("md5");
QCA::Hash hashObject(QStringLiteral("md5"));
// we split it into two parts to show incremental update
hashObject.update(part1);
hashObject.update(part2);
@ -75,4 +75,3 @@ int main(int argc, char **argv)
return 0;
}

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -20,8 +20,8 @@
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#include <QtCrypto>
#include <QCoreApplication>
#include <QtCrypto>
#include <iostream>
@ -43,8 +43,7 @@ int main(int argc, char **argv)
// We demonstrate PEM usage here, so we need to test for
// supportedIOTypes, not just supportedTypes
if(!QCA::isSupported("pkey") ||
!QCA::PKey::supportedIOTypes().contains(QCA::PKey::RSA))
if (!QCA::isSupported("pkey") || !QCA::PKey::supportedIOTypes().contains(QCA::PKey::RSA))
std::cout << "RSA not supported!\n";
else {
// 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
// You can use the same technique with the public key too.
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
QCA::ConvertResult conversionResult;
QCA::PrivateKey privateKey = QCA::PrivateKey::fromPEMFile( "keyprivate.pem",
passPhrase,
&conversionResult);
QCA::PrivateKey privateKey =
QCA::PrivateKey::fromPEMFile(QStringLiteral("keyprivate.pem"), passPhrase, &conversionResult);
if (!(QCA::ConvertGood == conversionResult)) {
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 << decrypt.data() << "\"" << std::endl;
// Some private keys can also be used for producing signatures
if (!privateKey.canSign()) {
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
// have all the message
if ( pubkey.canVerify() &&
pubkey.verifyMessage( arg, argSig, QCA::EMSA3_MD5 ) ) {
if (pubkey.canVerify() && pubkey.verifyMessage(arg, argSig, QCA::EMSA3_MD5)) {
std::cout << "Signature is valid" << std::endl;
} else {
std::cout << "Signature could not be verified" << std::endl;
}
}
return 0;
}

View File

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

View File

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

View File

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

View File

@ -1,8 +1,10 @@
set(ssltest_bin_SRCS ssltest.cpp)
MY_AUTOMOC( ssltest_bin_SRCS)
add_executable(ssltest ${ssltest_bin_SRCS})
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)
{
QString s;
switch(v)
{
switch (v) {
case QCA::ValidityGood:
s = "Validated";
s = QStringLiteral("Validated");
break;
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;
case QCA::ErrorUntrusted:
s = "Certificate not trusted for the required purpose";
s = QStringLiteral("Certificate not trusted for the required purpose");
break;
case QCA::ErrorSignatureFailed:
s = "Invalid signature";
s = QStringLiteral("Invalid signature");
break;
case QCA::ErrorInvalidCA:
s = "Invalid CA certificate";
s = QStringLiteral("Invalid CA certificate");
break;
case QCA::ErrorInvalidPurpose:
s = "Invalid certificate purpose";
s = QStringLiteral("Invalid certificate purpose");
break;
case QCA::ErrorSelfSigned:
s = "Certificate is self-signed";
s = QStringLiteral("Certificate is self-signed");
break;
case QCA::ErrorRevoked:
s = "Certificate has been revoked";
s = QStringLiteral("Certificate has been revoked");
break;
case QCA::ErrorPathLengthExceeded:
s = "Maximum certificate chain length exceeded";
s = QStringLiteral("Maximum certificate chain length exceeded");
break;
case QCA::ErrorExpired:
s = "Certificate has expired";
s = QStringLiteral("Certificate has expired");
break;
case QCA::ErrorExpiredCA:
s = "CA has expired";
s = QStringLiteral("CA has expired");
break;
case QCA::ErrorValidityUnknown:
default:
s = "General certificate validation error";
s = QStringLiteral("General certificate validation error");
break;
}
return s;
@ -111,22 +110,24 @@ public:
ssl_done = false;
sock = new QTcpSocket;
connect(sock, SIGNAL(connected()), SLOT(sock_connected()));
connect(sock, SIGNAL(readyRead()), SLOT(sock_readyRead()));
connect(sock, SIGNAL(error(QAbstractSocket::SocketError)),
SLOT(sock_error(QAbstractSocket::SocketError)));
connect(sock, &QTcpSocket::connected, this, &SecureTest::sock_connected);
connect(sock, &QTcpSocket::readyRead, this, &SecureTest::sock_readyRead);
#if QT_VERSION >= QT_VERSION_CHECK(5, 15, 0)
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;
connect(ssl, SIGNAL(certificateRequested()), SLOT(ssl_certificateRequested()));
connect(ssl, SIGNAL(handshaken()), SLOT(ssl_handshaken()));
connect(ssl, SIGNAL(readyRead()), SLOT(ssl_readyRead()));
connect(ssl, SIGNAL(readyReadOutgoing()),
SLOT(ssl_readyReadOutgoing()));
connect(ssl, SIGNAL(closed()), SLOT(ssl_closed()));
connect(ssl, SIGNAL(error()), SLOT(ssl_error()));
connect(ssl, &QCA::TLS::certificateRequested, this, &SecureTest::ssl_certificateRequested);
connect(ssl, &QCA::TLS::handshaken, this, &SecureTest::ssl_handshaken);
connect(ssl, &QCA::TLS::readyRead, this, &SecureTest::ssl_readyRead);
connect(ssl, &QCA::TLS::readyReadOutgoing, this, &SecureTest::ssl_readyReadOutgoing);
connect(ssl, &QCA::TLS::closed, this, &SecureTest::ssl_closed);
connect(ssl, &QCA::TLS::error, this, &SecureTest::ssl_error);
}
~SecureTest()
~SecureTest() override
{
delete ssl;
delete sock;
@ -134,15 +135,16 @@ public:
void start(const QString &_host)
{
int n = _host.indexOf(':');
int n = _host.indexOf(QLatin1Char(':'));
int port;
if(n != -1)
{
if (n != -1) {
host = _host.mid(0, n);
port = _host.mid(n+1).toInt();
}
else
{
#if QT_VERSION >= QT_VERSION_CHECK(5, 15, 0)
port = QStringView(_host).mid(n + 1).toInt();
#else
port = _host.midRef(n + 1).toInt();
#endif
} else {
host = _host;
port = 443;
}
@ -151,10 +153,10 @@ public:
sock->connectToHost(host, port);
}
signals:
Q_SIGNALS:
void quit();
private slots:
private Q_SLOTS:
void sock_connected()
{
// 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
// the server example.
rootCerts.addCertificate(QCA::Certificate::fromPEM(exampleCA_cert));
rootCerts.addCertificate(QCA::Certificate::fromPEM(QString::fromLatin1(exampleCA_cert)));
if (!QCA::haveSystemStore())
printf("Warning: no root certs\n");
@ -195,8 +197,7 @@ private slots:
void sock_error(QAbstractSocket::SocketError x)
{
if(x == QAbstractSocket::RemoteHostClosedError)
{
if (x == QAbstractSocket::RemoteHostClosedError) {
sock_connectionClosed();
return;
}
@ -216,29 +217,28 @@ private slots:
qPrintable(ssl->cipherSuite()),
ssl->cipherBits(),
ssl->cipherMaxBits());
if(r != QCA::TLS::NoCertificate)
{
if (r != QCA::TLS::NoCertificate) {
cert = ssl->peerCertificateChain().primary();
if (!cert.isNull())
showCertInfo(cert);
}
QString str = "Peer Identity: ";
QString str = QStringLiteral("Peer Identity: ");
if (r == QCA::TLS::Valid)
str += "Valid";
str += QStringLiteral("Valid");
else if (r == QCA::TLS::HostMismatch)
str += "Error: Wrong certificate";
str += QStringLiteral("Error: Wrong certificate");
else if (r == QCA::TLS::InvalidCertificate)
str += "Error: Invalid certificate.\n -> Reason: " +
str += QStringLiteral("Error: Invalid certificate.\n -> Reason: ") +
validityToString(ssl->peerCertificateValidity());
else
str += "Error: No certificate";
str += QStringLiteral("Error: No certificate");
printf("%s\n", qPrintable(str));
ssl->continueAfterStep();
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());
}
@ -249,8 +249,7 @@ private slots:
printf("Server requested client certificate.\n");
QList<QCA::CertificateInfoOrdered> issuerList = ssl->issuerList();
if(!issuerList.isEmpty())
{
if (!issuerList.isEmpty()) {
printf("Allowed issuers:\n");
foreach (QCA::CertificateInfoOrdered i, issuerList)
printf(" %s\n", qPrintable(i.toString()));
@ -291,13 +290,10 @@ private slots:
QCA::TLS *ssl = SecureTest::ssl;
int x = ssl->errorCode();
if(x == QCA::TLS::ErrorHandshake)
{
if (x == QCA::TLS::ErrorHandshake) {
printf("SSL Handshake Error!\n");
emit quit();
}
else
{
} else {
printf("SSL Error!\n");
emit quit();
}
@ -318,16 +314,15 @@ int main(int argc, char **argv)
QCA::Initializer init;
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");
return 1;
}
SecureTest *s = new SecureTest;
QObject::connect(s, SIGNAL(quit()), &app, SLOT(quit()));
QObject::connect(s, &SecureTest::quit, &app, &QCoreApplication::quit);
s->start(host);
app.exec();
delete s;

View File

@ -1,9 +1,8 @@
set(tlssocket_bin_moc_SRCS tlssocket.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})
add_executable(tlssocket tlssocket.cpp main.cpp)
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);
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");
while (socket.waitForReadyRead())
printf("%s", socket.readAll().data());
printf("%s", socket.readAll().constData());
return 0;
}

View File

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

View File

@ -21,24 +21,25 @@
#ifndef TLSSOCKET_H
#include <QtCrypto>
#include <QTcpSocket>
#include <QtCrypto>
class TLSSocket : public QTcpSocket
{
Q_OBJECT
public:
TLSSocket(QObject *parent = 0);
~TLSSocket();
TLSSocket(QObject *parent = nullptr);
~TLSSocket() override;
void connectToHostEncrypted(const QString &host, quint16 port);
QCA::TLS *tls();
bool waitForReadyRead(int msecs = -1);
bool waitForReadyRead(int msecs = -1) override;
protected:
// from qiodevice
virtual qint64 readData(char *data, qint64 maxlen);
virtual qint64 writeData(const char *data, qint64 len);
qint64 readData(char *data, qint64 maxlen) override;
qint64 writeData(const char *data, qint64 len) override;
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
#define QCA_H
#include "qca_core.h"
#include "qca_textfilter.h"
#include "qca_basic.h"
#include "qca_publickey.h"
#include "qca_cert.h"
#include "qca_core.h"
#include "qca_keystore.h"
#include "qca_publickey.h"
#include "qca_safetimer.h"
#include "qca_securelayer.h"
#include "qca_securemessage.h"
#include "qca_textfilter.h"
#include "qcaprovider.h"
#include "qpipe.h"
#include "qca_safetimer.h"
#endif

View File

@ -38,13 +38,6 @@
#include <QIODevice>
// Qt5 comes with QStringLiteral for wrapping string literals, which Qt4 does
// 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 {
/**
@ -87,7 +80,7 @@ public:
*/
Random(const Random &from);
~Random();
~Random() override;
/**
Assignment operator
@ -122,7 +115,7 @@ public:
Provide a random character (byte)
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
myRandomChar = QCA::Random::randomChar();
\endcode
@ -232,7 +225,7 @@ public:
*/
Hash(const Hash &from);
~Hash();
~Hash() override;
/**
Assignment operator
@ -265,7 +258,7 @@ public:
a Hash sub-class object to calculate additional
hashes.
*/
virtual void clear();
void clear() override;
/**
Update a hash, adding more of the message contents
@ -278,7 +271,7 @@ public:
\param a the byte array to add to the hash
*/
virtual void update(const MemoryRegion &a);
void update(const MemoryRegion &a) override;
/**
\overload
@ -340,7 +333,7 @@ if ( f.open( QIODevice::ReadOnly ) )
reuse the Hash object, you should call clear() and
start to update() again.
*/
virtual MemoryRegion final();
MemoryRegion final() override;
/**
%Hash a byte array, returning it as another
@ -635,8 +628,11 @@ public:
\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 = DefaultPadding,
Direction dir = Encode, const SymmetricKey &key = SymmetricKey(),
Cipher(const QString & type,
Mode mode,
Padding pad = DefaultPadding,
Direction dir = Encode,
const SymmetricKey & key = SymmetricKey(),
const InitializationVector &iv = InitializationVector(),
const QString & provider = QString());
@ -657,9 +653,13 @@ public:
\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,
Cipher(const QString & type,
Mode mode,
Padding pad,
Direction dir,
const SymmetricKey & key,
const InitializationVector &iv,
const AuthTag & tag,
const QString & provider = QString());
/**
@ -669,7 +669,7 @@ public:
*/
Cipher(const Cipher &from);
~Cipher();
~Cipher() override;
/**
Assignment operator
@ -733,7 +733,7 @@ public:
/**
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
@ -742,20 +742,20 @@ public:
\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
the completed block
*/
virtual MemoryRegion final();
MemoryRegion final() override;
/**
Test if an update() or final() call succeeded.
\return true if the previous call succeeded
*/
virtual bool ok() const;
bool ok() const override;
/**
Reset / reconfigure the Cipher
@ -798,6 +798,7 @@ public:
QCA::PCKS7)
*/
static QString withAlgorithms(const QString &cipherType, Mode modeType, Padding paddingType);
private:
class Private;
Private *d;
@ -847,7 +848,7 @@ public:
*/
MessageAuthenticationCode(const MessageAuthenticationCode &from);
~MessageAuthenticationCode();
~MessageAuthenticationCode() override;
/**
Assignment operator.
@ -899,7 +900,7 @@ public:
doesn't need to be changed, you don't need to call
setup() again, since the key can just be reused.
*/
virtual void clear();
void clear() override;
/**
Update the MAC, adding more of the message contents
@ -908,7 +909,7 @@ public:
\param array the message contents
*/
virtual void update(const MemoryRegion &array);
void update(const MemoryRegion &array) override;
/**
Finalises input and returns the MAC result
@ -921,7 +922,7 @@ public:
reuse the %MessageAuthenticationCode object, you
should call clear() and start to update() again.
*/
virtual MemoryRegion final();
MemoryRegion final() override;
/**
Initialise the MAC algorithm
@ -959,7 +960,7 @@ public:
*/
KeyDerivationFunction(const KeyDerivationFunction &from);
~KeyDerivationFunction();
~KeyDerivationFunction() override;
/**
Assignment operator
@ -983,7 +984,10 @@ public:
\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
@ -1052,7 +1056,9 @@ public:
\param provider the name of the provider to use, if available
*/
explicit PBKDF1(const QString &algorithm = QStringLiteral("sha1"), const QString &provider = QString())
: KeyDerivationFunction(withAlgorithm(QStringLiteral("pbkdf1"), algorithm), provider) {}
: KeyDerivationFunction(withAlgorithm(QStringLiteral("pbkdf1"), algorithm), provider)
{
}
};
/**
@ -1075,7 +1081,9 @@ public:
\param provider the name of the provider to use, if available
*/
explicit PBKDF2(const QString &algorithm = QStringLiteral("sha1"), const QString &provider = QString())
: KeyDerivationFunction(withAlgorithm(QStringLiteral("pbkdf2"), algorithm), provider) {}
: KeyDerivationFunction(withAlgorithm(QStringLiteral("pbkdf2"), algorithm), provider)
{
}
};
/**
@ -1107,7 +1115,7 @@ public:
*/
HKDF(const HKDF &from);
~HKDF();
~HKDF() override;
/**
Assignment operator
@ -1131,8 +1139,10 @@ public:
\return the derived key
*/
SymmetricKey makeKey(const SecureArray &secret, const InitializationVector &salt,
const InitializationVector &info, unsigned int keyLength);
SymmetricKey makeKey(const SecureArray & secret,
const InitializationVector &salt,
const InitializationVector &info,
unsigned int keyLength);
};
}

View File

@ -33,9 +33,9 @@
#ifndef QCA_CERT_H
#define QCA_CERT_H
#include <QDateTime>
#include "qca_core.h"
#include "qca_publickey.h"
#include <QDateTime>
namespace QCA {
@ -47,7 +47,6 @@ class CRL;
class CertificateCollection;
class CertificateChain;
/**
Certificate Request Format
*/
@ -309,7 +308,6 @@ private:
QSharedDataPointer<Private> d;
};
/**
Known types of certificate constraints
@ -329,15 +327,24 @@ enum ConstraintTypeKnown
DecipherOnly, ///< %Certificate can only be used for decryption, id = "KeyUsage.decipherOnly"
// 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.
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.
CodeSigning, ///< %Certificate can be used to sign code, id = "1.3.6.1.5.5.7.3.3". 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 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.
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.
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.
CodeSigning, ///< %Certificate can be used to sign code, id = "1.3.6.1.5.5.7.3.3". 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
///< 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.
};
/**
@ -497,7 +504,8 @@ enum Validity
ErrorSelfSigned, ///< The certificate is self-signed, and is not found in the list of trusted certificates
ErrorRevoked, ///< The certificate has been revoked
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
ErrorValidityUnknown = 64 ///< Validity is unknown
};
@ -879,7 +887,7 @@ public:
*/
Certificate(const Certificate &from);
~Certificate();
~Certificate() override;
/**
Standard assignment operator
@ -1015,9 +1023,9 @@ CertificateInfoOrdered info = cert.subjectInfoOrdered();
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;
@ -1070,7 +1078,10 @@ CertificateInfoOrdered info = cert.subjectInfoOrdered();
\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
@ -1101,7 +1112,8 @@ CertificateInfoOrdered info = cert.subjectInfoOrdered();
\return the Certificate corresponding to the certificate in the
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
@ -1115,7 +1127,7 @@ CertificateInfoOrdered info = cert.subjectInfoOrdered();
\return the Certificate corresponding to the certificate in the
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
@ -1130,7 +1142,8 @@ CertificateInfoOrdered info = cert.subjectInfoOrdered();
\return the Certificate corresponding to the certificate in the
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
@ -1178,8 +1191,13 @@ private:
QSharedDataPointer<Private> d;
friend class CertificateChain;
Validity chain_validate(const CertificateChain &chain, 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;
Validity chain_validate(const CertificateChain & chain,
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;
};
/**
@ -1194,7 +1212,7 @@ private:
The normal use of a CertificateChain is from a end-user Certificate (called
the primary, equivalent to QList::first()) through some intermediate
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
QList::append().
@ -1210,7 +1228,9 @@ public:
/**
Create an empty certificate chain
*/
inline CertificateChain() {}
inline CertificateChain()
{
}
/**
Create a certificate chain, starting at the specified certificate
@ -1218,12 +1238,18 @@ public:
\param primary the end-user certificate that forms one end of the
chain
*/
inline CertificateChain(const Certificate &primary) { append(primary); }
inline CertificateChain(const Certificate &primary)
{
append(primary);
}
/**
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
@ -1238,7 +1264,10 @@ public:
\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
@ -1263,10 +1292,14 @@ public:
\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())
return ErrorValidityUnknown;
@ -1323,7 +1356,7 @@ public:
*/
CertificateRequest(const CertificateRequest &from);
~CertificateRequest();
~CertificateRequest() override;
/**
Standard assignment operator
@ -1398,7 +1431,7 @@ public:
PublicKey subjectPublicKey() const;
/**
Test if this Certificate Request is for a Certificate Authority
Test if this %Certificate Request is for a %Certificate Authority
certificate
\note this only applies to PKCS#10 format certificate requests
@ -1406,7 +1439,7 @@ public:
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
*/
@ -1443,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
*/
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
*/
@ -1479,7 +1512,8 @@ public:
\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
@ -1496,7 +1530,8 @@ public:
\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
@ -1513,7 +1548,8 @@ public:
\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
@ -1538,7 +1574,8 @@ public:
\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
@ -1711,7 +1748,7 @@ public:
*/
CRL(const CRL &from);
~CRL();
~CRL() override;
/**
Standard assignment operator
@ -1723,7 +1760,7 @@ public:
/**
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;
@ -1832,7 +1869,7 @@ public:
\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)
@ -1845,7 +1882,7 @@ public:
\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
@ -1859,7 +1896,8 @@ public:
\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
@ -2004,7 +2042,8 @@ public:
\return the CertificateCollection corresponding to the contents of
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
@ -2019,7 +2058,8 @@ public:
\return the CertificateCollection corresponding to the contents of
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:
class Private;
@ -2054,7 +2094,7 @@ public:
*/
CertificateAuthority(const CertificateAuthority &from);
~CertificateAuthority();
~CertificateAuthority() override;
/**
Standard assignment operator
@ -2089,7 +2129,7 @@ public:
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
@ -2304,7 +2344,10 @@ else
\note This synchronous operation may require event handling, and so
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
@ -2336,7 +2379,10 @@ else
\note This synchronous operation may require event handling, and so
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:
class Private;
@ -2383,7 +2429,7 @@ public:
*/
PGPKey(const PGPKey &from);
~PGPKey();
~PGPKey() override;
/**
Standard assignment operator
@ -2493,7 +2539,7 @@ public:
\param provider the provider to use, if a particular provider is
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
@ -2504,7 +2550,7 @@ public:
\param provider the provider to use, if a particular provider is
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
@ -2516,7 +2562,8 @@ public:
\param provider the provider to use, if a particular provider is
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:
class Private;
@ -2571,8 +2618,8 @@ public:
\param parent the parent object for this object
*/
KeyLoader(QObject *parent = 0);
~KeyLoader();
KeyLoader(QObject *parent = nullptr);
~KeyLoader() override;
/**
Initiate an asynchronous loading of a PrivateKey from a PEM format

View File

@ -34,15 +34,15 @@
#ifndef QCA_CORE_H
#define QCA_CORE_H
#include <QString>
#include <QStringList>
#include <QList>
#include <QSharedData>
#include <QSharedDataPointer>
#include "qca_export.h"
#include "qca_support.h"
#include "qca_tools.h"
#include "qca_version.h"
#include <QList>
#include <QSharedData>
#include <QSharedDataPointer>
#include <QString>
#include <QStringList>
/**
The current version of %QCA.
@ -668,6 +668,9 @@ public:
*/
explicit Initializer(MemoryMode m = Practical, int prealloc = 64);
~Initializer();
Initializer(const Initializer &) = delete;
Initializer &operator=(const Initializer &) = delete;
};
/**
@ -706,18 +709,27 @@ public:
multiple of.
*/
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
*/
int minimum() const { return _min; }
int minimum() const
{
return _min;
}
/**
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
@ -725,7 +737,10 @@ public:
If this is one, then anything between minimum and maximum (inclusive)
is acceptable.
*/
int multiple() const { return _multiple; }
int multiple() const
{
return _multiple;
}
private:
const int _min, _max, _multiple;
@ -925,7 +940,7 @@ class QCA_EXPORT Provider::Context : public QObject
{
Q_OBJECT
public:
virtual ~Context();
~Context() override;
/**
The Provider associated with this Context
@ -995,7 +1010,7 @@ class QCA_EXPORT BasicContext : public Provider::Context
{
Q_OBJECT
public:
~BasicContext();
~BasicContext() override;
protected:
/**
@ -1295,26 +1310,26 @@ class QCA_EXPORT InitializationVector : public SecureArray
{
public:
/**
Construct an empty (zero length) initisation vector
Construct an empty (zero length) initialization vector
*/
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);
/**
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
*/
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
*/
@ -1507,7 +1522,10 @@ public:
information is required for
\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
@ -1566,8 +1584,8 @@ public:
\param parent the parent object for this object
*/
EventHandler(QObject *parent = 0);
~EventHandler();
EventHandler(QObject *parent = nullptr);
~EventHandler() override;
/**
mandatory function to call after connecting the
@ -1648,8 +1666,8 @@ public:
\param parent the parent object for this QObject
*/
PasswordAsker(QObject *parent = 0);
~PasswordAsker();
PasswordAsker(QObject *parent = nullptr);
~PasswordAsker() override;
/**
queue a password / passphrase request associated with a key store
@ -1662,7 +1680,8 @@ public:
information is required for (if applicable)
\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
@ -1740,8 +1759,8 @@ public:
\param parent the parent object for this QObject
*/
TokenAsker(QObject *parent = 0);
~TokenAsker();
TokenAsker(QObject *parent = nullptr);
~TokenAsker() override;
/**
queue a token request associated with a key store

View File

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

View File

@ -33,8 +33,8 @@
#ifndef QCA_PUBLICKEY_H
#define QCA_PUBLICKEY_H
#include <QObject>
#include "qca_core.h"
#include <QObject>
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_MD2, ///< MD2, 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_SHA256, ///< SHA256, 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
*/
enum Type {
enum Type
{
RSA, ///< RSA key
DSA, ///< DSA key
DH ///< Diffie Hellman key
@ -270,7 +272,7 @@ public:
*/
PKey(const PKey &from);
~PKey();
~PKey() override;
/**
Standard assignment operator
@ -554,7 +556,7 @@ public:
*/
PublicKey(const PublicKey &from);
~PublicKey();
~PublicKey() override;
/**
Assignment operator
@ -691,7 +693,10 @@ if( pubkey.canVerify() )
\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
@ -743,7 +748,7 @@ if (! QCA::ConvertGood == conversionResult)
conversion succeeded (ConvertGood) or not
\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
@ -770,7 +775,7 @@ if (! QCA::ConvertGood == conversionResult)
\sa toPEM, which provides an inverse of fromPEM()
\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
@ -799,7 +804,8 @@ if (! QCA::ConvertGood == conversionResult)
\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:
/**
@ -851,7 +857,7 @@ public:
*/
PrivateKey(const PrivateKey &from);
~PrivateKey();
~PrivateKey() override;
/**
Assignment operator
@ -1025,7 +1031,9 @@ public:
\sa fromPEM provides an inverse of toPEM, converting the PEM
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
@ -1045,7 +1053,10 @@ public:
\note This synchronous operation may require event handling, and so
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
@ -1065,7 +1076,10 @@ public:
\note This synchronous operation may require event handling, and so
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
@ -1089,7 +1103,10 @@ public:
\note This synchronous operation may require event handling, and so
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:
/**
@ -1126,9 +1143,9 @@ public:
\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,
@ -1325,7 +1342,12 @@ public:
\param provider the provider to use, if a particular provider is
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

View File

@ -34,8 +34,8 @@ class QCA_EXPORT SafeTimer : public QObject
{
Q_OBJECT
public:
SafeTimer(QObject *parent = 0);
~SafeTimer();
SafeTimer(QObject *parent = nullptr);
~SafeTimer() override;
int interval() const;
bool isActive() const;
@ -53,13 +53,17 @@ Q_SIGNALS:
void timeout();
protected:
bool event(QEvent *event);
void timerEvent(QTimerEvent *event);
bool event(QEvent *event) override;
void timerEvent(QTimerEvent *event) override;
private:
// Functions is used internally. Outer world mustn't have access them.
void startTimer() {}
void killTimer(int) {}
void startTimer()
{
}
void killTimer(int)
{
}
class Private;
Private *d;

View File

@ -32,10 +32,10 @@
#ifndef QCA_SECURELAYER_H
#define QCA_SECURELAYER_H
#include <QObject>
#include "qca_cert.h"
#include "qca_core.h"
#include "qca_publickey.h"
#include "qca_cert.h"
#include <QObject>
namespace QCA {
@ -111,7 +111,7 @@ public:
\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".
@ -176,7 +176,7 @@ public:
\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
@ -247,7 +247,7 @@ public:
*/
TLSSession(const TLSSession &from);
~TLSSession();
~TLSSession() override;
/**
Assignment operator
@ -345,7 +345,7 @@ public:
\param provider the name of the provider, if a specific provider
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.
@ -358,12 +358,12 @@ public:
\param provider the name of the provider, if a specific provider is
required
*/
explicit TLS(Mode mode, QObject *parent = 0, const QString &provider = QString());
explicit TLS(Mode mode, QObject *parent = nullptr, const QString &provider = QString());
/**
Destructor
*/
~TLS();
~TLS() override;
/**
Reset the connection
@ -681,16 +681,16 @@ foreach(const CertificateInfoOrdered &info, tls->issuerList())
CertificateChain peerCertificateChain() const;
// reimplemented
virtual bool isClosable() const;
virtual int bytesAvailable() const;
virtual int bytesOutgoingAvailable() const;
virtual void close();
virtual void write(const QByteArray &a);
virtual QByteArray read();
virtual void writeIncoming(const QByteArray &a);
virtual QByteArray readOutgoing(int *plainBytes = 0);
virtual QByteArray readUnprocessed();
virtual int convertBytesWritten(qint64 encryptedBytes);
bool isClosable() const override;
int bytesAvailable() const override;
int bytesOutgoingAvailable() const override;
void close() override;
void write(const QByteArray &a) override;
QByteArray read() override;
void writeIncoming(const QByteArray &a) override;
QByteArray readOutgoing(int *plainBytes = nullptr) override;
QByteArray readUnprocessed() override;
int convertBytesWritten(qint64 encryptedBytes) override;
/**
Determine the number of packets available to be
@ -783,11 +783,7 @@ protected:
\param signal the name of the signal that has been
connected to.
*/
#if QT_VERSION >= 0x050000
void connectNotify(const QMetaMethod &signal);
#else
void connectNotify(const char *signal);
#endif
void connectNotify(const QMetaMethod &signal) override;
/**
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
disconnected from.
*/
#if QT_VERSION >= 0x050000
void disconnectNotify(const QMetaMethod &signal);
#else
void disconnectNotify(const char *signal);
#endif
void disconnectNotify(const QMetaMethod &signal) override;
private:
Q_DISABLE_COPY(TLS)
@ -977,9 +969,9 @@ public:
specified, or specified as empty, then any provider is
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
@ -1059,7 +1051,10 @@ public:
\param mechlist the list of mechanisms which can be used
\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
@ -1072,7 +1067,10 @@ public:
\param realm the realm to use
\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)
@ -1177,13 +1175,13 @@ public:
void continueAfterAuthCheck();
// reimplemented
virtual int bytesAvailable() const;
virtual int bytesOutgoingAvailable() const;
virtual void write(const QByteArray &a);
virtual QByteArray read();
virtual void writeIncoming(const QByteArray &a);
virtual QByteArray readOutgoing(int *plainBytes = 0);
virtual int convertBytesWritten(qint64 encryptedBytes);
int bytesAvailable() const override;
int bytesOutgoingAvailable() const override;
void write(const QByteArray &a) override;
QByteArray read() override;
void writeIncoming(const QByteArray &a) override;
QByteArray readOutgoing(int *plainBytes = nullptr) override;
int convertBytesWritten(qint64 encryptedBytes) override;
Q_SIGNALS:
/**

View File

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

View File

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

View File

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

View File

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

View File

@ -33,11 +33,11 @@
#ifndef QCAPROVIDER_H
#define QCAPROVIDER_H
#include "qca_core.h"
#include "qca_basic.h"
#include "qca_publickey.h"
#include "qca_cert.h"
#include "qca_core.h"
#include "qca_keystore.h"
#include "qca_publickey.h"
#include "qca_securelayer.h"
#include "qca_securemessage.h"
@ -85,7 +85,9 @@ public:
/**
Destructs the object
*/
virtual ~QCAPlugin() {}
virtual ~QCAPlugin()
{
}
/**
Returns a newly allocated Provider instance.
@ -116,7 +118,10 @@ public:
\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
@ -153,7 +158,10 @@ public:
\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
@ -183,7 +191,10 @@ public:
\param p the provider associated with 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
@ -226,7 +237,10 @@ public:
\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.
*/
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
@ -289,7 +303,10 @@ public:
\param p the provider associated with 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
@ -351,7 +368,10 @@ public:
\param p the provider associated with this context
\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
@ -359,9 +379,12 @@ public:
\param secret the secret part (typically password)
\param salt the salt / initialization vector
\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
@ -370,7 +393,7 @@ public:
\param salt the salt / initialization vector
\param keyLength the length of the key to be produced
\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,
const InitializationVector &salt,
@ -399,7 +422,10 @@ public:
\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) {}
HKDFContext(Provider *p, const QString &type)
: BasicContext(p, type)
{
}
/**
Create a key and return it
@ -409,8 +435,10 @@ public:
\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;
virtual SymmetricKey makeKey(const SecureArray & secret,
const InitializationVector &salt,
const InitializationVector &info,
unsigned int keyLength) = 0;
};
/**
@ -432,7 +460,10 @@ public:
\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
@ -641,7 +672,10 @@ public:
\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
@ -668,7 +702,11 @@ public:
\param q the Q 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
@ -724,7 +762,10 @@ public:
\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
@ -794,7 +835,10 @@ public:
\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
@ -870,7 +914,10 @@ public:
\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
@ -1021,7 +1068,10 @@ public:
\param p the provider associated with 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
@ -1280,7 +1330,10 @@ public:
\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
@ -1333,7 +1386,11 @@ public:
\param u the desired usage for this certificate
\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
@ -1350,7 +1407,11 @@ public:
\param u the desired usage for the user certificate in the chain
\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;
};
/**
@ -1373,7 +1434,10 @@ public:
\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
@ -1454,7 +1518,10 @@ public:
\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
@ -1489,7 +1556,10 @@ public:
\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
@ -1514,7 +1584,8 @@ public:
\param certs the destination list for the certificates
\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;
};
/**
@ -1537,7 +1608,10 @@ public:
\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
@ -1592,7 +1666,8 @@ public:
\param entries the list of revoked entries
\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;
};
/**
@ -1614,7 +1689,10 @@ public:
\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
@ -1626,7 +1704,10 @@ public:
\param priv the private key to store
\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
@ -1642,7 +1723,11 @@ public:
\param chain the destination list for the certificate chain
\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;
};
/**
@ -1725,7 +1810,10 @@ public:
\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
@ -1783,7 +1871,10 @@ public:
\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
@ -1888,7 +1979,10 @@ public:
\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
@ -2126,7 +2220,10 @@ public:
\param p the Provider associated with this context
*/
TLSSessionContext(Provider *p) : BasicContext(p, QStringLiteral("tlssession")) {}
TLSSessionContext(Provider *p)
: BasicContext(p, QStringLiteral("tlssession"))
{
}
};
/**
@ -2206,7 +2303,10 @@ public:
\param p the Provider associated with 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
@ -2542,7 +2642,10 @@ public:
\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
@ -2570,7 +2673,12 @@ public:
\param ext_ssf the SSF of the external authentication channel
(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
@ -2757,7 +2865,8 @@ public:
\param pass the password
\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)
@ -2822,7 +2931,10 @@ public:
\param p the Provider associated with this context
\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
@ -2855,7 +2967,8 @@ public:
\param bundleSigner whether to bundle the signing keys (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
@ -2995,7 +3108,10 @@ public:
\param p the provider associated with this context
\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,

View File

@ -61,7 +61,6 @@ typedef int Q_PIPE_ID;
namespace QCA {
/**
\class QPipeDevice qpipe.h QtCrypto
@ -90,8 +89,8 @@ public:
\param parent the parent object to this object
*/
QPipeDevice(QObject *parent = 0);
~QPipeDevice();
QPipeDevice(QObject *parent = nullptr);
~QPipeDevice() override;
/**
The Type of the pipe device (that is, read or write)
@ -219,7 +218,6 @@ class QCA_EXPORT QPipeEnd : public QObject
{
Q_OBJECT
public:
/**
The type of error
*/
@ -234,9 +232,9 @@ public:
\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
@ -487,7 +485,7 @@ public:
\param parent the parent object for this object
*/
QPipe(QObject *parent = 0);
QPipe(QObject *parent = nullptr);
~QPipe();
@ -516,12 +514,18 @@ public:
/**
The read end of the pipe.
*/
QPipeEnd & readEnd() { return i; }
QPipeEnd &readEnd()
{
return i;
}
/**
The write end of the pipe.
*/
QPipeEnd & writeEnd() { return o; }
QPipeEnd &writeEnd()
{
return o;
}
private:
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")
elseif("${BUILD_PLUGINS}" STREQUAL "auto")
set(WITH_${PLUGIN}_PLUGIN "auto")
else("${BUILD_PLUGINS}" STREQUAL "all")
else()
set(WITH_${PLUGIN}_PLUGIN "no")
endif("${BUILD_PLUGINS}" STREQUAL "all")
endif()
elseif(NOT WITH_${PLUGIN}_PLUGIN)
set(WITH_${PLUGIN}_PLUGIN "no")
elseif("${WITH_${PLUGIN}_PLUGIN}" STREQUAL "auto")
set(WITH_${PLUGIN}_PLUGIN "auto")
else("${WITH_${PLUGIN}_PLUGIN}" STREQUAL "")
else()
set(WITH_${PLUGIN}_PLUGIN "yes")
endif("${WITH_${PLUGIN}_PLUGIN}" STREQUAL "")
endif()
# Build plugin if yes or auto
if(WITH_${PLUGIN}_PLUGIN)
add_subdirectory("qca-${PLUGIN}")
else(WITH_${PLUGIN}_PLUGIN)
else()
disable_plugin(${PLUGIN})
endif(WITH_${PLUGIN}_PLUGIN)
endif()
endforeach(PLUGIN IN LISTS PLUGINS)
else(NOT_PLUGIN_LIST)
else()
# BUILD_PLUGINS has list plugins to builds
foreach(PLUGIN IN LISTS PLUGINS)
list(FIND BUILD_PLUGINS "${PLUGIN}" PLUGIN_INDEX)
if(PLUGIN_INDEX GREATER -1)
set(WITH_${PLUGIN}_PLUGIN "yes")
add_subdirectory("qca-${PLUGIN}")
else(PLUGIN_INDEX GREATER -1)
else()
disable_plugin(${PLUGIN})
endif(PLUGIN_INDEX GREATER -1)
endif()
endforeach(PLUGIN IN LISTS PLUGINS)
endif(NOT_PLUGIN_LIST)
endif()
message("")
message("Plugins:")

View File

@ -1,22 +1,25 @@
find_package(PkgConfig REQUIRED)
if(WITH_botan_PLUGIN STREQUAL "yes")
find_package(Botan REQUIRED)
else(WITH_botan_PLUGIN STREQUAL "yes")
find_package(Botan)
endif(WITH_botan_PLUGIN STREQUAL "yes")
pkg_check_modules(BOTAN REQUIRED IMPORTED_TARGET botan-2)
else()
pkg_check_modules(BOTAN IMPORTED_TARGET botan-2)
endif()
if(BOTAN_FOUND)
enable_plugin("botan")
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})
if(APPLE AND ${PLUGIN_TYPE} STREQUAL "MODULE")
set_property(TARGET qca-botan PROPERTY SUFFIX ".dylib")
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)
install(TARGETS qca-botan
@ -27,6 +30,6 @@ if(BOTAN_FOUND)
install_pdb(qca-botan ${QCA_CRYPTO_INSTALL_DIR})
endif()
else(BOTAN_FOUND)
else()
disable_plugin("botan")
endif(BOTAN_FOUND)
endif()

View File

@ -17,46 +17,41 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*
*/
#include <QElapsedTimer>
#include <QtCrypto>
#include <QTime>
#include <QtPlugin>
#include <qstringlist.h>
#include <botan/hmac.h>
#include <botan/version.h>
#if BOTAN_VERSION_CODE < BOTAN_VERSION_CODE_FOR(2,0,0)
#include <botan/botan.h>
#include <botan/algo_factory.h>
#else
#include <botan/auto_rng.h>
#include <botan/block_cipher.h>
#include <botan/filters.h>
#include <botan/hash.h>
#include <botan/pbkdf.h>
#if BOTAN_VERSION_CODE >= BOTAN_VERSION_CODE_FOR(2,0,0)
#include <botan/hkdf.h>
#endif
#include <botan/hmac.h>
#include <botan/pbkdf.h>
#include <botan/stream_cipher.h>
#endif
#include <botan/version.h>
#include <stdlib.h>
#include <cstdlib>
#include <iostream>
//-----------------------------------------------------------
class botanRandomContext : public QCA::RandomContext
{
Q_OBJECT
public:
botanRandomContext(QCA::Provider *p) : RandomContext(p)
botanRandomContext(QCA::Provider *p)
: RandomContext(p)
{
}
Context *clone() const
Context *clone() const override
{
return new botanRandomContext(*this);
}
QCA::SecureArray nextBytes(int size)
QCA::SecureArray nextBytes(int size) override
{
QCA::SecureArray buf(size);
Botan::AutoSeeded_RNG rng;
@ -65,41 +60,66 @@ public:
}
};
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
{
Q_OBJECT
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)
{
#if BOTAN_VERSION_CODE < BOTAN_VERSION_CODE_FOR(2,0,0)
m_hashObj = Botan::get_hash(hashName.toStdString());
#else
const QString hashName = qcaHashToBotanHash(type);
m_hashObj = Botan::HashFunction::create(hashName.toStdString()).release();
#endif
}
~BotanHashContext()
~BotanHashContext() override
{
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();
}
void update(const QCA::MemoryRegion &a)
void update(const QCA::MemoryRegion &a) override
{
m_hashObj->update((const Botan::byte *)a.data(), a.size());
}
QCA::MemoryRegion final()
QCA::MemoryRegion final() override
{
QCA::SecureArray a(m_hashObj->output_length());
m_hashObj->final((Botan::byte *)a.data());
@ -110,28 +130,45 @@ private:
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
{
Q_OBJECT
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(2,0,0)
m_hashObj = new Botan::HMAC(Botan::global_state().algorithm_factory().make_hash_function(hashName.toStdString()));
#else
const QString hashName = qcaHmacToBotanHmac(type);
m_hashObj = new Botan::HMAC(Botan::HashFunction::create_or_throw(hashName.toStdString()).release());
#endif
if (0 == m_hashObj) {
if (nullptr == m_hashObj) {
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
// in the QCA MessageAuthenticationCode constructor. Botan doesn't like
@ -141,9 +178,9 @@ public:
}
}
Context *clone() const
Context *clone() const override
{
return new BotanHMACContext(*this);
return new BotanHMACContext(provider(), type());
}
void clear()
@ -151,17 +188,17 @@ public:
m_hashObj->clear();
}
QCA::KeyLength keyLength() const
QCA::KeyLength keyLength() const override
{
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());
}
void final( QCA::MemoryRegion *out)
void final(QCA::MemoryRegion *out) override
{
QCA::SecureArray sa(m_hashObj->output_length(), 0);
m_hashObj->final((Botan::byte *)sa.data());
@ -172,32 +209,61 @@ protected:
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
{
Q_OBJECT
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());
} catch (Botan::Exception &e) {
m_s2k = nullptr;
}
}
~BotanPBKDFContext()
~BotanPBKDFContext() override
{
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,
unsigned int keyLength, unsigned int iterationCount)
Context *clone() const override
{
std::string secretString(secret.data(), secret.size() );
Botan::OctetString key = m_s2k->derive_key(keyLength, secretString, (const Botan::byte*)salt.data(), salt.size(), iterationCount);
QCA::SecureArray retval(QByteArray((const char*)key.begin(), key.length()));
return new BotanPBKDFContext(provider(), type());
}
QCA::SymmetricKey makeKey(const QCA::SecureArray & secret,
const QCA::InitializationVector &salt,
unsigned int keyLength,
unsigned int iterationCount) override
{
if (!m_s2k)
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);
}
@ -205,21 +271,17 @@ public:
const QCA::InitializationVector &salt,
unsigned int keyLength,
int msecInterval,
unsigned int *iterationCount)
unsigned int * iterationCount) override
{
Q_ASSERT(iterationCount != NULL);
Q_ASSERT(iterationCount != nullptr);
Botan::OctetString key;
QTime timer;
std::string secretString(secret.data(), secret.size() );
QElapsedTimer timer;
const std::string secretString(secret.data(), secret.size());
*iterationCount = 0;
timer.start();
while (timer.elapsed() < msecInterval) {
key = m_s2k->derive_key(keyLength,
secretString,
(const Botan::byte*)salt.data(),
salt.size(),
1);
key = m_s2k->derive_key(keyLength, secretString, (const Botan::byte *)salt.data(), salt.size(), 1);
++(*iterationCount);
}
return makeKey(secret, salt, keyLength, *iterationCount);
@ -229,37 +291,52 @@ protected:
Botan::S2K *m_s2k;
};
static QString qcaHkdfToBotanHkdf(const QString &type)
{
if (type == QLatin1String("hkdf(sha256)"))
return QStringLiteral("SHA-256");
return {};
}
//-----------------------------------------------------------
#if BOTAN_VERSION_CODE >= BOTAN_VERSION_CODE_FOR(2,0,0)
class BotanHKDFContext : public QCA::HKDFContext
{
Q_OBJECT
public:
BotanHKDFContext(const QString &hashName, QCA::Provider *p, const QString &type) : QCA::HKDFContext(p, type)
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()
~BotanHKDFContext() override
{
delete m_hkdf;
}
Context *clone() const
Context *clone() const override
{
return new BotanHKDFContext( *this );
return new BotanHKDFContext(provider(), type());
}
QCA::SymmetricKey makeKey(const QCA::SecureArray &secret, const QCA::InitializationVector &salt,
const QCA::InitializationVector &info, unsigned int keyLength)
QCA::SymmetricKey makeKey(const QCA::SecureArray & secret,
const QCA::InitializationVector &salt,
const QCA::InitializationVector &info,
unsigned int keyLength) override
{
std::string secretString(secret.data(), secret.size());
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());
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);
}
@ -267,133 +344,219 @@ public:
protected:
Botan::HKDF *m_hkdf;
};
#endif
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
{
Q_OBJECT
public:
BotanCipherContext( const QString &algo, const QString &mode, const QString &padding,
QCA::Provider *p, const QString &type) : QCA::CipherContext(p, type)
BotanCipherContext(QCA::Provider *p, const QString &type)
: QCA::CipherContext(p, type)
{
m_algoName = algo.toStdString();
m_algoMode = mode.toStdString();
m_algoPadding = padding.toStdString();
qcaCipherToBotanCipher(type, &m_algoName, &m_algoMode, &m_algoPadding);
}
void setup(QCA::Direction dir,
const QCA::SymmetricKey & key,
const QCA::InitializationVector &iv,
const QCA::AuthTag &tag)
const QCA::AuthTag & tag) override
{
Q_UNUSED(tag);
try {
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 (QCA::Encode == dir) {
m_crypter = new Botan::Pipe(Botan::get_cipher(m_algoName+'/'+m_algoMode+'/'+m_algoPadding,
keyCopy, Botan::ENCRYPTION));
}
else {
m_crypter = new Botan::Pipe(Botan::get_cipher(m_algoName+'/'+m_algoMode+'/'+m_algoPadding,
keyCopy, Botan::DECRYPTION));
m_crypter = new Botan::Pipe(Botan::get_cipher(
m_algoName + '/' + m_algoMode + '/' + m_algoPadding, keyCopy, Botan::ENCRYPTION));
} else {
m_crypter = new Botan::Pipe(Botan::get_cipher(
m_algoName + '/' + m_algoMode + '/' + m_algoPadding, keyCopy, Botan::DECRYPTION));
}
} else {
Botan::InitializationVector ivCopy((Botan::byte*)iv.data(), iv.size());
const Botan::InitializationVector ivCopy((Botan::byte *)iv.data(), iv.size());
if (QCA::Encode == dir) {
m_crypter = new Botan::Pipe(Botan::get_cipher(m_algoName+'/'+m_algoMode+'/'+m_algoPadding,
keyCopy, ivCopy, Botan::ENCRYPTION));
}
else {
m_crypter = new Botan::Pipe(Botan::get_cipher(m_algoName+'/'+m_algoMode+'/'+m_algoPadding,
keyCopy, ivCopy, Botan::DECRYPTION));
m_crypter = new Botan::Pipe(Botan::get_cipher(
m_algoName + '/' + m_algoMode + '/' + m_algoPadding, keyCopy, ivCopy, Botan::ENCRYPTION));
} else {
m_crypter = new Botan::Pipe(Botan::get_cipher(
m_algoName + '/' + m_algoMode + '/' + m_algoPadding, keyCopy, ivCopy, Botan::DECRYPTION));
}
}
m_crypter->start_msg();
} catch (Botan::Exception &e) {
m_crypter = nullptr;
std::cout << "caught: " << e.what() << std::endl;
}
}
Context *clone() const
Context *clone() const override
{
return new BotanCipherContext(*this);
}
int blockSize() const
int blockSize() const override
{
#if BOTAN_VERSION_CODE < BOTAN_VERSION_CODE_FOR(2,0,0)
return Botan::block_size_of(m_algoName);
#else
if (const std::unique_ptr<Botan::BlockCipher> bc = Botan::BlockCipher::create(m_algoName))
return bc->block_size();
throw Botan::Algorithm_Not_Found(m_algoName);
#endif
}
QCA::AuthTag tag() const
QCA::AuthTag tag() const override
{
// For future implementation
return QCA::AuthTag();
}
bool update(const QCA::SecureArray &in, QCA::SecureArray *out)
bool update(const QCA::SecureArray &in, QCA::SecureArray *out) override
{
if (!m_crypter)
return false;
m_crypter->write((Botan::byte *)in.data(), in.size());
QCA::SecureArray result(m_crypter->remaining());
// 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);
*out = result;
return true;
}
bool final(QCA::SecureArray *out)
bool final(QCA::SecureArray *out) override
{
m_crypter->end_msg();
QCA::SecureArray result(m_crypter->remaining());
// 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);
*out = result;
return true;
}
QCA::KeyLength keyLength() const
QCA::KeyLength keyLength() const override
{
#if BOTAN_VERSION_CODE < BOTAN_VERSION_CODE_FOR(2,0,0)
Botan::Algorithm_Factory &af = Botan::global_state().algorithm_factory();
#endif
Botan::Key_Length_Specification kls(0);
#if BOTAN_VERSION_CODE < BOTAN_VERSION_CODE_FOR(2,0,0)
if(const Botan::BlockCipher *bc = af.prototype_block_cipher(m_algoName))
#else
if (const std::unique_ptr<Botan::BlockCipher> bc = Botan::BlockCipher::create(m_algoName))
#endif
kls = bc->key_spec();
#if BOTAN_VERSION_CODE < BOTAN_VERSION_CODE_FOR(2,0,0)
else if(const Botan::StreamCipher *sc = af.prototype_stream_cipher(m_algoName))
#else
else if (const std::unique_ptr<Botan::StreamCipher> sc = Botan::StreamCipher::create(m_algoName))
#endif
kls = sc->key_spec();
#if BOTAN_VERSION_CODE < BOTAN_VERSION_CODE_FOR(2,0,0)
else if(const Botan::MessageAuthenticationCode *mac = af.prototype_mac(m_algoName))
#else
else if(const std::unique_ptr<Botan::MessageAuthenticationCode> mac = Botan::MessageAuthenticationCode::create(m_algoName))
#endif
else if (const std::unique_ptr<Botan::MessageAuthenticationCode> mac =
Botan::MessageAuthenticationCode::create(m_algoName))
kls = mac->key_spec();
return QCA::KeyLength( kls.minimum_keylength(),
kls.maximum_keylength(),
kls.keylength_multiple() );
return QCA::KeyLength(kls.minimum_keylength(), kls.maximum_keylength(), kls.keylength_multiple());
}
~BotanCipherContext()
~BotanCipherContext() override
{
delete m_crypter;
}
@ -407,201 +570,180 @@ protected:
Botan::Pipe * m_crypter;
};
//==========================================================
class botanProvider : public QCA::Provider
{
public:
void init()
void init() override
{
#if BOTAN_VERSION_CODE < BOTAN_VERSION_CODE_FOR(2,0,0)
m_init = new Botan::LibraryInitializer;
#endif
}
~botanProvider()
~botanProvider() override
{
// We should be cleaning up there, but
// this causes the unit tests to segfault
// delete m_init;
}
int qcaVersion() const
int qcaVersion() const override
{
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;
list += "random";
list += "md2";
list += "md4";
list += "md5";
list += "sha1";
list += "sha256";
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)";
#if BOTAN_VERSION_CODE >= BOTAN_VERSION_CODE_FOR(2,0,0)
list += "hkdf(sha256)";
#endif
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";
static QStringList list;
if (list.isEmpty()) {
list += QStringLiteral("pbkdf1(sha1)");
std::unique_ptr<BotanPBKDFContext> pbkdf1md2(new BotanPBKDFContext(nullptr, QStringLiteral("pbkdf1(md2)")));
if (pbkdf1md2->isOk())
list += QStringLiteral("pbkdf1(md2)");
list += QStringLiteral("pbkdf2(sha1)");
}
return list;
}
Context *createContext(const QString &type)
const QStringList &hashTypes() const
{
if ( type == "random" )
return new botanRandomContext( this );
else if ( type == "md2" )
return new BotanHashContext( QString("MD2"), this, type );
else if ( type == "md4" )
return new BotanHashContext( QString("MD4"), this, type );
else if ( type == "md5" )
return new BotanHashContext( QString("MD5"), this, type );
else if ( type == "sha1" )
return new BotanHashContext( QString("SHA-1"), this, type );
else if ( type == "sha256" )
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 );
#if BOTAN_VERSION_CODE >= BOTAN_VERSION_CODE_FOR(2,0,0)
else if ( type == "hkdf(sha256)" )
return new BotanHKDFContext( QString("SHA-256"), this, type );
#endif
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:
#if BOTAN_VERSION_CODE < BOTAN_VERSION_CODE_FOR(2,0,0)
Botan::LibraryInitializer *m_init;
#endif
static QStringList supported;
if (supported.isEmpty()) {
QStringList list;
list += QStringLiteral("md2");
list += QStringLiteral("md4");
list += QStringLiteral("md5");
list += QStringLiteral("sha1");
list += QStringLiteral("sha256");
list += QStringLiteral("sha384");
list += QStringLiteral("sha512");
list += QStringLiteral("ripemd160");
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
{
Q_OBJECT
#if QT_VERSION >= 0x050000
Q_PLUGIN_METADATA(IID "com.affinix.qca.Plugin/1.0")
#endif
Q_INTERFACES(QCAPlugin)
public:
virtual QCA::Provider *createProvider() { return new botanProvider; }
QCA::Provider *createProvider() override
{
return new botanProvider;
}
};
#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")
find_package(Sasl2 REQUIRED)
else(WITH_cyrus-sasl_PLUGIN STREQUAL "yes")
else()
find_package(Sasl2)
endif(WITH_cyrus-sasl_PLUGIN STREQUAL "yes")
endif()
if(SASL2_FOUND)
enable_plugin("cyrus-sasl")
set(QCA_SASL_SOURCES qca-cyrus-sasl.cpp)
include_directories( ${SASL2_INCLUDE_DIR} )
my_automoc( QCA_SASL_SOURCES )
add_library(qca-cyrus-sasl ${PLUGIN_TYPE} ${QCA_SASL_SOURCES})
if(APPLE AND ${PLUGIN_TYPE} STREQUAL "MODULE")
set_property(TARGET qca-cyrus-sasl PROPERTY SUFFIX ".dylib")
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)
install(TARGETS qca-cyrus-sasl
@ -26,6 +29,6 @@ if(SASL2_FOUND)
install_pdb(qca-cyrus-sasl ${QCA_CRYPTO_INSTALL_DIR})
endif()
else(SASL2_FOUND)
else()
disable_plugin("cyrus-sasl")
endif(SASL2_FOUND)
endif()

View File

@ -19,19 +19,18 @@
*
*/
#include <QtCrypto>
#include <qcaprovider.h>
#include <QDebug>
#include <QtCrypto>
#include <QtPlugin>
#include <qcaprovider.h>
extern "C"
{
extern "C" {
#include <sasl/sasl.h>
}
#include <QStringList>
#include <QList>
#include <QFile>
#include <QList>
#include <QStringList>
#define SASL_BUFSIZE 8192
#define SASL_APP "qca"
@ -44,13 +43,13 @@ class saslProvider : public Provider
{
public:
saslProvider();
void init();
~saslProvider();
int qcaVersion() const;
QString name() const;
QString credit() const;
QStringList features() const;
Context *createContext(const QString &type);
void init() override;
~saslProvider() override;
int qcaVersion() const override;
QString name() const override;
QString credit() const override;
QStringList features() const override;
Context * createContext(const QString &type) override;
bool client_init;
bool server_init;
@ -154,7 +153,8 @@ public:
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 false;
}
@ -177,8 +177,8 @@ public:
{
if (i->result)
return;
QByteArray cs = s.toUtf8();
int len = cs.length();
const QByteArray cs = s.toUtf8();
const int len = cs.length();
char * p = new char[len + 1];
memcpy(p, cs.data(), len);
p[len] = 0;
@ -204,7 +204,7 @@ static QByteArray makeByteArray(const void *in, unsigned int len)
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
{
Q_OBJECT
saslProvider *g;
// core props
@ -262,19 +263,19 @@ private:
{
if (con) {
sasl_dispose(&con);
con = 0;
con = nullptr;
}
need = 0;
need = nullptr;
if (callbacks) {
delete callbacks;
callbacks = 0;
callbacks = nullptr;
}
localAddr = "";
remoteAddr = "";
localAddr = QLatin1String("");
remoteAddr = QLatin1String("");
maxoutbuf = 128;
sc_username = "";
sc_authzid = "";
sc_username = QLatin1String("");
sc_authzid = QLatin1String("");
result_authCondition = SASL::AuthFail;
result_haveClientInit = false;
@ -291,7 +292,7 @@ private:
secflags = 0;
ssf_min = 0;
ssf_max = 0;
ext_authid = "";
ext_authid = QLatin1String("");
ext_ssf = 0;
}
@ -301,20 +302,21 @@ private:
secprops.min_ssf = ssf_min;
secprops.max_ssf = ssf_max;
secprops.maxbufsize = SASL_BUFSIZE;
secprops.property_names = NULL;
secprops.property_values = NULL;
secprops.property_names = nullptr;
secprops.property_values = nullptr;
secprops.security_flags = secflags;
int r = sasl_setprop(con, SASL_SEC_PROPS, &secprops);
if (r != SASL_OK)
return false;
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;
r = sasl_setprop(con, SASL_SSF_EXTERNAL, &ssf);
if (r != SASL_OK)
return false;
r = sasl_setprop(con, SASL_AUTH_EXTERNAL, &authid);
r = sasl_setprop(con, SASL_AUTH_EXTERNAL, authid);
if (r != SASL_OK)
return false;
}
@ -328,23 +330,47 @@ private:
SASL::AuthCondition x;
switch (r) {
// common
case SASL_NOMECH: x = SASL::NoMechanism; break;
case SASL_BADPROT: x = SASL::BadProtocol; break;
case SASL_NOMECH:
x = SASL::NoMechanism;
break;
case SASL_BADPROT:
x = SASL::BadProtocol;
break;
// client
case SASL_BADSERV: x = SASL::BadServer; break;
case SASL_BADSERV:
x = SASL::BadServer;
break;
// server
case SASL_BADAUTH: x = SASL::BadAuth; break;
case SASL_NOAUTHZ: x = SASL::NoAuthzid; break;
case SASL_TOOWEAK: 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;
case SASL_BADAUTH:
x = SASL::BadAuth;
break;
case SASL_NOAUTHZ:
x = SASL::NoAuthzid;
break;
case SASL_TOOWEAK:
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;
}
@ -360,11 +386,19 @@ private:
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;
that->sc_username = auth_identity; // yeah yeah, it looks
that->sc_authzid = requested_user; // backwards, but it is right
that->sc_username = QString::fromLatin1(auth_identity); // yeah yeah, it looks
that->sc_authzid = QString::fromLatin1(requested_user); // backwards, but it is right
that->ca_flag = true;
return SASL_OK;
}
@ -377,22 +411,22 @@ private:
const char * clientout, *m;
unsigned int clientoutlen;
need = 0;
QString list = result_mechlist.join(" ");
need = nullptr;
const QString list = result_mechlist.join(QStringLiteral(" "));
int r;
while(1) {
while (true) {
if (need)
params.extractHave(need);
if (in_sendFirst)
r = sasl_client_start(con, list.toLatin1().data(), &need, &clientout, &clientoutlen, &m);
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)
break;
params.applyInteract(need);
if (params.missingAny()) {
out_mech = m;
out_mech = QString::fromLatin1(m);
result_result = Params;
return;
}
@ -403,7 +437,7 @@ private:
return;
}
out_mech = m;
out_mech = QString::fromLatin1(m);
if (in_sendFirst && clientout) {
out_buf = makeByteArray(clientout, clientoutlen);
result_haveClientInit = true;
@ -418,15 +452,15 @@ private:
}
result_result = Continue;
return;
}
else {
} else {
const char * clientout;
unsigned int clientoutlen;
int r;
while(1) {
while (true) {
if (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);
// printf("returned: %d\n", r);
if (r != SASL_INTERACT)
@ -458,7 +492,7 @@ private:
{
if (step == 0) {
if (!ca_skip) {
const char *clientin = 0;
const char * clientin = nullptr;
unsigned int clientinlen = 0;
if (in_useClientInit) {
clientin = in_clientInit.data();
@ -467,7 +501,8 @@ private:
const char * serverout;
unsigned int serveroutlen;
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) {
setAuthCondition(r);
result_result = Error;
@ -492,12 +527,11 @@ private:
}
result_result = Continue;
return;
}
else {
} else {
if (!ca_skip) {
const char * serverout;
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) {
setAuthCondition(r);
result_result = Error;
@ -536,7 +570,7 @@ private:
int at = 0;
out->resize(0);
while(1) {
while (true) {
int size = in.size() - at;
if (size == 0)
break;
@ -551,7 +585,7 @@ private:
r = sasl_decode(con, in.data() + at, size, &outbuf, &len);
if (r != SASL_OK)
return false;
int oldsize = out->size();
const int oldsize = out->size();
out->resize(oldsize + len);
memcpy(out->data() + oldsize, outbuf, len);
at += size;
@ -570,92 +604,102 @@ public:
{
result_result = Success;
g = _g;
con = 0;
callbacks = 0;
con = nullptr;
callbacks = nullptr;
reset();
}
~saslContext()
~saslContext() override
{
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;
}
virtual void reset()
void reset() override
{
resetState();
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;
host = _host;
localAddr = local ? addrString(*local) : "";
remoteAddr = remote ? addrString(*remote) : "";
localAddr = local ? addrString(*local) : QLatin1String("");
remoteAddr = remote ? addrString(*remote) : QLatin1String("");
ext_authid = ext_id;
ext_ssf = _ext_ssf;
}
virtual int ssf() const
int ssf() const override
{
return result_ssf;
}
virtual void startClient(const QStringList &mechlist, bool allowClientSendFirst)
void startClient(const QStringList &mechlist, bool allowClientSendFirst) override
{
resetState();
in_sendFirst = allowClientSendFirst;
if (!g->client_init) {
sasl_client_init(NULL);
sasl_client_init(nullptr);
g->client_init = true;
}
callbacks = new sasl_callback_t[5];
callbacks[0].id = SASL_CB_GETREALM;
callbacks[0].proc = 0;
callbacks[0].context = 0;
callbacks[0].proc = nullptr;
callbacks[0].context = nullptr;
callbacks[1].id = SASL_CB_USER;
callbacks[1].proc = 0;
callbacks[1].context = 0;
callbacks[1].proc = nullptr;
callbacks[1].context = nullptr;
callbacks[2].id = SASL_CB_AUTHNAME;
callbacks[2].proc = 0;
callbacks[2].context = 0;
callbacks[2].proc = nullptr;
callbacks[2].context = nullptr;
callbacks[3].id = SASL_CB_PASS;
callbacks[3].proc = 0;
callbacks[3].context = 0;
callbacks[3].proc = nullptr;
callbacks[3].context = nullptr;
callbacks[4].id = SASL_CB_LIST_END;
callbacks[4].proc = 0;
callbacks[4].context = 0;
callbacks[4].proc = nullptr;
callbacks[4].context = nullptr;
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) {
setAuthCondition(r);
doResultsReady();
return;
}
if(!setsecprops())
{
if (!setsecprops()) {
doResultsReady();
return;
}
@ -670,14 +714,14 @@ public:
}
// TODO: make use of disableServerSendLast
virtual void startServer(const QString &realm, bool disableServerSendLast)
void startServer(const QString &realm, bool disableServerSendLast) override
{
Q_UNUSED(disableServerSendLast);
resetState();
g->appname = SASL_APP;
g->appname = QStringLiteral(SASL_APP);
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;
}
@ -688,29 +732,35 @@ public:
callbacks[0].context = this;
callbacks[1].id = SASL_CB_LIST_END;
callbacks[1].proc = 0;
callbacks[1].context = 0;
callbacks[1].proc = nullptr;
callbacks[1].context = nullptr;
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) {
setAuthCondition(r);
doResultsReady();
return;
}
if(!setsecprops())
{
if (!setsecprops()) {
doResultsReady();
return;
}
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)
return;
result_mechlist = QString::fromUtf8(ml).split(' ');
result_mechlist = QString::fromUtf8(ml).split(QLatin1Char(' '));
servermode = true;
step = 0;
@ -721,26 +771,26 @@ public:
return;
}
virtual void serverFirstStep(const QString &mech, const QByteArray *clientInit)
void serverFirstStep(const QString &mech, const QByteArray *clientInit) override
{
in_mech = mech;
if (clientInit) {
in_useClientInit = true;
in_clientInit = *clientInit;
}
else
} else
in_useClientInit = false;
serverTryAgain();
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);
}
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)
params.setUsername(*user);
@ -752,23 +802,23 @@ public:
params.setRealm(*realm);
}
virtual QString username() const
QString username() const override
{
return sc_username;
}
virtual QString authzid() const
QString authzid() const override
{
return sc_authzid;
}
virtual void nextStep(const QByteArray &from_net)
void nextStep(const QByteArray &from_net) override
{
in_buf = from_net;
tryAgain();
}
virtual void tryAgain()
void tryAgain() override
{
if (servermode)
serverTryAgain();
@ -777,7 +827,7 @@ public:
doResultsReady();
}
virtual QString mech() const
QString mech() const override
{
if (servermode)
return in_mech;
@ -785,18 +835,18 @@ public:
return out_mech;
}
virtual QStringList mechlist() const
QStringList mechlist() const override
{
return result_mechlist;
}
virtual QStringList realmlist() const
QStringList realmlist() const override
{
// TODO
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;
if (!(f & SASL::AllowPlain))
@ -819,14 +869,14 @@ public:
ssf_max = maxSSF;
}
virtual bool waitForResultsReady(int msecs)
bool waitForResultsReady(int msecs) override
{
// TODO: for now, all operations block anyway
Q_UNUSED(msecs);
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;
if (!from_app.isEmpty())
@ -836,41 +886,42 @@ public:
result_result = ok ? Success : Error;
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();
}
virtual bool haveClientInit() const
bool haveClientInit() const override
{
return result_haveClientInit;
}
virtual QByteArray stepData() const
QByteArray stepData() const override
{
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();
return a;
}
virtual int encoded() const
int encoded() const override
{
return result_encoded;
}
virtual QByteArray to_app()
QByteArray to_app() override
{
QByteArray a = result_plain;
const QByteArray a = result_plain;
result_plain.clear();
return a;
}
virtual SASL::AuthCondition authCondition() const
SASL::AuthCondition authCondition() const override
{
return result_authCondition;
}
@ -902,7 +953,7 @@ int saslProvider::qcaVersion() const
QString saslProvider::name() const
{
return "qca-cyrus-sasl";
return QStringLiteral("qca-cyrus-sasl");
}
QString saslProvider::credit() const
@ -913,17 +964,17 @@ QString saslProvider::credit() const
QStringList saslProvider::features() const
{
QStringList list;
list += "sasl";
list += QStringLiteral("sasl");
return list;
}
Provider::Context *saslProvider::createContext(const QString &type)
{
if ( type == "sasl" )
if (type == QLatin1String("sasl"))
return new saslContext(this);
return 0;
return nullptr;
}
} // namespace saslQCAPlugin
@ -937,16 +988,13 @@ using namespace saslQCAPlugin;
class saslPlugin : public QObject, public QCAPlugin
{
Q_OBJECT
#if QT_VERSION >= 0x050000
Q_PLUGIN_METADATA(IID "com.affinix.qca.Plugin/1.0")
#endif
Q_INTERFACES(QCAPlugin)
public:
virtual Provider *createProvider() { return new saslProvider; }
Provider *createProvider() override
{
return new saslProvider;
}
};
#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")
find_package(LibGcrypt REQUIRED)
else(WITH_gcrypt_PLUGIN STREQUAL "yes")
else()
find_package(LibGcrypt)
endif(WITH_gcrypt_PLUGIN STREQUAL "yes")
endif()
if(LIBGCRYPT_FOUND)
include(CheckTypeSize)
@ -19,14 +19,17 @@ if(LIBGCRYPT_FOUND)
set(QCA_GCRYPT_SOURCES qca-gcrypt.cpp)
add_definitions(${LIBGCRYPT_CFLAGS})
my_automoc(QCA_GCRYPT_SOURCES)
add_library(qca-gcrypt ${PLUGIN_TYPE} ${QCA_GCRYPT_SOURCES})
if(APPLE AND ${PLUGIN_TYPE} STREQUAL "MODULE")
set_property(TARGET qca-gcrypt PROPERTY SUFFIX ".dylib")
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)
install(TARGETS qca-gcrypt
@ -36,10 +39,10 @@ if(LIBGCRYPT_FOUND)
install_pdb(qca-gcrypt ${QCA_CRYPTO_INSTALL_DIR})
endif()
else(HAVE_GCRY_ERROR_T)
else()
message(STATUS "libgcrypt seems to be too old")
disable_plugin("gcrypt")
endif(HAVE_GCRY_ERROR_T)
else(LIBGCRYPT_FOUND)
endif()
else()
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
*/
gcry_error_t
gcry_pbkdf2 (int PRF, const char *P, size_t Plen, const char *S,
size_t Slen, unsigned int c, unsigned int dkLen, char *DK)
static gcry_error_t gcry_pbkdf2(int PRF,
const char * P,
size_t Plen,
const char * S,
size_t Slen,
unsigned int c,
unsigned int dkLen,
char * DK)
{
gcry_md_hd_t prf;
gcry_error_t rc;
@ -144,26 +149,22 @@ gcry_pbkdf2 (int PRF, const char *P, size_t Plen, const char *S,
return rc;
U = (char *)gcry_malloc(hLen);
if (!U)
{
if (!U) {
rc = GPG_ERR_ENOMEM;
goto done;
}
for (i = 1; i <= l; i++)
{
for (i = 1; i <= l; i++) {
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);
rc = gcry_md_setkey(prf, P, Plen);
if (rc != GPG_ERR_NO_ERROR) {
goto done;
}
if (u == 1)
{
if (u == 1) {
char tmp[4];
gcry_md_write(prf, S, Slen);
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[3] = (i & 0x000000ff) >> 0;
gcry_md_write(prf, tmp, 4);
}
else
} else
gcry_md_write(prf, U, hLen);
p = gcry_md_read(prf, PRF);
if (p == NULL)
{
if (p == nullptr) {
rc = GPG_ERR_CONFIGURATION;
goto done;
}
@ -194,4 +193,3 @@ gcry_pbkdf2 (int PRF, const char *P, size_t Plen, const char *S,
gcry_free(U);
return rc;
}

View File

@ -21,22 +21,23 @@
#include <QtCore/qplugin.h>
#include <QTime>
#include <QElapsedTimer>
#include <qstringlist.h>
#include <gcrypt.h>
#include <iostream>
#include <qstringlist.h>
namespace gcryptQCAPlugin {
#include "hkdf.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 also don't flag weak keys.
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_strerror(err) << std::endl;
}
@ -44,8 +45,10 @@ void check_error( const QString &label, gcry_error_t err )
class gcryHashContext : public QCA::HashContext
{
Q_OBJECT
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;
err = gcry_md_open(&context, m_hashAlgorithm, 0);
@ -56,27 +59,27 @@ public:
}
}
~gcryHashContext()
~gcryHashContext() override
{
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);
}
void update(const QCA::MemoryRegion &a)
void update(const QCA::MemoryRegion &a) override
{
gcry_md_write(context, a.data(), a.size());
}
QCA::MemoryRegion final()
QCA::MemoryRegion final() override
{
unsigned char * md;
QCA::SecureArray a(gcry_md_get_algo_dlen(m_hashAlgorithm));
@ -93,8 +96,10 @@ protected:
class gcryHMACContext : public QCA::MACContext
{
Q_OBJECT
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;
err = gcry_md_open(&context, m_hashAlgorithm, GCRY_MD_FLAG_HMAC);
@ -105,19 +110,19 @@ public:
}
}
~gcryHMACContext()
~gcryHMACContext() override
{
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());
}
Context *clone() const
Context *clone() const override
{
return new gcryHMACContext(*this);
return new gcryHMACContext(m_hashAlgorithm, provider(), type());
}
void clear()
@ -125,17 +130,17 @@ public:
gcry_md_reset(context);
}
QCA::KeyLength keyLength() const
QCA::KeyLength keyLength() const override
{
return anyKeyLength();
}
void update(const QCA::MemoryRegion &a)
void update(const QCA::MemoryRegion &a) override
{
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);
unsigned char * md;
@ -150,11 +155,12 @@ protected:
int m_hashAlgorithm;
};
class gcryCipherContext : public QCA::CipherContext
{
Q_OBJECT
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_mode = mode;
@ -164,7 +170,7 @@ public:
void setup(QCA::Direction dir,
const QCA::SymmetricKey & key,
const QCA::InitializationVector &iv,
const QCA::AuthTag &tag)
const QCA::AuthTag & tag) override
{
Q_UNUSED(tag);
m_direction = dir;
@ -185,31 +191,33 @@ public:
check_error("gcry_cipher_setiv", err);
}
Context *clone() const
Context *clone() const override
{
return new gcryCipherContext(*this);
}
int blockSize() const
int blockSize() const override
{
unsigned int blockSize;
gcry_cipher_algo_info( m_cryptoAlgorithm, GCRYCTL_GET_BLKLEN, 0, (size_t*)&blockSize );
size_t blockSize;
gcry_cipher_algo_info(m_cryptoAlgorithm, GCRYCTL_GET_BLKLEN, nullptr, &blockSize);
return blockSize;
}
QCA::AuthTag tag() const
QCA::AuthTag tag() const override
{
// For future implementation
return QCA::AuthTag();
}
bool update(const QCA::SecureArray &in, QCA::SecureArray *out)
bool update(const QCA::SecureArray &in, QCA::SecureArray *out) override
{
QCA::SecureArray result(in.size());
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 {
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);
result.resize(in.size());
@ -217,15 +225,15 @@ public:
return true;
}
bool final(QCA::SecureArray *out)
bool final(QCA::SecureArray *out) override
{
QCA::SecureArray result;
if (m_pad) {
result.resize(blockSize());
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 {
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);
} else {
@ -235,10 +243,9 @@ public:
return true;
}
QCA::KeyLength keyLength() const
{
switch (m_cryptoAlgorithm)
QCA::KeyLength keyLength() const override
{
switch (m_cryptoAlgorithm) {
case GCRY_CIPHER_DES:
return QCA::KeyLength(8, 8, 1);
case GCRY_CIPHER_AES128:
@ -258,7 +265,6 @@ public:
}
}
protected:
gcry_cipher_hd_t context;
gcry_error_t err;
@ -268,11 +274,12 @@ protected:
bool m_pad;
};
class pbkdf1Context : public QCA::KDFContext
{
Q_OBJECT
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;
err = gcry_md_open(&context, m_hashAlgorithm, 0);
@ -283,18 +290,20 @@ public:
}
}
~pbkdf1Context()
~pbkdf1Context() override
{
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,
unsigned int keyLength, unsigned int iterationCount)
QCA::SymmetricKey makeKey(const QCA::SecureArray & secret,
const QCA::InitializationVector &salt,
unsigned int keyLength,
unsigned int iterationCount) override
{
/* from RFC2898:
Steps:
@ -347,10 +356,10 @@ public:
const QCA::InitializationVector &salt,
unsigned int keyLength,
int msecInterval,
unsigned int *iterationCount)
unsigned int * iterationCount) override
{
Q_ASSERT(iterationCount != NULL);
QTime timer;
Q_ASSERT(iterationCount != nullptr);
QElapsedTimer timer;
/*
from RFC2898:
@ -412,27 +421,35 @@ protected:
int m_hashAlgorithm;
};
class pbkdf2Context : public QCA::KDFContext
{
Q_OBJECT
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;
}
Context *clone() const
Context *clone() const override
{
return new pbkdf2Context(*this);
}
QCA::SymmetricKey makeKey(const QCA::SecureArray &secret, const QCA::InitializationVector &salt,
unsigned int keyLength, unsigned int iterationCount)
QCA::SymmetricKey makeKey(const QCA::SecureArray & secret,
const QCA::InitializationVector &salt,
unsigned int keyLength,
unsigned int iterationCount) override
{
QCA::SymmetricKey result(keyLength);
gcry_error_t retval = gcry_pbkdf2(m_algorithm, secret.data(), secret.size(),
salt.data(), salt.size(),
iterationCount, keyLength, result.data());
gcry_error_t retval = gcry_pbkdf2(m_algorithm,
secret.data(),
secret.size(),
salt.data(),
salt.size(),
iterationCount,
keyLength,
result.data());
if (retval == GPG_ERR_NO_ERROR) {
return result;
} else {
@ -445,24 +462,18 @@ public:
const QCA::InitializationVector &salt,
unsigned int keyLength,
int msecInterval,
unsigned int *iterationCount)
unsigned int * iterationCount) override
{
Q_ASSERT(iterationCount != NULL);
Q_ASSERT(iterationCount != nullptr);
QCA::SymmetricKey result(keyLength);
QTime timer;
QElapsedTimer timer;
*iterationCount = 0;
timer.start();
while (timer.elapsed() < msecInterval) {
gcry_pbkdf2(m_algorithm,
secret.data(),
secret.size(),
salt.data(),
salt.size(),
1,
keyLength,
result.data());
gcry_pbkdf2(
m_algorithm, secret.data(), secret.size(), salt.data(), salt.size(), 1, keyLength, result.data());
++(*iterationCount);
}
@ -473,10 +484,50 @@ protected:
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)
{
@ -507,193 +558,192 @@ int qca_func_secure_check (const void *)
class gcryptProvider : public QCA::Provider
{
public:
void init()
void init() override
{
if (!gcry_control (GCRYCTL_ANY_INITIALIZATION_P))
{ /* No other library has already initialized libgcrypt. */
if (!gcry_control(GCRYCTL_ANY_INITIALIZATION_P)) { /* 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 << ", have " << gcry_check_version(NULL) << ")" << std::endl;
std::cout << ", have " << gcry_check_version(nullptr) << ")" << std::endl;
}
gcry_set_allocation_handler (qca_func_malloc,
qca_func_secure_malloc,
qca_func_secure_check,
qca_func_realloc,
qca_func_free);
gcry_set_allocation_handler(
qca_func_malloc, qca_func_secure_malloc, qca_func_secure_check, qca_func_realloc, qca_func_free);
gcry_control(GCRYCTL_INITIALIZATION_FINISHED);
}
}
int qcaVersion() const
int qcaVersion() const override
{
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;
list += "sha1";
list += "md4";
list += "md5";
list += "ripemd160";
list += QStringLiteral("sha1");
list += QStringLiteral("md4");
list += QStringLiteral("md5");
list += QStringLiteral("ripemd160");
#ifdef GCRY_MD_SHA224
list += "sha224";
list += QStringLiteral("sha224");
#endif
list += "sha256";
list += "sha384";
list += "sha512";
list += "hmac(md5)";
list += "hmac(sha1)";
list += QStringLiteral("sha256");
list += QStringLiteral("sha384");
list += QStringLiteral("sha512");
list += QStringLiteral("hmac(md5)");
list += QStringLiteral("hmac(sha1)");
#ifdef GCRY_MD_SHA224
list += "hmac(sha224)";
list += QStringLiteral("hmac(sha224)");
#endif
list += "hmac(sha256)";
if ( ! ( NULL == gcry_check_version("1.3.0") ) ) {
list += QStringLiteral("hmac(sha256)");
if (!(nullptr == gcry_check_version("1.3.0"))) {
// 1.2 and earlier have broken implementation
list += "hmac(sha384)";
list += "hmac(sha512)";
list += QStringLiteral("hmac(sha384)");
list += QStringLiteral("hmac(sha512)");
}
list += "hmac(ripemd160)";
list += "aes128-ecb";
list += "aes128-cfb";
list += "aes128-cbc";
list += "aes192-ecb";
list += "aes192-cfb";
list += "aes192-cbc";
list += "aes256-ecb";
list += "aes256-cfb";
list += "aes256-cbc";
list += "blowfish-ecb";
list += "blowfish-cbc";
list += "blowfish-cfb";
list += "tripledes-ecb";
list += "des-ecb";
list += "des-cbc";
list += "des-cfb";
if ( ! ( NULL == gcry_check_version("1.3.0") ) ) {
list += QStringLiteral("hmac(ripemd160)");
list += QStringLiteral("aes128-ecb");
list += QStringLiteral("aes128-cfb");
list += QStringLiteral("aes128-cbc");
list += QStringLiteral("aes192-ecb");
list += QStringLiteral("aes192-cfb");
list += QStringLiteral("aes192-cbc");
list += QStringLiteral("aes256-ecb");
list += QStringLiteral("aes256-cfb");
list += QStringLiteral("aes256-cbc");
list += QStringLiteral("blowfish-ecb");
list += QStringLiteral("blowfish-cbc");
list += QStringLiteral("blowfish-cfb");
list += QStringLiteral("tripledes-ecb");
// list += QStringLiteral("des-ecb");
list += QStringLiteral("des-cbc");
list += QStringLiteral("des-cfb");
if (!(nullptr == gcry_check_version("1.3.0"))) {
// 1.2 branch and earlier doesn't support OFB mode
list += "aes128-ofb";
list += "aes192-ofb";
list += "aes256-ofb";
list += "des-ofb";
list += "tripledes-ofb";
list += "blowfish-ofb";
list += QStringLiteral("aes128-ofb");
list += QStringLiteral("aes192-ofb");
list += QStringLiteral("aes256-ofb");
list += QStringLiteral("des-ofb");
list += QStringLiteral("tripledes-ofb");
list += QStringLiteral("blowfish-ofb");
}
list += "pbkdf1(sha1)";
list += "pbkdf2(sha1)";
list += QStringLiteral("pbkdf1(sha1)");
list += QStringLiteral("pbkdf2(sha1)");
list += QStringLiteral("hkdf(sha256)");
return list;
}
Context *createContext(const QString &type)
Context *createContext(const QString &type) override
{
// std::cout << "type: " << qPrintable(type) << std::endl;
if ( type == "sha1" )
if (type == QLatin1String("sha1"))
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);
else if ( type == "md5" )
else if (type == QLatin1String("md5"))
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);
#ifdef GCRY_MD_SHA224
else if ( type == "sha224" )
else if (type == QLatin1String("sha224"))
return new gcryptQCAPlugin::gcryHashContext(GCRY_MD_SHA224, this, type);
#endif
else if ( type == "sha256" )
else if (type == QLatin1String("sha256"))
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);
else if ( type == "sha512" )
else if (type == QLatin1String("sha512"))
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);
else if ( type == "hmac(sha1)" )
else if (type == QLatin1String("hmac(sha1)"))
return new gcryptQCAPlugin::gcryHMACContext(GCRY_MD_SHA1, this, type);
#ifdef GCRY_MD_SHA224
else if ( type == "hmac(sha224)" )
else if (type == QLatin1String("hmac(sha224)"))
return new gcryptQCAPlugin::gcryHMACContext(GCRY_MD_SHA224, this, type);
#endif
else if ( type == "hmac(sha256)" )
else if (type == QLatin1String("hmac(sha256)"))
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);
else if ( type == "hmac(sha512)" )
else if (type == QLatin1String("hmac(sha512)"))
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);
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);
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);
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);
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);
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);
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);
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);
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);
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);
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);
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);
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);
else if ( type == "blowfish-ecb" )
return new gcryptQCAPlugin::gcryCipherContext( GCRY_CIPHER_BLOWFISH, GCRY_CIPHER_MODE_ECB, false, this, type );
else if ( type == "blowfish-cbc" )
return new gcryptQCAPlugin::gcryCipherContext( GCRY_CIPHER_BLOWFISH, GCRY_CIPHER_MODE_CBC, false, this, type );
else if ( type == "blowfish-cfb" )
return new gcryptQCAPlugin::gcryCipherContext( GCRY_CIPHER_BLOWFISH, GCRY_CIPHER_MODE_CFB, false, this, type );
else if ( type == "blowfish-ofb" )
return new gcryptQCAPlugin::gcryCipherContext( GCRY_CIPHER_BLOWFISH, GCRY_CIPHER_MODE_OFB, false, this, type );
else if ( type == "tripledes-ecb" )
else if (type == QLatin1String("blowfish-ecb"))
return new gcryptQCAPlugin::gcryCipherContext(
GCRY_CIPHER_BLOWFISH, GCRY_CIPHER_MODE_ECB, false, this, type);
else if (type == QLatin1String("blowfish-cbc"))
return new gcryptQCAPlugin::gcryCipherContext(
GCRY_CIPHER_BLOWFISH, GCRY_CIPHER_MODE_CBC, false, this, type);
else if (type == QLatin1String("blowfish-cfb"))
return new gcryptQCAPlugin::gcryCipherContext(
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);
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);
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);
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);
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);
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);
else if ( type == "pbkdf1(sha1)" )
else if (type == QLatin1String("pbkdf1(sha1)"))
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);
else if (type == QLatin1String("hkdf(sha256)"))
return new gcryptQCAPlugin::hkdfContext(GCRY_MD_SHA256, this, type);
else
return 0;
return nullptr;
}
};
class gcryptPlugin : public QObject, public QCAPlugin
{
Q_OBJECT
#if QT_VERSION >= 0x050000
Q_PLUGIN_METADATA(IID "com.affinix.qca.Plugin/1.0")
#endif
Q_INTERFACES(QCAPlugin)
public:
virtual QCA::Provider *createProvider() { return new gcryptProvider; }
QCA::Provider *createProvider() override
{
return new gcryptProvider;
}
};
#include "qca-gcrypt.moc"
#if QT_VERSION < 0x050000
Q_EXPORT_PLUGIN2(qca_gcrypt, gcryptPlugin)
#endif

View File

@ -2,11 +2,8 @@
enable_plugin("gnupg")
set(QCA_GNUPG_MOC_SOURCES
set(QCA_GNUPG_SOURCES
qca-gnupg.cpp
)
set(QCA_GNUPG_NONMOC_SOURCES
gpgop.cpp
utils.cpp
gpgproc/sprocess.cpp
@ -38,30 +35,22 @@ set(QCA_GNUPG_HEADERS
myopenpgpcontext.h
)
my_automoc(QCA_GNUPG_MOC_SOURCES)
qt4_wrap_cpp(EXTRA_GNUPG_SOURCES gpgop.h)
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} ${QCA_GNUPG_HEADERS})
add_library(qca-gnupg ${PLUGIN_TYPE} ${QCA_GNUPG_SOURCES} ${EXTRA_GNUPG_SOURCES} ${QCA_GNUPG_HEADERS})
if(APPLE AND ${PLUGIN_TYPE} STREQUAL "MODULE")
set_property(TARGET qca-gnupg PROPERTY SUFFIX ".dylib")
endif()
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)
target_link_libraries(qca-gnupg advapi32)
endif (WIN32)
endif()
if(NOT DEVELOPER_MODE)
install(TARGETS qca-gnupg DESTINATION

View File

@ -32,15 +32,10 @@ static QDateTime getTimestamp(const QString &s)
if (s.isEmpty())
return QDateTime();
if(s.contains('T'))
{
if (s.contains(QLatin1Char('T'))) {
return QDateTime::fromString(s, Qt::ISODate);
}
else
{
QDateTime dt;
dt.setTime_t(s.toInt());
return dt;
} else {
return QDateTime::fromSecsSinceEpoch(s.toInt());
}
}
@ -49,37 +44,27 @@ static QByteArray getCString(const QByteArray &a)
QByteArray out;
// convert the "backslash" C-string syntax
for(int n = 0; n < a.size(); ++n)
{
if(a[n] == '\\' && n + 1 < a.size())
{
for (int n = 0; n < a.size(); ++n) {
if (a[n] == '\\' && n + 1 < a.size()) {
++n;
unsigned char c = (unsigned char)a[n];
if(c == '\\')
{
if (c == '\\') {
out += '\\';
}
else if(c == 'x' && n + 2 < a.size())
{
} else if (c == 'x' && n + 2 < a.size()) {
++n;
QByteArray hex = a.mid(n, 2);
const QByteArray hex = a.mid(n, 2);
++n; // only skip one, loop will skip the next
bool ok;
uint val = hex.toInt(&ok, 16);
if(ok)
{
if (ok) {
out += (unsigned char)val;
}
else
{
} else {
out += "\\x";
out += hex;
}
}
}
else
{
} else {
out += a[n];
}
}
@ -90,7 +75,7 @@ static QByteArray getCString(const QByteArray &a)
static bool stringToKeyList(const QString &outstr, GpgOp::KeyList *_keylist, QString *_keyring)
{
GpgOp::KeyList keyList;
QStringList lines = outstr.split('\n');
const QStringList lines = outstr.split(QLatin1Char('\n'));
if (lines.count() < 1)
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
// with a new version of gnupg that doesn't give us
// 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...
keyring.clear();
// ...so read the first line again
it--;
}
else
{
} else {
// this was the divider line - skip it
it++;
}
for(; it != lines.constEnd(); ++it)
{
QStringList f = (*it).split(':');
for (; it != lines.constEnd(); ++it) {
const QStringList f = (*it).split(QLatin1Char(':'));
if (f.count() < 1)
continue;
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 sec = false; // private key or not
if(type == "pub")
{
if (type == QLatin1String("pub")) {
key = true;
primary = true;
}
else if(type == "sec")
{
} else if (type == QLatin1String("sec")) {
key = true;
primary = true;
// sec = true;
}
else if(type == "sub")
{
} else if (type == QLatin1String("sub")) {
key = true;
}
else if(type == "ssb")
{
} else if (type == QLatin1String("ssb")) {
key = true;
// sec = true;
}
if(key)
{
if(primary)
{
if (key) {
if (primary) {
keyList += GpgOp::Key();
QString trust = f[1];
if(trust == "f" || trust == "u")
if (trust == QLatin1String("f") || trust == QLatin1String("u"))
keyList.last().isTrusted = true;
}
int key_type = f[3].toInt();
QString caps = f[11];
const int key_type = f[3].toInt();
const QString caps = f[11];
GpgOp::KeyItem item;
item.bits = f[2].toInt();
@ -175,24 +147,20 @@ static bool stringToKeyList(const QString &outstr, GpgOp::KeyList *_keylist, QSt
item.id = f[4];
item.creationDate = getTimestamp(f[5]);
item.expirationDate = getTimestamp(f[6]);
if(caps.contains('e'))
if (caps.contains(QLatin1Char('e')))
item.caps |= GpgOp::KeyItem::Encrypt;
if(caps.contains('s'))
if (caps.contains(QLatin1Char('s')))
item.caps |= GpgOp::KeyItem::Sign;
if(caps.contains('c'))
if (caps.contains(QLatin1Char('c')))
item.caps |= GpgOp::KeyItem::Certify;
if(caps.contains('a'))
if (caps.contains(QLatin1Char('a')))
item.caps |= GpgOp::KeyItem::Auth;
keyList.last().keyItems += item;
}
else if(type == "uid")
{
QByteArray uid = getCString(f[9].toUtf8());
} else if (type == QLatin1String("uid")) {
const QByteArray uid = getCString(f[9].toUtf8());
keyList.last().userIds.append(QString::fromUtf8(uid));
}
else if(type == "fpr")
{
} else if (type == QLatin1String("fpr")) {
QString s = f[9];
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)
{
QStringList lines = outstr.split('\n');
const QStringList lines = outstr.split(QLatin1Char('\n'));
if (lines.count() < 1)
return false;
@ -224,16 +192,16 @@ GpgAction::GpgAction(QObject *parent)
{
dtextTimer.setSingleShot(true);
connect(&proc, SIGNAL(error(gpgQCAPlugin::GPGProc::Error)), SLOT(proc_error(gpgQCAPlugin::GPGProc::Error)));
connect(&proc, SIGNAL(finished(int)), SLOT(proc_finished(int)));
connect(&proc, SIGNAL(readyReadStdout()), SLOT(proc_readyReadStdout()));
connect(&proc, SIGNAL(readyReadStderr()), SLOT(proc_readyReadStderr()));
connect(&proc, SIGNAL(readyReadStatusLines()), SLOT(proc_readyReadStatusLines()));
connect(&proc, SIGNAL(bytesWrittenStdin(int)), SLOT(proc_bytesWrittenStdin(int)));
connect(&proc, SIGNAL(bytesWrittenAux(int)), SLOT(proc_bytesWrittenAux(int)));
connect(&proc, SIGNAL(bytesWrittenCommand(int)), SLOT(proc_bytesWrittenCommand(int)));
connect(&proc, SIGNAL(debug(const QString &)), SLOT(proc_debug(const QString &)));
connect(&dtextTimer, SIGNAL(timeout()), SLOT(t_dtext()));
connect(&proc, &GPGProc::error, this, &GpgAction::proc_error);
connect(&proc, &GPGProc::finished, this, &GpgAction::proc_finished);
connect(&proc, &GPGProc::readyReadStdout, this, &GpgAction::proc_readyReadStdout);
connect(&proc, &GPGProc::readyReadStderr, this, &GpgAction::proc_readyReadStderr);
connect(&proc, &GPGProc::readyReadStatusLines, this, &GpgAction::proc_readyReadStatusLines);
connect(&proc, &GPGProc::bytesWrittenStdin, this, &GpgAction::proc_bytesWrittenStdin);
connect(&proc, &GPGProc::bytesWrittenAux, this, &GpgAction::proc_bytesWrittenAux);
connect(&proc, &GPGProc::bytesWrittenCommand, this, &GpgAction::proc_bytesWrittenCommand);
connect(&proc, &GPGProc::debug, this, &GpgAction::proc_debug);
connect(&dtextTimer, &QCA::SafeTimer::timeout, this, &GpgAction::t_dtext);
reset();
}
@ -276,80 +244,77 @@ void GpgAction::start()
bool extra = false;
if (input.opt_ascii)
args += "--armor";
args += QStringLiteral("--armor");
if (input.opt_noagent)
args += "--no-use-agent";
args += QStringLiteral("--no-use-agent");
if (input.opt_alwaystrust)
args += "--always-trust";
args += QStringLiteral("--always-trust");
if(!input.opt_pubfile.isEmpty() && !input.opt_secfile.isEmpty())
{
args += "--no-default-keyring";
args += "--keyring";
if (!input.opt_pubfile.isEmpty() && !input.opt_secfile.isEmpty()) {
args += QStringLiteral("--no-default-keyring");
args += QStringLiteral("--keyring");
args += input.opt_pubfile;
args += "--secret-keyring";
args += QStringLiteral("--secret-keyring");
args += input.opt_secfile;
}
switch(input.op)
{
switch (input.op) {
case GpgOp::Check:
{
args += "--version";
args += QStringLiteral("--version");
readText = true;
break;
}
case GpgOp::SecretKeyringFile:
{
#ifndef Q_OS_WIN
args += "--display-charset=utf-8";
args += QStringLiteral("--display-charset=utf-8");
#endif
args += "--list-secret-keys";
args += QStringLiteral("--list-secret-keys");
readText = true;
break;
}
case GpgOp::PublicKeyringFile:
{
#ifndef Q_OS_WIN
args += "--display-charset=utf-8";
args += QStringLiteral("--display-charset=utf-8");
#endif
args += "--list-public-keys";
args += QStringLiteral("--list-public-keys");
readText = true;
break;
}
case GpgOp::SecretKeys:
{
args += "--fixed-list-mode";
args += "--with-colons";
args += "--with-fingerprint";
args += "--with-fingerprint";
args += "--list-secret-keys";
args += QStringLiteral("--fixed-list-mode");
args += QStringLiteral("--with-colons");
args += QStringLiteral("--with-fingerprint");
args += QStringLiteral("--with-fingerprint");
args += QStringLiteral("--list-secret-keys");
utf8Output = true;
readText = true;
break;
}
case GpgOp::PublicKeys:
{
args += "--fixed-list-mode";
args += "--with-colons";
args += "--with-fingerprint";
args += "--with-fingerprint";
args += "--list-public-keys";
args += QStringLiteral("--fixed-list-mode");
args += QStringLiteral("--with-colons");
args += QStringLiteral("--with-fingerprint");
args += QStringLiteral("--with-fingerprint");
args += QStringLiteral("--list-public-keys");
utf8Output = true;
readText = true;
break;
}
case GpgOp::Encrypt:
{
args += "--encrypt";
args += QStringLiteral("--encrypt");
// recipients
for(QStringList::ConstIterator it = input.recip_ids.constBegin(); it != input.recip_ids.constEnd(); ++it)
{
args += "--recipient";
args += QString("0x") + *it;
for (QStringList::ConstIterator it = input.recip_ids.constBegin(); it != input.recip_ids.constEnd(); ++it) {
args += QStringLiteral("--recipient");
args += QStringLiteral("0x") + *it;
}
extra = true;
collectOutput = false;
@ -360,7 +325,7 @@ void GpgAction::start()
}
case GpgOp::Decrypt:
{
args += "--decrypt";
args += QStringLiteral("--decrypt");
extra = true;
collectOutput = false;
allowInput = true;
@ -370,9 +335,9 @@ void GpgAction::start()
}
case GpgOp::Sign:
{
args += "--default-key";
args += QString("0x") + input.signer_id;
args += "--sign";
args += QStringLiteral("--default-key");
args += QStringLiteral("0x") + input.signer_id;
args += QStringLiteral("--sign");
extra = true;
collectOutput = false;
allowInput = true;
@ -383,16 +348,15 @@ void GpgAction::start()
}
case GpgOp::SignAndEncrypt:
{
args += "--default-key";
args += QString("0x") + input.signer_id;
args += "--sign";
args += "--encrypt";
args += QStringLiteral("--default-key");
args += QStringLiteral("0x") + input.signer_id;
args += QStringLiteral("--sign");
args += QStringLiteral("--encrypt");
// recipients
for(QStringList::ConstIterator it = input.recip_ids.constBegin(); it != input.recip_ids.constEnd(); ++it)
{
args += "--recipient";
args += QString("0x") + *it;
for (QStringList::ConstIterator it = input.recip_ids.constBegin(); it != input.recip_ids.constEnd(); ++it) {
args += QStringLiteral("--recipient");
args += QStringLiteral("0x") + *it;
}
extra = true;
collectOutput = false;
@ -404,9 +368,9 @@ void GpgAction::start()
}
case GpgOp::SignClearsign:
{
args += "--default-key";
args += QString("0x") + input.signer_id;
args += "--clearsign";
args += QStringLiteral("--default-key");
args += QStringLiteral("0x") + input.signer_id;
args += QStringLiteral("--clearsign");
extra = true;
collectOutput = false;
allowInput = true;
@ -417,9 +381,9 @@ void GpgAction::start()
}
case GpgOp::SignDetached:
{
args += "--default-key";
args += QString("0x") + input.signer_id;
args += "--detach-sign";
args += QStringLiteral("--default-key");
args += QStringLiteral("0x") + input.signer_id;
args += QStringLiteral("--detach-sign");
extra = true;
collectOutput = false;
allowInput = true;
@ -430,8 +394,8 @@ void GpgAction::start()
}
case GpgOp::Verify:
{
args += "--verify";
args += "-"; //krazy:exclude=doublequote_chars
args += QStringLiteral("--verify");
args += QStringLiteral("-"); // krazy:exclude=doublequote_chars
extra = true;
allowInput = true;
if (input.opt_ascii)
@ -440,9 +404,9 @@ void GpgAction::start()
}
case GpgOp::VerifyDetached:
{
args += "--verify";
args += "-"; //krazy:exclude=doublequote_chars
args += "-&?";
args += QStringLiteral("--verify");
args += QStringLiteral("-"); // krazy:exclude=doublequote_chars
args += QStringLiteral("-&?");
extra = true;
allowInput = true;
useAux = true;
@ -450,7 +414,7 @@ void GpgAction::start()
}
case GpgOp::Import:
{
args += "--import";
args += QStringLiteral("--import");
readText = true;
if (input.opt_ascii)
writeText = true;
@ -458,8 +422,8 @@ void GpgAction::start()
}
case GpgOp::Export:
{
args += "--export";
args += QString("0x") + input.export_key_id;
args += QStringLiteral("--export");
args += QStringLiteral("0x") + input.export_key_id;
collectOutput = false;
if (input.opt_ascii)
readText = true;
@ -467,9 +431,9 @@ void GpgAction::start()
}
case GpgOp::DeleteKey:
{
args += "--batch";
args += "--delete-key";
args += QString("0x") + input.delete_key_fingerprint;
args += QStringLiteral("--batch");
args += QStringLiteral("--delete-key");
args += QStringLiteral("0x") + input.delete_key_fingerprint;
break;
}
}
@ -481,11 +445,9 @@ void GpgAction::start()
proc.start(input.bin, args, extra ? GPGProc::ExtendedMode : GPGProc::NormalMode);
// detached sig
if(input.op == GpgOp::VerifyDetached)
{
if (input.op == GpgOp::VerifyDetached) {
QByteArray a = input.sig;
if(input.opt_ascii)
{
if (input.opt_ascii) {
LineConverter conv;
conv.setup(LineConverter::Write);
a = conv.process(a);
@ -495,11 +457,9 @@ void GpgAction::start()
}
// import
if(input.op == GpgOp::Import)
{
if (input.op == GpgOp::Import) {
QByteArray a = input.inkey;
if(writeText)
{
if (writeText) {
LineConverter conv;
conv.setup(LineConverter::Write);
a = conv.process(a);
@ -529,8 +489,7 @@ void GpgAction::submitPassphrase(const QCA::SecureArray &a)
// to indicate a submitted passphrase
b.resize(a.size());
int at = 0;
for(int n = 0; n < a.size(); ++n)
{
for (int n = 0; n < a.size(); ++n) {
if (a[n] != '\n')
b[at++] = a[n];
}
@ -583,8 +542,7 @@ void GpgAction::endWrite()
void GpgAction::cardOkay()
{
if(need_cardOkay)
{
if (need_cardOkay) {
need_cardOkay = false;
submitCommand("\n");
}
@ -605,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'
QString GpgAction::nextArg(QString str, QString *rest)
{
QString out;
int n = str.indexOf(' ');
if(n == -1)
{
int n = str.indexOf(QLatin1Char(' '));
if (n == -1) {
if (rest)
*rest = QString();
return str;
}
else
{
} else {
if (rest)
*rest = str.mid(n + 1);
return str.mid(0, n);
@ -623,7 +577,7 @@ QString GpgAction::nextArg(QString str, QString *rest)
void GpgAction::processStatusLine(const QString &line)
{
appendDiagnosticText("{" + line + "}");
appendDiagnosticText(QStringLiteral("{") + line + QStringLiteral("}"));
ensureDTextEmit();
if (!proc.isActive())
@ -632,35 +586,23 @@ void GpgAction::processStatusLine(const QString &line)
QString s, rest;
s = nextArg(line, &rest);
if(s == "NODATA")
{
if (s == QLatin1String("NODATA")) {
// only set this if it'll make it better
if (curError == GpgOp::ErrorUnknown)
curError = GpgOp::ErrorFormat;
}
else if(s == "UNEXPECTED")
{
} else if (s == QLatin1String("UNEXPECTED")) {
if (curError == GpgOp::ErrorUnknown)
curError = GpgOp::ErrorFormat;
}
else if(s == "EXPKEYSIG")
{
} else if (s == QLatin1String("EXPKEYSIG")) {
curError = GpgOp::ErrorSignerExpired;
}
else if(s == "REVKEYSIG")
{
} else if (s == QLatin1String("REVKEYSIG")) {
curError = GpgOp::ErrorSignerRevoked;
}
else if(s == "EXPSIG")
{
} else if (s == QLatin1String("EXPSIG")) {
curError = GpgOp::ErrorSignatureExpired;
}
else if(s == "INV_RECP")
{
int r = nextArg(rest).toInt();
} else if (s == QLatin1String("INV_RECP")) {
const int r = nextArg(rest).toInt();
if(curError == GpgOp::ErrorUnknown)
{
if (curError == GpgOp::ErrorUnknown) {
if (r == 10)
curError = GpgOp::ErrorEncryptUntrusted;
else if (r == 4)
@ -675,88 +617,60 @@ void GpgAction::processStatusLine(const QString &line)
// defaulting to this
curError = GpgOp::ErrorEncryptInvalid;
}
}
else if(s == "NO_SECKEY")
{
} else if (s == QLatin1String("NO_SECKEY")) {
output.encryptedToId = nextArg(rest);
if (curError == GpgOp::ErrorUnknown)
curError = GpgOp::ErrorDecryptNoKey;
}
else if(s == "DECRYPTION_OKAY")
{
} else if (s == QLatin1String("DECRYPTION_OKAY")) {
decryptGood = true;
// message could be encrypted with several keys
if (curError == GpgOp::ErrorDecryptNoKey)
curError = GpgOp::ErrorUnknown;
}
else if(s == "SIG_CREATED")
{
} else if (s == QLatin1String("SIG_CREATED")) {
signGood = true;
}
else if(s == "USERID_HINT")
{
} else if (s == QLatin1String("USERID_HINT")) {
passphraseKeyId = nextArg(rest);
}
else if(s == "GET_HIDDEN")
{
} else if (s == QLatin1String("GET_HIDDEN")) {
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;
// for signal-safety, emit later
QMetaObject::invokeMethod(this, "needPassphrase", Qt::QueuedConnection, Q_ARG(QString, passphraseKeyId));
}
}
else if(s == "GET_LINE")
{
} else if (s == QLatin1String("GET_LINE")) {
QString arg = nextArg(rest);
if(arg == "cardctrl.insert_card.okay")
{
if (arg == QLatin1String("cardctrl.insert_card.okay")) {
need_cardOkay = true;
QMetaObject::invokeMethod(this, "needCard", Qt::QueuedConnection);
}
}
else if(s == "GET_BOOL")
{
} else if (s == QLatin1String("GET_BOOL")) {
QString arg = nextArg(rest);
if(arg == "untrusted_key.override")
if (arg == QLatin1String("untrusted_key.override"))
submitCommand("no\n");
}
else if(s == "GOOD_PASSPHRASE")
{
} else if (s == QLatin1String("GOOD_PASSPHRASE")) {
badPassphrase = false;
}
else if(s == "BAD_PASSPHRASE")
{
} else if (s == QLatin1String("BAD_PASSPHRASE")) {
badPassphrase = true;
}
else if(s == "GOODSIG")
{
} else if (s == QLatin1String("GOODSIG")) {
output.wasSigned = true;
output.signerId = nextArg(rest);
output.verifyResult = GpgOp::VerifyGood;
}
else if(s == "BADSIG")
{
} else if (s == QLatin1String("BADSIG")) {
output.wasSigned = true;
output.signerId = nextArg(rest);
output.verifyResult = GpgOp::VerifyBad;
}
else if(s == "ERRSIG")
{
} else if (s == QLatin1String("ERRSIG")) {
output.wasSigned = true;
QStringList list = rest.split(' ', QString::SkipEmptyParts);
const QStringList list = rest.split(QLatin1Char(' '), Qt::SkipEmptyParts);
output.signerId = list[0];
output.timestamp = getTimestamp(list[4]);
output.verifyResult = GpgOp::VerifyNoKey;
}
else if(s == "VALIDSIG")
{
QStringList list = rest.split(' ', QString::SkipEmptyParts);
} else if (s == QLatin1String("VALIDSIG")) {
const QStringList list = rest.split(QLatin1Char(' '), Qt::SkipEmptyParts);
output.timestamp = getTimestamp(list[2]);
}
}
@ -773,13 +687,10 @@ void GpgAction::processResult(int code)
QString errstr;
#ifdef Q_OS_WIN
if (!utf8Output)
{
if (!utf8Output) {
outstr = QString::fromLocal8Bit(buf_stdout);
errstr = QString::fromLocal8Bit(buf_stderr);
}
else
{
} else {
#endif
outstr = QString::fromUtf8(buf_stdout);
errstr = QString::fromUtf8(buf_stderr);
@ -788,48 +699,34 @@ void GpgAction::processResult(int code)
#endif
if (collectOutput)
appendDiagnosticText(QString("stdout: [%1]").arg(outstr));
appendDiagnosticText(QString("stderr: [%1]").arg(errstr));
appendDiagnosticText(QStringLiteral("stdout: [%1]").arg(outstr));
appendDiagnosticText(QStringLiteral("stderr: [%1]").arg(errstr));
ensureDTextEmit();
if(badPassphrase)
{
if (badPassphrase) {
output.errorCode = GpgOp::ErrorPassphrase;
}
else if(curError != GpgOp::ErrorUnknown)
{
} else if (curError != GpgOp::ErrorUnknown) {
output.errorCode = curError;
}
else if(code == 0)
{
if(input.op == GpgOp::Check)
{
QStringList strList = outstr.split("\n");
foreach (const QString &str, strList)
{
if (!str.startsWith("Home: "))
} 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(' ', 1);
output.homeDir = str.section(QLatin1Char(' '), 1);
break;
}
output.success = true;
}
else if(input.op == GpgOp::SecretKeyringFile || input.op == GpgOp::PublicKeyringFile)
{
} else if (input.op == GpgOp::SecretKeyringFile || input.op == GpgOp::PublicKeyringFile) {
if (findKeyringFilename(outstr, &output.keyringFile))
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))
output.success = true;
}
else
} else
output.success = true;
}
else
{
} else {
// decrypt and sign success based on status only.
// this is mainly because gpg uses fatal return
// values if there is trouble with gpg-agent, even
@ -869,13 +766,13 @@ void GpgAction::proc_error(gpgQCAPlugin::GPGProc::Error e)
{
QString str;
if (e == GPGProc::FailedToStart)
str = "FailedToStart";
str = QStringLiteral("FailedToStart");
else if (e == GPGProc::UnexpectedExit)
str = "UnexpectedExit";
str = QStringLiteral("UnexpectedExit");
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();
output.errorCode = GpgOp::ErrorProcess;
@ -884,7 +781,7 @@ void GpgAction::proc_error(gpgQCAPlugin::GPGProc::Error e)
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();
processResult(exitCode);
@ -892,14 +789,12 @@ void GpgAction::proc_finished(int exitCode)
void GpgAction::proc_readyReadStdout()
{
if(collectOutput)
{
if (collectOutput) {
QByteArray a = proc.readStdout();
if (readText)
a = readConv.update(a);
buf_stdout.append(a);
}
else
} else
emit readyRead();
}
@ -910,15 +805,14 @@ void GpgAction::proc_readyReadStderr()
void GpgAction::proc_readyReadStatusLines()
{
QStringList lines = proc.readStatusLines();
const QStringList lines = proc.readStatusLines();
for (int n = 0; n < lines.count(); ++n)
processStatusLine(lines[n]);
}
void GpgAction::proc_bytesWrittenStdin(int bytes)
{
if(!useAux)
{
if (!useAux) {
int actual = writeConv.writtenToActual(bytes);
emit bytesWritten(actual);
}
@ -926,8 +820,7 @@ void GpgAction::proc_bytesWrittenStdin(int bytes)
void GpgAction::proc_bytesWrittenAux(int bytes)
{
if(useAux)
{
if (useAux) {
int actual = writeConv.writtenToActual(bytes);
emit bytesWritten(actual);
}
@ -940,7 +833,7 @@ void GpgAction::proc_bytesWrittenCommand(int)
void GpgAction::proc_debug(const QString &str)
{
appendDiagnosticText("GPGProc: " + str);
appendDiagnosticText(QStringLiteral("GPGProc: ") + str);
ensureDTextEmit();
}

View File

@ -19,13 +19,13 @@
#pragma once
#include "lineconverter.h"
#include "qca_safetimer.h"
#include "gpgop.h"
#include "gpgproc.h"
#include "lineconverter.h"
#include "qca_safetimer.h"
#include <QByteArray>
#include <QObject>
#include <QStringList>
#include <QByteArray>
#ifdef GPG_PROFILE
#include <QTime>
@ -50,7 +50,12 @@ public:
QString export_key_id;
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
@ -66,14 +71,19 @@ public:
GpgOp::VerifyResult verifyResult;
QString homeDir;
Output() : success(false), errorCode(GpgOp::ErrorUnknown), wasSigned(false) {}
Output()
: success(false)
, errorCode(GpgOp::ErrorUnknown)
, wasSigned(false)
{
}
};
Input input;
Output output;
GpgAction(QObject *parent = 0);
~GpgAction();
GpgAction(QObject *parent = nullptr);
~GpgAction() override;
void reset();
void start();
#ifdef QPIPE_SECURE
@ -82,14 +92,14 @@ public:
void submitPassphrase(const QByteArray &a);
#endif
public slots:
public Q_SLOTS:
QByteArray read();
void write(const QByteArray &in);
void endWrite();
void cardOkay();
QString readDiagnosticText();
signals:
Q_SIGNALS:
void readyRead();
void bytesWritten(int bytes);
void finished();
@ -101,7 +111,7 @@ private:
void submitCommand(const QByteArray &a);
// 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 processResult(int code);
void ensureDTextEmit();
@ -125,7 +135,7 @@ private:
QTime timer;
#endif
private slots:
private Q_SLOTS:
void t_dtext();
void proc_error(gpgQCAPlugin::GPGProc::Error e);
void proc_finished(int exitCode);
@ -139,5 +149,4 @@ private slots:
void appendDiagnosticText(const QString &line);
};
} // end namespace gpgQCAPlugin

View File

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

View File

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

View File

@ -19,19 +19,13 @@
#pragma once
#include "gpgop.h"
#include "gpgaction.h"
#include "gpgop.h"
#include "gpgproc_p.h"
#include <QObject>
namespace gpgQCAPlugin {
enum ResetMode
{
ResetSession = 0,
ResetSessionAndData = 1,
ResetAll = 2
};
class GpgOp::Private : public QObject
{
Q_OBJECT
@ -55,7 +49,7 @@ public:
#endif
Private(GpgOp *_q);
~Private();
~Private() override;
void reset(ResetMode mode);
void make_act(GpgOp::Type _op);
void eventReady(const GpgOp::Event &e);
@ -63,7 +57,7 @@ public:
void eventReady(GpgOp::Event::Type type, int written);
void eventReady(GpgOp::Event::Type type, const QString &keyId);
public slots:
public Q_SLOTS:
void act_readyRead();
void act_bytesWritten(int bytes);
void act_needPassphrase(const QString &keyId);

View File

@ -23,7 +23,6 @@
#define QT_PIPE_HACK
#endif
using namespace QCA;
namespace gpgQCAPlugin {
@ -31,11 +30,10 @@ namespace gpgQCAPlugin {
void releaseAndDeleteLater(QObject *owner, QObject *obj)
{
obj->disconnect(owner);
obj->setParent(0);
obj->setParent(nullptr);
obj->deleteLater();
}
GPGProc::Private::Private(GPGProc *_q)
: QObject(_q)
, q(_q)
@ -47,21 +45,19 @@ GPGProc::Private::Private(GPGProc *_q)
{
qRegisterMetaType<gpgQCAPlugin::GPGProc::Error>("gpgQCAPlugin::GPGProc::Error");
proc = 0;
#ifdef QPROC_SIGNAL_RELAY
proc_relay = 0;
#endif
proc = nullptr;
proc_relay = nullptr;
startTrigger.setSingleShot(true);
doneTrigger.setSingleShot(true);
connect(&pipeAux.writeEnd(), SIGNAL(bytesWritten(int)), SLOT(aux_written(int)));
connect(&pipeAux.writeEnd(), SIGNAL(error(QCA::QPipeEnd::Error)), SLOT(aux_error(QCA::QPipeEnd::Error)));
connect(&pipeCommand.writeEnd(), SIGNAL(bytesWritten(int)), SLOT(command_written(int)));
connect(&pipeCommand.writeEnd(), SIGNAL(error(QCA::QPipeEnd::Error)), SLOT(command_error(QCA::QPipeEnd::Error)));
connect(&pipeStatus.readEnd(), SIGNAL(readyRead()), SLOT(status_read()));
connect(&pipeStatus.readEnd(), SIGNAL(error(QCA::QPipeEnd::Error)), SLOT(status_error(QCA::QPipeEnd::Error)));
connect(&startTrigger, SIGNAL(timeout()), SLOT(doStart()));
connect(&doneTrigger, SIGNAL(timeout()), SLOT(doTryDone()));
connect(&pipeAux.writeEnd(), &QCA::QPipeEnd::bytesWritten, this, &GPGProc::Private::aux_written);
connect(&pipeAux.writeEnd(), &QCA::QPipeEnd::error, this, &GPGProc::Private::aux_error);
connect(&pipeCommand.writeEnd(), &QCA::QPipeEnd::bytesWritten, this, &GPGProc::Private::command_written);
connect(&pipeCommand.writeEnd(), &QCA::QPipeEnd::error, this, &GPGProc::Private::command_error);
connect(&pipeStatus.readEnd(), &QCA::QPipeEnd::readyRead, this, &GPGProc::Private::status_read);
connect(&pipeStatus.readEnd(), &QCA::QPipeEnd::error, this, &GPGProc::Private::status_error);
connect(&startTrigger, &QCA::SafeTimer::timeout, this, &GPGProc::Private::doStart);
connect(&doneTrigger, &QCA::SafeTimer::timeout, this, &GPGProc::Private::doTryDone);
reset(ResetSessionAndData);
}
@ -90,12 +86,10 @@ void GPGProc::Private::reset(ResetMode mode)
closePipes();
#endif
if(proc)
{
if (proc) {
proc->disconnect(this);
if(proc->state() != QProcess::NotRunning)
{
if (proc->state() != QProcess::NotRunning) {
// Before try to correct end proccess
// Terminate if failed
proc->close();
@ -104,15 +98,11 @@ void GPGProc::Private::reset(ResetMode mode)
proc->terminate();
}
proc->setParent(0);
#ifdef QPROC_SIGNAL_RELAY
proc->setParent(nullptr);
releaseAndDeleteLater(this, proc_relay);
proc_relay = 0;
proc_relay = nullptr;
delete proc; // should be safe to do thanks to relay
#else
proc->deleteLater();
#endif
proc = 0;
proc = nullptr;
}
#ifdef QT_PIPE_HACK
@ -133,8 +123,7 @@ void GPGProc::Private::reset(ResetMode mode)
fin_process = false;
fin_status = false;
if(mode >= ResetSessionAndData)
{
if (mode >= ResetSessionAndData) {
statusBuf.clear();
statusLines.clear();
leftover_stdout.clear();
@ -146,10 +135,9 @@ void GPGProc::Private::reset(ResetMode mode)
bool GPGProc::Private::setupPipes(bool makeAux)
{
if(makeAux && !pipeAux.create())
{
if (makeAux && !pipeAux.create()) {
closePipes();
emit q->debug("Error creating pipeAux");
emit q->debug(QStringLiteral("Error creating pipeAux"));
return false;
}
@ -160,14 +148,13 @@ bool GPGProc::Private::setupPipes(bool makeAux)
#endif
{
closePipes();
emit q->debug("Error creating pipeCommand");
emit q->debug(QStringLiteral("Error creating pipeCommand"));
return false;
}
if(!pipeStatus.create())
{
if (!pipeStatus.create()) {
closePipes();
emit q->debug("Error creating pipeStatus");
emit q->debug(QStringLiteral("Error creating pipeStatus"));
return false;
}
@ -177,30 +164,30 @@ bool GPGProc::Private::setupPipes(bool makeAux)
void GPGProc::Private::setupArguments()
{
QStringList fullargs;
fullargs += "--no-tty";
fullargs += QStringLiteral("--no-tty");
fullargs += QStringLiteral("--pinentry-mode");
fullargs += QStringLiteral("loopback");
if(mode == ExtendedMode)
{
fullargs += "--enable-special-filenames";
if (mode == ExtendedMode) {
fullargs += QStringLiteral("--enable-special-filenames");
fullargs += "--status-fd";
fullargs += QStringLiteral("--status-fd");
fullargs += QString::number(pipeStatus.writeEnd().idAsInt());
fullargs += "--command-fd";
fullargs += QStringLiteral("--command-fd");
fullargs += QString::number(pipeCommand.readEnd().idAsInt());
}
for(int n = 0; n < args.count(); ++n)
{
for (int n = 0; n < args.count(); ++n) {
QString a = args[n];
if(mode == ExtendedMode && a == "-&?")
fullargs += QString("-&") + QString::number(pipeAux.readEnd().idAsInt());
if (mode == ExtendedMode && a == QLatin1String("-&?"))
fullargs += QStringLiteral("-&") + QString::number(pipeAux.readEnd().idAsInt());
else
fullargs += a;
}
QString fullcmd = fullargs.join(" ");
emit q->debug(QString("Running: [") + bin + ' ' + fullcmd + ']');
QString fullcmd = fullargs.join(QStringLiteral(" "));
emit q->debug(QStringLiteral("Running: [") + bin + QLatin1Char(' ') + fullcmd + QLatin1Char(']'));
args = fullargs;
}
@ -234,7 +221,7 @@ void GPGProc::Private::aux_written(int x)
void GPGProc::Private::aux_error(QCA::QPipeEnd::Error)
{
emit q->debug("Aux: Pipe error");
emit q->debug(QStringLiteral("Aux: Pipe error"));
reset(ResetSession);
emit q->error(GPGProc::ErrorWrite);
}
@ -246,7 +233,7 @@ void GPGProc::Private::command_written(int x)
void GPGProc::Private::command_error(QCA::QPipeEnd::Error)
{
emit q->debug("Command: Pipe error");
emit q->debug(QStringLiteral("Command: Pipe error"));
reset(ResetSession);
emit q->error(GPGProc::ErrorWrite);
}
@ -260,9 +247,9 @@ void GPGProc::Private::status_read()
void GPGProc::Private::status_error(QCA::QPipeEnd::Error e)
{
if (e == QPipeEnd::ErrorEOF)
emit q->debug("Status: Closed (EOF)");
emit q->debug(QStringLiteral("Status: Closed (EOF)"));
else
emit q->debug("Status: Closed (gone)");
emit q->debug(QStringLiteral("Status: Closed (gone)"));
fin_status = true;
doTryDone();
@ -270,7 +257,7 @@ void GPGProc::Private::status_error(QCA::QPipeEnd::Error e)
void GPGProc::Private::proc_started()
{
emit q->debug("Process started");
emit q->debug(QStringLiteral("Process started"));
// Note: we don't close these here anymore. instead we
// do it just after calling proc->start().
@ -280,18 +267,15 @@ void GPGProc::Private::proc_started()
pipeStatus.writeEnd().close();*/
// do the pre* stuff
if(!pre_stdin.isEmpty())
{
if (!pre_stdin.isEmpty()) {
proc->write(pre_stdin);
pre_stdin.clear();
}
if(!pre_aux.isEmpty())
{
if (!pre_aux.isEmpty()) {
pipeAux.writeEnd().write(pre_aux);
pre_aux.clear();
}
if(!pre_command.isEmpty())
{
if (!pre_command.isEmpty()) {
#ifdef QPIPE_SECURE
pipeCommand.writeEnd().writeSecure(pre_command);
#else
@ -300,8 +284,7 @@ void GPGProc::Private::proc_started()
pre_command.clear();
}
if(pre_stdin_close)
{
if (pre_stdin_close) {
proc->waitForBytesWritten();
proc->closeWriteChannel();
}
@ -330,18 +313,16 @@ void GPGProc::Private::proc_bytesWritten(qint64 lx)
void GPGProc::Private::proc_finished(int x)
{
emit q->debug(QString("Process finished: %1").arg(x));
emit q->debug(QStringLiteral("Process finished: %1").arg(x));
exitCode = x;
fin_process = true;
fin_process_success = true;
if(need_status && !fin_status)
{
if (need_status && !fin_status) {
pipeStatus.readEnd().finalize();
fin_status = true;
if(readAndProcessStatusData())
{
if (readAndProcessStatusData()) {
doneTrigger.start();
emit q->readyReadStatusLines();
return;
@ -354,14 +335,14 @@ void GPGProc::Private::proc_finished(int x)
void GPGProc::Private::proc_error(QProcess::ProcessError x)
{
QMap<int, QString> errmap;
errmap[QProcess::FailedToStart] = "FailedToStart";
errmap[QProcess::Crashed] = "Crashed";
errmap[QProcess::Timedout] = "Timedout";
errmap[QProcess::WriteError] = "WriteError";
errmap[QProcess::ReadError] = "ReadError";
errmap[QProcess::UnknownError] = "UnknownError";
errmap[QProcess::FailedToStart] = QStringLiteral("FailedToStart");
errmap[QProcess::Crashed] = QStringLiteral("Crashed");
errmap[QProcess::Timedout] = QStringLiteral("Timedout");
errmap[QProcess::WriteError] = QStringLiteral("WriteError");
errmap[QProcess::ReadError] = QStringLiteral("ReadError");
errmap[QProcess::UnknownError] = QStringLiteral("UnknownError");
emit q->debug(QString("Process error: %1").arg(errmap[x]));
emit q->debug(QStringLiteral("Process error: %1").arg(errmap[x]));
if (x == QProcess::FailedToStart)
error = GPGProc::FailedToStart;
@ -386,12 +367,10 @@ void GPGProc::Private::proc_error(QProcess::ProcessError x)
pipeStatus.writeEnd().reset();
#endif
if(need_status && !fin_status)
{
if (need_status && !fin_status) {
pipeStatus.readEnd().finalize();
fin_status = true;
if(readAndProcessStatusData())
{
if (readAndProcessStatusData()) {
doneTrigger.start();
emit q->readyReadStatusLines();
return;
@ -409,7 +388,7 @@ void GPGProc::Private::doTryDone()
if (need_status && !fin_status)
return;
emit q->debug("Done");
emit q->debug(QStringLiteral("Done"));
// get leftover data
proc->setReadChannel(QProcess::StandardOutput);
@ -427,7 +406,7 @@ void GPGProc::Private::doTryDone()
bool GPGProc::Private::readAndProcessStatusData()
{
QByteArray buf = pipeStatus.readEnd().read();
const QByteArray buf = pipeStatus.readEnd().read();
if (buf.isEmpty())
return false;
@ -441,8 +420,7 @@ bool GPGProc::Private::processStatusData(const QByteArray &buf)
// extract all lines
QStringList list;
while(1)
{
while (true) {
int n = statusBuf.indexOf('\n');
if (n == -1)
break;
@ -451,7 +429,7 @@ bool GPGProc::Private::processStatusData(const QByteArray &buf)
++n;
char * p = (char *)statusBuf.data();
QByteArray cs(p, n);
int newsize = statusBuf.size() - n;
const int newsize = statusBuf.size() - n;
memmove(p, p + n, newsize);
statusBuf.resize(newsize);
@ -460,7 +438,7 @@ bool GPGProc::Private::processStatusData(const QByteArray &buf)
str.truncate(str.length() - 1);
// ensure it has a proper header
if(str.left(9) != "[GNUPG:] ")
if (str.left(9) != QLatin1String("[GNUPG:] "))
continue;
// take it off
@ -503,20 +481,19 @@ void GPGProc::start(const QString &bin, const QStringList &args, Mode mode)
if (isActive())
d->reset(ResetSessionAndData);
if(mode == ExtendedMode)
{
if(!d->setupPipes(args.contains("-&?")))
{
if (mode == ExtendedMode) {
if (!d->setupPipes(args.contains(QStringLiteral("-&?")))) {
d->error = FailedToStart;
// emit later
QMetaObject::invokeMethod(this, "error", Qt::QueuedConnection, Q_ARG(gpgQCAPlugin::GPGProc::Error, d->error));
QMetaObject::invokeMethod(
this, "error", Qt::QueuedConnection, Q_ARG(gpgQCAPlugin::GPGProc::Error, d->error));
return;
}
d->need_status = true;
emit debug("Pipe setup complete");
emit debug(QStringLiteral("Pipe setup complete"));
}
d->proc = new SProcess(d);
@ -540,22 +517,17 @@ void GPGProc::start(const QString &bin, const QStringList &args, Mode mode)
if (d->pipeStatus.readEnd().isValid())
d->pipeStatus.readEnd().enable();
#ifdef QPROC_SIGNAL_RELAY
d->proc_relay = new QProcessSignalRelay(d->proc, d);
connect(d->proc_relay, SIGNAL(started()), d, SLOT(proc_started()));
connect(d->proc_relay, SIGNAL(readyReadStandardOutput()), d, SLOT(proc_readyReadStandardOutput()));
connect(d->proc_relay, SIGNAL(readyReadStandardError()), d, SLOT(proc_readyReadStandardError()));
connect(d->proc_relay, SIGNAL(bytesWritten(qint64)), d, SLOT(proc_bytesWritten(qint64)));
connect(d->proc_relay, SIGNAL(finished(int)), d, SLOT(proc_finished(int)));
connect(d->proc_relay, SIGNAL(error(QProcess::ProcessError)), d, SLOT(proc_error(QProcess::ProcessError)));
#else
connect(d->proc, SIGNAL(started()), d, SLOT(proc_started()));
connect(d->proc, SIGNAL(readyReadStandardOutput()), d, SLOT(proc_readyReadStandardOutput()));
connect(d->proc, SIGNAL(readyReadStandardError()), d, SLOT(proc_readyReadStandardError()));
connect(d->proc, SIGNAL(bytesWritten(qint64)), d, SLOT(proc_bytesWritten(qint64)));
connect(d->proc, SIGNAL(finished(int)), d, SLOT(proc_finished(int)));
connect(d->proc, SIGNAL(error(QProcess::ProcessError)), d, SLOT(proc_error(QProcess::ProcessError)));
#endif
connect(d->proc_relay, &QProcessSignalRelay::started, d, &GPGProc::Private::proc_started);
connect(d->proc_relay,
&QProcessSignalRelay::readyReadStandardOutput,
d,
&GPGProc::Private::proc_readyReadStandardOutput);
connect(
d->proc_relay, &QProcessSignalRelay::readyReadStandardError, d, &GPGProc::Private::proc_readyReadStandardError);
connect(d->proc_relay, &QProcessSignalRelay::bytesWritten, d, &GPGProc::Private::proc_bytesWritten);
connect(d->proc_relay, &QProcessSignalRelay::finished, d, &GPGProc::Private::proc_finished);
connect(d->proc_relay, &QProcessSignalRelay::error, d, &GPGProc::Private::proc_error);
d->bin = bin;
d->args = args;
@ -565,14 +537,11 @@ void GPGProc::start(const QString &bin, const QStringList &args, Mode mode)
QByteArray GPGProc::readStdout()
{
if(d->proc)
{
if (d->proc) {
d->proc->setReadChannel(QProcess::StandardOutput);
return d->proc->readAll();
}
else
{
QByteArray a = d->leftover_stdout;
} else {
const QByteArray a = d->leftover_stdout;
d->leftover_stdout.clear();
return a;
}
@ -580,14 +549,11 @@ QByteArray GPGProc::readStdout()
QByteArray GPGProc::readStderr()
{
if(d->proc)
{
if (d->proc) {
d->proc->setReadChannel(QProcess::StandardError);
return d->proc->readAll();
}
else
{
QByteArray a = d->leftover_stderr;
} else {
const QByteArray a = d->leftover_stderr;
d->leftover_stderr.clear();
return a;
}
@ -595,7 +561,7 @@ QByteArray GPGProc::readStderr()
QStringList GPGProc::readStatusLines()
{
QStringList out = d->statusLines;
const QStringList out = d->statusLines;
d->statusLines.clear();
return out;
}
@ -646,13 +612,10 @@ void GPGProc::closeStdin()
if (!d->proc)
return;
if(d->proc->state() == QProcess::Running)
{
if (d->proc->state() == QProcess::Running) {
d->proc->waitForBytesWritten();
d->proc->closeWriteChannel();
}
else
{
} else {
d->pre_stdin_close = true;
}
}

View File

@ -32,10 +32,19 @@ class GPGProc : public QObject
{
Q_OBJECT
public:
enum Error { FailedToStart, UnexpectedExit, ErrorWrite };
enum Mode { NormalMode, ExtendedMode };
GPGProc(QObject *parent = 0);
~GPGProc();
enum Error
{
FailedToStart,
UnexpectedExit,
ErrorWrite
};
enum Mode
{
NormalMode,
ExtendedMode
};
GPGProc(QObject *parent = nullptr);
~GPGProc() override;
void reset();

View File

@ -19,11 +19,9 @@
#pragma once
#define QPROC_SIGNAL_RELAY
#include "gpgproc.h"
#include "qpipe.h"
#include "sprocess.h"
#include "gpgproc.h"
#include <QObject>
namespace gpgQCAPlugin {
@ -32,19 +30,31 @@ class QProcessSignalRelay : public QObject
{
Q_OBJECT
public:
QProcessSignalRelay(QProcess *proc, QObject *parent = 0)
QProcessSignalRelay(QProcess *proc, QObject *parent = nullptr)
: QObject(parent)
{
qRegisterMetaType<QProcess::ProcessError>("QProcess::ProcessError");
connect(proc, SIGNAL(started()), SLOT(proc_started()), Qt::QueuedConnection);
connect(proc, SIGNAL(readyReadStandardOutput()), SLOT(proc_readyReadStandardOutput()), Qt::QueuedConnection);
connect(proc, SIGNAL(readyReadStandardError()), SLOT(proc_readyReadStandardError()), Qt::QueuedConnection);
connect(proc, SIGNAL(bytesWritten(qint64)), SLOT(proc_bytesWritten(qint64)), Qt::QueuedConnection);
connect(proc, SIGNAL(finished(int)), SLOT(proc_finished(int)), Qt::QueuedConnection);
connect(proc, SIGNAL(error(QProcess::ProcessError)), SLOT(proc_error(QProcess::ProcessError)), Qt::QueuedConnection);
connect(proc, &QProcess::started, this, &QProcessSignalRelay::proc_started, Qt::QueuedConnection);
connect(proc,
&QProcess::readyReadStandardOutput,
this,
&QProcessSignalRelay::proc_readyReadStandardOutput,
Qt::QueuedConnection);
connect(proc,
&QProcess::readyReadStandardError,
this,
&QProcessSignalRelay::proc_readyReadStandardError,
Qt::QueuedConnection);
connect(proc, &QProcess::bytesWritten, this, &QProcessSignalRelay::proc_bytesWritten, Qt::QueuedConnection);
connect(proc,
QOverload<int, QProcess::ExitStatus>::of(&QProcess::finished),
this,
&QProcessSignalRelay::proc_finished,
Qt::QueuedConnection);
connect(proc, &QProcess::errorOccurred, this, &QProcessSignalRelay::proc_error, Qt::QueuedConnection);
}
signals:
Q_SIGNALS:
void started();
void readyReadStandardOutput();
void readyReadStandardError();
@ -52,7 +62,7 @@ signals:
void finished(int);
void error(QProcess::ProcessError);
public slots:
public Q_SLOTS:
void proc_started()
{
emit started();
@ -100,9 +110,7 @@ public:
QStringList args;
GPGProc::Mode mode;
SProcess * proc;
#ifdef QPROC_SIGNAL_RELAY
QProcessSignalRelay *proc_relay;
#endif
QCA::QPipe pipeAux, pipeCommand, pipeStatus;
QByteArray statusBuf;
QStringList statusLines;
@ -123,13 +131,13 @@ public:
QByteArray leftover_stderr;
Private(GPGProc *_q);
~Private();
~Private() override;
void closePipes();
void reset(ResetMode mode);
bool setupPipes(bool makeAux);
void setupArguments();
public slots:
public Q_SLOTS:
void doStart();
void aux_written(int x);
void aux_error(QCA::QPipeEnd::Error);
@ -149,8 +157,6 @@ private:
bool readAndProcessStatusData();
// return true if there are newly parsed lines available
bool processStatusData(const QByteArray &buf);
};
} // end namespace gpgQCAPlugin

View File

@ -20,8 +20,8 @@
#include "sprocess.h"
#ifdef Q_OS_UNIX
# include <unistd.h>
#include <fcntl.h>
#include <unistd.h>
#endif
namespace gpgQCAPlugin {
@ -32,6 +32,13 @@ namespace gpgQCAPlugin {
SProcess::SProcess(QObject *parent)
: QProcess(parent)
{
#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
setChildProcessModifier([this]() {
// set the pipes to be inheritable
for (int n = 0; n < pipeList.count(); ++n)
::fcntl(pipeList[n], F_SETFD, (::fcntl(pipeList[n], F_GETFD) & ~FD_CLOEXEC));
});
#endif
}
SProcess::~SProcess()
@ -44,6 +51,7 @@ void SProcess::setInheritPipeList(const QList<int> &list)
pipeList = list;
}
#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
void SProcess::setupChildProcess()
{
// set the pipes to be inheritable
@ -51,5 +59,6 @@ void SProcess::setupChildProcess()
::fcntl(pipeList[n], F_SETFD, (::fcntl(pipeList[n], F_GETFD) & ~FD_CLOEXEC));
}
#endif
#endif
}

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