File indexing completed on 2024-04-21 14:56:09

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