1/*
2 Copyright (C) 2003 Justin Karneges <justin@affinix.com>
3 Copyright (C) 2005 Brad Hards <bradh@frogmouth.net>
4
5 Permission is hereby granted, free of charge, to any person obtaining a copy
6 of this software and associated documentation files (the "Software"), to deal
7 in the Software without restriction, including without limitation the rights
8 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 copies of the Software, and to permit persons to whom the Software is
10 furnished to do so, subject to the following conditions:
11
12 The above copyright notice and this permission notice shall be included in
13 all copies or substantial portions of the Software.
14
15 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
19 AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
20 CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
21*/
22
23#include <QtCrypto>
24
25#include <QCoreApplication>
26#include <QFile>
27
28#include <iostream>
29
30#ifdef QT_STATICPLUGIN
31#include "import_plugins.h"
32#endif
33
34// dump out information about some part of the certificate
35// we use this same approach for information about the subject
36// of the certificate, and also about the issuer of the certificate
37static void dumpCertificateInfo(const QCA::CertificateInfo &info)
38{
39 std::cout << " Organization: " << std::endl;
40
41 // Note that a single certificate can apply to more than one
42 // organisation. QCA::Certificate is a multimap, so when you
43 // ask for the values associated with a parameter, it returns
44 // a list.
45 QList<QString> orgInfoList = info.values(key: QCA::Organization);
46
47 // foreach() interates over each value in the list, and we dump
48 // out each value. Note that is uncommon for a certificate to
49 // actually contain multiple values for a single parameter.
50 QString organization;
51 foreach (organization, orgInfoList) {
52 std::cout << " " << qPrintable(organization) << std::endl;
53 }
54
55 std::cout << " Country: " << std::endl;
56 // As above, however this shows a more compact way to represent
57 // the iteration and output.
58 foreach (QString country, info.values(QCA::Country)) { // clazy:exclude=container-anti-pattern
59 std::cout << " " << qPrintable(country) << std::endl;
60 }
61}
62
63// This is just a convenience routine
64static void dumpSubjectInfo(const QCA::CertificateInfo &subject)
65{
66 std::cout << "Subject: " << std::endl;
67
68 dumpCertificateInfo(info: subject);
69}
70
71// This is just a convenience routine
72static void dumpIssuerInfo(const QCA::CertificateInfo &issuer)
73{
74 std::cout << "Issuer: " << std::endl;
75
76 dumpCertificateInfo(info: issuer);
77}
78
79int main(int argc, char **argv)
80{
81 // the Initializer object sets things up, and
82 // also does cleanup when it goes out of scope
83 QCA::Initializer init;
84
85 QCoreApplication app(argc, argv);
86
87 // We need to ensure that we have certificate handling support
88 if (!QCA::isSupported(features: "cert")) {
89 std::cout << "Sorry, no PKI certificate support" << std::endl;
90 return 1;
91 }
92
93 // We are going to work with a number of certificates, and a
94 // QList is a great template class for that
95 QList<QCA::Certificate> certlist;
96
97 // We do two different cases - if we provide an argument, it is taken
98 // as a filename to read the keys from. If there is no argument, we just
99 // read from the system store certificates.
100 if (argc >= 2) {
101 // we are going to read the certificates in using a single call
102 // which requires a CertificateCollection.
103 QCA::CertificateCollection filecerts;
104 // The conversion can be tested (although you don't have to) to find out if it
105 // worked.
106 QCA::ConvertResult importResult;
107 // This imports all the PEM encoded certificates from the file specified as the argument
108 // Note that you pass in a pointer to the result argument.
109 filecerts = QCA::CertificateCollection::fromFlatTextFile(fileName: QFile::decodeName(localFileName: argv[1]), result: &importResult);
110 if (QCA::ConvertGood == importResult) {
111 std::cout << "Import succeeded" << std::endl;
112 // this turns the CertificateCollection into a QList of Certificate objects
113 certlist = filecerts.certificates();
114 }
115 } else {
116 // we have no arguments, so just use the system certificates
117 if (!QCA::haveSystemStore()) {
118 std::cout << "System certificates not available" << std::endl;
119 return 2;
120 }
121
122 // Similar to above, except we just want the system certificates
123 QCA::CertificateCollection systemcerts = QCA::systemStore();
124
125 // this turns the CertificateCollection into a QList of Certificate objects
126 certlist = systemcerts.certificates();
127 }
128
129 std::cout << "Number of certificates: " << certlist.count() << std::endl;
130
131 QCA::Certificate cert;
132 foreach (cert, certlist) {
133 std::cout << "Serial Number:";
134 // the serial number of the certificate is a QCA::BigInteger, but we can
135 // just convert it to a string, and then output it.
136 std::cout << qPrintable(cert.serialNumber().toString()) << std::endl;
137
138 // The subject information shows properties of who the certificate
139 // applies to. See the convenience routines above.
140 dumpSubjectInfo(subject: cert.subjectInfo());
141
142 // The issuer information shows properties of who the certificate
143 // was signed by. See the convenience routines above.
144 dumpIssuerInfo(issuer: cert.issuerInfo());
145
146 // Test if the certificate can be used as a certificate authority
147 if (cert.isCA()) {
148 std::cout << "Is certificate authority" << std::endl;
149 } else {
150 std::cout << "Is not a certificate authority" << std::endl;
151 }
152
153 // Test if the certificate is self-signed.
154 if (cert.isSelfSigned()) {
155 std::cout << "Self signed" << std::endl;
156 } else {
157 std::cout << "Is not self-signed!!!" << std::endl;
158 }
159
160 // Certificate are only valid between specific dates. We can get the dates
161 // (as a QDateTime) using a couple of calls
162 std::cout << "Valid from " << qPrintable(cert.notValidBefore().toString());
163 std::cout << ", until " << qPrintable(cert.notValidAfter().toString());
164 std::cout << std::endl;
165
166 // You can get the certificate in PEM encoding with a simple toPEM() call
167 std::cout << "PEM:" << std::endl;
168 std::cout << qPrintable(cert.toPEM());
169 std::cout << std::endl << std::endl;
170 }
171
172 return 0;
173}
174

source code of qca/examples/certtest/certtest.cpp