BER(3)

NAME
ber_get_element, ber_set_header, ber_link_elements, ber_unlink_elements, ber_replace_elements, ber_add_sequence, ber_add_set, ber_add_enumerated, ber_add_integer, ber_get_integer, ber_get_enumerated, ber_add_boolean, ber_get_boolean, ber_add_string, ber_add_nstring, ber_add_ostring, ber_add_bitstring, ber_get_string, ber_get_nstring, ber_get_ostring, ber_get_bitstring, ber_add_null, ber_get_null, ber_add_eoc, ber_get_eoc, ber_add_oid, ber_add_noid, ber_add_oidstring, ber_get_oid, ber_oid2ber, ber_string2oid, ber_oid_cmp, ber_printf_elements, ber_scanf_elements, ber_get_writebuf, ber_write_elements, ber_set_readbuf, ber_read_elements, ber_getpos, ber_free_element, ber_free_elements, ber_calc_len, ber_set_application, ber_set_writecallback, ber_free - encode and decode ASN.1 with Basic Encoding Rules

SYNOPSIS
#include <sys/types.h>
#include <ber.h>
struct ber_element *
ber_get_element(unsigned int encoding);
void
ber_set_header(struct ber_element *elm, int class, unsigned int type);
void
ber_link_elements(struct ber_element *prev, struct ber_element *elm);
struct ber_element *
ber_unlink_elements(struct ber_element *prev);
void
ber_replace_elements(struct ber_element *prev, struct ber_element *elm);
struct ber_element *
ber_add_sequence(struct ber_element *prev);
struct ber_element *
ber_add_set(struct ber_element *prev);
struct ber_element *
ber_add_integer(struct ber_element *prev, long long val);
int
ber_get_integer(struct ber_element *root, long long *val);
struct ber_element *
ber_add_enumerated(struct ber_element *prev, long long val);
int
ber_get_enumerated(struct ber_element *root, long long *val);
struct ber_element *
ber_add_boolean(struct ber_element *prev, int bool);
int
ber_get_boolean(struct ber_element *root, int *bool);
struct ber_element *
ber_add_string(struct ber_element *prev, const char *string);
struct ber_element *
ber_add_nstring(struct ber_element *prev, const char *string, size_t size);
struct ber_element *
ber_add_ostring(struct ber_element *prev, struct ber_octetstring *ostring);
int
ber_get_string(struct ber_element *root, char **charbuf);
int
ber_get_nstring(struct ber_element *root, void **buf, size_t *size);
int
ber_get_ostring(struct ber_element *root, struct ber_octetstring *ostring);
struct ber_element *
ber_add_bitstring(struct ber_element *prev, const void *buf, size_t size);
int
ber_get_bitstring(struct ber_element *root, void **buf, size_t *size);
struct ber_element *
ber_add_null(struct ber_element *prev);
int
ber_get_null(struct ber_element *root);
struct ber_element *
ber_add_eoc(struct ber_element *prev);
int
ber_get_eoc(struct ber_element *root);
struct ber_element *
ber_add_oid(struct ber_element *prev, struct ber_oid *oid);
struct ber_element *
ber_add_noid(struct ber_element *prev, struct ber_oid *oid, int n);
struct ber_element *
ber_add_oidstring(struct ber_element *prev, const char *string);
int
ber_get_oid(struct ber_element *root, struct ber_oid *oid);
size_t
ber_oid2ber(struct ber_oid *oid, u_int8_t *buf, size_t size);
int
ber_string2oid(const char *string, struct ber_oid *oid);
int
ber_oid_cmp(struct ber_oid *oid, struct ber_oid *oid);
struct ber_element *
ber_printf_elements(struct ber_element *prev, char *format, ...);
int
ber_scanf_elements(struct ber_element *root, char *format, ...);
ssize_t
ber_get_writebuf(struct ber *ber, void **buf);
ssize_t
ber_write_elements(struct ber *ber, struct ber_element *root);
void
ber_set_readbuf(struct ber *ber, void *buf, size_t len);
struct ber_element *
ber_read_elements(struct ber *ber, struct ber_element *root);
off_t
ber_getpos(struct ber_element *elm);
void
ber_free_element(struct ber_element *root);
void
ber_free_elements(struct ber_element *root);
size_t
ber_calc_len(struct ber_element *root);
void
ber_set_application(struct ber *ber, unsigned int (*cb)(struct ber_element *));
void
ber_set_writecallback(struct ber_element *elm, void (*cb)(void *arg, size_t offs), void *arg);
void
ber_free(struct ber *ber);

DESCRIPTION
The ber API provides a mechanism to read and write ASN.1 streams and buffers using the Basic Encoding Rules.

Encoded ber is stored in the following structure:

    struct ber {
    	off_t	 br_offs;
    	u_char	*br_wbuf;
    	u_char	*br_wptr;
    	u_char	*br_wend;
    	u_char	*br_rbuf;
    	u_char	*br_rptr;
    	u_char	*br_rend;
    	unsigned int (*br_application)(struct ber_element *);
    };

br_rbuf and br_wbuf are the read and write buffers for a ber stream. These buffers are used when reading an existing byte stream (e.g. received from a TLS connection), or when writing a new byte stream in preparation for subsequent operations performed by the calling application (e.g. network transmission or export to a file).

Intermediary storage of ber elements during decoding and encoding uses the following structure:

    struct ber_element {
    	struct ber_element	*be_next;
    	unsigned int		 be_type;
    	unsigned int		 be_encoding;
    	size_t			 be_len;
    	off_t			 be_offs;
    	int			 be_free;
    	u_int8_t		 be_class;
    	void			(*be_cb)(void *, size_t);
    	void			*be_cbarg;
    	union {
    		struct ber_element	*bv_sub;
    		void			*bv_val;
    		long long		 bv_numeric;
    	} be_union;
    #define be_sub		be_union.bv_sub
    #define be_val		be_union.bv_val
    #define be_numeric	be_union.bv_numeric
    };

A linked list containing one or more ber_element is created during the decoding and encoding of ber.

Once the ber and ber_element data structures have been declared, ber_set_readbuf() may be called to initialize br_rbuf in preparation for decoding. It is assumed that a pointer to a ber byte stream is already available to the application, commonly obtained by read(2), recv(2), or tls_read(3). ber_read_elements() may then be called to parse, validate, and store the data stream into its consituent parts for subsequent processing. ber_read_elements() returns a pointer to a fully populated list of one or more ber_element, or NULL on a type mismatch or read error.

The calling application must have explicit knowledge of the expected data types in order for correct decoding. ber_scanf_elements() may be called to extract ber_element content into local variables. The ber_get_*() functions extract the value of a single ber_element instance. ber_scanf_elements() and the ber_get_*() functions return 0 on success and -1 on failure.

The first step when creating new ber is to populate ber_element with the desired content. This may be achieved using the ber_add_*() and ber_printf_elements() functions, each of which return a pointer to ber_element on success or NULL on failure.

Once ber_element has been fully populated, ber_get_writebuf() may be used to initialize br_wbuf for writing. ber_write_elements() encodes ber_element into a compliant ber byte stream for subsequent use by the calling application, most commonly using send(2), write(2), or tls_write(3).

I/O OPERATIONS
ber_get_writebuf(), ber_write_elements(), ber_set_readbuf(), ber_read_elements(), ber_getpos(), ber_free_element(), ber_free_elements(), ber_set_application(), ber_set_writecallback(), ber_free()

BER ELEMENTS
ber_get_element(), ber_set_header(), ber_link_elements(), ber_unlink_elements(), ber_replace_elements(), ber_calc_len()

BER TYPES
ber_add_sequence(), ber_add_set(), ber_add_integer(), ber_get_integer(), ber_add_enumerated(), ber_get_enumerated(), ber_add_boolean(), ber_get_boolean(), ber_add_string(), ber_add_nstring(), ber_add_ostring(), ber_add_bitstring(), ber_get_string(), ber_get_nstring(), ber_get_ostring(), ber_get_bitstring(), ber_add_null(), ber_get_null(), ber_add_eoc(), ber_get_eoc()

FORMAT STRINGS
ber_printf_elements(), ber_scanf_elements()

OBJECT IDS
Object Identifiers are commonly used in ASN.1-based protocols. These functions provide an interface to parse OIDs. For internal representation of OIDs, the following structure struct ber_oid is being used:

    #define BER_MIN_OID_LEN		2
    #define BER_MAX_OID_LEN		32
    struct ber_oid {
    	u_int32_t	bo_id[BER_MAX_OID_LEN + 1];
    	size_t		bo_n;
    };

ber_add_oid(), ber_add_noid(), ber_add_oidstring(), ber_get_oid(), ber_oid2ber(), ber_string2oid() ber_oid_cmp(),

RETURN VALUES
Upon successful completion ber_get_integer(), ber_get_enumerated(), ber_get_boolean(), ber_get_string(), ber_get_nstring(), ber_get_ostring(), ber_get_bitstring(), ber_get_null(), ber_get_eoc(), ber_get_oid(), ber_string2oid() and ber_scanf_elements() return 0, while ber_write_elements() returns the number of bytes written. Otherwise, -1 is returned and the global variable errno is set to indicate the error.

SEE ALSO
read(2), recv(2), send(2), write(2), tls_read(3)

STANDARDS
ITU-T Recommendation X.690, also known as ISO/IEC 8825-1: Information technology - ASN.1 encoding rules.

HISTORY
The ber manpage first appeared in OpenBSD 4.3.

AUTHORS
-nosplit The ber library was written by Claudio Jeker <claudio@openbsd.org>, Marc Balmer <marc@openbsd.org> and Reyk Floeter <reyk@openbsd.org>.

CAVEATS
The ber API is subject to the following restrictions which are common to the Distinguished Encoding Rules as defined by X.690:

1.  Only the definite form of length encoding shall be used, encoded in the minimum number of octets.
2.  For bitstring, octetstring and restricted character string types, the constructed form of encoding shall not be used.
3.  If a boolean encoding represents the boolean value TRUE, its single contents octet shall have all eight bits set to one.
4.  Each unused bit in the final octet of the encoding of a bit string value shall be set to zero.
5.  If a bitstring value has no 1 bits, then an encoder shall encode the value with a length of 1 and an initial octet set to 0.

In addition, set and sequence values are limited to a maximum of 65535 elements. No alternative encodings are permitted.

“ Whereas the basic encoding rules give the sender of an encoding various choices as to how data values may be encoded, the canonical and distinguished encoding rules select just one encoding from those allowed by the basic encoding rules. ” [X.690]

The restrictions placed on this API avoid the ambiguity inherent in ber encoded ASN.1 thereby acting as a security mitigation.

BUGS
This manpage is a stub.