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>
This commit is contained in:
parent
49ecee098d
commit
1500b3a50d
@ -484,21 +484,24 @@ static void prf_hmac(tls_state_t *tls,
|
|||||||
|
|
||||||
static void bad_record_die(tls_state_t *tls, const char *expected, int len)
|
static void bad_record_die(tls_state_t *tls, const char *expected, int len)
|
||||||
{
|
{
|
||||||
bb_error_msg_and_die("got bad TLS record (len:%d) while expecting %s", len, expected);
|
bb_error_msg("got bad TLS record (len:%d) while expecting %s", len, expected);
|
||||||
if (len > 0) {
|
if (len > 0) {
|
||||||
uint8_t *p = tls->inbuf;
|
uint8_t *p = tls->inbuf;
|
||||||
while (len > 0)
|
while (len > 0) {
|
||||||
fprintf(stderr, " %02x", *p++);
|
fprintf(stderr, " %02x", *p++);
|
||||||
|
len--;
|
||||||
|
}
|
||||||
fputc('\n', stderr);
|
fputc('\n', stderr);
|
||||||
}
|
}
|
||||||
xfunc_die();
|
xfunc_die();
|
||||||
}
|
}
|
||||||
|
|
||||||
static void tls_error_die(tls_state_t *tls)
|
static void tls_error_die(tls_state_t *tls, int line)
|
||||||
{
|
{
|
||||||
dump_tls_record(tls->inbuf, tls->ofs_to_buffered + tls->buffered_size);
|
dump_tls_record(tls->inbuf, tls->ofs_to_buffered + tls->buffered_size);
|
||||||
bb_error_msg_and_die("TODO: useful diagnostic about %p", tls);
|
bb_error_msg_and_die("tls error at line %d cipher:%04x", line, tls->cipher_id);
|
||||||
}
|
}
|
||||||
|
#define tls_error_die(tls) tls_error_die(tls, __LINE__)
|
||||||
|
|
||||||
#if 0 //UNUSED
|
#if 0 //UNUSED
|
||||||
static void tls_free_inbuf(tls_state_t *tls)
|
static void tls_free_inbuf(tls_state_t *tls)
|
||||||
@ -1343,6 +1346,26 @@ static void get_server_cert(tls_state_t *tls)
|
|||||||
find_key_in_der_cert(tls, certbuf + 10, len);
|
find_key_in_der_cert(tls, certbuf + 10, len);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void send_empty_client_cert(tls_state_t *tls)
|
||||||
|
{
|
||||||
|
struct client_empty_cert {
|
||||||
|
uint8_t type;
|
||||||
|
uint8_t len24_hi, len24_mid, len24_lo;
|
||||||
|
uint8_t cert_chain_len24_hi, cert_chain_len24_mid, cert_chain_len24_lo;
|
||||||
|
};
|
||||||
|
struct client_empty_cert *record;
|
||||||
|
|
||||||
|
record = tls_get_outbuf(tls, sizeof(*record));
|
||||||
|
//FIXME: can just memcpy a ready-made one.
|
||||||
|
fill_handshake_record_hdr(record, HANDSHAKE_CERTIFICATE, sizeof(*record));
|
||||||
|
record->cert_chain_len24_hi = 0;
|
||||||
|
record->cert_chain_len24_mid = 0;
|
||||||
|
record->cert_chain_len24_lo = 0;
|
||||||
|
|
||||||
|
dbg(">> CERTIFICATE\n");
|
||||||
|
xwrite_and_update_handshake_hash(tls, sizeof(*record));
|
||||||
|
}
|
||||||
|
|
||||||
static void send_client_key_exchange(tls_state_t *tls)
|
static void send_client_key_exchange(tls_state_t *tls)
|
||||||
{
|
{
|
||||||
struct client_key_exchange {
|
struct client_key_exchange {
|
||||||
@ -1584,23 +1607,25 @@ void FAST_FUNC tls_handshake(tls_state_t *tls, const char *sni)
|
|||||||
// 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("<< SERVER_KEY_EXCHANGE len:%u\n", len);
|
dbg("<< SERVER_KEY_EXCHANGE len:%u\n", len);
|
||||||
//probably need to save it
|
//probably need to save it
|
||||||
tls_xread_handshake_block(tls, 4);
|
len = tls_xread_handshake_block(tls, 4);
|
||||||
}
|
}
|
||||||
|
|
||||||
// if (tls->inbuf[RECHDR_LEN] == HANDSHAKE_CERTIFICATE_REQUEST) {
|
if (tls->inbuf[RECHDR_LEN] == HANDSHAKE_CERTIFICATE_REQUEST) {
|
||||||
// dbg("<< CERTIFICATE_REQUEST\n");
|
dbg("<< CERTIFICATE_REQUEST\n");
|
||||||
// RFC 5246: (in response to this,) "If no suitable certificate is available,
|
// RFC 5246: "If no suitable certificate is available,
|
||||||
// the client MUST send a certificate message containing no
|
// the client MUST send a certificate message containing no
|
||||||
// certificates. That is, the certificate_list structure has a
|
// certificates. That is, the certificate_list structure has a
|
||||||
// length of zero. ...
|
// length of zero. ...
|
||||||
// Client certificates are sent using the Certificate structure
|
// Client certificates are sent using the Certificate structure
|
||||||
// defined in Section 7.4.2."
|
// defined in Section 7.4.2."
|
||||||
// (i.e. the same format as server certs)
|
// (i.e. the same format as server certs)
|
||||||
// tls_xread_handshake_block(tls, 4);
|
send_empty_client_cert(tls);
|
||||||
// }
|
len = tls_xread_handshake_block(tls, 4);
|
||||||
|
}
|
||||||
|
|
||||||
if (tls->inbuf[RECHDR_LEN] != HANDSHAKE_SERVER_HELLO_DONE)
|
if (tls->inbuf[RECHDR_LEN] != HANDSHAKE_SERVER_HELLO_DONE) {
|
||||||
tls_error_die(tls);
|
bad_record_die(tls, "'server hello done'", len);
|
||||||
|
}
|
||||||
// 0e 000000 (len:0)
|
// 0e 000000 (len:0)
|
||||||
dbg("<< SERVER_HELLO_DONE\n");
|
dbg("<< SERVER_HELLO_DONE\n");
|
||||||
|
|
||||||
@ -1616,7 +1641,7 @@ void FAST_FUNC tls_handshake(tls_state_t *tls, const char *sni)
|
|||||||
/* Get CHANGE_CIPHER_SPEC */
|
/* Get CHANGE_CIPHER_SPEC */
|
||||||
len = tls_xread_record(tls);
|
len = tls_xread_record(tls);
|
||||||
if (len != 1 || memcmp(tls->inbuf, rec_CHANGE_CIPHER_SPEC, 6) != 0)
|
if (len != 1 || memcmp(tls->inbuf, rec_CHANGE_CIPHER_SPEC, 6) != 0)
|
||||||
tls_error_die(tls);
|
bad_record_die(tls, "switch to encrypted traffic", len);
|
||||||
dbg("<< CHANGE_CIPHER_SPEC\n");
|
dbg("<< CHANGE_CIPHER_SPEC\n");
|
||||||
if (tls->cipher_id == TLS_RSA_WITH_NULL_SHA256)
|
if (tls->cipher_id == TLS_RSA_WITH_NULL_SHA256)
|
||||||
tls->min_encrypted_len_on_read = tls->MAC_size;
|
tls->min_encrypted_len_on_read = tls->MAC_size;
|
||||||
|
Loading…
Reference in New Issue
Block a user