📄 xyssl - client source code.htm
字号:
if( (int)( end - p ) != ssl->peer_cert->rsa.len )
return( ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE );
if( ssl->dhm_ctx.len < 64 || ssl->dhm_ctx.len > 256 )
return( ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE );
/*
* digitally-signed struct {
* opaque md5_hash[16];
* opaque sha_hash[20];
* };
*
* md5_hash
* MD5(ClientHello.random + ServerHello.random
* + ServerParams);
* sha_hash
* SHA(ClientHello.random + ServerHello.random
* + ServerParams);
*/
n = ssl->in_hslen - ( end - p ) - 6;
md5_starts( &md5 );
md5_update( &md5, ssl->randbytes, 64 );
md5_update( &md5, ssl->in_msg + 4, n );
md5_finish( &md5, hash );
sha1_starts( &sha1 );
sha1_update( &sha1, ssl->randbytes, 64 );
sha1_update( &sha1, ssl->in_msg + 4, n );
sha1_finish( &sha1, hash + 16 );
n = ssl->peer_cert->rsa.len;
if( ( ret = rsa_pkcs1_verify( &ssl->peer_cert->rsa,
RSA_RAW, hash, 36, p, n ) ) != 0 )
return( ret );
ssl->state++;
return( 0 );
#endif
}
static int ssl_parse_certificate_request( ssl_context *ssl )
{
int ret;
/*
* 0 . 0 handshake type
* 1 . 3 handshake length
* 4 . 5 SSL version
* 6 . 6 cert type count
* 7 .. n-1 cert types
* n .. n+1 length of all DNs
* n+2 .. n+3 length of DN 1
* n+4 .. ... Distinguished Name #1
* ... .. ... length of DN 2, etc.
*/
if( ( ret = ssl_read_record( ssl, 0 ) ) != 0 )
return( ret );
if( ssl->in_msgtype != SSL_MSG_HANDSHAKE )
return( ERR_SSL_UNEXPECTED_MESSAGE );
ssl->state++;
ssl->client_auth = 0;
if( ssl->in_msg[0] == SSL_HS_CERTIFICATE_REQUEST )
{
ssl->client_auth++;
/*
* We may want to continue the handshake, even when
* no client certificate has been configured.
*/
#if 0
if( ssl->own_cert == NULL )
return( ERR_SSL_CERTIFICATE_REQUIRED );
if( ssl->own_key == NULL )
return( ERR_SSL_PRIVATE_KEY_REQUIRED );
#endif
}
return( 0 );
}
static int ssl_parse_server_hello_done( ssl_context *ssl )
{
int ret;
if( ssl->client_auth != 0 )
{
if( ( ret = ssl_read_record( ssl, 0 ) ) != 0 )
return( ret );
if( ssl->in_msgtype != SSL_MSG_HANDSHAKE )
return( ERR_SSL_UNEXPECTED_MESSAGE );
}
if( ssl->in_hslen != 4 ||
ssl->in_msg[0] != SSL_HS_SERVER_HELLO_DONE )
return( ERR_SSL_BAD_HS_SERVER_HELLO_DONE );
ssl->state++;
return( 0 );
}
static int ssl_write_client_key_exchange( ssl_context *ssl )
{
int ret, i, n;
if( ssl->cipher == SSL3_EDH_RSA_DES_168_SHA ||
ssl->cipher == TLS1_EDH_RSA_AES_256_SHA )
{
#if defined(NO_DHM)
return( ERR_SSL_FEATURE_UNAVAILABLE );
#else
/*
* DHM key exchange -- send G^X mod P
*/
n = ssl->dhm_ctx.len;
ssl->out_msg[4] = ( n >> 8 );
ssl->out_msg[5] = ( n );
i = 6;
if( ( ret = dhm_make_public( &ssl->dhm_ctx,
&ssl->out_msg[i], n,
ssl->rng_f,
ssl->rng_d ) ) != 0 )
return( ret );
ssl->pmslen = ssl->dhm_ctx.len;
if( ( ret = dhm_calc_secret( &ssl->dhm_ctx,
ssl->premaster,
&ssl->pmslen ) ) != 0 )
return( ret );
#endif
}
else
{
/*
* RSA key exchange -- send rsa_public(premaster)
*/
memcpy( ssl->premaster, ssl->max_ver, 2 );
ssl->pmslen = 48;
for( i = 2; i < ssl->pmslen; i++ )
ssl->premaster[i] = ssl->rng_f( ssl->rng_d );
i = 4;
n = ssl->peer_cert->rsa.len;
if( ssl->minor_ver != SSLV3_MINOR_VERSION )
{
i += 2;
ssl->out_msg[4] = ( n >> 8 );
ssl->out_msg[5] = ( n );
}
ret = rsa_pkcs1_encrypt( &ssl->peer_cert->rsa,
ssl->premaster,
ssl->pmslen,
ssl->out_msg + i, n );
if( ret != 0 )
return( ret );
}
ssl_derive_keys( ssl );
ssl->out_msglen = i + n;
ssl->out_msgtype = SSL_MSG_HANDSHAKE;
ssl->out_msg[0] = SSL_HS_CLIENT_KEY_EXCHANGE;
ssl->state++;
return( ssl_write_record( ssl, 0 ) );
}
static int ssl_write_certificate_verify( ssl_context *ssl )
{
int ret, n;
unsigned char hash[36];
if( ssl->client_auth == 0 || ssl->own_key == NULL )
{
ssl->state++;
return( 0 );
}
/*
* Make an RSA signature of the handshake digests
*/
ssl_calc_verify( ssl, hash );
n = ssl->own_key->len;
ssl->out_msg[4] = ( n >> 8 );
ssl->out_msg[5] = ( n );
if( ( ret = rsa_pkcs1_sign( ssl->own_key, RSA_RAW, hash, 36,
ssl->out_msg + 6, n ) ) != 0 )
return( ret );
ssl->out_msglen = 6 + n;
ssl->out_msgtype = SSL_MSG_HANDSHAKE;
ssl->out_msg[0] = SSL_HS_CERTIFICATE_VERIFY;
ssl->state++;
return( ssl_write_record( ssl, 0 ) );
}
static const char _ssl_cli_src[] = "_ssl_cli_src";
/*
* SSL handshake -- client side
*/
int ssl_client_start( ssl_context *ssl )
{
int ret = ssl_flush_output( ssl );
while( ret == 0 )
{
switch( ssl->state )
{
case SSL_HELLO_REQUEST:
ssl->state = SSL_CLIENT_HELLO;
break;
/*
* ==> ClientHello
*/
case SSL_CLIENT_HELLO:
ret = ssl_write_client_hello( ssl );
break;
/*
* <== ServerHello
* Certificate
* ( ServerKeyExchange )
* ( CertificateRequest )
* ServerHelloDone
*/
case SSL_SERVER_HELLO:
ret = ssl_parse_server_hello( ssl );
break;
case SSL_SERVER_CERTIFICATE:
ret = ssl_parse_certificate( ssl );
break;
case SSL_SERVER_KEY_EXCHANGE:
ret = ssl_parse_server_key_exchange( ssl );
break;
case SSL_CERTIFICATE_REQUEST:
ret = ssl_parse_certificate_request( ssl );
break;
case SSL_SERVER_HELLO_DONE:
ret = ssl_parse_server_hello_done( ssl );
break;
/*
* ==> ( Certificate/Alert )
* ClientKeyExchange
* ( CertificateVerify )
* ChangeCipherSpec
* Finished
*/
case SSL_CLIENT_CERTIFICATE:
ret = ssl_write_certificate( ssl );
break;
case SSL_CLIENT_KEY_EXCHANGE:
ret = ssl_write_client_key_exchange( ssl );
break;
case SSL_CERTIFICATE_VERIFY:
ret = ssl_write_certificate_verify( ssl );
break;
case SSL_CLIENT_CHANGE_CIPHER_SPEC:
ret = ssl_write_change_cipher_spec( ssl );
break;
case SSL_CLIENT_FINISHED:
ret = ssl_write_finished( ssl );
break;
/*
* <== ChangeCipherSpec
* Finished
*/
case SSL_SERVER_CHANGE_CIPHER_SPEC:
ret = ssl_parse_change_cipher_spec( ssl );
break;
case SSL_SERVER_FINISHED:
ret = ssl_parse_finished( ssl );
break;
default:
return( 0 );
}
}
return( ret );
}
</PRE></TD></TR></TBODY></TABLE><BR> </TD></TR>
<TR align=middle>
<TD class=pagefoot colSpan=2><BR>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -