Main Page | Modules | Class List | Directories | File List | Class Members | File Members | Related Pages

asn1.c File Reference

ASN.1 Decoding API for BER and DER encodings. More...

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <sys/types.h>
#include "asn1.h"

Go to the source code of this file.

Defines

#define SF_ASN1_CLASS(c)   (((u_char)c) & SF_ASN1_CLASS_MASK)
#define SF_ASN1_FLAG(c)   (((u_char)c) & SF_ASN1_FLAG_MASK)
#define SF_ASN1_TAG(c)   (((u_char)c) & SF_ASN1_TAG_MASK)
#define SF_ASN1_LEN_EXT(c)   (((u_char)c) & SF_BER_LEN_MASK)
#define ASN1_OOB(s, e, d)   (!(((s) <= (d)) && ((d) < (e))))
#define ASN1_FATAL_ERR(e)   ((e) < 0)
#define ASN1_NONFATAL_ERR(e)   ((e) > 0)
#define ASN1_MAX_STACK   128

Functions

static void asn1_init_node_index (void)
static ASN1_TYPEasn1_node_alloc (void)
int asn1_init_mem (int iNodes)
static int asn1_decode_tag_num_ext (ASN1_DATA *asn1_data, u_int *tag_num)
static int asn1_decode_ident (ASN1_TYPE *asn1_type, ASN1_DATA *asn1_data)
static int asn1_decode_len_type (u_char *data)
static int asn1_decode_len_ext (ASN1_DATA *asn1_data, u_int *size)
static int asn1_decode_len (ASN1_TYPE *asn1_type, ASN1_DATA *asn1_data)
static int asn1_is_eoc (ASN1_TYPE *asn1)
static int asn1_decode_type (u_char **data, u_int *len, ASN1_TYPE **asn1_type)
int asn1_decode (u_char *data, u_int len, ASN1_TYPE **asn1_type)
int asn1_traverse (ASN1_TYPE *asn1, void *user, int(*DetectFunc)(ASN1_TYPE *, void *))
int asn1_print_types (ASN1_TYPE *asn1_type, void *user)

Variables

static ASN1_TYPEg_asn1_mem = NULL
static int g_asn1_max_nodes = 0
static int g_asn1_node_index = 0


Detailed Description

ASN.1 Decoding API for BER and DER encodings.

Author:
Daniel Roelker <droelker@sourcefire.com>
Copyright (C) 2004, Daniel Roelker and Sourcefire, Inc.

ASN.1 decoding functions that incorporate an internal stack for processing. That way we don't have to worry about attackers trying to overload the machine stack.

Handles both DER and BER encodings, and also the indefinite encoding that BER supports. Lots of functionality can be added on top of this library. SNMP will probably be the first.

NOTES:

Definition in file asn1.c.


Define Documentation

#define ASN1_FATAL_ERR  )     ((e) < 0)
 

Definition at line 44 of file asn1.c.

#define ASN1_MAX_STACK   128
 

Definition at line 47 of file asn1.c.

Referenced by asn1_decode(), and asn1_traverse().

#define ASN1_NONFATAL_ERR  )     ((e) > 0)
 

Definition at line 45 of file asn1.c.

#define ASN1_OOB s,
e,
 )     (!(((s) <= (d)) && ((d) < (e))))
 

Definition at line 43 of file asn1.c.

Referenced by asn1_decode_ident(), asn1_decode_len(), asn1_decode_len_ext(), asn1_decode_tag_num_ext(), and asn1_decode_type().

#define SF_ASN1_CLASS  )     (((u_char)c) & SF_ASN1_CLASS_MASK)
 

Definition at line 38 of file asn1.c.

Referenced by asn1_decode_ident().

#define SF_ASN1_FLAG  )     (((u_char)c) & SF_ASN1_FLAG_MASK)
 

Definition at line 39 of file asn1.c.

Referenced by asn1_decode_ident().

#define SF_ASN1_LEN_EXT  )     (((u_char)c) & SF_BER_LEN_MASK)
 

Definition at line 41 of file asn1.c.

Referenced by asn1_decode_len_type(), and asn1_decode_tag_num_ext().

#define SF_ASN1_TAG  )     (((u_char)c) & SF_ASN1_TAG_MASK)
 

Definition at line 40 of file asn1.c.

Referenced by asn1_decode_ident().


Function Documentation

int asn1_decode u_char *  data,
u_int  len,
ASN1_TYPE **  asn1_type
 

This function decodes an ASN.1 string and returns the decoded structures. We BER encoding, which means we handle both definite and indefinite length encodings (that was a B).

Returns:
integer
Return values:
ASN1_OK function successful
!ASN1_OK lots of error conditions, figure it out

Definition at line 622 of file asn1.c.

References asn1_decode_type(), ASN1_ERR_NULL_MEM, ASN1_ERR_OVERLONG_LEN, ASN1_ERR_STACK, asn1_init_node_index(), ASN1_MAX_STACK, ASN1_OK, s_ASN1_TYPE::cnext, s_ASN1_TYPE::data, s_ASN1_TYPE::data_len, s_ASN1_TYPE::eoc, s_ASN1_IDENT::flag, s_ASN1_TYPE::ident, index, s_ASN1_TYPE::len, s_ASN1_TYPE::next, NULL, SF_ASN1_FLAG_CONSTRUCT, SF_BER_LEN_INDEF, and s_ASN1_LEN::type.

Referenced by Asn1Detect().

static int asn1_decode_ident ASN1_TYPE asn1_type,
ASN1_DATA asn1_data
[static]
 

This function decodes the identifier byte(s) of an ASN.1 structure. We handle long tag numbers and check for overflows in the extended tag numbers.

Returns:
integer
Return values:
ASN1_ERR_NULL_MEM function arguments are NULL
ASN1_ERR_OOB buffer out of bounds
ASN1_ERR_INVALID_BER_TAG_LEN tag num too large or bad encoding
ASN1_OK function ok

Definition at line 198 of file asn1.c.

References asn1_decode_tag_num_ext(), ASN1_ERR_INVALID_BER_TAG_LEN, ASN1_ERR_NULL_MEM, ASN1_ERR_OOB, ASN1_OK, ASN1_OOB, s_ASN1_IDENT::class, s_ASN1_DATA::data, s_ASN1_DATA::end, s_ASN1_IDENT::flag, s_ASN1_TYPE::ident, SF_ASN1_CLASS, SF_ASN1_FLAG, SF_ASN1_TAG, SF_ASN1_TAG_EXTENSION, s_ASN1_DATA::start, s_ASN1_IDENT::tag, and s_ASN1_IDENT::tag_type.

Referenced by asn1_decode_type().

static int asn1_decode_len ASN1_TYPE asn1_type,
ASN1_DATA asn1_data
[static]
 

This function decodes the ASN.1 type length. Determines what type of BER encoding is used for the length and decodes that length.

Returns:
integer
Return values:
ASN1_ERR_NULL_MEM function arguments NULL
ASN1_ERR_FATAL should never get this
ASN1_ERR_OOB out of bounds condition
ASN1_OK function successful

Definition at line 356 of file asn1.c.

References asn1_decode_len_ext(), asn1_decode_len_type(), ASN1_ERR_FATAL, ASN1_ERR_NULL_MEM, ASN1_ERR_OOB, ASN1_OK, ASN1_OOB, s_ASN1_DATA::data, s_ASN1_DATA::end, s_ASN1_TYPE::len, SF_BER_LEN_DEF_LONG, SF_BER_LEN_DEF_SHORT, SF_BER_LEN_INDEF, s_ASN1_LEN::size, s_ASN1_DATA::start, and s_ASN1_LEN::type.

Referenced by asn1_decode_type().

static int asn1_decode_len_ext ASN1_DATA asn1_data,
u_int *  size
[static]
 

Decode the extended length version. Basically we read the first byte for the number of bytes in the extended length. We then read that number of bytes to determine the length. If the number of bytes in the length is greater than our variable, then we return ASN1_ERR_OVERLONG_LEN, and exit decoding.

Returns:
integer
Return values:
ASN1_ERR_NULL_MEM function arguments NULL
ASN1_ERR_OVERLONG_LEN length to long for us to decode
ASN1_ERR_OOB out of bounds condition
ASN1_OK function successful

Definition at line 289 of file asn1.c.

References ASN1_ERR_NULL_MEM, ASN1_ERR_OOB, ASN1_ERR_OVERLONG_LEN, ASN1_OK, ASN1_OOB, s_ASN1_DATA::data, s_ASN1_DATA::end, and s_ASN1_DATA::start.

Referenced by asn1_decode_len().

static int asn1_decode_len_type u_char *  data  )  [static]
 

Determine the type of len encoding. Could be short, long or indeterminate.

Returns:
integer
Return values:
SF_BER_LEN_DEF_LONG extended length
SF_BER_LEN_DEF_SHORT one byte length < 127
SF_BER_LEN_INDEF indeterminate length

Definition at line 251 of file asn1.c.

References SF_ASN1_LEN_EXT, SF_BER_LEN_DEF_LONG, SF_BER_LEN_DEF_SHORT, and SF_BER_LEN_INDEF.

Referenced by asn1_decode_len().

static int asn1_decode_tag_num_ext ASN1_DATA asn1_data,
u_int *  tag_num
[static]
 

This routine decodes extended tag numbers and checks for overlong tag numbers, etc.

Parameters:
ASN1_DATA ptr to data
u_int ptr to tag num
Returns:
integer
Return values:
ASN1_OK function successful
ASN1_ERR_OVERLONG_LEN tag number too large
ASN1_ERR_OOB encoding goes out of bounds
ASN1_ERR_NULL_MEM function arguments are NULL

Definition at line 143 of file asn1.c.

References ASN1_ERR_NULL_MEM, ASN1_ERR_OOB, ASN1_ERR_OVERLONG_LEN, ASN1_OK, ASN1_OOB, s_ASN1_DATA::data, s_ASN1_DATA::end, SF_ASN1_LEN_EXT, and s_ASN1_DATA::start.

Referenced by asn1_decode_ident().

static int asn1_decode_type u_char **  data,
u_int *  len,
ASN1_TYPE **  asn1_type
[static]
 

This function decodes an ASN1_TYPE structure. It processes the type in three parts.

1) Identifier 2) Length 3) Data

The data processing skips over primitive data (if it can) and processes construct data (if it can).

This function also updates the data and len ptrs so we continue moving through the data.

Returns:
integer
Return values:
ASN1_OK function successful
ASN1_ERR_MEM_ALLOC memory allocation failed
ASN1_ERR_INVALID_INDEF_LEN invalid indefinite encoding
ASN1_ERR_INVALID_ARG invalid argument
ASN1_ERR_OOB out of bounds

Definition at line 471 of file asn1.c.

References asn1_decode_ident(), asn1_decode_len(), ASN1_ERR_INVALID_ARG, ASN1_ERR_INVALID_INDEF_LEN, ASN1_ERR_MEM_ALLOC, ASN1_ERR_OOB, asn1_is_eoc(), asn1_node_alloc(), ASN1_OK, ASN1_OOB, s_ASN1_DATA::data, s_ASN1_DATA::end, memset, NULL, SF_ASN1_FLAG_CONSTRUCT, SF_BER_LEN_INDEF, and s_ASN1_DATA::start.

Referenced by asn1_decode().

int asn1_init_mem int  iNodes  ) 
 

This function initializes the number of nodes that we want to track in an ASN.1 decode. Pass in the max number of nodes for an ASN.1 decode and we will track that many.

Returns:
integer
Return values:
ASN1_OK function successful
ASN1_ERR_MEM_ALLOC memory allocation failed
ASN1_ERR_INVALID_ARG invalid argument

Definition at line 105 of file asn1.c.

References ASN1_ERR_INVALID_ARG, ASN1_ERR_MEM_ALLOC, ASN1_OK, and g_asn1_max_nodes.

Referenced by ParseConfig(), and SnortMain().

static void asn1_init_node_index void   )  [static]
 

This function should get called whenever we decode a new ASN.1 string to initialize the memory.

Returns:
void

Definition at line 63 of file asn1.c.

References g_asn1_node_index.

Referenced by asn1_decode().

static int asn1_is_eoc ASN1_TYPE asn1  )  [static]
 

This function checks and ASN1_TYPE for end-of-content encoding. This doesn't determine that this is what it is, but what it could be.

Returns:
int
Return values:
0 not EOC
1 is EOC

Definition at line 430 of file asn1.c.

References s_ASN1_IDENT::class, s_ASN1_IDENT::flag, s_ASN1_TYPE::ident, s_ASN1_TYPE::len, SF_BER_LEN_DEF_SHORT, s_ASN1_LEN::size, s_ASN1_IDENT::tag, and s_ASN1_LEN::type.

Referenced by asn1_decode_type().

static ASN1_TYPE* asn1_node_alloc void   )  [static]
 

Allocate an ASN1_NODE.

Returns:
ASN1_TYPE *
Return values:
NULL memory allocation failed
!NULL function successful

Definition at line 82 of file asn1.c.

References g_asn1_max_nodes, g_asn1_node_index, and NULL.

Referenced by asn1_decode_type().

int asn1_print_types ASN1_TYPE asn1_type,
void *  user
 

Print out the ASN.1 type.

Returns:
integer
Return values:
0 printed

Definition at line 929 of file asn1.c.

References s_ASN1_IDENT::class, s_ASN1_TYPE::data, s_ASN1_TYPE::data_len, s_ASN1_IDENT::flag, s_ASN1_TYPE::ident, s_ASN1_TYPE::len, s_ASN1_LEN::size, s_ASN1_IDENT::tag, s_ASN1_IDENT::tag_type, and s_ASN1_LEN::type.

Referenced by Asn1DetectFuncs().

int asn1_traverse ASN1_TYPE asn1,
void *  user,
int(*)(ASN1_TYPE *, void *)  DetectFunc
 

This function traverses a decoded ASN1 structure, applying a detection function for the different types. This is just to make this user stack generic AND easy.

Returns:
integer
Return values:
1 detection function successful
0 detection function unsuccessful

Definition at line 868 of file asn1.c.

References ASN1_MAX_STACK, s_ASN1_TYPE::cnext, s_ASN1_IDENT::flag, s_ASN1_TYPE::ident, index, s_ASN1_TYPE::next, and SF_ASN1_FLAG_CONSTRUCT.

Referenced by Asn1DetectFuncs(), DetectBitStringOverflow(), DetectDoubleOverflow(), and DetectOversizeLength().


Variable Documentation

int g_asn1_max_nodes = 0 [static]
 

Definition at line 50 of file asn1.c.

Referenced by asn1_init_mem(), and asn1_node_alloc().

ASN1_TYPE* g_asn1_mem = NULL [static]
 

Definition at line 49 of file asn1.c.

int g_asn1_node_index = 0 [static]
 

Definition at line 51 of file asn1.c.

Referenced by asn1_init_node_index(), and asn1_node_alloc().


Generated on Sun May 14 14:51:26 2006 by  doxygen 1.4.2