xref: /reactos/base/applications/mstsc/asn.c (revision 40462c92)
1 /* -*- c-basic-offset: 8 -*-
2    rdesktop: A Remote Desktop Protocol client.
3    ASN.1 utility functions
4    Copyright 2012 Henrik Andersson <hean01@cendio.se> for Cendio AB
5 
6    This program is free software: you can redistribute it and/or modify
7    it under the terms of the GNU General Public License as published by
8    the Free Software Foundation, either version 3 of the License, or
9    (at your option) any later version.
10 
11    This program is distributed in the hope that it will be useful,
12    but WITHOUT ANY WARRANTY; without even the implied warranty of
13    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.	See the
14    GNU General Public License for more details.
15 
16    You should have received a copy of the GNU General Public License
17    along with this program.	If not, see <http://www.gnu.org/licenses/>.
18 */
19 
20 #include "precomp.h"
21 
22 
23 /* Parse an ASN.1 BER header */
24 RD_BOOL
25 ber_parse_header(STREAM s, int tagval, int *length)
26 {
27 	int tag, len;
28 
29 	if (tagval > 0xff)
30 	{
31 		in_uint16_be(s, tag);
32 	}
33 	else
34 	{
35 		in_uint8(s, tag);
36 	}
37 
38 	if (tag != tagval)
39 	{
40 		error("expected tag %d, got %d\n", tagval, tag);
41 		return False;
42 	}
43 
44 	in_uint8(s, len);
45 
46 	if (len & 0x80)
47 	{
48 		len &= ~0x80;
49 		*length = 0;
50 		while (len--)
51 			next_be(s, *length);
52 	}
53 	else
54 		*length = len;
55 
56 	return s_check(s);
57 }
58 
59 /* Output an ASN.1 BER header */
60 void
61 ber_out_header(STREAM s, int tagval, int length)
62 {
63 	if (tagval > 0xff)
64 	{
65 		out_uint16_be(s, tagval);
66 	}
67 	else
68 	{
69 		out_uint8(s, tagval);
70 	}
71 
72 	if (length >= 0x80)
73 	{
74 		out_uint8(s, 0x82);
75 		out_uint16_be(s, length);
76 	}
77 	else
78 		out_uint8(s, length);
79 }
80 
81 /* Output an ASN.1 BER integer */
82 void
83 ber_out_integer(STREAM s, int value)
84 {
85 	ber_out_header(s, BER_TAG_INTEGER, 2);
86 	out_uint16_be(s, value);
87 }
88 
89 RD_BOOL
90 ber_in_header(STREAM s, int *tagval, int *decoded_len)
91 {
92 	in_uint8(s, *tagval);
93 	in_uint8(s, *decoded_len);
94 
95 	if (*decoded_len < 0x80)
96 		return True;
97 	else if (*decoded_len == 0x81)
98 	{
99 		in_uint8(s, *decoded_len);
100 		return True;
101 	}
102 	else if (*decoded_len == 0x82)
103 	{
104 		in_uint16_be(s, *decoded_len);
105 		return True;
106 	}
107 
108 	return False;
109 }
110