]> git.ipfire.org Git - thirdparty/FORT-validator.git/commitdiff
Add --mode=print
authorAlberto Leiva Popper <ydahhrk@gmail.com>
Sun, 21 Apr 2024 19:15:07 +0000 (13:15 -0600)
committerAlberto Leiva Popper <ydahhrk@gmail.com>
Sun, 21 Apr 2024 19:25:40 +0000 (13:25 -0600)
Prints an RPKI file in standard output. Only the asn1c signed objects
(ROAs, Manifests and Ghostbusters) are implemented right now.

In particular, it doesn't jsonify certificates nor CRLs yet, which
includes the "certificate" field of the signed objects.

Progress for #122.

49 files changed:
src/Makefile.am
src/asn1/asn1c/ANY.c
src/asn1/asn1c/BIT_STRING.c
src/asn1/asn1c/BOOLEAN.c
src/asn1/asn1c/BOOLEAN.h
src/asn1/asn1c/CMSAttribute.c
src/asn1/asn1c/ContentInfo.c
src/asn1/asn1c/EncapsulatedContentInfo.c
src/asn1/asn1c/GeneralizedTime.c
src/asn1/asn1c/GeneralizedTime.h
src/asn1/asn1c/IA5String.c
src/asn1/asn1c/INTEGER.c
src/asn1/asn1c/INTEGER.h
src/asn1/asn1c/Makefile.include
src/asn1/asn1c/NULL.c
src/asn1/asn1c/NULL.h
src/asn1/asn1c/OBJECT_IDENTIFIER.c
src/asn1/asn1c/OBJECT_IDENTIFIER.h
src/asn1/asn1c/OCTET_STRING.c
src/asn1/asn1c/OCTET_STRING.h
src/asn1/asn1c/OPEN_TYPE.c
src/asn1/asn1c/OPEN_TYPE.h
src/asn1/asn1c/ROAIPAddressFamily.c
src/asn1/asn1c/SignedAttributes.c
src/asn1/asn1c/UTCTime.c
src/asn1/asn1c/UTCTime.h
src/asn1/asn1c/asn_internal.h
src/asn1/asn1c/constr_CHOICE.c
src/asn1/asn1c/constr_CHOICE.h
src/asn1/asn1c/constr_SEQUENCE.c
src/asn1/asn1c/constr_SEQUENCE.h
src/asn1/asn1c/constr_SEQUENCE_OF.c
src/asn1/asn1c/constr_SEQUENCE_OF.h
src/asn1/asn1c/constr_SET_OF.c
src/asn1/asn1c/constr_SET_OF.h
src/asn1/asn1c/constr_TYPE.c
src/asn1/asn1c/constr_TYPE.h
src/asn1/asn1c/json_encoder.c [new file with mode: 0644]
src/asn1/asn1c/json_encoder.h [new file with mode: 0644]
src/asn1/content_info.c
src/asn1/content_info.h
src/config.c
src/config.h
src/config/mode.c
src/config/mode.h
src/main.c
src/object/signed_object.c
src/print_file.c [new file with mode: 0644]
src/print_file.h [new file with mode: 0644]

index f9b7d451306b37b020e0b696707404472fe418ab..8fb6b427f382ec5b756ced70a0489d0aaa289bfe 100644 (file)
@@ -22,6 +22,7 @@ fort_SOURCES += line_file.h line_file.c
 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
@@ -108,8 +109,6 @@ fort_SOURCES += thread/thread_pool.c thread/thread_pool.h
 
 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)
 
index f48c97834e351643a64ad5b1e27921669067aff9..75240df47c79a8bdf10b78b0e84713709af425f2 100644 (file)
@@ -18,6 +18,7 @@ asn_TYPE_operation_t asn_OP_ANY = {
        OCTET_STRING_compare,
        OCTET_STRING_decode_ber,
        OCTET_STRING_encode_der,
+       OCTET_STRING_encode_json,
        ANY_encode_xer,
        0       /* Use generic outmost tag fetcher */
 };
index 8e311a8765665af56030409744c731989b64bbab..94f9d788c56d6782c393d84f95471a506946d4fd 100644 (file)
@@ -26,6 +26,7 @@ asn_TYPE_operation_t asn_OP_BIT_STRING = {
        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 */
 };
index b0fdef44bdd0526b6d606cf5751ce1bdb25f59ec..ba56217be041c5beb1b0d5c53c5c20d06cd20d49 100644 (file)
@@ -18,6 +18,7 @@ asn_TYPE_operation_t asn_OP_BOOLEAN = {
        BOOLEAN_compare,
        BOOLEAN_decode_ber,
        BOOLEAN_encode_der,
+       BOOLEAN_encode_json,
        BOOLEAN_encode_xer,
        0       /* Use generic outmost tag fetcher */
 };
@@ -131,6 +132,17 @@ BOOLEAN_encode_der(const asn_TYPE_descriptor_t *td, const void *sptr,
        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,
index 0f5f85321904d6d2d2b380533c40bd2b59635bf7..22f4272ac5b2cd5e7e90de3be62d5b80d2d4165e 100644 (file)
@@ -22,6 +22,7 @@ asn_struct_print_f BOOLEAN_print;
 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
index e66ee68708bc3773b019d40c2e9d022aa7c5231d..9eca5b08e77463d325680b0cbcc488c67126177a 100644 (file)
@@ -7,6 +7,73 @@
 
 #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?) */,
@@ -80,7 +147,7 @@ asn_SEQUENCE_specifics_t asn_SPC_CMSAttribute_specs_1 = {
 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 */
index c522bebba047ab358783676efe5ea92e44095a13..94a321f5371642209a02ca721b2c6d655234306f 100644 (file)
@@ -7,6 +7,84 @@
 
 #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)),
@@ -44,7 +122,7 @@ static asn_SEQUENCE_specifics_t asn_SPC_ContentInfo_specs_1 = {
 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 */
index 6de83cae1a79e9df49dc952eb0ef1d689e6f6273..77b335ab6c1054df6c0c42e550e7bb419ba34e00 100644 (file)
@@ -7,6 +7,94 @@
 
 #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)),
@@ -44,7 +132,7 @@ asn_SEQUENCE_specifics_t asn_SPC_EncapsulatedContentInfo_specs_1 = {
 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 */
index f8efc307497a5216a6d6ff766af2926de0b5adff..5d66e77a95f7842e0bf6b671ec9747fac77a967c 100644 (file)
@@ -58,6 +58,7 @@ asn_TYPE_operation_t asn_OP_GeneralizedTime = {
        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 */
 };
@@ -78,6 +79,17 @@ asn_TYPE_descriptor_t asn_DEF_GeneralizedTime = {
 
 #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.
  */
@@ -124,6 +136,21 @@ GeneralizedTime_encode_der(const asn_TYPE_descriptor_t *td, const void *sptr,
     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
@@ -157,29 +184,35 @@ GeneralizedTime_encode_xer(const asn_TYPE_descriptor_t *td, const void *sptr,
 
 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
index 5a974f4ba736f6043744e336076266f07b3e57fe..fa98755f45700ba0a6a9d97bfd2cfab6c64eea46 100644 (file)
@@ -18,6 +18,7 @@ asn_struct_print_f GeneralizedTime_print;
 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
@@ -27,6 +28,10 @@ xer_type_encoder_f GeneralizedTime_encode_xer;
  * 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.
index 29a9df29cf8022a4a41a0655b8953baf31384469..5f574e83e84f6c7e2ecf92e1164d8d7a920a7604 100644 (file)
@@ -18,6 +18,7 @@ asn_TYPE_operation_t asn_OP_IA5String = {
        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 */
 };
index 2d6d0dfaa62de2c515287ad06ed0a8468712f74c..ca0a984daf6e2a21cfa302fe308656be1c313fbf 100644 (file)
@@ -21,6 +21,7 @@ asn_TYPE_operation_t asn_OP_INTEGER = {
        INTEGER_compare,
        ber_decode_primitive,
        INTEGER_encode_der,
+       INTEGER_encode_json,
        INTEGER_encode_xer,
        0       /* Use generic outmost tag fetcher */
 };
@@ -217,6 +218,29 @@ INTEGER_map_value2enum(const asn_INTEGER_specifics_t *specs, long value) {
                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,
index acc07ce3491404f45d94b971211279356c42fd2c..584f8fc945d24a5727ff25c81f847a762c20b3c7 100644 (file)
@@ -37,6 +37,7 @@ typedef struct asn_INTEGER_specifics_s {
 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;
 
 /***********************************
index 5043095d5e19d538905a4b67bea223c3c0757a2a..f9faea9d62a2431f03ea39e127a10a3b1faecbfa 100644 (file)
@@ -179,5 +179,7 @@ ASN_MODULE_HDRS+=asn1/asn1c/constr_TYPE.h
 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
index 2811a8462bb3d637f9fe796eabdc4d56ca19dd25..b4bd171798bf1369ca410898fd5e3bcaa03f3edf 100644 (file)
@@ -18,6 +18,7 @@ asn_TYPE_operation_t asn_OP_NULL = {
        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 */
 };
@@ -107,6 +108,12 @@ NULL_encode_der(const asn_TYPE_descriptor_t *td, const void *ptr, int tag_mode,
        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,
index f93bd4aef00203746914e1084dca07eed1cf572a..1c9bfec68714ed43bae216570ec9759b9187946c 100644 (file)
@@ -21,6 +21,7 @@ asn_struct_print_f NULL_print;
 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
index c964c8090273f8932ec665484d4b122e960c202f..04094ac439fddac52a2c782b1777a4f780b33937 100644 (file)
@@ -22,6 +22,7 @@ asn_TYPE_operation_t asn_OP_OBJECT_IDENTIFIER = {
        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 */
 };
@@ -210,6 +211,85 @@ OBJECT_IDENTIFIER_print(const asn_TYPE_descriptor_t *td, const void *sptr,
     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) {
@@ -508,3 +588,97 @@ OBJECT_IDENTIFIER_parse_arcs(const char *oid_text, ssize_t oid_txt_length,
        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));
+}
index 78fcecd86c867272cbdfc935ddd1b71e2b65ce1e..00acb6e10374cb096005fcb129eccf5af92dc0f0 100644 (file)
@@ -5,6 +5,7 @@
 #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"
@@ -20,6 +21,7 @@ extern asn_TYPE_operation_t asn_OP_OBJECT_IDENTIFIER;
 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
@@ -31,6 +33,9 @@ xer_type_encoder_f OBJECT_IDENTIFIER_encode_xer;
  * 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.
@@ -137,4 +142,15 @@ ssize_t OBJECT_IDENTIFIER_get_single_arc(const uint8_t *arcbuf,
 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_ */
index 377c8fcd8de3b24a18ae73e7bf51b043c82a5070..1dd9f7994a27b85732c5012902c2a7fddc25a877 100644 (file)
@@ -9,6 +9,8 @@
 #include <assert.h>
 #include <errno.h>
 
+#include "alloc.h"
+
 /*
  * OCTET STRING basic type description.
  */
@@ -27,6 +29,7 @@ asn_TYPE_operation_t asn_OP_OCTET_STRING = {
        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 */
 };
@@ -578,6 +581,37 @@ cb_failed:
        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,
index c05687508d98d10509b45299589bed30f73607a2..4647a803457b73f4b9be7c01fb4a44ef32233386 100644 (file)
@@ -31,6 +31,8 @@ asn_struct_print_f OCTET_STRING_print_utf8;
 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;
 
index fb167a928a929f4bf51035b5f0eb485713f3be8b..4fcee5a967a2d1cabb2d6c640ef2b035526fd2eb 100644 (file)
@@ -13,6 +13,7 @@ asn_TYPE_operation_t asn_OP_OPEN_TYPE = {
        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 */
 };
index 5913ab1b01f1240dfb8414408746bfa7f7724769..87ed5919770342abc69d6f2c1c69eece590216ce 100644 (file)
@@ -13,6 +13,7 @@
 #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;
index 80d165c3591ccdba5f42d1c6dfef8684ee18fce6..23e59b6c49dfb2532104b20c9035f39788447c6a 100644 (file)
@@ -7,6 +7,131 @@
 
 #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) {
@@ -132,7 +257,7 @@ asn_SEQUENCE_specifics_t asn_SPC_ROAIPAddressFamily_specs_1 = {
 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 */
index ef8f9f6c3ffdfb9ff4f0dbde58464b3a1aad4199..dc33197ab397ae70de6ffd7a10ef5e66cefb0bfb 100644 (file)
@@ -7,6 +7,58 @@
 
 #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)),
@@ -29,7 +81,7 @@ asn_SET_OF_specifics_t asn_SPC_SignedAttributes_specs_1 = {
 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 */
index 4e45451bf655af94d92b72422b26d21daedd9de9..c7c9a4cc2a4a78dbfedbc17e2faee976f91a904c 100644 (file)
@@ -26,6 +26,7 @@ asn_TYPE_operation_t asn_OP_UTCTime = {
        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 */
 };
@@ -97,31 +98,48 @@ UTCTime_encode_xer(const asn_TYPE_descriptor_t *td, const void *sptr,
 
 #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
index 25f308e78380b5e24ef4f9eb3fa92cefecac2e8d..1e085cbfcf6247273ba1f197461cb4b086b4a5f3 100644 (file)
@@ -17,6 +17,7 @@ extern asn_TYPE_operation_t asn_OP_UTCTime;
 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
index 4d74313e1cd05dec27391619239f12be847cee08..2bc3d9b51e380ac6c24949461055de3ff84f3b51 100644 (file)
@@ -21,9 +21,6 @@ int get_asn1c_environment_version(void);      /* Run-time version */
 #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
@@ -35,33 +32,10 @@ int get_asn1c_environment_version(void);    /* Run-time version */
  */
 #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 */
 
index 05039e2ed1ded8ca3534393256a95ef453e78fd2..df67ffa38c35cc02ba5359db4bb719349e29e9cb 100644 (file)
@@ -397,20 +397,16 @@ CHOICE_encode_der(const asn_TYPE_descriptor_t *td, const void *sptr,
         * 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:
@@ -468,17 +464,8 @@ CHOICE_outmost_tag(const asn_TYPE_descriptor_t *td, const void *ptr, int tag_mod
 
        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;
@@ -507,18 +494,14 @@ CHOICE_constraint(const asn_TYPE_descriptor_t *td, const void *sptr,
                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) {
@@ -536,6 +519,33 @@ CHOICE_constraint(const asn_TYPE_descriptor_t *td, const void *sptr,
        }
 }
 
+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,
@@ -562,15 +572,11 @@ CHOICE_encode_xer(const asn_TYPE_descriptor_t *td, const void *sptr, int ilevel,
                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);
@@ -610,12 +616,9 @@ CHOICE_print(const asn_TYPE_descriptor_t *td, const void *sptr, int ilevel,
                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) {
@@ -751,12 +754,7 @@ _get_member_ptr(const asn_TYPE_descriptor_t *td, const void *sptr,
         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 {
@@ -843,6 +841,7 @@ asn_TYPE_operation_t asn_OP_CHOICE = {
        CHOICE_compare,
        CHOICE_decode_ber,
        CHOICE_encode_der,
+       CHOICE_encode_json,
        CHOICE_encode_xer,
        CHOICE_outmost_tag
 };
index f8101e8ad826eb62ead023231633323702fcf88c..704a4d448e9f83c916587fc7c6d75177c1d88c6f 100644 (file)
@@ -37,6 +37,7 @@ asn_struct_compare_f CHOICE_compare;
 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;
index ce2ea37eb184279b80a125c89ee08b734581dd90..c4d177dfdc93e35bd92e214969a0d4b83f7f22e6 100644 (file)
@@ -611,6 +611,43 @@ SEQUENCE_encode_der(const asn_TYPE_descriptor_t *td, const void *sptr,
        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,
@@ -632,9 +669,7 @@ SEQUENCE_encode_xer(const asn_TYPE_descriptor_t *td, const void *sptr,
         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) {
@@ -651,9 +686,6 @@ SEQUENCE_encode_xer(const asn_TYPE_descriptor_t *td, const void *sptr,
                     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);
@@ -696,15 +728,12 @@ SEQUENCE_print(const asn_TYPE_descriptor_t *td, const void *sptr, int ilevel,
                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 */
@@ -790,18 +819,14 @@ SEQUENCE_constraint(const asn_TYPE_descriptor_t *td, const void *sptr,
                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) {
@@ -867,6 +892,7 @@ asn_TYPE_operation_t asn_OP_SEQUENCE = {
        SEQUENCE_compare,
        SEQUENCE_decode_ber,
        SEQUENCE_encode_der,
+       SEQUENCE_encode_json,
        SEQUENCE_encode_xer,
        0       /* Use generic outmost tag fetcher */
 };
index e90c821d8fa70731ff43f5b24302e66ed7bd029f..c64142c1ffbd4e7d02f81f7ee9ac5619d0e02300 100644 (file)
@@ -38,6 +38,7 @@ asn_struct_compare_f SEQUENCE_compare;
 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;
 
index 34d9e4ceebd8f15c09ae517859a05dda22460e03..1e7475fa9794aeabdadc5cd5dcd835e4afce298c 100644 (file)
@@ -174,6 +174,7 @@ asn_TYPE_operation_t asn_OP_SEQUENCE_OF = {
        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 */
 };
index fb15dd976d1c119863524073b6fd77f2ccdf3ba6..916f063c963089c2641994aedebd81802c82daa5 100644 (file)
@@ -21,5 +21,6 @@ extern asn_TYPE_operation_t asn_OP_SEQUENCE_OF;
 #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_ */
index ef4b3fee671ec7b3aa1d7cc1a74ed54b1c8be4c5..e2162e134a8f3b04420ef316398eb480e0887bc4 100644 (file)
@@ -489,6 +489,38 @@ SET_OF_encode_der(const asn_TYPE_descriptor_t *td, const void *sptr,
     }
 }
 
+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;
@@ -821,6 +853,7 @@ asn_TYPE_operation_t asn_OP_SET_OF = {
        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 */
 };
index ee09914e65d3c4f78f0dde2d12e0c9f4196caf0c..3d77f3813e0d09371a923df18e5a2e2720dde678 100644 (file)
@@ -27,6 +27,7 @@ asn_struct_compare_f SET_OF_compare;
 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;
 
index 02597a2ea23019ab3a378e48e8c012a6002973bd..602b263175475ac769db26c8fea4c20ca7320344 100644 (file)
@@ -75,7 +75,16 @@ void ASN_DEBUG_f(const char *fmt, ...);
 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));
+}
index e1d9c982280eb8a8342de0054776b482cbc4877b..758e6312fa503a5222a86cea218bdd524e66b0d1 100644 (file)
@@ -33,6 +33,7 @@ typedef struct asn_struct_ctx_s {
 #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 */
 
 /*
@@ -130,6 +131,7 @@ typedef struct asn_TYPE_operation_s {
     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;
@@ -227,4 +229,6 @@ int asn_fprint(FILE *stream, /* Destination stream descriptor */
                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_ */
diff --git a/src/asn1/asn1c/json_encoder.c b/src/asn1/asn1c/json_encoder.c
new file mode 100644 (file)
index 0000000..c7e7e2b
--- /dev/null
@@ -0,0 +1,14 @@
+#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);
+}
diff --git a/src/asn1/asn1c/json_encoder.h b/src/asn1/asn1c/json_encoder.h
new file mode 100644 (file)
index 0000000..0ecd83f
--- /dev/null
@@ -0,0 +1,21 @@
+#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_ */
index 1e3e489f819ad083832257d16dde804c988f0033..1aacb7939ede304da3006826743783674e03b5fd 100644 (file)
@@ -49,12 +49,12 @@ decode(struct file_contents *fc, struct ContentInfo **result)
 }
 
 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;
 
index 862510bde1c788cb7bfa3978b21c440bcd51e68c..89d7e722f6c88ac4976793444fb806e74eeea578 100644 (file)
@@ -3,10 +3,9 @@
 
 /* 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_ */
index de54d9086e000f9a36f2f8f612d95baa35227659..224596d2235b38db9297ac9566d50ce036c297d1 100644 (file)
@@ -43,7 +43,7 @@ struct rpki_config {
        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
@@ -192,6 +192,8 @@ struct rpki_config {
                        unsigned int max; /* Deprecated */
                } validation;
        } thread_pool;
+
+       char *payload;
 };
 
 static void print_usage(FILE *, bool);
@@ -988,6 +990,15 @@ valid_output_file(char const *path)
 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.");
 
@@ -1098,14 +1109,8 @@ handle_flags_config(int argc, char **argv)
                        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)
@@ -1453,6 +1458,12 @@ config_get_thread_pool_server_max(void)
        return rpki_config.thread_pool.server.max;
 }
 
+char const *
+config_get_payload(void)
+{
+       return rpki_config.payload;
+}
+
 void
 config_set_rsync_enabled(bool value)
 {
@@ -1473,4 +1484,5 @@ free_rpki_config(void)
        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);
 }
index 8f9738145f6a99ecbfb3e0a763c27355b604bd43..18cfa23f30d2f9ca9238093d5f91a98b9ce5dead 100644 (file)
@@ -55,6 +55,7 @@ char const *config_get_output_bgpsec(void);
 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);
index c0eb3f4eaec0dea12b5b08cd94e935eee79e4539..12d379fbc740425cf8f5a1c81abb962ec4ff2239 100644 (file)
@@ -7,6 +7,7 @@
 
 #define VALUE_SERVER           "server"
 #define VALUE_STANDALONE       "standalone"
+#define VALUE_PRINT_FILE       "print"
 
 #define DEREFERENCE(void_value) (*((enum mode *) void_value))
 
@@ -22,6 +23,9 @@ print_mode(struct option_field const *field, void *value)
        case STANDALONE:
                str = VALUE_STANDALONE;
                break;
+       case PRINT_FILE:
+               str = VALUE_PRINT_FILE;
+               break;
        }
 
        pr_op_info("%s: %s", field->name, str);
@@ -35,6 +39,8 @@ parse_argv_mode(struct option_field const *field, char const *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);
 
@@ -58,5 +64,5 @@ const struct global_type gt_mode = {
        .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,
 };
index 2cfd6ef782cd3fc6a1eb609bafad19460ed99f92..7dc3720a4552a80df6ef8b070e4dee38b91d453d 100644 (file)
@@ -7,14 +7,12 @@
  * 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;
index 62ac29defa6f9228fa8b9273c3263c3b1690ac6e..1f88bd14320321c9de59567c4eab10d4d2988cbd 100644 (file)
@@ -7,6 +7,7 @@
 #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"
@@ -169,6 +170,9 @@ main(int argc, char **argv)
        case SERVER:
                error = fort_server();
                break;
+       case PRINT_FILE:
+               error = print_file();
+               break;
        }
 
        /* End */
index a5b6667e18647e8a284e8ccdc4500367f8186242..5f00e538007a3904d8ddc81029f3fe1bb9c6c821 100644 (file)
@@ -8,7 +8,7 @@ signed_object_decode(struct signed_object *sobj, struct rpki_uri *uri)
 {
        int error;
 
-       error = content_info_load(uri, &sobj->cinfo);
+       error = content_info_load(uri_get_local(uri), &sobj->cinfo);
        if (error)
                return error;
 
diff --git a/src/print_file.c b/src/print_file.c
new file mode 100644 (file)
index 0000000..4999e83
--- /dev/null
@@ -0,0 +1,43 @@
+#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;
+}
diff --git a/src/print_file.h b/src/print_file.h
new file mode 100644 (file)
index 0000000..571f631
--- /dev/null
@@ -0,0 +1,6 @@
+#ifndef SRC_PRINT_FILE_H_
+#define SRC_PRINT_FILE_H_
+
+int print_file(void);
+
+#endif /* SRC_PRINT_FILE_H_ */