File indexing completed on 2023-09-24 04:05:19
0001 /* This file is part of the KDE project 0002 * 0003 * Copyright (C) 2000-2003 George Staikos <staikos@kde.org> 0004 * 2008 Richard Hartmann <richih-kde@net.in.tum.de> 0005 * 0006 * This library is free software; you can redistribute it and/or 0007 * modify it under the terms of the GNU Library General Public 0008 * License as published by the Free Software Foundation; either 0009 * version 2 of the License, or (at your option) any later version. 0010 * 0011 * This library is distributed in the hope that it will be useful, 0012 * but WITHOUT ANY WARRANTY; without even the implied warranty of 0013 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 0014 * Library General Public License for more details. 0015 * 0016 * You should have received a copy of the GNU Library General Public License 0017 * along with this library; see the file COPYING.LIB. If not, write to 0018 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 0019 * Boston, MA 02110-1301, USA. 0020 */ 0021 0022 #ifndef _KSSLCERTIFICATE_H 0023 #define _KSSLCERTIFICATE_H 0024 0025 // UPDATE: I like the structure of this class less and less every time I look 0026 // at it. I think it needs to change. 0027 // 0028 // 0029 // The biggest reason for making everything protected here is so that 0030 // the class can have all its methods available even if openssl is not 0031 // available. Also, to create a new certificate you should use the 0032 // KSSLCertificateFactory, and to manage the user's database of certificates, 0033 // you should go through the KSSLCertificateHome. 0034 // 0035 // There should be no reason to touch the X509 stuff directly. 0036 // 0037 0038 class QByteArray; 0039 class QString; 0040 class QStringList; 0041 class KSSL; 0042 class KSSLCertificatePrivate; 0043 class QDateTime; 0044 class KSSLCertChain; 0045 class KSSLX509V3; 0046 0047 #include <kdelibs4support_export.h> 0048 #include <ksslconfig.h> 0049 0050 #include <QList> 0051 0052 #if KSSL_HAVE_SSL 0053 typedef struct x509_st X509; 0054 #else 0055 class X509; 0056 #if !defined(QT_NO_OPENSSL) 0057 #include <QtNetwork/QSslCertificate> 0058 #endif 0059 #endif 0060 0061 /** 0062 * KDE X.509 Certificate 0063 * 0064 * This class represents an X.509 (SSL) certificate. 0065 * Note: this object is VERY HEAVY TO COPY. Please try to use reference 0066 * or pointer whenever possible 0067 * 0068 * @author George Staikos <staikos@kde.org> 0069 * @see KSSL 0070 * @short KDE X.509 Certificate 0071 * @deprecated since 5.0, use QSslCertificate 0072 */ 0073 class KDELIBS4SUPPORT_DEPRECATED_EXPORT KSSLCertificate 0074 { 0075 friend class KSSL; 0076 friend class KSSLCertificateHome; 0077 friend class KSSLCertificateFactory; 0078 friend class KSSLCertificateCache; 0079 friend class KSSLCertChain; 0080 friend class KSSLPeerInfo; 0081 friend class KSSLD; 0082 friend class KSMIMECryptoPrivate; 0083 0084 public: 0085 /** 0086 * Destroy this X.509 certificate. 0087 */ 0088 ~KSSLCertificate(); 0089 0090 /** 0091 * Create an X.509 certificate from a base64 encoded string. 0092 * @param cert the certificate in base64 form 0093 * @return the X.509 certificate, or NULL 0094 */ 0095 static KSSLCertificate *fromString(const QByteArray &cert); 0096 0097 /** 0098 * Create an X.509 certificate from the internal representation. 0099 * This one duplicates the X509 object for itself. 0100 * @param x5 the OpenSSL representation of the certificate 0101 * @return the X.509 certificate, or NULL 0102 * @internal 0103 */ 0104 static KSSLCertificate *fromX509(X509 *x5); 0105 0106 // TODO for KDE5 0107 // The enum values list below have to be kept for backwards comapability 0108 // They should be deleted when KDE5 comes around the corner. I am writing 0109 // this on 20080202 ;) 0110 // Rejected, Revoked, Untrusted, SelfSignedChain, SignatureFailed, Expired 0111 /** 0112 * Result of the validate() call. 0113 * 0114 * A CA certificate can be validated as Irrelevant when it was 0115 * not used to sign any other relevant certificate. 0116 */ 0117 enum KSSLValidation { Unknown, Ok, NoCARoot, InvalidPurpose, 0118 PathLengthExceeded, InvalidCA, Expired, 0119 SelfSigned, ErrorReadingRoot, NoSSL, 0120 Revoked, Untrusted, SignatureFailed, 0121 Rejected, PrivateKeyFailed, InvalidHost, 0122 Irrelevant, SelfSignedChain, 0123 GetIssuerCertFailed, DecodeIssuerPublicKeyFailed, 0124 GetIssuerCertLocallyFailed, 0125 CertificateNotYetValid, CertificateHasExpired, 0126 CRLNotYetValid, CRLHasExpired, 0127 CertificateFieldNotBeforeErroneous, 0128 CertificateFieldNotAfterErroneous, 0129 CRLFieldLastUpdateErroneous, 0130 CRLFieldNextUpdateErroneous, 0131 CertificateRevoked, 0132 CertificateUntrusted, VerifyLeafSignatureFailed, 0133 CertificateSignatureFailed, CRLSignatureFailed, 0134 DecryptCertificateSignatureFailed, 0135 DecryptCRLSignatureFailed, CertificateRejected, 0136 SelfSignedInChain, ApplicationVerificationFailed, 0137 AuthAndSubjectKeyIDAndNameMismatched, 0138 AuthAndSubjectKeyIDMismatched, OutOfMemory, 0139 GetCRLFailed, CertificateChainTooLong, 0140 KeyMayNotSignCertificate, 0141 IssuerSubjectMismatched 0142 }; 0143 0144 enum KSSLPurpose { None = 0, SSLServer = 1, SSLClient = 2, 0145 SMIMESign = 3, SMIMEEncrypt = 4, Any = 5 0146 }; 0147 0148 typedef QList<KSSLValidation> KSSLValidationList; 0149 0150 /** 0151 * Convert this certificate to a string. 0152 * @return the certificate in base64 format 0153 */ 0154 QString toString(); 0155 0156 /** 0157 * Get the subject of the certificate (X.509 map). 0158 * @return the subject 0159 */ 0160 QString getSubject() const; 0161 0162 /** 0163 * Get the issuer of the certificate (X.509 map). 0164 * @return the issuer 0165 */ 0166 QString getIssuer() const; 0167 0168 /** 0169 * Get the date that the certificate becomes valid on. 0170 * @return the date as a string, localised 0171 */ 0172 QString getNotBefore() const; 0173 0174 /** 0175 * Get the date that the certificate is valid until. 0176 * @return the date as a string, localised 0177 */ 0178 QString getNotAfter() const; 0179 0180 /** 0181 * Get the date that the certificate becomes valid on. 0182 * @return the date 0183 */ 0184 QDateTime getQDTNotBefore() const; 0185 0186 /** 0187 * Get the date that the certificate is valid until. 0188 * @return the date 0189 */ 0190 QDateTime getQDTNotAfter() const; 0191 0192 /** 0193 * Convert the certificate to DER (ASN.1) format. 0194 * @return the binary data of the DER encoding 0195 */ 0196 QByteArray toDer(); 0197 0198 /** 0199 * Convert the certificate to PEM (base64) format. 0200 * @return the binary data of the PEM encoding 0201 */ 0202 QByteArray toPem(); 0203 0204 /** 0205 * Convert the certificate to Netscape format. 0206 * @return the binary data of the Netscape encoding 0207 */ 0208 QByteArray toNetscape(); 0209 0210 /** 0211 * Convert the certificate to OpenSSL plain text format. 0212 * @return the OpenSSL text encoding 0213 */ 0214 QString toText(); 0215 0216 /** 0217 * Get the serial number of the certificate. 0218 * @return the serial number as a string 0219 */ 0220 QString getSerialNumber() const; 0221 0222 /** 0223 * Get the key type (RSA, DSA, etc). 0224 * @return the key type as a string 0225 */ 0226 QString getKeyType() const; 0227 0228 /** 0229 * Get the public key. 0230 * @return the public key as a hexidecimal string 0231 */ 0232 QString getPublicKeyText() const; 0233 0234 /** 0235 * Get the MD5 digest of the certificate. 0236 * Result is padded with : to separate bytes - it's a text version! 0237 * @return the MD5 digest in a hexidecimal string 0238 */ 0239 QString getMD5DigestText() const; 0240 0241 /** 0242 * Get the MD5 digest of the certificate. 0243 * @return the MD5 digest in a hexidecimal string 0244 */ 0245 QString getMD5Digest() const; 0246 0247 /** 0248 * Get the signature. 0249 * @return the signature in text format 0250 */ 0251 QString getSignatureText() const; 0252 0253 /** 0254 * Check if this is a valid certificate. Will use cached data. 0255 * @return true if it is valid 0256 */ 0257 bool isValid(); 0258 0259 /** 0260 * Check if this is a valid certificate. Will use cached data. 0261 * @param p the purpose to validate for 0262 * @return true if it is valid 0263 */ 0264 bool isValid(KSSLPurpose p); 0265 0266 /** 0267 * The alternate subject name. 0268 * @return string list with subjectAltName 0269 */ 0270 QStringList subjAltNames() const; 0271 0272 /** 0273 * Check if this is a valid certificate. Will use cached data. 0274 * @return the result of the validation 0275 */ 0276 KSSLValidation validate(); 0277 0278 /** 0279 * Check if this is a valid certificate. Will use cached data. 0280 * @param p the purpose to validate for 0281 * @return the result of the validation 0282 */ 0283 KSSLValidation validate(KSSLPurpose p); 0284 0285 /** 0286 * Check if this is a valid certificate. Will use cached data. 0287 * @param p the purpose to validate for 0288 * @return all problems encountered during validation 0289 */ 0290 KSSLValidationList validateVerbose(KSSLPurpose p); 0291 0292 /** 0293 * Check if the certificate ca is a proper CA for this 0294 * certificate. 0295 * @param p the purpose to validate for 0296 * @param ca the certificate to check 0297 * @return all problems encountered during validation 0298 */ 0299 KSSLValidationList validateVerbose(KSSLPurpose p, KSSLCertificate *ca); 0300 0301 /** 0302 * Check if this is a valid certificate. Will NOT use cached data. 0303 * @return the result of the validation 0304 */ 0305 KSSLValidation revalidate(); 0306 0307 /** 0308 * Check if this is a valid certificate. Will NOT use cached data. 0309 * @param p the purpose to validate for 0310 * @return the result of the validation 0311 */ 0312 KSSLValidation revalidate(KSSLPurpose p); 0313 0314 /** 0315 * Get a reference to the certificate chain. 0316 * @return reference to the chain 0317 */ 0318 KSSLCertChain &chain(); 0319 0320 /** 0321 * Obtain the localized message that corresponds to a validation result. 0322 * @param x the code to look up 0323 * @return the message text corresponding to the validation code 0324 */ 0325 static QString verifyText(KSSLValidation x); 0326 0327 /** 0328 * Explicitly make a copy of this certificate. 0329 * @return a copy of the certificate 0330 */ 0331 KSSLCertificate *replicate(); 0332 0333 /** 0334 * Copy constructor. Beware, this is very expensive. 0335 * @param x the object to copy from 0336 */ 0337 KSSLCertificate(const KSSLCertificate &x); // copy constructor 0338 0339 /** 0340 * Re-set the certificate from a base64 string. 0341 * @param cert the certificate to set to 0342 * @return true on success 0343 */ 0344 bool setCert(const QString &cert); 0345 0346 /** 0347 * Access the X.509v3 parameters. 0348 * @return reference to the extension object 0349 * @see KSSLX509V3 0350 */ 0351 KSSLX509V3 &x509V3Extensions(); 0352 0353 /** 0354 * Check if this is a signer certificate. 0355 * @return true if this is a signer certificate 0356 */ 0357 bool isSigner(); 0358 0359 /** 0360 * FIXME: document 0361 */ 0362 void getEmails(QStringList &to) const; 0363 0364 /** 0365 * KDEKey is a concatenation "Subject (MD5)", mostly needed for SMIME. 0366 * The result of getKDEKey might change and should not be used for 0367 * persistant storage. 0368 */ 0369 QString getKDEKey() const; 0370 0371 /** 0372 * Aegypten semantics force us to search by MD5Digest only. 0373 */ 0374 static QString getMD5DigestFromKDEKey(const QString &k); 0375 0376 private: 0377 KDELIBS4SUPPORT_DEPRECATED_EXPORT friend int operator!=(KSSLCertificate &x, KSSLCertificate &y); 0378 KDELIBS4SUPPORT_DEPRECATED_EXPORT friend int operator==(KSSLCertificate &x, KSSLCertificate &y); 0379 0380 KSSLCertificatePrivate *d; 0381 int purposeToOpenSSL(KSSLPurpose p) const; 0382 0383 protected: 0384 KSSLCertificate(); 0385 0386 void setCert(X509 *c); 0387 void setChain(void *c); 0388 X509 *getCert(); 0389 KSSLValidation processError(int ec); 0390 }; 0391 0392 KDELIBS4SUPPORT_DEPRECATED_EXPORT QDataStream &operator<<(QDataStream &s, const KSSLCertificate &r); 0393 KDELIBS4SUPPORT_DEPRECATED_EXPORT QDataStream &operator>>(QDataStream &s, KSSLCertificate &r); 0394 0395 KDELIBS4SUPPORT_DEPRECATED_EXPORT int operator==(KSSLCertificate &x, KSSLCertificate &y); 0396 KDELIBS4SUPPORT_DEPRECATED_EXPORT inline int operator!=(KSSLCertificate &x, KSSLCertificate &y) 0397 { 0398 return !(x == y); 0399 } 0400 0401 #endif 0402