---
name: "libressl-ASN1_put_object"
section: "3"
platform: "linux"
package: "libressl"
version: "4.4.0-1"
release: "Arch Linux 2026-11-01"
platforms: ["linux"]
url: "https://new.carta.tech/libressl-ASN1_put_object"
---

# libressl-ASN1\_put\_object(3)

start and end the BER encoding of an arbitrary ASN.1 data element

## NAME

**ASN1\_put\_object**, **ASN1\_put\_eoc**, **ASN1\_object\_size** – start and end the BER encoding of an arbitrary ASN.1 data element

## SYNOPSIS

Crypto Library (libcrypto, -lcrypto)

**#include \<openssl/asn1.h\>**

*void*\

**ASN1\_put\_object**(*unsigned char \*\*ber\_out*, *int constructed*, *int content\_length*, *int tag*, *int class*);

*int*\

**ASN1\_put\_eoc**(*unsigned char \*\*ber\_out*);

*int*\

**ASN1\_object\_size**(*int constructed*, *int content\_length*, *int tag*);

## DESCRIPTION

**ASN1\_put\_object**() begins writing the BER encoding of an arbitrary ASN.1 data element to the buffer \*ber\_out by writing the identifier and the length bytes. Making sure that there is sufficient space in the buffer is the responsibility of the caller. This function does not write any content bytes nor any end-of-content bytes.

The tag *class* can be V\_ASN1\_UNIVERSAL, V\_ASN1\_APPLICATION, V\_ASN1\_CONTEXT\_SPECIFIC, or V\_ASN1\_PRIVATE and is written to the two most significant bits of the first byte written.

The *constructed* argument can have the following values:

- 0

  Start a primitive value by setting the third most significant bit of the first byte written to 0. Always use the definite form.

- 1

  Start a constructed value by setting the third most significant bit of the first byte written to 1, and use the definite form.

- 2

  Start a constructed value and use the indefinite form,

If the *tag* is less than V\_ASN1\_PRIMITIVE\_TAG (= 0x1f), it is written to the five least significant bits of the only identifier byte written. Otherwise, these five bits are all set to 1, and the *tag* is encoded in one or more following identifier bytes as needed.

After completing the identifier byte(s), when using the definite form, the given *content\_length* is encoded in one or more bytes as needed, using the long form if and only if the *content\_length* is greater than 127. When using the indefinite form, the special byte 0x80 is written instead and the *content\_length* argument is ignored.

At the end, \**ber\_out* is set to the byte following the last byte written. The calling code can then start writing content bytes.

If the indefinite form was selected, the calling code is also responsible for calling **ASN1\_put\_eoc**() which writes an end-of-content marker to \**ber\_out*, consisting of two NUL bytes, and advances \**ber\_out* by two bytes.

**ASN1\_object\_size**() calculates the total length in bytes of the BER encoding of an ASN.1 data element with the given *tag* and the number of content bytes given by *content\_length*. The *constructed* argument has the same meaning as for **ASN1\_put\_object**(). The return value includes the identifier, length, and content bytes. If *constructed* is 2, it also includes the end-of-content bytes. For the definite form, only the short form is supported if the *content\_length* is less than 128.

## RETURN VALUES

**ASN1\_put\_eoc**() returns the number of bytes written, which is always 2.

**ASN1\_object\_size**() returns the total number of bytes in the encoding of the data element.

## SEE ALSO

ASN1\_item\_i2d(3), ASN1\_TYPE\_get(3), i2d\_ASN1\_NULL(3), i2d\_ASN1\_OBJECT(3), i2d\_ASN1\_OCTET\_STRING(3), i2d\_ASN1\_SEQUENCE\_ANY(3)

## STANDARDS

ITU-T Recommendation X.690, also known as ISO/IEC 8825-1: Information technology - ASN.1 encoding rules: Specification of Basic Encoding Rules (BER), Canonical Encoding Rules (CER) and Distinguished Encoding Rules (DER), section 8.1: General rules for encoding

## HISTORY

**ASN1\_put\_object**() and **ASN1\_object\_size**() first appeared in SSLeay 0.5.1 and have been available since OpenBSD 2.4.

**ASN1\_put\_eoc**() first appeared in OpenSSL 0.9.8 and has been available since OpenBSD 4.5.

## CAVEATS

None of these functions do any sanity checking. When called in inconsistent ways, invalid content may result in \**ber\_out*, for example

- a *tag* number less than V\_ASN1\_PRIMITIVE\_TAG with a *class* other than V\_ASN1\_UNIVERSAL

- a *tag* number equal to V\_ASN1\_EOC (0x00) or V\_ASN1\_PRIMITIVE\_TAG (0x1f)

- a *BOOLEAN*, *INTEGER*, *NULL* etc. with the *constructed* bit set

- a *SEQUENCE* or *SET* etc. without the *constructed* bit set

- a *content\_length* that makes no sense for the given *tag*

- a *content\_length* that disagrees with the following data

- a *BOOLEAN*, *INTEGER*, *NULL* etc. in indefinite form

- an end-of-content marker even though no indefinite form was started

- ...

If the calling code wants to find out how many bytes were written, it needs to save a copy of the pointer \**ber\_out* before calling **ASN1\_put\_object**().
