📄 xyssl - server source code.htm
字号:
static int ssl_write_server_hello( ssl_context *ssl )
{
int i;
time_t t;
unsigned char *buf, *p;
/*
* 0 . 0 handshake type
* 1 . 3 handshake length
* 4 . 5 protocol version
* 6 . 9 UNIX time()
* 10 . 37 random bytes
*/
buf = ssl->out_msg;
p = buf + 4;
*p++ = ssl->major_ver;
*p++ = ssl->minor_ver;
t = time( NULL );
*p++ = (unsigned char)( t >> 24 );
*p++ = (unsigned char)( t >> 16 );
*p++ = (unsigned char)( t >> 8 );
*p++ = (unsigned char)( t );
for( i = 28; i > 0; i-- )
*p++ = ssl->rng_f( ssl->rng_d );
memcpy( ssl->randbytes + 32, buf + 6, 32 );
/*
* 38 . 38 session id length
* 39 . 38+x session id
* 39+x . 40+x chosen cipher
* 41+x . 41+x chosen compression alg.
*/
*p++ = ssl->sidlen = 32;
if( ssl_get_session( ssl ) == 0 )
{
/*
* Found a matching session, resume it
*/
ssl->resumed = 1;
ssl->state = SSL_SERVER_CHANGE_CIPHER_SPEC;
ssl_derive_keys( ssl );
}
else
{
ssl->resumed = 0;
ssl->state++;
for( i = 0; i < ssl->sidlen; i++ )
ssl->sessid[i] = ssl->rng_f( ssl->rng_d );
}
memcpy( p, ssl->sessid, ssl->sidlen );
p += ssl->sidlen;
*p++ = 0;
*p++ = ssl->cipher;
*p++ = SSL_COMPRESS_NULL;
ssl->out_msglen = p - buf;
ssl->out_msgtype = SSL_MSG_HANDSHAKE;
ssl->out_msg[0] = SSL_HS_SERVER_HELLO;
return( ssl_write_record( ssl, 0 ) );
}
static int ssl_write_certificate_request( ssl_context *ssl )
{
int n;
unsigned char *buf, *p;
x509_cert *crt;
ssl->state++;
if( ssl->authmode == SSL_VERIFY_NONE )
return( 0 );
/*
* 0 . 0 handshake type
* 1 . 3 handshake length
* 4 . 4 cert type count
* 5 .. 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.
*/
buf = ssl->out_msg;
p = buf + 4;
*p++ = 1;
*p++ = 1; /* RSA sign */
p += 2;
crt = ssl->ca_chain;
while( crt != NULL && crt->next != NULL )
{
if( p - buf > 4096 )
break;
n = crt->subject_raw.len;
*p++ = ( n >> 8 );
*p++ = ( n );
memcpy( p, crt->subject_raw.p, n );
p += n;
crt = crt->next;
}
ssl->out_msglen = n = p - buf;
ssl->out_msgtype = SSL_MSG_HANDSHAKE;
ssl->out_msg[0] = SSL_HS_CERTIFICATE_REQUEST;
ssl->out_msg[6] = ( (n - 8) >> 8 );
ssl->out_msg[7] = ( (n - 8) );
return( ssl_write_record( ssl, 0 ) );
}
static int ssl_write_server_key_exchange( ssl_context *ssl )
{
int ret, n;
unsigned char hash[36];
md5_context md5;
sha1_context sha1;
if( ssl->cipher != SSL3_EDH_RSA_DES_168_SHA &&
ssl->cipher != TLS1_EDH_RSA_AES_256_SHA )
{
ssl->state++;
return( 0 );
}
#if defined(NO_DHM)
return( ERR_SSL_FEATURE_UNAVAILABLE );
#else
/*
* Ephemeral DH parameters:
*
* struct {
* opaque dh_p<1..2^16-1>;
* opaque dh_g<1..2^16-1>;
* opaque dh_Ys<1..2^16-1>;
* } ServerDHParams;
*/
if( ( ret = dhm_make_params( &ssl->dhm_ctx, ssl->rng_f,
ssl->rng_d, ssl->out_msg + 4, &n ) ) != 0 )
return( ret );
/*
* 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);
*/
md5_starts( &md5 );
md5_update( &md5, ssl->randbytes, 64 );
md5_update( &md5, ssl->out_msg + 4, n );
md5_finish( &md5, hash );
sha1_starts( &sha1 );
sha1_update( &sha1, ssl->randbytes, 64 );
sha1_update( &sha1, ssl->out_msg + 4, n );
sha1_finish( &sha1, hash + 16 );
ssl->out_msg[4 + n] = ( ssl->own_key->len >> 8 );
ssl->out_msg[5 + n] = ( ssl->own_key->len );
if( ( ret = rsa_pkcs1_sign( ssl->own_key, RSA_RAW,
hash, 36, ssl->out_msg + 6 + n,
ssl->own_key->len ) ) != 0 )
return( ret );
ssl->out_msglen = 6 + n + ssl->own_key->len;
ssl->out_msgtype = SSL_MSG_HANDSHAKE;
ssl->out_msg[0] = SSL_HS_SERVER_KEY_EXCHANGE;
ssl->state++;
return( ssl_write_record( ssl, 0 ) );
#endif
}
static int ssl_write_server_hello_done( ssl_context *ssl )
{
ssl->out_msglen = 4;
ssl->out_msgtype = SSL_MSG_HANDSHAKE;
ssl->out_msg[0] = SSL_HS_SERVER_HELLO_DONE;
ssl->state++;
return( ssl_write_record( ssl, 0 ) );
}
static int ssl_parse_client_key_exchange( ssl_context *ssl )
{
int ret, i, n;
if( ( ret = ssl_read_record( ssl, 0 ) ) != 0 )
return( ret );
if( ssl->in_msgtype != SSL_MSG_HANDSHAKE )
return( ERR_SSL_BAD_HS_CLIENT_KEY_EXCHANGE );
if( ssl->in_msg[0] != SSL_HS_CLIENT_KEY_EXCHANGE )
return( ERR_SSL_BAD_HS_CLIENT_KEY_EXCHANGE );
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
/*
* Receive G^Y mod P, premaster = (G^Y)^X mod P
*/
n = ( ssl->in_msg[4] << 8 )
| ( ssl->in_msg[5] );
if( n < 1 || n > ssl->dhm_ctx.len ||
n + 6 != ssl->in_hslen )
return( ERR_SSL_BAD_HS_CLIENT_KEY_EXCHANGE );
if( ( ret = dhm_read_public( &ssl->dhm_ctx,
ssl->in_msg + 6, n ) ) != 0 )
return( ERR_SSL_BAD_HS_CLIENT_KEY_EXCHANGE | ret );
ssl->pmslen = ssl->dhm_ctx.len;
if( ( ret = dhm_calc_secret( &ssl->dhm_ctx,
ssl->premaster,
&ssl->pmslen ) ) != 0 )
return( ERR_SSL_BAD_HS_CLIENT_KEY_EXCHANGE | ret );
#endif
}
else
{
/*
* Decrypt the premaster using own private RSA key
*/
i = 4;
n = ssl->own_key->len;
ssl->pmslen = 48;
if( ssl->minor_ver != SSLV3_MINOR_VERSION )
{
i += 2;
if( ssl->in_msg[4] != ( ( n >> 8 ) & 0xFF ) ||
ssl->in_msg[5] != ( ( n ) & 0xFF ) )
return( ERR_SSL_BAD_HS_CLIENT_KEY_EXCHANGE );
}
if( ssl->in_hslen != i + n )
return( ERR_SSL_BAD_HS_CLIENT_KEY_EXCHANGE );
ret = rsa_pkcs1_decrypt( ssl->own_key,
ssl->in_msg + i, n,
ssl->premaster,
&ssl->pmslen );
if( ret != 0 )
return( ERR_SSL_BAD_HS_CLIENT_KEY_EXCHANGE | ret );
if( ssl->pmslen != 48 ||
memcmp( ssl->premaster, ssl->max_ver, 2 ) != 0 )
return( ERR_SSL_BAD_HS_CLIENT_KEY_EXCHANGE );
}
ssl_derive_keys( ssl );
ssl_set_session( ssl );
ssl->state++;
return( 0 );
}
static int ssl_parse_certificate_verify( ssl_context *ssl )
{
int n1, n2, ret;
unsigned char hash[36];
if( ssl->peer_cert == NULL )
{
ssl->state++;
return( 0 );
}
ssl_calc_verify( ssl, hash );
if( ( ret = ssl_read_record( ssl, 0 ) ) != 0 )
return( ret );
if( ssl->in_msgtype != SSL_MSG_HANDSHAKE )
return( ERR_SSL_BAD_HS_CERTIFICATE_VERIFY );
if( ssl->in_msg[0] != SSL_HS_CERTIFICATE_VERIFY )
return( ERR_SSL_BAD_HS_CERTIFICATE_VERIFY );
n1 = ssl->peer_cert->rsa.len;
n2 = ( (int) ssl->in_msg[4] << 8 )
| ( (int) ssl->in_msg[5] );
if( n1 + 6 != ssl->in_hslen || n1 != n2 )
return( ERR_SSL_BAD_HS_CERTIFICATE_VERIFY );
ret = rsa_pkcs1_verify( &ssl->peer_cert->rsa,
RSA_RAW, hash, 36,
ssl->in_msg + 6, n1 );
ssl->state++;
return( ( ssl->authmode == SSL_VERIFY_REQUIRED ) ? ret : 0 );
}
static const char _ssl_srv_src[] = "_ssl_srv_src";
/*
* SSL handshake -- server side
*/
int ssl_server_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_parse_client_hello( ssl );
break;
/*
* ==> ServerHello
* Certificate
* ( ServerKeyExchange )
* ( CertificateRequest )
* ServerHelloDone
*/
case SSL_SERVER_HELLO:
ret = ssl_write_server_hello( ssl );
break;
case SSL_SERVER_CERTIFICATE:
ret = ssl_write_certificate( ssl );
break;
case SSL_SERVER_KEY_EXCHANGE:
ret = ssl_write_server_key_exchange( ssl );
break;
case SSL_CERTIFICATE_REQUEST:
ret = ssl_write_certificate_request( ssl );
break;
case SSL_SERVER_HELLO_DONE:
ret = ssl_write_server_hello_done( ssl );
break;
/*
* <== ( Certificate/Alert )
* ClientKeyExchange
* ( CertificateVerify )
* ChangeCipherSpec
* Finished
*/
case SSL_CLIENT_CERTIFICATE:
ret = ssl_parse_certificate( ssl );
break;
case SSL_CLIENT_KEY_EXCHANGE:
ret = ssl_parse_client_key_exchange( ssl );
break;
case SSL_CERTIFICATE_VERIFY:
ret = ssl_parse_certificate_verify( ssl );
break;
case SSL_CLIENT_CHANGE_CIPHER_SPEC:
ret = ssl_parse_change_cipher_spec( ssl );
break;
case SSL_CLIENT_FINISHED:
ret = ssl_parse_finished( ssl );
break;
/*
* ==> ChangeCipherSpec
* Finished
*/
case SSL_SERVER_CHANGE_CIPHER_SPEC:
ret = ssl_write_change_cipher_spec( ssl );
break;
case SSL_SERVER_FINISHED:
ret = ssl_write_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 + -