return 0;
}
- rval = ber_decode(0, td, (void **)&newst, st->buf, st->size);
+ rval = ber_decode(td, (void **)&newst, st->buf, st->size);
if(rval.code == RC_OK) {
*struct_ptr = newst;
return 0;
json_t *json;
attr = NULL;
- rval = ber_decode(NULL, td, &attr, ber->buf, ber->size);
+ rval = ber_decode(td, &attr, ber->buf, ber->size);
json = (rval.code == RC_OK) ? td->op->json_encoder(td, attr) : NULL;
json_t *json;
decoded = NULL;
- rval = ber_decode(NULL, td, &decoded, ber->buf, ber->size);
+ rval = ber_decode(td, &decoded, ber->buf, ber->size);
json = (rval.code == RC_OK) ? td->op->json_encoder(td, decoded) : NULL;
json_t *json;
decoded = NULL;
- rval = ber_decode(NULL, td, &decoded, eContent->buf, eContent->size);
+ rval = ber_decode(td, &decoded, eContent->buf, eContent->size);
json = (rval.code == RC_OK) ? td->op->json_encoder(td, decoded) : NULL;
return er;
}
-
-asn_dec_rval_t
-asn_decode(const asn_codec_ctx_t *opt_codec_ctx,
- enum asn_transfer_syntax syntax, const asn_TYPE_descriptor_t *td,
- void **sptr, const void *buffer, size_t size) {
- if(!td || !td->op || !sptr || (size && !buffer)) {
- ASN__DECODE_FAILED;
- }
-
- switch(syntax) {
- case ATS_CER:
- case ATS_NONSTANDARD_PLAINTEXT:
- default:
- errno = ENOENT;
- ASN__DECODE_FAILED;
-
- case ATS_DER:
- case ATS_BER:
- return ber_decode(opt_codec_ctx, td, sptr, buffer, size);
- }
-}
asn_app_consume_bytes_f *callback, void *callback_key);
-/*
- * A generic decoder for any supported transfer syntax.
- */
-asn_dec_rval_t asn_decode(
- const asn_codec_ctx_t *opt_codec_parameters, enum asn_transfer_syntax,
- const struct asn_TYPE_descriptor_s *type_to_decode,
- void **structure_ptr, /* Pointer to a target structure's pointer */
- const void *buffer, /* Data to be decoded */
- size_t size /* Size of that buffer */
-);
-
-
/*
* A callback of this type is called whenever constraint validation fails
* on some ASN.1 type. See "constraints.h" for more details on constraint
* A value from getrlimit(RLIMIT_STACK) may be used to initialize
* this variable. Be careful in multithreaded environments, as the
* stack size is rather limited.
+ *
+ * 2024-05-15: None of the RPKI objects employ recursive structures, and
+ * they're all somewhat shallow. So this feature seems to be clutter.
+ *
+ * In my test environment, the highest effective ASN1 stack size
+ * reported in a full run was 1296. Fort defaults
+ * `--asn1-decode-max-stack` to 4096. The asn1c default recommended
+ * maximum was 30000. My soft getrlimit(RLIMIT_STACK) is 8192...
+ * I don't feel threatened by these numbers.
+ *
+ * Also, this seems naive. The "ASN1 stack size" isn't really comparable
+ * to RLIMIT_STACK to begin with.
+ *
+ * TODO (fine) Consider (from worst to best)
+ * - switching `--asn1-decode-max-stack` to getrlimit(RLIMIT_STACK),
+ * - drop this feature altogether,
+ * - or replace it with a gcc -fstack-usage analysis/monitor. (See
+ * https://stackoverflow.com/a/74769668/1735458.)
*/
size_t max_stack_size; /* 0 disables stack bounds checking */
} asn_codec_ctx_t;
return -1; \
} while(0)
-/*
- * Check stack against overflow, if limit is set.
- */
-#define ASN__DEFAULT_STACK_MAX (30000)
static int CC_NOTUSED
ASN__STACK_OVERFLOW_CHECK(const asn_codec_ctx_t *ctx) {
if(ctx && ctx->max_stack_size) {
#include <assert.h>
#include "asn1/asn1c/asn_internal.h"
+#include "config.h"
#undef ADVANCE
#define ADVANCE(num_bytes) do { \
* The BER decoder of any type.
*/
asn_dec_rval_t
-ber_decode(const asn_codec_ctx_t *opt_codec_ctx,
- const asn_TYPE_descriptor_t *type_descriptor, void **struct_ptr,
- const void *ptr, size_t size) {
- asn_codec_ctx_t s_codec_ctx;
+ber_decode(const asn_TYPE_descriptor_t *type_descriptor, void **struct_ptr,
+ const void *ptr, size_t size)
+{
+ /* Needs to be allocated on the stack! */
+ asn_codec_ctx_t s_codec_ctx = { 0 };
- /*
- * Stack checker requires that the codec context
- * must be allocated on the stack.
- */
- if(opt_codec_ctx) {
- if(opt_codec_ctx->max_stack_size) {
- s_codec_ctx = *opt_codec_ctx;
- opt_codec_ctx = &s_codec_ctx;
- }
- } else {
- /* If context is not given, be security-conscious anyway */
- memset(&s_codec_ctx, 0, sizeof(s_codec_ctx));
- s_codec_ctx.max_stack_size = ASN__DEFAULT_STACK_MAX;
- opt_codec_ctx = &s_codec_ctx;
- }
+ s_codec_ctx.max_stack_size = config_get_asn1_decode_max_stack();
- /*
- * Invoke type-specific decoder.
- */
- return type_descriptor->op->ber_decoder(opt_codec_ctx, type_descriptor,
+ /* Invoke type-specific decoder. */
+ return type_descriptor->op->ber_decoder(&s_codec_ctx, type_descriptor,
struct_ptr, /* Pointer to the destination structure */
ptr, size, /* Buffer and its size */
0 /* Default tag mode is 0 */
- );
+ );
}
/*
* which is compliant with ber_decode().
*/
asn_dec_rval_t ber_decode(
- const struct asn_codec_ctx_s *opt_codec_ctx,
const struct asn_TYPE_descriptor_s *type_descriptor,
void **struct_ptr, /* Pointer to a target structure's pointer */
const void *buffer, /* Data to be decoded */
#include "asn1/decode.h"
#include "common.h"
-#include "config.h"
#include "log.h"
#include "incidence/incidence.h"
asn1_decode(const void *buffer, size_t buffer_size,
asn_TYPE_descriptor_t const *descriptor, void **result, bool log)
{
- asn_codec_ctx_t s_codec_ctx;
asn_dec_rval_t rval;
int error;
*result = NULL;
- s_codec_ctx.max_stack_size = config_get_asn1_decode_max_stack();
- rval = ber_decode(&s_codec_ctx, descriptor, result, buffer,
- buffer_size);
+ rval = ber_decode(descriptor, result, buffer, buffer_size);
if (rval.code != RC_OK) {
/* Must free partial object according to API contracts. */
ASN_STRUCT_FREE(*descriptor, *result);
goto fail;
}
- res = ber_decode(NULL, &asn_DEF_ContentInfo, (void **)&ci,
+ res = ber_decode(&asn_DEF_ContentInfo, (void **)&ci,
buffer, consumed);
pr_op_debug("Consumed: %zu", res.consumed);