aboutsummaryrefslogtreecommitdiff
path: root/rpkid/ext/POW.c
diff options
context:
space:
mode:
Diffstat (limited to 'rpkid/ext/POW.c')
-rw-r--r--rpkid/ext/POW.c49
1 files changed, 41 insertions, 8 deletions
diff --git a/rpkid/ext/POW.c b/rpkid/ext/POW.c
index 3e2ad60c..23ca662e 100644
--- a/rpkid/ext/POW.c
+++ b/rpkid/ext/POW.c
@@ -599,7 +599,8 @@ X509_object_helper_set_name(X509_NAME *name, PyObject *dn_obj)
asn1_type = V_ASN1_UTF8STRING;
if (!X509_NAME_add_entry_by_txt(name, type_str, asn1_type,
- value_str, strlen(value_str), -1, j > 0))
+ value_str, strlen(value_str),
+ -1, (j ? -1 : 0)))
lose("unable to add name entry");
Py_XDECREF(pair_obj);
@@ -627,10 +628,18 @@ X509_object_helper_get_name(X509_NAME *name, int format)
{
X509_NAME_ENTRY *entry = NULL;
PyObject *result = NULL;
+ PyObject *rdn = NULL;
PyObject *item = NULL;
const char *oid = NULL;
char oidbuf[512];
- int i;
+ int i, set = -1;
+
+ /*
+ * Overall theory here: multi-value RDNs are very rare in the wild.
+ * We should support them, so we don't throw an exception if handed
+ * one in a BPKI certificate, but with minimal effort. What we care
+ * about here is optimizing for the common case of single-valued RDNs.
+ */
if ((result = PyTuple_New(X509_NAME_entry_count(name))) == NULL)
lose("could not allocate memory");
@@ -640,8 +649,8 @@ X509_object_helper_get_name(X509_NAME *name, int format)
if ((entry = X509_NAME_get_entry(name, i)) == NULL)
lose("could not get certificate name");
- if (entry->set != i)
- lose("sorry, this code does not support multi-value RDNs yet");
+ if (entry->set < 0 || entry->set < set || entry->set > set + 1)
+ lose("X509_NAME->set value out of expected range");
switch (format) {
case SHORTNAME_FORMAT:
@@ -663,16 +672,40 @@ X509_object_helper_get_name(X509_NAME *name, int format)
oid = oidbuf;
}
- if ((item = Py_BuildValue("((ss#))", oid, entry->value->data, entry->value->length)) == NULL)
- goto error;
+ if (entry->set > set) {
+
+ set++;
+ if ((item = Py_BuildValue("((ss#))", oid, entry->value->data, entry->value->length)) == NULL)
+ goto error;
+ PyTuple_SET_ITEM(result, set, item);
+ item = NULL;
+
+ } else {
+
+ if ((rdn = PyTuple_GetItem(result, set)) == NULL)
+ goto error;
+ (void) _PyTuple_Resize(&rdn, PyTuple_Size(rdn) + 1);
+ PyTuple_SET_ITEM(result, set, rdn);
+ if (rdn == NULL)
+ goto error;
+ if ((item = Py_BuildValue("(ss#)", oid, entry->value->data, entry->value->length)) == NULL)
+ goto error;
+ PyTuple_SetItem(rdn, PyTuple_Size(rdn) - 1, item);
+ rdn = item = NULL;
+
+ }
+ }
- PyTuple_SET_ITEM(result, i, item);
- item = NULL;
+ if (++set != PyTuple_Size(result)) {
+ if (set < 0 || set > PyTuple_Size(result))
+ lose("impossible set count for DN, something went horribly wrong");
+ _PyTuple_Resize(&result, set);
}
return result;
error:
+ Py_XDECREF(item);
Py_XDECREF(result);
return NULL;
}