diff --git a/ssl/test/header_issue.dat b/ssl/test/header_issue.dat new file mode 100755 index 000000000..a48d23d2b Binary files /dev/null and b/ssl/test/header_issue.dat differ diff --git a/ssl/test/ssltest.c b/ssl/test/ssltest.c index d97e153ae..29fc621db 100644 --- a/ssl/test/ssltest.c +++ b/ssl/test/ssltest.c @@ -1718,6 +1718,64 @@ error: } #endif +/************************************************************************** + * Header issue + * + **************************************************************************/ +static void do_header_issue(void) +{ + uint8_t axtls_buf[2048]; +#ifndef WIN32 + pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL); +#endif + sprintf(axtls_buf, "./axssl s_client -connect localhost:%d", g_port); + system(axtls_buf); +} + +static int header_issue(void) +{ + FILE *f = fopen("../ssl/test/header_issue.dat", "r"); + int server_fd, client_fd, ret = 1; + uint8_t buf[2048]; + int size = 0; + struct sockaddr_in client_addr; + socklen_t clnt_len = sizeof(client_addr); +#ifndef WIN32 + pthread_t thread; +#endif + + if (f == NULL || (server_fd = server_socket_init(&g_port)) < 0) + goto error; + +#ifndef WIN32 + pthread_create(&thread, NULL, + (void *(*)(void *))do_header_issue, NULL); + pthread_detach(thread); +#else + CreateThread(NULL, 1024, (LPTHREAD_START_ROUTINE)do_header_issue, + NULL, 0, NULL); +#endif + if ((client_fd = accept(server_fd, + (struct sockaddr *) &client_addr, &clnt_len)) < 0) + { + ret = SSL_ERROR_SOCK_SETUP_FAILURE; + goto error; + } + + size = fread(buf, 1, sizeof(buf), f); + SOCKET_WRITE(client_fd, buf, size); + usleep(200000); + + ret = 0; +error: + fclose(f); + SOCKET_CLOSE(client_fd); + SOCKET_CLOSE(server_fd); + TTY_FLUSH(); + system("killall axssl"); + return ret; +} + /************************************************************************** * main() * @@ -1820,7 +1878,14 @@ int main(int argc, char *argv[]) system("sh ../ssl/test/killopenssl.sh"); + if (header_issue()) + { + printf("Header tests failed\n"); + goto cleanup; + } + ret = 0; /* all ok */ + printf("**** ALL TESTS PASSED ****\n"); TTY_FLUSH(); cleanup: if (ret) diff --git a/ssl/tls1.c b/ssl/tls1.c index baf44dc97..de5597fbd 100755 --- a/ssl/tls1.c +++ b/ssl/tls1.c @@ -1241,6 +1241,7 @@ int basic_read(SSL *ssl, uint8_t **in_data) switch (ssl->record_type) { case PT_HANDSHAKE_PROTOCOL: + ssl->bm_proc_index = 0; ret = do_handshake(ssl, buf, read_len); break; @@ -1723,10 +1724,10 @@ EXP_FUNC int STDCALL ssl_verify_cert(const SSL *ssl) int process_certificate(SSL *ssl, X509_CTX **x509_ctx) { int ret = SSL_OK; + uint8_t *buf = &ssl->bm_data[ssl->bm_proc_index]; int pkt_size = ssl->bm_index; int cert_size, offset = 5; - int total_cert_size = (ssl->bm_data[offset]<<8) + - ssl->bm_data[offset+1]; + int total_cert_size = (buf[offset]<<8) + buf[offset+1]; int is_client = IS_SET_SSL_FLAG(SSL_IS_CLIENT); X509_CTX **chain = x509_ctx; offset += 2; @@ -1736,10 +1737,10 @@ int process_certificate(SSL *ssl, X509_CTX **x509_ctx) while (offset < total_cert_size) { offset++; /* skip empty char */ - cert_size = (ssl->bm_data[offset]<<8) + ssl->bm_data[offset+1]; + cert_size = (buf[offset]<<8) + buf[offset+1]; offset += 2; - if (x509_new(&ssl->bm_data[offset], NULL, chain)) + if (x509_new(&buf[offset], NULL, chain)) { ret = SSL_ERROR_BAD_CERTIFICATE; goto error; @@ -1759,6 +1760,7 @@ int process_certificate(SSL *ssl, X509_CTX **x509_ctx) DISPLAY_CERT(ssl, "process_certificate", *x509_ctx); ssl->next_state = is_client ? HS_SERVER_HELLO_DONE : HS_CLIENT_KEY_XCHG; + ssl->bm_proc_index += offset; error: return ret; } diff --git a/ssl/tls1.h b/ssl/tls1.h index 1d07f29ac..45f13527d 100755 --- a/ssl/tls1.h +++ b/ssl/tls1.h @@ -173,6 +173,7 @@ struct _SSL uint8_t *bm_data; uint16_t bm_index; uint16_t bm_read_index; + uint16_t bm_proc_index; struct _SSL *next; /* doubly linked list */ struct _SSL *prev; SSL_CERT *certs; diff --git a/ssl/tls1_clnt.c b/ssl/tls1_clnt.c index 05fca96cb..939318b0e 100644 --- a/ssl/tls1_clnt.c +++ b/ssl/tls1_clnt.c @@ -221,11 +221,10 @@ static int process_server_hello(SSL *ssl) { uint8_t *buf = ssl->bm_data; int pkt_size = ssl->bm_index; - int offset; int version = (buf[4] << 4) + buf[5]; int num_sessions = ssl->ssl_ctx->num_sessions; uint8_t sess_id_size; - int ret = SSL_OK; + int offset, ret = SSL_OK; /* check that we are talking to a TLSv1 server */ if (version != 0x31) @@ -259,7 +258,9 @@ static int process_server_hello(SSL *ssl) ssl->next_state = IS_SET_SSL_FLAG(SSL_SESSION_RESUME) ? HS_FINISHED : HS_CERTIFICATE; + offset++; // skip the compr PARANOIA_CHECK(pkt_size, offset); + ssl->bm_proc_index = offset+1; error: return ret; @@ -311,10 +312,18 @@ static int send_client_key_xchg(SSL *ssl) */ static int process_cert_req(SSL *ssl) { + uint8_t *buf = &ssl->bm_data[ssl->bm_proc_index]; + int ret = SSL_OK; + int offset = (buf[2] << 4) + buf[3]; + int pkt_size = ssl->bm_index; + /* don't do any processing - we will send back an RSA certificate anyway */ ssl->next_state = HS_SERVER_HELLO_DONE; SET_SSL_FLAG(SSL_HAS_CERT_REQ); - return SSL_OK; + ssl->bm_proc_index += offset; + PARANOIA_CHECK(pkt_size, offset); +error: + return ret; } /*