#include <openssl/x509v3.h>
#include <openssl/pem.h>
#include "alloc.h"
-
-/* Swallows @bio. */
-static json_t *
-bio2json(BIO *bio)
-{
- BUF_MEM *buffer;
- json_t *json;
-
- json = (BIO_get_mem_ptr(bio, &buffer) > 0)
- ? json_stringn(buffer->data, buffer->length)
- : NULL;
-
- BIO_free_all(bio);
- return json;
-}
-
-/* Swallows @bio. */
-static char *
-bio2str(BIO *bio)
-{
- BUF_MEM *buffer;
- char *str;
-
- str = (BIO_get_mem_ptr(bio, &buffer) > 0)
- ? pstrndup(buffer->data, buffer->length)
- : NULL;
-
- BIO_free_all(bio);
- return str;
-}
-
-static json_t *
-asn1int2json(ASN1_INTEGER const *asn1int)
-{
- BIGNUM *bignum;
- char *str;
- json_t *json;
-
- if (asn1int == NULL)
- return NULL;
-
- bignum = ASN1_INTEGER_to_BN(asn1int, NULL);
- str = BN_bn2hex(bignum);
-
- json = json_string(str);
-
- OPENSSL_free(str);
- BN_free(bignum);
-
- return json;
-}
-
-static json_t *
-name2json(X509_NAME const *name)
-{
- json_t *root;
- json_t *child;
- int i;
-
- root = json_object();
- if (root == NULL)
- return NULL;
-
- for (i = 0; i < X509_NAME_entry_count(name); i++) {
- X509_NAME_ENTRY *entry;
- int nid;
- const ASN1_STRING *data;
-
- entry = X509_NAME_get_entry(name, i);
- nid = OBJ_obj2nid(X509_NAME_ENTRY_get_object(entry));
-
- data = X509_NAME_ENTRY_get_data(entry);
- if (data == NULL)
- goto fail;
- child = json_stringn((char *)data->data, data->length);
-
- if (json_object_set_new(root, OBJ_nid2ln(nid), child) < 0)
- goto fail;
- }
-
- return root;
-
-fail: json_decref(root);
- return NULL;
-}
-
-static json_t *
-asn1time2json(ASN1_TIME const *time)
-{
- BIO *bio = BIO_new(BIO_s_mem());
- if (bio == NULL)
- return NULL;
-
- if (!ASN1_TIME_print_ex(bio, time, ASN1_DTFLGS_ISO8601)) {
- BIO_free_all(bio);
- return NULL;
- }
-
- return bio2json(bio);
-}
+#include "extension.h"
+#include "libcrypto_util.h"
static json_t *
validity2json(X509 *x)
}
static json_t *
-bitstr2json(ASN1_BIT_STRING const *bitstr)
+iuid2json(X509 const *x)
{
- BIO *bio;
- unsigned char *data;
- int length;
- int i;
+ const ASN1_BIT_STRING *iuid;
+ X509_get0_uids(x, &iuid, NULL);
+ return asn1str2json(iuid);
+}
- if (bitstr == NULL)
- return json_null();
+static json_t *
+suid2json(X509 const *x)
+{
+ const ASN1_BIT_STRING *suid;
+ X509_get0_uids(x, NULL, &suid);
+ return asn1str2json(suid);
+}
- bio = BIO_new(BIO_s_mem());
- if (bio == NULL)
- return NULL;
+static json_t *
+ext2json_known(struct extension_metadata const *meta, X509_EXTENSION *ext)
+{
+ void *decoded;
+ json_t *json;
- data = bitstr->data;
- length = bitstr->length;
+ decoded = X509V3_EXT_d2i(ext);
+ if (decoded == NULL)
+ return NULL;
- for (i = 0; i < length; i++) {
- if (BIO_printf(bio, "%02x", data[i]) <= 0) {
- BIO_free_all(bio);
- return NULL;
- }
- }
+ json = meta->to_json(decoded);
- return bio2json(bio);
+ meta->destructor(decoded);
+ return json;
}
static json_t *
-iuid2json(X509 const *x)
+ext2json_unknown(X509_EXTENSION *ext)
{
- const ASN1_BIT_STRING *iuid;
- X509_get0_uids(x, &iuid, NULL);
- return bitstr2json(iuid);
+ BIO *bio = BIO_new(BIO_s_mem());
+ if (bio == NULL)
+ return NULL;
+
+ /* TODO Those flags are kinda interesting */
+ if (!X509V3_EXT_print(bio, ext, 0, 0)) {
+ BIO_free_all(bio);
+ return NULL;
+ }
+
+ return bio2json(bio);
}
static json_t *
-suid2json(X509 const *x)
+ext2json(X509_EXTENSION *ext)
{
- const ASN1_BIT_STRING *suid;
- X509_get0_uids(x, NULL, &suid);
- return bitstr2json(suid);
+ struct extension_metadata const **array, *meta;
+ int nid;
+
+ array = ext_metadatas();
+ nid = OBJ_obj2nid(X509_EXTENSION_get_object(ext));
+
+ for (meta = *array; meta != NULL; array++, meta = *array) {
+ if (meta->nid == nid) {
+ if (meta->to_json != NULL)
+ return ext2json_known(meta, ext);
+ else
+ break;
+ }
+ }
+
+ return ext2json_unknown(ext);
}
static json_t *
/* Child 1: Critical */
if (json_object_set_new(node, "critical", X509_EXTENSION_get_critical(ex) ? json_true() : json_false()) < 0)
goto fail;
-
/* Child 2: Value */
- bio = BIO_new(BIO_s_mem());
- if (bio == NULL)
- goto fail;
- /* TODO Those flags are kinda interesting */
- if (!X509V3_EXT_print(bio, ex, 0, 0)) {
- BIO_free_all(bio);
- goto fail;
- }
- if (json_object_set_new(node, "value", bio2json(bio)) < 0)
+ if (json_object_set_new(node, "value", ext2json(ex)))
goto fail;
}
goto fail;
if (json_object_set_new(tbsCert, "serialNumber", asn1int2json(X509_get0_serialNumber(x))) < 0)
goto fail;
- if (json_object_set_new(tbsCert, "signature", json_string(OBJ_nid2ln(X509_get_signature_nid(x)))) < 0)
+ if (json_object_set_new(tbsCert, "signature", json_string(OBJ_nid2sn(X509_get_signature_nid(x)))) < 0)
goto fail;
if (json_object_set_new(tbsCert, "issuer", name2json(X509_get_issuer_name(x))) < 0)
goto fail;
X509_get0_signature(NULL, &palg, cert);
X509_ALGOR_get0(&paobj, NULL, NULL, palg);
- return json_string(OBJ_nid2ln(OBJ_obj2nid(paobj)));
+ return oid2json(paobj);
}
static json_t *
{
const ASN1_BIT_STRING *signature;
X509_get0_signature(&signature, NULL, cert);
- return bitstr2json(signature);
+ return asn1str2json(signature);
}
static json_t *
{
const unsigned char *tmp;
X509 *cert;
+ json_t *root;
/*
* "If the call is successful *in is incremented to the byte following
if (cert == NULL)
return NULL;
- json_t *root = x509_to_json(cert);
+ root = x509_to_json(cert);
if (root == NULL)
goto fail;
#include <openssl/x509v3.h>
#include "cert_stack.h"
#include "common.h"
+#include "libcrypto_util.h"
#include "log.h"
#include "nid.h"
#include "thread_var.h"
#include "crypto/hash.h"
-static struct extension_metadata IR2 = {
- "Amended IP Resources",
- -1,
+static json_t *
+unimplemented(void const *arg)
+{
+ return arg ? json_string("<Not implemented for now>") : json_null();
+}
+
+static json_t *
+bc2json(void const *ext)
+{
+ BASIC_CONSTRAINTS const *bc = ext;
+ json_t *root;
+
+ root = json_object();
+ if (root == NULL)
+ return NULL;
+
+ if (json_object_set_new(root, "cA", json_boolean(bc->ca)) < 0)
+ goto fail;
+ if (json_object_set_new(root, "pathLenConstraint", asn1int2json(bc->pathlen)) < 0)
+ goto fail;
+
+ return root;
+
+fail: json_decref(root);
+ return NULL;
+}
+
+static void
+bc_destroy(void *bc)
+{
+ BASIC_CONSTRAINTS_free(bc);
+}
+
+static const struct extension_metadata BC = {
+ "Basic Constraints",
+ NID_basic_constraints,
true,
+ bc2json,
+ bc_destroy,
};
-static struct extension_metadata AR2 = {
- "Amended AS Resources",
- -1,
+static json_t *
+ski2json(void const *ext)
+{
+ return asn1str2json(ext);
+}
+
+static void
+ski_destroy(void *ski)
+{
+ ASN1_OCTET_STRING_free(ski);
+}
+
+static const struct extension_metadata SKI = {
+ "Subject Key Identifier",
+ NID_subject_key_identifier,
+ false,
+ ski2json,
+ ski_destroy,
+};
+
+static json_t *
+aki2json(void const *ext)
+{
+ AUTHORITY_KEYID const *aki = ext;
+ json_t *root;
+
+ root = json_object();
+ if (root == NULL)
+ return NULL;
+
+ if (json_object_set_new(root, "keyIdentifier", asn1str2json(aki->keyid)) < 0)
+ goto fail;
+ if (json_object_set_new(root, "authorityCertIssuer", unimplemented(aki->issuer)) < 0)
+ goto fail;
+ if (json_object_set_new(root, "authorityCertSerialNumber", asn1int2json(aki->serial)) < 0)
+ goto fail;
+
+ return root;
+
+fail: json_decref(root);
+ return NULL;
+}
+
+static void
+aki_destroy(void *aki)
+{
+ AUTHORITY_KEYID_free(aki);
+}
+
+static const struct extension_metadata AKI = {
+ "Authority Key Identifier",
+ NID_authority_key_identifier,
+ false,
+ aki2json,
+ aki_destroy,
+};
+
+static json_t *
+ku2json(void const *ext)
+{
+ ASN1_BIT_STRING const *ku = ext;
+ unsigned char data[2];
+ json_t *root;
+
+ if (ku->length < 1 || 2 < ku->length)
+ return NULL;
+ memset(data, 0, sizeof(data));
+ memcpy(data, ku->data, ku->length);
+
+ root = json_object();
+ if (root == NULL)
+ return NULL;
+
+ if (json_object_set_new(root, "digitalSignature", json_boolean(ku->data[0] & 0x80u)) < 0)
+ goto fail;
+ if (json_object_set_new(root, "contentCommitment", json_boolean(ku->data[0] & 0x40u)) < 0)
+ goto fail;
+ if (json_object_set_new(root, "keyEncipherment", json_boolean(ku->data[0] & 0x20u)) < 0)
+ goto fail;
+ if (json_object_set_new(root, "dataEncipherment", json_boolean(ku->data[0] & 0x10u)) < 0)
+ goto fail;
+ if (json_object_set_new(root, "keyAgreement", json_boolean(ku->data[0] & 0x08u)) < 0)
+ goto fail;
+ if (json_object_set_new(root, "keyCertSign", json_boolean(ku->data[0] & 0x04u)) < 0)
+ goto fail;
+ if (json_object_set_new(root, "cRLSign", json_boolean(ku->data[0] & 0x02u)) < 0)
+ goto fail;
+ if (json_object_set_new(root, "encipherOnly", json_boolean(ku->data[0] & 0x01u)) < 0)
+ goto fail;
+ if (json_object_set_new(root, "decipherOnly", json_boolean(ku->data[1] & 0x80u)) < 0)
+ goto fail;
+
+ return root;
+
+fail: json_decref(root);
+ return NULL;
+}
+
+static void
+ku_destroy(void *ku)
+{
+ ASN1_BIT_STRING_free(ku);
+}
+
+static const struct extension_metadata KU = {
+ "Key Usage",
+ NID_key_usage,
true,
+ ku2json,
+ ku_destroy,
};
-int extension_init(void)
+static json_t *
+dpname2json(DIST_POINT_NAME const *dpn)
{
- IR2.nid = nid_ipAddrBlocksv2();
- AR2.nid = nid_autonomousSysIdsv2();
- return 0;
+ if (dpn == NULL)
+ return json_null();
+ if (dpn->type) /* if relativename */
+ return name2json(dpn->dpname);
+ return gns2json(dpn->name.fullname);
}
-struct extension_metadata const *ext_bc(void)
+static json_t *
+cdp2json(void const *ext)
{
- static const struct extension_metadata BC = {
- "Basic Constraints",
- NID_basic_constraints,
- true,
- };
- return &BC;
+ STACK_OF(DIST_POINT) const *crldp = ext;
+ json_t *root, *child;
+ DIST_POINT *dp;
+ int d;
+
+ root = json_array();
+ if (root == NULL)
+ return NULL;
+
+ for (d = 0; d < sk_DIST_POINT_num(crldp); d++) {
+ dp = sk_DIST_POINT_value(crldp, 0);
+ if (json_array_append_new(root, child = json_object()) < 0)
+ goto fail;
+ if (json_object_set_new(child, "distributionPoint", dpname2json(dp->distpoint)) < 0)
+ goto fail;
+ if (json_object_set_new(child, "reasons", unimplemented(dp->reasons)) < 0)
+ goto fail;
+ if (json_object_set_new(child, "cRLIssuer", gns2json(dp->CRLissuer)) < 0)
+ goto fail;
+ }
+
+ return root;
+
+fail: json_decref(root);
+ return NULL;
}
-struct extension_metadata const *ext_ski(void)
+static void
+cdp_destroy(void *crldp)
{
- static const struct extension_metadata SKI = {
- "Subject Key Identifier",
- NID_subject_key_identifier,
- false,
- };
- return &SKI;
+ sk_DIST_POINT_pop_free(crldp, DIST_POINT_free);
}
-struct extension_metadata const *ext_aki(void)
+static const struct extension_metadata CDP = {
+ "CRL Distribution Points",
+ NID_crl_distribution_points,
+ false,
+ cdp2json,
+ cdp_destroy,
+};
+
+static json_t *
+aia2json(void const *ext)
{
- static const struct extension_metadata AKI = {
- "Authority Key Identifier",
- NID_authority_key_identifier,
- false,
- };
- return &AKI;
+ AUTHORITY_INFO_ACCESS const *ia = ext;
+ ACCESS_DESCRIPTION *ad;
+ json_t *root, *child;
+ int i;
+
+ root = json_array();
+ if (root == NULL)
+ return NULL;
+
+ for (i = 0; i < sk_ACCESS_DESCRIPTION_num(ia); i++) {
+ ad = sk_ACCESS_DESCRIPTION_value(ia, i);
+ if (json_array_append_new(root, child = json_object()) < 0)
+ goto fail;
+ if (json_object_set_new(child, "accessMethod", oid2json(ad->method)) < 0)
+ goto fail;
+ if (json_object_set_new(child, "accessLocation", gn2json(ad->location)) < 0)
+ goto fail;
+ }
+
+ return root;
+
+fail: json_decref(root);
+ return NULL;
}
-struct extension_metadata const *ext_ku(void)
+static void
+aia_destroy(void *aia)
{
- static const struct extension_metadata KU = {
- "Key Usage",
- NID_key_usage,
- true,
- };
- return &KU;
+ AUTHORITY_INFO_ACCESS_free(aia);
}
-struct extension_metadata const *ext_cdp(void)
+static const struct extension_metadata AIA = {
+ "Authority Information Access",
+ NID_info_access,
+ false,
+ aia2json,
+ aia_destroy,
+};
+
+static const struct extension_metadata SIA = {
+ "Subject Information Access",
+ NID_sinfo_access ,
+ false,
+ aia2json,
+ aia_destroy,
+};
+
+static json_t *
+pq2json(POLICYQUALINFO const *pqi)
{
- static const struct extension_metadata CDP = {
- "CRL Distribution Points",
- NID_crl_distribution_points,
- false,
- };
- return &CDP;
+ json_t *root;
+
+ if (pqi == NULL)
+ return json_null();
+
+ root = json_object();
+ if (root == NULL)
+ return NULL;
+
+ if (json_object_set_new(root, "policyQualifierId", oid2json(pqi->pqualid)) < 0)
+ goto fail;
+ if (json_object_set_new(root, "qualifier", unimplemented(&pqi->d)) < 0)
+ goto fail;
+
+ return NULL;
+
+fail: json_decref(root);
+ return NULL;
}
-struct extension_metadata const *ext_aia(void)
+static json_t *
+pqs2json(STACK_OF(POLICYQUALINFO) const *pqs)
{
- static const struct extension_metadata AIA = {
- "Authority Information Access",
- NID_info_access,
- false,
- };
- return &AIA;
+ json_t *root;
+ int i;
+
+ if (pqs == NULL)
+ return json_null();
+
+ root = json_array();
+ if (root == NULL)
+ return NULL;
+
+ for (i = 0; i < sk_POLICYQUALINFO_num(pqs); i++)
+ if (json_array_append_new(root, pq2json(sk_POLICYQUALINFO_value(pqs, i))) < 0)
+ goto fail;
+
+ return root;
+
+fail: json_decref(root);
+ return NULL;
}
-struct extension_metadata const *ext_sia(void)
+static json_t *
+pi2json(POLICYINFO const *pi)
{
- static const struct extension_metadata SIA = {
- "Subject Information Access",
- NID_sinfo_access ,
- false,
- };
- return &SIA;
+ json_t *root;
+
+ if (pi == NULL)
+ return json_null();
+
+ root = json_object();
+ if (root == NULL)
+ return NULL;
+
+ if (json_object_set_new(root, "policyIdentifier", oid2json(pi->policyid)) < 0)
+ goto fail;
+ if (json_object_set_new(root, "policyQualifiers", pqs2json(pi->qualifiers)) < 0)
+ goto fail;
+
+ return root;
+
+fail: json_decref(root);
+ return NULL;
}
-struct extension_metadata const *ext_cp(void)
+static json_t *
+cp2json(void const *ext)
{
- static const struct extension_metadata CP = {
- "Certificate Policies",
- NID_certificate_policies,
- true,
- };
- return &CP;
+ CERTIFICATEPOLICIES const *cp = ext;
+ json_t *root;
+ int i;
+
+ root = json_array();
+ if (root == NULL)
+ return NULL;
+
+ for (i = 0; i < sk_POLICYINFO_num(cp); i++)
+ if (json_array_append_new(root, pi2json(sk_POLICYINFO_value(cp, i))) < 0)
+ goto fail;
+
+ return root;
+
+fail: json_decref(root);
+ return NULL;
}
-struct extension_metadata const *ext_ir(void)
+static void
+cp_destroy(void *cp)
{
- static const struct extension_metadata IR = {
- "IP Resources",
- NID_sbgp_ipAddrBlock,
- true,
- };
- return &IR;
+ CERTIFICATEPOLICIES_free(cp);
}
-struct extension_metadata const *ext_ar(void)
+static const struct extension_metadata CP = {
+ "Certificate Policies",
+ NID_certificate_policies,
+ true,
+ cp2json,
+ cp_destroy,
+};
+
+static json_t *
+p2json(ASN1_BIT_STRING const *ap, int af)
{
- static const struct extension_metadata AR = {
- "AS Resources",
- NID_sbgp_autonomousSysNum,
- true,
- };
- return &AR;
+ unsigned char bin[16];
+ char str[INET6_ADDRSTRLEN];
+ unsigned int length;
+ json_t *root;
+
+ if (ap == NULL)
+ return json_null();
+
+ memset(bin, 0, sizeof(bin));
+ memcpy(bin, ap->data, ap->length);
+ if (inet_ntop(af, bin, str, INET6_ADDRSTRLEN) == NULL)
+ return NULL;
+
+ length = 8 * ap->length;
+ 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;
+}
+
+static json_t *
+iaor2json(IPAddressOrRange const *iaor, int af)
+{
+ json_t *root;
+
+ if (iaor == NULL)
+ return json_null();
+
+ switch (iaor->type) {
+ case IPAddressOrRange_addressPrefix:
+ return p2json(iaor->u.addressPrefix, af);
+ case IPAddressOrRange_addressRange:
+ return unimplemented(iaor->u.addressRange);
+ }
+
+ json_decref(root);
+ return NULL;
}
-struct extension_metadata const *ext_ir2(void)
+static json_t *
+iac2json(IPAddressChoice const *iac, int af)
{
- return &IR2;
+ json_t *root;
+ IPAddressOrRanges *iaor;
+ int i;
+
+ if (iac == NULL)
+ return json_null();
+
+ switch (iac->type) {
+ case IPAddressChoice_inherit:
+ return json_string("inherit");
+
+ case IPAddressChoice_addressesOrRanges:
+ iaor = iac->u.addressesOrRanges;
+ if (iaor == NULL)
+ return json_null();
+ root = json_array();
+ 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)
+ goto fail;
+ return root;
+ }
+
+ return NULL;
+
+fail: json_decref(root);
+ return NULL;
}
-struct extension_metadata const *ext_ar2(void)
+static json_t *
+iaf2json(IPAddressFamily const *iaf)
{
- return &AR2;
+ json_t *root;
+ ASN1_OCTET_STRING *af;
+ char const *family;
+ int afid;
+
+ if (iaf == NULL)
+ return json_null();
+
+ root = json_object();
+ if (root == NULL)
+ return NULL;
+
+ af = iaf->addressFamily;
+ if (af->length != 2)
+ goto fail;
+
+ if (af->data[0] == 0 && af->data[1] == 1) {
+ family = "IPv4";
+ afid = AF_INET;
+ } else if (af->data[0] == 0 && af->data[1] == 2) {
+ family = "IPv6";
+ afid = AF_INET6;
+ } else {
+ goto fail;
+ }
+
+ if (json_object_set_new(root, "addressFamily", json_string(family)) < 0)
+ goto fail;
+ if (json_object_set_new(root, "ipAddressChoice", iac2json(iaf->ipAddressChoice, afid)) < 0)
+ goto fail;
+
+ return root;
+
+fail: json_decref(root);
+ return NULL;
}
-struct extension_metadata const *ext_cn(void)
+static json_t *
+ir2json(void const *ext)
{
- static const struct extension_metadata CN = {
- "CRL Number",
- NID_crl_number,
- false,
- };
- return &CN;
+ STACK_OF(IPAddressFamily) const *iafs = ext;
+ json_t *root;
+ int i;
+
+ root = json_array();
+ if (root == NULL)
+ return NULL;
+
+ for (i = 0; i < sk_IPAddressFamily_num(iafs); i++)
+ if (json_array_append_new(root, iaf2json(sk_IPAddressFamily_value(iafs, i))) < 0)
+ goto fail;
+
+ return root;
+
+fail: json_decref(root);
+ return NULL;
+}
+
+static void
+ir_destroy(void *ir)
+{
+ sk_IPAddressFamily_pop_free(ir, IPAddressFamily_free);
+}
+
+static const struct extension_metadata IR = {
+ "IP Resources",
+ NID_sbgp_ipAddrBlock,
+ true,
+ ir2json,
+ ir_destroy,
+};
+
+static json_t *
+asr2json(ASRange const *range)
+{
+ json_t *root;
+
+ if (range == NULL)
+ return json_null();
+
+ root = json_object();
+ if (root == NULL)
+ return NULL;
+ if (json_object_set_new(root, "min", asn1int2json(range->min)) < 0)
+ goto fail;
+ if (json_object_set_new(root, "max", asn1int2json(range->max)) < 0)
+ goto fail;
+
+ return root;
+
+fail: json_decref(root);
+ return NULL;
+}
+
+static json_t *
+aor2json(ASIdOrRange const *aor)
+{
+ json_t *root;
+
+ if (aor == NULL)
+ return json_null();
+
+ switch (aor->type) {
+ case ASIdOrRange_id:
+ return asn1int2json(aor->u.id);
+ case ASIdOrRange_range:
+ return asr2json(aor->u.range);
+ }
+
+ json_decref(root);
+ return NULL;
+}
+
+static json_t *
+asidc2json(ASIdentifierChoice const *asidc)
+{
+ json_t *root;
+ ASIdOrRanges *iaor;
+ int i;
+
+ if (asidc == NULL)
+ return json_null();
+
+ switch (asidc->type) {
+ case ASIdentifierChoice_inherit:
+ return json_string("inherit");
+
+ case ASIdentifierChoice_asIdsOrRanges:
+ iaor = asidc->u.asIdsOrRanges;
+ if (iaor == NULL)
+ return json_null();
+ root = json_array();
+ if (root == NULL)
+ goto fail;
+ for (i = 0; i < sk_ASIdOrRange_num(iaor); i++)
+ if (json_array_append_new(root, aor2json(sk_ASIdOrRange_value(iaor, i))) < 0)
+ goto fail;
+ return root;
+ }
+
+ return NULL;
+
+fail: json_decref(root);
+ return NULL;
+}
+
+static json_t *
+ar2json(void const *ext)
+{
+ ASIdentifiers const *asid = ext;
+ json_t *root;
+
+ if (asid == NULL)
+ return json_null();
+
+ root = json_object();
+ if (root == NULL)
+ return NULL;
+ if (json_object_set_new(root, "asnum", asidc2json(asid->asnum)) < 0)
+ goto fail;
+ if (json_object_set_new(root, "rdi", asidc2json(asid->rdi)) < 0)
+ goto fail;
+
+ return root;
+
+fail: json_decref(root);
+ return NULL;
+}
+
+static void
+ar_destroy(void *ar)
+{
+ ASIdentifiers_free(ar);
+}
+
+static const struct extension_metadata AR = {
+ "AS Resources",
+ NID_sbgp_autonomousSysNum,
+ true,
+ ar2json,
+ ar_destroy,
+};
+
+static struct extension_metadata IR2 = {
+ "Amended IP Resources",
+ -1,
+ true,
+ ir2json,
+ ir_destroy,
+};
+
+static struct extension_metadata AR2 = {
+ "Amended AS Resources",
+ -1,
+ true,
+ ar2json,
+ ir_destroy,
+};
+
+static const struct extension_metadata CN = {
+ "CRL Number",
+ NID_crl_number,
+ false,
+};
+
+static const struct extension_metadata EKU = {
+ "Extended Key Usage",
+ NID_ext_key_usage,
+ false,
+};
+
+int extension_init(void)
+{
+ IR2.nid = nid_ipAddrBlocksv2();
+ AR2.nid = nid_autonomousSysIdsv2();
+ return 0;
}
-struct extension_metadata const *ext_eku(void)
+struct extension_metadata const *ext_bc(void) { return &BC; }
+struct extension_metadata const *ext_ski(void) { return &SKI; }
+struct extension_metadata const *ext_aki(void) { return &AKI; }
+struct extension_metadata const *ext_ku(void) { return &KU; }
+struct extension_metadata const *ext_cdp(void) { return &CDP; }
+struct extension_metadata const *ext_aia(void) { return &AIA; }
+struct extension_metadata const *ext_sia(void) { return &SIA; }
+struct extension_metadata const *ext_cp(void) { return &CP; }
+struct extension_metadata const *ext_ir(void) { return &IR; }
+struct extension_metadata const *ext_ar(void) { return &AR; }
+struct extension_metadata const *ext_ir2(void) { return &IR2; }
+struct extension_metadata const *ext_ar2(void) { return &AR2; }
+struct extension_metadata const *ext_cn(void) { return &CN; }
+struct extension_metadata const *ext_eku(void) { return &EKU; }
+
+struct extension_metadata const **
+ext_metadatas(void)
{
- static const struct extension_metadata EKU = {
- "Extended Key Usage",
- NID_ext_key_usage,
- false,
+ static struct extension_metadata const *array[] = {
+ &BC, &SKI, &AKI, &KU,
+ &CDP, &AIA, &SIA, &CP,
+ &IR, &AR, &IR2, &AR2,
+ &CN, &EKU, NULL
};
- return &EKU;
+ return array;
}
static int