diff options
author | Denys Vlasenko <vda.linux@googlemail.com> | 2017-01-24 17:06:10 +0100 |
---|---|---|
committer | Denys Vlasenko <vda.linux@googlemail.com> | 2017-01-24 17:06:10 +0100 |
commit | 1500b3a50d587adeca7be96b36394f23f2d80a82 (patch) | |
tree | 48e66ef66b0a501ab28be9dee205dffcc9fd5862 /networking/tls.c | |
parent | 49ecee098d062b92fcf095e05e15779c32899646 (diff) | |
download | busybox-w32-1500b3a50d587adeca7be96b36394f23f2d80a82.tar.gz busybox-w32-1500b3a50d587adeca7be96b36394f23f2d80a82.tar.bz2 busybox-w32-1500b3a50d587adeca7be96b36394f23f2d80a82.zip |
tls: if got CERTIFICATE_REQUEST, send an empty CERTIFICATE
wolfssl test server is not satisfied by an empty one,
but some real servers might be.
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
Diffstat (limited to 'networking/tls.c')
-rw-r--r-- | networking/tls.c | 65 |
1 files changed, 45 insertions, 20 deletions
diff --git a/networking/tls.c b/networking/tls.c index a65da4ad4..dc94a8b9b 100644 --- a/networking/tls.c +++ b/networking/tls.c | |||
@@ -484,21 +484,24 @@ static void prf_hmac(tls_state_t *tls, | |||
484 | 484 | ||
485 | static void bad_record_die(tls_state_t *tls, const char *expected, int len) | 485 | static void bad_record_die(tls_state_t *tls, const char *expected, int len) |
486 | { | 486 | { |
487 | bb_error_msg_and_die("got bad TLS record (len:%d) while expecting %s", len, expected); | 487 | bb_error_msg("got bad TLS record (len:%d) while expecting %s", len, expected); |
488 | if (len > 0) { | 488 | if (len > 0) { |
489 | uint8_t *p = tls->inbuf; | 489 | uint8_t *p = tls->inbuf; |
490 | while (len > 0) | 490 | while (len > 0) { |
491 | fprintf(stderr, " %02x", *p++); | 491 | fprintf(stderr, " %02x", *p++); |
492 | len--; | ||
493 | } | ||
492 | fputc('\n', stderr); | 494 | fputc('\n', stderr); |
493 | } | 495 | } |
494 | xfunc_die(); | 496 | xfunc_die(); |
495 | } | 497 | } |
496 | 498 | ||
497 | static void tls_error_die(tls_state_t *tls) | 499 | static void tls_error_die(tls_state_t *tls, int line) |
498 | { | 500 | { |
499 | dump_tls_record(tls->inbuf, tls->ofs_to_buffered + tls->buffered_size); | 501 | dump_tls_record(tls->inbuf, tls->ofs_to_buffered + tls->buffered_size); |
500 | bb_error_msg_and_die("TODO: useful diagnostic about %p", tls); | 502 | bb_error_msg_and_die("tls error at line %d cipher:%04x", line, tls->cipher_id); |
501 | } | 503 | } |
504 | #define tls_error_die(tls) tls_error_die(tls, __LINE__) | ||
502 | 505 | ||
503 | #if 0 //UNUSED | 506 | #if 0 //UNUSED |
504 | static void tls_free_inbuf(tls_state_t *tls) | 507 | static void tls_free_inbuf(tls_state_t *tls) |
@@ -1343,6 +1346,26 @@ static void get_server_cert(tls_state_t *tls) | |||
1343 | find_key_in_der_cert(tls, certbuf + 10, len); | 1346 | find_key_in_der_cert(tls, certbuf + 10, len); |
1344 | } | 1347 | } |
1345 | 1348 | ||
1349 | static void send_empty_client_cert(tls_state_t *tls) | ||
1350 | { | ||
1351 | struct client_empty_cert { | ||
1352 | uint8_t type; | ||
1353 | uint8_t len24_hi, len24_mid, len24_lo; | ||
1354 | uint8_t cert_chain_len24_hi, cert_chain_len24_mid, cert_chain_len24_lo; | ||
1355 | }; | ||
1356 | struct client_empty_cert *record; | ||
1357 | |||
1358 | record = tls_get_outbuf(tls, sizeof(*record)); | ||
1359 | //FIXME: can just memcpy a ready-made one. | ||
1360 | fill_handshake_record_hdr(record, HANDSHAKE_CERTIFICATE, sizeof(*record)); | ||
1361 | record->cert_chain_len24_hi = 0; | ||
1362 | record->cert_chain_len24_mid = 0; | ||
1363 | record->cert_chain_len24_lo = 0; | ||
1364 | |||
1365 | dbg(">> CERTIFICATE\n"); | ||
1366 | xwrite_and_update_handshake_hash(tls, sizeof(*record)); | ||
1367 | } | ||
1368 | |||
1346 | static void send_client_key_exchange(tls_state_t *tls) | 1369 | static void send_client_key_exchange(tls_state_t *tls) |
1347 | { | 1370 | { |
1348 | struct client_key_exchange { | 1371 | struct client_key_exchange { |
@@ -1584,23 +1607,25 @@ void FAST_FUNC tls_handshake(tls_state_t *tls, const char *sni) | |||
1584 | // 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... | 1607 | // 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... |
1585 | dbg("<< SERVER_KEY_EXCHANGE len:%u\n", len); | 1608 | dbg("<< SERVER_KEY_EXCHANGE len:%u\n", len); |
1586 | //probably need to save it | 1609 | //probably need to save it |
1587 | tls_xread_handshake_block(tls, 4); | 1610 | len = tls_xread_handshake_block(tls, 4); |
1588 | } | 1611 | } |
1589 | 1612 | ||
1590 | // if (tls->inbuf[RECHDR_LEN] == HANDSHAKE_CERTIFICATE_REQUEST) { | 1613 | if (tls->inbuf[RECHDR_LEN] == HANDSHAKE_CERTIFICATE_REQUEST) { |
1591 | // dbg("<< CERTIFICATE_REQUEST\n"); | 1614 | dbg("<< CERTIFICATE_REQUEST\n"); |
1592 | // RFC 5246: (in response to this,) "If no suitable certificate is available, | 1615 | // RFC 5246: "If no suitable certificate is available, |
1593 | // the client MUST send a certificate message containing no | 1616 | // the client MUST send a certificate message containing no |
1594 | // certificates. That is, the certificate_list structure has a | 1617 | // certificates. That is, the certificate_list structure has a |
1595 | // length of zero. ... | 1618 | // length of zero. ... |
1596 | // Client certificates are sent using the Certificate structure | 1619 | // Client certificates are sent using the Certificate structure |
1597 | // defined in Section 7.4.2." | 1620 | // defined in Section 7.4.2." |
1598 | // (i.e. the same format as server certs) | 1621 | // (i.e. the same format as server certs) |
1599 | // tls_xread_handshake_block(tls, 4); | 1622 | send_empty_client_cert(tls); |
1600 | // } | 1623 | len = tls_xread_handshake_block(tls, 4); |
1601 | 1624 | } | |
1602 | if (tls->inbuf[RECHDR_LEN] != HANDSHAKE_SERVER_HELLO_DONE) | 1625 | |
1603 | tls_error_die(tls); | 1626 | if (tls->inbuf[RECHDR_LEN] != HANDSHAKE_SERVER_HELLO_DONE) { |
1627 | bad_record_die(tls, "'server hello done'", len); | ||
1628 | } | ||
1604 | // 0e 000000 (len:0) | 1629 | // 0e 000000 (len:0) |
1605 | dbg("<< SERVER_HELLO_DONE\n"); | 1630 | dbg("<< SERVER_HELLO_DONE\n"); |
1606 | 1631 | ||
@@ -1616,7 +1641,7 @@ void FAST_FUNC tls_handshake(tls_state_t *tls, const char *sni) | |||
1616 | /* Get CHANGE_CIPHER_SPEC */ | 1641 | /* Get CHANGE_CIPHER_SPEC */ |
1617 | len = tls_xread_record(tls); | 1642 | len = tls_xread_record(tls); |
1618 | if (len != 1 || memcmp(tls->inbuf, rec_CHANGE_CIPHER_SPEC, 6) != 0) | 1643 | if (len != 1 || memcmp(tls->inbuf, rec_CHANGE_CIPHER_SPEC, 6) != 0) |
1619 | tls_error_die(tls); | 1644 | bad_record_die(tls, "switch to encrypted traffic", len); |
1620 | dbg("<< CHANGE_CIPHER_SPEC\n"); | 1645 | dbg("<< CHANGE_CIPHER_SPEC\n"); |
1621 | if (tls->cipher_id == TLS_RSA_WITH_NULL_SHA256) | 1646 | if (tls->cipher_id == TLS_RSA_WITH_NULL_SHA256) |
1622 | tls->min_encrypted_len_on_read = tls->MAC_size; | 1647 | tls->min_encrypted_len_on_read = tls->MAC_size; |