21#include <freerdp/config.h>
24#include <winpr/assert.h>
25#include <winpr/cast.h>
27#include <freerdp/crypto/er.h>
28#include <freerdp/crypto/ber.h>
29#include <freerdp/crypto/der.h>
31void er_read_length(
wStream* s,
int* length)
35 Stream_Read_UINT8(s,
byte);
49 Stream_Read_UINT8(s, *length);
51 Stream_Read_UINT16_BE(s, *length);
65int er_write_length(
wStream* s,
int length, BOOL flag)
67 WINPR_ASSERT(length >= 0);
69 return der_write_length(s, length);
71 return (
int)ber_write_length(s, (
size_t)length);
74int _er_skip_length(
int length)
82int er_get_content_length(
int length)
84 if (length - 1 > 0x7F)
97BOOL er_read_universal_tag(
wStream* s, BYTE tag, BOOL pc)
101 Stream_Read_UINT8(s,
byte);
103 return (
byte == (ER_CLASS_UNIV | ER_PC(pc) | (ER_TAG_MASK & tag)));
113void er_write_universal_tag(
wStream* s, BYTE tag, BOOL pc)
115 Stream_Write_UINT8(s, (ER_CLASS_UNIV | ER_PC(pc)) | (ER_TAG_MASK & tag));
125BOOL er_read_application_tag(
wStream* s, BYTE tag,
int* length)
131 Stream_Read_UINT8(s,
byte);
133 if (
byte != ((ER_CLASS_APPL | ER_CONSTRUCT) | ER_TAG_MASK))
136 Stream_Read_UINT8(s,
byte);
141 er_read_length(s, length);
145 Stream_Read_UINT8(s,
byte);
147 if (
byte != ((ER_CLASS_APPL | ER_CONSTRUCT) | (ER_TAG_MASK & tag)))
150 er_read_length(s, length);
163void er_write_application_tag(
wStream* s, BYTE tag,
int length, BOOL flag)
167 Stream_Write_UINT8(s, (ER_CLASS_APPL | ER_CONSTRUCT) | ER_TAG_MASK);
168 Stream_Write_UINT8(s, tag);
169 er_write_length(s, length, flag);
173 Stream_Write_UINT8(s, (ER_CLASS_APPL | ER_CONSTRUCT) | (ER_TAG_MASK & tag));
174 er_write_length(s, length, flag);
178BOOL er_read_contextual_tag(
wStream* s, BYTE tag,
int* length, BOOL pc)
182 Stream_Read_UINT8(s,
byte);
184 if (
byte != ((ER_CLASS_CTXT | ER_PC(pc)) | (ER_TAG_MASK & tag)))
190 er_read_length(s, length);
195int er_write_contextual_tag(
wStream* s, BYTE tag,
int length, BOOL pc, BOOL flag)
197 Stream_Write_UINT8(s, (ER_CLASS_CTXT | ER_PC(pc)) | (ER_TAG_MASK & tag));
198 return er_write_length(s, length, flag) + 1;
201int er_skip_contextual_tag(
int length)
203 return _er_skip_length(length) + 1;
206BOOL er_read_sequence_tag(
wStream* s,
int* length)
210 Stream_Read_UINT8(s,
byte);
212 if (
byte != ((ER_CLASS_UNIV | ER_CONSTRUCT) | (ER_TAG_SEQUENCE_OF)))
215 er_read_length(s, length);
226int er_write_sequence_tag(
wStream* s,
int length, BOOL flag)
228 Stream_Write_UINT8(s, (ER_CLASS_UNIV | ER_CONSTRUCT) | (ER_TAG_MASK & ER_TAG_SEQUENCE));
229 return er_write_length(s, length, flag) + 1;
232int er_skip_sequence(
int length)
234 return 1 + _er_skip_length(length) + length;
237int er_skip_sequence_tag(
int length)
239 return 1 + _er_skip_length(length);
242BOOL er_read_enumerated(
wStream* s, BYTE* enumerated, BYTE count)
246 er_read_universal_tag(s, ER_TAG_ENUMERATED, FALSE);
247 er_read_length(s, &length);
250 Stream_Read_UINT8(s, *enumerated);
255 if (*enumerated + 1 > count)
261void er_write_enumerated(
wStream* s, BYTE enumerated, WINPR_ATTR_UNUSED BYTE count, BOOL flag)
263 er_write_universal_tag(s, ER_TAG_ENUMERATED, FALSE);
264 er_write_length(s, 1, flag);
265 Stream_Write_UINT8(s, enumerated);
268BOOL er_read_bit_string(
wStream* s,
int* length, BYTE* padding)
270 er_read_universal_tag(s, ER_TAG_BIT_STRING, FALSE);
271 er_read_length(s, length);
272 Stream_Read_UINT8(s, *padding);
277BOOL er_write_bit_string_tag(
wStream* s, UINT32 length, BYTE padding, BOOL flag)
279 er_write_universal_tag(s, ER_TAG_BIT_STRING, FALSE);
280 er_write_length(s, WINPR_ASSERTING_INT_CAST(
int, length), flag);
281 Stream_Write_UINT8(s, padding);
285BOOL er_read_octet_string(
wStream* s,
int* length)
287 if (!er_read_universal_tag(s, ER_TAG_OCTET_STRING, FALSE))
289 er_read_length(s, length);
301void er_write_octet_string(
wStream* s, BYTE* oct_str,
int length, BOOL flag)
303 er_write_universal_tag(s, ER_TAG_OCTET_STRING, FALSE);
304 er_write_length(s, length, flag);
305 Stream_Write(s, oct_str, WINPR_ASSERTING_INT_CAST(
size_t, length));
308int er_write_octet_string_tag(
wStream* s,
int length, BOOL flag)
310 er_write_universal_tag(s, ER_TAG_OCTET_STRING, FALSE);
311 er_write_length(s, length, flag);
312 return 1 + _er_skip_length(length);
315int er_skip_octet_string(
int length)
317 return 1 + _er_skip_length(length) + length;
326BOOL er_read_BOOL(
wStream* s, BOOL* value)
331 if (!er_read_universal_tag(s, ER_TAG_BOOLEAN, FALSE))
333 er_read_length(s, &length);
336 Stream_Read_UINT8(s, v);
347void er_write_BOOL(
wStream* s, BOOL value)
349 er_write_universal_tag(s, ER_TAG_BOOLEAN, FALSE);
350 er_write_length(s, 1, FALSE);
351 Stream_Write_UINT8(s, (value == TRUE) ? 0xFF : 0);
354BOOL er_read_integer(
wStream* s, UINT32* value)
358 er_read_universal_tag(s, ER_TAG_INTEGER, FALSE);
359 er_read_length(s, &length);
361 if (value ==
nullptr)
363 Stream_Seek(s, WINPR_ASSERTING_INT_CAST(
size_t, length));
369 Stream_Read_UINT8(s, *value);
371 else if (length == 2)
373 Stream_Read_UINT16_BE(s, *value);
375 else if (length == 3)
378 Stream_Read_UINT8(s,
byte);
379 Stream_Read_UINT16_BE(s, *value);
380 *value += (
byte << 16) & 0xFF0000;
382 else if (length == 4)
384 Stream_Read_UINT32_BE(s, *value);
400int er_write_integer(
wStream* s, INT32 value)
402 er_write_universal_tag(s, ER_TAG_INTEGER, FALSE);
404 if (value <= 127 && value >= -128)
406 er_write_length(s, 1, FALSE);
407 Stream_Write_INT8(s, WINPR_ASSERTING_INT_CAST(INT8, value));
410 else if (value <= 32767 && value >= -32768)
412 er_write_length(s, 2, FALSE);
413 Stream_Write_INT16_BE(s, WINPR_ASSERTING_INT_CAST(INT16, value));
418 er_write_length(s, 4, FALSE);
419 Stream_Write_INT32_BE(s, value);
424int er_skip_integer(INT32 value)
426 if (value <= 127 && value >= -128)
428 return _er_skip_length(1) + 2;
430 else if (value <= 32767 && value >= -32768)
432 return _er_skip_length(2) + 3;
436 return _er_skip_length(4) + 5;
440BOOL er_read_integer_length(
wStream* s,
int* length)
442 er_read_universal_tag(s, ER_TAG_INTEGER, FALSE);
443 er_read_length(s, length);