Cryptography Reference
In-Depth Information
Listing 6-19: “tls.c” receive_tls_msg (continued in Listing 6-21)
msg_buf = ( char * ) malloc( message.length );
// keep looping & appending until all bytes are accounted for
accum_bytes = 0;
while ( accum_bytes < message.length )
{
if ( ( bytes_read = recv( connection, ( void * ) msg_buf,
message.length - accum_bytes, 0 ) ) <= 0 )
{
int status;
perror( “While reading a TLS packet” );
if ( ( status = send_alert_message( connection,
illegal_parameter ) ) )
{
free( msg_buf );
return status;
}
return -1;
}
accum_bytes += bytes_read;
msg_buf += bytes_read;
}
This loop, as presented here, is vulnerable to a denial of service attack. If the
server announces that 100 bytes are available but never sends them, the client
hangs forever waiting for these bytes. There's not much you can do about this,
though. You can (and should) set a socket-level timeout, but if it expires, there's
not much point in continuing the connection.
Sending Alerts
Notice that if recv returns an error, a function send_alert_message is invoked.
Remember the four types of TLS messages? Alert was one of them. This is how
clients and servers notify each other of unexpected conditions. In theory, an alert
can be recoverable — expired certifi cate is defi ned as an alert, for example — but
this poses a problem for the writer of a general-purpose TLS implementation.
If the client tells the server that its certifi cate has expired then in theory the
server could present a new certifi cate that hadn't expired. But why did it send
an expired certifi cate in the fi rst place, if it had one that was current? In general,
all alerts are treated as fatal errors.
Alerts are also frustratingly terse. As you can see, if the client wasn't able to
receive the entire message, it just returns an illegal parameter with no further
context. Although it logs a more detailed reason, the server developer probably
doesn't have access to those logs and has no clue what he did wrong. It would
Search WWH ::




Custom Search