ol.clave.crypto.impl.der

DER (Distinguished Encoding Rules) encoding and decoding for ASN.1 structures.

This namespace provides low-level functions for encoding and decoding ASN.1 data structures according to ITU-T X.690 (DER encoding rules).

We implement just enough to: - Generate CSRs - Generate TLS-ALPN-01 challenge certificates - Parse certificate extensions (AIA, AKI) - Parse OCSP responses

Encoding functions return byte arrays. Decoding functions work with byte arrays and return Clojure data structures.

tag-boolean

tag-integer

tag-bit-string

tag-octet-string

tag-null

tag-oid

tag-enumerated

tag-utf8-string

tag-printable-string

tag-ia5-string

tag-utc-time

tag-generalized-time

tag-sequence

tag-set

class-context-specific

constructed-bit

encode-length

(encode-length length)

Encode DER length octets (short or long form).

Short form (length < 128): single byte with the length value. Long form (length >= 128): first byte has high bit set and indicates number of length bytes, followed by length bytes in big-endian order.


concat-bytes

(concat-bytes & arrays)

Concatenate multiple byte arrays into a new byte array.

Efficiently copies all input arrays into a single output array. Returns empty array if no arrays provided.


der-primitive

(der-primitive tag content)

Encode DER primitive with given tag and content.

Tag should be a single-byte tag value (e.g., 0x02 for INTEGER). Content is the raw bytes for this primitive. Returns complete TLV (tag-length-value) encoded byte array.


der-constructed

(der-constructed tag content)

Encode DER constructed with given tag and content.

Tag should include the constructed bit (0x20). Content is the concatenated encoding of all child elements. Returns complete TLV (tag-length-value) encoded byte array.


der-sequence

(der-sequence & parts)

Encode DER SEQUENCE from parts.

Concatenates all parts and wraps in SEQUENCE tag (0x30). Returns encoded SEQUENCE byte array.


der-set

(der-set & parts)

Encode DER SET from parts.

DER requires SET elements to be sorted in lexicographic order by their encoded bytes. This implementation sorts all parts before encoding.

Returns encoded SET byte array.


der-integer

(der-integer value)

Encode DER INTEGER from long value.

Handles zero specially, uses BigInteger for proper two’s complement encoding. Returns encoded INTEGER byte array.


der-integer-bytes

(der-integer-bytes value)

Encode DER INTEGER from byte array.

Adds leading zero if high bit is set to avoid negative interpretation. Returns encoded INTEGER byte array.


der-boolean

(der-boolean v)

Encode DER BOOLEAN.

True encodes as 0xFF, false as 0x00. Returns encoded BOOLEAN byte array.


encode-base128

(encode-base128 value)

Encode a long value as base-128 (for OID encoding).

Used by der-oid for encoding OID arc values. Each byte has high bit set except the last byte. Returns base-128 encoded bytes.


der-oid

(der-oid dotted)

Encode DER OBJECT IDENTIFIER from dotted string.

Example: "2.5.4.3" for CN (Common Name). First two arcs are encoded specially per X.690 (40*arc1 + arc2). Returns encoded OID byte array.


der-utf8-string

(der-utf8-string s)

Encode DER UTF8String.

Encodes string using UTF-8 character set. Returns encoded UTF8String byte array.


der-octet-string

(der-octet-string content)

Encode DER OCTET STRING.

Wraps arbitrary byte content in OCTET STRING tag (0x04). Returns encoded OCTET STRING byte array.


der-bit-string

(der-bit-string bytes)

Encode DER BIT STRING.

First content byte specifies number of unused bits (always 0 here). Returns encoded BIT STRING byte array.


der-utc-time

(der-utc-time date)

Encode DER UTCTime from Date.

Format: YYMMDDHHmmssZ (2-digit year, UTC timezone). Used for dates before 2050 per X.509 conventions. Returns encoded UTCTime byte array.


der-generalized-time

(der-generalized-time date)

Encode DER GeneralizedTime from Date.

Format: YYYYMMDDHHmmssZ (4-digit year, UTC timezone). Used for dates in 2050 or later per X.509 conventions. Returns encoded GeneralizedTime byte array.


der-context-specific-constructed-implicit

(der-context-specific-constructed-implicit tag-number content)

Encode IMPLICIT [tag] CONSTRUCTED with given content.

Context-specific tag with constructed bit set (0xA0 | tag-number). Used for IMPLICIT tagging in ASN.1. Returns encoded context-specific byte array.


der-context-specific-primitive

(der-context-specific-primitive tag-number raw-content)

Encode context-specific PRIMITIVE tag with raw content.

Context-specific tag without constructed bit (0x80 | tag-number). Used for IMPLICIT tagging of primitive types in ASN.1. Returns encoded context-specific byte array.


read-length

(read-length data offset)

Read DER length and return [length bytes-consumed].

Supports short form (single byte < 128) and long form (multi-byte). Returns vector of [length-value number-of-bytes-consumed].


read-tlv

(read-tlv data offset)

Read a complete TLV (tag-length-value) structure.

Returns a map with: - :tag - the raw tag byte - :tag-class - :universal, :application, :context-specific, or :private - :constructed? - true if constructed (contains other TLVs) - :tag-number - the tag number within the class - :value - byte array of the value - :total-length - total bytes consumed including tag and length


decode-sequence-elements

(decode-sequence-elements data)

Decode all elements in a SEQUENCE/SET value.

Takes the value bytes (not including SEQUENCE tag/length) and returns a vector of TLV maps.


decode-integer

(decode-integer value)

Decode a DER INTEGER value bytes to BigInteger.


decode-enumerated

(decode-enumerated value)

Decode a DER ENUMERATED value bytes to long.


decode-oid

(decode-oid value)

Decode a DER OID value bytes to dotted string notation.

First two arcs are encoded as (40 * arc1 + arc2) in the first byte(s). Subsequent arcs use base-128 encoding with high bit continuation.


decode-octet-string

(decode-octet-string value)

Return the raw bytes from an OCTET STRING value.


decode-bit-string

(decode-bit-string value)

Decode a BIT STRING value, returning the actual bits as bytes.

First byte indicates unused bits in the last byte.


decode-ia5-string

(decode-ia5-string value)

Decode an IA5String (ASCII) value to String.


decode-utf8-string

(decode-utf8-string value)

Decode a UTF8String value to String.


decode-printable-string

(decode-printable-string value)

Decode a PrintableString value to String.


decode-generalized-time

(decode-generalized-time value)

Decode a GeneralizedTime value to java.time.Instant.

Format: YYYYMMDDHHmmss[.fraction]Z Supports optional fractional seconds.


decode-utc-time

(decode-utc-time value)

Decode a UTCTime value to java.time.Instant.

Format: YYMMDDHHmmssZ (2-digit year, interpreted as 1950-2049).


find-context-tag

(find-context-tag elements tag-number)

Find a context-specific tagged element by tag number in a sequence of TLVs.

Returns the TLV map if found, nil otherwise.


unwrap-octet-string

(unwrap-octet-string data)

Unwrap a DER OCTET STRING and return its content bytes.

Parses the TLV structure and extracts the value.


unwrap-sequence

(unwrap-sequence data)

Unwrap a DER SEQUENCE and return its decoded elements.

Parses the TLV structure and decodes all child elements.