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>
diff --git a/networking/tls.c b/networking/tls.c
index a65da4a..dc94a8b 100644
--- a/networking/tls.c
+++ b/networking/tls.c
@@ -484,21 +484,24 @@
 
 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) {
 		uint8_t *p = tls->inbuf;
-		while (len > 0)
+		while (len > 0) {
 			fprintf(stderr, " %02x", *p++);
+			len--;
+		}
 		fputc('\n', stderr);
 	}
 	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);
-	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
 static void tls_free_inbuf(tls_state_t *tls)
@@ -1343,6 +1346,26 @@
 		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)
 {
 	struct client_key_exchange {
@@ -1584,23 +1607,25 @@
 		// 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);
 //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) {
-//		dbg("<< CERTIFICATE_REQUEST\n");
-// RFC 5246: (in response to this,) "If no suitable certificate is available,
-// the client MUST send a certificate message containing no
-// certificates.  That is, the certificate_list structure has a
-// length of zero. ...
-// Client certificates are sent using the Certificate structure
-// defined in Section 7.4.2."
-// (i.e. the same format as server certs)
-//		tls_xread_handshake_block(tls, 4);
-//	}
+	if (tls->inbuf[RECHDR_LEN] == HANDSHAKE_CERTIFICATE_REQUEST) {
+		dbg("<< CERTIFICATE_REQUEST\n");
+		// RFC 5246: "If no suitable certificate is available,
+		// the client MUST send a certificate message containing no
+		// certificates.  That is, the certificate_list structure has a
+		// length of zero. ...
+		// Client certificates are sent using the Certificate structure
+		// defined in Section 7.4.2."
+		// (i.e. the same format as server certs)
+		send_empty_client_cert(tls);
+		len = tls_xread_handshake_block(tls, 4);
+	}
 
-	if (tls->inbuf[RECHDR_LEN] != HANDSHAKE_SERVER_HELLO_DONE)
-		tls_error_die(tls);
+	if (tls->inbuf[RECHDR_LEN] != HANDSHAKE_SERVER_HELLO_DONE) {
+		bad_record_die(tls, "'server hello done'", len);
+	}
 	// 0e 000000 (len:0)
 	dbg("<< SERVER_HELLO_DONE\n");
 
@@ -1616,7 +1641,7 @@
 	/* Get CHANGE_CIPHER_SPEC */
 	len = tls_xread_record(tls);
 	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");
 	if (tls->cipher_id == TLS_RSA_WITH_NULL_SHA256)
 		tls->min_encrypted_len_on_read = tls->MAC_size;