File indexing completed on 2025-02-16 13:38:15
0001 /* 0002 Copyright (C) 2003 Justin Karneges <justin@affinix.com> 0003 Copyright (C) 2005 Brad Hards <bradh@frogmouth.net> 0004 0005 Permission is hereby granted, free of charge, to any person obtaining a copy 0006 of this software and associated documentation files (the "Software"), to deal 0007 in the Software without restriction, including without limitation the rights 0008 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 0009 copies of the Software, and to permit persons to whom the Software is 0010 furnished to do so, subject to the following conditions: 0011 0012 The above copyright notice and this permission notice shall be included in 0013 all copies or substantial portions of the Software. 0014 0015 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 0016 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 0017 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 0018 AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN 0019 AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 0020 CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 0021 */ 0022 0023 #include <QtCrypto> 0024 0025 #include <QCoreApplication> 0026 #include <QFile> 0027 0028 #include <iostream> 0029 0030 #ifdef QT_STATICPLUGIN 0031 #include "import_plugins.h" 0032 #endif 0033 0034 // dump out information about some part of the certificate 0035 // we use this same approach for information about the subject 0036 // of the certificate, and also about the issuer of the certificate 0037 static void dumpCertificateInfo(const QCA::CertificateInfo &info) 0038 { 0039 std::cout << " Organization: " << std::endl; 0040 0041 // Note that a single certificate can apply to more than one 0042 // organisation. QCA::Certificate is a multimap, so when you 0043 // ask for the values associated with a parameter, it returns 0044 // a list. 0045 QList<QString> orgInfoList = info.values(QCA::Organization); 0046 0047 // foreach() interates over each value in the list, and we dump 0048 // out each value. Note that is uncommon for a certificate to 0049 // actually contain multiple values for a single parameter. 0050 QString organization; 0051 foreach (organization, orgInfoList) { 0052 std::cout << " " << qPrintable(organization) << std::endl; 0053 } 0054 0055 std::cout << " Country: " << std::endl; 0056 // As above, however this shows a more compact way to represent 0057 // the iteration and output. 0058 foreach (QString country, info.values(QCA::Country)) { // clazy:exclude=container-anti-pattern 0059 std::cout << " " << qPrintable(country) << std::endl; 0060 } 0061 } 0062 0063 // This is just a convenience routine 0064 static void dumpSubjectInfo(const QCA::CertificateInfo &subject) 0065 { 0066 std::cout << "Subject: " << std::endl; 0067 0068 dumpCertificateInfo(subject); 0069 } 0070 0071 // This is just a convenience routine 0072 static void dumpIssuerInfo(const QCA::CertificateInfo &issuer) 0073 { 0074 std::cout << "Issuer: " << std::endl; 0075 0076 dumpCertificateInfo(issuer); 0077 } 0078 0079 int main(int argc, char **argv) 0080 { 0081 // the Initializer object sets things up, and 0082 // also does cleanup when it goes out of scope 0083 QCA::Initializer init; 0084 0085 QCoreApplication app(argc, argv); 0086 0087 // We need to ensure that we have certificate handling support 0088 if (!QCA::isSupported("cert")) { 0089 std::cout << "Sorry, no PKI certificate support" << std::endl; 0090 return 1; 0091 } 0092 0093 // We are going to work with a number of certificates, and a 0094 // QList is a great template class for that 0095 QList<QCA::Certificate> certlist; 0096 0097 // We do two different cases - if we provide an argument, it is taken 0098 // as a filename to read the keys from. If there is no argument, we just 0099 // read from the system store certificates. 0100 if (argc >= 2) { 0101 // we are going to read the certificates in using a single call 0102 // which requires a CertificateCollection. 0103 QCA::CertificateCollection filecerts; 0104 // The conversion can be tested (although you don't have to) to find out if it 0105 // worked. 0106 QCA::ConvertResult importResult; 0107 // This imports all the PEM encoded certificates from the file specified as the argument 0108 // Note that you pass in a pointer to the result argument. 0109 filecerts = QCA::CertificateCollection::fromFlatTextFile(QFile::decodeName(argv[1]), &importResult); 0110 if (QCA::ConvertGood == importResult) { 0111 std::cout << "Import succeeded" << std::endl; 0112 // this turns the CertificateCollection into a QList of Certificate objects 0113 certlist = filecerts.certificates(); 0114 } 0115 } else { 0116 // we have no arguments, so just use the system certificates 0117 if (!QCA::haveSystemStore()) { 0118 std::cout << "System certificates not available" << std::endl; 0119 return 2; 0120 } 0121 0122 // Similar to above, except we just want the system certificates 0123 QCA::CertificateCollection systemcerts = QCA::systemStore(); 0124 0125 // this turns the CertificateCollection into a QList of Certificate objects 0126 certlist = systemcerts.certificates(); 0127 } 0128 0129 std::cout << "Number of certificates: " << certlist.count() << std::endl; 0130 0131 QCA::Certificate cert; 0132 foreach (cert, certlist) { 0133 std::cout << "Serial Number:"; 0134 // the serial number of the certificate is a QCA::BigInteger, but we can 0135 // just convert it to a string, and then output it. 0136 std::cout << qPrintable(cert.serialNumber().toString()) << std::endl; 0137 0138 // The subject information shows properties of who the certificate 0139 // applies to. See the convenience routines above. 0140 dumpSubjectInfo(cert.subjectInfo()); 0141 0142 // The issuer information shows properties of who the certificate 0143 // was signed by. See the convenience routines above. 0144 dumpIssuerInfo(cert.issuerInfo()); 0145 0146 // Test if the certificate can be used as a certificate authority 0147 if (cert.isCA()) { 0148 std::cout << "Is certificate authority" << std::endl; 0149 } else { 0150 std::cout << "Is not a certificate authority" << std::endl; 0151 } 0152 0153 // Test if the certificate is self-signed. 0154 if (cert.isSelfSigned()) { 0155 std::cout << "Self signed" << std::endl; 0156 } else { 0157 std::cout << "Is not self-signed!!!" << std::endl; 0158 } 0159 0160 // Certificate are only valid between specific dates. We can get the dates 0161 // (as a QDateTime) using a couple of calls 0162 std::cout << "Valid from " << qPrintable(cert.notValidBefore().toString()); 0163 std::cout << ", until " << qPrintable(cert.notValidAfter().toString()); 0164 std::cout << std::endl; 0165 0166 // You can get the certificate in PEM encoding with a simple toPEM() call 0167 std::cout << "PEM:" << std::endl; 0168 std::cout << qPrintable(cert.toPEM()); 0169 std::cout << std::endl << std::endl; 0170 } 0171 0172 return 0; 0173 }