openssl/test/wpackettest.c
Matt Caswell 08029dfa03 Convert WPACKET_put_bytes to use convenience macros
All the other functions that take an argument for the number of bytes
use convenience macros for this purpose. We should do the same with
WPACKET_put_bytes().

Reviewed-by: Rich Salz <rsalz@openssl.org>
2016-09-20 14:47:44 +01:00

413 lines
14 KiB
C

/*
* Copyright 2016 The OpenSSL Project Authors. All Rights Reserved.
*
* Licensed under the OpenSSL license (the "License"). You may not use
* this file except in compliance with the License. You can obtain a copy
* in the file LICENSE in the source distribution or at
* https://www.openssl.org/source/license.html
*/
#include <string.h>
#include <openssl/buffer.h>
#include "../ssl/packet_locl.h"
#include "testutil.h"
const static unsigned char simple1 = 0xff;
const static unsigned char simple2[] = { 0x01, 0xff };
const static unsigned char simple3[] = { 0x00, 0x00, 0x00, 0x01, 0xff };
const static unsigned char nestedsub[] = { 0x03, 0xff, 0x01, 0xff };
const static unsigned char seqsub[] = { 0x01, 0xff, 0x01, 0xff };
const static unsigned char empty = 0x00;
const static unsigned char alloc[] = { 0x02, 0xfe, 0xff };
const static unsigned char submem[] = { 0x03, 0x02, 0xfe, 0xff };
static BUF_MEM *buf;
static void testfail(const char *msg, WPACKET *pkt)
{
fprintf(stderr, "%s", msg);
WPACKET_cleanup(pkt);
}
static int test_WPACKET_init(void)
{
WPACKET pkt;
int i;
size_t written;
if (!WPACKET_init(&pkt, buf)
|| !WPACKET_put_bytes_u8(&pkt, 0xff)
/* Closing a top level WPACKET should fail */
|| WPACKET_close(&pkt)
/* Finishing a top level WPACKET should succeed */
|| !WPACKET_finish(&pkt)
/*
* Can't call close or finish on a WPACKET that's already
* finished.
*/
|| WPACKET_close(&pkt)
|| WPACKET_finish(&pkt)
|| !WPACKET_get_total_written(&pkt, &written)
|| written != sizeof(simple1)
|| memcmp(buf->data, &simple1, written) != 0) {
testfail("test_WPACKET_init():1 failed\n", &pkt);
return 0;
}
/* Now try with a one byte length prefix */
if (!WPACKET_init_len(&pkt, buf, 1)
|| !WPACKET_put_bytes_u8(&pkt, 0xff)
|| !WPACKET_finish(&pkt)
|| !WPACKET_get_total_written(&pkt, &written)
|| written != sizeof(simple2)
|| memcmp(buf->data, &simple2, written) != 0) {
testfail("test_WPACKET_init():2 failed\n", &pkt);
return 0;
}
/* And a longer length prefix */
if (!WPACKET_init_len(&pkt, buf, 4)
|| !WPACKET_put_bytes_u8(&pkt, 0xff)
|| !WPACKET_finish(&pkt)
|| !WPACKET_get_total_written(&pkt, &written)
|| written != sizeof(simple3)
|| memcmp(buf->data, &simple3, written) != 0) {
testfail("test_WPACKET_init():3 failed\n", &pkt);
return 0;
}
if (!WPACKET_init_len(&pkt, buf, 1)) {
testfail("test_WPACKET_init():4 failed\n", &pkt);
return 0;
}
for (i = 1; i < 257; i++) {
/*
* Putting more bytes in than fit for the size of the length prefix
* should fail
*/
if ((!WPACKET_put_bytes_u8(&pkt, 0xff)) == (i != 256)) {
testfail("test_WPACKET_init():4 failed\n", &pkt);
return 0;
}
}
if (!WPACKET_finish(&pkt)) {
testfail("test_WPACKET_init():4 failed\n", &pkt);
return 0;
}
return 1;
}
static int test_WPACKET_set_max_size(void)
{
WPACKET pkt;
size_t written;
if (!WPACKET_init(&pkt, buf)
/*
* No previous lenbytes set so we should be ok to set the max
* possible max size
*/
|| !WPACKET_set_max_size(&pkt, SIZE_MAX)
/* We should be able to set it smaller too */
|| !WPACKET_set_max_size(&pkt, SIZE_MAX -1)
/* And setting it bigger again should be ok */
|| !WPACKET_set_max_size(&pkt, SIZE_MAX)
|| !WPACKET_finish(&pkt)) {
testfail("test_WPACKET_set_max_size():1 failed\n", &pkt);
return 0;
}
if (!WPACKET_init_len(&pkt, buf, 1)
/*
* Should fail because we already consumed 1 byte with the
* length
*/
|| WPACKET_set_max_size(&pkt, 0)
/*
* Max size can't be bigger than biggest that will fit in
* lenbytes
*/
|| WPACKET_set_max_size(&pkt, 0x0101)
/* It can be the same as the maximum possible size */
|| !WPACKET_set_max_size(&pkt, 0x0100)
/* Or it can be less */
|| !WPACKET_set_max_size(&pkt, 0x01)
/*
* Should fail because packet is already filled
*/
|| WPACKET_put_bytes_u8(&pkt, 0xff)
/*
* You can't put in more bytes than max size
*/
|| !WPACKET_set_max_size(&pkt, 0x02)
|| !WPACKET_put_bytes_u8(&pkt, 0xff)
|| WPACKET_put_bytes_u8(&pkt, 0xff)
|| !WPACKET_finish(&pkt)
|| !WPACKET_get_total_written(&pkt, &written)
|| written != sizeof(simple2)
|| memcmp(buf->data, &simple2, written) != 0) {
testfail("test_WPACKET_set_max_size():2 failed\n", &pkt);
return 0;
}
return 1;
}
static int test_WPACKET_start_sub_packet(void)
{
WPACKET pkt;
size_t written;
size_t len;
if (!WPACKET_init(&pkt, buf)
|| !WPACKET_start_sub_packet(&pkt)
|| !WPACKET_put_bytes_u8(&pkt, 0xff)
/* Can't finish because we have a sub packet */
|| WPACKET_finish(&pkt)
|| !WPACKET_close(&pkt)
/* Sub packet is closed so can't close again */
|| WPACKET_close(&pkt)
/* Now a top level so finish should succeed */
|| !WPACKET_finish(&pkt)
|| !WPACKET_get_total_written(&pkt, &written)
|| written != sizeof(simple1)
|| memcmp(buf->data, &simple1, written) != 0) {
testfail("test_WPACKET_start_sub_packet():1 failed\n", &pkt);
return 0;
}
/* Single sub-packet with length prefix */
if (!WPACKET_init(&pkt, buf)
|| !WPACKET_start_sub_packet_u8(&pkt)
|| !WPACKET_put_bytes_u8(&pkt, 0xff)
|| !WPACKET_close(&pkt)
|| !WPACKET_finish(&pkt)
|| !WPACKET_get_total_written(&pkt, &written)
|| written != sizeof(simple2)
|| memcmp(buf->data, &simple2, written) != 0) {
testfail("test_WPACKET_start_sub_packet():2 failed\n", &pkt);
return 0;
}
/* Nested sub-packets with length prefixes */
if (!WPACKET_init(&pkt, buf)
|| !WPACKET_start_sub_packet_u8(&pkt)
|| !WPACKET_put_bytes_u8(&pkt, 0xff)
|| !WPACKET_start_sub_packet_u8(&pkt)
|| !WPACKET_put_bytes_u8(&pkt, 0xff)
|| !WPACKET_get_length(&pkt, &len)
|| len != 1
|| !WPACKET_close(&pkt)
|| !WPACKET_get_length(&pkt, &len)
|| len != 3
|| !WPACKET_close(&pkt)
|| !WPACKET_finish(&pkt)
|| !WPACKET_get_total_written(&pkt, &written)
|| written != sizeof(nestedsub)
|| memcmp(buf->data, &nestedsub, written) != 0) {
testfail("test_WPACKET_start_sub_packet():3 failed\n", &pkt);
return 0;
}
/* Sequential sub-packets with length prefixes */
if (!WPACKET_init(&pkt, buf)
|| !WPACKET_start_sub_packet_u8(&pkt)
|| !WPACKET_put_bytes_u8(&pkt, 0xff)
|| !WPACKET_close(&pkt)
|| !WPACKET_start_sub_packet_u8(&pkt)
|| !WPACKET_put_bytes_u8(&pkt, 0xff)
|| !WPACKET_close(&pkt)
|| !WPACKET_finish(&pkt)
|| !WPACKET_get_total_written(&pkt, &written)
|| written != sizeof(seqsub)
|| memcmp(buf->data, &seqsub, written) != 0) {
testfail("test_WPACKET_start_sub_packet():4 failed\n", &pkt);
return 0;
}
return 1;
}
static int test_WPACKET_set_flags(void)
{
WPACKET pkt;
size_t written;
/* Set packet to be non-zero length */
if (!WPACKET_init(&pkt, buf)
|| !WPACKET_set_flags(&pkt, WPACKET_FLAGS_NON_ZERO_LENGTH)
/* Should fail because of zero length */
|| WPACKET_finish(&pkt)
|| !WPACKET_put_bytes_u8(&pkt, 0xff)
|| !WPACKET_finish(&pkt)
|| !WPACKET_get_total_written(&pkt, &written)
|| written != sizeof(simple1)
|| memcmp(buf->data, &simple1, written) != 0) {
testfail("test_WPACKET_set_flags():1 failed\n", &pkt);
return 0;
}
/* Repeat above test in a sub-packet */
if (!WPACKET_init(&pkt, buf)
|| !WPACKET_start_sub_packet(&pkt)
|| !WPACKET_set_flags(&pkt, WPACKET_FLAGS_NON_ZERO_LENGTH)
/* Should fail because of zero length */
|| WPACKET_close(&pkt)
|| !WPACKET_put_bytes_u8(&pkt, 0xff)
|| !WPACKET_close(&pkt)
|| !WPACKET_finish(&pkt)
|| !WPACKET_get_total_written(&pkt, &written)
|| written != sizeof(simple1)
|| memcmp(buf->data, &simple1, written) != 0) {
testfail("test_WPACKET_set_flags():2 failed\n", &pkt);
return 0;
}
/* Set packet to abandon non-zero length */
if (!WPACKET_init_len(&pkt, buf, 1)
|| !WPACKET_set_flags(&pkt, WPACKET_FLAGS_ABANDON_ON_ZERO_LENGTH)
|| !WPACKET_finish(&pkt)
|| !WPACKET_get_total_written(&pkt, &written)
|| written != 0) {
testfail("test_WPACKET_set_flags():3 failed\n", &pkt);
return 0;
}
/* Repeat above test but only abandon a sub-packet */
if (!WPACKET_init_len(&pkt, buf, 1)
|| !WPACKET_start_sub_packet_u8(&pkt)
|| !WPACKET_set_flags(&pkt, WPACKET_FLAGS_ABANDON_ON_ZERO_LENGTH)
|| !WPACKET_close(&pkt)
|| !WPACKET_finish(&pkt)
|| !WPACKET_get_total_written(&pkt, &written)
|| written != sizeof(empty)
|| memcmp(buf->data, &empty, written) != 0) {
testfail("test_WPACKET_set_flags():4 failed\n", &pkt);
return 0;
}
/* And repeat with a non empty sub-packet */
if (!WPACKET_init(&pkt, buf)
|| !WPACKET_start_sub_packet_u8(&pkt)
|| !WPACKET_set_flags(&pkt, WPACKET_FLAGS_ABANDON_ON_ZERO_LENGTH)
|| !WPACKET_put_bytes_u8(&pkt, 0xff)
|| !WPACKET_close(&pkt)
|| !WPACKET_finish(&pkt)
|| !WPACKET_get_total_written(&pkt, &written)
|| written != sizeof(simple2)
|| memcmp(buf->data, &simple2, written) != 0) {
testfail("test_WPACKET_set_flags():5 failed\n", &pkt);
return 0;
}
return 1;
}
static int test_WPACKET_allocate_bytes(void)
{
WPACKET pkt;
size_t written;
unsigned char *bytes;
if (!WPACKET_init_len(&pkt, buf, 1)
|| !WPACKET_allocate_bytes(&pkt, 2, &bytes)) {
testfail("test_WPACKET_allocate_bytes():1 failed\n", &pkt);
return 0;
}
bytes[0] = 0xfe;
bytes[1] = 0xff;
if (!WPACKET_finish(&pkt)
|| !WPACKET_get_total_written(&pkt, &written)
|| written != sizeof(alloc)
|| memcmp(buf->data, &alloc, written) != 0) {
testfail("test_WPACKET_allocate_bytes():2 failed\n", &pkt);
return 0;
}
/* Repeat with WPACKET_sub_allocate_bytes */
if (!WPACKET_init_len(&pkt, buf, 1)
|| !WPACKET_sub_allocate_bytes_u8(&pkt, 2, &bytes)) {
testfail("test_WPACKET_allocate_bytes():3 failed\n", &pkt);
return 0;
}
bytes[0] = 0xfe;
bytes[1] = 0xff;
if (!WPACKET_finish(&pkt)
|| !WPACKET_get_total_written(&pkt, &written)
|| written != sizeof(submem)
|| memcmp(buf->data, &submem, written) != 0) {
testfail("test_WPACKET_allocate_bytes():4 failed\n", &pkt);
return 0;
}
return 1;
}
static int test_WPACKET_memcpy(void)
{
WPACKET pkt;
size_t written;
const unsigned char bytes[] = { 0xfe, 0xff };
if (!WPACKET_init_len(&pkt, buf, 1)
|| !WPACKET_memcpy(&pkt, bytes, sizeof(bytes))
|| !WPACKET_finish(&pkt)
|| !WPACKET_get_total_written(&pkt, &written)
|| written != sizeof(alloc)
|| memcmp(buf->data, &alloc, written) != 0) {
testfail("test_WPACKET_memcpy():1 failed\n", &pkt);
return 0;
}
/* Repeat with WPACKET_sub_memcpy() */
if (!WPACKET_init_len(&pkt, buf, 1)
|| !WPACKET_sub_memcpy_u8(&pkt, bytes, sizeof(bytes))
|| !WPACKET_finish(&pkt)
|| !WPACKET_get_total_written(&pkt, &written)
|| written != sizeof(submem)
|| memcmp(buf->data, &submem, written) != 0) {
testfail("test_WPACKET_memcpy():2 failed\n", &pkt);
return 0;
}
return 1;
}
int main(int argc, char *argv[])
{
BIO *err = NULL;
int testresult = 0;
err = BIO_new_fp(stderr, BIO_NOCLOSE | BIO_FP_TEXT);
CRYPTO_set_mem_debug(1);
CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_ON);
buf = BUF_MEM_new();
if (buf != NULL) {
ADD_TEST(test_WPACKET_init);
ADD_TEST(test_WPACKET_set_max_size);
ADD_TEST(test_WPACKET_start_sub_packet);
ADD_TEST(test_WPACKET_set_flags);
ADD_TEST(test_WPACKET_allocate_bytes);
ADD_TEST(test_WPACKET_memcpy);
testresult = run_tests(argv[0]);
BUF_MEM_free(buf);
}
#ifndef OPENSSL_NO_CRYPTO_MDEBUG
if (CRYPTO_mem_leaks(err) <= 0)
testresult = 1;
#endif
BIO_free(err);
if (!testresult)
printf("PASS\n");
return testresult;
}