summaryrefslogtreecommitdiff
path: root/libder/libder_private.h
diff options
context:
space:
mode:
Diffstat (limited to 'libder/libder_private.h')
-rw-r--r--libder/libder_private.h178
1 files changed, 178 insertions, 0 deletions
diff --git a/libder/libder_private.h b/libder/libder_private.h
new file mode 100644
index 000000000000..3324420ef6d8
--- /dev/null
+++ b/libder/libder_private.h
@@ -0,0 +1,178 @@
+/*-
+ * Copyright (c) 2024 Kyle Evans <kevans@FreeBSD.org>
+ *
+ * SPDX-License-Identifier: BSD-2-Clause
+ */
+
+#pragma once
+
+#include <sys/param.h>
+
+#include <assert.h>
+#include <signal.h>
+#include <stdbool.h>
+#ifdef __APPLE__
+#define __STDC_WANT_LIB_EXT1__ 1 /* memset_s */
+#endif
+/* explicit_bzero is in one of these... */
+#include <string.h>
+#include <strings.h>
+#include "libder.h"
+
+/* FreeBSD's sys/cdefs.h */
+#ifndef __DECONST
+#define __DECONST(type, var) ((type)(uintptr_t)(const void *)(var))
+#endif
+#ifndef __unused
+#define __unused __attribute__((__unused__))
+#endif
+
+/* FreeBSD's sys/params.h */
+#ifndef nitems
+#define nitems(x) (sizeof((x)) / sizeof((x)[0]))
+#endif
+#ifndef MIN
+#define MIN(a,b) (((a)<(b))?(a):(b))
+#endif
+#ifndef MAX
+#define MAX(a,b) (((a)>(b))?(a):(b))
+#endif
+
+struct libder_ctx;
+struct libder_object;
+
+struct libder_ctx {
+ uint64_t normalize;
+ size_t buffer_size;
+ enum libder_error error;
+ int verbose;
+ bool strict;
+ volatile sig_atomic_t abort;
+};
+
+struct libder_tag {
+ union {
+ uint8_t tag_short;
+ uint8_t *tag_long;
+ };
+ size_t tag_size;
+ enum libder_ber_class tag_class;
+ bool tag_constructed;
+ bool tag_encoded;
+};
+
+struct libder_object {
+ struct libder_tag *type;
+ size_t length;
+ size_t nchildren;
+ size_t disk_size;
+ uint8_t *payload; /* NULL for sequences */
+ struct libder_object *children;
+ struct libder_object *parent;
+ struct libder_object *next;
+};
+
+static inline sig_atomic_t
+libder_check_abort(struct libder_ctx *ctx)
+{
+
+ return (ctx->abort);
+}
+
+static inline void
+libder_clear_abort(struct libder_ctx *ctx)
+{
+
+ ctx->abort = 1;
+}
+
+#define LIBDER_PRIVATE __attribute__((__visibility__("hidden")))
+
+#define DER_NORMALIZING(ctx, bit) \
+ (((ctx)->normalize & (LIBDER_NORMALIZE_ ## bit)) != 0)
+
+static inline bool
+libder_normalizing_type(const struct libder_ctx *ctx, const struct libder_tag *type)
+{
+ uint8_t tagval;
+
+ assert(!type->tag_constructed);
+ assert(!type->tag_encoded);
+ assert(type->tag_class == BC_UNIVERSAL);
+ assert(type->tag_short < 0x1f);
+
+ tagval = type->tag_short;
+ return ((ctx->normalize & LIBDER_NORMALIZE_TYPE_FLAG(tagval)) != 0);
+}
+
+/* All of the lower bits set. */
+#define BER_TYPE_LONG_MASK 0x1f
+
+/*
+ * Check if the type matches one of our universal types.
+ */
+static inline bool
+libder_type_is(const struct libder_tag *type, uint8_t utype)
+{
+
+ if (type->tag_class != BC_UNIVERSAL || type->tag_encoded)
+ return (false);
+ if ((utype & BER_TYPE_CONSTRUCTED_MASK) != type->tag_constructed)
+ return (false);
+
+ utype &= ~BER_TYPE_CONSTRUCTED_MASK;
+ return (utype == type->tag_short);
+}
+
+/*
+ * We'll use this one a decent amount, so we'll keep it inline. There's also
+ * an _abi version that we expose as public interface via a 'libder_type_simple'
+ * macro.
+ */
+#undef libder_type_simple
+
+static inline uint8_t
+libder_type_simple(const struct libder_tag *type)
+{
+ uint8_t encoded = type->tag_class << 6;
+
+ assert(!type->tag_encoded);
+ if (type->tag_constructed)
+ encoded |= BER_TYPE_CONSTRUCTED_MASK;
+
+ encoded |= type->tag_short;
+ return (encoded);
+}
+
+static inline void
+libder_bzero(uint8_t *buf, size_t bufsz)
+{
+
+#ifdef __APPLE__
+ memset_s(buf, bufsz, 0, bufsz);
+#else
+ explicit_bzero(buf, bufsz);
+#endif
+}
+
+size_t libder_get_buffer_size(struct libder_ctx *);
+void libder_set_error(struct libder_ctx *, int, const char *, int);
+
+#define libder_set_error(ctx, error) \
+ libder_set_error((ctx), (error), __FILE__, __LINE__)
+
+struct libder_object *libder_obj_alloc_internal(struct libder_ctx *,
+ struct libder_tag *, uint8_t *, size_t, uint32_t);
+#define LDO_OWNTAG 0x0001 /* Object owns passed in tag */
+
+size_t libder_size_length(size_t);
+bool libder_is_valid_obj(struct libder_ctx *,
+ const struct libder_tag *, const uint8_t *, size_t, bool);
+size_t libder_obj_disk_size(struct libder_object *, bool);
+bool libder_obj_may_coalesce_children(const struct libder_object *);
+bool libder_obj_coalesce_children(struct libder_object *, struct libder_ctx *);
+bool libder_obj_normalize(struct libder_object *, struct libder_ctx *);
+
+struct libder_tag *libder_type_alloc(void);
+void libder_type_release(struct libder_tag *);
+void libder_normalize_type(struct libder_ctx *, struct libder_tag *);