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

📄 xyssl - server source code.htm

📁 ssl的服务器的源代码
💻 HTM
📖 第 1 页 / 共 2 页
字号:

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

⌨️ 快捷键说明

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