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  if (
byte != (ER_CLASS_UNIV | ER_PC(pc) | (ER_TAG_MASK & tag)))
 
  116void er_write_universal_tag(
wStream* s, BYTE tag, BOOL pc)
 
  118  Stream_Write_UINT8(s, (ER_CLASS_UNIV | ER_PC(pc)) | (ER_TAG_MASK & tag));
 
  128BOOL er_read_application_tag(
wStream* s, BYTE tag, 
int* length)
 
  134    Stream_Read_UINT8(s, 
byte);
 
  136    if (
byte != ((ER_CLASS_APPL | ER_CONSTRUCT) | ER_TAG_MASK))
 
  139    Stream_Read_UINT8(s, 
byte);
 
  144    er_read_length(s, length);
 
  148    Stream_Read_UINT8(s, 
byte);
 
  150    if (
byte != ((ER_CLASS_APPL | ER_CONSTRUCT) | (ER_TAG_MASK & tag)))
 
  153    er_read_length(s, length);
 
  166void er_write_application_tag(
wStream* s, BYTE tag, 
int length, BOOL flag)
 
  170    Stream_Write_UINT8(s, (ER_CLASS_APPL | ER_CONSTRUCT) | ER_TAG_MASK);
 
  171    Stream_Write_UINT8(s, tag);
 
  172    er_write_length(s, length, flag);
 
  176    Stream_Write_UINT8(s, (ER_CLASS_APPL | ER_CONSTRUCT) | (ER_TAG_MASK & tag));
 
  177    er_write_length(s, length, flag);
 
  181BOOL er_read_contextual_tag(
wStream* s, BYTE tag, 
int* length, BOOL pc)
 
  185  Stream_Read_UINT8(s, 
byte);
 
  187  if (
byte != ((ER_CLASS_CTXT | ER_PC(pc)) | (ER_TAG_MASK & tag)))
 
  193  er_read_length(s, length);
 
  198int er_write_contextual_tag(
wStream* s, BYTE tag, 
int length, BOOL pc, BOOL flag)
 
  200  Stream_Write_UINT8(s, (ER_CLASS_CTXT | ER_PC(pc)) | (ER_TAG_MASK & tag));
 
  201  return er_write_length(s, length, flag) + 1;
 
  204int er_skip_contextual_tag(
int length)
 
  206  return _er_skip_length(length) + 1;
 
  209BOOL er_read_sequence_tag(
wStream* s, 
int* length)
 
  213  Stream_Read_UINT8(s, 
byte);
 
  215  if (
byte != ((ER_CLASS_UNIV | ER_CONSTRUCT) | (ER_TAG_SEQUENCE_OF)))
 
  218  er_read_length(s, length);
 
  229int er_write_sequence_tag(
wStream* s, 
int length, BOOL flag)
 
  231  Stream_Write_UINT8(s, (ER_CLASS_UNIV | ER_CONSTRUCT) | (ER_TAG_MASK & ER_TAG_SEQUENCE));
 
  232  return er_write_length(s, length, flag) + 1;
 
  235int er_skip_sequence(
int length)
 
  237  return 1 + _er_skip_length(length) + length;
 
  240int er_skip_sequence_tag(
int length)
 
  242  return 1 + _er_skip_length(length);
 
  245BOOL er_read_enumerated(
wStream* s, BYTE* enumerated, BYTE count)
 
  249  er_read_universal_tag(s, ER_TAG_ENUMERATED, FALSE);
 
  250  er_read_length(s, &length);
 
  253    Stream_Read_UINT8(s, *enumerated);
 
  258  if (*enumerated + 1 > count)
 
  264void er_write_enumerated(
wStream* s, BYTE enumerated, WINPR_ATTR_UNUSED BYTE count, BOOL flag)
 
  266  er_write_universal_tag(s, ER_TAG_ENUMERATED, FALSE);
 
  267  er_write_length(s, 1, flag);
 
  268  Stream_Write_UINT8(s, enumerated);
 
  271BOOL er_read_bit_string(
wStream* s, 
int* length, BYTE* padding)
 
  273  er_read_universal_tag(s, ER_TAG_BIT_STRING, FALSE);
 
  274  er_read_length(s, length);
 
  275  Stream_Read_UINT8(s, *padding);
 
  280BOOL er_write_bit_string_tag(
wStream* s, UINT32 length, BYTE padding, BOOL flag)
 
  282  er_write_universal_tag(s, ER_TAG_BIT_STRING, FALSE);
 
  283  er_write_length(s, WINPR_ASSERTING_INT_CAST(
int, length), flag);
 
  284  Stream_Write_UINT8(s, padding);
 
  288BOOL er_read_octet_string(
wStream* s, 
int* length)
 
  290  if (!er_read_universal_tag(s, ER_TAG_OCTET_STRING, FALSE))
 
  292  er_read_length(s, length);
 
  304void er_write_octet_string(
wStream* s, BYTE* oct_str, 
int length, BOOL flag)
 
  306  er_write_universal_tag(s, ER_TAG_OCTET_STRING, FALSE);
 
  307  er_write_length(s, length, flag);
 
  308  Stream_Write(s, oct_str, WINPR_ASSERTING_INT_CAST(
size_t, length));
 
  311int er_write_octet_string_tag(
wStream* s, 
int length, BOOL flag)
 
  313  er_write_universal_tag(s, ER_TAG_OCTET_STRING, FALSE);
 
  314  er_write_length(s, length, flag);
 
  315  return 1 + _er_skip_length(length);
 
  318int er_skip_octet_string(
int length)
 
  320  return 1 + _er_skip_length(length) + length;
 
  329BOOL er_read_BOOL(
wStream* s, BOOL* value)
 
  334  if (!er_read_universal_tag(s, ER_TAG_BOOLEAN, FALSE))
 
  336  er_read_length(s, &length);
 
  339  Stream_Read_UINT8(s, v);
 
  340  *value = (v ? TRUE : FALSE);
 
  350void er_write_BOOL(
wStream* s, BOOL value)
 
  352  er_write_universal_tag(s, ER_TAG_BOOLEAN, FALSE);
 
  353  er_write_length(s, 1, FALSE);
 
  354  Stream_Write_UINT8(s, (value == TRUE) ? 0xFF : 0);
 
  357BOOL er_read_integer(
wStream* s, UINT32* value)
 
  361  er_read_universal_tag(s, ER_TAG_INTEGER, FALSE);
 
  362  er_read_length(s, &length);
 
  366    Stream_Seek(s, WINPR_ASSERTING_INT_CAST(
size_t, length));
 
  372    Stream_Read_UINT8(s, *value);
 
  374  else if (length == 2)
 
  376    Stream_Read_UINT16_BE(s, *value);
 
  378  else if (length == 3)
 
  381    Stream_Read_UINT8(s, 
byte);
 
  382    Stream_Read_UINT16_BE(s, *value);
 
  383    *value += (
byte << 16) & 0xFF0000;
 
  385  else if (length == 4)
 
  387    Stream_Read_UINT32_BE(s, *value);
 
  403int er_write_integer(
wStream* s, INT32 value)
 
  405  er_write_universal_tag(s, ER_TAG_INTEGER, FALSE);
 
  407  if (value <= 127 && value >= -128)
 
  409    er_write_length(s, 1, FALSE);
 
  410    Stream_Write_INT8(s, WINPR_ASSERTING_INT_CAST(INT8, value));
 
  413  else if (value <= 32767 && value >= -32768)
 
  415    er_write_length(s, 2, FALSE);
 
  416    Stream_Write_INT16_BE(s, WINPR_ASSERTING_INT_CAST(INT16, value));
 
  421    er_write_length(s, 4, FALSE);
 
  422    Stream_Write_INT32_BE(s, value);
 
  427int er_skip_integer(INT32 value)
 
  429  if (value <= 127 && value >= -128)
 
  431    return _er_skip_length(1) + 2;
 
  433  else if (value <= 32767 && value >= -32768)
 
  435    return _er_skip_length(2) + 3;
 
  439    return _er_skip_length(4) + 5;
 
  443BOOL er_read_integer_length(
wStream* s, 
int* length)
 
  445  er_read_universal_tag(s, ER_TAG_INTEGER, FALSE);
 
  446  er_read_length(s, length);