#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 <openssl/ssl.h>
class KVILIB_API KviSSLCertificate
{
public:
KviSSLCertificate(X509 * x509);
~KviSSLCertificate();
protected:
X509 * m_pX509;
KviPointerHashTable<const char *, KviCString> * m_pSubject;
KviPointerHashTable<const char *, KviCString> * 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<const char *, KviCString> * dict, const char * entry);
void splitX509String(KviPointerHashTable<const char *, KviCString> * 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_