#ifndef _KVI_SSL_H_ #define _KVI_SSL_H_ //============================================================================= // // File : KviSSL.h // Creation date : Mon May 27 2002 21:36:12 CEST by Szymon Stefanek // // This file is part of the KVIrc IRC client distribution // Copyright (C) 2002-2010 Szymon Stefanek (pragma at kvirc dot net) // // This program is FREE software. You can redistribute it and/or // modify it under the terms of the GNU General Public License // as published by the Free Software Foundation; either version 2 // 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 General Public License for more details. // // You should have received a copy of the GNU 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. // //============================================================================= #include "kvi_settings.h" #ifdef COMPILE_SSL_SUPPORT #include "KviCString.h" #include "KviPointerHashTable.h" #include "kvi_sockettype.h" // Apple deprecated openssl since osx 10.7: #ifdef DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER #undef DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER #define DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER #endif #include class KVILIB_API KviSSLCertificate { public: KviSSLCertificate(X509 * x509); ~KviSSLCertificate(); protected: X509 * m_pX509; KviPointerHashTable * m_pSubject; KviPointerHashTable * m_pIssuer; int m_iPubKeyBits; KviCString m_szPubKeyType; KviCString m_szSerialNumber; int m_iVersion; KviCString m_szSignatureType; KviCString m_szSignatureContents; private: void extractSubject(); void extractIssuer(); void extractPubKeyInfo(); void extractSerialNumber(); void extractSignature(); const char * dictEntry(KviPointerHashTable * dict, const char * entry); void splitX509String(KviPointerHashTable * dict, const char * t); int getFingerprint(unsigned char * bufferData, unsigned int * bufferLen, const char * digestName); public: void setX509(X509 * x509); char * getX509Base64(); //not owned, you'll need to free this const char * signatureType() { return m_szSignatureType.ptr(); }; const char * signatureContents() { return m_szSignatureContents.ptr(); }; const char * subjectCountry() { return dictEntry(m_pSubject, "C"); }; const char * subjectStateOrProvince() { return dictEntry(m_pSubject, "ST"); }; const char * subjectLocality() { return dictEntry(m_pSubject, "L"); }; const char * subjectOrganization() { return dictEntry(m_pSubject, "O"); }; const char * subjectOrganizationalUnit() { return dictEntry(m_pSubject, "OU"); }; const char * subjectCommonName() { return dictEntry(m_pSubject, "CN"); }; const char * issuerCountry() { return dictEntry(m_pIssuer, "C"); }; const char * issuerStateOrProvince() { return dictEntry(m_pIssuer, "ST"); }; const char * issuerLocality() { return dictEntry(m_pIssuer, "L"); }; const char * issuerOrganization() { return dictEntry(m_pIssuer, "O"); }; const char * issuerOrganizationalUnit() { return dictEntry(m_pIssuer, "OU"); }; const char * issuerCommonName() { return dictEntry(m_pIssuer, "CN"); }; int publicKeyBits() { return m_iPubKeyBits; }; const char * publicKeyType() { return m_szPubKeyType.ptr(); }; const char * serialNumber() { return m_szSerialNumber.len() ? m_szSerialNumber.ptr() : nullptr; }; int version() { return m_iVersion; }; bool fingerprintIsValid(); int fingerprintDigestId(); const char * fingerprintDigestStr(); const char * fingerprintContents(QString digestName = ""); #ifdef COMPILE_ON_WINDOWS // On windows we need to override new and delete operators // to ensure that always the right new/delete pair is called for an object instance // This bug is present in all the classes exported by a module that // can be instantiated/destroyed from external modules. // (this is a well known bug described in Q122675 of MSDN) void * operator new(size_t tSize); void operator delete(void * p); #endif }; class KVILIB_API KviSSLCipherInfo { public: #if OPENSSL_VERSION_NUMBER >= 0x10000000L KviSSLCipherInfo(const SSL_CIPHER * c, const SSL * s); #else KviSSLCipherInfo(SSL_CIPHER * c, SSL * s); #endif ~KviSSLCipherInfo(); protected: KviCString m_szVersion; int m_iNumBits; int m_iNumBitsUsed; KviCString m_szName; KviCString m_szDescription; public: const char * name() { return m_szName.ptr(); }; const char * description() { return m_szDescription.ptr(); }; int bits() { return m_iNumBits; }; int bitsUsed() { return m_iNumBitsUsed; }; const char * version() { return m_szVersion.ptr(); }; #ifdef COMPILE_ON_WINDOWS // On windows we need to override new and delete operators // to ensure that always the right new/delete pair is called for an object instance // This bug is present in all the classes exported by a module that // can be instantiated/destroyed from external modules. // (this is a well known bug described in Q122675 of MSDN) void * operator new(size_t tSize); void operator delete(void * p); #endif }; #ifdef Success #undef Success #endif class KVILIB_API KviSSL { public: enum Method { Client, Server }; enum Result { Success, NotInitialized, WantRead, WantWrite, ZeroReturn, FileIoError, UnknownError, ObscureError, SSLError, SyscallError, RemoteEndClosedConnection }; public: KviSSL(); ~KviSSL(); public: SSL * m_pSSL; SSL_CTX * m_pSSLCtx; KviCString m_szPass; public: static void globalInit(); static void globalDestroy(); static void globalSSLInit(); static void globalSSLDestroy(); public: bool initSocket(kvi_socket_t fd); bool initContext(KviSSL::Method m); void shutdown(); bool setTLSHostname(const char * name); bool enableADHCiphers(); KviSSL::Result connect(); KviSSL::Result accept(); int read(char * buffer, int len); int write(const char * buffer, int len); // SSL ERRORS unsigned long getLastError(bool bPeek = false); bool getLastErrorString(KviCString & buffer, bool bPeek = false); // Protocol error KviSSL::Result getProtocolError(int ret); KviSSLCertificate * getPeerCertificate(); KviSSLCertificate * getLocalCertificate(); KviSSLCipherInfo * getCurrentCipherInfo(); KviSSL::Result useCertificateFile(QString cert, QString pass); KviSSL::Result usePrivateKeyFile(QString key, QString pass); #ifdef COMPILE_ON_WINDOWS // On windows we need to override new and delete operators // to ensure that always the right new/delete pair is called for an object instance // This bug is present in all the classes exported by a module that // can be instantiated/destroyed from external modules. // (this is a well known bug described in Q122675 of MSDN) void * operator new(size_t tSize); void operator delete(void * p); #endif private: KviSSL::Result connectOrAcceptError(int ret); }; #endif //COMPILE_SSL_SUPPORT #endif //_KVI_SSL_H_