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 | |
| 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>
| -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; |
