⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 xyssl - client source code.htm

📁 ssl客户端的源代码实现
💻 HTM
📖 第 1 页 / 共 2 页
字号:

    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>&nbsp; </TD></TR>
  <TR align=middle>
    <TD class=pagefoot colSpan=2><BR>

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -