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

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

Generated on Tue Jul 1 15:29:59 2008 for Mobile-C by  doxygen 1.5.4