[rs-commit] r100 - in /redwax-tool/trunk: redwax_openssl.c redwax_util.c redwax_util.h
rs-commit at redwax.eu
rs-commit at redwax.eu
Wed Dec 1 21:51:36 CET 2021
Author: minfrin at redwax.eu
Date: Wed Dec 1 21:51:35 2021
New Revision: 100
Log:
Add output for some X509v3Extensions.
Modified:
redwax-tool/trunk/redwax_openssl.c
redwax-tool/trunk/redwax_util.c
redwax-tool/trunk/redwax_util.h
Modified: redwax-tool/trunk/redwax_openssl.c
==============================================================================
--- redwax-tool/trunk/redwax_openssl.c (original)
+++ redwax-tool/trunk/redwax_openssl.c Wed Dec 1 21:51:35 2021
@@ -2513,7 +2513,7 @@
cn = X509_NAME_ENTRY_get_data(e);
if ((lbio = BIO_new(BIO_s_mem())) == NULL) {
- return 0;
+ return APR_ENOMEM;
}
ASN1_STRING_print_ex(lbio, cn, ASN1_STRFLGS_ESC_2253 |
@@ -2569,8 +2569,8 @@
redwax_metadata_push_object(m, "SubjectPublicKeyInfo", 0);
- if ((bio = BIO_new(BIO_s_mem())) == NULL) {
- return 0;
+ if (!(bio = BIO_new(BIO_s_mem()))) {
+ return APR_ENOMEM;
}
i2a_ASN1_OBJECT(bio, xpoid);
@@ -2594,25 +2594,471 @@
return APR_SUCCESS;
}
-static apr_status_t redwax_openssl_extensions_metadata(redwax_tool_t *r,
- redwax_metadata_t *m, const STACK_OF(X509_EXTENSION) *xe)
-{
-
- return APR_ENOTIMPL;
-}
-
-static apr_status_t redwax_openssl_signature_metadata(redwax_tool_t *r,
- redwax_metadata_t *m, const X509_ALGOR *sig_alg, const ASN1_BIT_STRING *sig)
-{
+static apr_status_t redwax_openssl_general_name_metadata(redwax_tool_t *r,
+ redwax_metadata_t *m, GENERAL_NAME *gen)
+{
+ BIO *bio;
+
+ const char *key = NULL;
+ const char *okey = NULL;
+
+ if (!(bio = BIO_new(BIO_s_mem()))) {
+ return APR_ENOMEM;
+ }
+
+ switch (gen->type) {
+ case GEN_OTHERNAME: {
+
+ int nid;
+
+ nid = OBJ_obj2nid(gen->d.otherName->type_id);
+
+ if ((nid == NID_SRVName
+ && gen->d.otherName->value->type != V_ASN1_IA5STRING)
+ || (nid != NID_SRVName
+ && gen->d.otherName->value->type != V_ASN1_UTF8STRING)) {
+
+ redwax_print_error(r, "metadata-out: unsupported othername with nid %d, ignoring\n",
+ nid);
+
+ break;
+ }
+
+ switch (nid) {
+ case NID_id_on_SmtpUTF8Mailbox:
+ key = "OtherName";
+ okey = "SmtpUTF8Mailbox";
+ BIO_printf(bio, "%s",
+ gen->d.otherName->value->value.utf8string->data);
+ break;
+ case NID_XmppAddr:
+ key = "OtherName";
+ okey = "XmppAddr";
+ BIO_printf(bio, "%s",
+ gen->d.otherName->value->value.utf8string->data);
+ break;
+ case NID_SRVName:
+ key = "OtherName";
+ okey = "SRVName";
+ BIO_printf(bio, "%s",
+ gen->d.otherName->value->value.ia5string->data);
+ break;
+ case NID_ms_upn:
+ key = "OtherName";
+ okey = "UPN";
+ BIO_printf(bio, "%s",
+ gen->d.otherName->value->value.utf8string->data);
+ break;
+ case NID_NAIRealm:
+ key = "OtherName";
+ okey = "NAIRealm";
+ BIO_printf(bio, "%s",
+ gen->d.otherName->value->value.utf8string->data);
+ break;
+ default:
+
+ redwax_print_error(r, "metadata-out: unsupported othername with nid %d, ignoring\n",
+ nid);
+
+ break;
+ }
+ break;
+ }
+ case GEN_X400: {
+
+ /* X400Name unsupported */
+ redwax_print_error(r, "metadata-out: unsupported X400Name, ignoring\n");
+
+ break;
+ }
+ case GEN_EDIPARTY: {
+
+ /* EdiPartyName unsupported */
+ /* Maybe fix this: it is supported now */
+ redwax_print_error(r, "metadata-out: unsupported EdiPartyName, ignoring\n");
+
+ break;
+ }
+ case GEN_EMAIL: {
+ key = "Email";
+ ASN1_STRING_print(bio, gen->d.ia5);
+ break;
+ }
+ case GEN_DNS: {
+ key = "DNS";
+ ASN1_STRING_print(bio, gen->d.ia5);
+ break;
+ }
+ case GEN_URI: {
+ key = "URI";
+ ASN1_STRING_print(bio, gen->d.ia5);
+ break;
+ }
+ case GEN_DIRNAME: {
+ key = "DirName";
+ X509_NAME_print_ex(bio, gen->d.dirn, 0, XN_FLAG_ONELINE);
+ break;
+ }
+ case GEN_IPADD: {
+
+ unsigned char *p;
+ int i;
+
+ p = gen->d.ip->data;
+ if (gen->d.ip->length == 4) {
+ key = "IPAddress";
+ BIO_printf(bio, "%d.%d.%d.%d", p[0], p[1], p[2], p[3]);
+ }
+ else if (gen->d.ip->length == 16) {
+ key = "IPAddress";
+ for (i = 0; i < 8; i++) {
+ if (i) {
+ BIO_puts(bio, ":");
+ }
+ BIO_printf(bio, "%X", p[0] << 8 | p[1]);
+ p += 2;
+ }
+ }
+ break;
+ }
+ case GEN_RID: {
+ key = "RegisteredID";
+ i2a_ASN1_OBJECT(bio, gen->d.rid);
+ break;
+ }
+ }
+
+ if (key) {
+
+ char *buf = NULL;
+ int len = 0;
+
+ len = BIO_get_mem_data(bio, &buf);
+
+ if (okey) {
+ redwax_metadata_push_object(m, key, 0);
+ redwax_metadata_add_string(m, okey,
+ apr_psprintf(m->pool, "%.*s", len, buf));
+ redwax_metadata_pop_object(m);
+ }
+ else {
+ redwax_metadata_add_string(m, key,
+ apr_psprintf(m->pool, "%.*s", len, buf));
+ }
+ }
+
+ BIO_free(bio);
+
+ return APR_SUCCESS;
+}
+
+static BIT_STRING_BITNAME ns_cert_type_table[] = {
+ {0, "SSL Client", "client"},
+ {1, "SSL Server", "server"},
+ {2, "S/MIME", "email"},
+ {3, "Object Signing", "objsign"},
+ {4, "Unused", "reserved"},
+ {5, "SSL CA", "sslCA"},
+ {6, "S/MIME CA", "emailCA"},
+ {7, "Object Signing CA", "objCA"},
+ {-1, NULL, NULL}
+};
+
+static BIT_STRING_BITNAME key_usage_type_table[] = {
+ {0, "Digital Signature", "digitalSignature"},
+ {1, "Non Repudiation", "nonRepudiation"},
+ {2, "Key Encipherment", "keyEncipherment"},
+ {3, "Data Encipherment", "dataEncipherment"},
+ {4, "Key Agreement", "keyAgreement"},
+ {5, "Certificate Sign", "keyCertSign"},
+ {6, "CRL Sign", "cRLSign"},
+ {7, "Encipher Only", "encipherOnly"},
+ {8, "Decipher Only", "decipherOnly"},
+ {-1, NULL, NULL}
+};
+
+static apr_status_t redwax_openssl_extension_metadata(redwax_tool_t *r,
+ redwax_metadata_t *m, X509_EXTENSION *ex)
+{
+ ASN1_OBJECT *obj;
BIO *bio;
char *buf = NULL;
int len = 0;
+ int crit, nid;
+
+ obj = X509_EXTENSION_get_object(ex);
+
+ if ((bio = BIO_new(BIO_s_mem())) == NULL) {
+ return APR_ENOMEM;
+ }
+
+ i2a_ASN1_OBJECT(bio, obj);
+
+ len = BIO_get_mem_data(bio, &buf);
+
+ redwax_metadata_push_object(m, apr_pstrip_whitespace(m->pool, buf, len), 0);
+
+ BIO_free(bio);
+
+ crit = X509_EXTENSION_get_critical(ex);
+ if (crit) {
+ redwax_metadata_add_boolean(m, "Critical", 1);
+ }
+
+ nid = OBJ_obj2nid(obj);
+ switch (nid) {
+ case NID_basic_constraints: {
+
+ BASIC_CONSTRAINTS *bs = X509V3_EXT_d2i(ex);
+
+ if (bs) {
+
+ redwax_metadata_add_boolean(m, "CA", bs->ca);
+
+ if (bs->pathlen) {
+ if ((bs->pathlen->type == V_ASN1_NEG_INTEGER) || !bs->ca) {
+ redwax_metadata_add_boolean(m, "InvalidPathLength", 1);
+ } else {
+ redwax_metadata_add_long(m, "PathLength",
+ ASN1_INTEGER_get(bs->pathlen));
+ }
+ }
+
+ BASIC_CONSTRAINTS_free(bs);
+ }
+
+ break;
+ }
+ case NID_key_usage: {
+
+ ASN1_BIT_STRING *usage = X509V3_EXT_d2i(ex);
+ apr_uint32_t ex_kusage;
+
+ int i, usages = 0;
+
+ if (usage->length > 0) {
+ ex_kusage = usage->data[0];
+ if (usage->length > 1)
+ ex_kusage |= usage->data[1] << 8;
+ }
+ else {
+ ex_kusage = 0;
+ }
+
+ for (i = 0; key_usage_type_table[i].lname; i++) {
+ if ((ex_kusage >> i) & 1) {
+ usages++;
+ }
+ }
+
+ if (usages) {
+
+ redwax_metadata_push_array(m, "KeyUsages", 0);
+
+ for (i = 0; key_usage_type_table[i].sname; i++) {
+ if ((ex_kusage >> i) & 1) {
+ redwax_metadata_add_string(m, "KeyUsage",
+ key_usage_type_table[i].sname);
+ }
+ }
+
+ redwax_metadata_pop_array(m);
+ }
+
+ ASN1_BIT_STRING_free(usage);
+
+ break;
+ }
+ case NID_ext_key_usage: {
+
+ EXTENDED_KEY_USAGE *eku = X509V3_EXT_d2i(ex);
+
+ int i;
+
+ if (sk_ASN1_OBJECT_num(eku)) {
+
+ redwax_metadata_push_array(m, "ExtendedKeyUsages", 0);
+
+ for (i = 0; i < sk_ASN1_OBJECT_num(eku); i++) {
+
+ char obj_tmp[80];
+ ASN1_OBJECT *obj;
+
+ obj = sk_ASN1_OBJECT_value(eku, i);
+ i2t_ASN1_OBJECT(obj_tmp, sizeof(obj_tmp), obj);
+
+ redwax_metadata_add_string(m, "ExtendedKeyUsage",
+ key_usage_type_table[i].sname);
+
+ }
+
+ redwax_metadata_pop_array(m);
+ }
+
+ sk_ASN1_OBJECT_pop_free(eku, ASN1_OBJECT_free);
+
+ break;
+ }
+ case NID_netscape_cert_type: {
+
+ ASN1_BIT_STRING *nscert = X509V3_EXT_d2i(ex);
+ apr_uint32_t ex_nscert;
+
+ int i, nscerts = 0;
+
+ if (nscert->length > 0) {
+ ex_nscert = nscert->data[0];
+ if (nscert->length > 1)
+ ex_nscert |= nscert->data[1] << 8;
+ }
+ else {
+ ex_nscert = 0;
+ }
+
+ for (i = 0; ns_cert_type_table[i].lname; i++) {
+ if ((ex_nscert >> i) & 1) {
+ nscerts++;
+ }
+ }
+
+ if (nscerts) {
+
+ redwax_metadata_push_array(m, "CertificateTypes", 0);
+
+ for (i = 0; ns_cert_type_table[i].sname; i++) {
+ if ((ex_nscert >> i) & 1) {
+ redwax_metadata_add_string(m, "CertificateType",
+ ns_cert_type_table[i].sname);
+ }
+ }
+
+ redwax_metadata_pop_array(m);
+ }
+
+ ASN1_BIT_STRING_free(nscert);
+
+ break;
+ }
+ case NID_info_access:
+ case NID_sinfo_access: {
+
+ AUTHORITY_INFO_ACCESS *ainfo = X509V3_EXT_d2i(ex);
+
+ int i;
+
+ if (sk_ACCESS_DESCRIPTION_num(ainfo)) {
+
+ redwax_metadata_push_array(m, "Accesses", 0);
+
+ for (i = 0; i < sk_ACCESS_DESCRIPTION_num(ainfo); i++) {
+
+ char objtmp[80];
+ ACCESS_DESCRIPTION *desc;
+
+ desc = sk_ACCESS_DESCRIPTION_value(ainfo, i);
+ i2t_ASN1_OBJECT(objtmp, sizeof(objtmp), desc->method);
+
+ redwax_metadata_push_object(m, "Access", 0);
+ redwax_metadata_push_object(m,
+ apr_pstrip_whitespace(m->pool, objtmp, strlen(objtmp)),
+ 0);
+
+ redwax_openssl_general_name_metadata(r, m, desc->location);
+
+ redwax_metadata_pop_object(m);
+ redwax_metadata_pop_object(m);
+ }
+
+ redwax_metadata_pop_array(m);
+ }
+
+ AUTHORITY_INFO_ACCESS_free(ainfo);
+
+ break;
+ }
+ case NID_subject_alt_name:
+ case NID_issuer_alt_name:
+ case NID_certificate_issuer: {
+
+ GENERAL_NAMES *gens = X509V3_EXT_d2i(ex);
+
+ int i;
+
+ if (sk_GENERAL_NAME_num(gens)) {
+
+ redwax_metadata_push_array(m, "Names", 0);
+
+ for (i = 0; i < sk_GENERAL_NAME_num(gens); i++) {
+
+ GENERAL_NAME *gen;
+
+ gen = sk_GENERAL_NAME_value(gens, i);
+
+ redwax_metadata_push_object(m, "Name", 0);
+ redwax_openssl_general_name_metadata(r, m, gen);
+ redwax_metadata_pop_object(m);
+ }
+
+ redwax_metadata_pop_array(m);
+ }
+
+ break;
+ }
+ default:
+
+ /*
+ * Unknown extensions - we print they exist, but print no contents.
+ *
+ * This allows us to fill in contents at a future date without
+ * changing the existing format.
+ */
+
+ break;
+ }
+
+ redwax_metadata_pop_object(m);
+
+ return APR_SUCCESS;
+}
+
+static apr_status_t redwax_openssl_extensions_metadata(redwax_tool_t *r,
+ redwax_metadata_t *m, const STACK_OF(X509_EXTENSION) *exts)
+{
+ int i;
+
+ redwax_metadata_push_object(m, "X509v3Extensions", !sk_X509_EXTENSION_num(exts));
+
+ for (i = 0; i < sk_X509_EXTENSION_num(exts); i++) {
+
+ X509_EXTENSION *ex;
+
+ ex = sk_X509_EXTENSION_value(exts, i);
+
+ if (ex) {
+ redwax_openssl_extension_metadata(r, m, ex);
+ }
+
+ }
+
+ redwax_metadata_pop_object(m);
+
+ return APR_SUCCESS;
+}
+
+static apr_status_t redwax_openssl_signature_metadata(redwax_tool_t *r,
+ redwax_metadata_t *m, const X509_ALGOR *sig_alg, const ASN1_BIT_STRING *sig)
+{
+
+ BIO *bio;
+ char *buf = NULL;
+ int len = 0;
+
if (sig_alg) {
if ((bio = BIO_new(BIO_s_mem())) == NULL) {
- return 0;
+ return APR_ENOMEM;
}
i2a_ASN1_OBJECT(bio, sig_alg->algorithm);
@@ -2720,7 +3166,7 @@
int len = 0;
if ((bio = BIO_new(BIO_s_mem())) == NULL) {
- return 0;
+ return APR_ENOMEM;
}
ASN1_TIME_print(bio, tm);
@@ -2742,7 +3188,7 @@
int len = 0;
if ((bio = BIO_new(BIO_s_mem())) == NULL) {
- return 0;
+ return APR_ENOMEM;
}
ASN1_TIME_print(bio, tm);
Modified: redwax-tool/trunk/redwax_util.c
==============================================================================
--- redwax-tool/trunk/redwax_util.c (original)
+++ redwax-tool/trunk/redwax_util.c Wed Dec 1 21:51:35 2021
@@ -824,6 +824,76 @@
return NULL;
}
+apr_status_t redwax_strip_whitespace(char *escaped, const char *str,
+ apr_size_t slen, apr_size_t *len)
+{
+ apr_size_t size = 1;
+ int found = 0;
+ const unsigned char *s = (const unsigned char *) str;
+ unsigned char *d = (unsigned char *) escaped;
+ unsigned c;
+
+ if (slen == REDWAX_ESCAPE_STRING) {
+ slen = strlen(str);
+ }
+
+ if (s) {
+ if (d) {
+ while ((c = *s) && slen) {
+ if (apr_isspace(c)) {
+ found = 1;
+ }
+ else {
+ *d++ = c;
+ size++;
+ }
+ ++s;
+ slen--;
+ }
+ *d = '\0';
+ }
+ else {
+ while ((c = *s) && slen) {
+ if (apr_isspace(c)) {
+ found = 1;
+ }
+ else {
+ size++;
+ }
+ ++s;
+ slen--;
+ }
+ }
+ }
+
+ if (len) {
+ *len = size;
+ }
+ if (!found) {
+ return APR_NOTFOUND;
+ }
+
+ return APR_SUCCESS;
+}
+
+const char* apr_pstrip_whitespace(apr_pool_t *p, const char *str, apr_size_t slen)
+{
+ apr_size_t len;
+
+ switch (redwax_strip_whitespace(NULL, str, slen, &len)) {
+ case APR_SUCCESS: {
+ char *cmd = apr_palloc(p, len);
+ redwax_strip_whitespace(cmd, str, slen, NULL);
+ return cmd;
+ }
+ case APR_NOTFOUND: {
+ break;
+ }
+ }
+
+ return str;
+}
+
#define XML_PREAMBLE "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
static apr_status_t cleanup_metadata(void *dummy)
@@ -1647,3 +1717,126 @@
return APR_SUCCESS;
}
+
+apr_status_t redwax_metadata_add_number(redwax_metadata_t *m, const char *key,
+ void *v, apr_size_t vlen)
+{
+ redwax_metadata_level_t *ml = m->level;
+
+ apr_status_t status = APR_SUCCESS;
+
+ void *k = (void *)key;
+ int klen = k ? strlen(k) : 0;
+
+ int array = ml->array;
+ int object = ml->object;
+ int next = ml->next;
+
+ ml->next = 1;
+
+ redwax_metadata_prefix(m, 1);
+
+ switch (m->format) {
+ case REDWAX_FORMAT_TEXT:
+ break;
+ case REDWAX_FORMAT_XML: {
+
+ const struct iovec vec[] = {
+ {"\n", 1},
+ {m->object_prefix, m->prefix_len},
+ {"<", 1},
+ {k, klen},
+ {">", 1},
+ {v, vlen},
+ {"</", 2},
+ {k, klen},
+ {">", 1},
+ };
+
+ status = m->wv(m->ctx, vec, 9);
+
+ break;
+ }
+ case REDWAX_FORMAT_JSON: {
+
+ if (object) {
+
+ const struct iovec vec[] = {
+ {next ? "," : "", next ? 1 : 0},
+ {"\n", 1},
+ {m->object_prefix, m->prefix_len},
+ {"\"", 1},
+ {k, klen},
+ {"\": ", 3},
+ {v, vlen}
+ };
+
+ status = m->wv(m->ctx, vec, 7);
+ }
+
+ else if (array) {
+
+ const struct iovec vec[] = {
+ {next ? "," : "", next ? 1 : 0},
+ {"\n", 1},
+ {m->object_prefix, m->prefix_len},
+ {v, vlen}
+ };
+
+ status = m->wv(m->ctx, vec, 4);
+ }
+
+ break;
+ }
+ case REDWAX_FORMAT_YAML: {
+
+ if (object) {
+
+ const struct iovec vec[] = {
+ {"\n", 1},
+ {m->object_prefix, m->prefix_len},
+ {k, klen},
+ {": ", 2},
+ {v, vlen}
+ };
+
+ status = m->wv(m->ctx, vec, 5);
+ }
+
+ else if (array) {
+
+ const struct iovec vec[] = {
+ {"\n", 1},
+ {m->array_prefix, m->prefix_len},
+ {v, vlen}
+ };
+
+ status = m->wv(m->ctx, vec, 3);
+ }
+
+ break;
+ }
+ default:
+ break;
+ }
+
+ redwax_metadata_prefix(m, -1);
+
+ return APR_SUCCESS;
+}
+
+apr_status_t redwax_metadata_add_long(redwax_metadata_t *m, const char *key, long val)
+{
+ void *v = apr_itoa(m->pool, val);
+ int vlen = v ? strlen(v) : 0;
+
+ return redwax_metadata_add_number(m, key, v, vlen);
+}
+
+apr_status_t redwax_metadata_add_boolean(redwax_metadata_t *m, const char *key, int val)
+{
+ void *v = val ? "true" : "false";
+ int vlen = v ? strlen(v) : 0;
+
+ return redwax_metadata_add_number(m, key, v, vlen);
+}
Modified: redwax-tool/trunk/redwax_util.h
==============================================================================
--- redwax-tool/trunk/redwax_util.h (original)
+++ redwax-tool/trunk/redwax_util.h Wed Dec 1 21:51:35 2021
@@ -63,6 +63,11 @@
const char* redwax_pencode_base16_binary(apr_pool_t *p,
const unsigned char *src, apr_ssize_t slen, int flags, apr_size_t *len);
+apr_status_t redwax_strip_whitespace(char *escaped, const char *str,
+ apr_size_t slen, apr_size_t *len);
+
+const char* apr_pstrip_whitespace(apr_pool_t *p, const char *str, apr_size_t slen);
+
#define REDWAX_ESCAPE_STRING -1
/**
@@ -125,4 +130,11 @@
apr_status_t redwax_metadata_add_string(redwax_metadata_t *m, const char *k, const char *v);
+apr_status_t redwax_metadata_add_number(redwax_metadata_t *m, const char *key,
+ void *v, apr_size_t vlen);
+
+apr_status_t redwax_metadata_add_long(redwax_metadata_t *m, const char *key, long val);
+
+apr_status_t redwax_metadata_add_boolean(redwax_metadata_t *m, const char *key, int val);
+
#endif
More information about the rs-commit
mailing list