📄 ssl.c
字号:
iTmp = SSL_VERIFY_NONE; break;
case 1:
iTmp = SSL_VERIFY_PEER | SSL_VERIFY_CLIENT_ONCE; break;
case 2:
iTmp = SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT; break;
default:
PILog_addMessage(
PIObject_getDB( pObject ),
PIObject_getConfigurationDB( pObject ),
PILOG_ERROR, "%sSSL: Bad SSL verification code %d. \
Accepted verification codes are 0, 1, 2 or 3.", pWhere, iTmp );
return 0;
};
pConf->iVerify = iTmp;
}
else if ( !PIUtil_stricmp( pVar, KEY_CONF_VERIFYDEPTH ) )
{ pConf->iVerifyDepth = atoi( pVal ); }
else if ( !PIUtil_stricmp( KEY_CONF_TYPE, pVar ) )
{ pConf->iServer = PIUtil_stricmp( pVal, VALUE_PASSIVE ) ? 0 : 1; }
else if ( !PIUtil_stricmp( pVar, KEY_CONF_PRIVATEKEYFILE ) )
{ pConf->pKeyF = PIUtil_strdup( pVal ); }
else if ( !PIUtil_stricmp( pVar, KEY_CONF_CACERTIFICATEPATH ) )
{ pConf->pCACertP = PIUtil_strdup( pVal ); }
else if ( !PIUtil_stricmp( pVar, KEY_CONF_CACERTIFICATEFILE ) )
{ pConf->pCACertF = PIUtil_strdup( pVal ); }
else if ( !PIUtil_stricmp( pVar, KEY_CONF_CERTIFICATEFILE ) )
{ pConf->pCertF = PIUtil_strdup( pVal ); }
else if ( !PIUtil_stricmp( pVar, KEY_CONF_DEBUGFILE ) )
{ pConf->pDebugFile = PIUtil_strdup( pVal ); }
else if ( !PIUtil_stricmp( pVar, KEY_CONF_CIPHERLIST ) )
{ pConf->pCipherList = PIUtil_strdup( pVal ); }
else if ( !PIUtil_stricmp( pVar, KEY_CONF_RANDOMSEEDFILE ) )
{ pConf->pRandomSeedFile = PIUtil_strdup( pVal ); }
else if ( !PIUtil_stricmp( pVar, KEY_CONF_RANDOMSEEDSIZE ) )
{ pConf->iRandomSize = atoi( pVal ); }
else if ( !PIUtil_stricmp( pVar, KEY_CONF_PASSPHRASE ) )
{ pConf->pPassPhrase = PIUtil_strdup( pVal ); }
else if ( !PIUtil_stricmp( pVar, KEY_CONF_FLAG ) )
{
if ( !PIUtil_stricmp( pVal, VALUE_BUGS ) )
{ pConf->iBugs = 1; }
else if ( !PIUtil_stricmp( pVal, VALUE_HACK ) )
{ pConf->iHack = 1; }
else if ( !PIUtil_stricmp( pVal, VALUE_DISABLE ) )
{ pConf->iDisable = 1; }
else
{
PILog_addMessage(
PIObject_getDB( pObject ),
PIObject_getConfigurationDB( pObject ),
PILOG_ERROR, "%sSSL: Unknown flag '%s'.", pWhere, pVal );
return 0;
};
}
else if ( !PIUtil_stricmp( pVar, KEY_CONF_IOOBJECT ) )
{
/*
Load the prototype for the transport IO object. The function
PIObject_loadFromLine() will log the appropriate error messages
if it fails
*/
pSSL->pIOObject = PIObject_loadFromLine(
PIObject_getDB( pObject ),
PIObject_getConfigurationDB( pObject ),
pVal );
if ( !pSSL->pIOObject )
{ return 0; };
}
else
{
/* ---
Configuration error
--- */
PILog_addMessage(
PIObject_getDB( pObject ),
PIObject_getConfigurationDB( pObject ),
PILOG_ERROR, "%sSSL: Unknown directive '%s'.", pWhere, pVar );
return 0;
};
return 1;
}
/*____________________________________________________________________________*\
*
Function:
Synopsis:
Description:
Return non-zero on success, zero on failure.
\*____________________________________________________________________________*/
int SSL_init( PIObject *pObject, int iArgc, const char *ppArgv[] )
{
PISSL *pPrototype;
SSLConf *pConf;
int iRet;
SSL_METHOD *pSSLMethod = 0;
SSL *pSSL;
X509 *pX509;
PIFInfo *pFInfo;
PIPLATFORM_FD tFD;
void *pBuf;
EVP_PKEY *pKey;
FILE *fp;
static const char rnd_seed[] = "string to make the random number generator think it has entropy";
pPrototype = PIObject_getUserData( pObject );
pConf = pPrototype->pConf;
iRet = PIObject_readParameters( pObject, iArgc, ppArgv,
SSL_fnParameter, pObject );
if ( !iRet )
{
goto init_error;
};
/* ---
Initialize the random number generator
or OAEP may fail
--- */
if ( pConf->pRandomSeedFile && !pConf->iDisable )
{
/* --- get file info --- */
pFInfo = PIFInfo_new( pConf->pRandomSeedFile );
if ( !pFInfo || !PIFInfo_exists( pFInfo ) || PIFInfo_isDirectory( pFInfo )
|| !PIFInfo_isReadable( pFInfo))
{
PIFInfo_delete( pFInfo );
PILog_addMessage(
PIObject_getDB( pObject ),
PIObject_getConfigurationDB( pObject ),
PILOG_ERROR, "SSL: random seed file '%s' \
doesn't exist or isn't readable.",
pConf->pRandomSeedFile );
goto init_error;
};
PIFInfo_delete( pFInfo );
/* --- open file handle --- */
if ((tFD = PIFile_open( pConf->pRandomSeedFile, "r" )) == PIPLATFORM_FD_INVALID)
{
/* --- handle error --- */
int iErrorCode = PIPlatform_getLastError();
PILog_addMessage(
PIObject_getDB( pObject ),
PIObject_getConfigurationDB( pObject ),
PILOG_ERROR, "SSL: Error on open random seed file '%s'. \
The system error code is %d.",
pConf->pRandomSeedFile, iErrorCode );
goto init_error;
};
pBuf = PIUtil_malloc( pConf->iRandomSize );
if ( !pBuf )
{
/* --- handle error --- */
int iErrorCode = PIPlatform_getLastError();
PILog_addMessage(
PIObject_getDB( pObject ),
PIObject_getConfigurationDB( pObject ),
PILOG_ERROR, "SSL: Error on allocate random seed buffer. \
The system error code is %d.", iErrorCode );
goto init_error;
};
PIFile_read( tFD, pConf->iRandomSize, pBuf );
PIFile_close( tFD );
RAND_seed( pBuf, pConf->iRandomSize );
PIUtil_free( pBuf );
}
else
{
RAND_seed(rnd_seed, sizeof rnd_seed);
};
/*
** Open a debug file ?
*/
if ( pConf->pDebugFile )
{
if ( !strcmp( pConf->pDebugFile, "STDERR" ) )
{
pConf->pBIODebug = BIO_new_fp(stderr,BIO_NOCLOSE);
}
else if ( !strcmp( pConf->pDebugFile, "STDOUT" ) )
{
pConf->pBIODebug = BIO_new_fp(stdout,BIO_NOCLOSE);
}
else
{
pConf->pStdioDebug = fopen( pConf->pDebugFile, "w" );
if ( !pConf->pStdioDebug )
{
PILog_addMessage(
PIObject_getDB( pObject ),
PIObject_getConfigurationDB( pObject ),
PILOG_ERROR, "SSL: Failed to open debug file '%s'.",
pConf->pDebugFile );
goto init_error;
};
pConf->pBIODebug = BIO_new_fp( pConf->pStdioDebug, BIO_NOCLOSE );
};
}
/* ---
Check values were set
--- */
if ( !pPrototype->pIOObject )
{
PILog_addMessage(
PIObject_getDB( pObject ), PIObject_getConfigurationDB( pObject ),
PILOG_ERROR, "SSL: 'IOObject' not defined." );
goto init_error;
};
if ( !pConf->iServer && !pConf->pKeyF )
{
PILog_addMessage(
PIObject_getDB( pObject ),
PIObject_getConfigurationDB( pObject ),
PILOG_ERROR, "SSL: 'PrivateKeyFile' must be defined \
for server connection." );
goto init_error;
};
/* --- get file info --- */
pFInfo = PIFInfo_new( pConf->pKeyF );
if ( !pFInfo || !PIFInfo_exists( pFInfo ) || PIFInfo_isDirectory( pFInfo )
|| !PIFInfo_isReadable( pFInfo))
{
PIFInfo_delete( pFInfo );
PILog_addMessage(
PIObject_getDB( pObject ),
PIObject_getConfigurationDB( pObject ),
PILOG_ERROR, "SSL: private key file '%s' \
doesn't exist or isn't readable.",
pConf->pKeyF );
goto init_error;
};
PIFInfo_delete( pFInfo );
if ( !pConf->iServer && !pConf->pCertF )
{
PILog_addMessage(
PIObject_getDB( pObject ),
PIObject_getConfigurationDB( pObject ),
PILOG_ERROR, "SSL: 'CertificateFile' must be defined \
for server connection." );
goto init_error;
};
/* --- get file info --- */
pFInfo = PIFInfo_new( pConf->pCertF );
if ( !pFInfo || !PIFInfo_exists( pFInfo ) || PIFInfo_isDirectory( pFInfo )
|| !PIFInfo_isReadable( pFInfo))
{
PIFInfo_delete( pFInfo );
PILog_addMessage(
PIObject_getDB( pObject ),
PIObject_getConfigurationDB( pObject ),
PILOG_ERROR, "SSL: certificate file '%s' \
doesn't exist or isn't readable.",
pConf->pCertF );
goto init_error;
};
PIFInfo_delete( pFInfo );
/*
** Funny little piece of code
*/
switch( pConf->iVersion * ( 1 + pConf->iServer ) )
{
case 10: pSSLMethod = TLSv1_client_method(); break;
case 23: pSSLMethod = SSLv23_client_method(); break;
case 2: pSSLMethod = SSLv2_client_method(); break;
case 3: pSSLMethod = SSLv3_client_method(); break;
case 20: pSSLMethod = TLSv1_server_method(); break;
case 46: pSSLMethod = SSLv23_server_method(); break;
case 4: pSSLMethod = SSLv2_server_method(); break;
case 6: pSSLMethod = SSLv3_server_method(); break;
default:
assert( 0 );
};
pConf->pCtx = SSL_CTX_new( pSSLMethod );
if ( !pConf->pCtx )
{
PILog_addMessage(
PIObject_getDB( pObject ), PIObject_getConfigurationDB( pObject ),
PILOG_ERROR, "SSL: 'SSL_CTX_new()' failed." );
INIT_ERR( pConf->pBIODebug );
goto init_error;
};
#if ( PISSL_DEBUG )
SSL_CTX_set_info_callback( pConf->pCtx, fnSSLInfo );
#endif
/*
** Set list of allowed ciphers
*/
if ( pConf->pCipherList &&
!SSL_CTX_set_cipher_list( pConf->pCtx, pConf->pCipherList ) )
{
/*
** Cipher list was specified, but failed to set it
*/
PILog_addMessage(
PIObject_getDB( pObject ), PIObject_getConfigurationDB( pObject ),
PILOG_ERROR, "SSL: 'SSL_set_cipher_list()' failed \
for cipher list '%s'.", pConf->pCipherList );
INIT_ERR( pConf->pBIODebug );
goto init_error;
};
/*
** What are these for??
*/
if ( pConf->iBugs )
{ SSL_CTX_set_options( pConf->pCtx, SSL_OP_ALL); };
if ( pConf->iHack )
{
SSL_CTX_set_options( pConf->pCtx,
SSL_OP_NETSCAPE_DEMO_CIPHER_CHANGE_BUG);
// SSL_CTX_set_options( pConf->pCtx, SSL_OP_NON_EXPORT_FIRST);
};
if ( (!SSL_CTX_load_verify_locations( pConf->pCtx, pConf->pCACertF,
pConf->pCACertP ) ) &&
(!SSL_CTX_set_default_verify_paths( pConf->pCtx ) ) )
{
PILog_addMessage(
PIObject_getDB( pObject ), PIObject_getConfigurationDB( pObject ),
PILOG_ERROR, "SSL: 'SSL_CTX_load_verify_locations()' failed." );
INIT_ERR( pConf->pBIODebug );
goto init_error;
}
/*
** Set SSL verification callback
*/
SSL_CTX_set_verify( pConf->pCtx, pConf->iVerify, fnVerify );
if ( SSL_CTX_use_certificate_file(pConf->pCtx, pConf->pCertF,
SSL_FILETYPE_PEM) ==-1 )
{
PILog_addMessage(
PIObject_getDB( pObject ), PIObject_getConfigurationDB( pObject ),
PILOG_ERROR, "SSL: 'SSL_CTX_use_certificate_file()' failed." );
INIT_ERR( pConf->pBIODebug );
goto init_error;
};
/* --- open file handle --- */
fp = fopen( pConf->pKeyF, "r" );
if ( !fp )
{
PILog_addMessage(
PIObject_getDB( pObject ),
PIObject_getConfigurationDB( pObject ),
PILOG_ERROR, "SSL: Failed to open private key file '%s'.",
pConf->pKeyF );
goto init_error;
};
/* --- for passphrase callback --- */
if ( (pKey = PEM_read_PrivateKey( fp, NULL, &fnPassPhrase, pConf )) == NULL )
{
PILog_addMessage(
PIObject_getDB( pObject ), PIObject_getConfigurationDB( pObject ),
PILOG_ERROR, "SSL: 'PEM_read_PrivateKey()' failed. \n\
Check, if you entered the correct pass phrase for the used private key!" );
fclose( fp );
// INIT_ERR;
goto init_error;
};
fclose( fp );
/* old
if ( SSL_CTX_use_PrivateKey_file(pConf->pCtx, pConf->pKeyF,
SSL_FILETYPE_PEM) ==-1 )
*/
if ( SSL_CTX_use_PrivateKey( pConf->pCtx, pKey ) == -1 )
{
PILog_addMessage(
PIObject_getDB( pObject ), PIObject_getConfigurationDB( pObject ),
PILOG_ERROR, "SSL: 'SSL_CTX_use_PrivateKey()' failed." );
INIT_ERR( pConf->pBIODebug );
goto init_error;
};
SSL_CTX_set_tmp_rsa_callback( pConf->pCtx, fnTmpRSA );
/*
** If we are using DSA, we can copy the parameters from
** the private key
*/
pSSL=SSL_new( pConf->pCtx );
assert( pSSL );
CRYPTO_set_ex_data(&pSSL->ex_data, 0, (char *)pPrototype );
pX509=SSL_get_certificate( pSSL );
if ( pX509 )
{
EVP_PKEY_copy_parameters(
X509_get_pubkey( pX509 ), SSL_get_privatekey( pSSL ) );
};
SSL_free( pSSL );
/*
** Now we know that a key and cert have been set against
** the SSL context
*/
if ( !SSL_CTX_check_private_key( pConf->pCtx ) )
{
PILog_addMessage(
PIObject_getDB( pObject ), PIObject_getConfigurationDB( pObject ),
PILOG_ERROR, "SSL: Private key does not match the \
certificate public key." );
INIT_ERR( pConf->pBIODebug );
goto init_error;
}
return iRet;
init_error:
return 0;
}
static PISync **SSL_sync;
/*____________________________________________________________________________*\
*
Function:
Synopsis:
Description:
\*____________________________________________________________________________*/
void locking_callback(int mode, int type, const char *file, int line)
{
mode & CRYPTO_LOCK ? PISync_lock(SSL_sync[type]) : PISync_unlock(SSL_sync[type]);
}
/*____________________________________________________________________________*\
*
Function:
Synopsis:
Description:
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -