2
* FreeRDP: A Remote Desktop Protocol Implementation
3
* ASN.1 Encoding Rules (BER/DER common functions)
5
* Copyright 2011 Marc-Andre Moreau <marcandre.moreau@gmail.com>
6
* Modified by Jiten Pathy
8
* Licensed under the Apache License, Version 2.0 (the "License");
9
* you may not use this file except in compliance with the License.
10
* You may obtain a copy of the License at
12
* http://www.apache.org/licenses/LICENSE-2.0
14
* Unless required by applicable law or agreed to in writing, software
15
* distributed under the License is distributed on an "AS IS" BASIS,
16
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17
* See the License for the specific language governing permissions and
18
* limitations under the License.
25
#include <winpr/crt.h>
27
#include <freerdp/crypto/er.h>
28
#include <freerdp/crypto/ber.h>
29
#include <freerdp/crypto/der.h>
31
void er_read_length(wStream* s, int* length)
35
Stream_Read_UINT8(s, byte);
42
Stream_Read_UINT8(s, *length);
44
Stream_Read_UINT16_BE(s, *length);
55
* @param length length
58
int er_write_length(wStream* s, int length, BOOL flag)
61
return der_write_length(s, length);
63
return ber_write_length(s, length);
66
int _er_skip_length(int length)
74
int er_get_content_length(int length)
76
if (length - 1 > 0x7F)
83
* Read er Universal tag.
85
* @param tag er universally-defined tag
89
BOOL er_read_universal_tag(wStream* s, BYTE tag, BOOL pc)
93
Stream_Read_UINT8(s, byte);
95
if (byte != (ER_CLASS_UNIV | ER_PC(pc) | (ER_TAG_MASK & tag)))
102
* Write er Universal tag.
104
* @param tag er universally-defined tag
105
* @param pc primitive (FALSE) or constructed (TRUE)
108
void er_write_universal_tag(wStream* s, BYTE tag, BOOL pc)
110
Stream_Write_UINT8(s, (ER_CLASS_UNIV | ER_PC(pc)) | (ER_TAG_MASK & tag));
114
* Read er Application tag.
116
* @param tag er application-defined tag
117
* @param length length
120
BOOL er_read_application_tag(wStream* s, BYTE tag, int* length)
126
Stream_Read_UINT8(s, byte);
128
if (byte != ((ER_CLASS_APPL | ER_CONSTRUCT) | ER_TAG_MASK))
131
Stream_Read_UINT8(s, byte);
136
er_read_length(s, length);
140
Stream_Read_UINT8(s, byte);
142
if (byte != ((ER_CLASS_APPL | ER_CONSTRUCT) | (ER_TAG_MASK & tag)))
145
er_read_length(s, length);
152
* Write er Application tag.
154
* @param tag er application-defined tag
155
* @param length length
158
void er_write_application_tag(wStream* s, BYTE tag, int length, BOOL flag)
162
Stream_Write_UINT8(s, (ER_CLASS_APPL | ER_CONSTRUCT) | ER_TAG_MASK);
163
Stream_Write_UINT8(s, tag);
164
er_write_length(s, length, flag);
168
Stream_Write_UINT8(s, (ER_CLASS_APPL | ER_CONSTRUCT) | (ER_TAG_MASK & tag));
169
er_write_length(s, length, flag);
173
BOOL er_read_contextual_tag(wStream* s, BYTE tag, int* length, BOOL pc)
177
Stream_Read_UINT8(s, byte);
179
if (byte != ((ER_CLASS_CTXT | ER_PC(pc)) | (ER_TAG_MASK & tag)))
185
er_read_length(s, length);
190
int er_write_contextual_tag(wStream* s, BYTE tag, int length, BOOL pc, BOOL flag)
192
Stream_Write_UINT8(s, (ER_CLASS_CTXT | ER_PC(pc)) | (ER_TAG_MASK & tag));
193
return er_write_length(s, length, flag) + 1;
196
int er_skip_contextual_tag(int length)
198
return _er_skip_length(length) + 1;
201
BOOL er_read_sequence_tag(wStream* s, int* length)
205
Stream_Read_UINT8(s, byte);
207
if (byte != ((ER_CLASS_UNIV | ER_CONSTRUCT) | (ER_TAG_SEQUENCE_OF)))
210
er_read_length(s, length);
216
* Write er SEQUENCE tag.
218
* @param length length
221
int er_write_sequence_tag(wStream* s, int length, BOOL flag)
223
Stream_Write_UINT8(s, (ER_CLASS_UNIV | ER_CONSTRUCT) | (ER_TAG_MASK & ER_TAG_SEQUENCE));
224
return er_write_length(s, length, flag) + 1;
227
int er_skip_sequence(int length)
229
return 1 + _er_skip_length(length) + length;
232
int er_skip_sequence_tag(int length)
234
return 1 + _er_skip_length(length);
237
BOOL er_read_enumerated(wStream* s, BYTE* enumerated, BYTE count)
241
er_read_universal_tag(s, ER_TAG_ENUMERATED, FALSE);
242
er_read_length(s, &length);
245
Stream_Read_UINT8(s, *enumerated);
249
/* check that enumerated value falls within expected range */
250
if (*enumerated + 1 > count)
256
void er_write_enumerated(wStream* s, BYTE enumerated, BYTE count, BOOL flag)
258
er_write_universal_tag(s, ER_TAG_ENUMERATED, FALSE);
259
er_write_length(s, 1, flag);
260
Stream_Write_UINT8(s, enumerated);
263
BOOL er_read_bit_string(wStream* s, int* length, BYTE* padding)
265
er_read_universal_tag(s, ER_TAG_BIT_STRING, FALSE);
266
er_read_length(s, length);
267
Stream_Read_UINT8(s, *padding);
272
BOOL er_write_bit_string_tag(wStream* s, UINT32 length, BYTE padding, BOOL flag)
274
er_write_universal_tag(s, ER_TAG_BIT_STRING, FALSE);
275
er_write_length(s, length, flag);
276
Stream_Write_UINT8(s, padding);
280
BOOL er_read_octet_string(wStream* s, int* length)
282
if(!er_read_universal_tag(s, ER_TAG_OCTET_STRING, FALSE))
284
er_read_length(s, length);
290
* Write a er OCTET_STRING
292
* @param oct_str octet string
293
* @param length string length
296
void er_write_octet_string(wStream* s, BYTE* oct_str, int length, BOOL flag)
298
er_write_universal_tag(s, ER_TAG_OCTET_STRING, FALSE);
299
er_write_length(s, length, flag);
300
Stream_Write(s, oct_str, length);
303
int er_write_octet_string_tag(wStream* s, int length, BOOL flag)
305
er_write_universal_tag(s, ER_TAG_OCTET_STRING, FALSE);
306
er_write_length(s, length, flag);
307
return 1 + _er_skip_length(length);
310
int er_skip_octet_string(int length)
312
return 1 + _er_skip_length(length) + length;
321
BOOL er_read_BOOL(wStream* s, BOOL* value)
326
if (!er_read_universal_tag(s, ER_TAG_BOOLEAN, FALSE))
328
er_read_length(s, &length);
331
Stream_Read_UINT8(s, v);
332
*value = (v ? TRUE : FALSE);
342
void er_write_BOOL(wStream* s, BOOL value)
344
er_write_universal_tag(s, ER_TAG_BOOLEAN, FALSE);
345
er_write_length(s, 1, FALSE);
346
Stream_Write_UINT8(s, (value == TRUE) ? 0xFF : 0);
349
BOOL er_read_integer(wStream* s, UINT32* value)
353
er_read_universal_tag(s, ER_TAG_INTEGER, FALSE);
354
er_read_length(s, &length);
358
Stream_Seek(s, length);
364
Stream_Read_UINT8(s, *value);
366
else if (length == 2)
368
Stream_Read_UINT16_BE(s, *value);
370
else if (length == 3)
373
Stream_Read_UINT8(s, byte);
374
Stream_Read_UINT16_BE(s, *value);
375
*value += (byte << 16);
377
else if (length == 4)
379
Stream_Read_UINT32_BE(s, *value);
395
int er_write_integer(wStream* s, INT32 value)
397
er_write_universal_tag(s, ER_TAG_INTEGER, FALSE);
399
if (value <= 127 && value >= -128)
401
er_write_length(s, 1, FALSE);
402
Stream_Write_UINT8(s, value);
405
else if (value <= 32767 && value >= -32768)
407
er_write_length(s, 2, FALSE);
408
Stream_Write_UINT16_BE(s, value);
413
er_write_length(s, 4, FALSE);
414
Stream_Write_UINT32_BE(s, value);
421
int er_skip_integer(INT32 value)
423
if (value <= 127 && value >= -128)
425
return _er_skip_length(1) + 2;
427
else if (value <= 32767 && value >= -32768)
429
return _er_skip_length(2) + 3;
433
return _er_skip_length(4) + 5;
439
BOOL er_read_integer_length(wStream* s, int* length)
441
er_read_universal_tag(s, ER_TAG_INTEGER, FALSE);
442
er_read_length(s, length);