summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCendio <cendio@pairstation.lkpg.cendio.se>2018-01-17 14:38:06 +0100
committerCendio <cendio@pairstation.lkpg.cendio.se>2018-01-31 11:03:32 +0100
commit37da672908876ead09825b47882ba6550037e837 (patch)
tree1d14a6e2599c2d83e4c85acc0f798fcc9ada89d3
parentbdb92839f3c5cebc2043aef70afa5c0dcfeb62c7 (diff)
downloadrdesktop-37da672908876ead09825b47882ba6550037e837.zip
Added ber_out_sequence() util for writing ASN.1 sequences
Signed-off-by: Henrik Andersson <hean01@cendio.com> Signed-off-by: Thomas Nilefalk <thoni56@cendio.se>
-rw-r--r--asn.c11
-rw-r--r--proto.h1
-rw-r--r--tests/Makefile10
-rw-r--r--tests/asn_test.c123
4 files changed, 144 insertions, 1 deletions
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 <cgreen/cgreen.h>
+#include <cgreen/mocks.h>
+#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)));
+}