@@ -106,6 +106,10 @@ struct py_ssl_library_code {
106106# define PY_OPENSSL_1_1_API 1
107107#endif
108108
109+ #if (OPENSSL_VERSION_NUMBER >= 0x30300000L ) && !defined(LIBRESSL_VERSION_NUMBER )
110+ # define OPENSSL_VERSION_3_3 1
111+ #endif
112+
109113/* LibreSSL 2.7.0 provides necessary OpenSSL 1.1.0 APIs */
110114#if defined(LIBRESSL_VERSION_NUMBER ) && LIBRESSL_VERSION_NUMBER >= 0x2070000fL
111115# define PY_OPENSSL_1_1_API 1
@@ -161,6 +165,16 @@ struct py_ssl_library_code {
161165#define HAVE_OPENSSL_CRYPTO_LOCK
162166#endif
163167
168+ /* OpenSSL 1.1+ allows locking X509_STORE, 1.0.2 doesn't. */
169+ #ifdef OPENSSL_VERSION_1_1
170+ #define HAVE_OPENSSL_X509_STORE_LOCK
171+ #endif
172+
173+ /* OpenSSL 3.3 added the X509_STORE_get1_objects API */
174+ #ifdef OPENSSL_VERSION_3_3
175+ #define HAVE_OPENSSL_X509_STORE_GET1_OBJECTS 1
176+ #endif
177+
164178#if defined(OPENSSL_VERSION_1_1 ) && !defined(OPENSSL_NO_SSL2 )
165179#define OPENSSL_NO_SSL2
166180#endif
@@ -3504,7 +3518,15 @@ cert_store_stats(PySSLContext *self)
35043518 int x509 = 0 , crl = 0 , ca = 0 , i ;
35053519
35063520 store = SSL_CTX_get_cert_store (self -> ctx );
3507- objs = X509_STORE_get0_objects (store );
3521+ #if HAVE_OPENSSL_X509_STORE_GET1_OBJECTS
3522+ objs = X509_STORE_get1_objects (store );
3523+ if (objs == NULL ) {
3524+ PyErr_SetString (PyExc_MemoryError , "failed to query cert store" );
3525+ return NULL ;
3526+ }
3527+ #else
3528+ objs = X509_STORE_get0_objects (store );
3529+ #endif
35083530 for (i = 0 ; i < sk_X509_OBJECT_num (objs ); i ++ ) {
35093531 obj = sk_X509_OBJECT_value (objs , i );
35103532 switch (X509_OBJECT_get_type (obj )) {
@@ -3521,9 +3543,15 @@ cert_store_stats(PySSLContext *self)
35213543 /* Ignore X509_LU_FAIL, X509_LU_RETRY, X509_LU_PKEY.
35223544 * As far as I can tell they are internal states and never
35233545 * stored in a cert store */
3546+ /* Ignore enrecognized types */
35243547 break ;
35253548 }
35263549 }
3550+
3551+ #if HAVE_OPENSSL_X509_STORE_GET1_OBJECTS
3552+ sk_X509_OBJECT_pop_free (objs , X509_OBJECT_free );
3553+ #endif
3554+
35273555 return Py_BuildValue ("{sisisi}" , "x509" , x509 , "crl" , crl ,
35283556 "x509_ca" , ca );
35293557}
@@ -3558,9 +3586,16 @@ get_ca_certs(PySSLContext *self, PyObject *args, PyObject *kwds)
35583586 if ((rlist = PyList_New (0 )) == NULL ) {
35593587 return NULL ;
35603588 }
3561-
35623589 store = SSL_CTX_get_cert_store (self -> ctx );
3590+ #if HAVE_OPENSSL_X509_STORE_GET1_OBJECTS
3591+ objs = X509_STORE_get1_objects (store );
3592+ if (objs == NULL ) {
3593+ PyErr_SetString (PyExc_MemoryError , "failed to query cert store" );
3594+ return NULL ;
3595+ }
3596+ #else
35633597 objs = X509_STORE_get0_objects (store );
3598+ #endif
35643599 for (i = 0 ; i < sk_X509_OBJECT_num (objs ); i ++ ) {
35653600 X509_OBJECT * obj ;
35663601 X509 * cert ;
@@ -3588,9 +3623,15 @@ get_ca_certs(PySSLContext *self, PyObject *args, PyObject *kwds)
35883623 }
35893624 Py_CLEAR (ci );
35903625 }
3626+ #if HAVE_OPENSSL_X509_STORE_GET1_OBJECTS
3627+ sk_X509_OBJECT_pop_free (objs , X509_OBJECT_free );
3628+ #endif
35913629 return rlist ;
35923630
35933631 error :
3632+ #if HAVE_OPENSSL_X509_STORE_GET1_OBJECTS
3633+ sk_X509_OBJECT_pop_free (objs , X509_OBJECT_free );
3634+ #endif
35943635 Py_XDECREF (ci );
35953636 Py_XDECREF (rlist );
35963637 return NULL ;
@@ -4642,3 +4683,51 @@ init_ssl(void)
46424683 return ;
46434684}
46444685
4686+ /* Shim of X509_STORE_get1_objects API from OpenSSL 3.3
4687+ * Only available with the X509_STORE_lock() API */
4688+ #if defined(HAVE_OPENSSL_X509_STORE_LOCK ) && !defined(OPENSSL_VERSION_3_3 )
4689+ #define HAVE_OPENSSL_X509_STORE_GET1_OBJECTS 1
4690+
4691+ static X509_OBJECT * x509_object_dup (const X509_OBJECT * obj )
4692+ {
4693+ int ok ;
4694+ X509_OBJECT * ret = X509_OBJECT_new ();
4695+ if (ret == NULL ) {
4696+ return NULL ;
4697+ }
4698+ switch (X509_OBJECT_get_type (obj )) {
4699+ case X509_LU_X509 :
4700+ ok = X509_OBJECT_set1_X509 (ret , X509_OBJECT_get0_X509 (obj ));
4701+ break ;
4702+ case X509_LU_CRL :
4703+ /* X509_OBJECT_get0_X509_CRL was not const-correct prior to 3.0.*/
4704+ ok = X509_OBJECT_set1_X509_CRL (
4705+ ret , X509_OBJECT_get0_X509_CRL ((X509_OBJECT * )obj ));
4706+ break ;
4707+ default :
4708+ /* We cannot duplicate unrecognized types in a polyfill, but it is
4709+ * safe to leave an empty object. The caller will ignore it. */
4710+ ok = 1 ;
4711+ break ;
4712+ }
4713+ if (!ok ) {
4714+ X509_OBJECT_free (ret );
4715+ return NULL ;
4716+ }
4717+ return ret ;
4718+ }
4719+
4720+ static STACK_OF (X509_OBJECT ) *
4721+ X509_STORE_get1_objects (X509_STORE * store )
4722+ {
4723+ STACK_OF (X509_OBJECT ) * ret ;
4724+ if (!X509_STORE_lock (store )) {
4725+ return NULL ;
4726+ }
4727+ ret = sk_X509_OBJECT_deep_copy (X509_STORE_get0_objects (store ),
4728+ x509_object_dup , X509_OBJECT_free );
4729+ X509_STORE_unlock (store );
4730+ return ret ;
4731+ }
4732+ #endif
4733+
0 commit comments