00001 /* 00002 * SSLv3/TLSv1 client-side functions 00003 * 00004 * Copyright (C) 2006-2007 Christophe Devine 00005 * 00006 * This program is free software; you can redistribute it and/or modify 00007 * it under the terms of the GNU General Public License as published by 00008 * the Free Software Foundation; either version 2 of the License, or 00009 * (at your option) any later version. 00010 * 00011 * This program is distributed in the hope that it will be useful, 00012 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00013 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00014 * GNU General Public License for more details. 00015 * 00016 * You should have received a copy of the GNU General Public License along 00017 * with this program; if not, write to the Free Software Foundation, Inc., 00018 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 00019 */ 00020 00021 #include "xyssl/config.h" 00022 00023 #if defined(XYSSL_SSL_CLI_C) 00024 00025 #include "xyssl/debug.h" 00026 #include "xyssl/ssl.h" 00027 00028 #include <string.h> 00029 #include <stdlib.h> 00030 #include <stdio.h> 00031 #include <time.h> 00032 00033 static int ssl_write_client_hello( ssl_context *ssl ) 00034 { 00035 int ret, i, n; 00036 unsigned char *buf; 00037 unsigned char *p; 00038 time_t t; 00039 00040 SSL_DEBUG_MSG( 2, ( "=> write client hello" ) ); 00041 00042 ssl->major_ver = SSL_MAJOR_VERSION_3; 00043 ssl->minor_ver = SSL_MINOR_VERSION_0; 00044 00045 ssl->max_major_ver = SSL_MAJOR_VERSION_3; 00046 ssl->max_minor_ver = SSL_MINOR_VERSION_1; 00047 00048 /* 00049 * 0 . 0 handshake type 00050 * 1 . 3 handshake length 00051 * 4 . 5 highest version supported 00052 * 6 . 9 current UNIX time 00053 * 10 . 37 random bytes 00054 */ 00055 buf = ssl->out_msg; 00056 p = buf + 4; 00057 00058 *p++ = (unsigned char) ssl->max_major_ver; 00059 *p++ = (unsigned char) ssl->max_minor_ver; 00060 00061 SSL_DEBUG_MSG( 3, ( "client hello, max version: [%d:%d]", 00062 buf[4], buf[5] ) ); 00063 00064 t = time( NULL ); 00065 *p++ = (unsigned char)( t >> 24 ); 00066 *p++ = (unsigned char)( t >> 16 ); 00067 *p++ = (unsigned char)( t >> 8 ); 00068 *p++ = (unsigned char)( t ); 00069 00070 SSL_DEBUG_MSG( 3, ( "client hello, current time: %lu", t ) ); 00071 00072 for( i = 28; i > 0; i-- ) 00073 *p++ = (unsigned char) ssl->f_rng( ssl->p_rng ); 00074 00075 memcpy( ssl->randbytes, buf + 6, 32 ); 00076 00077 SSL_DEBUG_BUF( 3, "client hello, random bytes", buf + 6, 32 ); 00078 00079 /* 00080 * 38 . 38 session id length 00081 * 39 . 39+n session id 00082 * 40+n . 41+n cipherlist length 00083 * 42+n . .. cipherlist 00084 * .. . .. compression alg. (0) 00085 * .. . .. extensions (unused) 00086 */ 00087 n = ssl->session->length; 00088 00089 if( n < 16 || n > 32 || ssl->resume == 0 || 00090 t - ssl->session->start < ssl->timeout ) 00091 n = 0; 00092 00093 *p++ = (unsigned char) n; 00094 00095 for( i = 0; i < n; i++ ) 00096 *p++ = ssl->session->id[i]; 00097 00098 SSL_DEBUG_MSG( 3, ( "client hello, session id len.: %d", n ) ); 00099 SSL_DEBUG_BUF( 3, "client hello, session id", buf + 39, n ); 00100 00101 for( n = 0; ssl->ciphers[n] != 0; n++ ); 00102 *p++ = (unsigned char)( n >> 7 ); 00103 *p++ = (unsigned char)( n << 1 ); 00104 00105 SSL_DEBUG_MSG( 3, ( "client hello, got %d ciphers", n ) ); 00106 00107 for( i = 0; i < n; i++ ) 00108 { 00109 SSL_DEBUG_MSG( 3, ( "client hello, add cipher: %2d", 00110 ssl->ciphers[i] ) ); 00111 00112 *p++ = (unsigned char)( ssl->ciphers[i] >> 8 ); 00113 *p++ = (unsigned char)( ssl->ciphers[i] ); 00114 } 00115 00116 SSL_DEBUG_MSG( 3, ( "client hello, compress len.: %d", 1 ) ); 00117 SSL_DEBUG_MSG( 3, ( "client hello, compress alg.: %d", 0 ) ); 00118 00119 *p++ = 1; 00120 *p++ = SSL_COMPRESS_NULL; 00121 00122 if ( ssl->hostname != NULL ) { 00123 SSL_DEBUG_MSG( 3, ( "client hello, server name extension: %s", ssl->hostname ) ); 00124 00125 // Extensions length 00126 *p++ = (unsigned char)( ( ( ssl->hostname_len + 9 ) >> 8 ) & 0xff ); 00127 *p++ = (unsigned char)( ( ( ssl->hostname_len + 9 ) ) & 0xff ); 00128 00129 // Extension type 00130 *p++ = (unsigned char)( ( TLS_EXT_SERVERNAME >> 8 ) & 0xff ); 00131 *p++ = (unsigned char)( ( TLS_EXT_SERVERNAME ) & 0xff ); 00132 // Extension length 00133 *p++ = (unsigned char)( ( ( ssl->hostname_len + 5 ) >> 8 ) & 0xff ); 00134 *p++ = (unsigned char)( ( ( ssl->hostname_len + 5 ) ) & 0xff ); 00135 00136 // Server name list length 00137 *p++ = (unsigned char)( ( ( ssl->hostname_len + 3 ) >> 8 ) & 0xff ); 00138 *p++ = (unsigned char)( ( ( ssl->hostname_len + 3 ) ) & 0xff ); 00139 00140 // Name type 00141 *p++ = (unsigned char)( ( TLS_EXT_SERVERNAME_HOSTNAME ) & 0xff ); 00142 // Hostname length 00143 *p++ = (unsigned char)( ( ( ssl->hostname_len ) >> 8 ) & 0xff ); 00144 *p++ = (unsigned char)( ( ( ssl->hostname_len ) ) & 0xff ); 00145 // Hostname 00146 memcpy( p, ssl->hostname, ssl->hostname_len ); 00147 p += ssl->hostname_len; 00148 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( XYSSL_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( XYSSL_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( XYSSL_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( XYSSL_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 || 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( XYSSL_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( XYSSL_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 { 00325 SSL_DEBUG_MSG( 2, ( "<= skip parse server key exchange" ) ); 00326 ssl->state++; 00327 return( 0 ); 00328 } 00329 00330 #if !defined(XYSSL_DHM_C) 00331 SSL_DEBUG_MSG( 1, ( "support for dhm in not available" ) ); 00332 return( XYSSL_ERR_SSL_FEATURE_UNAVAILABLE ); 00333 #else 00334 if( ( ret = ssl_read_record( ssl ) ) != 0 ) 00335 { 00336 SSL_DEBUG_RET( 1, "ssl_read_record", ret ); 00337 return( ret ); 00338 } 00339 00340 if( ssl->in_msgtype != SSL_MSG_HANDSHAKE ) 00341 { 00342 SSL_DEBUG_MSG( 1, ( "bad server key exchange message" ) ); 00343 return( XYSSL_ERR_SSL_UNEXPECTED_MESSAGE ); 00344 } 00345 00346 if( ssl->in_msg[0] != SSL_HS_SERVER_KEY_EXCHANGE ) 00347 { 00348 SSL_DEBUG_MSG( 1, ( "bad server key exchange message" ) ); 00349 return( XYSSL_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE ); 00350 } 00351 00352 /* 00353 * Ephemeral DH parameters: 00354 * 00355 * struct { 00356 * opaque dh_p<1..2^16-1>; 00357 * opaque dh_g<1..2^16-1>; 00358 * opaque dh_Ys<1..2^16-1>; 00359 * } ServerDHParams; 00360 */ 00361 p = ssl->in_msg + 4; 00362 end = ssl->in_msg + ssl->in_hslen; 00363 00364 if( ( ret = dhm_read_params( &ssl->dhm_ctx, &p, end ) ) != 0 ) 00365 { 00366 SSL_DEBUG_MSG( 1, ( "bad server key exchange message" ) ); 00367 return( XYSSL_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE ); 00368 } 00369 00370 if( (int)( end - p ) != ssl->peer_cert->rsa.len ) 00371 { 00372 SSL_DEBUG_MSG( 1, ( "bad server key exchange message" ) ); 00373 return( XYSSL_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE ); 00374 } 00375 00376 if( ssl->dhm_ctx.len < 64 || ssl->dhm_ctx.len > 256 ) 00377 { 00378 SSL_DEBUG_MSG( 1, ( "bad server key exchange message" ) ); 00379 return( XYSSL_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE ); 00380 } 00381 00382 SSL_DEBUG_MPI( 3, "DHM: P ", &ssl->dhm_ctx.P ); 00383 SSL_DEBUG_MPI( 3, "DHM: G ", &ssl->dhm_ctx.G ); 00384 SSL_DEBUG_MPI( 3, "DHM: GY", &ssl->dhm_ctx.GY ); 00385 00386 /* 00387 * digitally-signed struct { 00388 * opaque md5_hash[16]; 00389 * opaque sha_hash[20]; 00390 * }; 00391 * 00392 * md5_hash 00393 * MD5(ClientHello.random + ServerHello.random 00394 * + ServerParams); 00395 * sha_hash 00396 * SHA(ClientHello.random + ServerHello.random 00397 * + ServerParams); 00398 */ 00399 n = ssl->in_hslen - ( end - p ) - 6; 00400 00401 md5_starts( &md5 ); 00402 md5_update( &md5, ssl->randbytes, 64 ); 00403 md5_update( &md5, ssl->in_msg + 4, n ); 00404 md5_finish( &md5, hash ); 00405 00406 sha1_starts( &sha1 ); 00407 sha1_update( &sha1, ssl->randbytes, 64 ); 00408 sha1_update( &sha1, ssl->in_msg + 4, n ); 00409 sha1_finish( &sha1, hash + 16 ); 00410 00411 SSL_DEBUG_BUF( 3, "parameters hash", hash, 36 ); 00412 00413 if( ( ret = rsa_pkcs1_verify( &ssl->peer_cert->rsa, RSA_PUBLIC, 00414 RSA_RAW, 36, hash, p ) ) != 0 ) 00415 { 00416 SSL_DEBUG_RET( 1, "rsa_pkcs1_verify", ret ); 00417 return( ret ); 00418 } 00419 00420 ssl->state++; 00421 00422 SSL_DEBUG_MSG( 2, ( "<= parse server key exchange" ) ); 00423 00424 return( 0 ); 00425 #endif 00426 } 00427 00428 static int ssl_parse_certificate_request( ssl_context *ssl ) 00429 { 00430 int ret; 00431 00432 SSL_DEBUG_MSG( 2, ( "=> parse certificate request" ) ); 00433 00434 /* 00435 * 0 . 0 handshake type 00436 * 1 . 3 handshake length 00437 * 4 . 5 SSL version 00438 * 6 . 6 cert type count 00439 * 7 .. n-1 cert types 00440 * n .. n+1 length of all DNs 00441 * n+2 .. n+3 length of DN 1 00442 * n+4 .. ... Distinguished Name #1 00443 * ... .. ... length of DN 2, etc. 00444 */ 00445 if( ( ret = ssl_read_record( ssl ) ) != 0 ) 00446 { 00447 SSL_DEBUG_RET( 1, "ssl_read_record", ret ); 00448 return( ret ); 00449 } 00450 00451 if( ssl->in_msgtype != SSL_MSG_HANDSHAKE ) 00452 { 00453 SSL_DEBUG_MSG( 1, ( "bad certificate request message" ) ); 00454 return( XYSSL_ERR_SSL_UNEXPECTED_MESSAGE ); 00455 } 00456 00457 ssl->client_auth = 0; 00458 ssl->state++; 00459 00460 if( ssl->in_msg[0] == SSL_HS_CERTIFICATE_REQUEST ) 00461 ssl->client_auth++; 00462 00463 SSL_DEBUG_MSG( 3, ( "got %s certificate request", 00464 ssl->client_auth ? "a" : "no" ) ); 00465 00466 SSL_DEBUG_MSG( 2, ( "<= parse certificate request" ) ); 00467 00468 return( 0 ); 00469 } 00470 00471 static int ssl_parse_server_hello_done( ssl_context *ssl ) 00472 { 00473 int ret; 00474 00475 SSL_DEBUG_MSG( 2, ( "=> parse server hello done" ) ); 00476 00477 if( ssl->client_auth != 0 ) 00478 { 00479 if( ( ret = ssl_read_record( ssl ) ) != 0 ) 00480 { 00481 SSL_DEBUG_RET( 1, "ssl_read_record", ret ); 00482 return( ret ); 00483 } 00484 00485 if( ssl->in_msgtype != SSL_MSG_HANDSHAKE ) 00486 { 00487 SSL_DEBUG_MSG( 1, ( "bad server hello done message" ) ); 00488 return( XYSSL_ERR_SSL_UNEXPECTED_MESSAGE ); 00489 } 00490 } 00491 00492 if( ssl->in_hslen != 4 || 00493 ssl->in_msg[0] != SSL_HS_SERVER_HELLO_DONE ) 00494 { 00495 SSL_DEBUG_MSG( 1, ( "bad server hello done message" ) ); 00496 return( XYSSL_ERR_SSL_BAD_HS_SERVER_HELLO_DONE ); 00497 } 00498 00499 ssl->state++; 00500 00501 SSL_DEBUG_MSG( 2, ( "<= parse server hello done" ) ); 00502 00503 return( 0 ); 00504 } 00505 00506 static int ssl_write_client_key_exchange( ssl_context *ssl ) 00507 { 00508 int ret, i, n; 00509 00510 SSL_DEBUG_MSG( 2, ( "=> write client key exchange" ) ); 00511 00512 if( ssl->session->cipher == SSL_EDH_RSA_DES_168_SHA || 00513 ssl->session->cipher == SSL_EDH_RSA_AES_256_SHA ) 00514 { 00515 #if !defined(XYSSL_DHM_C) 00516 SSL_DEBUG_MSG( 1, ( "support for dhm in not available" ) ); 00517 return( XYSSL_ERR_SSL_FEATURE_UNAVAILABLE ); 00518 #else 00519 /* 00520 * DHM key exchange -- send G^X mod P 00521 */ 00522 n = ssl->dhm_ctx.len; 00523 00524 ssl->out_msg[4] = (unsigned char)( n >> 8 ); 00525 ssl->out_msg[5] = (unsigned char)( n ); 00526 i = 6; 00527 00528 ret = dhm_make_public( &ssl->dhm_ctx, 256, 00529 &ssl->out_msg[i], n, 00530 ssl->f_rng, ssl->p_rng ); 00531 if( ret != 0 ) 00532 { 00533 SSL_DEBUG_RET( 1, "dhm_make_public", ret ); 00534 return( ret ); 00535 } 00536 00537 SSL_DEBUG_MPI( 3, "DHM: X ", &ssl->dhm_ctx.X ); 00538 SSL_DEBUG_MPI( 3, "DHM: GX", &ssl->dhm_ctx.GX ); 00539 00540 ssl->pmslen = ssl->dhm_ctx.len; 00541 00542 if( ( ret = dhm_calc_secret( &ssl->dhm_ctx, 00543 ssl->premaster, 00544 &ssl->pmslen ) ) != 0 ) 00545 { 00546 SSL_DEBUG_RET( 1, "dhm_calc_secret", ret ); 00547 return( ret ); 00548 } 00549 00550 SSL_DEBUG_MPI( 3, "DHM: K ", &ssl->dhm_ctx.K ); 00551 #endif 00552 } 00553 else 00554 { 00555 /* 00556 * RSA key exchange -- send rsa_public(pkcs1 v1.5(premaster)) 00557 */ 00558 ssl->premaster[0] = (unsigned char) ssl->max_major_ver; 00559 ssl->premaster[1] = (unsigned char) ssl->max_minor_ver; 00560 ssl->pmslen = 48; 00561 00562 for( i = 2; i < ssl->pmslen; i++ ) 00563 ssl->premaster[i] = (unsigned char) ssl->f_rng( ssl->p_rng ); 00564 00565 i = 4; 00566 n = ssl->peer_cert->rsa.len; 00567 00568 if( ssl->minor_ver != SSL_MINOR_VERSION_0 ) 00569 { 00570 i += 2; 00571 ssl->out_msg[4] = (unsigned char)( n >> 8 ); 00572 ssl->out_msg[5] = (unsigned char)( n ); 00573 } 00574 00575 ret = rsa_pkcs1_encrypt( &ssl->peer_cert->rsa, RSA_PUBLIC, 00576 ssl->pmslen, ssl->premaster, 00577 ssl->out_msg + i ); 00578 if( ret != 0 ) 00579 { 00580 SSL_DEBUG_RET( 1, "rsa_pkcs1_encrypt", ret ); 00581 return( ret ); 00582 } 00583 } 00584 00585 ssl_derive_keys( ssl ); 00586 00587 ssl->out_msglen = i + n; 00588 ssl->out_msgtype = SSL_MSG_HANDSHAKE; 00589 ssl->out_msg[0] = SSL_HS_CLIENT_KEY_EXCHANGE; 00590 00591 ssl->state++; 00592 00593 if( ( ret = ssl_write_record( ssl ) ) != 0 ) 00594 { 00595 SSL_DEBUG_RET( 1, "ssl_write_record", ret ); 00596 return( ret ); 00597 } 00598 00599 SSL_DEBUG_MSG( 2, ( "<= write client key exchange" ) ); 00600 00601 return( 0 ); 00602 } 00603 00604 static int ssl_write_certificate_verify( ssl_context *ssl ) 00605 { 00606 int ret, n; 00607 unsigned char hash[36]; 00608 00609 SSL_DEBUG_MSG( 2, ( "=> write certificate verify" ) ); 00610 00611 if( ssl->client_auth == 0 ) 00612 { 00613 SSL_DEBUG_MSG( 2, ( "<= skip write certificate verify" ) ); 00614 ssl->state++; 00615 return( 0 ); 00616 } 00617 00618 if( ssl->rsa_key == NULL ) 00619 { 00620 SSL_DEBUG_MSG( 1, ( "got no private key" ) ); 00621 return( XYSSL_ERR_SSL_PRIVATE_KEY_REQUIRED ); 00622 } 00623 00624 /* 00625 * Make an RSA signature of the handshake digests 00626 */ 00627 ssl_calc_verify( ssl, hash ); 00628 00629 n = ssl->rsa_key->len; 00630 ssl->out_msg[4] = (unsigned char)( n >> 8 ); 00631 ssl->out_msg[5] = (unsigned char)( n ); 00632 00633 if( ( ret = rsa_pkcs1_sign( ssl->rsa_key, RSA_PRIVATE, RSA_RAW, 00634 36, hash, ssl->out_msg + 6 ) ) != 0 ) 00635 { 00636 SSL_DEBUG_RET( 1, "rsa_pkcs1_sign", ret ); 00637 return( ret ); 00638 } 00639 00640 ssl->out_msglen = 6 + n; 00641 ssl->out_msgtype = SSL_MSG_HANDSHAKE; 00642 ssl->out_msg[0] = SSL_HS_CERTIFICATE_VERIFY; 00643 00644 ssl->state++; 00645 00646 if( ( ret = ssl_write_record( ssl ) ) != 0 ) 00647 { 00648 SSL_DEBUG_RET( 1, "ssl_write_record", ret ); 00649 return( ret ); 00650 } 00651 00652 SSL_DEBUG_MSG( 2, ( "<= write certificate verify" ) ); 00653 00654 return( 0 ); 00655 } 00656 00657 /* 00658 * SSL handshake -- client side 00659 */ 00660 int ssl_handshake_client( ssl_context *ssl ) 00661 { 00662 int ret = 0; 00663 00664 SSL_DEBUG_MSG( 2, ( "=> handshake client" ) ); 00665 00666 while( ssl->state != SSL_HANDSHAKE_OVER ) 00667 { 00668 SSL_DEBUG_MSG( 2, ( "client state: %d", ssl->state ) ); 00669 00670 if( ( ret = ssl_flush_output( ssl ) ) != 0 ) 00671 break; 00672 00673 switch( ssl->state ) 00674 { 00675 case SSL_HELLO_REQUEST: 00676 ssl->state = SSL_CLIENT_HELLO; 00677 break; 00678 00679 /* 00680 * ==> ClientHello 00681 */ 00682 case SSL_CLIENT_HELLO: 00683 ret = ssl_write_client_hello( ssl ); 00684 break; 00685 00686 /* 00687 * <== ServerHello 00688 * Certificate 00689 * ( ServerKeyExchange ) 00690 * ( CertificateRequest ) 00691 * ServerHelloDone 00692 */ 00693 case SSL_SERVER_HELLO: 00694 ret = ssl_parse_server_hello( ssl ); 00695 break; 00696 00697 case SSL_SERVER_CERTIFICATE: 00698 ret = ssl_parse_certificate( ssl ); 00699 break; 00700 00701 case SSL_SERVER_KEY_EXCHANGE: 00702 ret = ssl_parse_server_key_exchange( ssl ); 00703 break; 00704 00705 case SSL_CERTIFICATE_REQUEST: 00706 ret = ssl_parse_certificate_request( ssl ); 00707 break; 00708 00709 case SSL_SERVER_HELLO_DONE: 00710 ret = ssl_parse_server_hello_done( ssl ); 00711 break; 00712 00713 /* 00714 * ==> ( Certificate/Alert ) 00715 * ClientKeyExchange 00716 * ( CertificateVerify ) 00717 * ChangeCipherSpec 00718 * Finished 00719 */ 00720 case SSL_CLIENT_CERTIFICATE: 00721 ret = ssl_write_certificate( ssl ); 00722 break; 00723 00724 case SSL_CLIENT_KEY_EXCHANGE: 00725 ret = ssl_write_client_key_exchange( ssl ); 00726 break; 00727 00728 case SSL_CERTIFICATE_VERIFY: 00729 ret = ssl_write_certificate_verify( ssl ); 00730 break; 00731 00732 case SSL_CLIENT_CHANGE_CIPHER_SPEC: 00733 ret = ssl_write_change_cipher_spec( ssl ); 00734 break; 00735 00736 case SSL_CLIENT_FINISHED: 00737 ret = ssl_write_finished( ssl ); 00738 break; 00739 00740 /* 00741 * <== ChangeCipherSpec 00742 * Finished 00743 */ 00744 case SSL_SERVER_CHANGE_CIPHER_SPEC: 00745 ret = ssl_parse_change_cipher_spec( ssl ); 00746 break; 00747 00748 case SSL_SERVER_FINISHED: 00749 ret = ssl_parse_finished( ssl ); 00750 break; 00751 00752 case SSL_FLUSH_BUFFERS: 00753 SSL_DEBUG_MSG( 2, ( "handshake: done" ) ); 00754 ssl->state = SSL_HANDSHAKE_OVER; 00755 break; 00756 00757 default: 00758 SSL_DEBUG_MSG( 1, ( "invalid state %d", ssl->state ) ); 00759 return( XYSSL_ERR_SSL_BAD_INPUT_DATA ); 00760 } 00761 00762 if( ret != 0 ) 00763 break; 00764 } 00765 00766 SSL_DEBUG_MSG( 2, ( "<= handshake client" ) ); 00767 00768 return( ret ); 00769 } 00770 00771 #endif