aboutsummaryrefslogtreecommitdiff
path: root/ext/POW.c
diff options
context:
space:
mode:
Diffstat (limited to 'ext/POW.c')
-rw-r--r--ext/POW.c167
1 files changed, 85 insertions, 82 deletions
diff --git a/ext/POW.c b/ext/POW.c
index 40bd5d02..927750eb 100644
--- a/ext/POW.c
+++ b/ext/POW.c
@@ -1807,14 +1807,14 @@ static int check_aki(PyObject *status, const X509 *issuer, const AUTHORITY_KEYID
* Check a lot of pesky low-level things about RPKI certificates.
*/
-static int check_x509(x509_object *x509,
- STACK_OF(X509) *stack,
+static int check_x509(X509 *x,
+ X509 *issuer,
PyObject *status,
const int is_ta,
- const check_object_type_t object_type)
+ const check_object_type_t object_type,
+ x509_store_ctx_object *ctx)
{
EVP_PKEY *issuer_pkey = NULL, *subject_pkey = NULL;
- unsigned long flags = (X509_V_FLAG_POLICY_CHECK | X509_V_FLAG_EXPLICIT_POLICY | X509_V_FLAG_X509_STRICT);
AUTHORITY_INFO_ACCESS *sia = NULL, *aia = NULL;
STACK_OF(POLICYINFO) *policies = NULL;
ASN1_BIT_STRING *ski_pubkey = NULL;
@@ -1825,12 +1825,12 @@ static int check_x509(x509_object *x509,
unsigned ski_hashlen, afi;
int i, ok, crit, loc, ex_count, is_ca, routercert = 0, ret = 0;
- if (ASN1_INTEGER_cmp(X509_get_serialNumber(x509->x509), asn1_zero) <= 0 ||
- ASN1_INTEGER_cmp(X509_get_serialNumber(x509->x509), asn1_twenty_octets) > 0)
+ if (ASN1_INTEGER_cmp(X509_get_serialNumber(x), asn1_zero) <= 0 ||
+ ASN1_INTEGER_cmp(X509_get_serialNumber(x), asn1_twenty_octets) > 0)
lose_validation_error_from_code(status, BAD_CERTIFICATE_SERIAL_NUMBER);
- if (!check_allowed_time_encoding(X509_get_notBefore(x509->x509)) ||
- !check_allowed_time_encoding(X509_get_notAfter(x509->x509)))
+ if (!check_allowed_time_encoding(X509_get_notBefore(x)) ||
+ !check_allowed_time_encoding(X509_get_notAfter(x)))
lose_validation_error_from_code(status, NONCONFORMANT_ASN1_TIME_VALUE);
/*
@@ -1838,14 +1838,14 @@ static int check_x509(x509_object *x509,
* API functions for them. We wouldn't bother either if they
* weren't forbidden by the RPKI certificate profile.
*/
- if (!x509->x509->cert_info || x509->x509->cert_info->issuerUID || x509->x509->cert_info->subjectUID)
+ if (!x->cert_info || x->cert_info->issuerUID || x->cert_info->subjectUID)
lose_validation_error_from_code(status, NONCONFORMANT_CERTIFICATE_UID);
/*
* Keep track of allowed extensions we've seen. Once we've
* processed all the ones we expect, anything left is an error.
*/
- ex_count = X509_get_ext_count(x509->x509);
+ ex_count = X509_get_ext_count(x);
/*
* We don't use X509_check_ca() to check whether the certificate is
@@ -1853,9 +1853,9 @@ static int check_x509(x509_object *x509,
* certificate profile, but we still call it because we need it (or
* something) to invoke x509v3_cache_extensions() for us.
*/
- (void) X509_check_ca(x509->x509);
+ (void) X509_check_ca(x);
- if ((bc = X509_get_ext_d2i(x509->x509, NID_basic_constraints, &crit, NULL)) != NULL) {
+ if ((bc = X509_get_ext_d2i(x, NID_basic_constraints, &crit, NULL)) != NULL) {
ex_count--;
if (!crit || bc->ca <= 0 || bc->pathlen != NULL)
lose_validation_error_from_code(status, MALFORMED_BASIC_CONSTRAINTS);
@@ -1872,16 +1872,16 @@ static int check_x509(x509_object *x509,
#warning Why are we not checking the critical flag on these extensions?
- if ((aia = X509_get_ext_d2i(x509->x509, NID_info_access, NULL, NULL)) != NULL)
+ if ((aia = X509_get_ext_d2i(x, NID_info_access, NULL, NULL)) != NULL)
ex_count--;
- if ((sia = X509_get_ext_d2i(x509->x509, NID_sinfo_access, NULL, NULL)) != NULL)
+ if ((sia = X509_get_ext_d2i(x, NID_sinfo_access, NULL, NULL)) != NULL)
ex_count--;
- if ((crldp = X509_get_ext_d2i(x509->x509, NID_crl_distribution_points, NULL, NULL)) != NULL)
+ if ((crldp = X509_get_ext_d2i(x, NID_crl_distribution_points, NULL, NULL)) != NULL)
ex_count--;
- if ((eku = X509_get_ext_d2i(x509->x509, NID_ext_key_usage, &crit, NULL)) != NULL) {
+ if ((eku = X509_get_ext_d2i(x, NID_ext_key_usage, &crit, NULL)) != NULL) {
ex_count--;
if (crit || is_ca || object_type != check_object_type_cer || sk_ASN1_OBJECT_num(eku) == 0)
lose_validation_error_from_code(status, INAPPROPRIATE_EKU_EXTENSION);
@@ -1889,27 +1889,27 @@ static int check_x509(x509_object *x509,
routercert |= OBJ_obj2nid(sk_ASN1_OBJECT_value(eku, i)) == NID_id_kp_bgpsec_router;
}
- if (X509_get_version(x509->x509) != 2)
+ if (X509_get_version(x) != 2)
lose_validation_error_from_code(status, WRONG_OBJECT_VERSION);
- if (x509->x509->cert_info == NULL ||
- x509->x509->cert_info->signature == NULL ||
- x509->x509->cert_info->signature->algorithm == NULL ||
- OBJ_obj2nid(x509->x509->cert_info->signature->algorithm) != NID_sha256WithRSAEncryption)
+ if (x->cert_info == NULL ||
+ x->cert_info->signature == NULL ||
+ x->cert_info->signature->algorithm == NULL ||
+ OBJ_obj2nid(x->cert_info->signature->algorithm) != NID_sha256WithRSAEncryption)
lose_validation_error_from_code(status, NONCONFORMANT_SIGNATURE_ALGORITHM);
- if (x509->x509->skid)
+ if (x->skid)
ex_count--;
else
lose_validation_error_from_code(status, SKI_EXTENSION_MISSING);
- if (!check_allowed_dn(X509_get_subject_name(x509->x509)))
+ if (!check_allowed_dn(X509_get_subject_name(x)))
lose_validation_error_from_code_maybe(allow_nonconformant_name, status, NONCONFORMANT_SUBJECT_NAME);
- if (!check_allowed_dn(X509_get_issuer_name(x509->x509)))
+ if (!check_allowed_dn(X509_get_issuer_name(x)))
lose_validation_error_from_code_maybe(allow_nonconformant_name, status, NONCONFORMANT_ISSUER_NAME);
- if ((policies = X509_get_ext_d2i(x509->x509, NID_certificate_policies, &crit, NULL)) != NULL) {
+ if ((policies = X509_get_ext_d2i(x, NID_certificate_policies, &crit, NULL)) != NULL) {
POLICYQUALINFO *qualifier = NULL;
POLICYINFO *policy = NULL;
ex_count--;
@@ -1925,22 +1925,22 @@ static int check_x509(x509_object *x509,
goto error;
}
- if (!X509_EXTENSION_get_critical(X509_get_ext(x509->x509, X509_get_ext_by_NID(x509->x509, NID_key_usage, -1))) ||
- (x509->x509->ex_flags & EXFLAG_KUSAGE) == 0 ||
- x509->x509->ex_kusage != (is_ca ? KU_KEY_CERT_SIGN | KU_CRL_SIGN : KU_DIGITAL_SIGNATURE))
+ if (!X509_EXTENSION_get_critical(X509_get_ext(x, X509_get_ext_by_NID(x, NID_key_usage, -1))) ||
+ (x->ex_flags & EXFLAG_KUSAGE) == 0 ||
+ x->ex_kusage != (is_ca ? KU_KEY_CERT_SIGN | KU_CRL_SIGN : KU_DIGITAL_SIGNATURE))
lose_validation_error_from_code(status, BAD_KEY_USAGE);
ex_count--;
- if (x509->x509->rfc3779_addr) {
+ if (x->rfc3779_addr) {
ex_count--;
if (routercert ||
- (loc = X509_get_ext_by_NID(x509->x509, NID_sbgp_ipAddrBlock, -1)) < 0 ||
- !X509_EXTENSION_get_critical(X509_get_ext(x509->x509, loc)) ||
- !v3_addr_is_canonical(x509->x509->rfc3779_addr) ||
- sk_IPAddressFamily_num(x509->x509->rfc3779_addr) == 0)
+ (loc = X509_get_ext_by_NID(x, NID_sbgp_ipAddrBlock, -1)) < 0 ||
+ !X509_EXTENSION_get_critical(X509_get_ext(x, loc)) ||
+ !v3_addr_is_canonical(x->rfc3779_addr) ||
+ sk_IPAddressFamily_num(x->rfc3779_addr) == 0)
lose_validation_error_from_code(status, BAD_IPADDRBLOCKS);
- for (i = 0; i < sk_IPAddressFamily_num(x509->x509->rfc3779_addr); i++) {
- IPAddressFamily *f = sk_IPAddressFamily_value(x509->x509->rfc3779_addr, i);
+ for (i = 0; i < sk_IPAddressFamily_num(x->rfc3779_addr); i++) {
+ IPAddressFamily *f = sk_IPAddressFamily_value(x->rfc3779_addr, i);
afi = v3_addr_get_afi(f);
if (afi != IANA_AFI_IPV4 && afi != IANA_AFI_IPV6)
lose_validation_error_from_code(status, UNKNOWN_AFI);
@@ -1949,26 +1949,26 @@ static int check_x509(x509_object *x509,
}
}
- if (x509->x509->rfc3779_asid) {
+ if (x->rfc3779_asid) {
ex_count--;
- if ((loc = X509_get_ext_by_NID(x509->x509, NID_sbgp_autonomousSysNum, -1)) < 0 ||
- !X509_EXTENSION_get_critical(X509_get_ext(x509->x509, loc)) ||
- !v3_asid_is_canonical(x509->x509->rfc3779_asid) ||
- x509->x509->rfc3779_asid->asnum == NULL ||
- x509->x509->rfc3779_asid->rdi != NULL ||
- (routercert && x509->x509->rfc3779_asid->asnum->type == ASIdentifierChoice_inherit))
+ if ((loc = X509_get_ext_by_NID(x, NID_sbgp_autonomousSysNum, -1)) < 0 ||
+ !X509_EXTENSION_get_critical(X509_get_ext(x, loc)) ||
+ !v3_asid_is_canonical(x->rfc3779_asid) ||
+ x->rfc3779_asid->asnum == NULL ||
+ x->rfc3779_asid->rdi != NULL ||
+ (routercert && x->rfc3779_asid->asnum->type == ASIdentifierChoice_inherit))
lose_validation_error_from_code(status, BAD_ASIDENTIFIERS);
}
- if (!x509->x509->rfc3779_addr && !x509->x509->rfc3779_asid)
+ if (!x->rfc3779_addr && !x->rfc3779_asid)
lose_validation_error_from_code(status, MISSING_RESOURCES);
- subject_pkey = X509_get_pubkey(x509->x509);
+ subject_pkey = X509_get_pubkey(x);
ok = subject_pkey != NULL;
if (ok) {
ASN1_OBJECT *algorithm;
- (void) X509_PUBKEY_get0_param(&algorithm, NULL, NULL, NULL, X509_get_X509_PUBKEY(x509->x509));
+ (void) X509_PUBKEY_get0_param(&algorithm, NULL, NULL, NULL, X509_get_X509_PUBKEY(x));
switch (OBJ_obj2nid(algorithm)) {
@@ -1992,44 +1992,32 @@ static int check_x509(x509_object *x509,
if (!ok)
lose_validation_error_from_code(status, BAD_PUBLIC_KEY);
- if (x509->x509->skid == NULL ||
- (ski_pubkey = X509_get0_pubkey_bitstr(x509->x509)) == NULL ||
+ if (x->skid == NULL ||
+ (ski_pubkey = X509_get0_pubkey_bitstr(x)) == NULL ||
!EVP_Digest(ski_pubkey->data, ski_pubkey->length,
ski_hashbuf, &ski_hashlen, EVP_sha1(), NULL) ||
ski_hashlen != 20 ||
- ski_hashlen != x509->x509->skid->length ||
- memcmp(ski_hashbuf, x509->x509->skid->data, ski_hashlen))
+ ski_hashlen != x->skid->length ||
+ memcmp(ski_hashbuf, x->skid->data, ski_hashlen))
lose_validation_error_from_code(status, SKI_PUBLIC_KEY_MISMATCH);
- if (x509->x509->akid) {
+ if (x->akid) {
ex_count--;
- if (!check_aki(status, sk_X509_value(stack, 0), x509->x509->akid))
+ if (!check_aki(status, issuer, x->akid))
goto error;
}
- if (!x509->x509->akid && !is_ta)
+ if (!x->akid && !is_ta)
lose_validation_error_from_code(status, AKI_EXTENSION_MISSING);
- if ((issuer_pkey = X509_get_pubkey(sk_X509_value(stack, 0))) == NULL || X509_verify(x509->x509, issuer_pkey) <= 0)
+ if ((issuer_pkey = X509_get_pubkey(issuer)) == NULL || X509_verify(x, issuer_pkey) <= 0)
lose_validation_error_from_code(status, CERTIFICATE_BAD_SIGNATURE);
- /*
- * rcynic.c's check_x509() has a whole lot of complex code here to
- * deal with finding and binding CRLs into the X509_STORE_CTX for
- * non the TA case. Finding we want to handle in Python; binding is
- * something the caller of this function should handle, based on
- * whether or not it has been passed a CRL object as an (as yet
- * unspecified) argument.
- */
-
if (ex_count > 0)
lose_validation_error_from_code(status, DISALLOWED_X509V3_EXTENSION);
- /*
- * rcynic.c's check_x509() also handles setting up the policy
- * binding and trusted certificate stack here, then finally calls
- * X509_verify_cert().
- */
+ X509_VERIFY_PARAM_set_flags(ctx->ctx->param, X509_V_FLAG_POLICY_CHECK | X509_V_FLAG_EXPLICIT_POLICY);
+ X509_VERIFY_PARAM_add0_policy(ctx->ctx->param, OBJ_nid2obj(NID_cp_ipAddr_asNumber));
ret = 1;
@@ -5019,9 +5007,6 @@ static int x509_store_ctx_object_verify_cb(int ok, X509_STORE_CTX *ctx);
static char x509_store_object_verify__doc__[] =
"Verify an X509 certificate object using this certificate store.\n"
"\n"
- "Optional second argument is an iterable that supplies untrusted certificates\n"
- "to be considered when building a chain to the trust anchor.\n"
- "\n"
"This method returns an instance of the store's verification context class.\n"
;
@@ -5030,16 +5015,19 @@ static char x509_store_object_verify__doc__[] =
static PyObject *
x509_store_object_verify(x509_store_object *self, PyObject *args, PyObject *kwds)
{
- static char *kwlist[] = {"cert", "chain", "status", "ta", NULL};
+ static char *kwlist[] = {"cert", "trusted", "crl", "status", "ta", NULL};
x509_store_ctx_object *ctx = NULL;
- STACK_OF(X509) *stack = NULL;
+ STACK_OF(X509) *trusted_stack = NULL;
+ STACK_OF(X509_CRL) *crl_stack = NULL;
x509_object *x509 = NULL;
- PyObject *chain = Py_None;
+ PyObject *trusted = Py_None;
PyObject *status = Py_None;
PyObject *ta = Py_None;
+ crl_object *crl = NULL;
int ok;
- if (!PyArg_ParseTupleAndKeywords(args, kwds, "O!|OO!O", kwlist, &POW_X509_Type, &x509, &chain, &PySet_Type, &status, &ta))
+ if (!PyArg_ParseTupleAndKeywords(args, kwds, "O!|OO!O", kwlist, &POW_X509_Type, &x509, &trusted,
+ &POW_CRL_Type, &crl, &PySet_Type, &status, &ta))
goto error;
if ((ctx = (x509_store_ctx_object *) PyObject_CallFunctionObjArgs(self->ctxclass, self, NULL)) == NULL)
@@ -5051,31 +5039,44 @@ x509_store_object_verify(x509_store_object *self, PyObject *args, PyObject *kwds
if (ctx->ctx == NULL)
lose("Uninitialized X509StoreCTX");
- if (chain != Py_None && (stack = x509_helper_iterable_to_stack(chain)) == NULL)
+ if (trusted != Py_None && (trusted_stack = x509_helper_iterable_to_stack(trusted)) == NULL)
goto error;
- if (status != Py_None && !check_x509(x509, stack, status, PyObject_IsTrue(ta), check_object_type_cer))
+ if (crl != NULL && ((crl_stack = sk_X509_CRL_new_null()) == NULL || !sk_X509_CRL_push(crl_stack, crl->crl)))
+ lose_no_memory();
+
+ if (crl != NULL)
+ X509_VERIFY_PARAM_set_flags(ctx->ctx->param, X509_V_FLAG_CRL_CHECK);
+
+ if (status != Py_None && !check_x509(x509->x509, sk_X509_value(trusted_stack, 0), status,
+ PyObject_IsTrue(ta), check_object_type_cer, ctx))
goto error;
Py_XINCREF(x509);
- Py_XINCREF(chain);
+ Py_XINCREF(trusted);
+ Py_XINCREF(crl);
Py_XINCREF(status);
X509_STORE_CTX_set_cert(ctx->ctx, x509->x509);
- X509_STORE_CTX_set_chain(ctx->ctx, stack);
+ X509_STORE_CTX_trusted_stack(ctx->ctx, trusted_stack);
+ X509_STORE_CTX_set0_crls(ctx->ctx, crl_stack);
ctx->status = status;
X509_STORE_CTX_set_verify_cb(ctx->ctx, x509_store_ctx_object_verify_cb);
+ X509_VERIFY_PARAM_set_flags(ctx->ctx->param, X509_V_FLAG_X509_STRICT);
ok = X509_verify_cert(ctx->ctx);
ctx->status = NULL;
- X509_STORE_CTX_set_chain(ctx->ctx, NULL);
+ X509_STORE_CTX_set0_crls(ctx->ctx, NULL);
+ X509_STORE_CTX_trusted_stack(ctx->ctx, NULL);
X509_STORE_CTX_set_cert(ctx->ctx, NULL);
Py_XDECREF(status);
- Py_XDECREF(chain);
+ Py_XDECREF(crl);
+ Py_XDECREF(trusted);
Py_XDECREF(x509);
- sk_X509_free(stack);
+ sk_X509_free(trusted_stack);
+ sk_X509_CRL_free(crl_stack);
if (PyErr_Occurred())
goto error;
@@ -5085,7 +5086,9 @@ x509_store_object_verify(x509_store_object *self, PyObject *args, PyObject *kwds
return (PyObject *) ctx;
- error: /* fall through */
+ error:
+ sk_X509_free(trusted_stack);
+ sk_X509_CRL_free(crl_stack);
Py_XDECREF(ctx);
return NULL;
}