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

📄 ssl_tls_c.htm

📁 ssl和tls的源代码实现
💻 HTM
📖 第 1 页 / 共 3 页
字号:
                                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 + -