📄 ssl_tls_c.htm
字号:
ssl->peer_cn, &ssl->verify_result );
if( ssl->authmode == SSL_VERIFY_REQUIRED )
return( ret );
}
return( 0 );
}
int ssl_write_change_cipher_spec( ssl_context *ssl )
{
ssl->out_msgtype = SSL_MSG_CHANGE_CIPHER_SPEC;
ssl->out_msg[0] = ssl->out_msglen = 1;
ssl->state++;
return( ssl_write_record( ssl, 0 ) );
}
int ssl_parse_change_cipher_spec( ssl_context *ssl )
{
int ret;
if( ( ret = ssl_read_record( ssl, 0 ) ) != 0 )
return( ret );
if( ssl->in_msgtype != SSL_MSG_CHANGE_CIPHER_SPEC )
return( ERR_SSL_UNEXPECTED_MESSAGE );
if( ssl->in_msglen != 1 || ssl->in_msg[0] != 1 )
return( ERR_SSL_BAD_HS_CHANGE_CIPHER_SPEC );
ssl->state++;
return( 0 );
}
static void ssl_calc_finished(
ssl_context *ssl, unsigned char *buf, int from,
md5_context *md5, sha1_context *sha1 )
{
char *sender;
unsigned char padbuf[48];
unsigned char md5sum[16];
unsigned char sha1sum[20];
/*
* SSLv3:
* hash =
* MD5( master + pad2 +
* MD5( handshake + sender + master + pad1 ) )
* + SHA1( master + pad2 +
* SHA1( handshake + sender + master + pad1 ) )
*
* TLSv1:
* hash = PRF( master, finished_label,
* MD5( handshake ) + SHA1( handshake ) )[0..11]
*/
if( ssl->minor_ver == SSLV3_MINOR_VERSION )
{
sender = ( from == SSL_IS_CLIENT ) ? (char *) "CLNT"
: (char *) "SRVR";
memset( padbuf, 0x36, 48 );
md5_update( md5, (unsigned char *) sender, 4 );
md5_update( md5, ssl->master, 48 );
md5_update( md5, padbuf, 48 );
md5_finish( md5, md5sum );
sha1_update( sha1, (unsigned char *) sender, 4 );
sha1_update( sha1, ssl->master, 48 );
sha1_update( sha1, padbuf, 40 );
sha1_finish( sha1, sha1sum );
memset( padbuf, 0x5C, 48 );
md5_starts( md5 );
md5_update( md5, ssl->master, 48 );
md5_update( md5, padbuf, 48 );
md5_update( md5, md5sum, 16 );
md5_finish( md5, buf );
sha1_starts( sha1 );
sha1_update( sha1, ssl->master, 48 );
sha1_update( sha1, padbuf , 40 );
sha1_update( sha1, sha1sum, 20 );
sha1_finish( sha1, buf + 16 );
}
else
{
sender = ( from == SSL_IS_CLIENT )
? (char *) "client finished"
: (char *) "server finished";
md5_finish( md5, padbuf );
sha1_finish( sha1, padbuf + 16 );
tls1_prf( ssl->master, 48, sender, padbuf, 36, buf, 12 );
}
memset( md5, 0, sizeof( md5_context ) );
memset( sha1, 0, sizeof( sha1_context ) );
memset( padbuf, 0, sizeof( padbuf ) );
memset( md5sum, 0, sizeof( md5sum ) );
memset( sha1sum, 0, sizeof( sha1sum ) );
}
int ssl_write_finished( ssl_context *ssl )
{
int hash_len = 12;
md5_context md5;
sha1_context sha1;
memcpy( &md5 , &ssl->hs_md5 , sizeof( md5_context ) );
memcpy( &sha1, &ssl->hs_sha1, sizeof( sha1_context ) );
ssl_calc_finished( ssl, ssl->out_msg + 4,
ssl->endpoint, &md5, &sha1 );
if( ssl->minor_ver == SSLV3_MINOR_VERSION )
hash_len += 24;
ssl->out_msglen = 4 + hash_len;
ssl->out_msgtype = SSL_MSG_HANDSHAKE;
ssl->out_msg[0] = SSL_HS_FINISHED;
/*
* In case of session resuming, invert the client and server
* ChangeCipherSpec messages order.
*/
if( ssl->resumed != 0 )
{
if( ssl->endpoint == SSL_IS_CLIENT )
ssl->state = SSL_HANDSHAKE_OVER;
if( ssl->endpoint == SSL_IS_SERVER )
ssl->state = SSL_CLIENT_CHANGE_CIPHER_SPEC;
}
else
ssl->state++;
return( ssl_write_record( ssl, 1 ) );
}
int ssl_parse_finished( ssl_context *ssl )
{
int ret, hash_len = 12;
unsigned char buf[36];
md5_context md5;
sha1_context sha1;
memcpy( &md5 , &ssl->hs_md5 , sizeof( md5_context ) );
memcpy( &sha1, &ssl->hs_sha1, sizeof( sha1_context ) );
if( ( ret = ssl_read_record( ssl, 1 ) ) != 0 )
return( ret );
if( ssl->in_msgtype != SSL_MSG_HANDSHAKE )
return( ERR_SSL_UNEXPECTED_MESSAGE );
if( ssl->minor_ver == SSLV3_MINOR_VERSION )
hash_len += 24;
if( ssl->in_msg[0] != SSL_HS_FINISHED ||
ssl->in_hslen != 4 + hash_len )
return( ERR_SSL_BAD_HS_FINISHED );
ssl_calc_finished( ssl, buf, ssl->endpoint ^ 1, &md5, &sha1 );
if( memcmp( ssl->in_msg + 4, buf, hash_len ) != 0 )
return( ERR_SSL_BAD_HS_FINISHED );
if( ssl->resumed != 0 )
{
if( ssl->endpoint == SSL_IS_CLIENT )
ssl->state = SSL_CLIENT_CHANGE_CIPHER_SPEC;
if( ssl->endpoint == SSL_IS_SERVER )
ssl->state = SSL_HANDSHAKE_OVER;
}
else
ssl->state++;
return( 0 );
}
/*
* SSL context setup functions
*/
int ssl_init( ssl_context *ssl, int client_resume )
{
int tmp_sidlen = 0;
unsigned char tmp_sessid[32];
unsigned char tmp_master[48];
if( client_resume != 0 )
{
/*
* Backup the session id and master secret
*/
tmp_sidlen = ssl->sidlen;
memcpy( tmp_sessid, ssl->sessid, 32 );
memcpy( tmp_master, ssl->master, 48 );
}
memset( ssl, 0, sizeof( ssl_context ) );
ssl->in_ctr = (unsigned char *) malloc( SSL_BUFFER_LEN );
ssl->in_hdr = ssl->in_ctr + 8;
ssl->in_msg = ssl->in_ctr + 13;
ssl->out_ctr = (unsigned char *) malloc( SSL_BUFFER_LEN );
ssl->out_hdr = ssl->out_ctr + 8;
ssl->out_msg = ssl->out_ctr + 13;
if( ssl->in_ctr == NULL || ssl->out_ctr == NULL )
return( 1 );
memset( ssl-> in_ctr, 0, 8 );
memset( ssl->out_ctr, 0, 8 );
if( client_resume != 0 )
{
ssl->sidlen = tmp_sidlen;
memcpy( ssl->sessid, tmp_sessid, 32 );
memcpy( ssl->master, tmp_master, 48 );
}
return( 0 );
}
/*
* SSL set accessors
*/
void ssl_set_endpoint( ssl_context *ssl, int endpoint )
{
ssl->endpoint = endpoint;
}
void ssl_set_authmode( ssl_context *ssl, int authmode )
{
ssl->authmode = authmode;
}
void ssl_set_rng_func( ssl_context *ssl,
int (*rng_f)(void *),
void *rng_d )
{
ssl->rng_f = rng_f;
ssl->rng_d = rng_d;
}
void ssl_set_io_files( ssl_context *ssl, int read_fd, int write_fd )
{
ssl->read_fd = read_fd;
ssl->write_fd = write_fd;
}
void ssl_set_ciphlist( ssl_context *ssl, int *ciphers )
{
ssl->cipherlist = ciphers;
}
void ssl_set_ca_chain( ssl_context *ssl, x509_cert *ca, char *cn )
{
ssl->ca_chain = ca;
ssl->peer_cn = cn;
}
void ssl_set_rsa_cert( ssl_context *ssl, x509_cert *own_cert,
rsa_context *own_key )
{
ssl->own_cert = own_cert;
ssl->own_key = own_key;
}
void ssl_set_sidtable( ssl_context *ssl, unsigned char *sidtable )
{
ssl->sidtable = sidtable;
}
int ssl_set_dhm_vals( ssl_context *ssl, char *dhm_P, char *dhm_G )
{
if( mpi_read_string( &ssl->dhm_ctx.P, 16, dhm_P ) != 0 ||
mpi_read_string( &ssl->dhm_ctx.G, 16, dhm_G ) != 0 )
return( 1 );
return( 0 );
}
/*
* SSL get accessors
*/
int ssl_get_verify_result( ssl_context *ssl )
{
return( ssl->verify_result );
}
char *ssl_get_cipher_name( ssl_context *ssl )
{
switch( ssl->cipher )
{
#if !defined(NO_ARC4)
case SSL3_RSA_RC4_128_MD5:
return( "SSL3_RSA_RC4_128_MD5" );
case SSL3_RSA_RC4_128_SHA:
return( "SSL3_RSA_RC4_128_SHA" );
#endif
#if !defined(NO_DES)
case SSL3_RSA_DES_168_SHA:
return( "SSL3_RSA_DES_168_SHA" );
case SSL3_EDH_RSA_DES_168_SHA:
return( "SSL3_EDH_RSA_DES_168_SHA" );
#endif
#if !defined(NO_AES)
case TLS1_RSA_AES_256_SHA:
return( "TLS1_RSA_AES_256_SHA" );
case TLS1_EDH_RSA_AES_256_SHA:
return( "TLS1_EDH_RSA_AES_256_SHA" );
#endif
default:
break;
}
return( "UNKNOWN_CIPHER" );
}
int ssl_default_ciphers[] =
{
#if !defined(NO_DHM)
#if !defined(NO_AES)
TLS1_EDH_RSA_AES_256_SHA,
#endif
#if !defined(NO_DES)
SSL3_EDH_RSA_DES_168_SHA,
#endif
#endif
#if !defined(NO_AES)
TLS1_RSA_AES_256_SHA,
#endif
#if !defined(NO_DES)
SSL3_RSA_DES_168_SHA,
#endif
#if !defined(NO_ARC4)
SSL3_RSA_RC4_128_SHA,
SSL3_RSA_RC4_128_MD5,
#endif
0
};
/*
* Perform the SSL handshake
*/
int ssl_handshake( ssl_context *ssl )
{
#if !defined(NO_SSL_CLI)
if( ssl->endpoint == SSL_IS_CLIENT )
return( ssl_client_start( ssl ) );
#endif
#if !defined(NO_SSL_SRV)
if( ssl->endpoint == SSL_IS_SERVER )
return( ssl_server_start( ssl ) );
#endif
return( ERR_SSL_FEATURE_UNAVAILABLE );
}
/*
* Receive application data decrypted from the SSL layer
*/
int ssl_read( ssl_context *ssl, unsigned char *buf, int *len )
{
int ret, n;
if( ( ret = ssl_handshake( ssl ) ) != 0 )
return( ret );
if( ssl->in_offt == NULL )
{
if( ( ret = ssl_read_record( ssl, 1 ) ) != 0 )
return( ret );
if( ssl->in_msgtype != SSL_MSG_APPLICATION_DATA )
return( ERR_SSL_UNEXPECTED_MESSAGE );
ssl->in_offt = ssl->in_msg;
}
n = ( *len < ssl->in_msglen )
? *len : ssl->in_msglen;
memcpy( buf, ssl->in_offt, n );
ssl->in_msglen -= ( *len = n );
if( ssl->in_msglen == 0 )
ssl->in_offt = NULL;
else
ssl->in_offt += n;
return( 0 );
}
/*
* Send application data to be encrypted by the SSL layer
*/
int ssl_write( ssl_context *ssl, unsigned char *buf, int len )
{
int ret, n;
ret = ssl_handshake( ssl );
while( ssl->out_uoff < len && ret == 0 )
{
n = ( ( len - ssl->out_uoff ) < SSL_MAX_CONTENT_LEN )
? ( len - ssl->out_uoff ) : SSL_MAX_CONTENT_LEN;
ssl->out_uoff += n;
ssl->out_msglen = n;
ssl->out_msgtype = SSL_MSG_APPLICATION_DATA;
memcpy( ssl->out_msg, buf, n ); buf += n;
ret = ssl_write_record( ssl, 1 );
}
if( ssl->out_uoff >= len )
ssl->out_uoff = 0;
return( ret );
}
/*
* Notify the peer that the connection is being closed
*/
int ssl_close_notify( ssl_context *ssl )
{
int ret = ssl_flush_output( ssl );
if( ret == 0 && ssl->state == SSL_HANDSHAKE_OVER )
{
ssl->out_msgtype = SSL_MSG_ALERT;
ssl->out_msglen = 2;
ssl->out_msg[0] = SSL_ALERT_WARNING;
ssl->out_msg[1] = SSL_ALERT_CLOSE_NOTIFY;
ssl->state++;
ret = ssl_write_record( ssl, 1 );
}
return( ret );
}
static const char _ssl_tls_src[] = "_ssl_tls_src";
/*
* Free an SSL context
*/
void ssl_free( ssl_context *ssl )
{
if( ssl->ctx_dec != NULL )
{
memset( ssl->ctx_dec, 0, ssl->ctxlen );
free( ssl->ctx_dec );
ssl->ctx_dec = NULL;
}
if( ssl->ctx_enc != NULL )
{
memset( ssl->ctx_enc, 0, ssl->ctxlen );
free( ssl->ctx_enc );
ssl->ctx_enc = NULL;
}
#if !defined(NO_DHM)
dhm_free( &ssl->dhm_ctx );
#endif
if( ssl->peer_cert != NULL )
{
x509_free_cert( ssl->peer_cert );
free( ssl->peer_cert );
ssl->peer_cert = NULL;
}
if( ssl->out_ctr != NULL )
{
memset( ssl->out_ctr, 0, SSL_BUFFER_LEN );
free( ssl->out_ctr );
ssl->out_ctr = NULL;
}
if( ssl->in_ctr != NULL )
{
memset( ssl->in_ctr, 0, SSL_BUFFER_LEN );
free( ssl->in_ctr );
ssl->in_ctr = NULL;
}
}
</PRE></BODY></HTML>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -