fort_SOURCES += log.h log.c
fort_SOURCES += nid.h nid.c
fort_SOURCES += output_printer.h output_printer.c
+fort_SOURCES += print_file.h print_file.c
fort_SOURCES += resource.h resource.c
fort_SOURCES += rpp.h rpp.c
fort_SOURCES += rrdp.h rrdp.c
fort_SOURCES += xml/relax_ng.c xml/relax_ng.h
-# I'm placing these at the end because they rarely change, and I want warnings
-# to appear as soon as possible.
include asn1/asn1c/Makefile.include
fort_SOURCES += $(ASN_MODULE_SRCS) $(ASN_MODULE_HDRS)
OCTET_STRING_compare,
OCTET_STRING_decode_ber,
OCTET_STRING_encode_der,
+ OCTET_STRING_encode_json,
ANY_encode_xer,
0 /* Use generic outmost tag fetcher */
};
BIT_STRING_compare,
OCTET_STRING_decode_ber, /* Implemented in terms of OCTET STRING */
OCTET_STRING_encode_der, /* Implemented in terms of OCTET STRING */
+ OCTET_STRING_encode_json, /* Implemented in terms of OCTET STRING */
BIT_STRING_encode_xer,
0 /* Use generic outmost tag fetcher */
};
BOOLEAN_compare,
BOOLEAN_decode_ber,
BOOLEAN_encode_der,
+ BOOLEAN_encode_json,
BOOLEAN_encode_xer,
0 /* Use generic outmost tag fetcher */
};
ASN__ENCODED_OK(erval);
}
+json_t *
+BOOLEAN_encode_json(const struct asn_TYPE_descriptor_s *td, const void *sptr)
+{
+ const BOOLEAN_t *st = (const BOOLEAN_t *)sptr;
+
+ if (st == NULL)
+ return json_null();
+
+ return (*st) ? json_true() : json_false();
+}
+
asn_enc_rval_t
BOOLEAN_encode_xer(const asn_TYPE_descriptor_t *td, const void *sptr,
int ilevel, enum xer_encoder_flags_e flags,
asn_struct_compare_f BOOLEAN_compare;
ber_type_decoder_f BOOLEAN_decode_ber;
der_type_encoder_f BOOLEAN_encode_der;
+json_type_encoder_f BOOLEAN_encode_json;
xer_type_encoder_f BOOLEAN_encode_xer;
#define BOOLEAN_constraint asn_generic_no_constraint
#include "asn1/asn1c/CMSAttribute.h"
+#include "asn1/asn1c/ContentType.h"
+#include "asn1/asn1c/MessageDigest.h"
+#include "asn1/asn1c/SigningTime.h"
+
+static json_t *
+attr2json(asn_TYPE_descriptor_t const *td, struct CMSAttribute const *cattr)
+{
+ json_t *array, *node;
+ CMSAttributeValue_t *ber;
+ void *attr;
+ int i;
+ asn_dec_rval_t rval;
+
+ array = json_array();
+ if (array == NULL)
+ return NULL;
+
+ for (i = 0; i < cattr->attrValues.list.count; i++) {
+ ber = cattr->attrValues.list.array[i];
+ attr = NULL;
+
+ rval = ber_decode(NULL, td, &attr, ber->buf, ber->size);
+ if (rval.code != RC_OK)
+ goto fail;
+
+ node = td->op->json_encoder(td, attr);
+
+ ASN_STRUCT_FREE(*td, attr);
+
+ if (json_array_append_new(array, node) < 0)
+ goto fail;
+ }
+
+ return array;
+
+fail: json_decref(array);
+ return NULL;
+}
+
+json_t *
+CMSAttribute_encode_json(const asn_TYPE_descriptor_t *td, const void *sptr)
+{
+ struct CMSAttribute const *cattr = sptr;
+
+ if (!cattr)
+ return json_null();
+ if (OBJECT_IDENTIFIER_is_ContentType(&cattr->attrType))
+ return attr2json(&asn_DEF_ContentType, cattr);
+ if (OBJECT_IDENTIFIER_is_MessageDigest(&cattr->attrType))
+ return attr2json(&asn_DEF_MessageDigest, cattr);
+ if (OBJECT_IDENTIFIER_is_SigningTime(&cattr->attrType))
+ return attr2json(&asn_DEF_SigningTime, cattr);
+
+ return SEQUENCE_encode_json(td, sptr);
+}
+
+asn_TYPE_operation_t asn_OP_CMSAttribute = {
+ SEQUENCE_free,
+ SEQUENCE_print,
+ SEQUENCE_compare,
+ SEQUENCE_decode_ber,
+ SEQUENCE_encode_der,
+ CMSAttribute_encode_json,
+ SEQUENCE_encode_xer,
+ 0 /* Use generic outmost tag fetcher */
+};
+
static asn_TYPE_member_t asn_MBR_attrValues_3[] = {
{ ATF_ANY_TYPE | ATF_POINTER, 0, 0,
-1 /* Ambiguous tag (ANY?) */,
asn_TYPE_descriptor_t asn_DEF_CMSAttribute = {
"CMSAttribute",
"CMSAttribute",
- &asn_OP_SEQUENCE,
+ &asn_OP_CMSAttribute,
asn_DEF_CMSAttribute_tags_1,
sizeof(asn_DEF_CMSAttribute_tags_1)
/sizeof(asn_DEF_CMSAttribute_tags_1[0]), /* 1 */
#include "asn1/asn1c/ContentInfo.h"
+#include "asn1/asn1c/SignedData.h"
+
+json_t *
+content2json(const asn_TYPE_descriptor_t *td, ANY_t const *ber)
+{
+ void *decoded;
+ asn_dec_rval_t rval;
+ json_t *content;
+
+ decoded = NULL;
+ rval = ber_decode(NULL, td, &decoded, ber->buf, ber->size);
+ if (rval.code != RC_OK)
+ return NULL;
+
+ content = td->op->json_encoder(td, decoded);
+
+ ASN_STRUCT_FREE(*td, decoded);
+ return content;
+}
+
+json_t *
+ContentInfo_encode_json(const asn_TYPE_descriptor_t *td, const void *sptr)
+{
+ struct ContentInfo const *ci = sptr;
+ json_t *parent;
+ json_t *content_type;
+ json_t *content;
+
+ if (!ci)
+ return json_null();
+
+ parent = json_object();
+ if (parent == NULL)
+ return NULL;
+
+ td = &asn_DEF_ContentType;
+ content_type = td->op->json_encoder(td, &ci->contentType);
+ if (content_type == NULL)
+ goto fail;
+ if (json_object_set_new(parent, td->name, content_type))
+ goto fail;
+
+ if (OBJECT_IDENTIFIER_is_SignedData(&ci->contentType)) {
+ td = &asn_DEF_SignedData;
+ content = content2json(td, &ci->content);
+
+ } else {
+// printf("===========================\n");
+// for (ret = 0; ret < ci->contentType.size; ret++)
+// printf("%u ", ci->contentType.buf[ret]);
+// printf("\n==========================\n");
+
+ td = &asn_DEF_ANY;
+ content = td->op->json_encoder(td, &ci->content);
+ }
+
+ if (content == NULL)
+ goto fail;
+ if (json_object_set_new(parent, td->name, content))
+ goto fail;
+
+ return parent;
+
+fail: json_decref(parent);
+ return NULL;
+}
+
+asn_TYPE_operation_t asn_OP_ContentInfo = {
+ SEQUENCE_free,
+ SEQUENCE_print,
+ SEQUENCE_compare,
+ SEQUENCE_decode_ber,
+ SEQUENCE_encode_der,
+ ContentInfo_encode_json,
+ SEQUENCE_encode_xer,
+ 0 /* Use generic outmost tag fetcher */
+};
+
static asn_TYPE_member_t asn_MBR_ContentInfo_1[] = {
{ ATF_NOFLAGS, 0, offsetof(struct ContentInfo, contentType),
(ASN_TAG_CLASS_UNIVERSAL | (6 << 2)),
asn_TYPE_descriptor_t asn_DEF_ContentInfo = {
"ContentInfo",
"ContentInfo",
- &asn_OP_SEQUENCE,
+ &asn_OP_ContentInfo,
asn_DEF_ContentInfo_tags_1,
sizeof(asn_DEF_ContentInfo_tags_1)
/sizeof(asn_DEF_ContentInfo_tags_1[0]), /* 1 */
#include "asn1/asn1c/EncapsulatedContentInfo.h"
+#include "asn1/asn1c/Manifest.h"
+#include "asn1/asn1c/RouteOriginAttestation.h"
+
+static json_t *
+econtent2json(asn_TYPE_descriptor_t const *td, OCTET_STRING_t *eContent)
+{
+ void *decoded;
+ asn_dec_rval_t rval;
+ json_t *content;
+
+ decoded = NULL;
+ rval = ber_decode(NULL, td, &decoded, eContent->buf, eContent->size);
+ if (rval.code != RC_OK)
+ return NULL;
+
+ content = td->op->json_encoder(td, decoded);
+
+ ASN_STRUCT_FREE(*td, decoded);
+ return content;
+}
+
+json_t *
+EncapsulatedContentInfo_encode_json(const asn_TYPE_descriptor_t *td,
+ const void *sptr)
+{
+ struct EncapsulatedContentInfo const *eci = sptr;
+ json_t *parent;
+ json_t *content_type;
+ json_t *content;
+
+ if (!eci)
+ return json_null();
+
+ parent = json_object();
+ if (parent == NULL)
+ return NULL;
+
+ td = &asn_DEF_ContentType;
+ content_type = td->op->json_encoder(td, &eci->eContentType);
+ if (content_type == NULL)
+ goto fail;
+ if (json_object_set_new(parent, td->name, content_type))
+ goto fail;
+
+ if (OBJECT_IDENTIFIER_is_mft(&eci->eContentType)) {
+ td = &asn_DEF_Manifest;
+ content = econtent2json(td, eci->eContent);
+
+ } else if (OBJECT_IDENTIFIER_is_roa(&eci->eContentType)) {
+ td = &asn_DEF_RouteOriginAttestation;
+ content = econtent2json(td, eci->eContent);
+
+ } else if (OBJECT_IDENTIFIER_is_gbr(&eci->eContentType)) {
+ td = &asn_DEF_OCTET_STRING;
+ content = OCTET_STRING_encode_json_utf8(td, eci->eContent);
+
+ } else {
+// printf("===========================\n");
+// for (ret = 0; ret < eci->eContentType.size; ret++)
+// printf("%u ", eci->eContentType.buf[ret]);
+// printf("\n==========================\n");
+
+ td = &asn_DEF_OCTET_STRING;
+ content = td->op->json_encoder(td, eci->eContent);
+ }
+
+ if (content == NULL)
+ goto fail;
+ if (json_object_set_new(parent, td->name, content))
+ goto fail;
+
+ return parent;
+
+fail: json_decref(parent);
+ return NULL;
+}
+
+asn_TYPE_operation_t asn_OP_EncapsulatedContentInfo = {
+ SEQUENCE_free,
+ SEQUENCE_print,
+ SEQUENCE_compare,
+ SEQUENCE_decode_ber,
+ SEQUENCE_encode_der,
+ EncapsulatedContentInfo_encode_json,
+ SEQUENCE_encode_xer,
+ 0 /* Use generic outmost tag fetcher */
+};
+
asn_TYPE_member_t asn_MBR_EncapsulatedContentInfo_1[] = {
{ ATF_NOFLAGS, 0, offsetof(struct EncapsulatedContentInfo, eContentType),
(ASN_TAG_CLASS_UNIVERSAL | (6 << 2)),
asn_TYPE_descriptor_t asn_DEF_EncapsulatedContentInfo = {
"EncapsulatedContentInfo",
"EncapsulatedContentInfo",
- &asn_OP_SEQUENCE,
+ &asn_OP_EncapsulatedContentInfo,
asn_DEF_EncapsulatedContentInfo_tags_1,
sizeof(asn_DEF_EncapsulatedContentInfo_tags_1)
/sizeof(asn_DEF_EncapsulatedContentInfo_tags_1[0]), /* 1 */
GeneralizedTime_compare,
OCTET_STRING_decode_ber, /* Implemented in terms of OCTET STRING */
GeneralizedTime_encode_der,
+ GeneralizedTime_encode_json,
GeneralizedTime_encode_xer,
0 /* Use generic outmost tag fetcher */
};
#endif /* ASN___INTERNAL_TEST_MODE */
+static int
+GeneralizedTime2str(const GeneralizedTime_t *st, char *str)
+{
+ struct tm tm;
+
+ if (asn_GT2time(st, &tm) != 0)
+ return -1;
+
+ return asn_tm2str(&tm, str);
+}
+
/*
* Check that the time looks like the time.
*/
return erval;
}
+json_t *
+GeneralizedTime_encode_json(const struct asn_TYPE_descriptor_s *td, const void *sptr)
+{
+ const GeneralizedTime_t *st = (const GeneralizedTime_t *)sptr;
+ char buf[ASN_TM_STR_MAXLEN];
+
+ if (st == NULL || st->buf == NULL)
+ return json_null();
+
+ if (GeneralizedTime2str(st, buf) < 0)
+ return NULL;
+
+ return json_string(buf);
+}
+
#ifndef ASN___INTERNAL_TEST_MODE
asn_enc_rval_t
int
GeneralizedTime_print(const asn_TYPE_descriptor_t *td, const void *sptr,
- int ilevel, asn_app_consume_bytes_f *cb, void *app_key) {
- const GeneralizedTime_t *st = (const GeneralizedTime_t *)sptr;
+ int ilevel, asn_app_consume_bytes_f *cb, void *app_key)
+{
+ const GeneralizedTime_t *st = (const GeneralizedTime_t *)sptr;
+ char buf[ASN_TM_STR_MAXLEN];
+ int ret;
- (void)td; /* Unused argument */
- (void)ilevel; /* Unused argument */
+ if (st == NULL || st->buf == NULL)
+ return (cb("<absent>", 8, app_key) < 0) ? -1 : 0;
- if(st && st->buf) {
- char buf[32];
- struct tm tm;
- int ret;
+ ret = GeneralizedTime2str(st, buf);
+ if (ret < 0)
+ return (cb("<bad-value>", 11, app_key) < 0) ? -1 : 0;
- if(asn_GT2time(st, &tm) != 0)
- return (cb("<bad-value>", 11, app_key) < 0) ? -1 : 0;
+ return (cb(buf, ret, app_key) < 0) ? -1 : 0;
+}
- ret = snprintf(buf, sizeof(buf),
- "%04d-%02d-%02d %02d:%02d:%02d (GMT)",
- tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday,
- tm.tm_hour, tm.tm_min, tm.tm_sec);
- assert(ret > 0 && ret < (int)sizeof(buf));
- return (cb(buf, ret, app_key) < 0) ? -1 : 0;
- } else {
- return (cb("<absent>", 8, app_key) < 0) ? -1 : 0;
- }
+/* Returns string length (ASN_TM_STR_MAXLEN - 1); no errors possible. */
+int
+asn_tm2str(struct tm *tm, char *str)
+{
+ int ret;
+
+ ret = snprintf(str, ASN_TM_STR_MAXLEN,
+ "%04d-%02d-%02dT%02d:%02d:%02dZ",
+ tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday,
+ tm->tm_hour, tm->tm_min, tm->tm_sec);
+ assert(ret == ASN_TM_STR_MAXLEN - 1);
+
+ return ret;
}
int
asn_struct_compare_f GeneralizedTime_compare;
asn_constr_check_f GeneralizedTime_constraint;
der_type_encoder_f GeneralizedTime_encode_der;
+json_type_encoder_f GeneralizedTime_encode_json;
xer_type_encoder_f GeneralizedTime_encode_xer;
#define GeneralizedTime_free OCTET_STRING_free
* Some handy helpers. *
***********************/
+#define ASN_TM_STR_MAXLEN 21
+
+int asn_tm2str(struct tm *tm, char *str);
+
/*
* Convert a GeneralizedTime structure into time_t
* and optionally into struct tm.
OCTET_STRING_compare,
OCTET_STRING_decode_ber, /* Implemented in terms of OCTET STRING */
OCTET_STRING_encode_der,
+ OCTET_STRING_encode_json_utf8,
OCTET_STRING_encode_xer_utf8,
0 /* Use generic outmost tag fetcher */
};
INTEGER_compare,
ber_decode_primitive,
INTEGER_encode_der,
+ INTEGER_encode_json,
INTEGER_encode_xer,
0 /* Use generic outmost tag fetcher */
};
INTEGER__compar_value2enum);
}
+json_t *
+INTEGER_encode_json(const struct asn_TYPE_descriptor_s *td, const void *sptr)
+{
+ const INTEGER_t *st;
+ const asn_INTEGER_specifics_t *specs;
+ uintmax_t uint;
+ intmax_t sint;
+
+ st = (const INTEGER_t *)sptr;
+ specs = (const asn_INTEGER_specifics_t *)td->specifics;
+
+ if (specs && specs->field_unsigned) {
+ if (asn_INTEGER2umax(st, &uint) < 0)
+ return NULL;
+ return json_integer(uint);
+
+ } else {
+ if (asn_INTEGER2imax(st, &sint) < 0)
+ return NULL;
+ return json_integer(sint);
+ }
+}
+
asn_enc_rval_t
INTEGER_encode_xer(const asn_TYPE_descriptor_t *td, const void *sptr,
int ilevel, enum xer_encoder_flags_e flags,
asn_struct_print_f INTEGER_print;
asn_struct_compare_f INTEGER_compare;
der_type_encoder_f INTEGER_encode_der;
+json_type_encoder_f INTEGER_encode_json;
xer_type_encoder_f INTEGER_encode_xer;
/***********************************
ASN_MODULE_SRCS+=asn1/asn1c/constr_TYPE.c
ASN_MODULE_HDRS+=asn1/asn1c/constraints.h
ASN_MODULE_SRCS+=asn1/asn1c/constraints.c
+ASN_MODULE_HDRS+=asn1/asn1c/json_encoder.c
+ASN_MODULE_HDRS+=asn1/asn1c/json_encoder.h
ASN_MODULE_HDRS+=asn1/asn1c/xer_encoder.h
ASN_MODULE_SRCS+=asn1/asn1c/xer_encoder.c
\ No newline at end of file
NULL_compare,
NULL_decode_ber,
NULL_encode_der, /* Special handling of DER encoding */
+ NULL_encode_json,
NULL_encode_xer,
0 /* Use generic outmost tag fetcher */
};
ASN__ENCODED_OK(erval);
}
+json_t *
+NULL_encode_json(const struct asn_TYPE_descriptor_s *td, const void *sptr)
+{
+ return json_null();
+}
+
asn_enc_rval_t
NULL_encode_xer(const asn_TYPE_descriptor_t *td, const void *sptr, int ilevel,
enum xer_encoder_flags_e flags, asn_app_consume_bytes_f *cb,
asn_struct_compare_f NULL_compare;
ber_type_decoder_f NULL_decode_ber;
der_type_encoder_f NULL_encode_der;
+json_type_encoder_f NULL_encode_json;
xer_type_encoder_f NULL_encode_xer;
#define NULL_constraint asn_generic_no_constraint
OCTET_STRING_compare, /* Implemented in terms of a string comparison */
ber_decode_primitive,
der_encode_primitive,
+ OBJECT_IDENTIFIER_encode_json,
OBJECT_IDENTIFIER_encode_xer,
0 /* Use generic outmost tag fetcher */
};
return (cb(" }", 2, app_key) < 0) ? -1 : 0;
}
+struct string_buffer {
+ char *buf;
+ size_t len;
+};
+
+static int
+bytes2str(const void *addend, size_t addlen, void *arg)
+{
+ struct string_buffer *buffer = arg;
+
+ if (buffer->len + addlen + 1 > OID_STR_MAXLEN)
+ return -ENOSPC;
+
+ strncpy(buffer->buf + buffer->len, addend, addlen);
+ buffer->len += addlen;
+ return 0;
+}
+
+static char *
+OBJECT_IDENTIFIER_to_literal(OBJECT_IDENTIFIER_t const *oid, char *buf)
+{
+ struct string_buffer buffer;
+
+ buffer.buf = buf;
+ buffer.len = 0;
+
+ if (OBJECT_IDENTIFIER__dump_body(oid, bytes2str, &buffer) < 0)
+ return NULL;
+
+ buffer.buf[buffer.len] = '\0';
+ return buf;
+}
+
+char const *
+OBJECT_IDENTIFIER_to_string(OBJECT_IDENTIFIER_t const *oid, char *buf)
+{
+// printf("\n===========================\n");
+// for (ret = 0; ret < st->size; ret++)
+// printf("%u ", st->buf[ret]);
+// printf("\n===========================\n");
+
+ if (!oid || !oid->buf)
+ return NULL;
+ if (OBJECT_IDENTIFIER_is_rsaEncryption(oid))
+ return "rsaEncryption";
+ if (OBJECT_IDENTIFIER_is_sha256WithRSAEncryption(oid))
+ return "sha256WithRSAEncryption";
+ if (OBJECT_IDENTIFIER_is_SignedData(oid))
+ return "signedData";
+ if (OBJECT_IDENTIFIER_is_ContentType(oid))
+ return "Content-Type";
+ if (OBJECT_IDENTIFIER_is_MessageDigest(oid))
+ return "Message-Digest";
+ if (OBJECT_IDENTIFIER_is_SigningTime(oid))
+ return "Signing-Time";
+ if (OBJECT_IDENTIFIER_is_roa(oid))
+ return "ROA";
+ if (OBJECT_IDENTIFIER_is_mft(oid))
+ return "Manifest";
+ if (OBJECT_IDENTIFIER_is_gbr(oid))
+ return "Ghostbusters";
+ if (OBJECT_IDENTIFIER_is_sha256(oid))
+ return "sha256";
+
+ return OBJECT_IDENTIFIER_to_literal(oid, buf);
+}
+
+json_t *
+OBJECT_IDENTIFIER_encode_json(const struct asn_TYPE_descriptor_s *td,
+ const void *sptr)
+{
+ const OBJECT_IDENTIFIER_t *oid = (const OBJECT_IDENTIFIER_t *)sptr;
+ char buf[OID_STR_MAXLEN];
+ char const *string;
+
+ string = OBJECT_IDENTIFIER_to_string(oid, buf);
+ return (string != NULL) ? json_string(string) : NULL;
+}
+
ssize_t
OBJECT_IDENTIFIER_get_arcs(const OBJECT_IDENTIFIER_t *st, asn_oid_arc_t *arcs,
size_t arc_slots) {
errno = EINVAL; /* Broken OID */
return -1;
}
+
+static bool
+is_raw(OBJECT_IDENTIFIER_t const *oid, unsigned char const *raw, size_t size)
+{
+ return (oid->size == size) && memcmp(oid->buf, raw, size) == 0;
+}
+
+bool
+OBJECT_IDENTIFIER_is_rsaEncryption(OBJECT_IDENTIFIER_t const *oid)
+{
+ static const unsigned char RAW[] = {
+ 42, 134, 72, 134, 247, 13, 1, 1, 1
+ };
+ return is_raw(oid, RAW, sizeof(RAW));
+}
+
+bool
+OBJECT_IDENTIFIER_is_sha256WithRSAEncryption(OBJECT_IDENTIFIER_t const *oid)
+{
+ static const unsigned char RAW[] = {
+ 42, 134, 72, 134, 247, 13, 1, 1, 11
+ };
+ return is_raw(oid, RAW, sizeof(RAW));
+}
+
+bool
+OBJECT_IDENTIFIER_is_SignedData(OBJECT_IDENTIFIER_t const *oid)
+{
+ static const unsigned char RAW[] = {
+ 42, 134, 72, 134, 247, 13, 1, 7, 2
+ };
+ return is_raw(oid, RAW, sizeof(RAW));
+}
+
+bool
+OBJECT_IDENTIFIER_is_ContentType(OBJECT_IDENTIFIER_t const *oid)
+{
+ static const unsigned char RAW[] = {
+ 42, 134, 72, 134, 247, 13, 1, 9, 3
+ };
+ return is_raw(oid, RAW, sizeof(RAW));
+}
+
+bool
+OBJECT_IDENTIFIER_is_MessageDigest(OBJECT_IDENTIFIER_t const *oid)
+{
+ static const unsigned char RAW[] = {
+ 42, 134, 72, 134, 247, 13, 1, 9, 4
+ };
+ return is_raw(oid, RAW, sizeof(RAW));
+}
+
+bool
+OBJECT_IDENTIFIER_is_SigningTime(OBJECT_IDENTIFIER_t const *oid)
+{
+ static const unsigned char RAW[] = {
+ 42, 134, 72, 134, 247, 13, 1, 9, 5
+ };
+ return is_raw(oid, RAW, sizeof(RAW));
+}
+
+bool
+OBJECT_IDENTIFIER_is_roa(OBJECT_IDENTIFIER_t const *oid)
+{
+ static const unsigned char RAW[] = {
+ 42, 134, 72, 134, 247, 13, 1, 9, 16, 1, 24
+ };
+ return is_raw(oid, RAW, sizeof(RAW));
+}
+
+bool
+OBJECT_IDENTIFIER_is_mft(OBJECT_IDENTIFIER_t const *oid)
+{
+ static const unsigned char RAW[] = {
+ 42, 134, 72, 134, 247, 13, 1, 9, 16, 1, 26
+ };
+ return is_raw(oid, RAW, sizeof(RAW));
+}
+
+bool
+OBJECT_IDENTIFIER_is_gbr(OBJECT_IDENTIFIER_t const *oid)
+{
+ static const unsigned char RAW[] = {
+ 42, 134, 72, 134, 247, 13, 1, 9, 16, 1, 35
+ };
+ return is_raw(oid, RAW, sizeof(RAW));
+}
+
+bool
+OBJECT_IDENTIFIER_is_sha256(OBJECT_IDENTIFIER_t const *oid)
+{
+ static const unsigned char RAW[] = { 96, 134, 72, 1, 101, 3, 4, 2, 1 };
+ return is_raw(oid, RAW, sizeof(RAW));
+}
#ifndef _OBJECT_IDENTIFIER_H_
#define _OBJECT_IDENTIFIER_H_
+#include <stdbool.h>
#include "asn1/asn1c/asn_application.h"
#include "asn1/asn1c/asn_codecs_prim.h"
#include "asn1/asn1c/OCTET_STRING.h"
asn_struct_print_f OBJECT_IDENTIFIER_print;
asn_constr_check_f OBJECT_IDENTIFIER_constraint;
der_type_encoder_f OBJECT_IDENTIFIER_encode_der;
+json_type_encoder_f OBJECT_IDENTIFIER_encode_json;
xer_type_encoder_f OBJECT_IDENTIFIER_encode_xer;
#define OBJECT_IDENTIFIER_free ASN__PRIMITIVE_TYPE_free
* Some handy conversion routines *
**********************************/
+#define OID_STR_MAXLEN 64 /* Null char included */
+char const *OBJECT_IDENTIFIER_to_string(OBJECT_IDENTIFIER_t const *, char *);
+
/*
* This function fills an (arcs) array with OBJECT IDENTIFIER arcs
* up to specified (arc_slots) elements.
ssize_t OBJECT_IDENTIFIER_set_single_arc(uint8_t *arcbuf, size_t arcbuf_len,
asn_oid_arc_t arc_value);
+bool OBJECT_IDENTIFIER_is_rsaEncryption(OBJECT_IDENTIFIER_t const *oid);
+bool OBJECT_IDENTIFIER_is_sha256WithRSAEncryption(OBJECT_IDENTIFIER_t const *oid);
+bool OBJECT_IDENTIFIER_is_SignedData(OBJECT_IDENTIFIER_t const *oid);
+bool OBJECT_IDENTIFIER_is_ContentType(OBJECT_IDENTIFIER_t const *oid);
+bool OBJECT_IDENTIFIER_is_MessageDigest(OBJECT_IDENTIFIER_t const *oid);
+bool OBJECT_IDENTIFIER_is_SigningTime(OBJECT_IDENTIFIER_t const *oid);
+bool OBJECT_IDENTIFIER_is_roa(OBJECT_IDENTIFIER_t const *oid);
+bool OBJECT_IDENTIFIER_is_mft(OBJECT_IDENTIFIER_t const *oid);
+bool OBJECT_IDENTIFIER_is_gbr(OBJECT_IDENTIFIER_t const *oid);
+bool OBJECT_IDENTIFIER_is_sha256(OBJECT_IDENTIFIER_t const *oid);
+
#endif /* _OBJECT_IDENTIFIER_H_ */
#include <assert.h>
#include <errno.h>
+#include "alloc.h"
+
/*
* OCTET STRING basic type description.
*/
OCTET_STRING_compare,
OCTET_STRING_decode_ber,
OCTET_STRING_encode_der,
+ OCTET_STRING_encode_json,
OCTET_STRING_encode_xer,
0 /* Use generic outmost tag fetcher */
};
ASN__ENCODE_FAILED;
}
+json_t *
+OCTET_STRING_encode_json(const struct asn_TYPE_descriptor_s *td,
+ const void *sptr)
+{
+ static const char * const H2C = "0123456789abcdef";
+ const OCTET_STRING_t *os = sptr;
+ uint8_t *buf, *end;
+ char *result, *r;
+
+ result = pmalloc(2 * os->size + 1);
+
+ buf = os->buf;
+ end = buf + os->size;
+ r = result;
+ for (; buf < end; buf++) {
+ *r++ = H2C[(*buf >> 4) & 0x0F];
+ *r++ = H2C[(*buf ) & 0x0F];
+ }
+ *r = '\0';
+
+ return json_string(result);
+}
+
+json_t *
+OCTET_STRING_encode_json_utf8(const struct asn_TYPE_descriptor_s *td,
+ const void *sptr)
+{
+ const OCTET_STRING_t *os = sptr;
+ return json_stringn((char const *) os->buf, os->size);
+}
+
asn_enc_rval_t
OCTET_STRING_encode_xer(const asn_TYPE_descriptor_t *td, const void *sptr,
int ilevel, enum xer_encoder_flags_e flags,
asn_struct_compare_f OCTET_STRING_compare;
ber_type_decoder_f OCTET_STRING_decode_ber;
der_type_encoder_f OCTET_STRING_encode_der;
+json_type_encoder_f OCTET_STRING_encode_json;
+json_type_encoder_f OCTET_STRING_encode_json_utf8;
xer_type_encoder_f OCTET_STRING_encode_xer;
xer_type_encoder_f OCTET_STRING_encode_xer_utf8;
OPEN_TYPE_compare,
OPEN_TYPE_decode_ber,
OPEN_TYPE_encode_der,
+ OPEN_TYPE_encode_json,
OPEN_TYPE_encode_xer,
0, /* Use generic outmost tag fetcher */
};
#define OPEN_TYPE_constraint CHOICE_constraint
#define OPEN_TYPE_decode_ber NULL
#define OPEN_TYPE_encode_der CHOICE_encode_der
+#define OPEN_TYPE_encode_json CHOICE_encode_json
#define OPEN_TYPE_encode_xer CHOICE_encode_xer
extern asn_TYPE_operation_t asn_OP_OPEN_TYPE;
#include "asn1/asn1c/ROAIPAddressFamily.h"
+#include "types/address.h"
+
+static json_t *
+prefix2json(char *prefix, uint8_t length)
+{
+ json_t *root;
+
+ root = json_object();
+ if (root == NULL)
+ return NULL;
+ if (json_object_set_new(root, "prefix", json_string(prefix)) < 0)
+ goto fail;
+ if (json_object_set_new(root, "length", json_integer(length)) < 0)
+ goto fail;
+
+ return root;
+
+fail: json_decref(root);
+ return NULL;
+}
+
+static json_t *
+prefix4_to_json(struct ROAIPAddress *addr)
+{
+ struct ipv4_prefix prefix4;
+ char buff[INET_ADDRSTRLEN];
+
+ if (prefix4_decode(&addr->address, &prefix4) != 0)
+ return NULL;
+ if (inet_ntop(AF_INET, &prefix4.addr, buff, INET_ADDRSTRLEN) == NULL)
+ return NULL;
+
+ return prefix2json(buff, prefix4.len);
+}
+
+static json_t *
+prefix6_to_json(struct ROAIPAddress *addr)
+{
+ struct ipv6_prefix prefix6;
+ char buff[INET6_ADDRSTRLEN];
+
+ if (prefix6_decode(&addr->address, &prefix6) != 0)
+ return NULL;
+ if (inet_ntop(AF_INET6, &prefix6.addr, buff, INET6_ADDRSTRLEN) == NULL)
+ return NULL;
+
+ return prefix2json(buff, prefix6.len);
+}
+
+static json_t *
+AddrBlock2json(struct ROAIPAddressFamily const *riaf, char const *ipname,
+ json_t *(*pref2json)(struct ROAIPAddress *))
+{
+ json_t *root;
+ json_t *family, *addresses;
+ int i;
+
+ root = json_object();
+ if (root == NULL)
+ return NULL;
+
+ family = json_string(ipname);
+ if (family == NULL)
+ goto fail;
+ if (json_object_set_new(root, "addressFamily", family) < 0)
+ goto fail;
+
+ addresses = json_array();
+ if (addresses == NULL)
+ goto fail;
+ if (json_object_set_new(root, "addresses", addresses) < 0)
+ goto fail;
+
+ for (i = 0; i < riaf->addresses.list.count; i++) {
+ struct ROAIPAddress *src = riaf->addresses.list.array[i];
+ json_t *prefix, *maxlen;
+
+ prefix = pref2json(src);
+ if (prefix == NULL)
+ goto fail;
+ if (json_array_append(addresses, prefix))
+ goto fail;
+
+ maxlen = asn_DEF_INTEGER.op->json_encoder(&asn_DEF_INTEGER, src->maxLength);
+ if (maxlen == NULL)
+ goto fail;
+ if (json_object_set_new(prefix, "maxLength", maxlen))
+ goto fail;
+ }
+
+ return root;
+
+fail: json_decref(root);
+ return NULL;
+}
+
+json_t *
+ROAIPAddressFamily_encode_json(const asn_TYPE_descriptor_t *td, const void *sptr)
+{
+ struct ROAIPAddressFamily const *riaf = sptr;
+ OCTET_STRING_t const *af;
+
+ if (!riaf)
+ return json_null();
+
+ af = &riaf->addressFamily;
+ if (af->size == 2 && af->buf[0] == 0 && af->buf[1] == 1)
+ return AddrBlock2json(riaf, "IPv4", prefix4_to_json);
+ if (af->size == 2 && af->buf[0] == 0 && af->buf[1] == 2)
+ return AddrBlock2json(riaf, "IPv6", prefix6_to_json);
+
+ return SEQUENCE_encode_json(td, sptr);
+}
+
+asn_TYPE_operation_t asn_OP_ROAIPAddressFamily = {
+ SEQUENCE_free,
+ SEQUENCE_print,
+ SEQUENCE_compare,
+ SEQUENCE_decode_ber,
+ SEQUENCE_encode_der,
+ ROAIPAddressFamily_encode_json,
+ SEQUENCE_encode_xer,
+ 0 /* Use generic outmost tag fetcher */
+};
+
static int
memb_addressFamily_constraint_1(const asn_TYPE_descriptor_t *td, const void *sptr,
asn_app_constraint_failed_f *ctfailcb, void *app_key) {
asn_TYPE_descriptor_t asn_DEF_ROAIPAddressFamily = {
"ROAIPAddressFamily",
"ROAIPAddressFamily",
- &asn_OP_SEQUENCE,
+ &asn_OP_ROAIPAddressFamily,
asn_DEF_ROAIPAddressFamily_tags_1,
sizeof(asn_DEF_ROAIPAddressFamily_tags_1)
/sizeof(asn_DEF_ROAIPAddressFamily_tags_1[0]), /* 1 */
#include "asn1/asn1c/SignedAttributes.h"
+static json_t *
+SignedAttributes_encode_json(const struct asn_TYPE_descriptor_s *td,
+ const void *sptr)
+{
+ json_t *result;
+ const asn_anonymous_set_ *list;
+ asn_TYPE_descriptor_t *type;
+ int i;
+
+ if (!sptr)
+ return json_null();
+
+ result = json_object();
+ if (result == NULL)
+ return NULL;
+
+ list = _A_CSET_FROM_VOID(sptr);
+ type = &asn_DEF_CMSAttribute;
+
+ for (i = 0; i < list->count; i++) {
+ CMSAttribute_t *attr;
+ json_t *node;
+ char buf[OID_STR_MAXLEN];
+ char const *key;
+
+ attr = list->array[i];
+ node = type->op->json_encoder(type, attr);
+ if (node == NULL)
+ goto fail;
+
+ key = OBJECT_IDENTIFIER_to_string(&attr->attrType, buf);
+ if (json_object_set_new(result, key, node) < 0)
+ goto fail;
+ }
+
+ return result;
+
+fail: json_decref(result);
+ return NULL;
+}
+
+asn_TYPE_operation_t asn_OP_SignedAttributes = {
+ SET_OF_free,
+ SET_OF_print,
+ SET_OF_compare,
+ SET_OF_decode_ber,
+ SET_OF_encode_der,
+ SignedAttributes_encode_json,
+ SET_OF_encode_xer,
+ 0 /* Use generic outmost tag fetcher */
+};
+
asn_TYPE_member_t asn_MBR_SignedAttributes_1[] = {
{ ATF_POINTER, 0, 0,
(ASN_TAG_CLASS_UNIVERSAL | (16 << 2)),
asn_TYPE_descriptor_t asn_DEF_SignedAttributes = {
"SignedAttributes",
"SignedAttributes",
- &asn_OP_SET_OF,
+ &asn_OP_SignedAttributes,
asn_DEF_SignedAttributes_tags_1,
sizeof(asn_DEF_SignedAttributes_tags_1)
/sizeof(asn_DEF_SignedAttributes_tags_1[0]), /* 1 */
UTCTime_compare,
OCTET_STRING_decode_ber, /* Implemented in terms of OCTET STRING */
OCTET_STRING_encode_der, /* Implemented in terms of OCTET STRING */
+ UTCTime_encode_json,
UTCTime_encode_xer,
0 /* Use generic outmost tag fetcher */
};
#endif /* ASN___INTERNAL_TEST_MODE */
+static int
+UTCTime2str(const UTCTime_t *st, char *str)
+{
+ struct tm tm;
+
+ if (asn_UT2time(st, &tm) != 0)
+ return -1;
+
+ return asn_tm2str(&tm, str);
+}
+
int
UTCTime_print(const asn_TYPE_descriptor_t *td, const void *sptr, int ilevel,
- asn_app_consume_bytes_f *cb, void *app_key) {
- const UTCTime_t *st = (const UTCTime_t *)sptr;
+ asn_app_consume_bytes_f *cb, void *app_key)
+{
+ const UTCTime_t *st = (const UTCTime_t *)sptr;
+ char buf[ASN_TM_STR_MAXLEN];
+ int ret;
- (void)td; /* Unused argument */
- (void)ilevel; /* Unused argument */
+ if (st == NULL || st->buf == NULL)
+ return (cb("<absent>", 8, app_key) < 0) ? -1 : 0;
- if(st && st->buf) {
- char buf[32];
- struct tm tm;
- int ret;
+ ret = UTCTime2str(st, buf);
+ if (ret < 0)
+ return (cb("<bad-value>", 11, app_key) < 0) ? -1 : 0;
- if(asn_UT2time(st, &tm) != 0)
- return (cb("<bad-value>", 11, app_key) < 0) ? -1 : 0;
+ return (cb(buf, ret, app_key) < 0) ? -1 : 0;
+}
- ret = snprintf(buf, sizeof(buf),
- "%04d-%02d-%02d %02d:%02d:%02d (GMT)",
- tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday,
- tm.tm_hour, tm.tm_min, tm.tm_sec);
- assert(ret > 0 && ret < (int)sizeof(buf));
- return (cb(buf, ret, app_key) < 0) ? -1 : 0;
- } else {
- return (cb("<absent>", 8, app_key) < 0) ? -1 : 0;
- }
+json_t *
+UTCTime_encode_json(const asn_TYPE_descriptor_t *td, const void *sptr)
+{
+ const UTCTime_t *st = (const UTCTime_t *)sptr;
+ char buf[ASN_TM_STR_MAXLEN];
+
+ if (st == NULL || st->buf == NULL)
+ return json_null();
+
+ if (UTCTime2str(st, buf) < 0)
+ return NULL;
+
+ return json_string(buf);
}
time_t
asn_struct_print_f UTCTime_print;
asn_struct_compare_f UTCTime_compare;
asn_constr_check_f UTCTime_constraint;
+json_type_encoder_f UTCTime_encode_json;
xer_type_encoder_f UTCTime_encode_xer;
#define UTCTime_free OCTET_STRING_free
#define REALLOC(oldptr, size) realloc(oldptr, size)
#define FREEMEM(ptr) free(ptr)
-#define asn_debug_indent 0
-#define ASN_DEBUG_INDENT_ADD(i) do{}while(0)
-
#ifdef EMIT_ASN_DEBUG
#warning "Use ASN_EMIT_DEBUG instead of EMIT_ASN_DEBUG"
#define ASN_EMIT_DEBUG EMIT_ASN_DEBUG
*/
#ifndef ASN_DEBUG /* If debugging code is not defined elsewhere... */
#if ASN_EMIT_DEBUG == 1 /* And it was asked to emit this code... */
-#if __STDC_VERSION__ >= 199901L
-#ifdef ASN_THREAD_SAFE
-/* Thread safety requires sacrifice in output indentation:
- * Retain empty definition of ASN_DEBUG_INDENT_ADD. */
-#else /* !ASN_THREAD_SAFE */
-#undef ASN_DEBUG_INDENT_ADD
-#undef asn_debug_indent
-int asn_debug_indent;
-#define ASN_DEBUG_INDENT_ADD(i) do { asn_debug_indent += i; } while(0)
-#endif /* ASN_THREAD_SAFE */
-#define ASN_DEBUG(fmt, args...) do { \
- int adi = asn_debug_indent; \
- while(adi--) fprintf(stderr, " "); \
- fprintf(stderr, fmt, ##args); \
- fprintf(stderr, " (%s:%d)\n", \
- __FILE__, __LINE__); \
- } while(0)
-#else /* !C99 */
void CC_PRINTFLIKE(1, 2) ASN_DEBUG_f(const char *fmt, ...);
#define ASN_DEBUG ASN_DEBUG_f
-#endif /* C99 */
#else /* ASN_EMIT_DEBUG != 1 */
-#if __STDC_VERSION__ >= 199901L
-#define ASN_DEBUG(...) do{}while(0)
-#else /* not C99 */
static void CC_PRINTFLIKE(1, 2) ASN_DEBUG(const char *fmt, ...) { (void)fmt; }
-#endif /* C99 or better */
#endif /* ASN_EMIT_DEBUG */
#endif /* ASN_DEBUG */
* Seek over the present member of the structure.
*/
elm = &td->elements[present-1];
- if(elm->flags & ATF_POINTER) {
- memb_ptr =
- *(const void *const *)((const char *)sptr + elm->memb_offset);
- if(memb_ptr == 0) {
- if(elm->optional) {
- erval.encoded = 0;
- ASN__ENCODED_OK(erval);
- }
- /* Mandatory element absent */
- ASN__ENCODE_FAILED;
+
+ memb_ptr = get_member(sptr, elm);
+ if (memb_ptr == NULL) {
+ if(elm->optional) {
+ erval.encoded = 0;
+ ASN__ENCODED_OK(erval);
}
- } else {
- memb_ptr = (const void *)((const char *)sptr + elm->memb_offset);
- }
+ /* Mandatory element absent */
+ ASN__ENCODE_FAILED;
+ }
/*
* If the CHOICE itself is tagged EXPLICIT:
if(present > 0 && present <= td->elements_count) {
const asn_TYPE_member_t *elm = &td->elements[present-1];
- const void *memb_ptr;
- if(elm->flags & ATF_POINTER) {
- memb_ptr = *(const void * const *)
- ((const char *)ptr + elm->memb_offset);
- } else {
- memb_ptr = (const void *)
- ((const char *)ptr + elm->memb_offset);
- }
-
- return asn_TYPE_outmost_tag(elm->type, memb_ptr,
+ return asn_TYPE_outmost_tag(elm->type, get_member(ptr, elm),
elm->tag_mode, elm->tag);
} else {
return (ber_tlv_tag_t)-1;
asn_TYPE_member_t *elm = &td->elements[present-1];
const void *memb_ptr;
- if(elm->flags & ATF_POINTER) {
- memb_ptr = *(const void * const *)((const char *)sptr + elm->memb_offset);
- if(!memb_ptr) {
- if(elm->optional)
- return 0;
- ASN__CTFAIL(app_key, td, sptr,
- "%s: mandatory CHOICE element %s absent (%s:%d)",
- td->name, elm->name, __FILE__, __LINE__);
- return -1;
- }
- } else {
- memb_ptr = (const void *)((const char *)sptr + elm->memb_offset);
+ memb_ptr = get_member(sptr, elm);
+ if (memb_ptr == NULL) {
+ if(elm->optional)
+ return 0;
+ ASN__CTFAIL(app_key, td, sptr,
+ "%s: mandatory CHOICE element %s absent (%s:%d)",
+ td->name, elm->name, __FILE__, __LINE__);
+ return -1;
}
if(elm->encoding_constraints.general_constraints) {
}
}
+json_t *
+CHOICE_encode_json(const asn_TYPE_descriptor_t *td, const void *sptr)
+{
+ const asn_CHOICE_specifics_t *specs = (const asn_CHOICE_specifics_t *)td->specifics;
+ unsigned present;
+ asn_TYPE_member_t *elm;
+ const void *memb_ptr;
+
+ if (!sptr)
+ return json_null();
+
+ /* Figure out which CHOICE element is encoded. */
+ present = _fetch_present_idx(sptr, specs->pres_offset, specs->pres_size);
+
+ if (present <= 0 || td->elements_count < present)
+ return json_null();
+
+ /* Print that element. */
+ elm = &td->elements[present-1];
+
+ memb_ptr = get_member(sptr, elm);
+ if (memb_ptr == NULL)
+ return json_null();
+
+ return elm->type->op->json_encoder(elm->type, memb_ptr);
+}
+
asn_enc_rval_t
CHOICE_encode_xer(const asn_TYPE_descriptor_t *td, const void *sptr, int ilevel,
enum xer_encoder_flags_e flags, asn_app_consume_bytes_f *cb,
const char *mname = elm->name;
unsigned int mlen = strlen(mname);
- if(elm->flags & ATF_POINTER) {
- memb_ptr =
- *(const void *const *)((const char *)sptr + elm->memb_offset);
- if(!memb_ptr) ASN__ENCODE_FAILED;
- } else {
- memb_ptr = (const void *)((const char *)sptr + elm->memb_offset);
- }
+ memb_ptr = get_member(sptr, elm);
+ if (!memb_ptr)
+ ASN__ENCODE_FAILED;
- er.encoded = 0;
+ er.encoded = 0;
if(!(flags & XER_F_CANONICAL)) ASN__TEXT_INDENT(1, ilevel);
ASN__CALLBACK3("<", 1, mname, mlen, ">", 1);
asn_TYPE_member_t *elm = &td->elements[present-1];
const void *memb_ptr;
- if(elm->flags & ATF_POINTER) {
- memb_ptr = *(const void * const *)((const char *)sptr + elm->memb_offset);
- if(!memb_ptr) return (cb("<absent>", 8, app_key) < 0) ? -1 : 0;
- } else {
- memb_ptr = (const void *)((const char *)sptr + elm->memb_offset);
- }
+ memb_ptr = get_member(sptr, elm);
+ if (!memb_ptr)
+ return (cb("<absent>", 8, app_key) < 0) ? -1 : 0;
/* Print member's name and stuff */
if(0) {
asn_TYPE_member_t *const elm = &td->elements[present - 1];
const void *memb_ptr;
- if(elm->flags & ATF_POINTER) {
- memb_ptr =
- *(const void *const *)((const char *)sptr + elm->memb_offset);
- } else {
- memb_ptr = (const void *)((const char *)sptr + elm->memb_offset);
- }
+ memb_ptr = get_member(sptr, elm);
*elm_ptr = elm;
return memb_ptr;
} else {
CHOICE_compare,
CHOICE_decode_ber,
CHOICE_encode_der,
+ CHOICE_encode_json,
CHOICE_encode_xer,
CHOICE_outmost_tag
};
asn_constr_check_f CHOICE_constraint;
ber_type_decoder_f CHOICE_decode_ber;
der_type_encoder_f CHOICE_encode_der;
+json_type_encoder_f CHOICE_encode_json;
xer_type_encoder_f CHOICE_encode_xer;
asn_outmost_tag_f CHOICE_outmost_tag;
extern asn_TYPE_operation_t asn_OP_CHOICE;
ASN__ENCODED_OK(erval);
}
+json_t *
+SEQUENCE_encode_json(const struct asn_TYPE_descriptor_s *td, const void *sptr)
+{
+ json_t *parent, *child;
+ size_t c;
+
+ if (!sptr)
+ return json_null();
+
+ parent = json_object();
+ if (parent == NULL)
+ return NULL;
+
+ for (c = 0; c < td->elements_count; c++) {
+ asn_TYPE_member_t *elm = &td->elements[c];
+ const void *memb_ptr;
+
+ memb_ptr = get_member(sptr, elm);
+ if (!memb_ptr) {
+ if (elm->optional)
+ continue;
+ /* Fall through */
+ }
+
+ child = elm->type->op->json_encoder(elm->type, memb_ptr);
+ if (child == NULL)
+ goto fail;
+ if (json_object_set_new(parent, elm->name, child))
+ goto fail;
+ }
+
+ return parent;
+
+fail: json_decref(parent);
+ return NULL;
+}
+
asn_enc_rval_t
SEQUENCE_encode_xer(const asn_TYPE_descriptor_t *td, const void *sptr,
int ilevel, enum xer_encoder_flags_e flags,
const char *mname = elm->name;
unsigned int mlen = strlen(mname);
- if(elm->flags & ATF_POINTER) {
- memb_ptr =
- *(const void *const *)((const char *)sptr + elm->memb_offset);
+ memb_ptr = get_member(sptr, elm);
if(!memb_ptr) {
assert(tmp_def_val == 0);
if(elm->default_value_set) {
ASN__ENCODE_FAILED;
}
}
- } else {
- memb_ptr = (const void *)((const char *)sptr + elm->memb_offset);
- }
if(!xcan) ASN__TEXT_INDENT(1, ilevel);
ASN__CALLBACK3("<", 1, mname, mlen, ">", 1);
asn_TYPE_member_t *elm = &td->elements[edx];
const void *memb_ptr;
- if(elm->flags & ATF_POINTER) {
- memb_ptr = *(const void * const *)((const char *)sptr + elm->memb_offset);
- if(!memb_ptr) {
- if(elm->optional) continue;
- /* Print <absent> line */
- /* Fall through */
- }
- } else {
- memb_ptr = (const void *)((const char *)sptr + elm->memb_offset);
+ memb_ptr = get_member(sptr, elm);
+ if (!memb_ptr) {
+ if(elm->optional)
+ continue;
+ /* Print <absent> line */
+ /* Fall through */
}
/* Indentation */
asn_TYPE_member_t *elm = &td->elements[edx];
const void *memb_ptr;
- if(elm->flags & ATF_POINTER) {
- memb_ptr = *(const void * const *)((const char *)sptr + elm->memb_offset);
- if(!memb_ptr) {
- if(elm->optional)
- continue;
- ASN__CTFAIL(app_key, td, sptr,
- "%s: mandatory element %s absent (%s:%d)",
- td->name, elm->name, __FILE__, __LINE__);
- return -1;
- }
- } else {
- memb_ptr = (const void *)((const char *)sptr + elm->memb_offset);
+ memb_ptr = get_member(sptr, elm);
+ if (!memb_ptr) {
+ if(elm->optional)
+ continue;
+ ASN__CTFAIL(app_key, td, sptr,
+ "%s: mandatory element %s absent (%s:%d)",
+ td->name, elm->name, __FILE__, __LINE__);
+ return -1;
}
if(elm->encoding_constraints.general_constraints) {
SEQUENCE_compare,
SEQUENCE_decode_ber,
SEQUENCE_encode_der,
+ SEQUENCE_encode_json,
SEQUENCE_encode_xer,
0 /* Use generic outmost tag fetcher */
};
asn_constr_check_f SEQUENCE_constraint;
ber_type_decoder_f SEQUENCE_decode_ber;
der_type_encoder_f SEQUENCE_encode_der;
+json_type_encoder_f SEQUENCE_encode_json;
xer_type_encoder_f SEQUENCE_encode_xer;
extern asn_TYPE_operation_t asn_OP_SEQUENCE;
SEQUENCE_OF_compare,
SEQUENCE_OF_decode_ber,
SEQUENCE_OF_encode_der,
+ SEQUENCE_OF_encode_json,
SEQUENCE_OF_encode_xer,
0 /* Use generic outmost tag fetcher */
};
#define SEQUENCE_OF_print SET_OF_print
#define SEQUENCE_OF_constraint SET_OF_constraint
#define SEQUENCE_OF_decode_ber SET_OF_decode_ber
+#define SEQUENCE_OF_encode_json SET_OF_encode_json
#endif /* _CONSTR_SET_OF_H_ */
}
}
+json_t *
+SET_OF_encode_json(const struct asn_TYPE_descriptor_s *td, const void *sptr)
+{
+ json_t *result;
+ const asn_anonymous_set_ *list;
+ asn_TYPE_descriptor_t *type;
+ int i;
+
+ if (!sptr)
+ return json_null();
+
+ result = json_array();
+ if (result == NULL)
+ return NULL;
+
+ list = _A_CSET_FROM_VOID(sptr);
+ type = td->elements->type;
+
+ for (i = 0; i < list->count; i++) {
+ json_t *node = type->op->json_encoder(type, list->array[i]);
+ if (node == NULL)
+ goto fail;
+ if (json_array_append_new(result, node) < 0)
+ goto fail;
+ }
+
+ return result;
+
+fail: json_decref(result);
+ return NULL;
+}
+
typedef struct xer_tmp_enc_s {
void *buffer;
size_t offset;
SET_OF_compare,
SET_OF_decode_ber,
SET_OF_encode_der,
+ SET_OF_encode_json,
SET_OF_encode_xer,
0 /* Use generic outmost tag fetcher */
};
asn_constr_check_f SET_OF_constraint;
ber_type_decoder_f SET_OF_decode_ber;
der_type_encoder_f SET_OF_encode_der;
+json_type_encoder_f SET_OF_encode_json;
xer_type_encoder_f SET_OF_encode_xer;
extern asn_TYPE_operation_t asn_OP_SET_OF;
void ASN_DEBUG_f(const char *fmt, ...) {
va_list ap;
va_start(ap, fmt);
+ fprintf(stderr, "\x1B[32m");
vfprintf(stderr, fmt, ap);
- fprintf(stderr, "\n");
+ fprintf(stderr, "\x1B[0m\n");
va_end(ap);
}
+
+void const *
+get_member(const void *sptr, asn_TYPE_member_t const *elm)
+{
+ return (elm->flags & ATF_POINTER)
+ ? (*(const void * const *)((const char *)sptr + elm->memb_offset))
+ : ((const void *)((const char *)sptr + elm->memb_offset));
+}
#include "asn1/asn1c/ber_decoder.h" /* Basic Encoding Rules decoder */
#include "asn1/asn1c/der_encoder.h" /* Distinguished Encoding Rules encoder */
#include "asn1/asn1c/xer_encoder.h" /* Encoder into XER (XML, text) */
+#include "asn1/asn1c/json_encoder.h" /* Encoder into JSON */
#include "asn1/asn1c/constraints.h" /* Subtype constraints support */
/*
asn_struct_compare_f *compare_struct; /* Compare two structures */
ber_type_decoder_f *ber_decoder; /* Generic BER decoder */
der_type_encoder_f *der_encoder; /* Canonical DER encoder */
+ json_type_encoder_f *json_encoder;
xer_type_encoder_f *xer_encoder; /* [Canonical] XER encoder */
asn_outmost_tag_f *outmost_tag; /* <optional, internal> */
} asn_TYPE_operation_t;
const asn_TYPE_descriptor_t *td, /* ASN.1 type descriptor */
const void *struct_ptr); /* Structure to be printed */
+void const *get_member(const void *sptr, asn_TYPE_member_t const *elm);
+
#endif /* _CONSTR_TYPE_H_ */
--- /dev/null
+#include "asn1/asn1c/json_encoder.h"
+
+#include "asn1/asn1c/asn_internal.h"
+
+json_t *
+json_encode(const asn_TYPE_descriptor_t *td, const void *sptr)
+{
+ if (!td || !sptr) {
+ ASN_DEBUG("Failed to encode element %s", td ? td->name : "");
+ return NULL;
+ }
+
+ return td->op->json_encoder(td, sptr);
+}
--- /dev/null
+#ifndef SRC_ASN1_ASN1C_JSON_ENCODER_H_
+#define SRC_ASN1_ASN1C_JSON_ENCODER_H_
+
+#include <jansson.h>
+
+struct asn_TYPE_descriptor_s; /* Forward declaration */
+
+json_t *json_encode(
+ const struct asn_TYPE_descriptor_s *type_descriptor,
+ const void *struct_ptr /* Structure to be encoded */
+);
+
+/*
+ * Type of the generic JSON encoder.
+ */
+typedef json_t *(json_type_encoder_f)(
+ const struct asn_TYPE_descriptor_s *type_descriptor,
+ const void *struct_ptr /* Structure to be encoded */
+);
+
+#endif /* SRC_ASN1_ASN1C_JSON_ENCODER_H_ */
}
int
-content_info_load(struct rpki_uri *uri, struct ContentInfo **result)
+content_info_load(char const *file, struct ContentInfo **result)
{
struct file_contents fc;
int error;
- error = file_load(uri_get_local(uri), &fc);
+ error = file_load(file, &fc);
if (error)
return error;
/* Some wrappers for asn1/asn1c/ContentInfo.h. */
-#include "types/uri.h"
#include "asn1/asn1c/ContentInfo.h"
-int content_info_load(struct rpki_uri *, struct ContentInfo **);
+int content_info_load(char const *, struct ContentInfo **);
void content_info_free(struct ContentInfo *);
#endif /* SRC_CONTENT_INFO_H_ */
unsigned int maximum_certificate_depth;
/** File or directory where the .slurm file(s) is(are) located */
char *slurm;
- /* Run as RTR server or standalone validation */
+ /* */
enum mode mode;
/*
* Disable outgoing requests (currently rsync and http supported), if
unsigned int max; /* Deprecated */
} validation;
} thread_pool;
+
+ char *payload;
};
static void print_usage(FILE *, bool);
static int
validate_config(void)
{
+ if (rpki_config.mode == PRINT_FILE)
+ return (rpki_config.payload == NULL)
+ ? pr_op_err("Missing file name.")
+ : 0;
+
+ if (rpki_config.payload != NULL)
+ return pr_op_err("I don't know what '%s' is.",
+ rpki_config.payload);
+
if (rpki_config.tal == NULL)
return pr_op_err("The TAL(s) location (--tal) is mandatory.");
goto end;
}
- /*
- * This triggers when the user runs something like `fort help` instead
- * of `fort --help`. This program does not have unflagged payload.
- */
- if (optind < argc) {
- error = pr_op_err("I don't know what '%s' is.", argv[optind]);
- goto end;
- }
+ if (optind < argc)
+ rpki_config.payload = pstrdup(argv[optind]);
error = validate_config();
if (error)
return rpki_config.thread_pool.server.max;
}
+char const *
+config_get_payload(void)
+{
+ return rpki_config.payload;
+}
+
void
config_set_rsync_enabled(bool value)
{
FOREACH_OPTION(options, option, 0xFFFF)
if (is_rpki_config_field(option) && option->type->free != NULL)
option->type->free(get_rpki_config_field(option));
+ free(rpki_config.payload);
}
enum output_format config_get_output_format(void);
unsigned int config_get_asn1_decode_max_stack(void);
unsigned int config_get_thread_pool_server_max(void);
+char const *config_get_payload(void);
/* Logging getters */
bool config_get_op_log_enabled(void);
#define VALUE_SERVER "server"
#define VALUE_STANDALONE "standalone"
+#define VALUE_PRINT_FILE "print"
#define DEREFERENCE(void_value) (*((enum mode *) void_value))
case STANDALONE:
str = VALUE_STANDALONE;
break;
+ case PRINT_FILE:
+ str = VALUE_PRINT_FILE;
+ break;
}
pr_op_info("%s: %s", field->name, str);
DEREFERENCE(result) = SERVER;
else if (strcmp(str, VALUE_STANDALONE) == 0)
DEREFERENCE(result) = STANDALONE;
+ else if (strcmp(str, VALUE_PRINT_FILE) == 0)
+ DEREFERENCE(result) = PRINT_FILE;
else
return pr_op_err("Unknown mode: '%s'", str);
.print = print_mode,
.parse.argv = parse_argv_mode,
.parse.json = parse_json_mode,
- .arg_doc = VALUE_SERVER "|" VALUE_STANDALONE,
+ .arg_doc = VALUE_SERVER "|" VALUE_STANDALONE "|" VALUE_PRINT_FILE,
};
* FORT Run mode
*/
enum mode {
- /**
- * Run as an RTR server
- */
+ /* Run as RTR server */
SERVER,
- /*
- * Run standalone validation (run validation once and exit)
- */
+ /* Run standalone validation (run validation once and exit) */
STANDALONE,
+ /* Print file in standard output */
+ PRINT_FILE,
};
extern const struct global_type gt_mode;
#include "thread_var.h"
#include "http/http.h"
#include "incidence/incidence.h"
+#include "print_file.h"
#include "rtr/rtr.h"
#include "rtr/db/vrps.h"
#include "xml/relax_ng.h"
case SERVER:
error = fort_server();
break;
+ case PRINT_FILE:
+ error = print_file();
+ break;
}
/* End */
{
int error;
- error = content_info_load(uri, &sobj->cinfo);
+ error = content_info_load(uri_get_local(uri), &sobj->cinfo);
if (error)
return error;
--- /dev/null
+#include "print_file.h"
+
+#include <errno.h>
+#include "config.h"
+#include "log.h"
+#include "asn1/content_info.h"
+
+int
+print_file(void)
+{
+ char const *filename;
+ struct ContentInfo *ci;
+ json_t *json;
+ int error;
+
+ filename = config_get_payload();
+// if (str_starts_with(filename, "rsync://")) {
+//
+// } else {
+ error = content_info_load(filename, &ci);
+ if (error)
+ return error;
+// }
+
+ json = json_encode(&asn_DEF_ContentInfo, ci);
+ if (json == NULL) {
+ pr_op_err("Error parsing object.");
+ goto end;
+ }
+
+ errno = 0;
+ if (json_dumpf(json, stdout, JSON_INDENT(4)) < 0) {
+ error = errno;
+ if (error)
+ pr_op_err("Error writing JSON to file: %s", strerror(error));
+ else
+ pr_op_err("Unknown error writing JSON to file.");
+ }
+
+ json_decref(json);
+end: ASN_STRUCT_FREE(asn_DEF_ContentInfo, ci);
+ return error;
+}
--- /dev/null
+#ifndef SRC_PRINT_FILE_H_
+#define SRC_PRINT_FILE_H_
+
+int print_file(void);
+
+#endif /* SRC_PRINT_FILE_H_ */