/home/dko/projects/mobilec/trunk/src/security/xyssl-0.7/library/ssl_tls.c

Go to the documentation of this file.
00001 /*
00002  *  SSLv3/TLSv1 shared functions
00003  *
00004  *  Copyright (C) 2006-2007  Christophe Devine
00005  *
00006  *  This library is free software; you can redistribute it and/or
00007  *  modify it under the terms of the GNU Lesser General Public
00008  *  License, version 2.1 as published by the Free Software Foundation.
00009  *
00010  *  This library is distributed in the hope that it will be useful,
00011  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
00012  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00013  *  Lesser General Public License for more details.
00014  *
00015  *  You should have received a copy of the GNU Lesser General Public
00016  *  License along with this library; if not, write to the Free Software
00017  *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
00018  *  MA  02110-1301  USA
00019  */
00020 /*
00021  *  The SSL 3.0 specification was drafted by Netscape in 1996,
00022  *  and became an IETF standard in 1999.
00023  *
00024  *  http://wp.netscape.com/eng/ssl3/
00025  *  http://www.ietf.org/rfc/rfc2246.txt
00026  *  http://www.ietf.org/rfc/rfc4346.txt
00027  */
00028 
00029 #ifndef _CRT_SECURE_NO_DEPRECATE
00030 #define _CRT_SECURE_NO_DEPRECATE 1
00031 #endif
00032 
00033 #include <string.h>
00034 #include <stdlib.h>
00035 #include <time.h>
00036 
00037 #include "xyssl/net.h"
00038 #include "xyssl/ssl.h"
00039 #include "xyssl/aes.h"
00040 #include "xyssl/arc4.h"
00041 #include "xyssl/des.h"
00042 
00043 /*
00044  * Key material generation
00045  */
00046 static void tls1_prf( unsigned char *secret, int slen, char *label,
00047                       unsigned char *random, int rlen,
00048                       unsigned char *dstbuf, int dlen )
00049 {
00050     int nb, hs;
00051     int i, j, k;
00052     unsigned char *S1, *S2;
00053     unsigned char tmp[128];
00054     unsigned char h_i[20];
00055 
00056     if( sizeof( tmp ) < 20 + strlen( label ) + rlen )
00057         return;
00058 
00059     hs = ( slen + 1 ) / 2;
00060     S1 = secret;
00061     S2 = secret + slen - hs;
00062 
00063     nb = strlen( label );
00064     memcpy( tmp + 20, label, nb );
00065     memcpy( tmp + 20 + nb, random, rlen );
00066     nb += rlen;
00067 
00068     /*
00069      * First compute P_md5(secret,label+random)[0..dlen]
00070      */
00071     md5_hmac( S1, hs, tmp + 20, nb, 4 + tmp );
00072 
00073     for( i = 0; i < dlen; i += 16 )
00074     {
00075         md5_hmac( S1, hs, 4 + tmp, 16 + nb, h_i );
00076         md5_hmac( S1, hs, 4 + tmp, 16,  4 + tmp );
00077 
00078         k = ( i + 16 > dlen ) ? dlen % 16 : 16;
00079 
00080         for( j = 0; j < k; j++ )
00081             dstbuf[i + j]  = h_i[j];
00082     }
00083 
00084     /*
00085      * XOR out with P_sha1(secret,label+random)[0..dlen]
00086      */
00087     sha1_hmac( S2, hs, tmp + 20, nb, tmp );
00088 
00089     for( i = 0; i < dlen; i += 20 )
00090     {
00091         sha1_hmac( S2, hs, tmp, 20 + nb, h_i );
00092         sha1_hmac( S2, hs, tmp, 20,      tmp );
00093 
00094         k = ( i + 20 > dlen ) ? dlen % 20 : 20;
00095 
00096         for( j = 0; j < k; j++ )
00097             dstbuf[i + j] ^= h_i[j];
00098     }
00099 }
00100 
00101 int ssl_derive_keys( ssl_context *ssl )
00102 {
00103     int i;
00104     md5_context md5;
00105     sha1_context sha1;
00106     unsigned char padding[16];
00107     unsigned char sha1sum[20];
00108     unsigned char keyblk[256];
00109     unsigned char *key1, *key2;
00110     void *ctx1, *ctx2;
00111 
00112     /*
00113      * SSLv3:
00114      *   master =
00115      *     MD5( premaster + SHA1( 'A'   + premaster + randbytes ) ) +
00116      *     MD5( premaster + SHA1( 'BB'  + premaster + randbytes ) ) +
00117      *     MD5( premaster + SHA1( 'CCC' + premaster + randbytes ) )
00118      *
00119      * TLSv1:
00120      *   master = PRF( premaster, "master secret", randbytes )[0..47]
00121      */
00122     if( ssl->resumed == 0 )
00123     {
00124         int len = ssl->pmslen;
00125 
00126         if( ssl->minor_ver == SSLV3_MINOR_VERSION )
00127         {
00128             for( i = 0; i < 3; i++ )
00129             {
00130                 memset( padding, 'A' + i, i + 1 );
00131 
00132                 sha1_starts( &sha1 );
00133                 sha1_update( &sha1, padding, i + 1 );
00134                 sha1_update( &sha1, ssl->premaster, len );
00135                 sha1_update( &sha1, ssl->randbytes,  64 );
00136                 sha1_finish( &sha1, sha1sum );
00137 
00138                 md5_starts( &md5 );
00139                 md5_update( &md5, ssl->premaster, len );
00140                 md5_update( &md5, sha1sum, 20 );
00141                 md5_finish( &md5, ssl->master + i * 16 );
00142             }
00143         }
00144         else
00145             tls1_prf( ssl->premaster, len, "master secret",
00146                       ssl->randbytes, 64, ssl->master, 48 );
00147 
00148         memset( ssl->premaster, 0, sizeof( ssl->premaster ) );
00149     }
00150 
00151     /*
00152      *  SSLv3:
00153      *    key block =
00154      *      MD5( master + SHA1( 'A'    + master + randbytes ) ) +
00155      *      MD5( master + SHA1( 'BB'   + master + randbytes ) ) +
00156      *      MD5( master + SHA1( 'CCC'  + master + randbytes ) ) +
00157      *      MD5( master + SHA1( 'DDDD' + master + randbytes ) ) +
00158      *      ...
00159      *
00160      *  TLSv1:
00161      *    key block = PRF( master, "key expansion", randbytes )
00162      */
00163     {
00164         /*
00165          * Swap the client and server random values.
00166          */
00167         unsigned char tmp[64];
00168 
00169         memcpy( tmp, ssl->randbytes, 64 );
00170         memcpy( ssl->randbytes, tmp + 32, 32 );
00171         memcpy( ssl->randbytes + 32, tmp, 32 );
00172         memset( tmp, 0, sizeof( tmp ) );
00173     }
00174 
00175     if( ssl->minor_ver == SSLV3_MINOR_VERSION )
00176     {
00177         for( i = 0; i < 16; i++ )
00178         {
00179             memset( padding, 'A' + i, i + 1 );
00180 
00181             sha1_starts( &sha1 );
00182             sha1_update( &sha1, padding, i + 1 );
00183             sha1_update( &sha1, ssl->master, 48 );
00184             sha1_update( &sha1, ssl->randbytes, 64 );
00185             sha1_finish( &sha1, sha1sum );
00186 
00187             md5_starts( &md5 );
00188             md5_update( &md5, ssl->master, 48 );
00189             md5_update( &md5, sha1sum, 20 );
00190             md5_finish( &md5, keyblk + i * 16 );
00191         }
00192 
00193         memset( &md5,    0, sizeof( md5     ) );
00194         memset( &sha1,   0, sizeof( sha1    ) );
00195         memset( padding, 0, sizeof( padding ) );
00196         memset( sha1sum, 0, sizeof( sha1sum ) );
00197     }
00198     else
00199         tls1_prf( ssl->master, 48, "key expansion",
00200                   ssl->randbytes, 64, keyblk, 256 );
00201 
00202     memset( ssl->randbytes, 0, sizeof( ssl->randbytes ) );
00203 
00204     /*
00205      * Determine the appropriate key, IV and MAC length.
00206      */
00207     switch( ssl->cipher )
00208     {
00209 #if !defined(NO_ARC4)
00210         case SSL3_RSA_RC4_128_MD5:
00211             ssl->keylen = 16;
00212             ssl->ivlen  =  0;
00213             ssl->maclen = 16;
00214             ssl->minlen = 16;
00215             ssl->ctxlen = sizeof( arc4_context );
00216             break;
00217 
00218         case SSL3_RSA_RC4_128_SHA:
00219             ssl->keylen = 16;
00220             ssl->ivlen  =  0;
00221             ssl->maclen = 20;
00222             ssl->minlen = 20;
00223             ssl->ctxlen = sizeof( arc4_context );
00224             break;
00225 #endif
00226 
00227 #if !defined(NO_DES)
00228         case SSL3_RSA_DES_168_SHA:
00229         case SSL3_EDH_RSA_DES_168_SHA:
00230             ssl->keylen = 24;
00231             ssl->ivlen  =  8;
00232             ssl->maclen = 20;
00233             ssl->minlen = 24;
00234             ssl->ctxlen = sizeof( des3_context );
00235             break;
00236 #endif
00237 
00238 #if !defined(NO_AES)
00239         case TLS1_RSA_AES_256_SHA:
00240         case TLS1_EDH_RSA_AES_256_SHA:
00241             ssl->keylen = 32;
00242             ssl->ivlen  = 16;
00243             ssl->maclen = 20;
00244             ssl->minlen = 32;
00245             ssl->ctxlen = sizeof( aes_context );
00246             break;
00247 #endif
00248 
00249         default:
00250             return( ERR_SSL_FEATURE_UNAVAILABLE );
00251     }
00252 
00253     /*
00254      * Finally setup the cipher contexts, IVs and MAC secrets.
00255      */
00256     key1 = keyblk + ssl->maclen * 2;
00257     key2 = keyblk + ssl->maclen * 2 + ssl->keylen;
00258 
00259     if( ( ctx1 = (void *) malloc( ssl->ctxlen ) ) == NULL ||
00260         ( ctx2 = (void *) malloc( ssl->ctxlen ) ) == NULL )
00261         return( 1 );
00262 
00263     switch( ssl->cipher )
00264     {
00265 #if !defined(NO_ARC4)
00266         case SSL3_RSA_RC4_128_MD5:
00267         case SSL3_RSA_RC4_128_SHA:
00268             arc4_setup( (arc4_context *) ctx1, key1, ssl->keylen );
00269             arc4_setup( (arc4_context *) ctx2, key2, ssl->keylen );
00270             break;
00271 #endif
00272 
00273 #if !defined(NO_DES)
00274         case SSL3_RSA_DES_168_SHA:
00275         case SSL3_EDH_RSA_DES_168_SHA:
00276             des3_set_3keys( (des3_context *) ctx1, key1 );
00277             des3_set_3keys( (des3_context *) ctx2, key2 );
00278             break;
00279 #endif
00280 
00281 #if !defined(NO_AES)
00282         case TLS1_RSA_AES_256_SHA:
00283         case TLS1_EDH_RSA_AES_256_SHA:
00284             aes_set_key( (aes_context *) ctx1, key1, 256 );
00285             aes_set_key( (aes_context *) ctx2, key2, 256 );
00286             break;
00287 #endif
00288 
00289         default:
00290             return( ERR_SSL_FEATURE_UNAVAILABLE );
00291     }
00292 
00293     if( ssl->endpoint == SSL_IS_CLIENT )
00294     {
00295         memcpy( ssl->mac_enc, keyblk,  ssl->maclen );
00296         memcpy( ssl->mac_dec, keyblk + ssl->maclen, ssl->maclen );
00297 
00298         ssl->ctx_enc = ctx1;
00299         ssl->ctx_dec = ctx2;
00300 
00301         memcpy( ssl->iv_enc, key2 + ssl->keylen,  ssl->ivlen );
00302         memcpy( ssl->iv_dec, key2 + ssl->keylen + ssl->ivlen,
00303                 ssl->ivlen );
00304     }
00305     else
00306     {
00307         memcpy( ssl->mac_dec, keyblk,  ssl->maclen );
00308         memcpy( ssl->mac_enc, keyblk + ssl->maclen, ssl->maclen );
00309 
00310         ssl->ctx_dec = ctx1;
00311         ssl->ctx_enc = ctx2;
00312 
00313         memcpy( ssl->iv_dec, key2 + ssl->keylen,  ssl->ivlen );
00314         memcpy( ssl->iv_enc, key2 + ssl->keylen + ssl->ivlen,
00315                 ssl->ivlen );
00316     }
00317 
00318     memset( keyblk, 0, sizeof( keyblk ) );
00319 
00320     return( 0 );
00321 }
00322 
00323 /*
00324  * Compute the client CertificateVerify MAC
00325  */
00326 int ssl_calc_verify( ssl_context *ssl, unsigned char hash[36] )
00327 {
00328     md5_context md5;
00329     sha1_context sha1;
00330     unsigned char pad_1[48];
00331     unsigned char pad_2[48];
00332 
00333     memcpy( &md5,  &ssl->hs_md5,  sizeof(  md5_context ) );
00334     memcpy( &sha1, &ssl->hs_sha1, sizeof( sha1_context ) );
00335 
00336     if( ssl->minor_ver != SSLV3_MINOR_VERSION )
00337     {
00338          md5_finish( &md5,  hash );
00339         sha1_finish( &sha1, hash + 16 );
00340         return( 0 );
00341     }
00342 
00343     memset( pad_1, 0x36, 48 );
00344     memset( pad_2, 0x5C, 48 );
00345 
00346     md5_update( &md5, ssl->master, 48 );
00347     md5_update( &md5, pad_1, 48 );
00348     md5_finish( &md5, hash );
00349 
00350     md5_starts( &md5 );
00351     md5_update( &md5, ssl->master, 48 );
00352     md5_update( &md5, pad_2, 48 );
00353     md5_update( &md5, hash,  16 );
00354     md5_finish( &md5, hash );
00355     
00356     sha1_update( &sha1, ssl->master, 48 );
00357     sha1_update( &sha1, pad_1, 40 );
00358     sha1_finish( &sha1, hash + 16 );
00359 
00360     sha1_starts( &sha1 );
00361     sha1_update( &sha1, ssl->master, 48 );
00362     sha1_update( &sha1, pad_2, 40 );
00363     sha1_update( &sha1, hash + 16, 20 );
00364     sha1_finish( &sha1, hash + 16 );
00365 
00366     return( 0 );
00367 }
00368 
00369 /*
00370  * SSLv3 MAC functions
00371  */
00372 static void ssl_mac_md5( unsigned char *secret,
00373                          unsigned char *buf, int len,
00374                          unsigned char *ctr, int type )
00375 {
00376     unsigned char header[11];
00377     unsigned char padding[48];
00378     md5_context md5;
00379 
00380     memcpy( header, ctr, 8 );
00381     header[ 8] = type;
00382     header[ 9] = len >> 8;
00383     header[10] = len;
00384 
00385     memset( padding, 0x36, 48 );
00386     md5_starts( &md5 );
00387     md5_update( &md5, secret,  16 );
00388     md5_update( &md5, padding, 48 );
00389     md5_update( &md5, header,  11 );
00390     md5_update( &md5, buf,  len );
00391     md5_finish( &md5, buf + len );
00392 
00393     memset( padding, 0x5C, 48 );
00394     md5_starts( &md5 );
00395     md5_update( &md5, secret,  16 );
00396     md5_update( &md5, padding, 48 );
00397     md5_update( &md5, buf + len, 16 );
00398     md5_finish( &md5, buf + len );
00399 }
00400 
00401 static void ssl_mac_sha1( unsigned char *secret,
00402                           unsigned char *buf, int len,
00403                           unsigned char *ctr, int type )
00404 {
00405     unsigned char header[11];
00406     unsigned char padding[40];
00407     sha1_context sha1;
00408 
00409     memcpy( header, ctr, 8 );
00410     header[ 8] = type;
00411     header[ 9] = len >> 8;
00412     header[10] = len;
00413 
00414     memset( padding, 0x36, 40 );
00415     sha1_starts( &sha1 );
00416     sha1_update( &sha1, secret,  20 );
00417     sha1_update( &sha1, padding, 40 );
00418     sha1_update( &sha1, header, 11 );
00419     sha1_update( &sha1, buf,  len );
00420     sha1_finish( &sha1, buf + len );
00421 
00422     memset( padding, 0x5C, 40 );
00423     sha1_starts( &sha1 );
00424     sha1_update( &sha1, secret,  20 );
00425     sha1_update( &sha1, padding, 40 );
00426     sha1_update( &sha1, buf + len, 20 );
00427     sha1_finish( &sha1, buf + len );
00428 }
00429 
00430 /*
00431  * Message encryption/decryption
00432  */ 
00433 static int ssl_encrypt_buf( ssl_context *ssl )
00434 {
00435     int i, padlen;
00436 
00437     /*
00438      * Add MAC then encrypt
00439      */
00440     if( ssl->minor_ver == SSLV3_MINOR_VERSION )
00441     {
00442         if( ssl->maclen == 16 )
00443              ssl_mac_md5( ssl->mac_enc, ssl->out_msg, ssl->out_msglen,
00444                           ssl->out_ctr, ssl->out_msgtype );
00445 
00446         if( ssl->maclen == 20 )
00447             ssl_mac_sha1( ssl->mac_enc, ssl->out_msg, ssl->out_msglen,
00448                           ssl->out_ctr, ssl->out_msgtype );
00449     }
00450     else
00451     {
00452         if( ssl->maclen == 16 )
00453              md5_hmac( ssl->mac_enc, 16, ssl->out_ctr,
00454                        ssl->out_msglen + 13,
00455                        ssl->out_msg + ssl->out_msglen );
00456 
00457         if( ssl->maclen == 20 )
00458             sha1_hmac( ssl->mac_enc, 20, ssl->out_ctr,
00459                        ssl->out_msglen + 13,
00460                        ssl->out_msg + ssl->out_msglen );               
00461     }
00462 
00463     ssl->out_msglen += ssl->maclen;
00464 
00465     for( i = 7; i >= 0; i-- )
00466         if( ++ssl->out_ctr[i] != 0 )
00467             break;
00468 
00469     if( ssl->ivlen == 0 )
00470     {
00471 #if !defined(NO_ARC4)
00472         padlen = 0;
00473         arc4_crypt( (arc4_context *) ssl->ctx_enc,
00474                     ssl->out_msg, ssl->out_msglen );
00475 #else
00476         return( ERR_SSL_FEATURE_UNAVAILABLE );
00477 #endif
00478     }
00479     else
00480     {
00481         padlen = ssl->ivlen - ( ssl->out_msglen + 1 ) % ssl->ivlen;
00482         if( padlen == ssl->ivlen )
00483             padlen = 0;
00484 
00485         for( i = 0; i <= padlen; i++ )
00486             ssl->out_msg[ssl->out_msglen + i] = padlen;
00487 
00488         ssl->out_msglen += padlen + 1;
00489 
00490         switch( ssl->ivlen )
00491         {
00492             case  8:
00493 #if !defined(NO_DES)
00494                 des3_cbc_encrypt( (des3_context *) ssl->ctx_enc,
00495                                   ssl->iv_enc,  ssl->out_msg,
00496                                   ssl->out_msg, ssl->out_msglen );
00497                 break;
00498 #endif
00499 
00500             case 16:
00501 #if !defined(NO_AES)
00502                 aes_cbc_encrypt( (aes_context *) ssl->ctx_enc,
00503                                  ssl->iv_enc,  ssl->out_msg,
00504                                  ssl->out_msg, ssl->out_msglen );
00505                 break;
00506 #endif
00507 
00508             default:
00509                 return( ERR_SSL_FEATURE_UNAVAILABLE );
00510         }
00511 
00512     }
00513 
00514     return( 0 );
00515 }
00516 
00517 static int ssl_decrypt_buf( ssl_context *ssl )
00518 {
00519     int i, padlen;
00520     unsigned char tmp[20];
00521 
00522     if( ssl->in_msglen < ssl->minlen )
00523         return( ERR_SSL_INVALID_MAC );
00524 
00525     if( ssl->ivlen == 0 )
00526     {
00527 #if !defined(NO_ARC4)
00528         padlen = 0;
00529         arc4_crypt( (arc4_context *) ssl->ctx_dec,
00530                     ssl->in_msg, ssl->in_msglen );
00531 #else
00532         return( ERR_SSL_FEATURE_UNAVAILABLE );
00533 #endif
00534     }
00535     else
00536     {
00537         /*
00538          * Decrypt and check the padding
00539          */
00540         if( ssl->in_msglen % ssl->ivlen != 0 )
00541             return( ERR_SSL_INVALID_MAC );
00542 
00543         switch( ssl->ivlen )
00544         {
00545 #if !defined(NO_DES)
00546             case  8:
00547                 des3_cbc_decrypt( (des3_context *) ssl->ctx_dec,
00548                                   ssl->iv_dec, ssl->in_msg,
00549                                   ssl->in_msg, ssl->in_msglen );
00550                 break;
00551 #endif
00552 
00553 #if !defined(NO_AES)
00554             case 16:
00555                  aes_cbc_decrypt( (aes_context *) ssl->ctx_dec,
00556                                   ssl->iv_dec, ssl->in_msg,
00557                                   ssl->in_msg, ssl->in_msglen );
00558                  break;
00559 #endif
00560 
00561             default:
00562                 return( ERR_SSL_FEATURE_UNAVAILABLE );
00563         }
00564 
00565         padlen = 1 + ssl->in_msg[ssl->in_msglen - 1];
00566 
00567         if( ssl->minor_ver == SSLV3_MINOR_VERSION )
00568         {
00569             if( padlen > ssl->ivlen )
00570                 padlen = 0;
00571         }
00572         else
00573         {
00574             for( i = 1; i <= (int) padlen; i++ )
00575                 if( ssl->in_msg[ssl->in_msglen - i] != padlen - 1 )
00576                     padlen = 0;
00577         }
00578     }
00579 
00580     /*
00581      * Always compute the MAC (RFC4346, CBCTIME).
00582      */
00583     ssl->in_msglen -= ( ssl->maclen + padlen );
00584 
00585     ssl->in_hdr[3] = ssl->in_msglen >> 8;
00586     ssl->in_hdr[4] = ssl->in_msglen;
00587 
00588     memcpy( tmp, ssl->in_msg + ssl->in_msglen, 20 );
00589 
00590     if( ssl->minor_ver == SSLV3_MINOR_VERSION )
00591     {
00592         if( ssl->maclen == 16 )
00593              ssl_mac_md5( ssl->mac_dec,
00594                           ssl->in_msg, ssl->in_msglen,
00595                           ssl->in_ctr, ssl->in_msgtype );
00596         else
00597             ssl_mac_sha1( ssl->mac_dec,
00598                           ssl->in_msg, ssl->in_msglen,
00599                           ssl->in_ctr, ssl->in_msgtype );
00600     }
00601     else
00602     {
00603         if( ssl->maclen == 16 )
00604              md5_hmac( ssl->mac_dec, 16,
00605                        ssl->in_ctr,  ssl->in_msglen + 13,
00606                        ssl->in_msg + ssl->in_msglen );
00607         else
00608             sha1_hmac( ssl->mac_dec, 20,
00609                        ssl->in_ctr,  ssl->in_msglen + 13,
00610                        ssl->in_msg + ssl->in_msglen );
00611     }
00612 
00613     if( memcmp( tmp, ssl->in_msg + ssl->in_msglen,
00614                      ssl->maclen ) != 0 )
00615         return( ERR_SSL_INVALID_MAC );
00616 
00617     /*
00618      * Finally verify the padding length; bad padding
00619      * will produce the same error as an invalid MAC.
00620      */
00621     if( ssl->ivlen != 0 && padlen == 0 )
00622         return( ERR_SSL_INVALID_MAC );
00623 
00624     if( ssl->in_msglen == 0 )
00625     {
00626         ssl->nb_zero++;
00627 
00628         /*
00629          * Three or more empty messages may be a DoS attack.
00630          */
00631         if( ssl->nb_zero > 2 )
00632             return( ERR_SSL_INVALID_MAC );
00633     }
00634     else
00635         ssl->nb_zero = 0;
00636             
00637     for( i = 7; i >= 0; i-- )
00638         if( ++ssl->in_ctr[i] != 0 )
00639             break;
00640 
00641     return( 0 );
00642 }
00643 
00644 /*
00645  * Record layer functions
00646  */
00647 int ssl_write_record( ssl_context *ssl, int do_crypt )
00648 {
00649     int ret, len = ssl->out_msglen;
00650 
00651     ssl->out_hdr[0] = ssl->out_msgtype;
00652     ssl->out_hdr[1] = ssl->major_ver;
00653     ssl->out_hdr[2] = ssl->minor_ver;
00654     ssl->out_hdr[3] = len >> 8;
00655     ssl->out_hdr[4] = len;
00656 
00657     if( ssl->out_msgtype == SSL_MSG_HANDSHAKE )
00658     {
00659         ssl->out_msg[1] = ( len - 4 ) >> 16;
00660         ssl->out_msg[2] = ( len - 4 ) >>  8;
00661         ssl->out_msg[3] = ( len - 4 );
00662 
00663          md5_update( &ssl->hs_md5 , ssl->out_msg, len );
00664         sha1_update( &ssl->hs_sha1, ssl->out_msg, len );
00665     }
00666 
00667     if( do_crypt != 0 )
00668     {
00669         if( ( ret = ssl_encrypt_buf( ssl ) ) != 0 )
00670             return( ret );
00671 
00672         len = ssl->out_msglen;
00673         ssl->out_hdr[3] = len >> 8;
00674         ssl->out_hdr[4] = len;
00675     }
00676 
00677     ssl->out_left = 5 + ssl->out_msglen;
00678 
00679     return( net_send( ssl->write_fd,
00680                       ssl->out_hdr,
00681                      &ssl->out_left ) );
00682 }
00683 
00684 int ssl_read_record( ssl_context *ssl, int do_crypt )
00685 {
00686     int ret, len;
00687 
00688     if( ssl->in_hslen != 0 &&
00689         ssl->in_hslen < ssl->in_msglen )
00690     {
00691         /*
00692          * Get next Handshake message in the current record
00693          */
00694         ssl->in_msglen -= ssl->in_hslen;
00695 
00696         memcpy( ssl->in_msg, ssl->in_msg + ssl->in_hslen,
00697                 ssl->in_msglen );
00698 
00699         if( ssl->in_msglen < 4 || ssl->in_msg[1] != 0 )
00700             return( ERR_SSL_INVALID_RECORD );
00701 
00702         ssl->in_hslen  = 4;
00703         ssl->in_hslen += ( (int) ssl->in_msg[2] << 8 )
00704                        | ( (int) ssl->in_msg[3]      );
00705 
00706         if( ssl->in_msglen < ssl->in_hslen )
00707             return( ERR_SSL_INVALID_RECORD );
00708 
00709         return( 0 );
00710     }
00711 
00712     ssl->in_hslen = 0;
00713 
00714     /*
00715      * Read the record header and validate it
00716      */
00717     if( ssl->in_left < 5 )
00718     {
00719         len = 5 - ssl->in_left;
00720         ret = net_recv( ssl->read_fd, ssl->in_hdr
00721                                     + ssl->in_left, &len );
00722         ssl->in_left += len;
00723 
00724         if( ret != 0 )
00725             return( ret );
00726     }
00727 
00728     ssl->in_msgtype = ssl->in_hdr[0];
00729     ssl->in_msglen  = ( (int) ssl->in_hdr[3] << 8 )
00730                     | ( (int) ssl->in_hdr[4]      );
00731 
00732     if( ssl->in_hdr[1] != ssl->major_ver )
00733         return( ERR_SSL_INVALID_RECORD );
00734 
00735     if( ssl->in_hdr[2] != SSLV3_MINOR_VERSION &&
00736         ssl->in_hdr[2] != TLS10_MINOR_VERSION )
00737         return( ERR_SSL_INVALID_RECORD );
00738 
00739     /*
00740      * Make sure the message length is acceptable
00741      */
00742     if( do_crypt == 0 )
00743     {
00744         if( ssl->in_msglen < 1 ||
00745             ssl->in_msglen > SSL_MAX_CONTENT_LEN )
00746             return( ERR_SSL_INVALID_RECORD );
00747     }
00748     else
00749     {
00750         if( ssl->in_msglen < ssl->minlen )
00751             return( ERR_SSL_INVALID_RECORD );
00752 
00753         if( ssl->minor_ver == 0 &&
00754             ssl->in_msglen > ssl->minlen + SSL_MAX_CONTENT_LEN )
00755             return( ERR_SSL_INVALID_RECORD );
00756 
00757         /*
00758          * TLS encrypted messages can have up to 256 bytes of padding
00759          */
00760         if( ssl->minor_ver != 0 &&
00761             ssl->in_msglen > ssl->minlen + SSL_MAX_CONTENT_LEN + 256 )
00762             return( ERR_SSL_INVALID_RECORD );
00763     }
00764 
00765     /*
00766      * Read and optionally decrypt the message contents
00767      */
00768     len = ssl->in_msglen - ( ssl->in_left - 5 );
00769     ret = net_recv( ssl->read_fd, ssl->in_hdr
00770                                 + ssl->in_left, &len );
00771     ssl->in_left += len;
00772 
00773     if( ret != 0 )
00774         return( ret );
00775 
00776     if( do_crypt != 0 )
00777     {
00778         if( ( ret = ssl_decrypt_buf( ssl ) ) != 0 )
00779             return( ret );
00780 
00781         if( ssl->in_msglen > SSL_MAX_CONTENT_LEN )
00782             return( ERR_SSL_INVALID_RECORD );
00783     }
00784 
00785     if( ssl->in_msgtype == SSL_MSG_HANDSHAKE )
00786     {
00787         /*
00788          * Additional checks to validate the handshake header
00789          */
00790         if( ssl->in_msglen < 4 || ssl->in_msg[1] != 0 )
00791             return( ERR_SSL_INVALID_RECORD );
00792 
00793         ssl->in_hslen  = 4;
00794         ssl->in_hslen += ( (int) ssl->in_msg[2] << 8 )
00795                        | ( (int) ssl->in_msg[3]      );
00796 
00797         if( ssl->in_msglen < ssl->in_hslen )
00798             return( ERR_SSL_INVALID_RECORD );
00799 
00800           md5_update( &ssl->hs_md5 , ssl->in_msg, ssl->in_msglen );
00801          sha1_update( &ssl->hs_sha1, ssl->in_msg, ssl->in_msglen );
00802     }
00803 
00804     if( ssl->in_msgtype == SSL_MSG_ALERT )
00805     {
00806         /*
00807          * Ignore non-fatal alerts, except close_notify
00808          */
00809         if( ssl->in_msg[0] == SSL_ALERT_FATAL )
00810             return( ERR_SSL_FATAL_ALERT_MESSAGE );
00811 
00812         if( ssl->in_msg[0] == SSL_ALERT_WARNING &&
00813             ssl->in_msg[1] == SSL_ALERT_CLOSE_NOTIFY )
00814             return( ERR_SSL_PEER_CLOSE_NOTIFY );
00815     }
00816 
00817     ssl->in_left = 0;
00818 
00819     return( 0 );
00820 }
00821 
00822 /*
00823  * Flush any data not yet written
00824  */
00825 int ssl_flush_output( ssl_context *ssl )
00826 {
00827     int ret = 0;
00828     unsigned char *buf;
00829 
00830     if( ssl->out_left > 0 )
00831     {
00832         buf = ssl->out_hdr + ssl->out_msglen -
00833             ( ssl->out_left - 5 );
00834 
00835         ret = net_send( ssl->write_fd, buf,
00836                        &ssl->out_left );
00837     }
00838 
00839     return( ret );
00840 }
00841 
00842 /*
00843  * Handshake functions
00844  */
00845 int ssl_write_certificate( ssl_context *ssl )
00846 {
00847     int i, n;
00848     x509_cert *crt;
00849 
00850     if( ssl->endpoint == SSL_IS_CLIENT )
00851     {
00852         if( ssl->client_auth == 0 )
00853         {
00854             ssl->state++;
00855             return( 0 );
00856         }
00857 
00858         /*
00859          * If using SSLv3 and got no cert, send an Alert message
00860          * (otherwise an empty Certificate message will be sent).
00861          */
00862         if( ssl->own_cert  == NULL &&
00863             ssl->minor_ver == SSLV3_MINOR_VERSION )
00864         {
00865             ssl->out_msglen  = 2;
00866             ssl->out_msgtype = SSL_MSG_ALERT;
00867             ssl->out_msg[0]  = SSL_ALERT_WARNING;
00868             ssl->out_msg[1]  = SSL_ALERT_NO_CERTIFICATE;
00869 
00870             ssl->state++;
00871             return( ssl_write_record( ssl, 0 ) );
00872         }
00873     }
00874     else /* SSL_IS_SERVER */
00875         if( ssl->own_cert == NULL )
00876             return( ERR_SSL_CERTIFICATE_REQUIRED );
00877 
00878     /*
00879      *     0  .  0    handshake type
00880      *     1  .  3    handshake length
00881      *     4  .  6    length of all certs
00882      *     7  .  9    length of cert. 1
00883      *    10  . n-1   peer certificate
00884      *     n  . n+2   length of cert. 2
00885      *    n+3 . ...   upper level cert, etc.
00886      */
00887     i = 7;
00888     crt = ssl->own_cert;
00889     while( crt != NULL && crt->next != NULL )
00890     {
00891         n = crt->raw.len;
00892         if( i + 3 + n > SSL_MAX_CONTENT_LEN )
00893             return( ERR_SSL_CERTIFICATE_TOO_LARGE );
00894 
00895         ssl->out_msg[i    ] = ( n >> 16 );
00896         ssl->out_msg[i + 1] = ( n >>  8 );
00897         ssl->out_msg[i + 2] = ( n       );
00898 
00899         i += 3; memcpy( ssl->out_msg + i, crt->raw.p, n );
00900         i += n; crt = crt->next;
00901     }
00902 
00903     ssl->out_msg[4] = ( i - 7 ) >> 16;
00904     ssl->out_msg[5] = ( i - 7 ) >>  8;
00905     ssl->out_msg[6] = ( i - 7 )      ;
00906 
00907     ssl->out_msglen  = i;
00908     ssl->out_msgtype = SSL_MSG_HANDSHAKE;
00909     ssl->out_msg[0]  = SSL_HS_CERTIFICATE;
00910 
00911     ssl->state++;
00912 
00913     return( ssl_write_record( ssl, 0 ) );
00914 }
00915 
00916 int ssl_parse_certificate( ssl_context *ssl )
00917 {
00918     int ret, i, n;
00919 
00920     if( ssl->endpoint == SSL_IS_SERVER &&
00921         ssl->authmode == SSL_VERIFY_NONE )
00922     {
00923         ssl->state++;
00924         return( 0 );
00925     }
00926 
00927     if( ( ret = ssl_read_record( ssl, 0 ) ) != 0 )
00928         return( ret );
00929 
00930     ssl->state++;
00931 
00932     /*
00933      * Check if the client sent an empty certificate
00934      */
00935     if( ssl->endpoint  == SSL_IS_SERVER &&
00936         ssl->minor_ver == SSLV3_MINOR_VERSION )
00937     {
00938         if( ssl->in_msglen  == 2                    &&
00939             ssl->in_msgtype == SSL_MSG_ALERT        &&
00940             ssl->in_msg[0]  == SSL_ALERT_WARNING    &&
00941             ssl->in_msg[1]  == SSL_ALERT_NO_CERTIFICATE )
00942         {
00943             if( ssl->authmode == SSL_VERIFY_OPTIONAL )
00944                 return( 0 );
00945             else
00946                 return( ERR_SSL_NO_CLIENT_CERTIFICATE );
00947         }
00948     }
00949 
00950     if( ssl->endpoint  == SSL_IS_SERVER &&
00951         ssl->minor_ver != SSLV3_MINOR_VERSION )
00952     {
00953         if( ssl->in_hslen   == 7                    &&
00954             ssl->in_msgtype == SSL_MSG_HANDSHAKE    &&
00955             ssl->in_msg[0]  == SSL_HS_CERTIFICATE   &&
00956             memcmp( ssl->in_msg + 4, "\0\0\0", 3 ) == 0 )
00957         {
00958             if( ssl->authmode == SSL_VERIFY_OPTIONAL )
00959                 return( 0 );
00960             else
00961                 return( ERR_SSL_NO_CLIENT_CERTIFICATE );
00962         }
00963     }
00964 
00965     if( ssl->in_msgtype != SSL_MSG_HANDSHAKE )
00966         return( ERR_SSL_UNEXPECTED_MESSAGE );
00967 
00968     if( ssl->in_msg[0] != SSL_HS_CERTIFICATE || ssl->in_hslen < 10 )
00969         return( ERR_SSL_BAD_HS_CERTIFICATE );
00970 
00971     /*
00972      * Same message structure as shown above
00973      */
00974     n = ( (int) ssl->in_msg[5] << 8 )
00975       | ( (int) ssl->in_msg[6]      );
00976 
00977     if( ssl->in_msg[4] != 0 || ssl->in_hslen != 7 + n )
00978         return( ERR_SSL_BAD_HS_CERTIFICATE );
00979 
00980     if( ( ssl->peer_cert = (x509_cert *) malloc(
00981                     sizeof( x509_cert ) ) ) == NULL )
00982         return( 1 );
00983 
00984     memset( ssl->peer_cert, 0, sizeof( x509_cert ) );
00985     i = 7;
00986 
00987     while( i < ssl->in_hslen )
00988     {
00989         if( ssl->in_msg[i] != 0 )
00990             return( ERR_SSL_BAD_HS_CERTIFICATE );
00991 
00992         n = ( (unsigned int) ssl->in_msg[i + 1] << 8 )
00993           | ( (unsigned int) ssl->in_msg[i + 2]      );
00994         i += 3;
00995 
00996         if( n < 128 || i + n > ssl->in_hslen )
00997             return( ERR_SSL_BAD_HS_CERTIFICATE );
00998 
00999         ret = x509_add_certs( ssl->peer_cert, ssl->in_msg + i, n );
01000         if( ret != 0 )
01001             return( ret );
01002 
01003         i += n;
01004     }
01005 
01006     if( ssl->authmode != SSL_VERIFY_NONE )
01007     {
01008         if( ssl->ca_chain == NULL )
01009             return( ERR_SSL_CA_CHAIN_REQUIRED );
01010 
01011         ret = x509_verify_cert( ssl->peer_cert, ssl->ca_chain,
01012                                 ssl->peer_cn,  &ssl->verify_result );
01013 
01014         if( ssl->authmode == SSL_VERIFY_REQUIRED )
01015             return( ret );
01016     }
01017 
01018     return( 0 );
01019 }
01020 
01021 int ssl_write_change_cipher_spec( ssl_context *ssl )
01022 {
01023     ssl->out_msgtype = SSL_MSG_CHANGE_CIPHER_SPEC;
01024     ssl->out_msg[0]  = ssl->out_msglen = 1;
01025 
01026     ssl->state++;
01027     return( ssl_write_record( ssl, 0 ) );
01028 }
01029 
01030 int ssl_parse_change_cipher_spec( ssl_context *ssl )
01031 {
01032     int ret;
01033 
01034     if( ( ret = ssl_read_record( ssl, 0 ) ) != 0 )
01035         return( ret );
01036 
01037     if( ssl->in_msgtype != SSL_MSG_CHANGE_CIPHER_SPEC )
01038         return( ERR_SSL_UNEXPECTED_MESSAGE );
01039 
01040     if( ssl->in_msglen != 1 || ssl->in_msg[0] != 1 )
01041         return( ERR_SSL_BAD_HS_CHANGE_CIPHER_SPEC );
01042 
01043     ssl->state++;
01044     return( 0 );
01045 }
01046 
01047 static void ssl_calc_finished(
01048                 ssl_context *ssl, unsigned char *buf, int from,
01049                 md5_context *md5, sha1_context *sha1 )
01050 {
01051     char *sender;
01052     unsigned char padbuf[48];
01053     unsigned char md5sum[16];
01054     unsigned char sha1sum[20];
01055 
01056     /*
01057      * SSLv3:
01058      *   hash =
01059      *      MD5( master + pad2 +
01060      *          MD5( handshake + sender + master + pad1 ) )
01061      *   + SHA1( master + pad2 +
01062      *         SHA1( handshake + sender + master + pad1 ) )
01063      *
01064      * TLSv1:
01065      *   hash = PRF( master, finished_label,
01066      *               MD5( handshake ) + SHA1( handshake ) )[0..11]
01067      */
01068     if( ssl->minor_ver == SSLV3_MINOR_VERSION )
01069     {
01070         sender = ( from == SSL_IS_CLIENT ) ? (char *) "CLNT"
01071                                            : (char *) "SRVR";
01072 
01073         memset( padbuf, 0x36, 48 );
01074 
01075         md5_update( md5, (unsigned char *) sender, 4 );
01076         md5_update( md5, ssl->master, 48 );
01077         md5_update( md5, padbuf, 48 );
01078         md5_finish( md5, md5sum );
01079 
01080         sha1_update( sha1, (unsigned char *) sender, 4 );
01081         sha1_update( sha1, ssl->master, 48 );
01082         sha1_update( sha1, padbuf, 40 );
01083         sha1_finish( sha1, sha1sum );
01084 
01085         memset( padbuf, 0x5C, 48 );
01086 
01087         md5_starts( md5 );
01088         md5_update( md5, ssl->master, 48 );
01089         md5_update( md5, padbuf, 48 );
01090         md5_update( md5, md5sum, 16 );
01091         md5_finish( md5, buf );
01092 
01093         sha1_starts( sha1 );
01094         sha1_update( sha1, ssl->master, 48 );
01095         sha1_update( sha1, padbuf , 40 );
01096         sha1_update( sha1, sha1sum, 20 );
01097         sha1_finish( sha1, buf + 16 );
01098     }
01099     else
01100     {
01101         sender = ( from == SSL_IS_CLIENT )
01102                  ? (char *) "client finished"
01103                  : (char *) "server finished";
01104 
01105          md5_finish(  md5, padbuf );
01106         sha1_finish( sha1, padbuf + 16 );
01107 
01108         tls1_prf( ssl->master, 48, sender, padbuf, 36, buf, 12 );
01109     }
01110 
01111     memset(  md5, 0, sizeof(  md5_context ) );
01112     memset( sha1, 0, sizeof( sha1_context ) );
01113 
01114     memset(  padbuf, 0, sizeof(  padbuf ) );
01115     memset(  md5sum, 0, sizeof(  md5sum ) );
01116     memset( sha1sum, 0, sizeof( sha1sum ) );
01117 }
01118 
01119 int ssl_write_finished( ssl_context *ssl )
01120 {
01121     int hash_len = 12;
01122      md5_context  md5;
01123     sha1_context sha1;
01124 
01125     memcpy( &md5 , &ssl->hs_md5 , sizeof(  md5_context ) );
01126     memcpy( &sha1, &ssl->hs_sha1, sizeof( sha1_context ) );
01127 
01128     ssl_calc_finished( ssl, ssl->out_msg + 4,
01129                        ssl->endpoint, &md5, &sha1 );
01130 
01131     if( ssl->minor_ver == SSLV3_MINOR_VERSION )
01132         hash_len += 24;
01133 
01134     ssl->out_msglen  = 4 + hash_len;
01135     ssl->out_msgtype = SSL_MSG_HANDSHAKE;
01136     ssl->out_msg[0]  = SSL_HS_FINISHED;
01137 
01138     /*
01139      * In case of session resuming, invert the client and server
01140      * ChangeCipherSpec messages order.
01141      */
01142     if( ssl->resumed != 0 )
01143     {
01144         if( ssl->endpoint == SSL_IS_CLIENT )
01145             ssl->state = SSL_HANDSHAKE_OVER;
01146 
01147         if( ssl->endpoint == SSL_IS_SERVER )
01148             ssl->state = SSL_CLIENT_CHANGE_CIPHER_SPEC;
01149     }
01150     else
01151         ssl->state++;
01152 
01153     return( ssl_write_record( ssl, 1 ) );
01154 }
01155 
01156 int ssl_parse_finished( ssl_context *ssl )
01157 {
01158     int ret, hash_len = 12;
01159     unsigned char buf[36];
01160      md5_context  md5;
01161     sha1_context sha1;
01162 
01163     memcpy( &md5 , &ssl->hs_md5 , sizeof(  md5_context ) );
01164     memcpy( &sha1, &ssl->hs_sha1, sizeof( sha1_context ) );
01165 
01166     if( ( ret = ssl_read_record( ssl, 1 ) ) != 0 )
01167         return( ret );
01168 
01169     if( ssl->in_msgtype != SSL_MSG_HANDSHAKE )
01170         return( ERR_SSL_UNEXPECTED_MESSAGE );
01171 
01172     if( ssl->minor_ver == SSLV3_MINOR_VERSION )
01173         hash_len += 24;
01174 
01175     if( ssl->in_msg[0] != SSL_HS_FINISHED ||
01176         ssl->in_hslen  != 4 + hash_len )
01177         return( ERR_SSL_BAD_HS_FINISHED );
01178 
01179     ssl_calc_finished( ssl, buf, ssl->endpoint ^ 1, &md5, &sha1 );
01180 
01181     if( memcmp( ssl->in_msg + 4, buf, hash_len ) != 0 )
01182         return( ERR_SSL_BAD_HS_FINISHED );
01183 
01184     if( ssl->resumed != 0 )
01185     {
01186         if( ssl->endpoint == SSL_IS_CLIENT )
01187             ssl->state = SSL_CLIENT_CHANGE_CIPHER_SPEC;
01188 
01189         if( ssl->endpoint == SSL_IS_SERVER )
01190             ssl->state = SSL_HANDSHAKE_OVER;
01191     }
01192     else
01193         ssl->state++;
01194 
01195     return( 0 );
01196 }
01197 
01198 /*
01199  * SSL context setup functions
01200  */
01201 int ssl_init( ssl_context *ssl, int client_resume )
01202 {
01203     int tmp_sidlen = 0;
01204     unsigned char tmp_sessid[32];
01205     unsigned char tmp_master[48];
01206 
01207     if( client_resume != 0 )
01208     {
01209         /*
01210          * Backup the session id and master secret
01211          */
01212         tmp_sidlen = ssl->sidlen;
01213         memcpy( tmp_sessid, ssl->sessid, 32 );
01214         memcpy( tmp_master, ssl->master, 48 );
01215     }
01216 
01217     memset( ssl, 0, sizeof( ssl_context ) );
01218 
01219     ssl->in_ctr  = (unsigned char *) malloc( SSL_BUFFER_LEN );
01220     ssl->in_hdr  = ssl->in_ctr +  8;
01221     ssl->in_msg  = ssl->in_ctr + 13;
01222 
01223     ssl->out_ctr = (unsigned char *) malloc( SSL_BUFFER_LEN );
01224     ssl->out_hdr = ssl->out_ctr +  8;
01225     ssl->out_msg = ssl->out_ctr + 13;
01226 
01227     if( ssl->in_ctr == NULL || ssl->out_ctr == NULL )
01228         return( 1 );
01229 
01230     memset( ssl-> in_ctr, 0, 8 );
01231     memset( ssl->out_ctr, 0, 8 );
01232 
01233     if( client_resume != 0 )
01234     {
01235         ssl->sidlen = tmp_sidlen;
01236         memcpy( ssl->sessid, tmp_sessid, 32 );
01237         memcpy( ssl->master, tmp_master, 48 );
01238     }
01239 
01240     return( 0 );
01241 }
01242 
01243 /*
01244  * SSL set accessors
01245  */
01246 void ssl_set_endpoint( ssl_context *ssl, int endpoint )
01247 {
01248     ssl->endpoint   = endpoint;
01249 }
01250 
01251 void ssl_set_authmode( ssl_context *ssl, int authmode )
01252 {
01253     ssl->authmode   = authmode;
01254 }
01255 
01256 void ssl_set_rng_func( ssl_context *ssl,
01257                        int (*rng_f)(void *),
01258                        void *rng_d )
01259 {
01260     ssl->rng_f      = rng_f;
01261     ssl->rng_d      = rng_d;
01262 }
01263 
01264 void ssl_set_io_files( ssl_context *ssl, int read_fd, int write_fd )
01265 {
01266     ssl->read_fd    = read_fd;
01267     ssl->write_fd   = write_fd;
01268 }
01269 
01270 void ssl_set_ciphlist( ssl_context *ssl, int *ciphers )
01271 {
01272     ssl->cipherlist = ciphers;
01273 }
01274 
01275 void ssl_set_ca_chain( ssl_context *ssl, x509_cert *ca, char *cn )
01276 {
01277     ssl->ca_chain   = ca;
01278     ssl->peer_cn    = cn;
01279 }
01280 
01281 void ssl_set_rsa_cert( ssl_context *ssl, x509_cert *own_cert,
01282                        rsa_context *own_key )
01283 {
01284     ssl->own_cert   = own_cert;
01285     ssl->own_key    = own_key;
01286 }
01287 
01288 void ssl_set_sidtable( ssl_context *ssl, unsigned char *sidtable )
01289 {
01290     ssl->sidtable   = sidtable;
01291 }
01292 
01293 int ssl_set_dhm_vals( ssl_context *ssl, char *dhm_P, char *dhm_G )
01294 {
01295     if( mpi_read_string( &ssl->dhm_ctx.P, 16, dhm_P ) != 0 ||
01296         mpi_read_string( &ssl->dhm_ctx.G, 16, dhm_G ) != 0 )
01297         return( 1 );
01298 
01299     return( 0 );
01300 }
01301 
01302 /*
01303  * SSL get accessors
01304  */
01305 int ssl_get_verify_result( ssl_context *ssl )
01306 {
01307     return( ssl->verify_result );
01308 }
01309 
01310 char *ssl_get_cipher_name( ssl_context *ssl )
01311 {
01312     switch( ssl->cipher )
01313     {
01314 #if !defined(NO_ARC4)
01315         case SSL3_RSA_RC4_128_MD5:
01316             return( "SSL3_RSA_RC4_128_MD5" );
01317 
01318         case SSL3_RSA_RC4_128_SHA:
01319             return( "SSL3_RSA_RC4_128_SHA" );
01320 #endif
01321 
01322 #if !defined(NO_DES)
01323         case SSL3_RSA_DES_168_SHA:
01324             return( "SSL3_RSA_DES_168_SHA" );
01325 
01326         case SSL3_EDH_RSA_DES_168_SHA:
01327             return( "SSL3_EDH_RSA_DES_168_SHA" );
01328 #endif
01329 
01330 #if !defined(NO_AES)
01331         case TLS1_RSA_AES_256_SHA:
01332             return( "TLS1_RSA_AES_256_SHA" );
01333 
01334         case TLS1_EDH_RSA_AES_256_SHA:
01335             return( "TLS1_EDH_RSA_AES_256_SHA" );
01336 #endif
01337 
01338         default:
01339             break;
01340     }
01341 
01342     return( "UNKNOWN_CIPHER" );
01343 }
01344 
01345 int ssl_default_ciphers[] =
01346 {
01347 #if !defined(NO_DHM)
01348 #if !defined(NO_AES)
01349     TLS1_EDH_RSA_AES_256_SHA,
01350 #endif
01351 #if !defined(NO_DES)
01352     SSL3_EDH_RSA_DES_168_SHA,
01353 #endif
01354 #endif
01355 #if !defined(NO_AES)
01356     TLS1_RSA_AES_256_SHA,
01357 #endif
01358 #if !defined(NO_DES)
01359     SSL3_RSA_DES_168_SHA,
01360 #endif
01361 #if !defined(NO_ARC4)
01362     SSL3_RSA_RC4_128_SHA,
01363     SSL3_RSA_RC4_128_MD5,
01364 #endif
01365     0
01366 };
01367 
01368 /*
01369  * Perform the SSL handshake
01370  */
01371 int ssl_handshake( ssl_context *ssl )
01372 {
01373 #if !defined(NO_SSL_CLI)
01374     if( ssl->endpoint == SSL_IS_CLIENT )
01375         return( ssl_client_start( ssl ) );
01376 #endif
01377 
01378 #if !defined(NO_SSL_SRV)
01379     if( ssl->endpoint == SSL_IS_SERVER )
01380         return( ssl_server_start( ssl ) );
01381 #endif
01382 
01383     return( ERR_SSL_FEATURE_UNAVAILABLE );
01384 }
01385 
01386 /*
01387  * Receive application data decrypted from the SSL layer
01388  */
01389 int ssl_read( ssl_context *ssl, unsigned char *buf, int *len )
01390 {
01391     int ret, n;
01392 
01393     if( ( ret = ssl_handshake( ssl ) ) != 0 )
01394         return( ret );
01395 
01396     if( ssl->in_offt == NULL )
01397     {
01398         if( ( ret = ssl_read_record( ssl, 1 ) ) != 0 )
01399             return( ret );
01400 
01401         if( ssl->in_msgtype != SSL_MSG_APPLICATION_DATA )
01402             return( ERR_SSL_UNEXPECTED_MESSAGE );
01403 
01404         ssl->in_offt = ssl->in_msg;
01405     }
01406 
01407     n = ( *len < ssl->in_msglen )
01408         ? *len : ssl->in_msglen;
01409 
01410     memcpy( buf, ssl->in_offt, n );
01411     ssl->in_msglen -= ( *len = n );
01412 
01413     if( ssl->in_msglen == 0 )
01414         ssl->in_offt = NULL;
01415     else
01416         ssl->in_offt += n;
01417 
01418     return( 0 );
01419 }
01420 
01421 /*
01422  * Send application data to be encrypted by the SSL layer
01423  */
01424 int ssl_write( ssl_context *ssl, unsigned char *buf, int len )
01425 {
01426     int ret, n;
01427 
01428     ret = ssl_handshake( ssl );
01429 
01430     while( ssl->out_uoff < len && ret == 0 )
01431     {
01432         n = ( ( len - ssl->out_uoff ) < SSL_MAX_CONTENT_LEN )
01433             ? ( len - ssl->out_uoff ) : SSL_MAX_CONTENT_LEN;
01434 
01435         ssl->out_uoff   += n;
01436         ssl->out_msglen  = n;
01437         ssl->out_msgtype = SSL_MSG_APPLICATION_DATA;
01438         memcpy( ssl->out_msg, buf, n ); buf += n;
01439 
01440         ret = ssl_write_record( ssl, 1 );
01441     }
01442 
01443     if( ssl->out_uoff >= len )
01444         ssl->out_uoff  = 0;
01445 
01446     return( ret );
01447 }
01448 
01449 /*
01450  * Notify the peer that the connection is being closed
01451  */
01452 int ssl_close_notify( ssl_context *ssl )
01453 {
01454     int ret = ssl_flush_output( ssl );
01455 
01456     if( ret == 0 && ssl->state == SSL_HANDSHAKE_OVER )
01457     {
01458         ssl->out_msgtype = SSL_MSG_ALERT;
01459         ssl->out_msglen  = 2;
01460         ssl->out_msg[0]  = SSL_ALERT_WARNING;
01461         ssl->out_msg[1]  = SSL_ALERT_CLOSE_NOTIFY;
01462 
01463         ssl->state++;
01464         ret = ssl_write_record( ssl, 1 );
01465     }
01466 
01467     return( ret );
01468 }
01469 
01470 static const char _ssl_tls_src[] = "_ssl_tls_src";
01471 
01472 /*
01473  * Free an SSL context
01474  */
01475 void ssl_free( ssl_context *ssl )
01476 {
01477     if( ssl->ctx_dec != NULL )
01478     {
01479         memset( ssl->ctx_dec, 0, ssl->ctxlen );
01480           free( ssl->ctx_dec );
01481         ssl->ctx_dec = NULL;
01482     }
01483 
01484     if( ssl->ctx_enc != NULL )
01485     {
01486         memset( ssl->ctx_enc, 0, ssl->ctxlen );
01487           free( ssl->ctx_enc );
01488         ssl->ctx_enc = NULL;
01489     }
01490 
01491 #if !defined(NO_DHM)
01492     dhm_free( &ssl->dhm_ctx );
01493 #endif
01494 
01495     if( ssl->peer_cert != NULL )
01496     {
01497         x509_free_cert( ssl->peer_cert );
01498         free( ssl->peer_cert );
01499         ssl->peer_cert = NULL;
01500     }
01501 
01502     if( ssl->out_ctr != NULL )
01503     {
01504         memset( ssl->out_ctr, 0, SSL_BUFFER_LEN );
01505           free( ssl->out_ctr );
01506         ssl->out_ctr = NULL;
01507     }
01508 
01509     if( ssl->in_ctr != NULL )
01510     {
01511         memset( ssl->in_ctr, 0, SSL_BUFFER_LEN );
01512           free( ssl->in_ctr );
01513         ssl->in_ctr = NULL;
01514     }
01515 }

Generated on Fri May 16 14:49:55 2008 for Mobile-C by  doxygen 1.5.4