- Main Page
- Related Pages
- Data Structures
- Files

# ssl_cli.c

Go to the documentation of this file.

    00001 /*
    00002  *  SSLv3/TLSv1 client-side functions
    00003  *
    00004  *  Copyright (C) 2006-2009, Paul Bakker <polarssl_maintainer at polarssl.org>
    00005  *  All rights reserved.
    00006  *
    00007  *  Joined copyright on original XySSL code with: Christophe Devine
    00008  *
    00009  *  This program is free software; you can redistribute it and/or modify
    00010  *  it under the terms of the GNU General Public License as published by
    00011  *  the Free Software Foundation; either version 2 of the License, or
    00012  *  (at your option) any later version.
    00013  *
    00014  *  This program is distributed in the hope that it will be useful,
    00015  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
    00016  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    00017  *  GNU General Public License for more details.
    00018  *
    00019  *  You should have received a copy of the GNU General Public License along
    00020  *  with this program; if not, write to the Free Software Foundation, Inc.,
    00021  *  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
    00022  */
    00023
    00024 #include "polarssl/config.h"
    00025
    00026 #if defined(POLARSSL_SSL_CLI_C)
    00027
    00028 #include "polarssl/debug.h"
    00029 #include "polarssl/ssl.h"
    00030
    00031 #include <string.h>
    00032 #include <stdlib.h>
    00033 #include <stdio.h>
    00034 #include <time.h>
    00035
    00036 static int ssl_write_client_hello( ssl_context *ssl )
    00037 {
    00038     int ret, i, n;
    00039     unsigned char *buf;
    00040     unsigned char *p;
    00041     time_t t;
    00042
    00043     SSL_DEBUG_MSG( 2, ( "=> write client hello" ) );
    00044
    00045     ssl->major_ver = SSL_MAJOR_VERSION_3;
    00046     ssl->minor_ver = SSL_MINOR_VERSION_0;
    00047
    00048     ssl->max_major_ver = SSL_MAJOR_VERSION_3;
    00049     ssl->max_minor_ver = SSL_MINOR_VERSION_1;
    00050
    00051     /*
    00052      *     0  .   0   handshake type
    00053      *     1  .   3   handshake length
    00054      *     4  .   5   highest version supported
    00055      *     6  .   9   current UNIX time
    00056      *    10  .  37   random bytes
    00057      */
    00058     buf = ssl->out_msg;
    00059     p = buf + 4;
    00060
    00061     *p++ = (unsigned char) ssl->max_major_ver;
    00062     *p++ = (unsigned char) ssl->max_minor_ver;
    00063
    00064     SSL_DEBUG_MSG( 3, ( "client hello, max version: [%d:%d]",
    00065                    buf[4], buf[5] ) );
    00066
    00067     t = time( NULL );
    00068     *p++ = (unsigned char)( t >> 24 );
    00069     *p++ = (unsigned char)( t >> 16 );
    00070     *p++ = (unsigned char)( t >>  8 );
    00071     *p++ = (unsigned char)( t       );
    00072
    00073     SSL_DEBUG_MSG( 3, ( "client hello, current time: %lu", t ) );
    00074
    00075     for( i = 28; i > 0; i-- )
    00076         *p++ = (unsigned char) ssl->f_rng( ssl->p_rng );
    00077
    00078     memcpy( ssl->randbytes, buf + 6, 32 );
    00079
    00080     SSL_DEBUG_BUF( 3, "client hello, random bytes", buf + 6, 32 );
    00081
    00082     /*
    00083      *    38  .  38   session id length
    00084      *    39  . 39+n  session id
    00085      *   40+n . 41+n  cipherlist length
    00086      *   42+n . ..    cipherlist
    00087      *   ..   . ..    compression alg. (0)
    00088      *   ..   . ..    extensions (unused)
    00089      */
    00090     n = ssl->session->length;
    00091
    00092     if( n < 16 || n > 32 || ssl->resume == 0 ||
    00093         t - ssl->session->start > ssl->timeout )
    00094         n = 0;
    00095
    00096     *p++ = (unsigned char) n;
    00097
    00098     for( i = 0; i < n; i++ )
    00099         *p++ = ssl->session->id[i];
    00100
    00101     SSL_DEBUG_MSG( 3, ( "client hello, session id len.: %d", n ) );
    00102     SSL_DEBUG_BUF( 3,   "client hello, session id", buf + 39, n );
    00103
    00104     for( n = 0; ssl->ciphers[n] != 0; n++ );
    00105     *p++ = (unsigned char)( n >> 7 );
    00106     *p++ = (unsigned char)( n << 1 );
    00107
    00108     SSL_DEBUG_MSG( 3, ( "client hello, got %d ciphers", n ) );
    00109
    00110     for( i = 0; i < n; i++ )
    00111     {
    00112         SSL_DEBUG_MSG( 3, ( "client hello, add cipher: %2d",
    00113                        ssl->ciphers[i] ) );
    00114
    00115         *p++ = (unsigned char)( ssl->ciphers[i] >> 8 );
    00116         *p++ = (unsigned char)( ssl->ciphers[i]      );
    00117     }
    00118
    00119     SSL_DEBUG_MSG( 3, ( "client hello, compress len.: %d", 1 ) );
    00120     SSL_DEBUG_MSG( 3, ( "client hello, compress alg.: %d", 0 ) );
    00121
    00122     *p++ = 1;
    00123     *p++ = SSL_COMPRESS_NULL;
    00124
    00125     if ( ssl->hostname != NULL )
    00126     {
    00127         SSL_DEBUG_MSG( 3, ( "client hello, server name extension: %s",
    00128                        ssl->hostname ) );
    00129
    00130         *p++ = (unsigned char)( ( (ssl->hostname_len + 9) >> 8 ) & 0xFF );
    00131         *p++ = (unsigned char)( ( (ssl->hostname_len + 9)      ) & 0xFF );
    00132
    00133         *p++ = (unsigned char)( ( TLS_EXT_SERVERNAME >> 8 ) & 0xFF );
    00134         *p++ = (unsigned char)( ( TLS_EXT_SERVERNAME      ) & 0xFF );
    00135
    00136         *p++ = (unsigned char)( ( (ssl->hostname_len + 5) >> 8 ) & 0xFF );
    00137         *p++ = (unsigned char)( ( (ssl->hostname_len + 5)      ) & 0xFF );
    00138
    00139         *p++ = (unsigned char)( ( (ssl->hostname_len + 3) >> 8 ) & 0xFF );
    00140         *p++ = (unsigned char)( ( (ssl->hostname_len + 3)      ) & 0xFF );
    00141
    00142         *p++ = (unsigned char)( ( TLS_EXT_SERVERNAME_HOSTNAME ) & 0xFF );
    00143         *p++ = (unsigned char)( ( ssl->hostname_len >> 8 ) & 0xFF );
    00144         *p++ = (unsigned char)( ( ssl->hostname_len      ) & 0xFF );
    00145
    00146         memcpy( p, ssl->hostname, ssl->hostname_len );
    00147
    00148         p += ssl->hostname_len;
    00149     }
    00150
    00151     ssl->out_msglen  = p - buf;
    00152     ssl->out_msgtype = SSL_MSG_HANDSHAKE;
    00153     ssl->out_msg[0]  = SSL_HS_CLIENT_HELLO;
    00154
    00155     ssl->state++;
    00156
    00157     if( ( ret = ssl_write_record( ssl ) ) != 0 )
    00158     {
    00159         SSL_DEBUG_RET( 1, "ssl_write_record", ret );
    00160         return( ret );
    00161     }
    00162
    00163     SSL_DEBUG_MSG( 2, ( "<= write client hello" ) );
    00164
    00165     return( 0 );
    00166 }
    00167
    00168 static int ssl_parse_server_hello( ssl_context *ssl )
    00169 {
    00170     time_t t;
    00171     int ret, i, n;
    00172     int ext_len;
    00173     unsigned char *buf;
    00174
    00175     SSL_DEBUG_MSG( 2, ( "=> parse server hello" ) );
    00176
    00177     /*
    00178      *     0  .   0   handshake type
    00179      *     1  .   3   handshake length
    00180      *     4  .   5   protocol version
    00181      *     6  .   9   UNIX time()
    00182      *    10  .  37   random bytes
    00183      */
    00184     buf = ssl->in_msg;
    00185
    00186     if( ( ret = ssl_read_record( ssl ) ) != 0 )
    00187     {
    00188         SSL_DEBUG_RET( 1, "ssl_read_record", ret );
    00189         return( ret );
    00190     }
    00191
    00192     if( ssl->in_msgtype != SSL_MSG_HANDSHAKE )
    00193     {
    00194         SSL_DEBUG_MSG( 1, ( "bad server hello message" ) );
    00195         return( POLARSSL_ERR_SSL_UNEXPECTED_MESSAGE );
    00196     }
    00197
    00198     SSL_DEBUG_MSG( 3, ( "server hello, chosen version: [%d:%d]",
    00199                    buf[4], buf[5] ) );
    00200
    00201     if( ssl->in_hslen < 42 ||
    00202         buf[0] != SSL_HS_SERVER_HELLO ||
    00203         buf[4] != SSL_MAJOR_VERSION_3 )
    00204     {
    00205         SSL_DEBUG_MSG( 1, ( "bad server hello message" ) );
    00206         return( POLARSSL_ERR_SSL_BAD_HS_SERVER_HELLO );
    00207     }
    00208
    00209     if( buf[5] != SSL_MINOR_VERSION_0 &&
    00210         buf[5] != SSL_MINOR_VERSION_1 )
    00211     {
    00212         SSL_DEBUG_MSG( 1, ( "bad server hello message" ) );
    00213         return( POLARSSL_ERR_SSL_BAD_HS_SERVER_HELLO );
    00214     }
    00215
    00216     ssl->minor_ver = buf[5];
    00217
    00218     t = ( (time_t) buf[6] << 24 )
    00219       | ( (time_t) buf[7] << 16 )
    00220       | ( (time_t) buf[8] <<  8 )
    00221       | ( (time_t) buf[9]       );
    00222
    00223     memcpy( ssl->randbytes + 32, buf + 6, 32 );
    00224
    00225     n = buf[38];
    00226
    00227     SSL_DEBUG_MSG( 3, ( "server hello, current time: %lu", t ) );
    00228     SSL_DEBUG_BUF( 3,   "server hello, random bytes", buf + 6, 32 );
    00229
    00230     /*
    00231      *    38  .  38   session id length
    00232      *    39  . 38+n  session id
    00233      *   39+n . 40+n  chosen cipher
    00234      *   41+n . 41+n  chosen compression alg.
    00235      *   42+n . 43+n  extensions length
    00236      *   44+n . 44+n+m extensions
    00237      */
    00238     if( n < 0 || n > 32 || ssl->in_hslen > 42 + n )
    00239     {
    00240         ext_len = ( ( buf[42 + n] <<  8 )
    00241                   | ( buf[43 + n]       ) ) + 2;
    00242     }
    00243     else
    00244     {
    00245         ext_len = 0;
    00246     }
    00247
    00248     if( n < 0 || n > 32 || ssl->in_hslen != 42 + n + ext_len )
    00249     {
    00250         SSL_DEBUG_MSG( 1, ( "bad server hello message" ) );
    00251         return( POLARSSL_ERR_SSL_BAD_HS_SERVER_HELLO );
    00252     }
    00253
    00254     i = ( buf[39 + n] << 8 ) | buf[40 + n];
    00255
    00256     SSL_DEBUG_MSG( 3, ( "server hello, session id len.: %d", n ) );
    00257     SSL_DEBUG_BUF( 3,   "server hello, session id", buf + 39, n );
    00258
    00259     /*
    00260      * Check if the session can be resumed
    00261      */
    00262     if( ssl->resume == 0 || n == 0 ||
    00263         ssl->session->cipher  != i ||
    00264         ssl->session->length  != n ||
    00265         memcmp( ssl->session->id, buf + 39, n ) != 0 )
    00266     {
    00267         ssl->state++;
    00268         ssl->resume = 0;
    00269         ssl->session->start = time( NULL );
    00270         ssl->session->cipher = i;
    00271         ssl->session->length = n;
    00272         memcpy( ssl->session->id, buf + 39, n );
    00273     }
    00274     else
    00275     {
    00276         ssl->state = SSL_SERVER_CHANGE_CIPHER_SPEC;
    00277         ssl_derive_keys( ssl );
    00278     }
    00279
    00280     SSL_DEBUG_MSG( 3, ( "%s session has been resumed",
    00281                    ssl->resume ? "a" : "no" ) );
    00282
    00283     SSL_DEBUG_MSG( 3, ( "server hello, chosen cipher: %d", i ) );
    00284     SSL_DEBUG_MSG( 3, ( "server hello, compress alg.: %d", buf[41 + n] ) );
    00285
    00286     i = 0;
    00287     while( 1 )
    00288     {
    00289         if( ssl->ciphers[i] == 0 )
    00290         {
    00291             SSL_DEBUG_MSG( 1, ( "bad server hello message" ) );
    00292             return( POLARSSL_ERR_SSL_BAD_HS_SERVER_HELLO );
    00293         }
    00294
    00295         if( ssl->ciphers[i++] == ssl->session->cipher )
    00296             break;
    00297     }
    00298
    00299     if( buf[41 + n] != SSL_COMPRESS_NULL )
    00300     {
    00301         SSL_DEBUG_MSG( 1, ( "bad server hello message" ) );
    00302         return( POLARSSL_ERR_SSL_BAD_HS_SERVER_HELLO );
    00303     }
    00304
    00305     /* TODO: Process extensions */
    00306
    00307     SSL_DEBUG_MSG( 2, ( "<= parse server hello" ) );
    00308
    00309     return( 0 );
    00310 }
    00311
    00312 static int ssl_parse_server_key_exchange( ssl_context *ssl )
    00313 {
    00314     int ret, n;
    00315     unsigned char *p, *end;
    00316     unsigned char hash[36];
    00317     md5_context md5;
    00318     sha1_context sha1;
    00319
    00320     SSL_DEBUG_MSG( 2, ( "=> parse server key exchange" ) );
    00321
    00322     if( ssl->session->cipher != SSL_EDH_RSA_DES_168_SHA &&
    00323         ssl->session->cipher != SSL_EDH_RSA_AES_256_SHA &&
    00324     ssl->session->cipher != SSL_EDH_RSA_CAMELLIA_256_SHA)
    00325     {
    00326         SSL_DEBUG_MSG( 2, ( "<= skip parse server key exchange" ) );
    00327         ssl->state++;
    00328         return( 0 );
    00329     }
    00330
    00331 #if !defined(POLARSSL_DHM_C)
    00332     SSL_DEBUG_MSG( 1, ( "support for dhm in not available" ) );
    00333     return( POLARSSL_ERR_SSL_FEATURE_UNAVAILABLE );
    00334 #else
    00335     if( ( ret = ssl_read_record( ssl ) ) != 0 )
    00336     {
    00337         SSL_DEBUG_RET( 1, "ssl_read_record", ret );
    00338         return( ret );
    00339     }
    00340
    00341     if( ssl->in_msgtype != SSL_MSG_HANDSHAKE )
    00342     {
    00343         SSL_DEBUG_MSG( 1, ( "bad server key exchange message" ) );
    00344         return( POLARSSL_ERR_SSL_UNEXPECTED_MESSAGE );
    00345     }
    00346
    00347     if( ssl->in_msg[0] != SSL_HS_SERVER_KEY_EXCHANGE )
    00348     {
    00349         SSL_DEBUG_MSG( 1, ( "bad server key exchange message" ) );
    00350         return( POLARSSL_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE );
    00351     }
    00352
    00353     /*
    00354      * Ephemeral DH parameters:
    00355      *
    00356      * struct {
    00357      *     opaque dh_p<1..2^16-1>;
    00358      *     opaque dh_g<1..2^16-1>;
    00359      *     opaque dh_Ys<1..2^16-1>;
    00360      * } ServerDHParams;
    00361      */
    00362     p   = ssl->in_msg + 4;
    00363     end = ssl->in_msg + ssl->in_hslen;
    00364
    00365     if( ( ret = dhm_read_params( &ssl->dhm_ctx, &p, end ) ) != 0 )
    00366     {
    00367         SSL_DEBUG_MSG( 1, ( "bad server key exchange message" ) );
    00368         return( POLARSSL_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE );
    00369     }
    00370
    00371     if( (int)( end - p ) != ssl->peer_cert->rsa.len )
    00372     {
    00373         SSL_DEBUG_MSG( 1, ( "bad server key exchange message" ) );
    00374         return( POLARSSL_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE );
    00375     }
    00376
    00377     if( ssl->dhm_ctx.len < 64 || ssl->dhm_ctx.len > 256 )
    00378     {
    00379         SSL_DEBUG_MSG( 1, ( "bad server key exchange message" ) );
    00380         return( POLARSSL_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE );
    00381     }
    00382
    00383     SSL_DEBUG_MPI( 3, "DHM: P ", &ssl->dhm_ctx.P  );
    00384     SSL_DEBUG_MPI( 3, "DHM: G ", &ssl->dhm_ctx.G  );
    00385     SSL_DEBUG_MPI( 3, "DHM: GY", &ssl->dhm_ctx.GY );
    00386
    00387     /*
    00388      * digitally-signed struct {
    00389      *     opaque md5_hash[16];
    00390      *     opaque sha_hash[20];
    00391      * };
    00392      *
    00393      * md5_hash
    00394      *     MD5(ClientHello.random + ServerHello.random
    00395      *                            + ServerParams);
    00396      * sha_hash
    00397      *     SHA(ClientHello.random + ServerHello.random
    00398      *                            + ServerParams);
    00399      */
    00400     n = ssl->in_hslen - ( end - p ) - 6;
    00401
    00402     md5_starts( &md5 );
    00403     md5_update( &md5, ssl->randbytes, 64 );
    00404     md5_update( &md5, ssl->in_msg + 4, n );
    00405     md5_finish( &md5, hash );
    00406
    00407     sha1_starts( &sha1 );
    00408     sha1_update( &sha1, ssl->randbytes, 64 );
    00409     sha1_update( &sha1, ssl->in_msg + 4, n );
    00410     sha1_finish( &sha1, hash + 16 );
    00411
    00412     SSL_DEBUG_BUF( 3, "parameters hash", hash, 36 );
    00413
    00414     if( ( ret = rsa_pkcs1_verify( &ssl->peer_cert->rsa, RSA_PUBLIC,
    00415                                   SIG_RSA_RAW, 36, hash, p ) ) != 0 )
    00416     {
    00417         SSL_DEBUG_RET( 1, "rsa_pkcs1_verify", ret );
    00418         return( ret );
    00419     }
    00420
    00421     ssl->state++;
    00422
    00423     SSL_DEBUG_MSG( 2, ( "<= parse server key exchange" ) );
    00424
    00425     return( 0 );
    00426 #endif
    00427 }
    00428
    00429 static int ssl_parse_certificate_request( ssl_context *ssl )
    00430 {
    00431     int ret;
    00432
    00433     SSL_DEBUG_MSG( 2, ( "=> parse certificate request" ) );
    00434
    00435     /*
    00436      *     0  .   0   handshake type
    00437      *     1  .   3   handshake length
    00438      *     4  .   5   SSL version
    00439      *     6  .   6   cert type count
    00440      *     7  .. n-1  cert types
    00441      *     n  .. n+1  length of all DNs
    00442      *    n+2 .. n+3  length of DN 1
    00443      *    n+4 .. ...  Distinguished Name #1
    00444      *    ... .. ...  length of DN 2, etc.
    00445      */
    00446     if( ( ret = ssl_read_record( ssl ) ) != 0 )
    00447     {
    00448         SSL_DEBUG_RET( 1, "ssl_read_record", ret );
    00449         return( ret );
    00450     }
    00451
    00452     if( ssl->in_msgtype != SSL_MSG_HANDSHAKE )
    00453     {
    00454         SSL_DEBUG_MSG( 1, ( "bad certificate request message" ) );
    00455         return( POLARSSL_ERR_SSL_UNEXPECTED_MESSAGE );
    00456     }
    00457
    00458     ssl->client_auth = 0;
    00459     ssl->state++;
    00460
    00461     if( ssl->in_msg[0] == SSL_HS_CERTIFICATE_REQUEST )
    00462         ssl->client_auth++;
    00463
    00464     SSL_DEBUG_MSG( 3, ( "got %s certificate request",
    00465                         ssl->client_auth ? "a" : "no" ) );
    00466
    00467     SSL_DEBUG_MSG( 2, ( "<= parse certificate request" ) );
    00468
    00469     return( 0 );
    00470 }
    00471
    00472 static int ssl_parse_server_hello_done( ssl_context *ssl )
    00473 {
    00474     int ret;
    00475
    00476     SSL_DEBUG_MSG( 2, ( "=> parse server hello done" ) );
    00477
    00478     if( ssl->client_auth != 0 )
    00479     {
    00480         if( ( ret = ssl_read_record( ssl ) ) != 0 )
    00481         {
    00482             SSL_DEBUG_RET( 1, "ssl_read_record", ret );
    00483             return( ret );
    00484         }
    00485
    00486         if( ssl->in_msgtype != SSL_MSG_HANDSHAKE )
    00487         {
    00488             SSL_DEBUG_MSG( 1, ( "bad server hello done message" ) );
    00489             return( POLARSSL_ERR_SSL_UNEXPECTED_MESSAGE );
    00490         }
    00491     }
    00492
    00493     if( ssl->in_hslen  != 4 ||
    00494         ssl->in_msg[0] != SSL_HS_SERVER_HELLO_DONE )
    00495     {
    00496         SSL_DEBUG_MSG( 1, ( "bad server hello done message" ) );
    00497         return( POLARSSL_ERR_SSL_BAD_HS_SERVER_HELLO_DONE );
    00498     }
    00499
    00500     ssl->state++;
    00501
    00502     SSL_DEBUG_MSG( 2, ( "<= parse server hello done" ) );
    00503
    00504     return( 0 );
    00505 }
    00506
    00507 static int ssl_write_client_key_exchange( ssl_context *ssl )
    00508 {
    00509     int ret, i, n;
    00510
    00511     SSL_DEBUG_MSG( 2, ( "=> write client key exchange" ) );
    00512
    00513     if( ssl->session->cipher == SSL_EDH_RSA_DES_168_SHA ||
    00514         ssl->session->cipher == SSL_EDH_RSA_AES_256_SHA ||
    00515     ssl->session->cipher == SSL_EDH_RSA_CAMELLIA_256_SHA)
    00516     {
    00517 #if !defined(POLARSSL_DHM_C)
    00518         SSL_DEBUG_MSG( 1, ( "support for dhm in not available" ) );
    00519         return( POLARSSL_ERR_SSL_FEATURE_UNAVAILABLE );
    00520 #else
    00521         /*
    00522          * DHM key exchange -- send G^X mod P
    00523          */
    00524         n = ssl->dhm_ctx.len;
    00525
    00526         ssl->out_msg[4] = (unsigned char)( n >> 8 );
    00527         ssl->out_msg[5] = (unsigned char)( n      );
    00528         i = 6;
    00529
    00530         ret = dhm_make_public( &ssl->dhm_ctx, 256,
    00531                                &ssl->out_msg[i], n,
    00532                                 ssl->f_rng, ssl->p_rng );
    00533         if( ret != 0 )
    00534         {
    00535             SSL_DEBUG_RET( 1, "dhm_make_public", ret );
    00536             return( ret );
    00537         }
    00538
    00539         SSL_DEBUG_MPI( 3, "DHM: X ", &ssl->dhm_ctx.X  );
    00540         SSL_DEBUG_MPI( 3, "DHM: GX", &ssl->dhm_ctx.GX );
    00541
    00542         ssl->pmslen = ssl->dhm_ctx.len;
    00543
    00544         if( ( ret = dhm_calc_secret( &ssl->dhm_ctx,
    00545                                       ssl->premaster,
    00546                                      &ssl->pmslen ) ) != 0 )
    00547         {
    00548             SSL_DEBUG_RET( 1, "dhm_calc_secret", ret );
    00549             return( ret );
    00550         }
    00551
    00552         SSL_DEBUG_MPI( 3, "DHM: K ", &ssl->dhm_ctx.K  );
    00553 #endif
    00554     }
    00555     else
    00556     {
    00557         /*
    00558          * RSA key exchange -- send rsa_public(pkcs1 v1.5(premaster))
    00559          */
    00560         ssl->premaster[0] = (unsigned char) ssl->max_major_ver;
    00561         ssl->premaster[1] = (unsigned char) ssl->max_minor_ver;
    00562         ssl->pmslen = 48;
    00563
    00564         for( i = 2; i < ssl->pmslen; i++ )
    00565             ssl->premaster[i] = (unsigned char) ssl->f_rng( ssl->p_rng );
    00566
    00567         i = 4;
    00568         n = ssl->peer_cert->rsa.len;
    00569
    00570         if( ssl->minor_ver != SSL_MINOR_VERSION_0 )
    00571         {
    00572             i += 2;
    00573             ssl->out_msg[4] = (unsigned char)( n >> 8 );
    00574             ssl->out_msg[5] = (unsigned char)( n      );
    00575         }
    00576
    00577         ret = rsa_pkcs1_encrypt( &ssl->peer_cert->rsa, RSA_PUBLIC,
    00578                                   ssl->pmslen, ssl->premaster,
    00579                                   ssl->out_msg + i );
    00580         if( ret != 0 )
    00581         {
    00582             SSL_DEBUG_RET( 1, "rsa_pkcs1_encrypt", ret );
    00583             return( ret );
    00584         }
    00585     }
    00586
    00587     ssl_derive_keys( ssl );
    00588
    00589     ssl->out_msglen  = i + n;
    00590     ssl->out_msgtype = SSL_MSG_HANDSHAKE;
    00591     ssl->out_msg[0]  = SSL_HS_CLIENT_KEY_EXCHANGE;
    00592
    00593     ssl->state++;
    00594
    00595     if( ( ret = ssl_write_record( ssl ) ) != 0 )
    00596     {
    00597         SSL_DEBUG_RET( 1, "ssl_write_record", ret );
    00598         return( ret );
    00599     }
    00600
    00601     SSL_DEBUG_MSG( 2, ( "<= write client key exchange" ) );
    00602
    00603     return( 0 );
    00604 }
    00605
    00606 static int ssl_write_certificate_verify( ssl_context *ssl )
    00607 {
    00608     int ret, n;
    00609     unsigned char hash[36];
    00610
    00611     SSL_DEBUG_MSG( 2, ( "=> write certificate verify" ) );
    00612
    00613     if( ssl->client_auth == 0 )
    00614     {
    00615         SSL_DEBUG_MSG( 2, ( "<= skip write certificate verify" ) );
    00616         ssl->state++;
    00617         return( 0 );
    00618     }
    00619
    00620     if( ssl->rsa_key == NULL )
    00621     {
    00622         SSL_DEBUG_MSG( 1, ( "got no private key" ) );
    00623         return( POLARSSL_ERR_SSL_PRIVATE_KEY_REQUIRED );
    00624     }
    00625
    00626     /*
    00627      * Make an RSA signature of the handshake digests
    00628      */
    00629     ssl_calc_verify( ssl, hash );
    00630
    00631     n = ssl->rsa_key->len;
    00632     ssl->out_msg[4] = (unsigned char)( n >> 8 );
    00633     ssl->out_msg[5] = (unsigned char)( n      );
    00634
    00635     if( ( ret = rsa_pkcs1_sign( ssl->rsa_key, RSA_PRIVATE, SIG_RSA_RAW,
    00636                                 36, hash, ssl->out_msg + 6 ) ) != 0 )
    00637     {
    00638         SSL_DEBUG_RET( 1, "rsa_pkcs1_sign", ret );
    00639         return( ret );
    00640     }
    00641
    00642     ssl->out_msglen  = 6 + n;
    00643     ssl->out_msgtype = SSL_MSG_HANDSHAKE;
    00644     ssl->out_msg[0]  = SSL_HS_CERTIFICATE_VERIFY;
    00645
    00646     ssl->state++;
    00647
    00648     if( ( ret = ssl_write_record( ssl ) ) != 0 )
    00649     {
    00650         SSL_DEBUG_RET( 1, "ssl_write_record", ret );
    00651         return( ret );
    00652     }
    00653
    00654     SSL_DEBUG_MSG( 2, ( "<= write certificate verify" ) );
    00655
    00656     return( 0 );
    00657 }
    00658
    00659 /*
    00660  * SSL handshake -- client side
    00661  */
    00662 int ssl_handshake_client( ssl_context *ssl )
    00663 {
    00664     int ret = 0;
    00665
    00666     SSL_DEBUG_MSG( 2, ( "=> handshake client" ) );
    00667
    00668     while( ssl->state != SSL_HANDSHAKE_OVER )
    00669     {
    00670         SSL_DEBUG_MSG( 2, ( "client state: %d", ssl->state ) );
    00671
    00672         if( ( ret = ssl_flush_output( ssl ) ) != 0 )
    00673             break;
    00674
    00675         switch( ssl->state )
    00676         {
    00677             case SSL_HELLO_REQUEST:
    00678                 ssl->state = SSL_CLIENT_HELLO;
    00679                 break;
    00680
    00681             /*
    00682              *  ==>   ClientHello
    00683              */
    00684             case SSL_CLIENT_HELLO:
    00685                 ret = ssl_write_client_hello( ssl );
    00686                 break;
    00687
    00688             /*
    00689              *  <==   ServerHello
    00690              *        Certificate
    00691              *      ( ServerKeyExchange  )
    00692              *      ( CertificateRequest )
    00693              *        ServerHelloDone
    00694              */
    00695             case SSL_SERVER_HELLO:
    00696                 ret = ssl_parse_server_hello( ssl );
    00697                 break;
    00698
    00699             case SSL_SERVER_CERTIFICATE:
    00700                 ret = ssl_parse_certificate( ssl );
    00701                 break;
    00702
    00703             case SSL_SERVER_KEY_EXCHANGE:
    00704                 ret = ssl_parse_server_key_exchange( ssl );
    00705                 break;
    00706
    00707             case SSL_CERTIFICATE_REQUEST:
    00708                 ret = ssl_parse_certificate_request( ssl );
    00709                 break;
    00710
    00711             case SSL_SERVER_HELLO_DONE:
    00712                 ret = ssl_parse_server_hello_done( ssl );
    00713                 break;
    00714
    00715             /*
    00716              *  ==> ( Certificate/Alert  )
    00717              *        ClientKeyExchange
    00718              *      ( CertificateVerify  )
    00719              *        ChangeCipherSpec
    00720              *        Finished
    00721              */
    00722             case SSL_CLIENT_CERTIFICATE:
    00723                 ret = ssl_write_certificate( ssl );
    00724                 break;
    00725
    00726             case SSL_CLIENT_KEY_EXCHANGE:
    00727                 ret = ssl_write_client_key_exchange( ssl );
    00728                 break;
    00729
    00730             case SSL_CERTIFICATE_VERIFY:
    00731                 ret = ssl_write_certificate_verify( ssl );
    00732                 break;
    00733
    00734             case SSL_CLIENT_CHANGE_CIPHER_SPEC:
    00735                 ret = ssl_write_change_cipher_spec( ssl );
    00736                 break;
    00737
    00738             case SSL_CLIENT_FINISHED:
    00739                 ret = ssl_write_finished( ssl );
    00740                 break;
    00741
    00742             /*
    00743              *  <==   ChangeCipherSpec
    00744              *        Finished
    00745              */
    00746             case SSL_SERVER_CHANGE_CIPHER_SPEC:
    00747                 ret = ssl_parse_change_cipher_spec( ssl );
    00748                 break;
    00749
    00750             case SSL_SERVER_FINISHED:
    00751                 ret = ssl_parse_finished( ssl );
    00752                 break;
    00753
    00754             case SSL_FLUSH_BUFFERS:
    00755                 SSL_DEBUG_MSG( 2, ( "handshake: done" ) );
    00756                 ssl->state = SSL_HANDSHAKE_OVER;
    00757                 break;
    00758
    00759             default:
    00760                 SSL_DEBUG_MSG( 1, ( "invalid state %d", ssl->state ) );
    00761                 return( POLARSSL_ERR_SSL_BAD_INPUT_DATA );
    00762         }
    00763
    00764         if( ret != 0 )
    00765             break;
    00766     }
    00767
    00768     SSL_DEBUG_MSG( 2, ( "<= handshake client" ) );
    00769
    00770     return( ret );
    00771 }
    00772
    00773 #endif