2 * SSLv3/TLSv1 client-side functions
4 * Copyright (C) 2006-2007 Christophe Devine
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License along
17 * with this program; if not, write to the Free Software Foundation, Inc.,
18 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
21 #include "xyssl/config.h"
23 #if defined(XYSSL_SSL_CLI_C)
25 #include "xyssl/debug.h"
26 #include "xyssl/ssl.h"
33 static int ssl_write_client_hello( ssl_context
*ssl
)
40 SSL_DEBUG_MSG( 2, ( "=> write client hello" ) );
42 ssl
->major_ver
= SSL_MAJOR_VERSION_3
;
43 ssl
->minor_ver
= SSL_MINOR_VERSION_0
;
45 ssl
->max_major_ver
= SSL_MAJOR_VERSION_3
;
46 ssl
->max_minor_ver
= SSL_MINOR_VERSION_1
;
49 * 0 . 0 handshake type
50 * 1 . 3 handshake length
51 * 4 . 5 highest version supported
52 * 6 . 9 current UNIX time
53 * 10 . 37 random bytes
58 *p
++ = (unsigned char) ssl
->max_major_ver
;
59 *p
++ = (unsigned char) ssl
->max_minor_ver
;
61 SSL_DEBUG_MSG( 3, ( "client hello, max version: [%d:%d]",
65 *p
++ = (unsigned char)( t
>> 24 );
66 *p
++ = (unsigned char)( t
>> 16 );
67 *p
++ = (unsigned char)( t
>> 8 );
68 *p
++ = (unsigned char)( t
);
70 SSL_DEBUG_MSG( 3, ( "client hello, current time: %lu", t
) );
72 for( i
= 28; i
> 0; i
-- )
73 *p
++ = (unsigned char) ssl
->f_rng( ssl
->p_rng
);
75 memcpy( ssl
->randbytes
, buf
+ 6, 32 );
77 SSL_DEBUG_BUF( 3, "client hello, random bytes", buf
+ 6, 32 );
80 * 38 . 38 session id length
81 * 39 . 39+n session id
82 * 40+n . 41+n cipherlist length
83 * 42+n . .. cipherlist
84 * .. . .. compression alg. (0)
85 * .. . .. extensions (unused)
87 n
= ssl
->session
->length
;
89 if( n
< 16 || n
> 32 || ssl
->resume
== 0 ||
90 t
- ssl
->session
->start
< ssl
->timeout
)
93 *p
++ = (unsigned char) n
;
95 for( i
= 0; i
< n
; i
++ )
96 *p
++ = ssl
->session
->id
[i
];
98 SSL_DEBUG_MSG( 3, ( "client hello, session id len.: %d", n
) );
99 SSL_DEBUG_BUF( 3, "client hello, session id", buf
+ 39, n
);
101 for( n
= 0; ssl
->ciphers
[n
] != 0; n
++ );
102 *p
++ = (unsigned char)( n
>> 7 );
103 *p
++ = (unsigned char)( n
<< 1 );
105 SSL_DEBUG_MSG( 3, ( "client hello, got %d ciphers", n
) );
107 for( i
= 0; i
< n
; i
++ )
109 SSL_DEBUG_MSG( 3, ( "client hello, add cipher: %2d",
112 *p
++ = (unsigned char)( ssl
->ciphers
[i
] >> 8 );
113 *p
++ = (unsigned char)( ssl
->ciphers
[i
] );
116 SSL_DEBUG_MSG( 3, ( "client hello, compress len.: %d", 1 ) );
117 SSL_DEBUG_MSG( 3, ( "client hello, compress alg.: %d", 0 ) );
120 *p
++ = SSL_COMPRESS_NULL
;
122 if ( ssl
->hostname
!= NULL
) {
123 SSL_DEBUG_MSG( 3, ( "client hello, server name extension: %s", ssl
->hostname
) );
126 *p
++ = (unsigned char)( ( ( ssl
->hostname_len
+ 9 ) >> 8 ) & 0xff );
127 *p
++ = (unsigned char)( ( ( ssl
->hostname_len
+ 9 ) ) & 0xff );
130 *p
++ = (unsigned char)( ( TLS_EXT_SERVERNAME
>> 8 ) & 0xff );
131 *p
++ = (unsigned char)( ( TLS_EXT_SERVERNAME
) & 0xff );
133 *p
++ = (unsigned char)( ( ( ssl
->hostname_len
+ 5 ) >> 8 ) & 0xff );
134 *p
++ = (unsigned char)( ( ( ssl
->hostname_len
+ 5 ) ) & 0xff );
136 // Server name list length
137 *p
++ = (unsigned char)( ( ( ssl
->hostname_len
+ 3 ) >> 8 ) & 0xff );
138 *p
++ = (unsigned char)( ( ( ssl
->hostname_len
+ 3 ) ) & 0xff );
141 *p
++ = (unsigned char)( ( TLS_EXT_SERVERNAME_HOSTNAME
) & 0xff );
143 *p
++ = (unsigned char)( ( ( ssl
->hostname_len
) >> 8 ) & 0xff );
144 *p
++ = (unsigned char)( ( ( ssl
->hostname_len
) ) & 0xff );
146 memcpy( p
, ssl
->hostname
, ssl
->hostname_len
);
147 p
+= ssl
->hostname_len
;
151 ssl
->out_msglen
= p
- buf
;
152 ssl
->out_msgtype
= SSL_MSG_HANDSHAKE
;
153 ssl
->out_msg
[0] = SSL_HS_CLIENT_HELLO
;
157 if( ( ret
= ssl_write_record( ssl
) ) != 0 )
159 SSL_DEBUG_RET( 1, "ssl_write_record", ret
);
163 SSL_DEBUG_MSG( 2, ( "<= write client hello" ) );
168 static int ssl_parse_server_hello( ssl_context
*ssl
)
175 SSL_DEBUG_MSG( 2, ( "=> parse server hello" ) );
178 * 0 . 0 handshake type
179 * 1 . 3 handshake length
180 * 4 . 5 protocol version
182 * 10 . 37 random bytes
186 if( ( ret
= ssl_read_record( ssl
) ) != 0 )
188 SSL_DEBUG_RET( 1, "ssl_read_record", ret
);
192 if( ssl
->in_msgtype
!= SSL_MSG_HANDSHAKE
)
194 SSL_DEBUG_MSG( 1, ( "bad server hello message" ) );
195 return( XYSSL_ERR_SSL_UNEXPECTED_MESSAGE
);
198 SSL_DEBUG_MSG( 3, ( "server hello, chosen version: [%d:%d]",
201 if( ssl
->in_hslen
< 42 ||
202 buf
[0] != SSL_HS_SERVER_HELLO
||
203 buf
[4] != SSL_MAJOR_VERSION_3
)
205 SSL_DEBUG_MSG( 1, ( "bad server hello message" ) );
206 return( XYSSL_ERR_SSL_BAD_HS_SERVER_HELLO
);
209 if( buf
[5] != SSL_MINOR_VERSION_0
&&
210 buf
[5] != SSL_MINOR_VERSION_1
)
212 SSL_DEBUG_MSG( 1, ( "bad server hello message" ) );
213 return( XYSSL_ERR_SSL_BAD_HS_SERVER_HELLO
);
216 ssl
->minor_ver
= buf
[5];
218 t
= ( (time_t) buf
[6] << 24 )
219 | ( (time_t) buf
[7] << 16 )
220 | ( (time_t) buf
[8] << 8 )
221 | ( (time_t) buf
[9] );
223 memcpy( ssl
->randbytes
+ 32, buf
+ 6, 32 );
227 SSL_DEBUG_MSG( 3, ( "server hello, current time: %lu", t
) );
228 SSL_DEBUG_BUF( 3, "server hello, random bytes", buf
+ 6, 32 );
231 * 38 . 38 session id length
232 * 39 . 38+n session id
233 * 39+n . 40+n chosen cipher
234 * 41+n . 41+n chosen compression alg.
235 * 42+n . 43+n extensions length
236 * 44+n . 44+n+m extensions
238 if( n
< 0 || n
> 32 || ssl
->in_hslen
> 42 + n
)
240 ext_len
= ( ( buf
[42 + n
] << 8 )
241 | ( buf
[43 + n
] ) ) + 2;
248 if( n
< 0 || n
> 32 || ssl
->in_hslen
!= 42 + n
+ ext_len
)
250 SSL_DEBUG_MSG( 1, ( "bad server hello message" ) );
251 return( XYSSL_ERR_SSL_BAD_HS_SERVER_HELLO
);
254 i
= ( buf
[39 + n
] << 8 ) | buf
[40 + n
];
256 SSL_DEBUG_MSG( 3, ( "server hello, session id len.: %d", n
) );
257 SSL_DEBUG_BUF( 3, "server hello, session id", buf
+ 39, n
);
260 * Check if the session can be resumed
262 if( ssl
->resume
== 0 ||
263 ssl
->session
->cipher
!= i
||
264 ssl
->session
->length
!= n
||
265 memcmp( ssl
->session
->id
, buf
+ 39, n
) != 0 )
269 ssl
->session
->start
= time( NULL
);
270 ssl
->session
->cipher
= i
;
271 ssl
->session
->length
= n
;
272 memcpy( ssl
->session
->id
, buf
+ 39, n
);
276 ssl
->state
= SSL_SERVER_CHANGE_CIPHER_SPEC
;
277 ssl_derive_keys( ssl
);
280 SSL_DEBUG_MSG( 3, ( "%s session has been resumed",
281 ssl
->resume
? "a" : "no" ) );
283 SSL_DEBUG_MSG( 3, ( "server hello, chosen cipher: %d", i
) );
284 SSL_DEBUG_MSG( 3, ( "server hello, compress alg.: %d", buf
[41 + n
] ) );
289 if( ssl
->ciphers
[i
] == 0 )
291 SSL_DEBUG_MSG( 1, ( "bad server hello message" ) );
292 return( XYSSL_ERR_SSL_BAD_HS_SERVER_HELLO
);
295 if( ssl
->ciphers
[i
++] == ssl
->session
->cipher
)
299 if( buf
[41 + n
] != SSL_COMPRESS_NULL
)
301 SSL_DEBUG_MSG( 1, ( "bad server hello message" ) );
302 return( XYSSL_ERR_SSL_BAD_HS_SERVER_HELLO
);
305 // TODO: Process extensions
307 SSL_DEBUG_MSG( 2, ( "<= parse server hello" ) );
312 static int ssl_parse_server_key_exchange( ssl_context
*ssl
)
315 unsigned char *p
, *end
;
316 unsigned char hash
[36];
320 SSL_DEBUG_MSG( 2, ( "=> parse server key exchange" ) );
322 if( ssl
->session
->cipher
!= SSL_EDH_RSA_DES_168_SHA
&&
323 ssl
->session
->cipher
!= SSL_EDH_RSA_AES_256_SHA
)
325 SSL_DEBUG_MSG( 2, ( "<= skip parse server key exchange" ) );
330 #if !defined(XYSSL_DHM_C)
331 SSL_DEBUG_MSG( 1, ( "support for dhm in not available" ) );
332 return( XYSSL_ERR_SSL_FEATURE_UNAVAILABLE
);
334 if( ( ret
= ssl_read_record( ssl
) ) != 0 )
336 SSL_DEBUG_RET( 1, "ssl_read_record", ret
);
340 if( ssl
->in_msgtype
!= SSL_MSG_HANDSHAKE
)
342 SSL_DEBUG_MSG( 1, ( "bad server key exchange message" ) );
343 return( XYSSL_ERR_SSL_UNEXPECTED_MESSAGE
);
346 if( ssl
->in_msg
[0] != SSL_HS_SERVER_KEY_EXCHANGE
)
348 SSL_DEBUG_MSG( 1, ( "bad server key exchange message" ) );
349 return( XYSSL_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE
);
353 * Ephemeral DH parameters:
356 * opaque dh_p<1..2^16-1>;
357 * opaque dh_g<1..2^16-1>;
358 * opaque dh_Ys<1..2^16-1>;
362 end
= ssl
->in_msg
+ ssl
->in_hslen
;
364 if( ( ret
= dhm_read_params( &ssl
->dhm_ctx
, &p
, end
) ) != 0 )
366 SSL_DEBUG_MSG( 1, ( "bad server key exchange message" ) );
367 return( XYSSL_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE
);
370 if( (int)( end
- p
) != ssl
->peer_cert
->rsa
.len
)
372 SSL_DEBUG_MSG( 1, ( "bad server key exchange message" ) );
373 return( XYSSL_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE
);
376 if( ssl
->dhm_ctx
.len
< 64 || ssl
->dhm_ctx
.len
> 256 )
378 SSL_DEBUG_MSG( 1, ( "bad server key exchange message" ) );
379 return( XYSSL_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE
);
382 SSL_DEBUG_MPI( 3, "DHM: P ", &ssl
->dhm_ctx
.P
);
383 SSL_DEBUG_MPI( 3, "DHM: G ", &ssl
->dhm_ctx
.G
);
384 SSL_DEBUG_MPI( 3, "DHM: GY", &ssl
->dhm_ctx
.GY
);
387 * digitally-signed struct {
388 * opaque md5_hash[16];
389 * opaque sha_hash[20];
393 * MD5(ClientHello.random + ServerHello.random
396 * SHA(ClientHello.random + ServerHello.random
399 n
= ssl
->in_hslen
- ( end
- p
) - 6;
402 md5_update( &md5
, ssl
->randbytes
, 64 );
403 md5_update( &md5
, ssl
->in_msg
+ 4, n
);
404 md5_finish( &md5
, hash
);
406 sha1_starts( &sha1
);
407 sha1_update( &sha1
, ssl
->randbytes
, 64 );
408 sha1_update( &sha1
, ssl
->in_msg
+ 4, n
);
409 sha1_finish( &sha1
, hash
+ 16 );
411 SSL_DEBUG_BUF( 3, "parameters hash", hash
, 36 );
413 if( ( ret
= rsa_pkcs1_verify( &ssl
->peer_cert
->rsa
, RSA_PUBLIC
,
414 RSA_RAW
, 36, hash
, p
) ) != 0 )
416 SSL_DEBUG_RET( 1, "rsa_pkcs1_verify", ret
);
422 SSL_DEBUG_MSG( 2, ( "<= parse server key exchange" ) );
428 static int ssl_parse_certificate_request( ssl_context
*ssl
)
432 SSL_DEBUG_MSG( 2, ( "=> parse certificate request" ) );
435 * 0 . 0 handshake type
436 * 1 . 3 handshake length
438 * 6 . 6 cert type count
439 * 7 .. n-1 cert types
440 * n .. n+1 length of all DNs
441 * n+2 .. n+3 length of DN 1
442 * n+4 .. ... Distinguished Name #1
443 * ... .. ... length of DN 2, etc.
445 if( ( ret
= ssl_read_record( ssl
) ) != 0 )
447 SSL_DEBUG_RET( 1, "ssl_read_record", ret
);
451 if( ssl
->in_msgtype
!= SSL_MSG_HANDSHAKE
)
453 SSL_DEBUG_MSG( 1, ( "bad certificate request message" ) );
454 return( XYSSL_ERR_SSL_UNEXPECTED_MESSAGE
);
457 ssl
->client_auth
= 0;
460 if( ssl
->in_msg
[0] == SSL_HS_CERTIFICATE_REQUEST
)
463 SSL_DEBUG_MSG( 3, ( "got %s certificate request",
464 ssl
->client_auth
? "a" : "no" ) );
466 SSL_DEBUG_MSG( 2, ( "<= parse certificate request" ) );
471 static int ssl_parse_server_hello_done( ssl_context
*ssl
)
475 SSL_DEBUG_MSG( 2, ( "=> parse server hello done" ) );
477 if( ssl
->client_auth
!= 0 )
479 if( ( ret
= ssl_read_record( ssl
) ) != 0 )
481 SSL_DEBUG_RET( 1, "ssl_read_record", ret
);
485 if( ssl
->in_msgtype
!= SSL_MSG_HANDSHAKE
)
487 SSL_DEBUG_MSG( 1, ( "bad server hello done message" ) );
488 return( XYSSL_ERR_SSL_UNEXPECTED_MESSAGE
);
492 if( ssl
->in_hslen
!= 4 ||
493 ssl
->in_msg
[0] != SSL_HS_SERVER_HELLO_DONE
)
495 SSL_DEBUG_MSG( 1, ( "bad server hello done message" ) );
496 return( XYSSL_ERR_SSL_BAD_HS_SERVER_HELLO_DONE
);
501 SSL_DEBUG_MSG( 2, ( "<= parse server hello done" ) );
506 static int ssl_write_client_key_exchange( ssl_context
*ssl
)
510 SSL_DEBUG_MSG( 2, ( "=> write client key exchange" ) );
512 if( ssl
->session
->cipher
== SSL_EDH_RSA_DES_168_SHA
||
513 ssl
->session
->cipher
== SSL_EDH_RSA_AES_256_SHA
)
515 #if !defined(XYSSL_DHM_C)
516 SSL_DEBUG_MSG( 1, ( "support for dhm in not available" ) );
517 return( XYSSL_ERR_SSL_FEATURE_UNAVAILABLE
);
520 * DHM key exchange -- send G^X mod P
522 n
= ssl
->dhm_ctx
.len
;
524 ssl
->out_msg
[4] = (unsigned char)( n
>> 8 );
525 ssl
->out_msg
[5] = (unsigned char)( n
);
528 ret
= dhm_make_public( &ssl
->dhm_ctx
, 256,
530 ssl
->f_rng
, ssl
->p_rng
);
533 SSL_DEBUG_RET( 1, "dhm_make_public", ret
);
537 SSL_DEBUG_MPI( 3, "DHM: X ", &ssl
->dhm_ctx
.X
);
538 SSL_DEBUG_MPI( 3, "DHM: GX", &ssl
->dhm_ctx
.GX
);
540 ssl
->pmslen
= ssl
->dhm_ctx
.len
;
542 if( ( ret
= dhm_calc_secret( &ssl
->dhm_ctx
,
544 &ssl
->pmslen
) ) != 0 )
546 SSL_DEBUG_RET( 1, "dhm_calc_secret", ret
);
550 SSL_DEBUG_MPI( 3, "DHM: K ", &ssl
->dhm_ctx
.K
);
556 * RSA key exchange -- send rsa_public(pkcs1 v1.5(premaster))
558 ssl
->premaster
[0] = (unsigned char) ssl
->max_major_ver
;
559 ssl
->premaster
[1] = (unsigned char) ssl
->max_minor_ver
;
562 for( i
= 2; i
< ssl
->pmslen
; i
++ )
563 ssl
->premaster
[i
] = (unsigned char) ssl
->f_rng( ssl
->p_rng
);
566 n
= ssl
->peer_cert
->rsa
.len
;
568 if( ssl
->minor_ver
!= SSL_MINOR_VERSION_0
)
571 ssl
->out_msg
[4] = (unsigned char)( n
>> 8 );
572 ssl
->out_msg
[5] = (unsigned char)( n
);
575 ret
= rsa_pkcs1_encrypt( &ssl
->peer_cert
->rsa
, RSA_PUBLIC
,
576 ssl
->pmslen
, ssl
->premaster
,
580 SSL_DEBUG_RET( 1, "rsa_pkcs1_encrypt", ret
);
585 ssl_derive_keys( ssl
);
587 ssl
->out_msglen
= i
+ n
;
588 ssl
->out_msgtype
= SSL_MSG_HANDSHAKE
;
589 ssl
->out_msg
[0] = SSL_HS_CLIENT_KEY_EXCHANGE
;
593 if( ( ret
= ssl_write_record( ssl
) ) != 0 )
595 SSL_DEBUG_RET( 1, "ssl_write_record", ret
);
599 SSL_DEBUG_MSG( 2, ( "<= write client key exchange" ) );
604 static int ssl_write_certificate_verify( ssl_context
*ssl
)
607 unsigned char hash
[36];
609 SSL_DEBUG_MSG( 2, ( "=> write certificate verify" ) );
611 if( ssl
->client_auth
== 0 )
613 SSL_DEBUG_MSG( 2, ( "<= skip write certificate verify" ) );
618 if( ssl
->rsa_key
== NULL
)
620 SSL_DEBUG_MSG( 1, ( "got no private key" ) );
621 return( XYSSL_ERR_SSL_PRIVATE_KEY_REQUIRED
);
625 * Make an RSA signature of the handshake digests
627 ssl_calc_verify( ssl
, hash
);
629 n
= ssl
->rsa_key
->len
;
630 ssl
->out_msg
[4] = (unsigned char)( n
>> 8 );
631 ssl
->out_msg
[5] = (unsigned char)( n
);
633 if( ( ret
= rsa_pkcs1_sign( ssl
->rsa_key
, RSA_PRIVATE
, RSA_RAW
,
634 36, hash
, ssl
->out_msg
+ 6 ) ) != 0 )
636 SSL_DEBUG_RET( 1, "rsa_pkcs1_sign", ret
);
640 ssl
->out_msglen
= 6 + n
;
641 ssl
->out_msgtype
= SSL_MSG_HANDSHAKE
;
642 ssl
->out_msg
[0] = SSL_HS_CERTIFICATE_VERIFY
;
646 if( ( ret
= ssl_write_record( ssl
) ) != 0 )
648 SSL_DEBUG_RET( 1, "ssl_write_record", ret
);
652 SSL_DEBUG_MSG( 2, ( "<= write certificate verify" ) );
658 * SSL handshake -- client side
660 int ssl_handshake_client( ssl_context
*ssl
)
664 SSL_DEBUG_MSG( 2, ( "=> handshake client" ) );
666 while( ssl
->state
!= SSL_HANDSHAKE_OVER
)
668 SSL_DEBUG_MSG( 2, ( "client state: %d", ssl
->state
) );
670 if( ( ret
= ssl_flush_output( ssl
) ) != 0 )
675 case SSL_HELLO_REQUEST
:
676 ssl
->state
= SSL_CLIENT_HELLO
;
682 case SSL_CLIENT_HELLO
:
683 ret
= ssl_write_client_hello( ssl
);
689 * ( ServerKeyExchange )
690 * ( CertificateRequest )
693 case SSL_SERVER_HELLO
:
694 ret
= ssl_parse_server_hello( ssl
);
697 case SSL_SERVER_CERTIFICATE
:
698 ret
= ssl_parse_certificate( ssl
);
701 case SSL_SERVER_KEY_EXCHANGE
:
702 ret
= ssl_parse_server_key_exchange( ssl
);
705 case SSL_CERTIFICATE_REQUEST
:
706 ret
= ssl_parse_certificate_request( ssl
);
709 case SSL_SERVER_HELLO_DONE
:
710 ret
= ssl_parse_server_hello_done( ssl
);
714 * ==> ( Certificate/Alert )
716 * ( CertificateVerify )
720 case SSL_CLIENT_CERTIFICATE
:
721 ret
= ssl_write_certificate( ssl
);
724 case SSL_CLIENT_KEY_EXCHANGE
:
725 ret
= ssl_write_client_key_exchange( ssl
);
728 case SSL_CERTIFICATE_VERIFY
:
729 ret
= ssl_write_certificate_verify( ssl
);
732 case SSL_CLIENT_CHANGE_CIPHER_SPEC
:
733 ret
= ssl_write_change_cipher_spec( ssl
);
736 case SSL_CLIENT_FINISHED
:
737 ret
= ssl_write_finished( ssl
);
741 * <== ChangeCipherSpec
744 case SSL_SERVER_CHANGE_CIPHER_SPEC
:
745 ret
= ssl_parse_change_cipher_spec( ssl
);
748 case SSL_SERVER_FINISHED
:
749 ret
= ssl_parse_finished( ssl
);
752 case SSL_FLUSH_BUFFERS
:
753 SSL_DEBUG_MSG( 2, ( "handshake: done" ) );
754 ssl
->state
= SSL_HANDSHAKE_OVER
;
758 SSL_DEBUG_MSG( 1, ( "invalid state %d", ssl
->state
) );
759 return( XYSSL_ERR_SSL_BAD_INPUT_DATA
);
766 SSL_DEBUG_MSG( 2, ( "<= handshake client" ) );