1.\" $OpenBSD: ober_read_elements.3,v 1.3 2021/03/12 05:18:01 jsg Exp $ 2.\" 3.\" Copyright (c) 2007, 2012 Reyk Floeter <reyk@openbsd.org> 4.\" 5.\" Permission to use, copy, modify, and distribute this software for any 6.\" purpose with or without fee is hereby granted, provided that the above 7.\" copyright notice and this permission notice appear in all copies. 8.\" 9.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 10.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 11.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 12.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 13.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 14.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 15.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 16.\" 17.Dd $Mdocdate: March 12 2021 $ 18.Dt OBER_READ_ELEMENTS 3 19.Os 20.Sh NAME 21.Nm ober_set_readbuf , 22.Nm ober_set_application , 23.Nm ober_read_elements , 24.Nm ober_get_writebuf , 25.Nm ober_write_elements , 26.Nm ober_free 27.Nd encode and decode ASN.1 with Basic Encoding Rules 28.Sh SYNOPSIS 29.In sys/types.h 30.In ber.h 31.Ft "void" 32.Fn "ober_set_readbuf" "struct ber *ber" "void *buf" "size_t len" 33.Ft "void" 34.Fo "ober_set_application" 35.Fa "struct ber *ber" 36.Fa "unsigned int (*cb)(struct ber_element *)" 37.Fc 38.Ft "struct ber_element *" 39.Fn "ober_read_elements" "struct ber *ber" "struct ber_element *root" 40.Ft "ssize_t" 41.Fn "ober_get_writebuf" "struct ber *ber" "void **buf" 42.Ft "ssize_t" 43.Fn "ober_write_elements" "struct ber *ber" "struct ber_element *root" 44.Ft "void" 45.Fn "ober_free" "struct ber *ber" 46.Sh DESCRIPTION 47The BER API provides a mechanism to read and write ASN.1 using the 48Basic Encoding Rules. 49.Pp 50Encoded BER is stored in the following structure: 51.Bd -literal 52struct ber { 53 off_t br_offs; 54 u_char *br_wbuf; 55 u_char *br_wptr; 56 u_char *br_wend; 57 u_char *br_rbuf; 58 u_char *br_rptr; 59 u_char *br_rend; 60 61 unsigned int (*br_application)(struct ber_element *); 62}; 63.Ed 64.Pp 65.Fa br_rbuf 66and 67.Fa br_wbuf 68are the read and write buffers for a BER byte stream. 69These buffers are used when reading an existing byte stream (e.g. received from 70a TLS connection), or when writing a new byte stream in preparation for 71subsequent operations performed by the calling application (e.g. network 72transmission or export to a file). 73.Pp 74Intermediary storage of BER elements during encoding and decoding uses the 75following structure: 76.Bd -literal 77struct ber_element { 78 struct ber_element *be_next; 79 unsigned int be_type; 80 unsigned int be_encoding; 81 size_t be_len; 82 off_t be_offs; 83 int be_free; 84 u_int8_t be_class; 85 void (*be_cb)(void *, size_t); 86 void *be_cbarg; 87 union { 88 struct ber_element *bv_sub; 89 void *bv_val; 90 long long bv_numeric; 91 } be_union; 92#define be_sub be_union.bv_sub 93#define be_val be_union.bv_val 94#define be_numeric be_union.bv_numeric 95}; 96.Ed 97.Pp 98.Fn ober_set_readbuf 99sets 100.Fa br_rbuf 101to point an input buffer of BER encoded bytes in preparation for decoding. 102It is assumed that 103.Fa br_rbuf 104is already populated and available to the 105application, commonly obtained by 106.Xr read 2 , 107.Xr recv 2 , 108or 109.Xr tls_read 3 . 110.Pp 111.Fn ober_read_elements 112may then be called to parse, validate, and store the 113.Fa ber 114data stream into its 115constituent 116.Vt ber_element 117parts for subsequent processing. 118The calling application must have explicit knowledge of the expected data 119types in order for correct decoding. 120.Pp 121.Fn ober_get_writebuf 122sets 123.Fa br_wbuf 124to point to an output buffer for writing a BER byte stream. 125.Pp 126.Fn ober_write_elements 127encodes 128.Fa root 129into a compliant BER byte stream which is written to 130.Fa ber 131for subsequent use by the calling 132functions such as 133.Xr send 2 , 134.Xr write 2 , 135or 136.Xr tls_write 3 . 137.Pp 138.Fn ober_free 139frees any dynamically allocated storage associated with 140.Fa ber . 141.Sh RETURN VALUES 142.Fn ober_read_elements 143returns a pointer to a fully populated list of one or more 144.Vt ber_element 145structures. 146Otherwise \-1 is returned and the global variable 147.Va errno 148is set to indicate the error. 149.Pp 150.Fn ober_get_writebuf 151returns the number of bytes contained within the buffer 152.Fa buf 153or \-1 on failure. 154.Pp 155.Fn ober_write_elements 156returns the number of bytes written. 157Otherwise \-1 is returned and the global variable 158.Va errno 159is set to 160.Er ENOMEM . 161.Sh ERRORS 162.Fn ober_read_elements 163will fail if: 164.Bl -tag -width Er 165.It Bq Er ENOMEM 166No memory was available to create the full 167.Vt ber_element 168structure list. 169.It Bq Er ENOBUFS 170.Fn ober_read_elements 171was called before calling 172.Fn ober_set_readbuf . 173.It Bq Er ECANCELED 174.Fa buf 175does not contain enough data to complete the unpacking. 176.It Bq Er EINVAL 177.Fa buf 178does not contain a valid BER data structure. 179.It Bq Er ERANGE 180One of the values in the structure is larger than the library can unpack. 181.El 182.Sh SEE ALSO 183.Xr read 2 , 184.Xr recv 2 , 185.Xr send 2 , 186.Xr write 2 , 187.Xr ober_add_string 3 , 188.Xr ober_get_string 3 , 189.Xr ober_oid_cmp 3 , 190.Xr ober_set_header 3 , 191.Xr tls_read 3 192.Sh STANDARDS 193ITU-T Recommendation X.690, also known as ISO/IEC 8825-1: 194Information technology - ASN.1 encoding rules. 195.Sh HISTORY 196These functions first appeared as internal functions in 197.Xr snmpd 8 198in 199.Ox 4.2 200and were moved to libutil in 201.Ox 6.6 . 202.Sh AUTHORS 203.An -nosplit 204The BER library was written by 205.An Claudio Jeker Aq Mt claudio@openbsd.org , 206.An Marc Balmer Aq Mt marc@openbsd.org 207and 208.An Reyk Floeter Aq Mt reyk@openbsd.org . 209.Sh CAVEATS 210The BER 211API is subject to the following restrictions which are common to the 212Distinguished Encoding Rules as defined by X.690: 213.Pp 214.Bl -enum -compact 215.It 216Only the definite form of length encoding shall be used, encoded in the 217minimum number of octets. 218.It 219For bitstring, octetstring and restricted character string types, the 220constructed form of encoding shall not be used. 221.It 222If a boolean encoding represents the boolean value TRUE, its single contents 223octet shall have all eight bits set to one. 224.It 225Each unused bit in the final octet of the encoding of a bit string value shall 226be set to zero. 227.It 228If a bitstring value has no 1 bits, then an encoder shall encode the value with 229a length of 1 and an initial octet set to 0. 230.El 231.Pp 232In addition, set and sequence values are limited to a maximum of 65535 elements. 233No alternative encodings are permitted. 234.Pp 235.Do 236Whereas the basic encoding rules give the sender of an encoding various choices 237as to how data values may be encoded, the canonical and distinguished encoding 238rules select just one encoding from those allowed by the basic encoding rules. 239.Dc 240.Bq X.690 241.Pp 242The restrictions placed on this API avoid the ambiguity inherent in 243BER encoded ASN.1 thereby acting as a security mitigation. 244