tls: process CHANGE_CIPHER_SPEC and FINISHED from server
Successfully finishes handshake with test servers using NULL-SHA256 cipher. The "only" thing remaining before there is a chance this can actually work with real servers is AES encrypt/decrypt. Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
This commit is contained in:
parent
fe0588df3b
commit
e69d78c038
@ -163,6 +163,7 @@ typedef struct tls_state {
|
|||||||
uint8_t master_secret[48];
|
uint8_t master_secret[48];
|
||||||
|
|
||||||
uint8_t encrypt_on_write;
|
uint8_t encrypt_on_write;
|
||||||
|
uint8_t decrypt_on_read;
|
||||||
uint8_t client_write_MAC_key[SHA256_OUTSIZE];
|
uint8_t client_write_MAC_key[SHA256_OUTSIZE];
|
||||||
// RFC 5246
|
// RFC 5246
|
||||||
// sequence number
|
// sequence number
|
||||||
@ -1044,15 +1045,16 @@ static void send_client_key_exchange(tls_state_t *tls)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void send_change_cipher_spec(tls_state_t *tls)
|
static const uint8_t rec_CHANGE_CIPHER_SPEC[] = {
|
||||||
{
|
|
||||||
static const uint8_t rec[] = {
|
|
||||||
RECORD_TYPE_CHANGE_CIPHER_SPEC, TLS_MAJ, TLS_MIN, 00, 01,
|
RECORD_TYPE_CHANGE_CIPHER_SPEC, TLS_MAJ, TLS_MIN, 00, 01,
|
||||||
01
|
01
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static void send_change_cipher_spec(tls_state_t *tls)
|
||||||
|
{
|
||||||
/* Not "xwrite_and_hash": this is not a handshake message */
|
/* Not "xwrite_and_hash": this is not a handshake message */
|
||||||
dbg(">> CHANGE_CIPHER_SPEC\n");
|
dbg(">> CHANGE_CIPHER_SPEC\n");
|
||||||
xwrite(tls->fd, rec, sizeof(rec));
|
xwrite(tls->fd, rec_CHANGE_CIPHER_SPEC, sizeof(rec_CHANGE_CIPHER_SPEC));
|
||||||
|
|
||||||
/* tls->write_seq64_be = 0; - already is */
|
/* tls->write_seq64_be = 0; - already is */
|
||||||
tls->encrypt_on_write = 1;
|
tls->encrypt_on_write = 1;
|
||||||
@ -1138,16 +1140,6 @@ static void send_client_finished(tls_state_t *tls)
|
|||||||
xwrite_and_hash(tls, &record, sizeof(record));
|
xwrite_and_hash(tls, &record, sizeof(record));
|
||||||
}
|
}
|
||||||
|
|
||||||
static void get_change_cipher_spec(tls_state_t *tls)
|
|
||||||
{
|
|
||||||
tls->fd = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void get_server_finished(tls_state_t *tls)
|
|
||||||
{
|
|
||||||
tls->fd = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void tls_handshake(tls_state_t *tls)
|
static void tls_handshake(tls_state_t *tls)
|
||||||
{
|
{
|
||||||
// Client RFC 5246 Server
|
// Client RFC 5246 Server
|
||||||
@ -1205,20 +1197,32 @@ static void tls_handshake(tls_state_t *tls)
|
|||||||
// (i.e. the same format as server certs)
|
// (i.e. the same format as server certs)
|
||||||
// xread_tls_handshake_block(tls, 4);
|
// xread_tls_handshake_block(tls, 4);
|
||||||
// }
|
// }
|
||||||
if (tls->inbuf[5] == HANDSHAKE_SERVER_HELLO_DONE) {
|
if (tls->inbuf[5] != HANDSHAKE_SERVER_HELLO_DONE)
|
||||||
|
tls_error_die(tls);
|
||||||
// 0e 000000 (len:0)
|
// 0e 000000 (len:0)
|
||||||
dbg("got SERVER_HELLO_DONE\n");
|
dbg("got SERVER_HELLO_DONE\n");
|
||||||
|
|
||||||
send_client_key_exchange(tls);
|
send_client_key_exchange(tls);
|
||||||
|
|
||||||
send_change_cipher_spec(tls);
|
send_change_cipher_spec(tls);
|
||||||
//we now should be able to send encrypted... as soon as we grok AES.
|
/* we now should send encrypted... as soon as we grok AES. */
|
||||||
|
|
||||||
send_client_finished(tls);
|
send_client_finished(tls);
|
||||||
|
|
||||||
get_change_cipher_spec(tls);
|
/* Get CHANGE_CIPHER_SPEC */
|
||||||
get_server_finished(tls);
|
len = xread_tls_block(tls);
|
||||||
//we now should receive encrypted, and application data can be sent/received
|
if (len != 1 || memcmp(tls->inbuf, rec_CHANGE_CIPHER_SPEC, 6) != 0)
|
||||||
} else {
|
|
||||||
tls_error_die(tls);
|
tls_error_die(tls);
|
||||||
}
|
dbg("got CHANGE_CIPHER_SPEC\n");
|
||||||
|
tls->decrypt_on_read = 1;
|
||||||
|
/* we now should receive encrypted */
|
||||||
|
|
||||||
|
/* Get (encrypted) FINISHED from the server */
|
||||||
|
len = xread_tls_block(tls);
|
||||||
|
if (len < 4 || tls->inbuf[5] != HANDSHAKE_FINISHED)
|
||||||
|
tls_error_die(tls);
|
||||||
|
dbg("got FINISHED\n");
|
||||||
|
/* application data can be sent/received */
|
||||||
}
|
}
|
||||||
|
|
||||||
// To run a test server using openssl:
|
// To run a test server using openssl:
|
||||||
|
Loading…
Reference in New Issue
Block a user