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

📄 ssl_tls_c.htm

📁 ssl和tls的源代码实现
💻 HTM
📖 第 1 页 / 共 3 页
字号:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<!-- saved from url=(0046)http://xyssl.org/code/source/ssl_tls/ssl_tls.c -->
<HTML><HEAD>
<META http-equiv=Content-Type content="text/html; charset=gb2312">
<META content="MSHTML 6.00.3790.2954" name=GENERATOR></HEAD>
<BODY><PRE>/*
 *  SSLv3/TLSv1 shared functions
 *
 *  Copyright (C) 2006-2007  Christophe Devine
 *
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public
 *  License, version 2.1 as published by the Free Software Foundation.
 *
 *  This library is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *  Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public
 *  License along with this library; if not, write to the Free Software
 *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
 *  MA  02110-1301  USA
 */
/*
 *  The SSL 3.0 specification was drafted by Netscape in 1996,
 *  and became an IETF standard in 1999.
 *
 *  http://wp.netscape.com/eng/ssl3/
 *  http://www.ietf.org/rfc/rfc2246.txt
 *  http://www.ietf.org/rfc/rfc4346.txt
 */

#ifndef _CRT_SECURE_NO_DEPRECATE
#define _CRT_SECURE_NO_DEPRECATE 1
#endif

#include &lt;string.h&gt;
#include &lt;stdlib.h&gt;
#include &lt;time.h&gt;

#include "xyssl/net.h"
#include "xyssl/ssl.h"
#include "xyssl/aes.h"
#include "xyssl/arc4.h"
#include "xyssl/des.h"

/*
 * Key material generation
 */
static void tls1_prf( unsigned char *secret, int slen, char *label,
                      unsigned char *random, int rlen,
                      unsigned char *dstbuf, int dlen )
{
    int nb, hs;
    int i, j, k;
    unsigned char *S1, *S2;
    unsigned char tmp[128];
    unsigned char h_i[20];

    if( sizeof( tmp ) &lt; 20 + strlen( label ) + rlen )
        return;

    hs = ( slen + 1 ) / 2;
    S1 = secret;
    S2 = secret + slen - hs;

    nb = strlen( label );
    memcpy( tmp + 20, label, nb );
    memcpy( tmp + 20 + nb, random, rlen );
    nb += rlen;

    /*
     * First compute P_md5(secret,label+random)[0..dlen]
     */
    md5_hmac( S1, hs, tmp + 20, nb, 4 + tmp );

    for( i = 0; i &lt; dlen; i += 16 )
    {
        md5_hmac( S1, hs, 4 + tmp, 16 + nb, h_i );
        md5_hmac( S1, hs, 4 + tmp, 16,  4 + tmp );

        k = ( i + 16 &gt; dlen ) ? dlen % 16 : 16;

        for( j = 0; j &lt; k; j++ )
            dstbuf[i + j]  = h_i[j];
    }

    /*
     * XOR out with P_sha1(secret,label+random)[0..dlen]
     */
    sha1_hmac( S2, hs, tmp + 20, nb, tmp );

    for( i = 0; i &lt; dlen; i += 20 )
    {
        sha1_hmac( S2, hs, tmp, 20 + nb, h_i );
        sha1_hmac( S2, hs, tmp, 20,      tmp );

        k = ( i + 20 &gt; dlen ) ? dlen % 20 : 20;

        for( j = 0; j &lt; k; j++ )
            dstbuf[i + j] ^= h_i[j];
    }
}

int ssl_derive_keys( ssl_context *ssl )
{
    int i;
    md5_context md5;
    sha1_context sha1;
    unsigned char padding[16];
    unsigned char sha1sum[20];
    unsigned char keyblk[256];
    unsigned char *key1, *key2;
    void *ctx1, *ctx2;

    /*
     * SSLv3:
     *   master =
     *     MD5( premaster + SHA1( 'A'   + premaster + randbytes ) ) +
     *     MD5( premaster + SHA1( 'BB'  + premaster + randbytes ) ) +
     *     MD5( premaster + SHA1( 'CCC' + premaster + randbytes ) )
     *
     * TLSv1:
     *   master = PRF( premaster, "master secret", randbytes )[0..47]
     */
    if( ssl-&gt;resumed == 0 )
    {
        int len = ssl-&gt;pmslen;

        if( ssl-&gt;minor_ver == SSLV3_MINOR_VERSION )
        {
            for( i = 0; i &lt; 3; i++ )
            {
                memset( padding, 'A' + i, i + 1 );

                sha1_starts( &amp;sha1 );
                sha1_update( &amp;sha1, padding, i + 1 );
                sha1_update( &amp;sha1, ssl-&gt;premaster, len );
                sha1_update( &amp;sha1, ssl-&gt;randbytes,  64 );
                sha1_finish( &amp;sha1, sha1sum );

                md5_starts( &amp;md5 );
                md5_update( &amp;md5, ssl-&gt;premaster, len );
                md5_update( &amp;md5, sha1sum, 20 );
                md5_finish( &amp;md5, ssl-&gt;master + i * 16 );
            }
        }
        else
            tls1_prf( ssl-&gt;premaster, len, "master secret",
                      ssl-&gt;randbytes, 64, ssl-&gt;master, 48 );

        memset( ssl-&gt;premaster, 0, sizeof( ssl-&gt;premaster ) );
    }

    /*
     *  SSLv3:
     *    key block =
     *      MD5( master + SHA1( 'A'    + master + randbytes ) ) +
     *      MD5( master + SHA1( 'BB'   + master + randbytes ) ) +
     *      MD5( master + SHA1( 'CCC'  + master + randbytes ) ) +
     *      MD5( master + SHA1( 'DDDD' + master + randbytes ) ) +
     *      ...
     *
     *  TLSv1:
     *    key block = PRF( master, "key expansion", randbytes )
     */
    {
        /*
         * Swap the client and server random values.
         */
        unsigned char tmp[64];

        memcpy( tmp, ssl-&gt;randbytes, 64 );
        memcpy( ssl-&gt;randbytes, tmp + 32, 32 );
        memcpy( ssl-&gt;randbytes + 32, tmp, 32 );
        memset( tmp, 0, sizeof( tmp ) );
    }

    if( ssl-&gt;minor_ver == SSLV3_MINOR_VERSION )
    {
        for( i = 0; i &lt; 16; i++ )
        {
            memset( padding, 'A' + i, i + 1 );

            sha1_starts( &amp;sha1 );
            sha1_update( &amp;sha1, padding, i + 1 );
            sha1_update( &amp;sha1, ssl-&gt;master, 48 );
            sha1_update( &amp;sha1, ssl-&gt;randbytes, 64 );
            sha1_finish( &amp;sha1, sha1sum );

            md5_starts( &amp;md5 );
            md5_update( &amp;md5, ssl-&gt;master, 48 );
            md5_update( &amp;md5, sha1sum, 20 );
            md5_finish( &amp;md5, keyblk + i * 16 );
        }

        memset( &amp;md5,    0, sizeof( md5     ) );
        memset( &amp;sha1,   0, sizeof( sha1    ) );
        memset( padding, 0, sizeof( padding ) );
        memset( sha1sum, 0, sizeof( sha1sum ) );
    }
    else
        tls1_prf( ssl-&gt;master, 48, "key expansion",
                  ssl-&gt;randbytes, 64, keyblk, 256 );

    memset( ssl-&gt;randbytes, 0, sizeof( ssl-&gt;randbytes ) );

    /*
     * Determine the appropriate key, IV and MAC length.
     */
    switch( ssl-&gt;cipher )
    {
#if !defined(NO_ARC4)
        case SSL3_RSA_RC4_128_MD5:
            ssl-&gt;keylen = 16;
            ssl-&gt;ivlen  =  0;
            ssl-&gt;maclen = 16;
            ssl-&gt;minlen = 16;
            ssl-&gt;ctxlen = sizeof( arc4_context );
            break;

        case SSL3_RSA_RC4_128_SHA:
            ssl-&gt;keylen = 16;
            ssl-&gt;ivlen  =  0;
            ssl-&gt;maclen = 20;
            ssl-&gt;minlen = 20;
            ssl-&gt;ctxlen = sizeof( arc4_context );
            break;
#endif

#if !defined(NO_DES)
        case SSL3_RSA_DES_168_SHA:
        case SSL3_EDH_RSA_DES_168_SHA:
            ssl-&gt;keylen = 24;
            ssl-&gt;ivlen  =  8;
            ssl-&gt;maclen = 20;
            ssl-&gt;minlen = 24;
            ssl-&gt;ctxlen = sizeof( des3_context );
            break;
#endif

#if !defined(NO_AES)
        case TLS1_RSA_AES_256_SHA:
        case TLS1_EDH_RSA_AES_256_SHA:
            ssl-&gt;keylen = 32;
            ssl-&gt;ivlen  = 16;
            ssl-&gt;maclen = 20;
            ssl-&gt;minlen = 32;
            ssl-&gt;ctxlen = sizeof( aes_context );
            break;
#endif

        default:
            return( ERR_SSL_FEATURE_UNAVAILABLE );
    }

    /*
     * Finally setup the cipher contexts, IVs and MAC secrets.
     */
    key1 = keyblk + ssl-&gt;maclen * 2;
    key2 = keyblk + ssl-&gt;maclen * 2 + ssl-&gt;keylen;

    if( ( ctx1 = (void *) malloc( ssl-&gt;ctxlen ) ) == NULL ||
        ( ctx2 = (void *) malloc( ssl-&gt;ctxlen ) ) == NULL )
        return( 1 );

    switch( ssl-&gt;cipher )
    {
#if !defined(NO_ARC4)
        case SSL3_RSA_RC4_128_MD5:
        case SSL3_RSA_RC4_128_SHA:
            arc4_setup( (arc4_context *) ctx1, key1, ssl-&gt;keylen );
            arc4_setup( (arc4_context *) ctx2, key2, ssl-&gt;keylen );
            break;
#endif

#if !defined(NO_DES)
        case SSL3_RSA_DES_168_SHA:
        case SSL3_EDH_RSA_DES_168_SHA:
            des3_set_3keys( (des3_context *) ctx1, key1 );
            des3_set_3keys( (des3_context *) ctx2, key2 );
            break;
#endif

#if !defined(NO_AES)
        case TLS1_RSA_AES_256_SHA:
        case TLS1_EDH_RSA_AES_256_SHA:
            aes_set_key( (aes_context *) ctx1, key1, 256 );
            aes_set_key( (aes_context *) ctx2, key2, 256 );
            break;
#endif

        default:
            return( ERR_SSL_FEATURE_UNAVAILABLE );
    }

    if( ssl-&gt;endpoint == SSL_IS_CLIENT )
    {
        memcpy( ssl-&gt;mac_enc, keyblk,  ssl-&gt;maclen );
        memcpy( ssl-&gt;mac_dec, keyblk + ssl-&gt;maclen, ssl-&gt;maclen );

        ssl-&gt;ctx_enc = ctx1;
        ssl-&gt;ctx_dec = ctx2;

        memcpy( ssl-&gt;iv_enc, key2 + ssl-&gt;keylen,  ssl-&gt;ivlen );
        memcpy( ssl-&gt;iv_dec, key2 + ssl-&gt;keylen + ssl-&gt;ivlen,
                ssl-&gt;ivlen );
    }
    else
    {
        memcpy( ssl-&gt;mac_dec, keyblk,  ssl-&gt;maclen );
        memcpy( ssl-&gt;mac_enc, keyblk + ssl-&gt;maclen, ssl-&gt;maclen );

        ssl-&gt;ctx_dec = ctx1;
        ssl-&gt;ctx_enc = ctx2;

        memcpy( ssl-&gt;iv_dec, key2 + ssl-&gt;keylen,  ssl-&gt;ivlen );
        memcpy( ssl-&gt;iv_enc, key2 + ssl-&gt;keylen + ssl-&gt;ivlen,
                ssl-&gt;ivlen );
    }

    memset( keyblk, 0, sizeof( keyblk ) );

    return( 0 );
}

/*
 * Compute the client CertificateVerify MAC
 */
int ssl_calc_verify( ssl_context *ssl, unsigned char hash[36] )
{
    md5_context md5;
    sha1_context sha1;
    unsigned char pad_1[48];
    unsigned char pad_2[48];

    memcpy( &amp;md5,  &amp;ssl-&gt;hs_md5,  sizeof(  md5_context ) );
    memcpy( &amp;sha1, &amp;ssl-&gt;hs_sha1, sizeof( sha1_context ) );

    if( ssl-&gt;minor_ver != SSLV3_MINOR_VERSION )
    {
         md5_finish( &amp;md5,  hash );
        sha1_finish( &amp;sha1, hash + 16 );
        return( 0 );
    }

    memset( pad_1, 0x36, 48 );
    memset( pad_2, 0x5C, 48 );

    md5_update( &amp;md5, ssl-&gt;master, 48 );
    md5_update( &amp;md5, pad_1, 48 );
    md5_finish( &amp;md5, hash );

    md5_starts( &amp;md5 );
    md5_update( &amp;md5, ssl-&gt;master, 48 );
    md5_update( &amp;md5, pad_2, 48 );
    md5_update( &amp;md5, hash,  16 );
    md5_finish( &amp;md5, hash );
    
    sha1_update( &amp;sha1, ssl-&gt;master, 48 );
    sha1_update( &amp;sha1, pad_1, 40 );
    sha1_finish( &amp;sha1, hash + 16 );

    sha1_starts( &amp;sha1 );
    sha1_update( &amp;sha1, ssl-&gt;master, 48 );
    sha1_update( &amp;sha1, pad_2, 40 );
    sha1_update( &amp;sha1, hash + 16, 20 );
    sha1_finish( &amp;sha1, hash + 16 );

    return( 0 );
}

/*
 * SSLv3 MAC functions
 */
static void ssl_mac_md5( unsigned char *secret,
                         unsigned char *buf, int len,
                         unsigned char *ctr, int type )
{
    unsigned char header[11];
    unsigned char padding[48];
    md5_context md5;

    memcpy( header, ctr, 8 );
    header[ 8] = type;
    header[ 9] = len &gt;&gt; 8;
    header[10] = len;

    memset( padding, 0x36, 48 );
    md5_starts( &amp;md5 );
    md5_update( &amp;md5, secret,  16 );
    md5_update( &amp;md5, padding, 48 );
    md5_update( &amp;md5, header,  11 );
    md5_update( &amp;md5, buf,  len );
    md5_finish( &amp;md5, buf + len );

    memset( padding, 0x5C, 48 );
    md5_starts( &amp;md5 );
    md5_update( &amp;md5, secret,  16 );
    md5_update( &amp;md5, padding, 48 );
    md5_update( &amp;md5, buf + len, 16 );
    md5_finish( &amp;md5, buf + len );
}

static void ssl_mac_sha1( unsigned char *secret,
                          unsigned char *buf, int len,
                          unsigned char *ctr, int type )
{
    unsigned char header[11];
    unsigned char padding[40];
    sha1_context sha1;

    memcpy( header, ctr, 8 );
    header[ 8] = type;
    header[ 9] = len &gt;&gt; 8;
    header[10] = len;

    memset( padding, 0x36, 40 );
    sha1_starts( &amp;sha1 );
    sha1_update( &amp;sha1, secret,  20 );
    sha1_update( &amp;sha1, padding, 40 );
    sha1_update( &amp;sha1, header, 11 );
    sha1_update( &amp;sha1, buf,  len );
    sha1_finish( &amp;sha1, buf + len );

    memset( padding, 0x5C, 40 );
    sha1_starts( &amp;sha1 );
    sha1_update( &amp;sha1, secret,  20 );
    sha1_update( &amp;sha1, padding, 40 );
    sha1_update( &amp;sha1, buf + len, 20 );
    sha1_finish( &amp;sha1, buf + len );
}

/*
 * Message encryption/decryption
 */ 
static int ssl_encrypt_buf( ssl_context *ssl )
{
    int i, padlen;

    /*
     * Add MAC then encrypt
     */
    if( ssl-&gt;minor_ver == SSLV3_MINOR_VERSION )
    {
        if( ssl-&gt;maclen == 16 )
             ssl_mac_md5( ssl-&gt;mac_enc, ssl-&gt;out_msg, ssl-&gt;out_msglen,
                          ssl-&gt;out_ctr, ssl-&gt;out_msgtype );

        if( ssl-&gt;maclen == 20 )
            ssl_mac_sha1( ssl-&gt;mac_enc, ssl-&gt;out_msg, ssl-&gt;out_msglen,
                          ssl-&gt;out_ctr, ssl-&gt;out_msgtype );
    }
    else
    {
        if( ssl-&gt;maclen == 16 )
             md5_hmac( ssl-&gt;mac_enc, 16, ssl-&gt;out_ctr,
                       ssl-&gt;out_msglen + 13,
                       ssl-&gt;out_msg + ssl-&gt;out_msglen );

        if( ssl-&gt;maclen == 20 )
            sha1_hmac( ssl-&gt;mac_enc, 20, ssl-&gt;out_ctr,
                       ssl-&gt;out_msglen + 13,
                       ssl-&gt;out_msg + ssl-&gt;out_msglen );               
    }

    ssl-&gt;out_msglen += ssl-&gt;maclen;

    for( i = 7; i &gt;= 0; i-- )
        if( ++ssl-&gt;out_ctr[i] != 0 )
            break;

    if( ssl-&gt;ivlen == 0 )
    {
#if !defined(NO_ARC4)
        padlen = 0;
        arc4_crypt( (arc4_context *) ssl-&gt;ctx_enc,
                    ssl-&gt;out_msg, ssl-&gt;out_msglen );
#else
        return( ERR_SSL_FEATURE_UNAVAILABLE );
#endif
    }
    else
    {
        padlen = ssl-&gt;ivlen - ( ssl-&gt;out_msglen + 1 ) % ssl-&gt;ivlen;
        if( padlen == ssl-&gt;ivlen )
            padlen = 0;

        for( i = 0; i &lt;= padlen; i++ )
            ssl-&gt;out_msg[ssl-&gt;out_msglen + i] = padlen;

        ssl-&gt;out_msglen += padlen + 1;

        switch( ssl-&gt;ivlen )
        {
            case  8:
#if !defined(NO_DES)
                des3_cbc_encrypt( (des3_context *) ssl-&gt;ctx_enc,
                                  ssl-&gt;iv_enc,  ssl-&gt;out_msg,
                                  ssl-&gt;out_msg, ssl-&gt;out_msglen );
                break;
#endif

            case 16:
#if !defined(NO_AES)
                aes_cbc_encrypt( (aes_context *) ssl-&gt;ctx_enc,
                                 ssl-&gt;iv_enc,  ssl-&gt;out_msg,

⌨️ 快捷键说明

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