Hi Python enthusiasts, Currently _ssl.c always reports CERTIFICATE_VERIFY_FAILED for any certification verification errors. In OpenSSL, it's possible to tell from different reasons that lead to CERTIFICATE_VERIFY_FAILED. For example, https://expired.badssl.com/ reports X509_V_ERR_CERT_HAS_EXPIRED, and https://self-signed.badssl.com/ reports X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT. Seems CPython does not expose such information yet? I hope it can be added to CPython. For example, creating a new exception class SSLCertificateError, which is a subclass of SSLError, that provides error codes like X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT. Any ideas?
The attachment is a naive try to printf some information about a verification failure. It's just a proof-of-concept and does not provide any practical advantage :) Best, Yen Chi Hsuan
diff --git a/Modules/_ssl.c b/Modules/_ssl.c --- a/Modules/_ssl.c +++ b/Modules/_ssl.c @@ -2770,16 +2770,24 @@ get_verify_mode(PySSLContext *self, void case SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT: return PyLong_FromLong(PY_SSL_CERT_REQUIRED); } PyErr_SetString(PySSLErrorObject, "invalid return value from SSL_CTX_get_verify_mode"); return NULL; } +static int verify_cb(int ok, X509_STORE_CTX *ctx) +{ + long x509_err = X509_STORE_CTX_get_error(ctx); + printf("ok = %d, err = %ld, errstr = %s\n", ok, x509_err, + X509_verify_cert_error_string(x509_err)); + return ok; +} + static int set_verify_mode(PySSLContext *self, PyObject *arg, void *c) { int n, mode; if (!PyArg_Parse(arg, "i", &n)) return -1; if (n == PY_SSL_CERT_NONE) mode = SSL_VERIFY_NONE; @@ -2794,16 +2802,22 @@ set_verify_mode(PySSLContext *self, PyOb } if (mode == SSL_VERIFY_NONE && self->check_hostname) { PyErr_SetString(PyExc_ValueError, "Cannot set verify_mode to CERT_NONE when " "check_hostname is enabled."); return -1; } SSL_CTX_set_verify(self->ctx, mode, NULL); + + { + X509_STORE *store = SSL_CTX_get_cert_store(self->ctx); + X509_STORE_set_verify_cb(store, verify_cb); + } + return 0; } static PyObject * get_verify_flags(PySSLContext *self, void *c) { X509_STORE *store; X509_VERIFY_PARAM *param;
_______________________________________________ Python-ideas mailing list Python-ideas@python.org https://mail.python.org/mailman/listinfo/python-ideas Code of Conduct: http://python.org/psf/codeofconduct/