QSC Post Quantum Cryptographic Library 1.3.0.0 (C1)
A post quantum secure library written in Ansi C
Loading...
Searching...
No Matches
encoding.h File Reference

Encoding and decoding functions for Base64, Hex, BER/DER, and PEM. More...

#include "qsccommon.h"

Go to the source code of this file.

Data Structures

struct  qsc_encoding_ber_element
 In-memory representation of a single BER/DER ASN.1 TLV element. More...

Macros

#define QSC_ENCODING_BER_CLASS_UNIVERSAL   0x00U
 ASN.1 universal tag class (bits 8-7 = 00).
#define QSC_ENCODING_BER_CLASS_APPLICATION   0x40U
 ASN.1 application-specific tag class (bits 8-7 = 01).
#define QSC_ENCODING_BER_CLASS_CONTEXT_SPECIFIC   0x80U
 ASN.1 context-specific tag class (bits 8-7 = 10).
#define QSC_ENCODING_BER_CLASS_PRIVATE   0xC0U
 ASN.1 private tag class (bits 8-7 = 11).
#define QSC_BER_ENCODING_INDEFINITE_LENGTH   ((size_t)-1)
 Sentinel value for requesting indefinite-length BER encoding.

Typedefs

typedef QSC_EXPORT_API struct qsc_encoding_ber_element qsc_encoding_ber_element
 In-memory representation of a single BER/DER ASN.1 TLV element.

Enumerations

enum  qsc_encoding_ber_asn1_tag_t {
  BER_ASN1_EOC = 0x00U , BER_ASN1_BOOLEAN = 0x01U , BER_ASN1_INTEGER = 0x02U , BER_ASN1_BIT_STRING = 0x03U ,
  BER_ASN1_OCTET_STRING = 0x04U , BER_ASN1_NULL = 0x05U , BER_ASN1_OBJECT_IDENTIFIER = 0x06U , BER_ASN1_OBJECT_DESCRIPTOR = 0x07U ,
  BER_ASN1_EXTERNAL = 0x08U , BER_ASN1_REAL = 0x09U , BER_ASN1_ENUMERATED = 0x0AU , BER_ASN1_EMBEDDED_PDV = 0x0BU ,
  BER_ASN1_UTF8_STRING = 0x0CU , BER_ASN1_RELATIVE_OID = 0x0DU , BER_ASN1_SEQUENCE = 0x10U , BER_ASN1_SET = 0x11U ,
  BER_ASN1_NUMERIC_STRING = 0x12U , BER_ASN1_PRINTABLE_STRING = 0x13U , BER_ASN1_T61_STRING = 0x14U , BER_ASN1_VIDEOTEX_STRING = 0x15U ,
  BER_ASN1_IA5_STRING = 0x16U , BER_ASN1_UTCTIME = 0x17U , BER_ASN1_GENERALIZEDTIME = 0x18U , BER_ASN1_GRAPHIC_STRING = 0x19U ,
  BER_ASN1_VISIBLE_STRING = 0x1AU , BER_ASN1_GENERAL_STRING = 0x1BU , BER_ASN1_UNIVERSAL_STRING = 0x1CU , BER_ASN1_CHARACTER_STRING = 0x1DU ,
  BER_ASN1_BMP_STRING = 0x1EU
}
 Universal ASN.1 tag numbers as defined in X.680 8.6 and X.690 Table 1. More...

Functions

QSC_EXPORT_API bool qsc_encoding_base64_decode (uint8_t *output, size_t otplen, const char *input, size_t inplen)
 Decode a Base64-encoded string to a byte array.
QSC_EXPORT_API size_t qsc_encoding_base64_decoded_size (const char *input, size_t length)
 Compute the byte count required to hold the decoded form of a Base64 string.
QSC_EXPORT_API bool qsc_encoding_base64_encode (char *output, size_t otplen, const uint8_t *input, size_t inplen)
 Encode a byte array to a Base64 string.
QSC_EXPORT_API size_t qsc_encoding_base64_encoded_size (size_t length)
 Compute the character count required to hold the Base64 encoding of length input bytes, including trailing '=' padding.
QSC_EXPORT_API bool qsc_encoding_base64_is_valid_char (char value)
 Test whether a character belongs to the Base64 alphabet.
QSC_EXPORT_API qsc_encoding_ber_elementqsc_encoding_ber_decode_element (const uint8_t *buffer, size_t buflen, size_t *consumed)
 Decode a single BER element from an octet buffer.
QSC_EXPORT_API size_t qsc_encoding_ber_decode_length (const uint8_t *buffer, size_t buflen, size_t *length, bool *indef)
 Decode a BER length field from an octet buffer.
QSC_EXPORT_API size_t qsc_encoding_ber_decode_tag (const uint8_t *buffer, size_t buflen, uint8_t *tagclass, bool *construct, uint32_t *tagnum)
 Decode a BER tag field from an octet buffer.
QSC_EXPORT_API size_t qsc_encoding_ber_encode_element (qsc_encoding_ber_element *element, uint8_t *buffer, size_t buflen)
 Encode a complete BER element (tag + length + value) to an octet buffer.
QSC_EXPORT_API size_t qsc_encoding_ber_encode_length (size_t length, uint8_t *buffer, size_t buflen)
 Encode a length value to BER form.
QSC_EXPORT_API size_t qsc_encoding_ber_encode_tag (uint8_t tagclass, bool construct, uint32_t tagnum, uint8_t *buffer, size_t buflen)
 Encode an ASN.1 tag to BER form.
QSC_EXPORT_API void qsc_encoding_ber_free_element (qsc_encoding_ber_element *element)
 Recursively free a decoded BER element tree.
QSC_EXPORT_API qsc_encoding_ber_elementqsc_encoding_der_decode_element (const uint8_t *buffer, size_t buflen, size_t *consumed)
 Decode a single DER element from an octet buffer.
QSC_EXPORT_API size_t qsc_encoding_der_encode_element (qsc_encoding_ber_element *element, uint8_t *buffer, size_t buflen)
 Encode an ASN.1 element tree using DER.
QSC_EXPORT_API bool qsc_encoding_hex_decode (const char *input, size_t inplen, uint8_t *output, size_t otplen, size_t *declen)
 Decode a hexadecimal string to binary data.
QSC_EXPORT_API bool qsc_encoding_hex_encode (const uint8_t *input, size_t inplen, char *output, size_t otplen)
 Encode binary data to an upper-case hexadecimal string.
QSC_EXPORT_API bool qsc_encoding_pem_decode (const char *input, size_t inplen, uint8_t *output, size_t otplen, size_t *declen)
 Decode a PEM-formatted string to binary data.
QSC_EXPORT_API bool qsc_encoding_pem_encode (const char *label, char *output, size_t otplen, const uint8_t *data, size_t datalen)
 Encode binary data in PEM format.

Detailed Description

Encoding and decoding functions for Base64, Hex, BER/DER, and PEM.

This header provides production-quality implementations of four encoding schemes that are heavily used in cryptographic infrastructure. All implementations are written to their governing specifications so that encoded output is accepted by any conformant decoder, including the certificate-processing pipelines found in X.509 / PKIX.

Base64 (RFC 4648)
qsc_encoding_base64_encode and qsc_encoding_base64_decode implement the standard Base64 alphabet defined in RFC 4648, Table 1. The decode function enforces the three RFC 4648 padding rules:
  • The total encoded length must be a non-zero multiple of four.
  • The '=' padding character may appear only at positions 2 and/or 3 of the final four-character group.
  • If position 2 of the final group contains '=', position 3 must also contain '=' (two-byte pad form).
Hexadecimal Encoding
qsc_encoding_hex_encode produces upper-case hex and writes a null terminator. qsc_encoding_hex_decode accepts both upper- and lower-case digits and rejects input whose character count is odd. On any decode failure the partially written output buffer is zeroed before the function returns.
BER/DER (ISO/IEC 8825-1 / X.690)
BER (Basic Encoding Rules) and its strict subset DER (Distinguished Encoding Rules) encode ASN.1 values as Tag-Length-Value (TLV) triples. The implementation covers:
  • Short-form (1-byte) and long-form (multi-byte) tag encoding.
  • Short-form (1-byte) and long-form (multi-byte) definite-length encoding.
  • Indefinite-length encoding for constructed BER elements, terminated by the End-of-Contents (EOC) octet pair 0x00 0x00.
  • Recursive encoding and decoding of constructed (composite) elements using a dynamically grown child pointer array.
  • DER encode uses a two-pass approach: a write-free size-computation pass (encoding_der_element_size) followed by a direct in-buffer recursive write, eliminating any fixed-size temporary allocation and correctly handling arbitrarily large structures (e.g. post-quantum X.509 certificates).
  • DER decode delegates to the BER decoder and then rejects any element that used the indefinite-length form, as required by X.690 11.1.
PEM (RFC 7468 / RFC 1421)
PEM wraps a Base64 payload between "-----BEGIN \<label\>-----" and "-----END \<label\>-----" boundaries, with the Base64 data split into lines of exactly 64 characters each. The decode function:
  • Validates that the header and footer carry identical type labels.
  • Validates that the stripped payload length is a multiple of four.
  • Strips intra-line whitespace (spaces, CR, TAB) to tolerate RFC 2822-style folded encoding.
  • Rejects malformed or padded Base64 per the RFC 4648 rules above.
Memory and resource management
Functions that return heap-allocated qsc_encoding_ber_element* trees must be freed by the caller with qsc_encoding_ber_free_element. All other functions write into caller-supplied buffers. There are no internal memory leaks; every allocation failure is recovered before the function returns.
Example: Base64 round-trip
#include "encoding.h"
uint8_t data[] = { 0xDE, 0xAD, 0xBE, 0xEF };
size_t data_len = sizeof(data);
// Encode
size_t enc_len = qsc_encoding_base64_encoded_size(data_len);
char enc[12U] = { 0U }; // enc_len + 1 for NUL
qsc_encoding_base64_encode(enc, sizeof(enc), data, data_len);
// Decode
uint8_t dec[4U] = { 0U };
size_t dec_size = qsc_encoding_base64_decoded_size(enc, enc_len);
qsc_encoding_base64_decode(dec, sizeof(dec), enc, enc_len);
Encoding and decoding functions for Base64, Hex, BER/DER, and PEM.
Example: PEM round-trip
char pem[512U] = { 0U };
qsc_encoding_pem_encode("CERTIFICATE", pem, sizeof(pem), data, data_len);
uint8_t raw[256U] = { 0U };
size_t rawlen = 0U;
qsc_encoding_pem_decode(pem, sizeof(pem), raw, sizeof(raw), &rawlen);
Example: BER element encode/decode
// Encode a primitive INTEGER element containing the value 0x01.
uint8_t val = 0x01U;
elem.length = 1U;
elem.value = &val;
uint8_t ber_buf[8U];
size_t ber_len = qsc_encoding_ber_encode_element(&elem, ber_buf, sizeof(ber_buf));
// Decode it back.
size_t consumed = 0U;
qsc_encoding_ber_decode_element(ber_buf, ber_len, &consumed);
if (decoded != NULL) { qsc_encoding_ber_free_element(decoded); }
#define QSC_ENCODING_BER_CLASS_UNIVERSAL
ASN.1 universal tag class (bits 8-7 = 00).
Definition encoding.h:189
@ BER_ASN1_INTEGER
Definition encoding.h:249
In-memory representation of a single BER/DER ASN.1 TLV element.
Definition encoding.h:311
uint8_t tagclass
Definition encoding.h:312
uint32_t tagnumber
Definition encoding.h:318
uint8_t * value
Definition encoding.h:325
size_t length
Definition encoding.h:322

Reference Documents

Macro Definition Documentation

◆ QSC_BER_ENCODING_INDEFINITE_LENGTH

#define QSC_BER_ENCODING_INDEFINITE_LENGTH   ((size_t)-1)

Sentinel value for requesting indefinite-length BER encoding.

Pass this value as the length argument to qsc_encoding_ber_encode_length to produce the single-byte indefinite- length indicator (0x80) defined in X.690 8.1.3.6. Only valid for constructed BER elements; DER (and primitive BER) always use definite- length form.

◆ QSC_ENCODING_BER_CLASS_APPLICATION

#define QSC_ENCODING_BER_CLASS_APPLICATION   0x40U

ASN.1 application-specific tag class (bits 8-7 = 01).

Used for types whose meaning is specific to an application. The interpretation of the tag number is application-defined. Defined in X.690 8.1.2.2, Table 1.

◆ QSC_ENCODING_BER_CLASS_CONTEXT_SPECIFIC

#define QSC_ENCODING_BER_CLASS_CONTEXT_SPECIFIC   0x80U

ASN.1 context-specific tag class (bits 8-7 = 10).

Used to distinguish between data elements that appear at the same position in different contexts within a structured type (e.g. OPTIONAL fields in a SEQUENCE). Defined in X.690 8.1.2.2, Table 1.

◆ QSC_ENCODING_BER_CLASS_PRIVATE

#define QSC_ENCODING_BER_CLASS_PRIVATE   0xC0U

ASN.1 private tag class (bits 8-7 = 11).

Reserved for enterprise or vendor-specific extensions. Defined in X.690 8.1.2.2, Table 1.

◆ QSC_ENCODING_BER_CLASS_UNIVERSAL

#define QSC_ENCODING_BER_CLASS_UNIVERSAL   0x00U

ASN.1 universal tag class (bits 8-7 = 00).

Used for types that are common to all ASN.1 applications, such as INTEGER, BOOLEAN, SEQUENCE, SET, BIT STRING, OCTET STRING, OBJECT IDENTIFIER, etc. Defined in X.690 8.1.2.2, Table 1.

Typedef Documentation

◆ qsc_encoding_ber_element

typedef QSC_EXPORT_API struct qsc_encoding_ber_element qsc_encoding_ber_element

In-memory representation of a single BER/DER ASN.1 TLV element.

An element is either:

Primitive
The raw value octets are stored in value and length reflects their count. children is NULL and ccount is 0.
Constructed (definite-length)
For elements created by the encoder with a pre-encoded content block, value holds that block and length reflects its byte count. For elements produced by the decoder, children holds pointers to individually decoded child elements and length reflects the total content byte count (not including tag/length overhead of this element).
Constructed (indefinite-length BER only)
indefinite is true. The decoder populates children with all elements found before the EOC marker; the encoder iterates children and appends the 0x00 0x00 EOC pair. DER rejects indefinite-length encoding at both encode and decode time.
Warning
The children array is heap-allocated and owned by this element. Always release element trees with qsc_encoding_ber_free_element to avoid memory leaks.

Enumeration Type Documentation

◆ qsc_encoding_ber_asn1_tag_t

Universal ASN.1 tag numbers as defined in X.680 8.6 and X.690 Table 1.

These values occupy the low five bits of the first tag octet when the tag class is QSC_ENCODING_BER_CLASS_UNIVERSAL and the element uses short-form tag encoding (tag number < 31). Values 14 and 15 are reserved by the standard and are not listed here.

Enumerator
BER_ASN1_EOC 

End-of-Contents (EOC) marker.

BER_ASN1_BOOLEAN 

BOOLEAN.

BER_ASN1_INTEGER 

INTEGER.

BER_ASN1_BIT_STRING 

BIT STRING.

BER_ASN1_OCTET_STRING 

OCTET STRING.

BER_ASN1_NULL 

NULL.

BER_ASN1_OBJECT_IDENTIFIER 

OBJECT IDENTIFIER.

BER_ASN1_OBJECT_DESCRIPTOR 

Object Descriptor (GraphicString subtype).

BER_ASN1_EXTERNAL 

EXTERNAL / INSTANCE OF.

BER_ASN1_REAL 

REAL (floating-point).

BER_ASN1_ENUMERATED 

ENUMERATED.

BER_ASN1_EMBEDDED_PDV 

EMBEDDED PDV.

BER_ASN1_UTF8_STRING 

UTF8String.

BER_ASN1_RELATIVE_OID 

RELATIVE-OID.

BER_ASN1_SEQUENCE 

SEQUENCE / SEQUENCE OF.

BER_ASN1_SET 

SET / SET OF.

BER_ASN1_NUMERIC_STRING 

NumericString.

BER_ASN1_PRINTABLE_STRING 

PrintableString.

BER_ASN1_T61_STRING 

TeletexString (T61String).

BER_ASN1_VIDEOTEX_STRING 

VideotexString.

BER_ASN1_IA5_STRING 

IA5String.

BER_ASN1_UTCTIME 

UTCTime.

BER_ASN1_GENERALIZEDTIME 

GeneralizedTime.

BER_ASN1_GRAPHIC_STRING 

GraphicString.

BER_ASN1_VISIBLE_STRING 

VisibleString (ISO646String).

BER_ASN1_GENERAL_STRING 

GeneralString.

BER_ASN1_UNIVERSAL_STRING 

UniversalString (UTF-32).

BER_ASN1_CHARACTER_STRING 

CharacterString.

BER_ASN1_BMP_STRING 

BMPString (UTF-16 subset).

Function Documentation

◆ qsc_encoding_base64_decode()

QSC_EXPORT_API bool qsc_encoding_base64_decode ( uint8_t * output,
size_t otplen,
const char * input,
size_t inplen )

Decode a Base64-encoded string to a byte array.

Implements RFC 4648, 4. The function performs three sequential validation passes before writing output:

  1. Checks that inplen is a non-zero multiple of four.
  2. Checks that every character belongs to the Base64 alphabet or is '='.
  3. Checks that '=' appears only at the legally permitted positions in the final four-character group.
Parameters
output[uint8_t*] Buffer that receives the decoded bytes. Must be at least qsc_encoding_base64_decoded_size(input, inplen) bytes.
otplen[size_t] Capacity of output in bytes.
input[const char*] Null-terminated or length-bounded Base64 string.
inplen[size_t] Length of input in characters; must be a non-zero multiple of four.
Returns
[bool] true on success; false if any validation check fails or if output is too small.

◆ qsc_encoding_base64_decoded_size()

QSC_EXPORT_API size_t qsc_encoding_base64_decoded_size ( const char * input,
size_t length )

Compute the byte count required to hold the decoded form of a Base64 string.

Accounts for RFC 4648 trailing padding characters ('='). The result is exact when input is a valid, padded Base64 string whose length is a multiple of four. Returns 0 if input is NULL, length is zero, or length is not a multiple of four.

Parameters
input[const char*] Pointer to the Base64-encoded string.
length[size_t] Length of the encoded string in characters.
Returns
[size_t] Number of decoded bytes, or 0 on error.

◆ qsc_encoding_base64_encode()

QSC_EXPORT_API bool qsc_encoding_base64_encode ( char * output,
size_t otplen,
const uint8_t * input,
size_t inplen )

Encode a byte array to a Base64 string.

Implements RFC 4648, 4, using the standard alphabet (A-Z, a-z, 0-9, '+', '/') with '=' padding to ensure the output length is a multiple of four. A null terminator is written after the encoded data.

The caller must supply an output buffer of at least qsc_encoding_base64_encoded_size(inplen) + 1 bytes.

Parameters
output[char*] Buffer that receives the Base64 string.
otplen[size_t] Capacity of output in bytes (must be at least qsc_encoding_base64_encoded_size(inplen) + 1).
input[const uint8_t*] Binary data to encode.
inplen[size_t] Number of bytes to encode.
Returns
[bool] true on success; false if the output buffer is too small or if any pointer argument is NULL.

◆ qsc_encoding_base64_encoded_size()

QSC_EXPORT_API size_t qsc_encoding_base64_encoded_size ( size_t length)

Compute the character count required to hold the Base64 encoding of length input bytes, including trailing '=' padding.

The returned value does not include the null terminator; allocate qsc_encoding_base64_encoded_size(length) + 1 bytes for the output buffer passed to qsc_encoding_base64_encode.

Parameters
length[size_t] Number of raw input bytes.
Returns
[size_t] Number of Base64 characters required (always a multiple of four), or 0 if length is zero.

◆ qsc_encoding_base64_is_valid_char()

QSC_EXPORT_API bool qsc_encoding_base64_is_valid_char ( char value)

Test whether a character belongs to the Base64 alphabet.

Returns true for A-Z, a-z, 0-9, '+', '/', and the padding character '='. All other characters return false.

Parameters
value[char] The character to test.
Returns
[bool] true if value is a legal Base64 symbol.

◆ qsc_encoding_ber_decode_element()

QSC_EXPORT_API qsc_encoding_ber_element * qsc_encoding_ber_decode_element ( const uint8_t * buffer,
size_t buflen,
size_t * consumed )

Decode a single BER element from an octet buffer.

Parses the tag, length, and value (or child elements for constructed types) from buffer according to X.690. For constructed elements, child elements are decoded recursively and stored in a heap-allocated pointer array. Indefinite-length constructed elements are fully supported; the parser consumes child elements until the EOC marker (0x00 0x00) is reached.

On success, *consumed is set to the total number of octets read from buffer (tag + length + value fields, including the EOC pair for indefinite-length elements). On failure, *consumed is set to 0 and the return value is NULL; any partial allocations are freed internally.

The caller must release the returned element tree with qsc_encoding_ber_free_element.

Parameters
buffer[const uint8_t*] Input buffer containing the BER-encoded element.
buflen[size_t] Number of bytes available in buffer. Must be at least 2.
consumed[size_t*] Receives the number of bytes consumed on success, or 0 on failure.
Returns
[qsc_encoding_ber_element*] Pointer to the decoded element tree, or NULL on error.

◆ qsc_encoding_ber_decode_length()

QSC_EXPORT_API size_t qsc_encoding_ber_decode_length ( const uint8_t * buffer,
size_t buflen,
size_t * length,
bool * indef )

Decode a BER length field from an octet buffer.

Implements X.690 8.1.3. All three length forms are supported:

  • Short definite form (1 byte, value < 128).
  • Long definite form (2-9 bytes; the first byte's low seven bits give the count of subsequent length octets).
  • Indefinite form (single byte 0x80); *indef is set to true and *length is set to 0.

The reserved value 0xFF (bnum = 127) and any long-form count that would overflow a native size_t are rejected.

Parameters
buffer[const uint8_t*] Input buffer positioned at the first length octet.
buflen[size_t] Number of bytes available at buffer.
length[size_t*] Receives the decoded length value on success.
indef[bool*] Set to true if the indefinite-length form was decoded.
Returns
[size_t] Number of bytes consumed from buffer (1 for short and indefinite forms; 1 + bnum for long form), or 0 on error.

◆ qsc_encoding_ber_decode_tag()

QSC_EXPORT_API size_t qsc_encoding_ber_decode_tag ( const uint8_t * buffer,
size_t buflen,
uint8_t * tagclass,
bool * construct,
uint32_t * tagnum )

Decode a BER tag field from an octet buffer.

Implements X.690 8.1.2. Both short-form (1-byte, tag number < 31) and long-form (multi-byte base-128, continuation bit in bit 8) tags are handled. If the buffer is exhausted before the final base-128 octet (bit 8 = 0) is found, the function returns 0 to indicate failure.

Parameters
buffer[const uint8_t*] Input buffer positioned at the first tag octet.
buflen[size_t] Number of bytes available at buffer.
tagclass[uint8_t*] Receives the tag class (QSC_ENCODING_BER_CLASS_UNIVERSAL et al.).
construct[bool*] Set to true if the Primitive/Constructed bit (bit 6) is set.
tagnum[uint32_t*] Receives the decoded tag number.
Returns
[size_t] Number of bytes consumed from buffer, or 0 on error.

◆ qsc_encoding_ber_encode_element()

QSC_EXPORT_API size_t qsc_encoding_ber_encode_element ( qsc_encoding_ber_element * element,
uint8_t * buffer,
size_t buflen )

Encode a complete BER element (tag + length + value) to an octet buffer.

Implements X.690 8. Behaviour depends on the element type:

Primitive
Writes the tag, a definite-length field, and the raw value bytes from element->value.
Constructed (definite-length)
Writes the tag, a definite-length field, then copies the pre-encoded content block from element->value.
Constructed (indefinite-length)
Writes the tag, the single-byte indefinite-length indicator (0x80), recursively encodes each child in element->children, then appends the EOC pair (0x00 0x00).
Parameters
element[qsc_encoding_ber_element*] Element to encode.
buffer[uint8_t*] Output buffer.
buflen[size_t] Capacity of buffer in bytes.
Returns
[size_t] Total bytes written to buffer, or 0 on error (e.g. buffer too small, NULL pointer, or a child encoding failure).

◆ qsc_encoding_ber_encode_length()

QSC_EXPORT_API size_t qsc_encoding_ber_encode_length ( size_t length,
uint8_t * buffer,
size_t buflen )

Encode a length value to BER form.

Implements X.690 8.1.3:

  • If length equals QSC_BER_ENCODING_INDEFINITE_LENGTH, writes the single-byte indefinite-length indicator 0x80.
  • If length is in the range [0, 127], writes it as a single byte (short definite-length form).
  • Otherwise encodes length in the minimum number of big-endian octets and prepends a lead byte whose low seven bits give that count.
Parameters
length[size_t] Length value to encode, or QSC_BER_ENCODING_INDEFINITE_LENGTH.
buffer[uint8_t*] Output buffer.
buflen[size_t] Capacity of buffer in bytes.
Returns
[size_t] Number of bytes written, or 0 if the buffer is too small or a pointer argument is NULL.

◆ qsc_encoding_ber_encode_tag()

QSC_EXPORT_API size_t qsc_encoding_ber_encode_tag ( uint8_t tagclass,
bool construct,
uint32_t tagnum,
uint8_t * buffer,
size_t buflen )

Encode an ASN.1 tag to BER form.

Implements X.690 8.1.2:

  • Composes the first byte from tagclass (bits 8-7), construct (bit 6), and the tag-number field (bits 5-1).
  • Short form: if tagnum < 31, the tag number occupies bits 5-1 of the first byte and encoding is complete.
  • Long form: bits 5-1 of the first byte are set to 11111; subsequent bytes encode tagnum in base-128 big-endian with the continuation bit (bit 8) set on every byte except the last.
Parameters
tagclass[uint8_t] Tag class constant (QSC_ENCODING_BER_CLASS_UNIVERSAL et al.).
construct[bool] true for constructed (composite) elements.
tagnum[uint32_t] Tag number; values >= 31 trigger long-form encoding.
buffer[uint8_t*] Output buffer.
buflen[size_t] Capacity of buffer in bytes.
Returns
[size_t] Number of bytes written, or 0 on error (e.g. buffer too small or NULL pointer).

◆ qsc_encoding_ber_free_element()

QSC_EXPORT_API void qsc_encoding_ber_free_element ( qsc_encoding_ber_element * element)

Recursively free a decoded BER element tree.

Releases all memory associated with element and its descendants: for constructed elements the children array and each child element are freed depth-first; for primitive elements the value buffer is freed. The element itself is then freed. Passing NULL is safe and is a no-op.

Parameters
element[qsc_encoding_ber_element*] Root of the element tree to free.

◆ qsc_encoding_der_decode_element()

QSC_EXPORT_API qsc_encoding_ber_element * qsc_encoding_der_decode_element ( const uint8_t * buffer,
size_t buflen,
size_t * consumed )

Decode a single DER element from an octet buffer.

Delegates to qsc_encoding_ber_decode_element and then enforces the DER constraint (X.690 11.1) that indefinite-length encoding is forbidden. If the decoded element carries an indefinite length, it is freed and NULL is returned with *consumed set to 0.

The caller must release the returned element with qsc_encoding_ber_free_element.

Parameters
buffer[const uint8_t*] Input buffer containing the DER-encoded element.
buflen[size_t] Number of bytes available in buffer.
consumed[size_t*] Receives the number of bytes consumed on success, or 0 on failure.
Returns
[qsc_encoding_ber_element*] Pointer to the decoded element, or NULL on error.

◆ qsc_encoding_der_encode_element()

QSC_EXPORT_API size_t qsc_encoding_der_encode_element ( qsc_encoding_ber_element * element,
uint8_t * buffer,
size_t buflen )

Encode an ASN.1 element tree using DER.

Implements X.690 11 (DER). Indefinite-length encoding is rejected. For constructed elements, the function performs a write-free recursive size-computation pass over the child tree to determine the exact content length before writing any output. Child elements are then encoded directly into buffer without an intermediate temporary allocation, making this function suitable for large structures such as post-quantum X.509 certificates whose content may exceed many kilobytes.

Parameters
element[qsc_encoding_ber_element*] Element tree to encode. Must not contain any indefinite-length nodes.
buffer[uint8_t*] Output buffer.
buflen[size_t] Capacity of buffer in bytes.
Returns
[size_t] Total bytes written on success, or 0 on error (indefinite-length element present, buffer too small, NULL pointer, or a child encoding failure).

◆ qsc_encoding_hex_decode()

QSC_EXPORT_API bool qsc_encoding_hex_decode ( const char * input,
size_t inplen,
uint8_t * output,
size_t otplen,
size_t * declen )

Decode a hexadecimal string to binary data.

Accepts both upper- and lower-case hexadecimal digits (0-9, A-F, a-f). The input length must be even. On any decode error (odd length, out-of- range character, or insufficient output buffer) the function clears any partial output it has written, sets *declen to 0, and returns false.

Parameters
input[const char*] Hex-encoded input string.
inplen[size_t] Length of input in characters (must be even).
output[uint8_t*] Buffer that receives the decoded bytes.
otplen[size_t] Capacity of output (must be >= inplen / 2).
declen[size_t*] Receives the number of decoded bytes on success, or 0 on failure.
Returns
[bool] true on success; false on any error.

◆ qsc_encoding_hex_encode()

QSC_EXPORT_API bool qsc_encoding_hex_encode ( const uint8_t * input,
size_t inplen,
char * output,
size_t otplen )

Encode binary data to an upper-case hexadecimal string.

Produces exactly inplen * 2 upper-case hex characters followed by a null terminator. The output buffer must be at least inplen * 2 + 1 bytes.

Parameters
input[const uint8_t*] Binary data to encode.
inplen[size_t] Number of bytes to encode.
output[char*] Buffer that receives the hex string.
otplen[size_t] Capacity of output (must be >= inplen * 2 + 1).
Returns
[bool] true on success; false if the output buffer is too small or if any pointer argument is NULL.

◆ qsc_encoding_pem_decode()

QSC_EXPORT_API bool qsc_encoding_pem_decode ( const char * input,
size_t inplen,
uint8_t * output,
size_t otplen,
size_t * declen )

Decode a PEM-formatted string to binary data.

Implements RFC 7468 textual-encoding format. The function:

  1. Verifies that the header ("-----BEGIN \<label\>-----") and footer ("-----END \<label\>-----") carry identical type labels.
  2. Verifies that the total Base64 character count (after stripping whitespace) is a multiple of four.
  3. Strips intra-line whitespace (spaces, CR, TAB) from each payload line to accommodate RFC 2822 folded lines.
  4. Decodes the resulting Base64 string with full RFC 4648 padding validation.

On any failure *declen is set to 0 and the function returns false.

Parameters
input[const char*] Null-terminated PEM string (header + payload + footer).
inplen[size_t] Size of input in bytes.
output[uint8_t*] Buffer that receives the decoded binary data.
otplen[size_t] Capacity of output in bytes.
declen[size_t*] Receives the number of decoded bytes on success, or 0 on failure.
Returns
[bool] true on success; false on any validation or capacity error.

◆ qsc_encoding_pem_encode()

QSC_EXPORT_API bool qsc_encoding_pem_encode ( const char * label,
char * output,
size_t otplen,
const uint8_t * data,
size_t datalen )

Encode binary data in PEM format.

Produces a RFC 7468-conformant PEM encapsulation:

  • Header line: "-----BEGIN \<label\>-----\n"
  • Base64 data: wrapped at exactly 64 characters per line (RFC 7468 2).
  • Footer line: "-----END \<label\>-----\n"
  • Null terminator appended to output.

Returns false (without writing to output) if the output buffer is too small to hold the complete PEM encoding or if any pointer argument is NULL.

Parameters
label[const char*] Type label string, e.g. "CERTIFICATE".
output[char*] Buffer that receives the PEM text.
otplen[size_t] Capacity of output in bytes.
data[const uint8_t*] Binary data to encode.
datalen[size_t] Number of bytes in data.
Returns
[bool] true on success; false if the buffer is too small or if any pointer argument is NULL.