tls: send CHANGE_CIPHER_SPEC
To "actually implement it" will take more work... Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
This commit is contained in:
parent
f78ad0938b
commit
c5540d61f6
@ -269,6 +269,23 @@ static int xread_tls_block(tls_state_t *tls)
|
|||||||
return target;
|
return target;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int xread_tls_handshake_block(tls_state_t *tls, int min_len)
|
||||||
|
{
|
||||||
|
struct record_hdr *xhdr;
|
||||||
|
int len = xread_tls_block(tls);
|
||||||
|
|
||||||
|
xhdr = (void*)tls->inbuf;
|
||||||
|
if (len < min_len
|
||||||
|
|| xhdr->type != RECORD_TYPE_HANDSHAKE
|
||||||
|
|| xhdr->proto_maj != TLS_MAJ
|
||||||
|
|| xhdr->proto_min != TLS_MIN
|
||||||
|
) {
|
||||||
|
tls_error_die(tls);
|
||||||
|
}
|
||||||
|
dbg("got HANDSHAKE\n");
|
||||||
|
return len;
|
||||||
|
}
|
||||||
|
|
||||||
static void send_client_hello(tls_state_t *tls)
|
static void send_client_hello(tls_state_t *tls)
|
||||||
{
|
{
|
||||||
struct client_hello {
|
struct client_hello {
|
||||||
@ -296,8 +313,8 @@ static void send_client_hello(tls_state_t *tls)
|
|||||||
//hello.len24_hi = 0;
|
//hello.len24_hi = 0;
|
||||||
//zero: hello.len24_mid = (sizeof(hello) - sizeof(hello.xhdr) - 4) >> 8;
|
//zero: hello.len24_mid = (sizeof(hello) - sizeof(hello.xhdr) - 4) >> 8;
|
||||||
hello.len24_lo = (sizeof(hello) - sizeof(hello.xhdr) - 4);
|
hello.len24_lo = (sizeof(hello) - sizeof(hello.xhdr) - 4);
|
||||||
hello.proto_maj = TLS_MAJ;
|
hello.proto_maj = TLS_MAJ; /* the "requested" version of the protocol, */
|
||||||
hello.proto_min = TLS_MIN;
|
hello.proto_min = TLS_MIN; /* can be higher than one in record headers */
|
||||||
tls_get_random(hello.rand32, sizeof(hello.rand32));
|
tls_get_random(hello.rand32, sizeof(hello.rand32));
|
||||||
//hello.session_id_len = 0;
|
//hello.session_id_len = 0;
|
||||||
//hello.cipherid_len16_hi = 0;
|
//hello.cipherid_len16_hi = 0;
|
||||||
@ -325,20 +342,10 @@ static void get_server_hello_or_die(tls_state_t *tls)
|
|||||||
/* extensions may follow, but only those which client offered in its Hello */
|
/* extensions may follow, but only those which client offered in its Hello */
|
||||||
};
|
};
|
||||||
struct server_hello *hp;
|
struct server_hello *hp;
|
||||||
int len;
|
|
||||||
|
|
||||||
len = xread_tls_block(tls);
|
xread_tls_handshake_block(tls, 74);
|
||||||
|
|
||||||
hp = (void*)tls->inbuf;
|
hp = (void*)tls->inbuf;
|
||||||
if (len != 74 /* TODO: if we accept extensions, should be < instead of != */
|
|
||||||
|| hp->xhdr.type != RECORD_TYPE_HANDSHAKE
|
|
||||||
|| hp->xhdr.proto_maj != TLS_MAJ
|
|
||||||
|| hp->xhdr.proto_min != TLS_MIN
|
|
||||||
) {
|
|
||||||
/* example: RECORD_TYPE_ALERT if server can't support our ciphers */
|
|
||||||
tls_error_die(tls);
|
|
||||||
}
|
|
||||||
dbg("got HANDSHAKE\n");
|
|
||||||
// 74 bytes:
|
// 74 bytes:
|
||||||
// 02 000046 03|03 58|78|cf|c1 50|a5|49|ee|7e|29|48|71|fe|97|fa|e8|2d|19|87|72|90|84|9d|37|a3|f0|cb|6f|5f|e3|3c|2f |20 |d8|1a|78|96|52|d6|91|01|24|b3|d6|5b|b7|d0|6c|b3|e1|78|4e|3c|95|de|74|a0|ba|eb|a7|3a|ff|bd|a2|bf |00|9c |00|
|
// 02 000046 03|03 58|78|cf|c1 50|a5|49|ee|7e|29|48|71|fe|97|fa|e8|2d|19|87|72|90|84|9d|37|a3|f0|cb|6f|5f|e3|3c|2f |20 |d8|1a|78|96|52|d6|91|01|24|b3|d6|5b|b7|d0|6c|b3|e1|78|4e|3c|95|de|74|a0|ba|eb|a7|3a|ff|bd|a2|bf |00|9c |00|
|
||||||
//SvHl len=70 maj.min unixtime^^^ 28randbytes^^^^^^^^^^^^^^^^^^^^^^^^^^^^_^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^_^^^ slen sid32bytes^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cipSel comprSel
|
//SvHl len=70 maj.min unixtime^^^ 28randbytes^^^^^^^^^^^^^^^^^^^^^^^^^^^^_^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^_^^^ slen sid32bytes^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cipSel comprSel
|
||||||
@ -572,16 +579,9 @@ static void get_server_cert_or_die(tls_state_t *tls)
|
|||||||
uint8_t *certbuf;
|
uint8_t *certbuf;
|
||||||
int len, len1;
|
int len, len1;
|
||||||
|
|
||||||
len = xread_tls_block(tls);
|
len = xread_tls_handshake_block(tls, 10);
|
||||||
|
|
||||||
xhdr = (void*)tls->inbuf;
|
xhdr = (void*)tls->inbuf;
|
||||||
if (len < sizeof(*xhdr) + 10
|
|
||||||
|| xhdr->type != RECORD_TYPE_HANDSHAKE
|
|
||||||
|| xhdr->proto_maj != TLS_MAJ
|
|
||||||
|| xhdr->proto_min != TLS_MIN
|
|
||||||
) {
|
|
||||||
tls_error_die(tls);
|
|
||||||
}
|
|
||||||
dbg("got HANDSHAKE\n");
|
|
||||||
certbuf = (void*)(xhdr + 1);
|
certbuf = (void*)(xhdr + 1);
|
||||||
if (certbuf[0] != HANDSHAKE_CERTIFICATE)
|
if (certbuf[0] != HANDSHAKE_CERTIFICATE)
|
||||||
tls_error_die(tls);
|
tls_error_die(tls);
|
||||||
@ -703,6 +703,15 @@ static void send_client_key_exchange(tls_state_t *tls)
|
|||||||
xwrite(tls->fd, &record, sizeof(record));
|
xwrite(tls->fd, &record, sizeof(record));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void send_change_cipher_spec(tls_state_t *tls)
|
||||||
|
{
|
||||||
|
static const uint8_t rec[] = {
|
||||||
|
RECORD_TYPE_CHANGE_CIPHER_SPEC, TLS_MAJ, TLS_MIN, 00, 01,
|
||||||
|
01
|
||||||
|
};
|
||||||
|
xwrite(tls->fd, rec, sizeof(rec));
|
||||||
|
}
|
||||||
|
|
||||||
static void tls_handshake(tls_state_t *tls)
|
static void tls_handshake(tls_state_t *tls)
|
||||||
{
|
{
|
||||||
// Client RFC 5246 Server
|
// Client RFC 5246 Server
|
||||||
@ -754,29 +763,28 @@ static void tls_handshake(tls_state_t *tls)
|
|||||||
// (for example, kernel.org does not even accept DH_anon cipher id)
|
// (for example, kernel.org does not even accept DH_anon cipher id)
|
||||||
get_server_cert_or_die(tls);
|
get_server_cert_or_die(tls);
|
||||||
|
|
||||||
len = xread_tls_block(tls);
|
len = xread_tls_handshake_block(tls, 4);
|
||||||
/* Next handshake type is not predetermined */
|
if (tls->inbuf[5] == HANDSHAKE_SERVER_KEY_EXCHANGE) {
|
||||||
switch (tls->inbuf[5]) {
|
|
||||||
case HANDSHAKE_SERVER_KEY_EXCHANGE:
|
|
||||||
// 459 bytes:
|
// 459 bytes:
|
||||||
// 0c 00|01|c7 03|00|17|41|04|87|94|2e|2f|68|d0|c9|f4|97|a8|2d|ef|ed|67|ea|c6|f3|b3|56|47|5d|27|b6|bd|ee|70|25|30|5e|b0|8e|f6|21|5a...
|
// 0c 00|01|c7 03|00|17|41|04|87|94|2e|2f|68|d0|c9|f4|97|a8|2d|ef|ed|67|ea|c6|f3|b3|56|47|5d|27|b6|bd|ee|70|25|30|5e|b0|8e|f6|21|5a...
|
||||||
//SvKey len=455^
|
//SvKey len=455^
|
||||||
// with TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA: 461 bytes:
|
// with TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA: 461 bytes:
|
||||||
// 0c 00|01|c9 03|00|17|41|04|cd|9b|b4|29|1f|f6|b0|c2|84|82|7f|29|6a|47|4e|ec|87|0b|c1|9c|69|e1|f8|c6|d0|53|e9|27|90|a5|c8|02|15|75...
|
// 0c 00|01|c9 03|00|17|41|04|cd|9b|b4|29|1f|f6|b0|c2|84|82|7f|29|6a|47|4e|ec|87|0b|c1|9c|69|e1|f8|c6|d0|53|e9|27|90|a5|c8|02|15|75...
|
||||||
dbg("got SERVER_KEY_EXCHANGE\n");
|
dbg("got SERVER_KEY_EXCHANGE len:%u\n", len);
|
||||||
len = xread_tls_block(tls);
|
//need to save it
|
||||||
break;
|
xread_tls_handshake_block(tls, 4);
|
||||||
case HANDSHAKE_CERTIFICATE_REQUEST:
|
}
|
||||||
dbg("got CERTIFICATE_REQUEST\n");
|
// if (tls->inbuf[5] == HANDSHAKE_CERTIFICATE_REQUEST) {
|
||||||
len = xread_tls_block(tls);
|
// dbg("got CERTIFICATE_REQUEST\n");
|
||||||
break;
|
// xread_tls_handshake_block(tls, 4);
|
||||||
case HANDSHAKE_SERVER_HELLO_DONE:
|
// }
|
||||||
|
if (tls->inbuf[5] == HANDSHAKE_SERVER_HELLO_DONE) {
|
||||||
// 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);
|
||||||
len = xread_tls_block(tls);
|
send_change_cipher_spec(tls);
|
||||||
break;
|
//we now should be able to send encrypted... as soon as we grok AES.
|
||||||
default:
|
} else {
|
||||||
tls_error_die(tls);
|
tls_error_die(tls);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user