From 37da672908876ead09825b47882ba6550037e837 Mon Sep 17 00:00:00 2001 From: Cendio Date: Wed, 17 Jan 2018 14:38:06 +0100 Subject: [PATCH] Added ber_out_sequence() util for writing ASN.1 sequences Signed-off-by: Henrik Andersson Signed-off-by: Thomas Nilefalk --- asn.c | 11 +++++ proto.h | 1 + tests/Makefile | 10 +++- tests/asn_test.c | 123 +++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 144 insertions(+), 1 deletion(-) create mode 100644 tests/asn_test.c diff --git a/asn.c b/asn.c index 09e67e5..26b0e9b 100644 --- a/asn.c +++ b/asn.c @@ -56,6 +56,17 @@ ber_parse_header(STREAM s, int tagval, int *length) return s_check(s); } +void +ber_out_sequence(STREAM out, STREAM content) +{ + size_t length; + length = (content ? s_length(content) : 0); + ber_out_header(out, BER_TAG_SEQUENCE | BER_TAG_CONSTRUCTED, length); + if (content) + out_stream(out, content); +} + + /* Output an ASN.1 BER header */ void ber_out_header(STREAM s, int tagval, int length) diff --git a/proto.h b/proto.h index f346646..54ed81b 100644 --- a/proto.h +++ b/proto.h @@ -226,6 +226,7 @@ RD_BOOL ber_in_header(STREAM s, int *tagval, int *length); void ber_out_header(STREAM s, int tagval, int length); RD_BOOL ber_parse_header(STREAM s, int tagval, int *length); void ber_out_integer(STREAM s, int value); +void ber_out_sequence(STREAM s, STREAM contents); /* xclip.c */ void ui_clip_format_announce(uint8 * data, uint32 length); diff --git a/tests/Makefile b/tests/Makefile index 71f6c0f..c506caa 100644 --- a/tests/Makefile +++ b/tests/Makefile @@ -2,7 +2,7 @@ CC=gcc CFLAGS=-fPIC -Wall -Wextra -ggdb -gdwarf-2 -g3 CGREEN_RUNNER=cgreen-runner -TESTS=resize rdp xwin utils parse_geometry mcs +TESTS=resize rdp xwin utils parse_geometry mcs asn RDP_MOCKS=ui_mock.o bitmap_mock.o secure_mock.o ssl_mock.o mppc_mock.o \ @@ -25,6 +25,8 @@ PARSE_MOCKS=ui_mock.o rdpdr_mock.o rdpedisp_mock.o ssl_mock.o ctrl_mock.o secure MCS_MOCKS=utils_mock.o secure_mock.o iso_mock.o +ASN_MOCKS=utils_mock.o + all: test .PHONY: test @@ -54,6 +56,12 @@ parse_geometry: parse_geometry_test.o $(PARSE_MOCKS) ../rdesktop.c mcs: mcs_test.o $(MCS_MOCKS) stream.o $(CC) $(CFLAGS) -shared -lcgreen -o $@ $^ +asn: asn_test.o $(ASN_MOCKS) asn.o stream.o + $(CC) $(CFLAGS) -shared -lcgreen -o $@ $^ + +asn.o: ../asn.c + $(CC) $(CFLAGS) -c -o $@ $^ + stream.o: ../stream.c $(CC) $(CFLAGS) -c -o $@ $^ diff --git a/tests/asn_test.c b/tests/asn_test.c new file mode 100644 index 0000000..ff47d93 --- /dev/null +++ b/tests/asn_test.c @@ -0,0 +1,123 @@ +#include +#include +#include "../rdesktop.h" + +char g_codepage[16]; + +/* Boilerplate */ +Describe(ASN1); +BeforeEach(ASN1) {} +AfterEach(ASN1) {} + +/* malloc; exit if out of memory */ +void * +xmalloc(int size) +{ + void *mem = malloc(size); + if (mem == NULL) + { + logger(Core, Error, "xmalloc, failed to allocate %d bytes", size); + exit(EX_UNAVAILABLE); + } + return mem; +} + +/* realloc; exit if out of memory */ +void * +xrealloc(void *oldmem, size_t size) +{ + void *mem; + + if (size == 0) + size = 1; + mem = realloc(oldmem, size); + if (mem == NULL) + { + logger(Core, Error, "xrealloc, failed to reallocate %ld bytes", size); + exit(EX_UNAVAILABLE); + } + return mem; +} + +/* free */ +void +xfree(void *mem) +{ + free(mem); +} + +static struct stream *stream_new(size_t size) { + struct stream *s; + s = malloc(sizeof(struct stream)); + memset(s, 0, sizeof(struct stream)); + s_realloc(s, size); + s_reset(s); + return(s); +} + + +Ensure(ASN1, can_create_empty_sequence) +{ + struct stream *s, *empty; + uint8_t expected_data[] = {0x30, 0x00}; + + s = stream_new(100); + empty = stream_new(100); + + ber_out_sequence(s, empty); + s_mark_end(s); + + assert_that(s_length(s), is_equal_to(sizeof(expected_data))); + assert_that(s->data, is_equal_to_contents_of(expected_data, sizeof(expected_data))); +} + +Ensure(ASN1, can_create_empty_sequence_using_null) +{ + struct stream *s; + uint8_t expected_data[] = {0x30, 0x00}; + + s = stream_new(100); + + ber_out_sequence(s, NULL); + s_mark_end(s); + + assert_that(s_length(s), is_equal_to(sizeof(expected_data))); + assert_that(s->data, is_equal_to_contents_of(expected_data, sizeof(expected_data))); +} + +Ensure(ASN1, can_create_sequence_of_two_integers) +{ + struct stream *s, *content; + uint8_t expected_data[] = {0x30, 0x08, 0x02, 0x02, 0x00, 0xbe, 0x02, 0x02, 0x00, 0xef}; + + s = stream_new(100); + content = stream_new(100); + + ber_out_integer(content, 0xbe); + ber_out_integer(content, 0xef); + s_mark_end(content); + + ber_out_sequence(s, content); + s_mark_end(s); + + assert_that(s_length(s), is_equal_to(sizeof(expected_data))); + assert_that(s->data, is_equal_to_contents_of(expected_data, sizeof(expected_data))); +} + +Ensure(ASN1, can_create_sequence_of_one_integer) +{ + struct stream *s, *content; + uint8_t expected_data[] = {0x30, 0x04, 0x02, 0x02, 0x00, 0xbe}; + + s = stream_new(100); + content = stream_new(100); + + ber_out_integer(content, 0xbe); + s_mark_end(content); + + ber_out_sequence(s, content); + s_mark_end(s); + + assert_that(s_length(s), is_equal_to(sizeof(expected_data))); + assert_that(s->data, is_equal_to_contents_of(expected_data, sizeof(expected_data))); +}