bpo-18233: Add internal methods to access peer chain (GH-25467)
The internal `_ssl._SSLSocket` object now provides methods to retrieve
the peer cert chain and verified cert chain as a list of Certificate
objects. Certificate objects have methods to convert the cert to a dict,
PEM, or DER (ASN.1).
These are private APIs for now. There is a slim chance to stabilize the
approach and provide a public API for 3.10. Otherwise I'll provide a
stable API in 3.11.
Signed-off-by: Christian Heimes <christian@python.org>
diff --git a/Modules/_ssl.h b/Modules/_ssl.h
index 3fd517b..5fe6504 100644
--- a/Modules/_ssl.h
+++ b/Modules/_ssl.h
@@ -1,6 +1,10 @@
#ifndef Py_SSL_H
#define Py_SSL_H
+/* OpenSSL header files */
+#include "openssl/evp.h"
+#include "openssl/x509.h"
+
/*
* ssl module state
*/
@@ -10,6 +14,7 @@ typedef struct {
PyTypeObject *PySSLSocket_Type;
PyTypeObject *PySSLMemoryBIO_Type;
PyTypeObject *PySSLSession_Type;
+ PyTypeObject *PySSLCertificate_Type;
/* SSL error object */
PyObject *PySSLErrorObject;
PyObject *PySSLCertVerificationErrorObject;
@@ -40,6 +45,30 @@ get_ssl_state(PyObject *module)
(get_ssl_state(_PyType_GetModuleByDef(type, &_sslmodule_def)))
#define get_state_ctx(c) (((PySSLContext *)(c))->state)
#define get_state_sock(s) (((PySSLSocket *)(s))->ctx->state)
-#define get_state_mbio(b) ((_sslmodulestate *)PyType_GetModuleState(Py_TYPE(b)))
+#define get_state_obj(o) ((_sslmodulestate *)PyType_GetModuleState(Py_TYPE(o)))
+#define get_state_mbio(b) get_state_obj(b)
+#define get_state_cert(c) get_state_obj(c)
+
+/* ************************************************************************
+ * certificate
+ */
+
+enum py_ssl_encoding {
+ PY_SSL_ENCODING_PEM=X509_FILETYPE_PEM,
+ PY_SSL_ENCODING_DER=X509_FILETYPE_ASN1,
+ PY_SSL_ENCODING_PEM_AUX=X509_FILETYPE_PEM + 0x100,
+};
+
+typedef struct {
+ PyObject_HEAD
+ X509 *cert;
+ Py_hash_t hash;
+} PySSLCertificate;
+
+/* ************************************************************************
+ * helpers and utils
+ */
+static PyObject *_PySSL_BytesFromBIO(_sslmodulestate *state, BIO *bio);
+static PyObject *_PySSL_UnicodeFromBIO(_sslmodulestate *state, BIO *bio, const char *error);
#endif /* Py_SSL_H */