X-Git-Url: https://pd.if.org/git/?a=blobdiff_plain;f=crypto%2Ftlse.c;h=5274dbade4aa15ceca9a6a9e3f621f14fbcc802a;hb=HEAD;hp=8920467058eb3c76f7c57e13c19a2afa8fee3e53;hpb=4b448fbc77510c589cc7f367c05bef63acc07858;p=zpackage diff --git a/crypto/tlse.c b/crypto/tlse.c index 8920467..5274dba 100644 --- a/crypto/tlse.c +++ b/crypto/tlse.c @@ -61,6 +61,12 @@ #define CHECK_HANDSHAKE_STATE(context, n, limit) { if (context->hs_messages[n] >= limit) { DEBUG_PRINT("* UNEXPECTED MESSAGE (%i)\n", (int)n); payload_res = TLS_UNEXPECTED_MESSAGE; break; } context->hs_messages[n]++; } +#ifdef DEBUG +int tls_indent = 0; +int tls_indent_i = 0; +#endif + +//#define MARK typedef enum { KEA_dhe_dss, KEA_dhe_rsa, @@ -205,23 +211,65 @@ static uint32_t get24(const unsigned char *buf) { return res; } +#ifdef DEBUG +static char *packet_content_type(int type) { + switch (type) { + case 20: return "change_cipher_spec"; break; + case 21: return "alert"; break; + case 22: return "handshake"; break; + case 23: return "application_data"; break; + default: break; + } + return "unknown content type"; +} + +static char *packet_handshake_type(int type) { + switch (type) { + case 0: return "hello_request"; break; + case 1: return "client_hello"; break; + case 2: return "server_hello"; break; + case 11: return "certificate"; break; + case 12: return "server_key_exchange"; break; + case 13: return "certificate_request"; break; + case 14: return "server_hello_done"; break; + case 15: return "certificate_verify"; break; + case 16: return "client_key_exchange"; break; + case 20: return "finished"; break; + default: break; + } + return "unknown handshake type"; +} +#endif + size_t tls_queue_packet(struct TLSPacket *packet) { + ENTER; if (!packet) { + LEAVE; return -1; } struct TLSContext *context = packet->context; if (!context) { + LEAVE; return -1; } + DEBUG_PRINTLN("sending packet type %d %s\n", (int)packet->buf[0], + packet_content_type(packet->buf[0])); + if (packet->buf[0] == 22) { + DEBUG_PRINTLN("handshake type %d %s\n", (int)packet->buf[5], + packet_handshake_type(packet->buf[5]) + ); + } tls_buffer_append(&context->output_buffer, packet->buf, packet->len); tls_destroy_packet(packet); + LEAVE; return context->output_buffer.len; } static void tls_send_change_cipher_spec(struct TLSContext *context) { + ENTER; struct TLSPacket *packet = tls_create_packet(context, TLS_CHANGE_CIPHER, context->version, 64); @@ -229,6 +277,7 @@ static void tls_send_change_cipher_spec(struct TLSContext *context) { tls_packet_update(packet); context->local_sequence_number = 0; tls_queue_packet(packet); + LEAVE; return; } @@ -275,6 +324,7 @@ static void tls_send_certificate(struct TLSContext *context) { int certificates_count; struct TLSCertificate **certificates; + ENTER; if (context->is_server) { certificates_count = context->certificates_count; certificates = context->certificates; @@ -362,6 +412,7 @@ static void tls_send_certificate(struct TLSContext *context) { } tls_packet_update(packet); tls_queue_packet(packet); + LEAVE; return; } @@ -400,8 +451,10 @@ static void tls_init() { #endif #endif /* TODO remove these */ +#if 0 register_hash(&md5_desc); register_hash(&sha1_desc); +#endif register_hash(&sha256_desc); register_hash(&sha384_desc); @@ -1235,10 +1288,11 @@ static void tls_prf(struct TLSContext *context, } static void tls_send_finished(struct TLSContext *context) { + ENTER; struct TLSPacket *packet = tls_create_packet(context, TLS_HANDSHAKE, context->version, TLS_MIN_FINISHED_OPAQUE_LEN + 64); - tls_packet_uint8(packet, 0x14); + tls_packet_uint8(packet, 20); if (context->tlsver == TLS_VERSION13) { tls_packet_uint24(packet, tls_mac_length(context)); @@ -1268,6 +1322,7 @@ static void tls_send_finished(struct TLSContext *context) { /* TODO probably need to terminate */ tls_destroy_packet(packet); + LEAVE; return; } @@ -1307,6 +1362,7 @@ static void tls_send_finished(struct TLSContext *context) { tls_packet_update(packet); DEBUG_DUMP_HEX_LABEL("VERIFY DATA", out, out_size); tls_queue_packet(packet); + LEAVE; return; } @@ -1733,17 +1789,21 @@ static int tls_expand_key(struct TLSContext *context) { (int) TLS_MAX_KEY_EXPANSION_SIZE); DEBUG_DUMP_HEX_LABEL("CLIENT KEY", clientkey, key_length); DEBUG_DUMP_HEX_LABEL("CLIENT IV", clientiv, iv_length); +#if 0 DEBUG_DUMP_HEX_LABEL("CLIENT MAC KEY", context->is_server ? context->crypto. ctx_remote_mac.remote_mac : context-> crypto.ctx_local_mac.local_mac, mac_length); +#endif DEBUG_DUMP_HEX_LABEL("SERVER KEY", serverkey, key_length); DEBUG_DUMP_HEX_LABEL("SERVER IV", serveriv, iv_length); +#if 0 DEBUG_DUMP_HEX_LABEL("SERVER MAC KEY", context->is_server ? context->crypto. ctx_local_mac.local_mac : context->crypto. ctx_remote_mac.remote_mac, mac_length); +#endif if (context->is_server) { if (is_aead == 2) { memcpy(context->crypto.ctx_remote_mac.remote_nonce, @@ -2441,16 +2501,7 @@ int tls_random(unsigned char *key, int len) { } int tls_established(struct TLSContext *context) { - if (context) { - if (context->critical_error) { - return -1; - } - - if (context->connection_status == TLS_CONNECTED) { - return 1; - } - } - return 0; + return context && context->connection_status == TLS_CONNECTED; } void tls_read_clear(struct TLSContext *context) { @@ -3337,6 +3388,7 @@ int tls_parse_certificate(struct TLSContext *context, res += certificate_size; } if (!valid_certificate) { + MARK; return TLS_UNSUPPORTED_CERTIFICATE; } if (res != buf_len) { @@ -3538,6 +3590,7 @@ int tls_parse_server_key_exchange(struct TLSContext *context, DEBUG_PRINT(" dh_q: "); dh_res = parse_dh(&buf[res], buf_len - res, &dh_g, &dh_g_len); if (dh_res <= 0) { + MARK; return TLS_BROKEN_PACKET; } res += dh_res; @@ -3547,6 +3600,7 @@ int tls_parse_server_key_exchange(struct TLSContext *context, dh_res = parse_dh(&buf[res], buf_len - res, &dh_Ys, &dh_Ys_len); if (dh_res <= 0) { + MARK; return TLS_BROKEN_PACKET; } res += dh_res; @@ -3709,6 +3763,7 @@ static int tls_parse_server_hello_done(const unsigned char *buf, int buf_len) { return TLS_NEED_MORE_DATA; } + MARK; res += size; return res; } @@ -3829,6 +3884,7 @@ int tls_parse_finished(struct TLSContext *context, // fprintf(stderr, "set conn status = %d\n", context->connection_status); + MARK; res += size; return res; } @@ -3956,6 +4012,7 @@ int tls_parse_verify(struct TLSContext *context, const unsigned char *buf, /* TODO This is actually a parse a handshake message */ int tls_parse_payload(struct TLSContext *context, const unsigned char *buf, int buf_len) { + ENTER; int orig_len = buf_len; @@ -4187,6 +4244,7 @@ int tls_parse_payload(struct TLSContext *context, const unsigned char *buf, } if (certificate_verify_alert != no_error) { + MARK; tls_alert(context, 1, certificate_verify_alert); context->critical_error = 1; } @@ -4194,21 +4252,27 @@ int tls_parse_payload(struct TLSContext *context, const unsigned char *buf, if (payload_res < 0) { switch (payload_res) { case TLS_UNEXPECTED_MESSAGE: + MARK; tls_alert(context, 1, unexpected_message); break; case TLS_COMPRESSION_NOT_SUPPORTED: + MARK; tls_alert(context, 1, decompression_failure_RESERVED); break; case TLS_BROKEN_PACKET: + MARK; tls_alert(context, 1, decode_error); break; case TLS_NO_MEMORY: + MARK; tls_alert(context, 1, internal_error); break; case TLS_NOT_VERIFIED: + MARK; tls_alert(context, 1, bad_record_mac); break; case TLS_BAD_CERTIFICATE: + MARK; if (context->is_server) { /* bad client certificate, continue */ tls_alert(context, 0, bad_certificate); @@ -4218,19 +4282,24 @@ int tls_parse_payload(struct TLSContext *context, const unsigned char *buf, } break; case TLS_UNSUPPORTED_CERTIFICATE: + MARK; tls_alert(context, 1, unsupported_certificate); break; case TLS_NO_COMMON_CIPHER: + MARK; tls_alert(context, 1, insufficient_security); break; case TLS_NOT_UNDERSTOOD: + MARK; tls_alert(context, 1, internal_error); break; case TLS_NO_RENEGOTIATION: + MARK; tls_alert(context, 0, no_renegotiation_RESERVED); payload_res = 0; break; case TLS_DECRYPTION_FAILED: + MARK; tls_alert(context, 1, decryption_failed_RESERVED); break; } @@ -4241,6 +4310,7 @@ int tls_parse_payload(struct TLSContext *context, const unsigned char *buf, if (certificate_verify_alert != no_error) { payload_res = TLS_BAD_CERTIFICATE; + /* TODO this is set but not used */ } /* except renegotiation */ @@ -4248,7 +4318,6 @@ int tls_parse_payload(struct TLSContext *context, const unsigned char *buf, switch (write_packets) { case 1: if (context->client_verified == 2) { - DEBUG_PRINT("<= Building CERTIFICATE \n"); tls_send_certificate(context); context->client_verified = 0; } @@ -4287,9 +4356,7 @@ int tls_parse_payload(struct TLSContext *context, const unsigned char *buf, } tls_send_certificate(context); - tls_send_certificate_verify(context); - tls_send_finished(context); /* new key */ @@ -4349,6 +4416,7 @@ int tls_parse_payload(struct TLSContext *context, const unsigned char *buf, buf += payload_size; buf_len -= payload_size; } + LEAVE; return orig_len; } @@ -5277,6 +5345,7 @@ int tls_consume_stream(struct TLSContext *context) { /* This is the only place tls_parse_message is called */ int consumed = tls_parse_message(context, buffer+index, length); if (consumed < 0) { + fprintf(stderr, "parse message error: %d\n", consumed); err_flag = consumed; break; } @@ -5567,21 +5636,35 @@ int tls_connect(struct TLSContext *context) { int res; ssize_t read_size; - if (!context || context->fd <= 0 || context->critical_error) { + MARK; + if (!context || context->fd < 0 || context->critical_error) { + if (!context) { + MARK; + } else if (context->fd < 0) { + MARK; + } else { + MARK; + } + return TLS_GENERIC_ERROR; } + MARK; if (context->is_server) { return TLS_UNEXPECTED_MESSAGE; } + MARK; res = tls_queue_packet(tls_build_client_hello(context)); + MARK; if (res < 0) { return res; } + MARK; res = tls_fsync(context); + MARK; if (res < 0) { return res; } @@ -5593,13 +5676,19 @@ int tls_connect(struct TLSContext *context) { return res; } } + MARK; if (tls_established(context)) { + MARK; return 1; } + MARK; if (context->critical_error) { + fprintf(stderr, "critical error: %d\n", + context->critical_error); return TLS_GENERIC_ERROR; } } + MARK; return read_size; } @@ -5677,7 +5766,7 @@ ssize_t tls_read(struct TLSContext *context, void *buf, size_t count) { return TLS_GENERIC_ERROR; } - if (tls_established(context) != 1) { + if (!tls_established(context)) { return TLS_GENERIC_ERROR; }