From 2dcb371e2f6663ad1452039065e233df6fdb3f6e Mon Sep 17 00:00:00 2001 From: Alberto Leiva Popper Date: Thu, 9 May 2024 12:18:22 -0600 Subject: [PATCH] Review jsonification They want Fort to jsonify more faithfully to the ASN1 grammar, rather than human-friendlier. A --human-readable flag wouldn't go amiss, but I should probably waint until someone requests it. --- src/asn1/asn1c/CMSAttribute.c | 69 +++++++++++++----------- src/asn1/asn1c/ContentInfo.c | 6 +-- src/asn1/asn1c/EncapsulatedContentInfo.c | 4 +- src/asn1/asn1c/SignedAttributes.c | 53 +----------------- src/extension.c | 58 +++++++++++++------- src/libcrypto_util.c | 41 +++++++------- 6 files changed, 103 insertions(+), 128 deletions(-) diff --git a/src/asn1/asn1c/CMSAttribute.c b/src/asn1/asn1c/CMSAttribute.c index 9eca5b08..fb09a614 100644 --- a/src/asn1/asn1c/CMSAttribute.c +++ b/src/asn1/asn1c/CMSAttribute.c @@ -12,55 +12,60 @@ #include "asn1/asn1c/SigningTime.h" static json_t * -attr2json(asn_TYPE_descriptor_t const *td, struct CMSAttribute const *cattr) +attr2json(asn_TYPE_descriptor_t const *td, CMSAttributeValue_t const *ber) { - json_t *array, *node; - CMSAttributeValue_t *ber; void *attr; - int i; asn_dec_rval_t rval; + json_t *json; - 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; - } + attr = NULL; + rval = ber_decode(NULL, td, &attr, ber->buf, ber->size); + if (rval.code != RC_OK) + return NULL; /* TODO release attr? */ - return array; + json = td->op->json_encoder(td, attr); -fail: json_decref(array); - return NULL; + ASN_STRUCT_FREE(*td, attr); + return json; } json_t * CMSAttribute_encode_json(const asn_TYPE_descriptor_t *td, const void *sptr) { struct CMSAttribute const *cattr = sptr; + json_t *root; + json_t *attrValues; + int a; if (!cattr) return json_null(); + + root = json_object(); + if (root == NULL) + return NULL; + + if (json_object_set_new(root, "attrType", OBJECT_IDENTIFIER_encode_json(NULL, &cattr->attrType))) + goto fail; + if (json_object_set_new(root, "attrValues", attrValues = json_array())) + goto fail; + 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); + td = &asn_DEF_ContentType; + else if (OBJECT_IDENTIFIER_is_MessageDigest(&cattr->attrType)) + td = &asn_DEF_MessageDigest; + else if (OBJECT_IDENTIFIER_is_SigningTime(&cattr->attrType)) + td = &asn_DEF_SigningTime; + else + td = &asn_DEF_ANY; + + for (a = 0; a < cattr->attrValues.list.count; a++) + if (json_array_append_new(attrValues, attr2json(td, cattr->attrValues.list.array[a]))) + goto fail; - return SEQUENCE_encode_json(td, sptr); + return root; + +fail: json_decref(root); + return NULL; } asn_TYPE_operation_t asn_OP_CMSAttribute = { diff --git a/src/asn1/asn1c/ContentInfo.c b/src/asn1/asn1c/ContentInfo.c index 94a321f5..e5d4bdd5 100644 --- a/src/asn1/asn1c/ContentInfo.c +++ b/src/asn1/asn1c/ContentInfo.c @@ -44,9 +44,7 @@ ContentInfo_encode_json(const asn_TYPE_descriptor_t *td, const void *sptr) 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)) + if (json_object_set_new(parent, "contentType", content_type)) goto fail; if (OBJECT_IDENTIFIER_is_SignedData(&ci->contentType)) { @@ -65,7 +63,7 @@ ContentInfo_encode_json(const asn_TYPE_descriptor_t *td, const void *sptr) if (content == NULL) goto fail; - if (json_object_set_new(parent, td->name, content)) + if (json_object_set_new(parent, "content", content)) goto fail; return parent; diff --git a/src/asn1/asn1c/EncapsulatedContentInfo.c b/src/asn1/asn1c/EncapsulatedContentInfo.c index 77b335ab..e2470f19 100644 --- a/src/asn1/asn1c/EncapsulatedContentInfo.c +++ b/src/asn1/asn1c/EncapsulatedContentInfo.c @@ -48,7 +48,7 @@ EncapsulatedContentInfo_encode_json(const asn_TYPE_descriptor_t *td, 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)) + if (json_object_set_new(parent, "eContentType", content_type)) goto fail; if (OBJECT_IDENTIFIER_is_mft(&eci->eContentType)) { @@ -75,7 +75,7 @@ EncapsulatedContentInfo_encode_json(const asn_TYPE_descriptor_t *td, if (content == NULL) goto fail; - if (json_object_set_new(parent, td->name, content)) + if (json_object_set_new(parent, "eContent", content)) goto fail; return parent; diff --git a/src/asn1/asn1c/SignedAttributes.c b/src/asn1/asn1c/SignedAttributes.c index a9d3d526..ef8f9f6c 100644 --- a/src/asn1/asn1c/SignedAttributes.c +++ b/src/asn1/asn1c/SignedAttributes.c @@ -7,57 +7,6 @@ #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; - int i; - - if (!sptr) - return json_null(); - - result = json_object(); - if (result == NULL) - return NULL; - - list = _A_CSET_FROM_VOID(sptr); - td = &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 = td->op->json_encoder(td, 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)), @@ -80,7 +29,7 @@ asn_SET_OF_specifics_t asn_SPC_SignedAttributes_specs_1 = { asn_TYPE_descriptor_t asn_DEF_SignedAttributes = { "SignedAttributes", "SignedAttributes", - &asn_OP_SignedAttributes, + &asn_OP_SET_OF, asn_DEF_SignedAttributes_tags_1, sizeof(asn_DEF_SignedAttributes_tags_1) /sizeof(asn_DEF_SignedAttributes_tags_1[0]), /* 1 */ diff --git a/src/extension.c b/src/extension.c index d8e00426..10e36b74 100644 --- a/src/extension.c +++ b/src/extension.c @@ -164,14 +164,43 @@ static const struct extension_metadata KU = { ku_destroy, }; +static json_t * +rdn2json(STACK_OF(X509_NAME_ENTRY) *rdn) +{ + json_t *root; + json_t *child; + X509_NAME_ENTRY *name; + int n; + + root = json_array(); + if (root == NULL) + return NULL; + + for (n = 0; n < sk_X509_NAME_ENTRY_num(rdn); n++) { + if (json_array_append_new(root, child = json_object())) + goto fail; + + name = sk_X509_NAME_ENTRY_value(rdn, n); + if (json_object_set_new(child, "type", oid2json(X509_NAME_ENTRY_get_object(name)))) + goto fail; + if (json_object_set_new(child, "value", asn1str2json(X509_NAME_ENTRY_get_data(name)))) + goto fail; + } + + return root; + +fail: json_decref(root); + return NULL; +} + static json_t * dpname2json(DIST_POINT_NAME const *dpn) { if (dpn == NULL) return json_null(); - if (dpn->type) /* if relativename */ - return name2json(dpn->dpname); - return gns2json(dpn->name.fullname); + return (dpn->type) + ? rdn2json(dpn->name.relativename) + : gns2json(dpn->name.fullname); } static json_t * @@ -349,7 +378,7 @@ cp2json(void const *ext) return NULL; for (i = 0; i < sk_POLICYINFO_num(cp); i++) - if (json_array_append_new(root, pi2json(sk_POLICYINFO_value(cp, i))) < 0) + if (json_array_append_new(root, pi2json(sk_POLICYINFO_value(cp, i)))) goto fail; return root; @@ -378,7 +407,8 @@ p2json(ASN1_BIT_STRING const *ap, int af) unsigned char bin[16]; char str[INET6_ADDRSTRLEN]; unsigned int length; - json_t *root; + char full[INET6_ADDRSTRLEN + 4]; + int written; if (ap == NULL) return json_null(); @@ -392,18 +422,8 @@ p2json(ASN1_BIT_STRING const *ap, int af) if (ap->flags & ASN1_STRING_FLAG_BITS_LEFT) length -= ap->flags & 7; - root = json_object(); - if (root == NULL) - return NULL; - if (json_object_set_new(root, "address", json_string(str)) < 0) - goto fail; - if (json_object_set_new(root, "length", json_integer(length)) < 0) - goto fail; - - return root; - -fail: json_decref(root); - return NULL; + written = snprintf(full, INET6_ADDRSTRLEN + 4, "%s/%u", str, length); + return json_stringn(full, written); } static json_t * @@ -447,7 +467,7 @@ iac2json(IPAddressChoice const *iac, int af) if (root == NULL) goto fail; for (i = 0; i < sk_IPAddressOrRange_num(iaor); i++) - if (json_array_append_new(root, iaor2json(sk_IPAddressOrRange_value(iaor, i), af)) < 0) + if (json_array_append_new(root, iaor2json(sk_IPAddressOrRange_value(iaor, i), af))) goto fail; return root; } @@ -510,7 +530,7 @@ ir2json(void const *ext) return NULL; for (i = 0; i < sk_IPAddressFamily_num(iafs); i++) - if (json_array_append_new(root, iaf2json(sk_IPAddressFamily_value(iafs, i))) < 0) + if (json_array_append_new(root, iaf2json(sk_IPAddressFamily_value(iafs, i)))) goto fail; return root; diff --git a/src/libcrypto_util.c b/src/libcrypto_util.c index a7f344fb..35a0b9db 100644 --- a/src/libcrypto_util.c +++ b/src/libcrypto_util.c @@ -117,7 +117,8 @@ json_t * name2json(X509_NAME const *name) { json_t *root; - json_t *child; + json_t *rdnSequence; + json_t *typeval; int i; if (name == NULL) @@ -126,21 +127,23 @@ name2json(X509_NAME const *name) root = json_object(); if (root == NULL) return NULL; + if (json_object_set_new(root, "rdnSequence", rdnSequence = json_array())) + goto fail; for (i = 0; i < X509_NAME_entry_count(name); i++) { - X509_NAME_ENTRY *entry; + X509_NAME_ENTRY *entry = X509_NAME_get_entry(name, i); int nid; const ASN1_STRING *data; - entry = X509_NAME_get_entry(name, i); - nid = OBJ_obj2nid(X509_NAME_ENTRY_get_object(entry)); + if (json_array_append_new(rdnSequence, typeval = json_object())) + goto fail; - data = X509_NAME_ENTRY_get_data(entry); - if (data == NULL) + nid = OBJ_obj2nid(X509_NAME_ENTRY_get_object(entry)); + if (json_object_set_new(typeval, "type", json_string(OBJ_nid2ln(nid)))) goto fail; - child = json_stringn((char *)data->data, data->length); - if (json_object_set_new(root, OBJ_nid2sn(nid), child) < 0) + data = X509_NAME_ENTRY_get_data(entry); + if (json_object_set_new(typeval, "value", json_stringn((char *)data->data, data->length))) goto fail; } @@ -179,7 +182,7 @@ gns2json(GENERAL_NAMES const *gns) return NULL; for (n = 0; n < sk_GENERAL_NAME_num(gns); n++) - if (json_array_append_new(root, gn2json(sk_GENERAL_NAME_value(gns, n))) < 0) + if (json_array_append_new(root, gn2json(sk_GENERAL_NAME_value(gns, n)))) goto fail; return root; @@ -245,6 +248,7 @@ json_t * exts2json(const STACK_OF(X509_EXTENSION) *exts) { json_t *root; + json_t *child; BIO *bio; char *name; int i; @@ -253,14 +257,16 @@ exts2json(const STACK_OF(X509_EXTENSION) *exts) if (sk_X509_EXTENSION_num(exts) <= 0) return json_null(); - root = json_object(); + root = json_array(); if (root == NULL) return NULL; for (i = 0; i < sk_X509_EXTENSION_num(exts); i++) { - json_t *node; X509_EXTENSION *ex; + if (json_array_append_new(root, child = json_object())) + goto fail; + ex = sk_X509_EXTENSION_value(exts, i); /* Get the extension name */ @@ -271,19 +277,16 @@ exts2json(const STACK_OF(X509_EXTENSION) *exts) BIO_free_all(bio); goto fail; } - name = bio2str(bio); - /* Create node, add to parent */ - ret = json_object_set_new(root, name, node = json_object()); + name = bio2str(bio); + ret = json_object_set_new(child, "extnID", json_string(name)); free(name); - if (ret < 0) + if (ret) goto fail; - /* Child 1: Critical */ - if (json_object_set_new(node, "critical", X509_EXTENSION_get_critical(ex) ? json_true() : json_false()) < 0) + if (json_object_set_new(child, "critical", json_boolean(X509_EXTENSION_get_critical(ex)))) goto fail; - /* Child 2: Value */ - if (json_object_set_new(node, "value", ext2json(ex))) + if (json_object_set_new(child, "extnValue", ext2json(ex))) goto fail; } -- 2.47.3