From 49e96055224e94f392e231e0a69aa6483dc28722 Mon Sep 17 00:00:00 2001 From: Rob Austein Date: Tue, 28 Jan 2014 04:03:40 +0000 Subject: Add ExtendedKeyUsage, refactor extension handling code. svn path=/branches/tk671/; revision=5649 --- rpkid/ext/POW.c | 1207 ++++++++++++++++++++++++++----------------------------- 1 file changed, 579 insertions(+), 628 deletions(-) (limited to 'rpkid/ext/POW.c') diff --git a/rpkid/ext/POW.c b/rpkid/ext/POW.c index 05007135..3d662fbc 100644 --- a/rpkid/ext/POW.c +++ b/rpkid/ext/POW.c @@ -1047,6 +1047,464 @@ ASN1_OBJECT_to_PyString(const ASN1_OBJECT *oid) +/* + * Extension functions. + */ + +static PyObject * +extension_get_key_usage(STACK_OF(X509_EXTENSION) **exts) +{ + ASN1_BIT_STRING *ext = NULL; + PyObject *result = NULL; + PyObject *token = NULL; + int bit = -1; + + ENTERING(extension_get_key_usage); + + if (!exts) + lose("Missing extensions"); + + if ((ext = X509V3_get_d2i(*exts, NID_key_usage, NULL, NULL)) == NULL) + Py_RETURN_NONE; + + if ((result = PyFrozenSet_New(NULL)) == NULL) + goto error; + + for (bit = 0; key_usage_bit_names[bit] != NULL; bit++) { + if (ASN1_BIT_STRING_get_bit(ext, bit) && + ((token = PyString_FromString(key_usage_bit_names[bit])) == NULL || + PySet_Add(result, token) < 0)) + goto error; + Py_XDECREF(token); + token = NULL; + } + + ASN1_BIT_STRING_free(ext); + return result; + + error: + ASN1_BIT_STRING_free(ext); + Py_XDECREF(token); + Py_XDECREF(result); + return NULL; +} + +static PyObject * +extension_set_key_usage(STACK_OF(X509_EXTENSION) **exts, PyObject *args) +{ + ASN1_BIT_STRING *ext = NULL; + PyObject *iterable = NULL; + PyObject *critical = Py_True; + PyObject *iterator = NULL; + PyObject *item = NULL; + const char *token; + int bit = -1; + int ok = 0; + + ENTERING(extension_set_key_usage); + + if (!exts) + lose("Missing extensions"); + + if ((ext = ASN1_BIT_STRING_new()) == NULL) + lose_no_memory(); + + if (!PyArg_ParseTuple(args, "O|O", &iterable, &critical) || + (iterator = PyObject_GetIter(iterable)) == NULL) + goto error; + + while ((item = PyIter_Next(iterator)) != NULL) { + + if ((token = PyString_AsString(item)) == NULL) + goto error; + + for (bit = 0; key_usage_bit_names[bit] != NULL; bit++) + if (!strcmp(token, key_usage_bit_names[bit])) + break; + + if (key_usage_bit_names[bit] == NULL) + lose("Unrecognized KeyUsage token"); + + if (!ASN1_BIT_STRING_set_bit(ext, bit, 1)) + lose_no_memory(); + + Py_XDECREF(item); + item = NULL; + } + + if (!X509V3_add1_i2d(exts, NID_key_usage, ext, + PyObject_IsTrue(critical), + X509V3_ADD_REPLACE)) + lose_openssl_error("Couldn't add KeyUsage extension to OpenSSL object"); + + ok = 1; + + error: /* Fall through */ + ASN1_BIT_STRING_free(ext); + Py_XDECREF(iterator); + Py_XDECREF(item); + + if (ok) + Py_RETURN_NONE; + else + return NULL; +} + +static PyObject * +extension_get_basic_constraints(STACK_OF(X509_EXTENSION) **exts) +{ + BASIC_CONSTRAINTS *ext = NULL; + PyObject *result = NULL; + + ENTERING(extension_get_basic_constraints); + + if (!exts) + lose("Missing extensions"); + + if ((ext = X509V3_get_d2i(*exts, NID_basic_constraints, NULL, NULL)) == NULL) + Py_RETURN_NONE; + + if (ext->pathlen == NULL) + result = Py_BuildValue("(NO)", PyBool_FromLong(ext->ca), Py_None); + else + result = Py_BuildValue("(Nl)", PyBool_FromLong(ext->ca), ASN1_INTEGER_get(ext->pathlen)); + + error: + BASIC_CONSTRAINTS_free(ext); + return result; +} + +static PyObject * +extension_set_basic_constraints(STACK_OF(X509_EXTENSION) **exts, PyObject *args) +{ + BASIC_CONSTRAINTS *ext = NULL; + PyObject *is_ca = NULL; + PyObject *pathlen_obj = Py_None; + PyObject *critical = Py_True; + long pathlen = -1; + int ok = 0; + + ENTERING(extension_set_basic_constraints); + + if (!exts) + lose("Missing extensions"); + + if (!PyArg_ParseTuple(args, "O|OO", &is_ca, &pathlen_obj, &critical)) + goto error; + + if (pathlen_obj != Py_None && (pathlen = PyInt_AsLong(pathlen_obj)) < 0) + lose_type_error("Bad pathLenConstraint value"); + + if ((ext = BASIC_CONSTRAINTS_new()) == NULL) + lose_no_memory(); + + ext->ca = PyObject_IsTrue(is_ca) ? 0xFF : 0; + + if (pathlen_obj != Py_None && + ((ext->pathlen == NULL && (ext->pathlen = ASN1_INTEGER_new()) == NULL) || + !ASN1_INTEGER_set(ext->pathlen, pathlen))) + lose_no_memory(); + + if (!X509V3_add1_i2d(exts, NID_basic_constraints, ext, + PyObject_IsTrue(critical), X509V3_ADD_REPLACE)) + lose_openssl_error("Couldn't add BasicConstraints extension to OpenSSL object"); + + ok = 1; + + error: + BASIC_CONSTRAINTS_free(ext); + + if (ok) + Py_RETURN_NONE; + else + return NULL; +} + +static PyObject * +extension_get_sia(STACK_OF(X509_EXTENSION) **exts) +{ + AUTHORITY_INFO_ACCESS *ext = NULL; + PyObject *result = NULL; + PyObject *result_caRepository = NULL; + PyObject *result_rpkiManifest = NULL; + PyObject *result_signedObject = NULL; + int n_caRepository = 0; + int n_rpkiManifest = 0; + int n_signedObject = 0; + const char *uri; + PyObject *obj; + int i, nid; + + ENTERING(pkcs10_object_get_sia); + + if (!exts) + lose("Missing extensions"); + + if ((ext = X509V3_get_d2i(*exts, NID_sinfo_access, NULL, NULL)) == NULL) + Py_RETURN_NONE; + + /* + * Easiest to do this in two passes, first pass just counts URIs. + */ + + for (i = 0; i < sk_ACCESS_DESCRIPTION_num(ext); i++) { + ACCESS_DESCRIPTION *a = sk_ACCESS_DESCRIPTION_value(ext, i); + if (a->location->type != GEN_URI) + continue; + nid = OBJ_obj2nid(a->method); + if (nid == NID_caRepository) { + n_caRepository++; + continue; + } + if (nid == NID_rpkiManifest) { + n_rpkiManifest++; + continue; + } + if (nid == NID_signedObject) { + n_signedObject++; + continue; + } + } + + if (((result_caRepository = PyTuple_New(n_caRepository)) == NULL) || + ((result_rpkiManifest = PyTuple_New(n_rpkiManifest)) == NULL) || + ((result_signedObject = PyTuple_New(n_signedObject)) == NULL)) + goto error; + + n_caRepository = n_rpkiManifest = n_signedObject = 0; + + for (i = 0; i < sk_ACCESS_DESCRIPTION_num(ext); i++) { + ACCESS_DESCRIPTION *a = sk_ACCESS_DESCRIPTION_value(ext, i); + if (a->location->type != GEN_URI) + continue; + nid = OBJ_obj2nid(a->method); + uri = (char *) ASN1_STRING_data(a->location->d.uniformResourceIdentifier); + if (nid == NID_caRepository) { + if ((obj = PyString_FromString(uri)) == NULL) + goto error; + PyTuple_SET_ITEM(result_caRepository, n_caRepository++, obj); + continue; + } + if (nid == NID_rpkiManifest) { + if ((obj = PyString_FromString(uri)) == NULL) + goto error; + PyTuple_SET_ITEM(result_rpkiManifest, n_rpkiManifest++, obj); + continue; + } + if (nid == NID_signedObject) { + if ((obj = PyString_FromString(uri)) == NULL) + goto error; + PyTuple_SET_ITEM(result_signedObject, n_signedObject++, obj); + continue; + } + } + + result = Py_BuildValue("(OOO)", + result_caRepository, + result_rpkiManifest, + result_signedObject); + + error: + AUTHORITY_INFO_ACCESS_free(ext); + Py_XDECREF(result_caRepository); + Py_XDECREF(result_rpkiManifest); + Py_XDECREF(result_signedObject); + return result; +} + +static PyObject * +extension_set_sia(STACK_OF(X509_EXTENSION) **exts, PyObject *args, PyObject *kwds) +{ + static char *kwlist[] = {"caRepository", "rpkiManifest", "signedObject", NULL}; + AUTHORITY_INFO_ACCESS *ext = NULL; + PyObject *caRepository = Py_None; + PyObject *rpkiManifest = Py_None; + PyObject *signedObject = Py_None; + PyObject *iterator = NULL; + ASN1_OBJECT *oid = NULL; + PyObject **pobj = NULL; + PyObject *item = NULL; + ACCESS_DESCRIPTION *a = NULL; + int i, nid = NID_undef, ok = 0; + Py_ssize_t urilen; + char *uri; + + ENTERING(extension_set_sia); + + if (!exts) + lose("Missing extensions"); + + if (!PyArg_ParseTupleAndKeywords(args, kwds, "|OOO", kwlist, + &caRepository, &rpkiManifest, &signedObject)) + goto error; + + if ((ext = AUTHORITY_INFO_ACCESS_new()) == NULL) + lose_no_memory(); + + /* + * This is going to want refactoring, because it's ugly, because we + * want to reuse code for AIA, and because it'd be nice to support a + * single URI as an abbreviation for a collection containing one URI. + */ + + for (i = 0; i < 3; i++) { + switch (i) { + case 0: pobj = &caRepository; nid = NID_caRepository; break; + case 1: pobj = &rpkiManifest; nid = NID_rpkiManifest; break; + case 2: pobj = &signedObject; nid = NID_signedObject; break; + } + + if (*pobj == Py_None) + continue; + + if ((oid = OBJ_nid2obj(nid)) == NULL) + lose_openssl_error("Couldn't find SIA accessMethod OID"); + + if ((iterator = PyObject_GetIter(*pobj)) == NULL) + goto error; + + while ((item = PyIter_Next(iterator)) != NULL) { + + if (PyString_AsStringAndSize(item, &uri, &urilen) < 0) + goto error; + + if ((a = ACCESS_DESCRIPTION_new()) == NULL || + (a->method = OBJ_dup(oid)) == NULL || + (a->location->d.uniformResourceIdentifier = ASN1_IA5STRING_new()) == NULL || + !ASN1_OCTET_STRING_set(a->location->d.uniformResourceIdentifier, (unsigned char *) uri, urilen)) + lose_no_memory(); + + a->location->type = GEN_URI; + + if (!sk_ACCESS_DESCRIPTION_push(ext, a)) + lose_no_memory(); + + a = NULL; + Py_XDECREF(item); + item = NULL; + } + + Py_XDECREF(iterator); + iterator = NULL; + } + + if (!X509V3_add1_i2d(exts, NID_sinfo_access, ext, 0, X509V3_ADD_REPLACE)) + lose_openssl_error("Couldn't add SIA extension to OpenSSL object"); + + ok = 1; + + error: + AUTHORITY_INFO_ACCESS_free(ext); + ACCESS_DESCRIPTION_free(a); + Py_XDECREF(item); + Py_XDECREF(iterator); + + if (ok) + Py_RETURN_NONE; + else + return NULL; +} + +static PyObject * +extension_get_extended_key_usage(STACK_OF(X509_EXTENSION) **exts) +{ + EXTENDED_KEY_USAGE *ext = NULL; + PyObject *result = NULL; + PyObject *oid = NULL; + int i; + + ENTERING(extension_get_extended_key_usage); + + if (!exts) + lose("Missing extensions"); + + if ((ext = X509V3_get_d2i(*exts, NID_ext_key_usage, NULL, NULL)) == NULL) + Py_RETURN_NONE; + + if ((result = PyFrozenSet_New(NULL)) == NULL) + goto error; + + for (i = 0; sk_ASN1_OBJECT_num(ext); i++) { + if ((oid = ASN1_OBJECT_to_PyString(sk_ASN1_OBJECT_value(ext, i))) == NULL || + PySet_Add(result, oid) < 0) + goto error; + Py_XDECREF(oid); + oid = NULL; + } + + sk_ASN1_OBJECT_pop_free(ext, ASN1_OBJECT_free); + return result; + + error: + sk_ASN1_OBJECT_pop_free(ext, ASN1_OBJECT_free); + Py_XDECREF(oid); + Py_XDECREF(result); + return NULL; +} + +static PyObject * +extension_set_extended_key_usage(STACK_OF(X509_EXTENSION) **exts, PyObject *args) +{ + EXTENDED_KEY_USAGE *ext = NULL; + PyObject *iterable = NULL; + PyObject *critical = Py_False; + PyObject *iterator = NULL; + PyObject *item = NULL; + ASN1_OBJECT *obj = NULL; + const char *txt; + int ok = 0; + + ENTERING(extension_set_extended_key_usage); + + if (!exts) + lose("Missing extensions"); + + if ((ext = sk_ASN1_OBJECT_new_null()) == NULL) + lose_no_memory(); + + if (!PyArg_ParseTuple(args, "O|O", &iterable, &critical) || + (iterator = PyObject_GetIter(iterable)) == NULL) + goto error; + + while ((item = PyIter_Next(iterator)) != NULL) { + + if ((txt = PyString_AsString(item)) == NULL) + goto error; + + if ((obj = OBJ_txt2obj(txt, 1)) == NULL) + lose("Couldn't parse OID"); + + if (!sk_ASN1_OBJECT_push(ext, obj)) + lose_no_memory(); + + obj = NULL; + Py_XDECREF(item); + item = NULL; + } + + if (sk_ASN1_OBJECT_num(ext) < 1) + lose("Empty ExtendedKeyUsage extension"); + + if (!X509V3_add1_i2d(exts, NID_ext_key_usage, ext, + PyObject_IsTrue(critical), + X509V3_ADD_REPLACE)) + lose_openssl_error("Couldn't add ExtendedKeyUsage extension to OpenSSL object"); + + ok = 1; + + error: /* Fall through */ + sk_ASN1_OBJECT_pop_free(ext, ASN1_OBJECT_free); + Py_XDECREF(item); + Py_XDECREF(iterator); + + if (ok) + Py_RETURN_NONE; + else + return NULL; +} + + + /* * IPAddress object. */ @@ -1716,6 +2174,15 @@ x509_object_der_write(x509_object *self) return result; } +static STACK_OF(X509_EXTENSION) ** +x509_object_extension_helper(x509_object *self) +{ + if (self && self->x509 && self->x509->cert_info && self->x509->cert_info->extensions) + return &self->x509->cert_info->extensions; + else + return NULL; +} + static char x509_object_get_public_key__doc__[] = "Return the public key from this certificate object,\n" "as an Asymmetric object.\n" @@ -2268,36 +2735,7 @@ static char x509_object_get_key_usage__doc__[] = static PyObject * x509_object_get_key_usage(x509_object *self) { - ASN1_BIT_STRING *ext = NULL; - PyObject *result = NULL; - PyObject *token = NULL; - int bit = -1; - - ENTERING(x509_object_get_key_usage); - - if ((ext = X509_get_ext_d2i(self->x509, NID_key_usage, NULL, NULL)) == NULL) - Py_RETURN_NONE; - - if ((result = PyFrozenSet_New(NULL)) == NULL) - goto error; - - for (bit = 0; key_usage_bit_names[bit] != NULL; bit++) { - if (ASN1_BIT_STRING_get_bit(ext, bit) && - ((token = PyString_FromString(key_usage_bit_names[bit])) == NULL || - PySet_Add(result, token) < 0)) - goto error; - Py_XDECREF(token); - token = NULL; - } - - ASN1_BIT_STRING_free(ext); - return result; - - error: - ASN1_BIT_STRING_free(ext); - Py_XDECREF(token); - Py_XDECREF(result); - return NULL; + return extension_get_key_usage(x509_object_extension_helper(self)); } static char x509_object_set_key_usage__doc__[] = @@ -2314,59 +2752,36 @@ static char x509_object_set_key_usage__doc__[] = static PyObject * x509_object_set_key_usage(x509_object *self, PyObject *args) { - ASN1_BIT_STRING *ext = NULL; - PyObject *iterable = NULL; - PyObject *critical = Py_True; - PyObject *iterator = NULL; - PyObject *token = NULL; - const char *t; - int bit = -1; - int ok = 0; - - ENTERING(x509_object_set_key_usage); - - if ((ext = ASN1_BIT_STRING_new()) == NULL) - lose_no_memory(); - - if (!PyArg_ParseTuple(args, "O|O", &iterable, &critical) || - (iterator = PyObject_GetIter(iterable)) == NULL) - goto error; - - while ((token = PyIter_Next(iterator)) != NULL) { - - if ((t = PyString_AsString(token)) == NULL) - goto error; - - for (bit = 0; key_usage_bit_names[bit] != NULL; bit++) - if (!strcmp(t, key_usage_bit_names[bit])) - break; - - if (key_usage_bit_names[bit] == NULL) - lose("Unrecognized KeyUsage token"); - - if (!ASN1_BIT_STRING_set_bit(ext, bit, 1)) - lose_no_memory(); - - Py_XDECREF(token); - token = NULL; - } + return extension_set_key_usage(x509_object_extension_helper(self), args); +} - if (!X509_add1_ext_i2d(self->x509, NID_key_usage, ext, - PyObject_IsTrue(critical), - X509V3_ADD_REPLACE)) - lose_openssl_error("Couldn't add KeyUsage extension to certificate"); +static char x509_object_get_extended_key_usage__doc__[] = + "Return a FrozenSet of object identifiers representing the\n" + "ExtendedKeyUsage settings for this certificate, or None if\n" + "the certificate has no ExtendedKeyUsage extension.\n" + ; - ok = 1; +static PyObject * +x509_object_get_extended_key_usage(x509_object *self) +{ + return extension_get_extended_key_usage(x509_object_extension_helper(self)); +} - error: /* Fall through */ - ASN1_BIT_STRING_free(ext); - Py_XDECREF(iterator); - Py_XDECREF(token); +static char x509_object_set_extended_key_usage__doc__[] = + "Set the ExtendedKeyUsage extension for this certificate.\n" + "\n" + "Argument \"iterable\" should be an iterable object which returns one or more\n" + "object identifiers.\n" + "\n" + "Optional argument \"critical\" is a boolean indicating whether the extension\n" + "should be marked as critical or not. RFC 6487 4.8.5 says this extension\n" + "MUST NOT be marked as non-critical when used, so the default is False.\n" + ; - if (ok) - Py_RETURN_NONE; - else - return NULL; +static PyObject * +x509_object_set_extended_key_usage(x509_object *self, PyObject *args) +{ + return extension_set_extended_key_usage(x509_object_extension_helper(self), args); } static char x509_object_get_rfc3779__doc__[] = @@ -2745,21 +3160,7 @@ static char x509_object_get_basic_constraints__doc__[] = static PyObject * x509_object_get_basic_constraints(x509_object *self) { - BASIC_CONSTRAINTS *ext = NULL; - PyObject *result; - - ENTERING(x509_object_get_basic_constraints); - - if ((ext = X509_get_ext_d2i(self->x509, NID_basic_constraints, NULL, NULL)) == NULL) - Py_RETURN_NONE; - - if (ext->pathlen == NULL) - result = Py_BuildValue("(NO)", PyBool_FromLong(ext->ca), Py_None); - else - result = Py_BuildValue("(Nl)", PyBool_FromLong(ext->ca), ASN1_INTEGER_get(ext->pathlen)); - - BASIC_CONSTRAINTS_free(ext); - return result; + return extension_get_basic_constraints(x509_object_extension_helper(self)); } static char x509_object_set_basic_constraints__doc__[] = @@ -2775,49 +3176,12 @@ static char x509_object_set_basic_constraints__doc__[] = "Optional third argument \"critical\" specifies whether the extension\n" "should be marked as critical. RFC 5280 4.2.1.9 requires that CA\n" "certificates mark this extension as critical, so the default is True.\n" - ; - -static PyObject * -x509_object_set_basic_constraints(x509_object *self, PyObject *args) -{ - BASIC_CONSTRAINTS *ext = NULL; - PyObject *is_ca = NULL; - PyObject *pathlen_obj = Py_None; - PyObject *critical = Py_True; - long pathlen = -1; - int ok = 0; - - ENTERING(x509_object_set_basic_constraints); - - if (!PyArg_ParseTuple(args, "O|OO", &is_ca, &pathlen_obj, &critical)) - goto error; - - if (pathlen_obj != Py_None && (pathlen = PyInt_AsLong(pathlen_obj)) < 0) - lose_type_error("Bad pathLenConstraint value"); - - if ((ext = BASIC_CONSTRAINTS_new()) == NULL) - lose_no_memory(); - - ext->ca = PyObject_IsTrue(is_ca) ? 0xFF : 0; - - if (pathlen_obj != Py_None && - ((ext->pathlen == NULL && (ext->pathlen = ASN1_INTEGER_new()) == NULL) || - !ASN1_INTEGER_set(ext->pathlen, pathlen))) - lose_no_memory(); - - if (!X509_add1_ext_i2d(self->x509, NID_basic_constraints, - ext, PyObject_IsTrue(critical), X509V3_ADD_REPLACE)) - lose_openssl_error("Couldn't add BasicConstraints extension to certificate"); - - ok = 1; - - error: - BASIC_CONSTRAINTS_free(ext); + ; - if (ok) - Py_RETURN_NONE; - else - return NULL; +static PyObject * +x509_object_set_basic_constraints(x509_object *self, PyObject *args) +{ + return extension_set_basic_constraints(x509_object_extension_helper(self), args); } static char x509_object_get_sia__doc__[] = @@ -2837,90 +3201,7 @@ static char x509_object_get_sia__doc__[] = static PyObject * x509_object_get_sia(x509_object *self) { - AUTHORITY_INFO_ACCESS *ext = NULL; - PyObject *result = NULL; - PyObject *result_caRepository = NULL; - PyObject *result_rpkiManifest = NULL; - PyObject *result_signedObject = NULL; - int n_caRepository = 0; - int n_rpkiManifest = 0; - int n_signedObject = 0; - const char *uri; - PyObject *obj; - int i, nid; - - ENTERING(x509_object_get_sia); - - if ((ext = X509_get_ext_d2i(self->x509, NID_sinfo_access, NULL, NULL)) == NULL) - Py_RETURN_NONE; - - /* - * Easiest to do this in two passes, first pass just counts URIs. - */ - - for (i = 0; i < sk_ACCESS_DESCRIPTION_num(ext); i++) { - ACCESS_DESCRIPTION *a = sk_ACCESS_DESCRIPTION_value(ext, i); - if (a->location->type != GEN_URI) - continue; - nid = OBJ_obj2nid(a->method); - if (nid == NID_caRepository) { - n_caRepository++; - continue; - } - if (nid == NID_rpkiManifest) { - n_rpkiManifest++; - continue; - } - if (nid == NID_signedObject) { - n_signedObject++; - continue; - } - } - - if (((result_caRepository = PyTuple_New(n_caRepository)) == NULL) || - ((result_rpkiManifest = PyTuple_New(n_rpkiManifest)) == NULL) || - ((result_signedObject = PyTuple_New(n_signedObject)) == NULL)) - goto error; - - n_caRepository = n_rpkiManifest = n_signedObject = 0; - - for (i = 0; i < sk_ACCESS_DESCRIPTION_num(ext); i++) { - ACCESS_DESCRIPTION *a = sk_ACCESS_DESCRIPTION_value(ext, i); - if (a->location->type != GEN_URI) - continue; - nid = OBJ_obj2nid(a->method); - uri = (char *) ASN1_STRING_data(a->location->d.uniformResourceIdentifier); - if (nid == NID_caRepository) { - if ((obj = PyString_FromString(uri)) == NULL) - goto error; - PyTuple_SET_ITEM(result_caRepository, n_caRepository++, obj); - continue; - } - if (nid == NID_rpkiManifest) { - if ((obj = PyString_FromString(uri)) == NULL) - goto error; - PyTuple_SET_ITEM(result_rpkiManifest, n_rpkiManifest++, obj); - continue; - } - if (nid == NID_signedObject) { - if ((obj = PyString_FromString(uri)) == NULL) - goto error; - PyTuple_SET_ITEM(result_signedObject, n_signedObject++, obj); - continue; - } - } - - result = Py_BuildValue("(OOO)", - result_caRepository, - result_rpkiManifest, - result_signedObject); - - error: - AUTHORITY_INFO_ACCESS_free(ext); - Py_XDECREF(result_caRepository); - Py_XDECREF(result_rpkiManifest); - Py_XDECREF(result_signedObject); - return result; + return extension_get_sia(x509_object_extension_helper(self)); } static char x509_object_set_sia__doc__[] = @@ -2935,91 +3216,7 @@ static char x509_object_set_sia__doc__[] = static PyObject * x509_object_set_sia(x509_object *self, PyObject *args, PyObject *kwds) { - static char *kwlist[] = {"caRepository", "rpkiManifest", "signedObject", NULL}; - AUTHORITY_INFO_ACCESS *ext = NULL; - PyObject *caRepository = Py_None; - PyObject *rpkiManifest = Py_None; - PyObject *signedObject = Py_None; - PyObject *iterator = NULL; - ASN1_OBJECT *oid = NULL; - PyObject **pobj = NULL; - PyObject *item = NULL; - ACCESS_DESCRIPTION *a = NULL; - int i, nid = NID_undef, ok = 0; - Py_ssize_t urilen; - char *uri; - - ENTERING(x509_object_set_sia); - - if (!PyArg_ParseTupleAndKeywords(args, kwds, "|OOO", kwlist, - &caRepository, &rpkiManifest, &signedObject)) - goto error; - - if ((ext = AUTHORITY_INFO_ACCESS_new()) == NULL) - lose_no_memory(); - - /* - * This is going to want refactoring, because it's ugly, because we - * want to reuse code for AIA, and because it'd be nice to support a - * single URI as an abbreviation for a collection containing one URI. - */ - - for (i = 0; i < 3; i++) { - switch (i) { - case 0: pobj = &caRepository; nid = NID_caRepository; break; - case 1: pobj = &rpkiManifest; nid = NID_rpkiManifest; break; - case 2: pobj = &signedObject; nid = NID_signedObject; break; - } - - if (*pobj == Py_None) - continue; - - if ((oid = OBJ_nid2obj(nid)) == NULL) - lose_openssl_error("Couldn't find SIA accessMethod OID"); - - if ((iterator = PyObject_GetIter(*pobj)) == NULL) - goto error; - - while ((item = PyIter_Next(iterator)) != NULL) { - - if (PyString_AsStringAndSize(item, &uri, &urilen) < 0) - goto error; - - if ((a = ACCESS_DESCRIPTION_new()) == NULL || - (a->method = OBJ_dup(oid)) == NULL || - (a->location->d.uniformResourceIdentifier = ASN1_IA5STRING_new()) == NULL || - !ASN1_OCTET_STRING_set(a->location->d.uniformResourceIdentifier, (unsigned char *) uri, urilen)) - lose_no_memory(); - - a->location->type = GEN_URI; - - if (!sk_ACCESS_DESCRIPTION_push(ext, a)) - lose_no_memory(); - - a = NULL; - Py_XDECREF(item); - item = NULL; - } - - Py_XDECREF(iterator); - iterator = NULL; - } - - if (!X509_add1_ext_i2d(self->x509, NID_sinfo_access, ext, 0, X509V3_ADD_REPLACE)) - lose_openssl_error("Couldn't add SIA extension to certificate"); - - ok = 1; - - error: - AUTHORITY_INFO_ACCESS_free(ext); - ACCESS_DESCRIPTION_free(a); - Py_XDECREF(item); - Py_XDECREF(iterator); - - if (ok) - Py_RETURN_NONE; - else - return NULL; + return extension_set_sia(x509_object_extension_helper(self), args, kwds); } static char x509_object_get_aia__doc__[] = @@ -3464,6 +3661,8 @@ static struct PyMethodDef x509_object_methods[] = { Define_Method(setAKI, x509_object_set_aki, METH_VARARGS), Define_Method(getKeyUsage, x509_object_get_key_usage, METH_NOARGS), Define_Method(setKeyUsage, x509_object_set_key_usage, METH_VARARGS), + Define_Method(getExtendedKeyUsage, x509_object_get_extended_key_usage, METH_NOARGS), + Define_Method(setExtendedKeyUsage, x509_object_set_extended_key_usage, METH_VARARGS), Define_Method(getRFC3779, x509_object_get_rfc3779, METH_NOARGS), Define_Method(setRFC3779, x509_object_set_rfc3779, METH_KEYWORDS), Define_Method(getBasicConstraints, x509_object_get_basic_constraints, METH_NOARGS), @@ -4249,6 +4448,15 @@ static char crl_object_get_version__doc__[] = "return the version number of this CRL.\n" ; +static STACK_OF(X509_EXTENSION) ** +crl_object_extension_helper(crl_object *self) +{ + if (self && self->crl && self->crl->crl && self->crl->crl->extensions) + return &self->crl->crl->extensions; + else + return NULL; +} + static PyObject * crl_object_get_version(crl_object *self) { @@ -8073,6 +8281,15 @@ pkcs10_object_der_write(pkcs10_object *self) return result; } +static STACK_OF(X509_EXTENSION) ** +pkcs10_object_extension_helper(pkcs10_object *self) +{ + if (self && self->exts) + return &self->exts; + else + return NULL; +} + static char pkcs10_object_get_public_key__doc__[] = "Return the public key from this PKCS#10 request, as an Asymmetric\n" "object.\n" @@ -8306,114 +8523,62 @@ pkcs10_object_set_subject(pkcs10_object *self, PyObject *args) return NULL; } -static char pkcs10_object_get_key_usage__doc__[] = - "Return a FrozenSet of strings representing the KeyUsage settings for\n" - "this PKCS#10 request, or None if the request has no KeyUsage\n" - "extension. The bits have the same names as in RFC 5280.\n" - ; - -static PyObject * -pkcs10_object_get_key_usage(pkcs10_object *self) -{ - ASN1_BIT_STRING *ext = NULL; - PyObject *result = NULL; - PyObject *token = NULL; - int bit = -1; - - ENTERING(pkcs10_object_get_key_usage); - - if ((ext = X509V3_get_d2i(self->exts, NID_key_usage, NULL, NULL)) == NULL) - Py_RETURN_NONE; - - if ((result = PyFrozenSet_New(NULL)) == NULL) - goto error; - - for (bit = 0; key_usage_bit_names[bit] != NULL; bit++) { - if (ASN1_BIT_STRING_get_bit(ext, bit) && - ((token = PyString_FromString(key_usage_bit_names[bit])) == NULL || - PySet_Add(result, token) < 0)) - goto error; - Py_XDECREF(token); - token = NULL; - } - - ASN1_BIT_STRING_free(ext); - return result; - - error: - ASN1_BIT_STRING_free(ext); - Py_XDECREF(token); - Py_XDECREF(result); - return NULL; -} - -static char pkcs10_object_set_key_usage__doc__[] = - "Set the KeyUsage extension for this PKCS#10 request.\n" - "\n" - "Argument \"iterable\" should be an iterable object which returns zero or more\n" - "strings naming bits to be enabled. The bits have the same names as in RFC 5280.\n" - "\n" - "Optional argument \"critical\" is a boolean indicating whether the extension\n" - "should be marked as critical or not. RFC 5280 4.2.1.3 says this extension SHOULD\n" - "be marked as critical when used, so the default is True.\n" - ; - -static PyObject * -pkcs10_object_set_key_usage(pkcs10_object *self, PyObject *args) -{ - ASN1_BIT_STRING *ext = NULL; - PyObject *iterable = NULL; - PyObject *critical = Py_True; - PyObject *iterator = NULL; - PyObject *token = NULL; - const char *t; - int bit = -1; - int ok = 0; - - ENTERING(pkcs10_object_set_key_usage); - - if ((ext = ASN1_BIT_STRING_new()) == NULL) - lose_no_memory(); - - if (!PyArg_ParseTuple(args, "O|O", &iterable, &critical) || - (iterator = PyObject_GetIter(iterable)) == NULL) - goto error; - - while ((token = PyIter_Next(iterator)) != NULL) { - - if ((t = PyString_AsString(token)) == NULL) - goto error; - - for (bit = 0; key_usage_bit_names[bit] != NULL; bit++) - if (!strcmp(t, key_usage_bit_names[bit])) - break; +static char pkcs10_object_get_key_usage__doc__[] = + "Return a FrozenSet of strings representing the KeyUsage settings for\n" + "this PKCS#10 request, or None if the request has no KeyUsage\n" + "extension. The bits have the same names as in RFC 5280.\n" + ; - if (key_usage_bit_names[bit] == NULL) - lose("Unrecognized KeyUsage token"); +static PyObject * +pkcs10_object_get_key_usage(pkcs10_object *self) +{ + return extension_get_key_usage(pkcs10_object_extension_helper(self)); +} - if (!ASN1_BIT_STRING_set_bit(ext, bit, 1)) - lose_no_memory(); +static char pkcs10_object_set_key_usage__doc__[] = + "Set the KeyUsage extension for this PKCS#10 request.\n" + "\n" + "Argument \"iterable\" should be an iterable object which returns zero or more\n" + "strings naming bits to be enabled. The bits have the same names as in RFC 5280.\n" + "\n" + "Optional argument \"critical\" is a boolean indicating whether the extension\n" + "should be marked as critical or not. RFC 5280 4.2.1.3 says this extension SHOULD\n" + "be marked as critical when used, so the default is True.\n" + ; - Py_XDECREF(token); - token = NULL; - } +static PyObject * +pkcs10_object_set_key_usage(pkcs10_object *self, PyObject *args) +{ + return extension_set_key_usage(pkcs10_object_extension_helper(self), args); +} - if (!X509V3_add1_i2d(&self->exts, NID_key_usage, ext, - PyObject_IsTrue(critical), - X509V3_ADD_REPLACE)) - lose_openssl_error("Couldn't add KeyUsage extension to certificate"); +static char pkcs10_object_get_extended_key_usage__doc__[] = + "Return a FrozenSet of object identifiers representing the\n" + "ExtendedKeyUsage settings for this PKCS #10 requst, or None if\n" + "the request has no ExtendedKeyUsage extension.\n" + ; - ok = 1; +static PyObject * +pkcs10_object_get_extended_key_usage(pkcs10_object *self) +{ + return extension_get_extended_key_usage(pkcs10_object_extension_helper(self)); +} - error: /* Fall through */ - ASN1_BIT_STRING_free(ext); - Py_XDECREF(iterator); - Py_XDECREF(token); +static char pkcs10_object_set_extended_key_usage__doc__[] = + "Set the ExtendedKeyUsage extension for this PKCS #10 request.\n" + "\n" + "Argument \"iterable\" should be an iterable object which returns one or more\n" + "object identifiers.\n" + "\n" + "Optional argument \"critical\" is a boolean indicating whether the extension\n" + "should be marked as critical or not. RFC 6487 4.8.5 says this extension\n" + "MUST NOT be marked as non-critical when used, so the default is False.\n" + ; - if (ok) - Py_RETURN_NONE; - else - return NULL; +static PyObject * +pkcs10_object_set_extended_key_usage(pkcs10_object *self, PyObject *args) +{ + return extension_set_extended_key_usage(pkcs10_object_extension_helper(self), args); } static char pkcs10_object_get_basic_constraints__doc__[] = @@ -8431,21 +8596,7 @@ static char pkcs10_object_get_basic_constraints__doc__[] = static PyObject * pkcs10_object_get_basic_constraints(pkcs10_object *self) { - BASIC_CONSTRAINTS *ext = NULL; - PyObject *result; - - ENTERING(pkcs10_object_get_basic_constraints); - - if ((ext = X509V3_get_d2i(self->exts, NID_basic_constraints, NULL, NULL)) == NULL) - Py_RETURN_NONE; - - if (ext->pathlen == NULL) - result = Py_BuildValue("(NO)", PyBool_FromLong(ext->ca), Py_None); - else - result = Py_BuildValue("(Nl)", PyBool_FromLong(ext->ca), ASN1_INTEGER_get(ext->pathlen)); - - BASIC_CONSTRAINTS_free(ext); - return result; + return extension_get_basic_constraints(pkcs10_object_extension_helper(self)); } static char pkcs10_object_set_basic_constraints__doc__[] = @@ -8467,44 +8618,7 @@ static char pkcs10_object_set_basic_constraints__doc__[] = static PyObject * pkcs10_object_set_basic_constraints(pkcs10_object *self, PyObject *args) { - BASIC_CONSTRAINTS *ext = NULL; - PyObject *is_ca = NULL; - PyObject *pathlen_obj = Py_None; - PyObject *critical = Py_True; - long pathlen = -1; - int ok = 0; - - ENTERING(pkcs10_object_set_basic_constraints); - - if (!PyArg_ParseTuple(args, "O|OO", &is_ca, &pathlen_obj, &critical)) - goto error; - - if (pathlen_obj != Py_None && (pathlen = PyInt_AsLong(pathlen_obj)) < 0) - lose_type_error("Bad pathLenConstraint value"); - - if ((ext = BASIC_CONSTRAINTS_new()) == NULL) - lose_no_memory(); - - ext->ca = PyObject_IsTrue(is_ca) ? 0xFF : 0; - - if (pathlen_obj != Py_None && - ((ext->pathlen == NULL && (ext->pathlen = ASN1_INTEGER_new()) == NULL) || - !ASN1_INTEGER_set(ext->pathlen, pathlen))) - lose_no_memory(); - - if (!X509V3_add1_i2d(&self->exts, NID_basic_constraints, ext, - PyObject_IsTrue(critical), X509V3_ADD_REPLACE)) - lose_openssl_error("Couldn't add BasicConstraints extension to certificate"); - - ok = 1; - - error: - BASIC_CONSTRAINTS_free(ext); - - if (ok) - Py_RETURN_NONE; - else - return NULL; + return extension_set_basic_constraints(pkcs10_object_extension_helper(self), args); } static char pkcs10_object_get_sia__doc__[] = @@ -8521,90 +8635,7 @@ static char pkcs10_object_get_sia__doc__[] = static PyObject * pkcs10_object_get_sia(pkcs10_object *self) { - AUTHORITY_INFO_ACCESS *ext = NULL; - PyObject *result = NULL; - PyObject *result_caRepository = NULL; - PyObject *result_rpkiManifest = NULL; - PyObject *result_signedObject = NULL; - int n_caRepository = 0; - int n_rpkiManifest = 0; - int n_signedObject = 0; - const char *uri; - PyObject *obj; - int i, nid; - - ENTERING(pkcs10_object_get_sia); - - if ((ext = X509V3_get_d2i(self->exts, NID_sinfo_access, NULL, NULL)) == NULL) - Py_RETURN_NONE; - - /* - * Easiest to do this in two passes, first pass just counts URIs. - */ - - for (i = 0; i < sk_ACCESS_DESCRIPTION_num(ext); i++) { - ACCESS_DESCRIPTION *a = sk_ACCESS_DESCRIPTION_value(ext, i); - if (a->location->type != GEN_URI) - continue; - nid = OBJ_obj2nid(a->method); - if (nid == NID_caRepository) { - n_caRepository++; - continue; - } - if (nid == NID_rpkiManifest) { - n_rpkiManifest++; - continue; - } - if (nid == NID_signedObject) { - n_signedObject++; - continue; - } - } - - if (((result_caRepository = PyTuple_New(n_caRepository)) == NULL) || - ((result_rpkiManifest = PyTuple_New(n_rpkiManifest)) == NULL) || - ((result_signedObject = PyTuple_New(n_signedObject)) == NULL)) - goto error; - - n_caRepository = n_rpkiManifest = n_signedObject = 0; - - for (i = 0; i < sk_ACCESS_DESCRIPTION_num(ext); i++) { - ACCESS_DESCRIPTION *a = sk_ACCESS_DESCRIPTION_value(ext, i); - if (a->location->type != GEN_URI) - continue; - nid = OBJ_obj2nid(a->method); - uri = (char *) ASN1_STRING_data(a->location->d.uniformResourceIdentifier); - if (nid == NID_caRepository) { - if ((obj = PyString_FromString(uri)) == NULL) - goto error; - PyTuple_SET_ITEM(result_caRepository, n_caRepository++, obj); - continue; - } - if (nid == NID_rpkiManifest) { - if ((obj = PyString_FromString(uri)) == NULL) - goto error; - PyTuple_SET_ITEM(result_rpkiManifest, n_rpkiManifest++, obj); - continue; - } - if (nid == NID_signedObject) { - if ((obj = PyString_FromString(uri)) == NULL) - goto error; - PyTuple_SET_ITEM(result_signedObject, n_signedObject++, obj); - continue; - } - } - - result = Py_BuildValue("(OOO)", - result_caRepository, - result_rpkiManifest, - result_signedObject); - - error: - AUTHORITY_INFO_ACCESS_free(ext); - Py_XDECREF(result_caRepository); - Py_XDECREF(result_rpkiManifest); - Py_XDECREF(result_signedObject); - return result; + return extension_get_sia(pkcs10_object_extension_helper(self)); } static char pkcs10_object_set_sia__doc__[] = @@ -8619,91 +8650,9 @@ static char pkcs10_object_set_sia__doc__[] = ; static PyObject * -pkcs10_object_set_sia(pkcs10_object *self, PyObject *args) +pkcs10_object_set_sia(pkcs10_object *self, PyObject *args, PyObject *kwds) { - AUTHORITY_INFO_ACCESS *ext = NULL; - PyObject *caRepository = NULL; - PyObject *rpkiManifest = NULL; - PyObject *signedObject = NULL; - PyObject *iterator = NULL; - ASN1_OBJECT *oid = NULL; - PyObject **pobj = NULL; - PyObject *item = NULL; - ACCESS_DESCRIPTION *a = NULL; - int i, nid = NID_undef, ok = 0; - Py_ssize_t urilen; - char *uri; - - ENTERING(pkcs10_object_set_sia); - - if (!PyArg_ParseTuple(args, "OOO", &caRepository, &rpkiManifest, &signedObject)) - goto error; - - if ((ext = AUTHORITY_INFO_ACCESS_new()) == NULL) - lose_no_memory(); - - /* - * This is going to want refactoring, because it's ugly, because we - * want to reuse code for AIA, and because it'd be nice to support a - * single URI as an abbreviation for a sequence containing one URI. - */ - - for (i = 0; i < 3; i++) { - switch (i) { - case 0: pobj = &caRepository; nid = NID_caRepository; break; - case 1: pobj = &rpkiManifest; nid = NID_rpkiManifest; break; - case 2: pobj = &signedObject; nid = NID_signedObject; break; - } - - if (*pobj == Py_None) - continue; - - if ((oid = OBJ_nid2obj(nid)) == NULL) - lose_openssl_error("Couldn't find SIA accessMethod OID"); - - if ((iterator = PyObject_GetIter(*pobj)) == NULL) - goto error; - - while ((item = PyIter_Next(iterator)) != NULL) { - - if (PyString_AsStringAndSize(item, &uri, &urilen) < 0) - goto error; - - if ((a = ACCESS_DESCRIPTION_new()) == NULL || - (a->method = OBJ_dup(oid)) == NULL || - (a->location->d.uniformResourceIdentifier = ASN1_IA5STRING_new()) == NULL || - !ASN1_OCTET_STRING_set(a->location->d.uniformResourceIdentifier, (unsigned char *) uri, urilen)) - lose_no_memory(); - - a->location->type = GEN_URI; - - if (!sk_ACCESS_DESCRIPTION_push(ext, a)) - lose_no_memory(); - - a = NULL; - Py_XDECREF(item); - item = NULL; - } - - Py_XDECREF(iterator); - iterator = NULL; - } - - if (!X509V3_add1_i2d(&self->exts, NID_sinfo_access, ext, 0, X509V3_ADD_REPLACE)) - lose_openssl_error("Couldn't add SIA extension to certificate"); - - ok = 1; - - error: - AUTHORITY_INFO_ACCESS_free(ext); - ACCESS_DESCRIPTION_free(a); - Py_XDECREF(item); - Py_XDECREF(iterator); - - if (ok) - Py_RETURN_NONE; - else - return NULL; + return extension_set_sia(pkcs10_object_extension_helper(self), args, kwds); } static char pkcs10_object_get_signature_algorithm__doc__[] = @@ -8800,10 +8749,12 @@ static struct PyMethodDef pkcs10_object_methods[] = { Define_Method(pprint, pkcs10_object_pprint, METH_NOARGS), Define_Method(getKeyUsage, pkcs10_object_get_key_usage, METH_NOARGS), Define_Method(setKeyUsage, pkcs10_object_set_key_usage, METH_VARARGS), + Define_Method(getExtendedKeyUsage, pkcs10_object_get_extended_key_usage, METH_NOARGS), + Define_Method(setExtendedKeyUsage, pkcs10_object_set_extended_key_usage, METH_VARARGS), Define_Method(getBasicConstraints, pkcs10_object_get_basic_constraints, METH_NOARGS), Define_Method(setBasicConstraints, pkcs10_object_set_basic_constraints, METH_VARARGS), Define_Method(getSIA, pkcs10_object_get_sia, METH_NOARGS), - Define_Method(setSIA, pkcs10_object_set_sia, METH_VARARGS), + Define_Method(setSIA, pkcs10_object_set_sia, METH_KEYWORDS), Define_Method(getSignatureAlgorithm, pkcs10_object_get_signature_algorithm, METH_NOARGS), Define_Method(getExtensionOIDs, pkcs10_object_get_extension_oids, METH_NOARGS), Define_Class_Method(pemRead, pkcs10_object_pem_read, METH_VARARGS), -- cgit v1.2.3 From 27c6393b76fa9921f0bb1b3977f091579e44872a Mon Sep 17 00:00:00 2001 From: Rob Austein Date: Tue, 28 Jan 2014 22:31:30 +0000 Subject: More consolidation of extension handling code. Debug *_extension_helper() methods. Rework assertion handling. svn path=/branches/tk671/; revision=5650 --- rpkid/ext/POW.c | 392 +++++++++++++++++++++++++++++--------------------------- 1 file changed, 203 insertions(+), 189 deletions(-) (limited to 'rpkid/ext/POW.c') diff --git a/rpkid/ext/POW.c b/rpkid/ext/POW.c index 3d662fbc..52441581 100644 --- a/rpkid/ext/POW.c +++ b/rpkid/ext/POW.c @@ -355,7 +355,7 @@ typedef struct { typedef struct { PyObject_HEAD X509_REQ *pkcs10; - STACK_OF(X509_EXTENSION) *exts; + X509_EXTENSIONS *exts; } pkcs10_object; @@ -405,7 +405,7 @@ typedef struct { #define lose_openssl_error(_msg_) \ do { \ - set_openssl_exception(OpenSSLErrorObject, (_msg_)); \ + set_openssl_exception(OpenSSLErrorObject, (_msg_), 0); \ goto error; \ } while (0) @@ -417,19 +417,21 @@ typedef struct { #define assert_no_unhandled_openssl_errors() \ do { \ - if (ERR_peek_error()) \ - lose_openssl_error(assert_helper(__LINE__)); \ + if (ERR_peek_error()) { \ + set_openssl_exception(OpenSSLErrorObject, NULL, __LINE__); \ + goto error; \ + } \ } while (0) -static char * -assert_helper(int line) -{ - static const char fmt[] = "Unhandled OpenSSL error at " __FILE__ ":%d!"; - static char msg[sizeof(fmt) + 10]; - - snprintf(msg, sizeof(msg), fmt, line); - return msg; -} +#define POW_assert(_cond_) \ + do { \ + if (!(_cond_)) { \ + (void) PyErr_Format(POWErrorObject, \ + "Assertion %s failed at " __FILE__ ":%d", \ + #_cond_, __LINE__); \ + goto error; \ + } \ + } while (0) /* * Consolidate some tedious EVP-related switch statements. @@ -451,10 +453,19 @@ evp_digest_factory(int digest_type) /* * Raise an exception with data pulled from the OpenSSL error stack. - * Exception value is a tuple with some internal structure. If a - * string error message is supplied, that string is the first element - * of the exception value tuple. Remainder of exception value tuple - * is zero or more tuples, each representing one error from the stack. + * Exception value is a tuple with some internal structure. + * + * If a string error message is supplied, that string is the first + * element of the exception value tuple. + * + * If a non-zero line number is supplied, a string listing this as an + * unhandled exception detected at that line will be the next element + * of the exception value tuple (or the first, if no error message was + * supplied). + * + * Remainder of exception value tuple is zero or more tuples, each + * representing one error from the stack. + * * Each error tuple contains six slots: * - the numeric error code * - string translation of numeric error code ("reason") @@ -465,18 +476,26 @@ evp_digest_factory(int digest_type) */ static void -set_openssl_exception(PyObject *error_class, const char *msg) +set_openssl_exception(PyObject *error_class, const char *msg, const int unhandled_line) { - PyObject *errors; + PyObject *errtuple = NULL; + PyObject *errlist = NULL; unsigned long err; const char *file; int line; - errors = PyList_New(0); + if ((errlist = PyList_New(0)) == NULL) + return; if (msg) { - PyObject *s = Py_BuildValue("s", msg); - (void) PyList_Append(errors, s); + PyObject *s = PyString_FromString(msg); + (void) PyList_Append(errlist, s); + Py_XDECREF(s); + } + + if (unhandled_line) { + PyObject *s = PyString_FromFormat("Unhandled OpenSSL error at " __FILE__ ":%d!", unhandled_line); + (void) PyList_Append(errlist, s); Py_XDECREF(s); } @@ -488,12 +507,15 @@ set_openssl_exception(PyObject *error_class, const char *msg) ERR_func_error_string(err), file, line); - (void) PyList_Append(errors, t); + (void) PyList_Append(errlist, t); Py_XDECREF(t); } - PyErr_SetObject(error_class, PyList_AsTuple(errors)); - Py_XDECREF(errors); + if ((errtuple = PyList_AsTuple(errlist)) != NULL) + PyErr_SetObject(error_class, errtuple); + + Py_XDECREF(errtuple); + Py_XDECREF(errlist); } static X509_NAME * @@ -1048,11 +1070,14 @@ ASN1_OBJECT_to_PyString(const ASN1_OBJECT *oid) /* - * Extension functions. + * Extension functions. Calling sequence here is a little weird, + * because it turns out that the simplest way to avoid massive + * duplication of code between classes is to work directly with + * X509_EXTENSIONS objects. */ static PyObject * -extension_get_key_usage(STACK_OF(X509_EXTENSION) **exts) +extension_get_key_usage(X509_EXTENSIONS **exts) { ASN1_BIT_STRING *ext = NULL; PyObject *result = NULL; @@ -1061,8 +1086,7 @@ extension_get_key_usage(STACK_OF(X509_EXTENSION) **exts) ENTERING(extension_get_key_usage); - if (!exts) - lose("Missing extensions"); + assert (exts); if ((ext = X509V3_get_d2i(*exts, NID_key_usage, NULL, NULL)) == NULL) Py_RETURN_NONE; @@ -1090,7 +1114,7 @@ extension_get_key_usage(STACK_OF(X509_EXTENSION) **exts) } static PyObject * -extension_set_key_usage(STACK_OF(X509_EXTENSION) **exts, PyObject *args) +extension_set_key_usage(X509_EXTENSIONS **exts, PyObject *args) { ASN1_BIT_STRING *ext = NULL; PyObject *iterable = NULL; @@ -1103,8 +1127,7 @@ extension_set_key_usage(STACK_OF(X509_EXTENSION) **exts, PyObject *args) ENTERING(extension_set_key_usage); - if (!exts) - lose("Missing extensions"); + assert (exts); if ((ext = ASN1_BIT_STRING_new()) == NULL) lose_no_memory(); @@ -1151,15 +1174,14 @@ extension_set_key_usage(STACK_OF(X509_EXTENSION) **exts, PyObject *args) } static PyObject * -extension_get_basic_constraints(STACK_OF(X509_EXTENSION) **exts) +extension_get_basic_constraints(X509_EXTENSIONS **exts) { BASIC_CONSTRAINTS *ext = NULL; PyObject *result = NULL; ENTERING(extension_get_basic_constraints); - if (!exts) - lose("Missing extensions"); + POW_assert(exts); if ((ext = X509V3_get_d2i(*exts, NID_basic_constraints, NULL, NULL)) == NULL) Py_RETURN_NONE; @@ -1175,7 +1197,7 @@ extension_get_basic_constraints(STACK_OF(X509_EXTENSION) **exts) } static PyObject * -extension_set_basic_constraints(STACK_OF(X509_EXTENSION) **exts, PyObject *args) +extension_set_basic_constraints(X509_EXTENSIONS **exts, PyObject *args) { BASIC_CONSTRAINTS *ext = NULL; PyObject *is_ca = NULL; @@ -1186,8 +1208,7 @@ extension_set_basic_constraints(STACK_OF(X509_EXTENSION) **exts, PyObject *args) ENTERING(extension_set_basic_constraints); - if (!exts) - lose("Missing extensions"); + POW_assert(exts); if (!PyArg_ParseTuple(args, "O|OO", &is_ca, &pathlen_obj, &critical)) goto error; @@ -1221,7 +1242,7 @@ extension_set_basic_constraints(STACK_OF(X509_EXTENSION) **exts, PyObject *args) } static PyObject * -extension_get_sia(STACK_OF(X509_EXTENSION) **exts) +extension_get_sia(X509_EXTENSIONS **exts) { AUTHORITY_INFO_ACCESS *ext = NULL; PyObject *result = NULL; @@ -1237,8 +1258,7 @@ extension_get_sia(STACK_OF(X509_EXTENSION) **exts) ENTERING(pkcs10_object_get_sia); - if (!exts) - lose("Missing extensions"); + POW_assert(exts); if ((ext = X509V3_get_d2i(*exts, NID_sinfo_access, NULL, NULL)) == NULL) Py_RETURN_NONE; @@ -1313,7 +1333,7 @@ extension_get_sia(STACK_OF(X509_EXTENSION) **exts) } static PyObject * -extension_set_sia(STACK_OF(X509_EXTENSION) **exts, PyObject *args, PyObject *kwds) +extension_set_sia(X509_EXTENSIONS **exts, PyObject *args, PyObject *kwds) { static char *kwlist[] = {"caRepository", "rpkiManifest", "signedObject", NULL}; AUTHORITY_INFO_ACCESS *ext = NULL; @@ -1331,8 +1351,7 @@ extension_set_sia(STACK_OF(X509_EXTENSION) **exts, PyObject *args, PyObject *kwd ENTERING(extension_set_sia); - if (!exts) - lose("Missing extensions"); + POW_assert(exts); if (!PyArg_ParseTupleAndKeywords(args, kwds, "|OOO", kwlist, &caRepository, &rpkiManifest, &signedObject)) @@ -1406,7 +1425,7 @@ extension_set_sia(STACK_OF(X509_EXTENSION) **exts, PyObject *args, PyObject *kwd } static PyObject * -extension_get_extended_key_usage(STACK_OF(X509_EXTENSION) **exts) +extension_get_extended_key_usage(X509_EXTENSIONS **exts) { EXTENDED_KEY_USAGE *ext = NULL; PyObject *result = NULL; @@ -1415,8 +1434,7 @@ extension_get_extended_key_usage(STACK_OF(X509_EXTENSION) **exts) ENTERING(extension_get_extended_key_usage); - if (!exts) - lose("Missing extensions"); + POW_assert(exts); if ((ext = X509V3_get_d2i(*exts, NID_ext_key_usage, NULL, NULL)) == NULL) Py_RETURN_NONE; @@ -1443,7 +1461,7 @@ extension_get_extended_key_usage(STACK_OF(X509_EXTENSION) **exts) } static PyObject * -extension_set_extended_key_usage(STACK_OF(X509_EXTENSION) **exts, PyObject *args) +extension_set_extended_key_usage(X509_EXTENSIONS **exts, PyObject *args) { EXTENDED_KEY_USAGE *ext = NULL; PyObject *iterable = NULL; @@ -1456,8 +1474,7 @@ extension_set_extended_key_usage(STACK_OF(X509_EXTENSION) **exts, PyObject *args ENTERING(extension_set_extended_key_usage); - if (!exts) - lose("Missing extensions"); + POW_assert(exts); if ((ext = sk_ASN1_OBJECT_new_null()) == NULL) lose_no_memory(); @@ -1503,6 +1520,125 @@ extension_set_extended_key_usage(STACK_OF(X509_EXTENSION) **exts, PyObject *args return NULL; } +static PyObject * +extension_get_ski(X509_EXTENSIONS **exts) +{ + ASN1_OCTET_STRING *ext = NULL; + PyObject *result = NULL; + + ENTERING(extension_get_ski); + + POW_assert(exts); + + if ((ext = X509V3_get_d2i(*exts, NID_subject_key_identifier, NULL, NULL)) == NULL) + Py_RETURN_NONE; + + result = Py_BuildValue("s#", ASN1_STRING_data(ext), + (Py_ssize_t) ASN1_STRING_length(ext)); + + error: /* Fall through */ + ASN1_OCTET_STRING_free(ext); + return result; +} + +static PyObject * +extension_set_ski(X509_EXTENSIONS **exts, PyObject *args) +{ + ASN1_OCTET_STRING *ext = NULL; + const unsigned char *buf = NULL; + Py_ssize_t len; + int ok = 0; + + ENTERING(extension_set_ski); + + POW_assert(exts); + + if (!PyArg_ParseTuple(args, "s#", &buf, &len)) + goto error; + + if ((ext = ASN1_OCTET_STRING_new()) == NULL || + !ASN1_OCTET_STRING_set(ext, buf, len)) + lose_no_memory(); + + /* + * RFC 5280 says this MUST be non-critical. + */ + + if (!X509V3_add1_i2d(exts, NID_subject_key_identifier, + ext, 0, X509V3_ADD_REPLACE)) + lose_openssl_error("Couldn't add SKI extension to OpenSSL object"); + + ok = 1; + + error: + ASN1_OCTET_STRING_free(ext); + + if (ok) + Py_RETURN_NONE; + else + return NULL; +} + +static PyObject * +extension_get_aki(X509_EXTENSIONS **exts) +{ + AUTHORITY_KEYID *ext = NULL; + PyObject *result = NULL; + + ENTERING(extension_get_aki); + + POW_assert(exts); + + if ((ext = X509V3_get_d2i(*exts, NID_authority_key_identifier, NULL, NULL)) == NULL) + Py_RETURN_NONE; + + result = Py_BuildValue("s#", ASN1_STRING_data(ext->keyid), + (Py_ssize_t) ASN1_STRING_length(ext->keyid)); + + error: /* Fall through */ + AUTHORITY_KEYID_free(ext); + return result; +} + +static PyObject * +extension_set_aki(X509_EXTENSIONS **exts, PyObject *args) +{ + AUTHORITY_KEYID *ext = NULL; + const unsigned char *buf = NULL; + Py_ssize_t len; + int ok = 0; + + ENTERING(extension_set_aki); + + assert (exts); + + if (!PyArg_ParseTuple(args, "s#", &buf, &len)) + goto error; + + if ((ext = AUTHORITY_KEYID_new()) == NULL || + (ext->keyid == NULL && (ext->keyid = ASN1_OCTET_STRING_new()) == NULL) || + !ASN1_OCTET_STRING_set(ext->keyid, buf, len)) + lose_no_memory(); + + /* + * RFC 5280 says this MUST be non-critical. + */ + + if (!X509V3_add1_i2d(exts, NID_authority_key_identifier, + ext, 0, X509V3_ADD_REPLACE)) + lose_openssl_error("Couldn't add AKI extension to OpenSSL object"); + + ok = 1; + + error: + AUTHORITY_KEYID_free(ext); + + if (ok) + Py_RETURN_NONE; + else + return NULL; +} + /* @@ -2174,10 +2310,10 @@ x509_object_der_write(x509_object *self) return result; } -static STACK_OF(X509_EXTENSION) ** +static X509_EXTENSIONS ** x509_object_extension_helper(x509_object *self) { - if (self && self->x509 && self->x509->cert_info && self->x509->cert_info->extensions) + if (self && self->x509 && self->x509->cert_info) return &self->x509->cert_info->extensions; else return NULL; @@ -2611,15 +2747,7 @@ static char x509_object_get_ski__doc__[] = static PyObject * x509_object_get_ski(x509_object *self) { - ENTERING(x509_object_get_ski); - - (void) X509_check_ca(self->x509); /* Calls x509v3_cache_extensions() */ - - if (self->x509->skid == NULL) - Py_RETURN_NONE; - else - return Py_BuildValue("s#", ASN1_STRING_data(self->x509->skid), - (Py_ssize_t) ASN1_STRING_length(self->x509->skid)); + return extension_get_ski(x509_object_extension_helper(self)); } static char x509_object_set_ski__doc__[] = @@ -2629,37 +2757,7 @@ static char x509_object_set_ski__doc__[] = static PyObject * x509_object_set_ski(x509_object *self, PyObject *args) { - ASN1_OCTET_STRING *ext = NULL; - const unsigned char *buf = NULL; - Py_ssize_t len; - int ok = 0; - - ENTERING(x509_object_set_ski); - - if (!PyArg_ParseTuple(args, "s#", &buf, &len)) - goto error; - - if ((ext = ASN1_OCTET_STRING_new()) == NULL || - !ASN1_OCTET_STRING_set(ext, buf, len)) - lose_no_memory(); - - /* - * RFC 5280 4.2.1.2 says this MUST be non-critical. - */ - - if (!X509_add1_ext_i2d(self->x509, NID_subject_key_identifier, - ext, 0, X509V3_ADD_REPLACE)) - lose_openssl_error("Couldn't add SKI extension to certificate"); - - ok = 1; - - error: - ASN1_OCTET_STRING_free(ext); - - if (ok) - Py_RETURN_NONE; - else - return NULL; + return extension_set_ski(x509_object_extension_helper(self), args); } static char x509_object_get_aki__doc__[] = @@ -2671,15 +2769,7 @@ static char x509_object_get_aki__doc__[] = static PyObject * x509_object_get_aki(x509_object *self) { - ENTERING(x509_object_get_aki); - - (void) X509_check_ca(self->x509); /* Calls x509v3_cache_extensions() */ - - if (self->x509->akid == NULL || self->x509->akid->keyid == NULL) - Py_RETURN_NONE; - else - return Py_BuildValue("s#", ASN1_STRING_data(self->x509->akid->keyid), - (Py_ssize_t) ASN1_STRING_length(self->x509->akid->keyid)); + return extension_get_aki(x509_object_extension_helper(self)); } static char x509_object_set_aki__doc__[] = @@ -2692,38 +2782,7 @@ static char x509_object_set_aki__doc__[] = static PyObject * x509_object_set_aki(x509_object *self, PyObject *args) { - AUTHORITY_KEYID *ext = NULL; - const unsigned char *buf = NULL; - Py_ssize_t len; - int ok = 0; - - ENTERING(x509_object_set_aki); - - if (!PyArg_ParseTuple(args, "s#", &buf, &len)) - goto error; - - if ((ext = AUTHORITY_KEYID_new()) == NULL || - (ext->keyid == NULL && (ext->keyid = ASN1_OCTET_STRING_new()) == NULL) || - !ASN1_OCTET_STRING_set(ext->keyid, buf, len)) - lose_no_memory(); - - /* - * RFC 5280 4.2.1.1 says this MUST be non-critical. - */ - - if (!X509_add1_ext_i2d(self->x509, NID_authority_key_identifier, - ext, 0, X509V3_ADD_REPLACE)) - lose_openssl_error("Couldn't add AKI extension to certificate"); - - ok = 1; - - error: - AUTHORITY_KEYID_free(ext); - - if (ok) - Py_RETURN_NONE; - else - return NULL; + return extension_set_aki(x509_object_extension_helper(self), args); } static char x509_object_get_key_usage__doc__[] = @@ -4444,19 +4503,19 @@ crl_object_der_read_file(PyTypeObject *type, PyObject *args) return read_from_file_helper(crl_object_der_read_helper, type, args); } -static char crl_object_get_version__doc__[] = - "return the version number of this CRL.\n" - ; - -static STACK_OF(X509_EXTENSION) ** +static X509_EXTENSIONS ** crl_object_extension_helper(crl_object *self) { - if (self && self->crl && self->crl->crl && self->crl->crl->extensions) + if (self && self->crl && self->crl->crl) return &self->crl->crl->extensions; else return NULL; } +static char crl_object_get_version__doc__[] = + "return the version number of this CRL.\n" + ; + static PyObject * crl_object_get_version(crl_object *self) { @@ -4825,7 +4884,7 @@ crl_object_sign(crl_object *self, PyObject *args) } static char crl_object_verify__doc__[] = - "Verifie this CRL's signature.\n" + "Verify this CRL's signature.\n" "\n" "The check is performed using OpenSSL's X509_CRL_verify() function.\n" "\n" @@ -4908,22 +4967,7 @@ static char crl_object_get_aki__doc__[] = static PyObject * crl_object_get_aki(crl_object *self) { - AUTHORITY_KEYID *ext = X509_CRL_get_ext_d2i(self->crl, NID_authority_key_identifier, NULL, NULL); - int empty = (ext == NULL || ext->keyid == NULL); - PyObject *result = NULL; - - ENTERING(crl_object_get_aki); - - if (!empty) - result = Py_BuildValue("s#", ASN1_STRING_data(ext->keyid), - (Py_ssize_t) ASN1_STRING_length(ext->keyid)); - - AUTHORITY_KEYID_free(ext); - - if (empty) - Py_RETURN_NONE; - else - return result; + return extension_get_aki(crl_object_extension_helper(self)); } static char crl_object_set_aki__doc__[] = @@ -4935,34 +4979,7 @@ static char crl_object_set_aki__doc__[] = static PyObject * crl_object_set_aki(crl_object *self, PyObject *args) { - AUTHORITY_KEYID *ext = NULL; - const unsigned char *buf = NULL; - Py_ssize_t len; - int ok = 0; - - ENTERING(crl_object_set_aki); - - if (!PyArg_ParseTuple(args, "s#", &buf, &len)) - goto error; - - if ((ext = AUTHORITY_KEYID_new()) == NULL || - (ext->keyid = ASN1_OCTET_STRING_new()) == NULL || - !ASN1_OCTET_STRING_set(ext->keyid, buf, len)) - lose_no_memory(); - - if (!X509_CRL_add1_ext_i2d(self->crl, NID_authority_key_identifier, - ext, 0, X509V3_ADD_REPLACE)) - lose_openssl_error("Couldn't add AKI extension to CRL"); - - ok = 1; - - error: - AUTHORITY_KEYID_free(ext); - - if (ok) - Py_RETURN_NONE; - else - return NULL; + return extension_set_aki(crl_object_extension_helper(self), args); } static char crl_object_get_crl_number__doc__[] = @@ -8281,13 +8298,10 @@ pkcs10_object_der_write(pkcs10_object *self) return result; } -static STACK_OF(X509_EXTENSION) ** +static X509_EXTENSIONS ** pkcs10_object_extension_helper(pkcs10_object *self) { - if (self && self->exts) - return &self->exts; - else - return NULL; + return &self->exts; } static char pkcs10_object_get_public_key__doc__[] = -- cgit v1.2.3 From f3ee7f51c0a091f244985ae7fd3d975a3259fee9 Mon Sep 17 00:00:00 2001 From: Rob Austein Date: Wed, 29 Jan 2014 02:32:36 +0000 Subject: Checkpoint svn path=/branches/tk671/; revision=5651 --- rpkid/ext/POW.c | 40 ++++++++++++++++++++-------------------- 1 file changed, 20 insertions(+), 20 deletions(-) (limited to 'rpkid/ext/POW.c') diff --git a/rpkid/ext/POW.c b/rpkid/ext/POW.c index 52441581..683427b1 100644 --- a/rpkid/ext/POW.c +++ b/rpkid/ext/POW.c @@ -1425,14 +1425,14 @@ extension_set_sia(X509_EXTENSIONS **exts, PyObject *args, PyObject *kwds) } static PyObject * -extension_get_extended_key_usage(X509_EXTENSIONS **exts) +extension_get_eku(X509_EXTENSIONS **exts) { EXTENDED_KEY_USAGE *ext = NULL; PyObject *result = NULL; PyObject *oid = NULL; int i; - ENTERING(extension_get_extended_key_usage); + ENTERING(extension_get_eku); POW_assert(exts); @@ -1461,7 +1461,7 @@ extension_get_extended_key_usage(X509_EXTENSIONS **exts) } static PyObject * -extension_set_extended_key_usage(X509_EXTENSIONS **exts, PyObject *args) +extension_set_eku(X509_EXTENSIONS **exts, PyObject *args) { EXTENDED_KEY_USAGE *ext = NULL; PyObject *iterable = NULL; @@ -1472,7 +1472,7 @@ extension_set_extended_key_usage(X509_EXTENSIONS **exts, PyObject *args) const char *txt; int ok = 0; - ENTERING(extension_set_extended_key_usage); + ENTERING(extension_set_eku); POW_assert(exts); @@ -2814,19 +2814,19 @@ x509_object_set_key_usage(x509_object *self, PyObject *args) return extension_set_key_usage(x509_object_extension_helper(self), args); } -static char x509_object_get_extended_key_usage__doc__[] = +static char x509_object_get_eku__doc__[] = "Return a FrozenSet of object identifiers representing the\n" "ExtendedKeyUsage settings for this certificate, or None if\n" "the certificate has no ExtendedKeyUsage extension.\n" ; static PyObject * -x509_object_get_extended_key_usage(x509_object *self) +x509_object_get_eku(x509_object *self) { - return extension_get_extended_key_usage(x509_object_extension_helper(self)); + return extension_get_eku(x509_object_extension_helper(self)); } -static char x509_object_set_extended_key_usage__doc__[] = +static char x509_object_set_eku__doc__[] = "Set the ExtendedKeyUsage extension for this certificate.\n" "\n" "Argument \"iterable\" should be an iterable object which returns one or more\n" @@ -2838,9 +2838,9 @@ static char x509_object_set_extended_key_usage__doc__[] = ; static PyObject * -x509_object_set_extended_key_usage(x509_object *self, PyObject *args) +x509_object_set_eku(x509_object *self, PyObject *args) { - return extension_set_extended_key_usage(x509_object_extension_helper(self), args); + return extension_set_eku(x509_object_extension_helper(self), args); } static char x509_object_get_rfc3779__doc__[] = @@ -3720,8 +3720,8 @@ static struct PyMethodDef x509_object_methods[] = { Define_Method(setAKI, x509_object_set_aki, METH_VARARGS), Define_Method(getKeyUsage, x509_object_get_key_usage, METH_NOARGS), Define_Method(setKeyUsage, x509_object_set_key_usage, METH_VARARGS), - Define_Method(getExtendedKeyUsage, x509_object_get_extended_key_usage, METH_NOARGS), - Define_Method(setExtendedKeyUsage, x509_object_set_extended_key_usage, METH_VARARGS), + Define_Method(getEKU, x509_object_get_eku, METH_NOARGS), + Define_Method(setEKU, x509_object_set_eku, METH_VARARGS), Define_Method(getRFC3779, x509_object_get_rfc3779, METH_NOARGS), Define_Method(setRFC3779, x509_object_set_rfc3779, METH_KEYWORDS), Define_Method(getBasicConstraints, x509_object_get_basic_constraints, METH_NOARGS), @@ -8566,19 +8566,19 @@ pkcs10_object_set_key_usage(pkcs10_object *self, PyObject *args) return extension_set_key_usage(pkcs10_object_extension_helper(self), args); } -static char pkcs10_object_get_extended_key_usage__doc__[] = +static char pkcs10_object_get_eku__doc__[] = "Return a FrozenSet of object identifiers representing the\n" "ExtendedKeyUsage settings for this PKCS #10 requst, or None if\n" "the request has no ExtendedKeyUsage extension.\n" ; static PyObject * -pkcs10_object_get_extended_key_usage(pkcs10_object *self) +pkcs10_object_get_eku(pkcs10_object *self) { - return extension_get_extended_key_usage(pkcs10_object_extension_helper(self)); + return extension_get_eku(pkcs10_object_extension_helper(self)); } -static char pkcs10_object_set_extended_key_usage__doc__[] = +static char pkcs10_object_set_eku__doc__[] = "Set the ExtendedKeyUsage extension for this PKCS #10 request.\n" "\n" "Argument \"iterable\" should be an iterable object which returns one or more\n" @@ -8590,9 +8590,9 @@ static char pkcs10_object_set_extended_key_usage__doc__[] = ; static PyObject * -pkcs10_object_set_extended_key_usage(pkcs10_object *self, PyObject *args) +pkcs10_object_set_eku(pkcs10_object *self, PyObject *args) { - return extension_set_extended_key_usage(pkcs10_object_extension_helper(self), args); + return extension_set_eku(pkcs10_object_extension_helper(self), args); } static char pkcs10_object_get_basic_constraints__doc__[] = @@ -8763,8 +8763,8 @@ static struct PyMethodDef pkcs10_object_methods[] = { Define_Method(pprint, pkcs10_object_pprint, METH_NOARGS), Define_Method(getKeyUsage, pkcs10_object_get_key_usage, METH_NOARGS), Define_Method(setKeyUsage, pkcs10_object_set_key_usage, METH_VARARGS), - Define_Method(getExtendedKeyUsage, pkcs10_object_get_extended_key_usage, METH_NOARGS), - Define_Method(setExtendedKeyUsage, pkcs10_object_set_extended_key_usage, METH_VARARGS), + Define_Method(getEKU, pkcs10_object_get_eku, METH_NOARGS), + Define_Method(setEKU, pkcs10_object_set_eku, METH_VARARGS), Define_Method(getBasicConstraints, pkcs10_object_get_basic_constraints, METH_NOARGS), Define_Method(setBasicConstraints, pkcs10_object_set_basic_constraints, METH_VARARGS), Define_Method(getSIA, pkcs10_object_get_sia, METH_NOARGS), -- cgit v1.2.3 From 4ec274abc733ebc726fb2e450fdc8054344fa43d Mon Sep 17 00:00:00 2001 From: Rob Austein Date: Thu, 13 Feb 2014 23:33:04 +0000 Subject: Failure of one of the _extension_helper() functions isn't really an assertion failure, it's bad input data. OK, it's bad input data that we should never see and would indicate an OpenSSL bug, but still. svn path=/branches/tk671/; revision=5661 --- rpkid/ext/POW.c | 45 ++++++++++++++++++++++----------------------- 1 file changed, 22 insertions(+), 23 deletions(-) (limited to 'rpkid/ext/POW.c') diff --git a/rpkid/ext/POW.c b/rpkid/ext/POW.c index 683427b1..202fc034 100644 --- a/rpkid/ext/POW.c +++ b/rpkid/ext/POW.c @@ -403,6 +403,12 @@ typedef struct { goto error; \ } while (0) +#define lose_value_error(_msg_) \ + do { \ + PyErr_SetString(PyExc_ValueError, (_msg_)); \ + goto error; \ + } while (0) + #define lose_openssl_error(_msg_) \ do { \ set_openssl_exception(OpenSSLErrorObject, (_msg_), 0); \ @@ -1086,9 +1092,7 @@ extension_get_key_usage(X509_EXTENSIONS **exts) ENTERING(extension_get_key_usage); - assert (exts); - - if ((ext = X509V3_get_d2i(*exts, NID_key_usage, NULL, NULL)) == NULL) + if (!exts || (ext = X509V3_get_d2i(*exts, NID_key_usage, NULL, NULL)) == NULL) Py_RETURN_NONE; if ((result = PyFrozenSet_New(NULL)) == NULL) @@ -1127,7 +1131,8 @@ extension_set_key_usage(X509_EXTENSIONS **exts, PyObject *args) ENTERING(extension_set_key_usage); - assert (exts); + if (!exts) + lose_value_error("Object with no X509_EXTENSIONS"); if ((ext = ASN1_BIT_STRING_new()) == NULL) lose_no_memory(); @@ -1181,9 +1186,7 @@ extension_get_basic_constraints(X509_EXTENSIONS **exts) ENTERING(extension_get_basic_constraints); - POW_assert(exts); - - if ((ext = X509V3_get_d2i(*exts, NID_basic_constraints, NULL, NULL)) == NULL) + if (!exts || (ext = X509V3_get_d2i(*exts, NID_basic_constraints, NULL, NULL)) == NULL) Py_RETURN_NONE; if (ext->pathlen == NULL) @@ -1208,7 +1211,8 @@ extension_set_basic_constraints(X509_EXTENSIONS **exts, PyObject *args) ENTERING(extension_set_basic_constraints); - POW_assert(exts); + if (!exts) + lose_value_error("Object with no X509_EXTENSIONS"); if (!PyArg_ParseTuple(args, "O|OO", &is_ca, &pathlen_obj, &critical)) goto error; @@ -1258,9 +1262,7 @@ extension_get_sia(X509_EXTENSIONS **exts) ENTERING(pkcs10_object_get_sia); - POW_assert(exts); - - if ((ext = X509V3_get_d2i(*exts, NID_sinfo_access, NULL, NULL)) == NULL) + if (!exts || (ext = X509V3_get_d2i(*exts, NID_sinfo_access, NULL, NULL)) == NULL) Py_RETURN_NONE; /* @@ -1351,7 +1353,8 @@ extension_set_sia(X509_EXTENSIONS **exts, PyObject *args, PyObject *kwds) ENTERING(extension_set_sia); - POW_assert(exts); + if (!exts) + lose_value_error("Object with no X509_EXTENSIONS"); if (!PyArg_ParseTupleAndKeywords(args, kwds, "|OOO", kwlist, &caRepository, &rpkiManifest, &signedObject)) @@ -1434,9 +1437,7 @@ extension_get_eku(X509_EXTENSIONS **exts) ENTERING(extension_get_eku); - POW_assert(exts); - - if ((ext = X509V3_get_d2i(*exts, NID_ext_key_usage, NULL, NULL)) == NULL) + if (!exts || (ext = X509V3_get_d2i(*exts, NID_ext_key_usage, NULL, NULL)) == NULL) Py_RETURN_NONE; if ((result = PyFrozenSet_New(NULL)) == NULL) @@ -1474,7 +1475,8 @@ extension_set_eku(X509_EXTENSIONS **exts, PyObject *args) ENTERING(extension_set_eku); - POW_assert(exts); + if (!exts) + lose_value_error("Object with no X509_EXTENSIONS"); if ((ext = sk_ASN1_OBJECT_new_null()) == NULL) lose_no_memory(); @@ -1528,9 +1530,7 @@ extension_get_ski(X509_EXTENSIONS **exts) ENTERING(extension_get_ski); - POW_assert(exts); - - if ((ext = X509V3_get_d2i(*exts, NID_subject_key_identifier, NULL, NULL)) == NULL) + if (!exts || (ext = X509V3_get_d2i(*exts, NID_subject_key_identifier, NULL, NULL)) == NULL) Py_RETURN_NONE; result = Py_BuildValue("s#", ASN1_STRING_data(ext), @@ -1551,7 +1551,8 @@ extension_set_ski(X509_EXTENSIONS **exts, PyObject *args) ENTERING(extension_set_ski); - POW_assert(exts); + if (!exts) + lose_value_error("Object with no X509_EXTENSIONS"); if (!PyArg_ParseTuple(args, "s#", &buf, &len)) goto error; @@ -1587,9 +1588,7 @@ extension_get_aki(X509_EXTENSIONS **exts) ENTERING(extension_get_aki); - POW_assert(exts); - - if ((ext = X509V3_get_d2i(*exts, NID_authority_key_identifier, NULL, NULL)) == NULL) + if (!exts || (ext = X509V3_get_d2i(*exts, NID_authority_key_identifier, NULL, NULL)) == NULL) Py_RETURN_NONE; result = Py_BuildValue("s#", ASN1_STRING_data(ext->keyid), -- cgit v1.2.3 From 5e2af311d5865ca916244b3f77c61b270738732e Mon Sep 17 00:00:00 2001 From: Rob Austein Date: Thu, 13 Feb 2014 23:42:30 +0000 Subject: Better way to handle _object_exception_helper() failures. svn path=/branches/tk671/; revision=5662 --- rpkid/ext/POW.c | 48 +++++++++++++++++++++++++++++++++--------------- 1 file changed, 33 insertions(+), 15 deletions(-) (limited to 'rpkid/ext/POW.c') diff --git a/rpkid/ext/POW.c b/rpkid/ext/POW.c index 202fc034..54c8274a 100644 --- a/rpkid/ext/POW.c +++ b/rpkid/ext/POW.c @@ -1092,7 +1092,10 @@ extension_get_key_usage(X509_EXTENSIONS **exts) ENTERING(extension_get_key_usage); - if (!exts || (ext = X509V3_get_d2i(*exts, NID_key_usage, NULL, NULL)) == NULL) + if (!exts) + goto error; + + if ((ext = X509V3_get_d2i(*exts, NID_key_usage, NULL, NULL)) == NULL) Py_RETURN_NONE; if ((result = PyFrozenSet_New(NULL)) == NULL) @@ -1132,7 +1135,7 @@ extension_set_key_usage(X509_EXTENSIONS **exts, PyObject *args) ENTERING(extension_set_key_usage); if (!exts) - lose_value_error("Object with no X509_EXTENSIONS"); + goto error; if ((ext = ASN1_BIT_STRING_new()) == NULL) lose_no_memory(); @@ -1186,7 +1189,10 @@ extension_get_basic_constraints(X509_EXTENSIONS **exts) ENTERING(extension_get_basic_constraints); - if (!exts || (ext = X509V3_get_d2i(*exts, NID_basic_constraints, NULL, NULL)) == NULL) + if (!exts) + goto error; + + if ((ext = X509V3_get_d2i(*exts, NID_basic_constraints, NULL, NULL)) == NULL) Py_RETURN_NONE; if (ext->pathlen == NULL) @@ -1212,7 +1218,7 @@ extension_set_basic_constraints(X509_EXTENSIONS **exts, PyObject *args) ENTERING(extension_set_basic_constraints); if (!exts) - lose_value_error("Object with no X509_EXTENSIONS"); + goto error; if (!PyArg_ParseTuple(args, "O|OO", &is_ca, &pathlen_obj, &critical)) goto error; @@ -1262,7 +1268,10 @@ extension_get_sia(X509_EXTENSIONS **exts) ENTERING(pkcs10_object_get_sia); - if (!exts || (ext = X509V3_get_d2i(*exts, NID_sinfo_access, NULL, NULL)) == NULL) + if (!exts) + goto error; + + if ((ext = X509V3_get_d2i(*exts, NID_sinfo_access, NULL, NULL)) == NULL) Py_RETURN_NONE; /* @@ -1354,7 +1363,7 @@ extension_set_sia(X509_EXTENSIONS **exts, PyObject *args, PyObject *kwds) ENTERING(extension_set_sia); if (!exts) - lose_value_error("Object with no X509_EXTENSIONS"); + goto error; if (!PyArg_ParseTupleAndKeywords(args, kwds, "|OOO", kwlist, &caRepository, &rpkiManifest, &signedObject)) @@ -1437,7 +1446,10 @@ extension_get_eku(X509_EXTENSIONS **exts) ENTERING(extension_get_eku); - if (!exts || (ext = X509V3_get_d2i(*exts, NID_ext_key_usage, NULL, NULL)) == NULL) + if (!exts) + goto error; + + if ((ext = X509V3_get_d2i(*exts, NID_ext_key_usage, NULL, NULL)) == NULL) Py_RETURN_NONE; if ((result = PyFrozenSet_New(NULL)) == NULL) @@ -1476,7 +1488,7 @@ extension_set_eku(X509_EXTENSIONS **exts, PyObject *args) ENTERING(extension_set_eku); if (!exts) - lose_value_error("Object with no X509_EXTENSIONS"); + goto error; if ((ext = sk_ASN1_OBJECT_new_null()) == NULL) lose_no_memory(); @@ -1530,7 +1542,10 @@ extension_get_ski(X509_EXTENSIONS **exts) ENTERING(extension_get_ski); - if (!exts || (ext = X509V3_get_d2i(*exts, NID_subject_key_identifier, NULL, NULL)) == NULL) + if (!exts) + goto error; + + if ((ext = X509V3_get_d2i(*exts, NID_subject_key_identifier, NULL, NULL)) == NULL) Py_RETURN_NONE; result = Py_BuildValue("s#", ASN1_STRING_data(ext), @@ -1552,7 +1567,7 @@ extension_set_ski(X509_EXTENSIONS **exts, PyObject *args) ENTERING(extension_set_ski); if (!exts) - lose_value_error("Object with no X509_EXTENSIONS"); + goto error; if (!PyArg_ParseTuple(args, "s#", &buf, &len)) goto error; @@ -1588,7 +1603,10 @@ extension_get_aki(X509_EXTENSIONS **exts) ENTERING(extension_get_aki); - if (!exts || (ext = X509V3_get_d2i(*exts, NID_authority_key_identifier, NULL, NULL)) == NULL) + if (!exts) + goto error; + + if ((ext = X509V3_get_d2i(*exts, NID_authority_key_identifier, NULL, NULL)) == NULL) Py_RETURN_NONE; result = Py_BuildValue("s#", ASN1_STRING_data(ext->keyid), @@ -2314,8 +2332,8 @@ x509_object_extension_helper(x509_object *self) { if (self && self->x509 && self->x509->cert_info) return &self->x509->cert_info->extensions; - else - return NULL; + PyErr_SetString(PyExc_ValueError, "Can't find X509_EXTENSIONS in X509 object"); + return NULL; } static char x509_object_get_public_key__doc__[] = @@ -4507,8 +4525,8 @@ crl_object_extension_helper(crl_object *self) { if (self && self->crl && self->crl->crl) return &self->crl->crl->extensions; - else - return NULL; + PyErr_SetString(PyExc_ValueError, "Can't find X509_EXTENSIONS in CRL object"); + return NULL; } static char crl_object_get_version__doc__[] = -- cgit v1.2.3 From a25c336c1d7752b60a251fcce51f2fbd81d930bf Mon Sep 17 00:00:00 2001 From: Rob Austein Date: Fri, 21 Feb 2014 02:05:36 +0000 Subject: Add router certificate support to yamltest, rpkic, etc. svn path=/branches/tk671/; revision=5680 --- rpkid/ext/POW.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'rpkid/ext/POW.c') diff --git a/rpkid/ext/POW.c b/rpkid/ext/POW.c index 54c8274a..b5d9ccaf 100644 --- a/rpkid/ext/POW.c +++ b/rpkid/ext/POW.c @@ -1455,7 +1455,7 @@ extension_get_eku(X509_EXTENSIONS **exts) if ((result = PyFrozenSet_New(NULL)) == NULL) goto error; - for (i = 0; sk_ASN1_OBJECT_num(ext); i++) { + for (i = 0; i < sk_ASN1_OBJECT_num(ext); i++) { if ((oid = ASN1_OBJECT_to_PyString(sk_ASN1_OBJECT_value(ext, i))) == NULL || PySet_Add(result, oid) < 0) goto error; -- cgit v1.2.3