aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ext/POW.c91
-rwxr-xr-xrp/rcynic/rcynicng25
-rw-r--r--rpki/POW/__init__.py3
3 files changed, 34 insertions, 85 deletions
diff --git a/ext/POW.c b/ext/POW.c
index a355ed92..3ef06dfb 100644
--- a/ext/POW.c
+++ b/ext/POW.c
@@ -1177,82 +1177,6 @@ _record_validation_status(PyObject *status, const char *code)
return result == 0;
}
-/*
- * Validation callback code for use with x509_verify_cert().
- *
- * There's no direct way to handle exceptions here, so we're depending
- * on x509_store_object_verify() calling PyErr_Occurred() to check
- * (which it has to do anyway to handle exceptions generated by Python
- * callback handlers.
- */
-
-#warning Probably most of this callback handler should become Python code
-
-static int
-validation_status_x509_verify_cert_cb(int ok, X509_STORE_CTX *ctx, PyObject *status)
-{
- switch (ctx->error) {
- case X509_V_OK:
- return ok;
-
- case X509_V_ERR_SUBJECT_ISSUER_MISMATCH:
- /*
- * Informational events, not really errors. ctx->check_issued()
- * is called in many places where failure to find an issuer is not
- * a failure for the calling function. Just leave these alone.
- */
-#warning Could be done in Python
- return ok;
-
- case X509_V_ERR_CRL_HAS_EXPIRED:
- /*
- * This isn't really an error, because CRLs don't really
- * "expire".
- */
-
-#warning Could be done in Python
- return 1;
-
- case X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT:
- /*
- * This is another error that's only an error in the strange world
- * of OpenSSL, but a more serious one. By default, OpenSSL
- * expects all trust anchors to be self-signed. This is not a
- * PKIX requirement, it's just an OpenSSL thing, but one violates
- * it at one's peril, because the only way to convince OpenSSL to
- * allow a non-self-signed trust anchor is to intercept this
- * "error" in the verify callback handler.
- *
- * So this program supports non-self-signed trust anchors, but be
- * warned that enabling this feature may cause this program's
- * output not to work with other OpenSSL-based applications.
- */
-#warning Could be done in Python
-#if 0
- if (allow_non_self_signed_trust_anchor)
- ok = 1;
-#endif
- record_validation_status(status, TRUST_ANCHOR_NOT_SELF_SIGNED);
- return ok;
-
- /*
- * Handle all other OpenSSL verify errors by stuffing an integer
- * into the status set.
- */
-#warning Could be done in Python
- default:
- if (status != Py_None) {
- PyObject *value = PyInt_FromLong(ctx->error);
- PySet_Add(status, value);
- Py_XDECREF(value);
- }
- return ok;
- }
-
- error:
- return ok;
-}
-
/*
@@ -1425,7 +1349,7 @@ static int check_x509(X509 *x,
ok = sk_ACCESS_DESCRIPTION_num(aia) > 0;
for (i = 0; ok && i < sk_ACCESS_DESCRIPTION_num(aia); i++) {
ACCESS_DESCRIPTION *a = sk_ACCESS_DESCRIPTION_value(aia, i);
- ok = (a != NULL && a->location->type == GEN_URI ||
+ ok = (a != NULL && a->location->type == GEN_URI &&
OBJ_obj2nid(a->method) == NID_ad_ca_issuers);
}
if (!ok)
@@ -4958,13 +4882,6 @@ x509_store_ctx_object_verify_cb(int ok, X509_STORE_CTX *ctx)
if (self == NULL)
return ok;
- /*
- * This is where we'd extract flags (allow_*, etc) to pass to the callback handler.
- */
-
- if (self->status != NULL && self->status != Py_None)
- ok = validation_status_x509_verify_cert_cb(ok, ctx, self->status);
-
if (!PyObject_HasAttrString((PyObject *) self, method_name))
return ok;
@@ -7834,6 +7751,9 @@ manifest_object_verify(manifest_object *self, PyObject *args, PyObject *kwds)
lose_openssl_error("Couldn't decode manifest");
}
+ if (status != Py_None && !check_cms(self->cms.cms, status))
+ goto error;
+
if (status != Py_None && !check_manifest(self->cms.cms, self->manifest, status))
goto error;
@@ -8515,6 +8435,9 @@ roa_object_verify(roa_object *self, PyObject *args, PyObject *kwds)
lose_openssl_error("Couldn't decode ROA");
}
+ if (status != Py_None && !check_cms(self->cms.cms, status))
+ goto error;
+
if (status != Py_None && !check_roa(self->cms.cms, self->roa, status))
goto error;
diff --git a/rp/rcynic/rcynicng b/rp/rcynic/rcynicng
index b06154cb..fed75ab2 100755
--- a/rp/rcynic/rcynicng
+++ b/rp/rcynic/rcynicng
@@ -157,6 +157,28 @@ def final_install():
shutil.rmtree(path)
+class X509StoreCTX(rpki.POW.X509StoreCTX):
+
+ @classmethod
+ def subclass(cls, **kwargs):
+ return type(cls.__name__, (cls,), kwargs)
+
+ status = None
+
+ def verify_callback(self, ok):
+ err = self.getError()
+ if err in (codes.X509_V_OK.code, codes.X509_V_ERR_SUBJECT_ISSUER_MISMATCH.code):
+ return ok
+ elif err == codes.X509_V_ERR_CRL_HAS_EXPIRED.code:
+ return True
+ elif err == codes.X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT.code:
+ self.status.add(codes.TRUST_ANCHOR_NOT_SELF_SIGNED)
+ return ok
+ else:
+ self.status.add(codes.find(err))
+ return ok
+
+
class X509(rpki.POW.X509):
def __repr__(self):
@@ -254,7 +276,8 @@ class X509(rpki.POW.X509):
if not is_ta and self.count_uris(self.crldp) == 0:
status.add(codes.MALFORMED_CRLDP_EXTENSION)
try:
- self.verify(trusted = [self] if trusted is None else trusted, crl = crl, status = status)
+ self.verify(trusted = [self] if trusted is None else trusted, crl = crl, status = status,
+ context_class = X509StoreCTX.subclass(status = status))
except rpki.POW.ValidationError as e:
logger.debug("%r rejected: %s", self, e)
status.add(codes.OBJECT_REJECTED)
diff --git a/rpki/POW/__init__.py b/rpki/POW/__init__.py
index 0b961e81..e88fae80 100644
--- a/rpki/POW/__init__.py
+++ b/rpki/POW/__init__.py
@@ -79,6 +79,9 @@ class StatusCodeDB(object):
status.remove(s)
status.add(self._map[s])
+ def find(self, code):
+ return self._map[code]
+
validation_status = StatusCodeDB(
bad = dict(