Cryptography Reference
In-Depth Information
parameters->active_cipher_spec->new_digest( &ctx );
update_digest( &ctx, parameters->read_key,
parameters->active_cipher_spec->key_size );
update_digest( &ctx, data, data_len );
sequence_number = htonl( parameters->read_sequence_number );
update_digest( &ctx, ( unsigned char * ) &sequence_number,
sizeof( int ) );
finalize_digest( &ctx );
return ( !memcmp( ctx.hash, mac, mac_len ) );
}
This works just like add_mac . In fact, the only differences here are that it uses
the read_key as the fi rst n bytes of the MAC buffer, and rather than memcpy -
ing the resultant MAC to a target output buffer, it instead does a memcmp and
returns a true or false.
If the MAC verifi es properly, the decrypted data is copied into a target buf-
fer and processed just as if it had been received as plaintext. Add a third “case
arm” to the handshake processing switch:
if ( !parameters->handshake_finished )
{
switch ( buffer[ 0 ] )
{
case SSL_MT_SERVER_VERIFY:
status = parse_server_verify( parameters, buffer + 1 );
break;
Parsing the ServerVerify , after it's been successfully decrypted, is straight-
forward, as shown in Listing C-29.
Listing C-29: “ssl.c” parse_server_verify
static int parse_server_verify( SSLParameters *parameters,
const unsigned char *buf )
{
ServerVerify package;
memcpy( package.challenge, buf, CHALLENGE_LEN );
parameters->got_server_verify = 1;
return ( !memcmp( parameters->challenge, package.challenge,
CHALLENGE_LEN ) );
}
 
Search WWH ::




Custom Search