]> pd.if.org Git - zpackage/blobdiff - crypto/parse_message.c
fix bug with dhe cbc mode
[zpackage] / crypto / parse_message.c
index e4e7b15ef95a61bd56c4a36169c229c05becba66..8f722992343cd9352b12f8b1696e3623789e3ab5 100644 (file)
 #define ntohll(x) ((1==ntohl(1)) ? (x) : ((uint64_t)ntohl((x) & 0xFFFFFFFF) << 32) | ntohl((x) >> 32))
 #endif
 
+#ifdef DEBUG
+static char *tls_alert_msg_name(int code) {
+       switch (code) {
+               case 0: return "close_notify"; break;
+               case 10: return "unexpected_message"; break;
+               case 20: return "bad_record_mac"; break;
+               default: break;
+       }
+       return "unknown alert";
+}
+#endif
+
 static uint16_t get16(const unsigned char *buf) {
        uint16_t res;
 
@@ -293,14 +305,23 @@ static int decrypt_other(struct TLSContext *context, uint16_t length, int
                *buf, struct tls_buffer *pt_buffer) {
        int err;
 
+       ENTER;
+       tls_buffer_expand(pt_buffer, length);
+       DEBUG_PRINTLN("cbc_decrypt(%p, %p, %lu, %p)\n",
+                       buf+header_size, pt_buffer->buffer,
+                       (unsigned long)length, &context->crypto.ctx_remote.aes_remote);
        err = cbc_decrypt(buf+header_size, pt_buffer->buffer, length,
                        &context->crypto.ctx_remote.aes_remote);
        if (err) {
-               DEBUG_PRINT("Decryption error %i\n", (int) err);
+               DEBUG_PRINTLN("Decryption error %d %s\n", err,
+                               error_to_string(err));
+               LEAVE;
                return TLS_BROKEN_PACKET;
        }
+       pt_buffer->len = length;
        unsigned char padding_byte = pt_buffer->buffer[length - 1];
        unsigned char padding = padding_byte + 1;
+       DEBUG_PRINTLN("cbc padding byte = %d\n", (int)padding_byte);
 
        /* poodle check */
        int padding_index = length - padding;
@@ -309,9 +330,9 @@ static int decrypt_other(struct TLSContext *context, uint16_t length, int
                int limit = length - 1;
                for (i = length - padding; i < limit; i++) {
                        if (pt_buffer->buffer[i] != padding_byte) {
-                               DEBUG_PRINT
-                                       ("BROKEN PACKET (POODLE ?)\n");
+                               DEBUG_PRINTLN("BROKEN PACKET (POODLE ?)\n");
                                tls_alert(context, 1, decrypt_error);
+                               LEAVE;
                                return TLS_BROKEN_PACKET;
                        }
                }
@@ -323,23 +344,24 @@ static int decrypt_other(struct TLSContext *context, uint16_t length, int
                pt_buffer->len -= padding;
        }
 
-       DEBUG_DUMP_HEX_LABEL("decrypted3", pt_buffer->buffer, decrypted_length);
-       ptr = pt_buffer->buffer;
+       DEBUG_DUMP_HEX_LABEL("decrypted", pt_buffer->buffer, decrypted_length);
 
        if (decrypted_length > TLS_AES_IV_LENGTH) {
                decrypted_length -= TLS_AES_IV_LENGTH;
-               ptr += TLS_AES_IV_LENGTH;
                tls_buffer_shift(pt_buffer, TLS_AES_IV_LENGTH);
        }
+       ptr = pt_buffer->buffer;
        length = decrypted_length;
 
        unsigned int mac_size = tls_mac_length(context);
        if (length < mac_size || !mac_size) {
-               DEBUG_PRINT("BROKEN PACKET\n");
+               DEBUG_PRINTLN("BROKEN PACKET\n");
                tls_alert(context, 1, decrypt_error);
+                               LEAVE;
                return TLS_BROKEN_PACKET;
        }
 
+       DEBUG_PRINTLN("mac size %u\n", mac_size);
        length -= mac_size;
        pt_buffer->len -= mac_size;
 
@@ -352,16 +374,18 @@ static int decrypt_other(struct TLSContext *context, uint16_t length, int
                        ptr, length, hmac_out, mac_size);
        if (hmac_out_len != mac_size
                        || memcmp(message_hmac, hmac_out, mac_size)) {
-               DEBUG_PRINT("INTEGRITY CHECK FAILED (msg length %i)\n",
+               DEBUG_PRINTLN("INTEGRITY CHECK FAILED (msg length %i)\n",
                                length);
                DEBUG_DUMP_HEX_LABEL("HMAC RECEIVED", message_hmac, mac_size);
                DEBUG_DUMP_HEX_LABEL("HMAC COMPUTED", hmac_out, hmac_out_len);
 
                tls_alert(context, 1, bad_record_mac);
 
+               LEAVE;
                return TLS_INTEGRITY_FAILED;
        }
 
+       LEAVE;
        return 0;
 }
 
@@ -408,7 +432,10 @@ int tls_parse_message(struct TLSContext *context, unsigned char *buf,
 
        int header_size = res;
 
+       ENTER;
+
        if (buf_len < res) {
+               LEAVE;
                return TLS_NEED_MORE_DATA;
        }
 
@@ -418,6 +445,7 @@ int tls_parse_message(struct TLSContext *context, unsigned char *buf,
        buf_pos += 2;
 
        if (!tls_supported_version(version)) {
+               LEAVE;
                return TLS_NOT_SAFE;
        }
 
@@ -426,7 +454,7 @@ int tls_parse_message(struct TLSContext *context, unsigned char *buf,
 
        ptr = buf + buf_pos;
 
-       DEBUG_PRINT("Message type: %0x, length: %i\n", (int)type, (int)length);
+       DEBUG_PRINTLN("Message type: %d, length: %d\n", (int)type, (int)length);
 
        /* this buffer can go out of scope */
        tls_buffer_init(&pt, 0);
@@ -438,6 +466,7 @@ int tls_parse_message(struct TLSContext *context, unsigned char *buf,
                if (!context->crypto.created) {
                        DEBUG_PRINT("Encryption context not created\n");
                        random_sleep(TLS_MAX_ERROR_SLEEP_uS);
+                       LEAVE;
                        return TLS_BROKEN_PACKET;
                }
 
@@ -447,12 +476,14 @@ int tls_parse_message(struct TLSContext *context, unsigned char *buf,
                if (rv != 0) {
                        tls_buffer_free(&pt);
                        random_sleep(TLS_MAX_ERROR_SLEEP_uS);
+                       LEAVE;
                        return rv;
                }
 
                if (pt.error) {
                        tls_buffer_free(&pt);
                        random_sleep(TLS_MAX_ERROR_SLEEP_uS);
+                       LEAVE;
                        return TLS_NO_MEMORY;
                }
 
@@ -524,15 +555,14 @@ int tls_parse_message(struct TLSContext *context, unsigned char *buf,
                        break;
                        /* alert */
                case TLS_ALERT:
-                       DEBUG_PRINT("ALERT MESSAGE\n");
+                       DEBUG_PRINTLN("ALERT MESSAGE\n");
                        if (length >= 2) {
-                               DEBUG_PRINT("ALERT MESSAGE ...\n");
-                               DEBUG_DUMP_HEX(ptr, length);
                                int level = ptr[0];
                                int code = ptr[1];
-                               DEBUG_PRINT("level = %d, code = %d\n",
-                                               level, code);
+                               DEBUG_PRINTLN("level = %d, code = %d\n", level, code);
                                if (level == TLS_ALERT_CRITICAL) {
+                                       DEBUG_PRINTLN("critical error: %s\n",
+                                                       tls_alert_msg_name(code));
                                        context->critical_error = 1;
                                        res = TLS_ERROR_ALERT;
                                }
@@ -551,12 +581,15 @@ int tls_parse_message(struct TLSContext *context, unsigned char *buf,
        tls_buffer_free(&pt);
 
        if (payload_res < 0) {
+               LEAVE;
                return payload_res;
        }
 
        if (res > 0) {
+               LEAVE;
                return header_size + length;
        }
 
+       LEAVE;
        return res;
 }