#ifndef _CORECRYPTO_CCDER_H_
#define _CORECRYPTO_CCDER_H_
#include <corecrypto/ccasn1.h>
#include <corecrypto/ccn.h>
#define CCDER_MULTIBYTE_TAGS 1
#ifdef CCDER_MULTIBYTE_TAGS
typedef unsigned long ccder_tag;
#else
typedef uint8_t ccder_tag;
#endif
enum {
CCDER_EOL = CCASN1_EOL,
CCDER_BOOLEAN = CCASN1_BOOLEAN,
CCDER_INTEGER = CCASN1_INTEGER,
CCDER_BIT_STRING = CCASN1_BIT_STRING,
CCDER_OCTET_STRING = CCASN1_OCTET_STRING,
CCDER_NULL = CCASN1_NULL,
CCDER_OBJECT_IDENTIFIER = CCASN1_OBJECT_IDENTIFIER,
CCDER_OBJECT_DESCRIPTOR = CCASN1_OBJECT_DESCRIPTOR,
CCDER_REAL = CCASN1_REAL,
CCDER_ENUMERATED = CCASN1_ENUMERATED,
CCDER_EMBEDDED_PDV = CCASN1_EMBEDDED_PDV,
CCDER_UTF8_STRING = CCASN1_UTF8_STRING,
CCDER_SEQUENCE = CCASN1_SEQUENCE,
CCDER_SET = CCASN1_SET,
CCDER_NUMERIC_STRING = CCASN1_NUMERIC_STRING,
CCDER_PRINTABLE_STRING = CCASN1_PRINTABLE_STRING,
CCDER_T61_STRING = CCASN1_T61_STRING,
CCDER_VIDEOTEX_STRING = CCASN1_VIDEOTEX_STRING,
CCDER_IA5_STRING = CCASN1_IA5_STRING,
CCDER_UTC_TIME = CCASN1_UTC_TIME,
CCDER_GENERALIZED_TIME = CCASN1_GENERALIZED_TIME,
CCDER_GRAPHIC_STRING = CCASN1_GRAPHIC_STRING,
CCDER_VISIBLE_STRING = CCASN1_VISIBLE_STRING,
CCDER_GENERAL_STRING = CCASN1_GENERAL_STRING,
CCDER_UNIVERSAL_STRING = CCASN1_UNIVERSAL_STRING,
CCDER_BMP_STRING = CCASN1_BMP_STRING,
CCDER_HIGH_TAG_NUMBER = CCASN1_HIGH_TAG_NUMBER,
CCDER_TELETEX_STRING = CCDER_T61_STRING,
#ifdef CCDER_MULTIBYTE_TAGS
CCDER_TAG_MASK = ((ccder_tag)~0),
CCDER_TAGNUM_MASK = ((ccder_tag)~((ccder_tag)7 << (sizeof(ccder_tag) * 8 - 3))),
CCDER_METHOD_MASK = ((ccder_tag)1 << (sizeof(ccder_tag) * 8 - 3)),
CCDER_PRIMITIVE = ((ccder_tag)0 << (sizeof(ccder_tag) * 8 - 3)),
CCDER_CONSTRUCTED = ((ccder_tag)1 << (sizeof(ccder_tag) * 8 - 3)),
CCDER_CLASS_MASK = ((ccder_tag)3 << (sizeof(ccder_tag) * 8 - 2)),
CCDER_UNIVERSAL = ((ccder_tag)0 << (sizeof(ccder_tag) * 8 - 2)),
CCDER_APPLICATION = ((ccder_tag)1 << (sizeof(ccder_tag) * 8 - 2)),
CCDER_CONTEXT_SPECIFIC = ((ccder_tag)2 << (sizeof(ccder_tag) * 8 - 2)),
CCDER_PRIVATE = ((ccder_tag)3 << (sizeof(ccder_tag) * 8 - 2)),
#else
CCDER_TAG_MASK = CCASN1_TAG_MASK,
CCDER_TAGNUM_MASK = CCASN1_TAGNUM_MASK,
CCDER_METHOD_MASK = CCASN1_METHOD_MASK,
CCDER_PRIMITIVE = CCASN1_PRIMITIVE,
CCDER_CONSTRUCTED = CCASN1_CONSTRUCTED,
CCDER_CLASS_MASK = CCASN1_CLASS_MASK,
CCDER_UNIVERSAL = CCASN1_UNIVERSAL,
CCDER_APPLICATION = CCASN1_APPLICATION,
CCDER_CONTEXT_SPECIFIC = CCASN1_CONTEXT_SPECIFIC,
CCDER_PRIVATE = CCASN1_PRIVATE,
#endif
CCDER_CONSTRUCTED_SET = CCDER_SET | CCDER_CONSTRUCTED,
CCDER_CONSTRUCTED_SEQUENCE = CCDER_SEQUENCE | CCDER_CONSTRUCTED,
};
#define CC_NO_INLINE
CC_NO_INLINE CC_CONST
size_t ccder_sizeof(ccder_tag tag, size_t len);
CC_NO_INLINE CC_PURE
size_t ccder_sizeof_implicit_integer(ccder_tag implicit_tag,
cc_size n, const cc_unit *s);
CC_NO_INLINE CC_PURE
size_t ccder_sizeof_implicit_octet_string(ccder_tag implicit_tag,
cc_size n, const cc_unit *s);
CC_NO_INLINE CC_CONST
size_t ccder_sizeof_implicit_raw_octet_string(ccder_tag implicit_tag,
size_t s_size);
CC_NO_INLINE CC_CONST
size_t ccder_sizeof_implicit_uint64(ccder_tag implicit_tag, uint64_t value);
CC_NO_INLINE CC_PURE
size_t ccder_sizeof_integer(cc_size n, const cc_unit *s);
CC_NO_INLINE CC_CONST
size_t ccder_sizeof_len(size_t len);
CC_NO_INLINE CC_PURE
size_t ccder_sizeof_octet_string(cc_size n, const cc_unit *s);
CC_NO_INLINE CC_PURE
size_t ccder_sizeof_oid(ccoid_t oid);
CC_NO_INLINE CC_CONST
size_t ccder_sizeof_raw_octet_string(size_t s_size);
CC_NO_INLINE CC_CONST
size_t ccder_sizeof_tag(ccder_tag tag);
CC_NO_INLINE CC_CONST
size_t ccder_sizeof_uint64(uint64_t value);
CC_NO_INLINE CC_NONNULL2
uint8_t *ccder_encode_tag(ccder_tag tag, const uint8_t *der, uint8_t *der_end);
CC_NO_INLINE CC_NONNULL2
uint8_t *
ccder_encode_len(size_t len, const uint8_t *der, uint8_t *der_end);
CC_NO_INLINE CC_NONNULL3
uint8_t *
ccder_encode_tl(ccder_tag tag, size_t len, const uint8_t *der, uint8_t *der_end);
CC_NO_INLINE CC_PURE CC_NONNULL2
uint8_t *
ccder_encode_body_nocopy(size_t size, const uint8_t *der, uint8_t *der_end);
CC_NO_INLINE CC_NONNULL((2, 3))
uint8_t *
ccder_encode_constructed_tl(ccder_tag tag, const uint8_t *body_end,
const uint8_t *der, uint8_t *der_end);
CC_NO_INLINE CC_NONNULL_TU((1)) CC_NONNULL2
uint8_t *ccder_encode_oid(ccoid_t oid, const uint8_t *der, uint8_t *der_end);
CC_NO_INLINE CC_NONNULL((3, 4))
uint8_t *ccder_encode_implicit_integer(ccder_tag implicit_tag,
cc_size n, const cc_unit *s,
const uint8_t *der, uint8_t *der_end);
CC_NO_INLINE CC_NONNULL((2, 3))
uint8_t *ccder_encode_integer(cc_size n, const cc_unit *s,
const uint8_t *der, uint8_t *der_end);
CC_NO_INLINE CC_NONNULL3
uint8_t *ccder_encode_implicit_uint64(ccder_tag implicit_tag,
uint64_t value,
const uint8_t *der, uint8_t *der_end);
CC_NO_INLINE CC_NONNULL2
uint8_t *ccder_encode_uint64(uint64_t value,
const uint8_t *der, uint8_t *der_end);
CC_NO_INLINE CC_NONNULL((3, 4))
uint8_t *ccder_encode_implicit_octet_string(ccder_tag implicit_tag,
cc_size n, const cc_unit *s,
const uint8_t *der,
uint8_t *der_end);
CC_NO_INLINE CC_NONNULL((2, 3))
uint8_t *ccder_encode_octet_string(cc_size n, const cc_unit *s,
const uint8_t *der, uint8_t *der_end);
CC_NO_INLINE CC_NONNULL((3, 4))
uint8_t *ccder_encode_implicit_raw_octet_string(ccder_tag implicit_tag,
size_t s_size, const uint8_t *s,
const uint8_t *der,
uint8_t *der_end);
CC_NO_INLINE CC_NONNULL((2, 3))
uint8_t *ccder_encode_raw_octet_string(size_t s_size, const uint8_t *s,
const uint8_t *der, uint8_t *der_end);
CC_NO_INLINE CC_NONNULL3
uint8_t *
ccder_encode_body(size_t size, const uint8_t* body,
const uint8_t *der, uint8_t *der_end);
CC_NO_INLINE CC_NONNULL((1, 3))
const uint8_t *ccder_decode_tag(ccder_tag *tagp, const uint8_t *der, const uint8_t *der_end);
CC_NO_INLINE CC_NONNULL((1, 3))
const uint8_t *ccder_decode_len(size_t *lenp, const uint8_t *der, const uint8_t *der_end);
CC_NO_INLINE CC_NONNULL((2, 4))
const uint8_t *ccder_decode_tl(ccder_tag expected_tag, size_t *lenp,
const uint8_t *der, const uint8_t *der_end);
CC_NO_INLINE CC_NONNULL((2, 4))
const uint8_t *
ccder_decode_constructed_tl(ccder_tag expected_tag, const uint8_t **body_end,
const uint8_t *der, const uint8_t *der_end);
CC_NO_INLINE CC_NONNULL((1, 3))
const uint8_t *
ccder_decode_sequence_tl(const uint8_t **body_end,
const uint8_t *der, const uint8_t *der_end);
CC_NO_INLINE CC_NONNULL((2, 4))
const uint8_t *ccder_decode_uint(cc_size n, cc_unit *r,
const uint8_t *der, const uint8_t *der_end);
CC_NO_INLINE CC_NONNULL((1, 3))
const uint8_t *ccder_decode_uint64(uint64_t* r,
const uint8_t *der, const uint8_t *der_end);
CC_NO_INLINE CC_NONNULL((2, 3, 5))
const uint8_t *ccder_decode_seqii(cc_size n, cc_unit *r, cc_unit *s,
const uint8_t *der, const uint8_t *der_end);
CC_NO_INLINE CC_NONNULL_TU((1)) CC_NONNULL((3))
const uint8_t *ccder_decode_oid(ccoid_t *oidp,
const uint8_t *der, const uint8_t *der_end);
CC_NO_INLINE CC_NONNULL_ALL
const uint8_t *ccder_decode_bitstring(const uint8_t **bit_string,
size_t *bit_length,
const uint8_t *der, const uint8_t *der_end);
CC_NO_INLINE CC_NONNULL_ALL
const uint8_t *ccder_decode_eckey(uint64_t *version,
size_t *priv_size, const uint8_t **priv_key,
ccoid_t *oid,
size_t *pub_size, const uint8_t **pub_key,
const uint8_t *der, const uint8_t *der_end);
#ifndef CCDER_MULTIBYTE_TAGS
#include <corecrypto/ccder_decode_constructed_tl.h>
#include <corecrypto/ccder_decode_len.h>
#include <corecrypto/ccder_decode_oid.h>
#include <corecrypto/ccder_decode_seqii.h>
#include <corecrypto/ccder_decode_sequence_tl.h>
#include <corecrypto/ccder_decode_tag.h>
#include <corecrypto/ccder_decode_tl.h>
#include <corecrypto/ccder_decode_uint.h>
#include <corecrypto/ccder_decode_bitstring.h>
#include <corecrypto/ccder_decode_eckey.h>
#include <corecrypto/ccder_encode_body_nocopy.h>
#include <corecrypto/ccder_encode_constructed_tl.h>
#include <corecrypto/ccder_encode_implicit_integer.h>
#include <corecrypto/ccder_encode_implicit_octet_string.h>
#include <corecrypto/ccder_encode_implicit_uint64.h>
#include <corecrypto/ccder_encode_integer.h>
#include <corecrypto/ccder_encode_len.h>
#include <corecrypto/ccder_encode_octet_string.h>
#include <corecrypto/ccder_encode_oid.h>
#include <corecrypto/ccder_encode_tag.h>
#include <corecrypto/ccder_encode_tl.h>
#include <corecrypto/ccder_encode_uint64.h>
#include <corecrypto/ccder_sizeof.h>
#include <corecrypto/ccder_sizeof_integer.h>
#include <corecrypto/ccder_sizeof_len.h>
#include <corecrypto/ccder_sizeof_oid.h>
#include <corecrypto/ccder_sizeof_tag.h>
#endif
#endif