Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

support raw ssl cert/key/dhparam objects for initialization #59

Open
wants to merge 4 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
155 changes: 111 additions & 44 deletions Csocket.cc
Original file line number Diff line number Diff line change
Expand Up @@ -1044,6 +1044,9 @@ void Csock::Copy( const Csock & cCopy )
m_shostname = cCopy.m_shostname;
m_sbuffer = cCopy.m_sbuffer;
m_sSockName = cCopy.m_sSockName;
m_pUseKey = cCopy.m_pUseKey;
m_pUseCert = cCopy.m_pUseCert;
m_pUseDHParam = cCopy.m_pUseDHParam;
m_sKeyFile = cCopy.m_sKeyFile;
m_sDHParamFile = cCopy.m_sDHParamFile;
m_sPemFile = cCopy.m_sPemFile;
Expand Down Expand Up @@ -1570,20 +1573,32 @@ bool Csock::SSLClientSetup()

SSL_CTX_set_default_verify_paths( m_ssl_ctx );

if( !m_sPemFile.empty() )
{
// are we sending a client cerificate ?
SSL_CTX_set_default_passwd_cb( m_ssl_ctx, _PemPassCB );
SSL_CTX_set_default_passwd_cb_userdata( m_ssl_ctx, ( void * )this );
// are we sending a client cerificate ?
SSL_CTX_set_default_passwd_cb( m_ssl_ctx, _PemPassCB );
SSL_CTX_set_default_passwd_cb_userdata( m_ssl_ctx, ( void * )this );

//
// set up the CTX
// set up the CTX
if( m_pUseCert && m_pUseKey )
{
if( SSL_CTX_use_certificate( m_ssl_ctx, m_pUseCert ) <= 0 )
{
CS_DEBUG( "Error with SSLCert file [" << m_sPemFile << "]" );
SSLErrors( __FILE__, __LINE__ );
}
if( SSL_CTX_use_PrivateKey( m_ssl_ctx, m_pUseKey ) <= 0 )
{
CS_DEBUG( "Error with SSLCert file [" << m_sPemFile << "]" );
SSLErrors( __FILE__, __LINE__ );
}
}
else if( !m_sPemFile.empty() )
{
if( SSL_CTX_use_certificate_file( m_ssl_ctx, m_sPemFile.c_str() , SSL_FILETYPE_PEM ) <= 0 )
{
CS_DEBUG( "Error with SSLCert file [" << m_sPemFile << "]" );
SSLErrors( __FILE__, __LINE__ );
}
CS_STRING privKeyFile = m_sKeyFile.empty() ? m_sPemFile : m_sKeyFile;
CS_STRING privKeyFile = m_sKeyFile.empty() ? m_sPemFile : m_sKeyFile;
if( SSL_CTX_use_PrivateKey_file( m_ssl_ctx, privKeyFile.c_str(), SSL_FILETYPE_PEM ) <= 0 )
{
CS_DEBUG( "Error with SSLKey file [" << privKeyFile << "]" );
Expand Down Expand Up @@ -1704,64 +1719,98 @@ SSL_CTX * Csock::SetupServerCTX()
SSL_CTX_set_default_passwd_cb( pCTX, _PemPassCB );
SSL_CTX_set_default_passwd_cb_userdata( pCTX, ( void * )this );

if( m_sPemFile.empty() || access( m_sPemFile.c_str(), R_OK ) != 0 )
if( !m_pUseCert )
{
CS_DEBUG( "Empty, missing, or bad pemfile ... [" << m_sPemFile << "]" );
SSL_CTX_free( pCTX );
return( NULL );
if( m_sPemFile.empty() || access( m_sPemFile.c_str(), R_OK ) != 0 )
{
CS_DEBUG( "Empty, missing, or bad pemfile ... [" << m_sPemFile << "]" );
SSL_CTX_free( pCTX );
return( NULL );
}
else
{
//
// set up the CTX
if( SSL_CTX_use_certificate_chain_file( pCTX, m_sPemFile.c_str() ) <= 0 )
{
CS_DEBUG( "Error with SSLCert file [" << m_sPemFile << "]" );
SSLErrors( __FILE__, __LINE__ );
SSL_CTX_free( pCTX );
return( NULL );
}
}
}

if( ! m_sKeyFile.empty() && access( m_sKeyFile.c_str(), R_OK ) != 0 )
else
{
CS_DEBUG( "Bad keyfile ... [" << m_sKeyFile << "]" );
SSL_CTX_free( pCTX );
return( NULL );
if( SSL_CTX_use_certificate( pCTX, m_pUseCert ) <= 0 )
{
CS_DEBUG( "Error with SSLCert file [" << m_sPemFile << "]" );
SSLErrors( __FILE__, __LINE__ );
}
}

//
// set up the CTX
if( SSL_CTX_use_certificate_chain_file( pCTX, m_sPemFile.c_str() ) <= 0 )

if( !m_pUseKey )
{
CS_DEBUG( "Error with SSLCert file [" << m_sPemFile << "]" );
SSLErrors( __FILE__, __LINE__ );
SSL_CTX_free( pCTX );
return( NULL );
if( ! m_sKeyFile.empty() && access( m_sKeyFile.c_str(), R_OK ) != 0 )
{
CS_DEBUG( "Bad keyfile ... [" << m_sKeyFile << "]" );
SSL_CTX_free( pCTX );
return( NULL );
}
else
{
CS_STRING privKeyFile = m_sKeyFile.empty() ? m_sPemFile : m_sKeyFile;
if( SSL_CTX_use_PrivateKey_file( pCTX, privKeyFile.c_str(), SSL_FILETYPE_PEM ) <= 0 )
{
CS_DEBUG( "Error with SSLKey file [" << privKeyFile << "]" );
SSLErrors( __FILE__, __LINE__ );
SSL_CTX_free( pCTX );
return( NULL );
}
}
}

CS_STRING privKeyFile = m_sKeyFile.empty() ? m_sPemFile : m_sKeyFile;
if( SSL_CTX_use_PrivateKey_file( pCTX, privKeyFile.c_str(), SSL_FILETYPE_PEM ) <= 0 )
else
{
CS_DEBUG( "Error with SSLKey file [" << privKeyFile << "]" );
SSLErrors( __FILE__, __LINE__ );
SSL_CTX_free( pCTX );
return( NULL );
if( SSL_CTX_use_PrivateKey( pCTX, m_pUseKey ) <= 0 )
{
CS_DEBUG( "Error with SSLCert file [" << m_sPemFile << "]" );
SSLErrors( __FILE__, __LINE__ );
}
}

// check to see if this pem file contains a DH structure for use with DH key exchange
// https://github.com/znc/znc/pull/46
CS_STRING DHParamFile = m_sDHParamFile.empty() ? m_sPemFile : m_sDHParamFile;
FILE *dhParamsFile = fopen( DHParamFile.c_str(), "r" );
if( !dhParamsFile )
DH * pDHParam;
if( !m_pUseDHParam )
{
CS_DEBUG( "Error with DHParam file [" << DHParamFile << "]" );
SSL_CTX_free( pCTX );
return( NULL );
CS_STRING sDHParamFile = m_sDHParamFile.empty() ? m_sPemFile : m_sDHParamFile;
FILE *pDHParamsFile = fopen( sDHParamFile.c_str(), "r" );
if( !pDHParamsFile )
{
CS_DEBUG( "Error with DHParam file [" << sDHParamFile << "]" );
SSL_CTX_free( pCTX );
return( NULL );
}
pDHParam = PEM_read_DHparams( pDHParamsFile, NULL, NULL, NULL );
fclose( pDHParamsFile );
}

DH * dhParams = PEM_read_DHparams( dhParamsFile, NULL, NULL, NULL );
fclose( dhParamsFile );
if( dhParams )
else
{
pDHParam = m_pUseDHParam;
}
if( pDHParam )
{
SSL_CTX_set_options( pCTX, SSL_OP_SINGLE_DH_USE );
if( !SSL_CTX_set_tmp_dh( pCTX, dhParams ) )
if( !SSL_CTX_set_tmp_dh( pCTX, pDHParam ) )
{
CS_DEBUG( "Error setting ephemeral DH parameters from [" << m_sPemFile << "]" );
SSLErrors( __FILE__, __LINE__ );
DH_free( dhParams );
DH_free( pDHParam );
SSL_CTX_free( pCTX );
return( NULL );
}
DH_free( dhParams );
DH_free( pDHParam );
}
else
{
Expand Down Expand Up @@ -2549,6 +2598,15 @@ void Csock::SetSSL( bool b ) { m_bUseSSL = b; }
void Csock::SetCipher( const CS_STRING & sCipher ) { m_sCipherType = sCipher; }
const CS_STRING & Csock::GetCipher() const { return( m_sCipherType ); }

void Csock::SetUseKey( EVP_PKEY * sKeyRaw ) { m_pUseKey = sKeyRaw; }
EVP_PKEY * Csock::GetUseKey() const { return( m_pUseKey ); }

void Csock::SetUseCert( X509 * sCertRaw ) { m_pUseCert = sCertRaw; }
X509 * Csock::GetUseCert() const { return( m_pUseCert ); }

void Csock::SetUseDHParam( DH * sDHParamRaw ) { m_pUseDHParam = sDHParamRaw; }
DH * Csock::GetUseDHParam() const { return( m_pUseDHParam ); }

void Csock::SetDHParamLocation( const CS_STRING & sDHParamFile ) { m_sDHParamFile = sDHParamFile; }
const CS_STRING & Csock::GetDHParamLocation() const { return( m_sDHParamFile ); }

Expand Down Expand Up @@ -3069,6 +3127,9 @@ void Csock::Init( const CS_STRING & sHostname, uint16_t uPort, int iTimeout )
m_uDisableProtocols = 0;
m_bNoSSLCompression = false;
m_bSSLCipherServerPreference = false;
m_pUseCert = NULL;
m_pUseKey = NULL;
m_pUseDHParam = NULL;
#endif /* HAVE_LIBSSL */
m_iTcount = 0;
m_iReadSock = CS_INVALID_SOCK;
Expand Down Expand Up @@ -4044,6 +4105,12 @@ void CSocketManager::Select( std::map<Csock *, EMessages> & mpeSocks )
NewpcSock->SetDHParamLocation( pcSock->GetDHParamLocation() );
NewpcSock->SetKeyLocation( pcSock->GetKeyLocation() );
NewpcSock->SetPemLocation( pcSock->GetPemLocation() );
NewpcSock->SetPemPass( pcSock->GetPemPass() );

NewpcSock->SetUseCert( pcSock->GetUseCert() );
NewpcSock->SetUseKey( pcSock->GetUseKey() );
NewpcSock->SetUseDHParam( pcSock->GetUseDHParam() );

NewpcSock->SetPemPass( pcSock->GetPemPass() );
NewpcSock->SetRequireClientCertFlags( pcSock->GetRequireClientCertFlags() );
bAddSock = NewpcSock->AcceptSSL();
Expand Down
29 changes: 29 additions & 0 deletions Csocket.h
Original file line number Diff line number Diff line change
Expand Up @@ -876,6 +876,14 @@ class CS_EXPORT Csock : public CSockCommon
void SetPemPass( const CS_STRING & sPassword );
const CS_STRING & GetPemPass() const;

//! set raw certificate, keys & dhparam
void SetUseKey( EVP_PKEY * sKeyRaw );
EVP_PKEY * GetUseKey() const;
void SetUseCert( X509 * sCertRaw );
X509 * GetUseCert() const;
void SetUseDHParam( DH * sDHParamRaw );
DH * GetUseDHParam() const;

//! Set the SSL method type
void SetSSLMethod( int iMethod );
int GetSSLMethod() const;
Expand Down Expand Up @@ -1172,6 +1180,9 @@ class CS_EXPORT Csock : public CSockCommon
bool m_bUseSSL, m_bIsConnected;
bool m_bsslEstablished, m_bEnableReadLine, m_bPauseRead;
CS_STRING m_shostname, m_sbuffer, m_sSockName, m_sDHParamFile, m_sKeyFile, m_sPemFile, m_sCipherType, m_sParentName;
X509* m_pUseCert;
EVP_PKEY* m_pUseKey;
DH* m_pUseDHParam;
CS_STRING m_sSend, m_sPemPass;
ECloseType m_eCloseType;

Expand Down Expand Up @@ -1264,6 +1275,9 @@ class CS_EXPORT CSConnection

#ifdef HAVE_LIBSSL
const CS_STRING & GetCipher() const { return( m_sCipher ); }
const X509 * GetUseCert() const { return( m_pUseCert ); }
const EVP_PKEY * GetUseKey() const { return( m_pUseKey ); }
const DH * GetUseDHParam() const { return( m_pUseDHParam ); }
const CS_STRING & GetPemLocation() const { return( m_sPemLocation ); }
const CS_STRING & GetKeyLocation() const { return( m_sKeyLocation ); }
const CS_STRING & GetDHParamLocation() const { return( m_sDHParamLocation ); }
Expand Down Expand Up @@ -1302,6 +1316,9 @@ class CS_EXPORT CSConnection
CSSockAddr::EAFRequire m_iAFrequire;
#ifdef HAVE_LIBSSL
CS_STRING m_sDHParamLocation, m_sKeyLocation, m_sPemLocation, m_sPemPass, m_sCipher;
X509* m_pUseCert;
EVP_PKEY* m_pUseKey;
DH* m_pUseDHParam;
#endif /* HAVE_LIBSSL */
};

Expand Down Expand Up @@ -1356,6 +1373,9 @@ class CS_EXPORT CSListener
#ifdef HAVE_LIBSSL
const CS_STRING & GetCipher() const { return( m_sCipher ); }
const CS_STRING & GetDHParamLocation() const { return( m_sDHParamLocation ); }
const EVP_PKEY * GetUseKey() const { return( m_pUseKey ); }
const X509 * GetUseCert() const { return( m_pUseCert ); }
const DH * GetUseDHParam() const { return( m_pUseDHParam ); }
const CS_STRING & GetKeyLocation() const { return( m_sKeyLocation ); }
const CS_STRING & GetPemLocation() const { return( m_sPemLocation ); }
const CS_STRING & GetPemPass() const { return( m_sPemPass ); }
Expand All @@ -1380,6 +1400,12 @@ class CS_EXPORT CSListener
#ifdef HAVE_LIBSSL
//! set the cipher strength to use, default is HIGH
void SetCipher( const CS_STRING & s ) { m_sCipher = s; }
//! set the raw cert data
void SetUseCert( X509 * s ) { m_pUseCert = s; }
//! set the raw key data
void SetUseKey( EVP_PKEY * s ) { m_pUseKey = s; }
//! set the raw dhparam data
void SetUseDHParam( DH * s ) { m_pUseDHParam = s; }
//! set the location of the pemfile
void SetPemLocation( const CS_STRING & s ) { m_sPemLocation = s; }
//! set the location of the keyfile
Expand All @@ -1404,6 +1430,9 @@ class CS_EXPORT CSListener

#ifdef HAVE_LIBSSL
CS_STRING m_sDHParamLocation, m_sKeyLocation, m_sPemLocation, m_sPemPass, m_sCipher;
X509* m_pUseCert;
EVP_PKEY* m_pUseKey;
DH* m_pUseDHParam;
uint32_t m_iRequireCertFlags;
#endif /* HAVE_LIBSSL */
};
Expand Down