boolean ber_read_integer(STREAM* s, uint32* value) { int length; ber_read_universal_tag(s, BER_TAG_INTEGER, false); ber_read_length(s, &length); if (value == NULL) { stream_seek(s, length); return true; } if (length == 1) stream_read_uint8(s, *value); else if (length == 2) stream_read_uint16_be(s, *value); else if (length == 3) { uint8 byte; stream_read_uint8(s, byte); stream_read_uint16_be(s, *value); *value += (byte << 16); } else if (length == 4) stream_read_uint32_be(s, *value); else return false; return true; }
boolean ber_read_octet_string(STREAM* s, int* length) { ber_read_universal_tag(s, BER_TAG_OCTET_STRING, false); ber_read_length(s, length); return true; }
boolean ber_read_bit_string(STREAM* s, int* length, uint8* padding) { ber_read_universal_tag(s, BER_TAG_BIT_STRING, false); ber_read_length(s, length); stream_read_uint8(s, *padding); return true; }
BOOL ber_read_bit_string(wStream* s, int* length, BYTE* padding) { if (!ber_read_universal_tag(s, BER_TAG_BIT_STRING, FALSE) || !ber_read_length(s, length)) return FALSE; if (Stream_GetRemainingLength(s) < 1) return FALSE; Stream_Read_UINT8(s, *padding); return TRUE; }
BOOL ber_read_bit_string(wStream* s, int* length, BYTE* padding) { if(!ber_read_universal_tag(s, BER_TAG_BIT_STRING, FALSE) || !ber_read_length(s, length)) return FALSE; if(stream_get_left(s) < 1) return FALSE; stream_read_BYTE(s, *padding); return TRUE; }
boolean ber_read_boolean(STREAM* s, boolean* value) { int length; uint8 v; if (!ber_read_universal_tag(s, BER_TAG_BOOLEAN, false)) return false; ber_read_length(s, &length); if (length != 1) return false; stream_read_uint8(s, v); *value = (v ? true : false); return true; }
BOOL ber_read_BOOL(wStream* s, BOOL* value) { int length; BYTE v; if (!ber_read_universal_tag(s, BER_TAG_BOOLEAN, FALSE) || !ber_read_length(s, &length)) return FALSE; if (length != 1 || Stream_GetRemainingLength(s) < 1) return FALSE; Stream_Read_UINT8(s, v); *value = (v ? TRUE : FALSE); return TRUE; }
BOOL ber_read_BOOL(wStream* s, BOOL* value) { int length; BYTE v; if (!ber_read_universal_tag(s, BER_TAG_BOOLEAN, FALSE) || !ber_read_length(s, &length)) return FALSE; if (length != 1 || stream_get_left(s) < 1) return FALSE; stream_read_BYTE(s, v); *value = (v ? TRUE : FALSE); return TRUE; }
BOOL ber_read_integer(wStream* s, UINT32* value) { int length; if (!ber_read_universal_tag(s, BER_TAG_INTEGER, FALSE) || !ber_read_length(s, &length) || ((int) Stream_GetRemainingLength(s)) < length) return FALSE; if (value == NULL) { // even if we don't care the integer value, check the announced size return Stream_SafeSeek(s, length); } if (length == 1) { Stream_Read_UINT8(s, *value); } else if (length == 2) { Stream_Read_UINT16_BE(s, *value); } else if (length == 3) { BYTE byte; Stream_Read_UINT8(s, byte); Stream_Read_UINT16_BE(s, *value); *value += (byte << 16); } else if (length == 4) { Stream_Read_UINT32_BE(s, *value); } else if (length == 8) { WLog_ERR(TAG, "should implement reading an 8 bytes integer"); return FALSE; } else { WLog_ERR(TAG, "should implement reading an integer with length=%d", length); return FALSE; } return TRUE; }
BOOL ber_read_integer(wStream* s, UINT32* value) { int length; if (!ber_read_universal_tag(s, BER_TAG_INTEGER, FALSE) || !ber_read_length(s, &length) || stream_get_left(s) < length) return FALSE; if (value == NULL) { // even if we don't care the integer value, check the announced size return stream_skip(s, length); } if (length == 1) { stream_read_BYTE(s, *value); } else if (length == 2) { stream_read_UINT16_be(s, *value); } else if (length == 3) { BYTE byte; stream_read_BYTE(s, byte); stream_read_UINT16_be(s, *value); *value += (byte << 16); } else if (length == 4) { stream_read_UINT32_be(s, *value); } else if (length == 8) { printf("%s: should implement reading an 8 bytes integer\n", __FUNCTION__); return FALSE; } else { printf("%s: should implement reading an integer with length=%d\n", __FUNCTION__, length); return FALSE; } return TRUE; }
boolean ber_read_enumerated(STREAM* s, uint8* enumerated, uint8 count) { int length; ber_read_universal_tag(s, BER_TAG_ENUMERATED, false); ber_read_length(s, &length); if (length == 1) stream_read_uint8(s, *enumerated); else return false; /* check that enumerated value falls within expected range */ if (*enumerated + 1 > count) return false; return true; }
BOOL ber_read_enumerated(wStream* s, BYTE* enumerated, BYTE count) { int length; if (!ber_read_universal_tag(s, BER_TAG_ENUMERATED, FALSE) || !ber_read_length(s, &length)) return FALSE; if (length != 1 || Stream_GetRemainingLength(s) < 1) return FALSE; Stream_Read_UINT8(s, *enumerated); /* check that enumerated value falls within expected range */ if (*enumerated + 1 > count) return FALSE; return TRUE; }
BOOL ber_read_octet_string_tag(wStream* s, int* length) { return ber_read_universal_tag(s, BER_TAG_OCTET_STRING, FALSE) && ber_read_length(s, length); }
boolean ber_read_integer_length(STREAM* s, int* length) { ber_read_universal_tag(s, BER_TAG_INTEGER, false); ber_read_length(s, length); return true; }