@@ -4553,6 +4553,50 @@ set_sni_callback(PySSLContext *self, PyObject *arg, void *c)
45534553 return 0 ;
45544554}
45554555
4556+ #if OPENSSL_VERSION_NUMBER < 0x30300000L
4557+ static X509_OBJECT * x509_object_dup (const X509_OBJECT * obj )
4558+ {
4559+ int ok ;
4560+ X509_OBJECT * ret = X509_OBJECT_new ();
4561+ if (ret == NULL ) {
4562+ return NULL ;
4563+ }
4564+ switch (X509_OBJECT_get_type (obj )) {
4565+ case X509_LU_X509 :
4566+ ok = X509_OBJECT_set1_X509 (ret , X509_OBJECT_get0_X509 (obj ));
4567+ break ;
4568+ case X509_LU_CRL :
4569+ /* X509_OBJECT_get0_X509_CRL was not const-correct prior to 3.0.*/
4570+ ok = X509_OBJECT_set1_X509_CRL (
4571+ ret , X509_OBJECT_get0_X509_CRL ((X509_OBJECT * )obj ));
4572+ break ;
4573+ default :
4574+ /* We cannot duplicate unrecognized types in a polyfill, but it is
4575+ * safe to leave an empty object. The caller will ignore it. */
4576+ ok = 1 ;
4577+ break ;
4578+ }
4579+ if (!ok ) {
4580+ X509_OBJECT_free (ret );
4581+ return NULL ;
4582+ }
4583+ return ret ;
4584+ }
4585+
4586+ static STACK_OF (X509_OBJECT ) *
4587+ X509_STORE_get1_objects (X509_STORE * store )
4588+ {
4589+ STACK_OF (X509_OBJECT ) * ret ;
4590+ if (!X509_STORE_lock (store )) {
4591+ return NULL ;
4592+ }
4593+ ret = sk_X509_OBJECT_deep_copy (X509_STORE_get0_objects (store ),
4594+ x509_object_dup , X509_OBJECT_free );
4595+ X509_STORE_unlock (store );
4596+ return ret ;
4597+ }
4598+ #endif
4599+
45564600PyDoc_STRVAR (PySSLContext_sni_callback_doc ,
45574601"Set a callback that will be called when a server name is provided by the SSL/TLS client in the SNI extension.\n\
45584602\n\
@@ -4582,7 +4626,12 @@ _ssl__SSLContext_cert_store_stats_impl(PySSLContext *self)
45824626 int x509 = 0 , crl = 0 , ca = 0 , i ;
45834627
45844628 store = SSL_CTX_get_cert_store (self -> ctx );
4585- objs = X509_STORE_get0_objects (store );
4629+ objs = X509_STORE_get1_objects (store );
4630+ if (objs == NULL ) {
4631+ PyErr_SetString (PyExc_MemoryError , "failed to query cert store" );
4632+ return NULL ;
4633+ }
4634+
45864635 for (i = 0 ; i < sk_X509_OBJECT_num (objs ); i ++ ) {
45874636 obj = sk_X509_OBJECT_value (objs , i );
45884637 switch (X509_OBJECT_get_type (obj )) {
@@ -4596,12 +4645,11 @@ _ssl__SSLContext_cert_store_stats_impl(PySSLContext *self)
45964645 crl ++ ;
45974646 break ;
45984647 default :
4599- /* Ignore X509_LU_FAIL, X509_LU_RETRY, X509_LU_PKEY.
4600- * As far as I can tell they are internal states and never
4601- * stored in a cert store */
4648+ /* Ignore unrecognized types. */
46024649 break ;
46034650 }
46044651 }
4652+ sk_X509_OBJECT_pop_free (objs , X509_OBJECT_free );
46054653 return Py_BuildValue ("{sisisi}" , "x509" , x509 , "crl" , crl ,
46064654 "x509_ca" , ca );
46074655}
@@ -4633,7 +4681,12 @@ _ssl__SSLContext_get_ca_certs_impl(PySSLContext *self, int binary_form)
46334681 }
46344682
46354683 store = SSL_CTX_get_cert_store (self -> ctx );
4636- objs = X509_STORE_get0_objects (store );
4684+ objs = X509_STORE_get1_objects (store );
4685+ if (objs == NULL ) {
4686+ PyErr_SetString (PyExc_MemoryError , "failed to query cert store" );
4687+ goto error ;
4688+ }
4689+
46374690 for (i = 0 ; i < sk_X509_OBJECT_num (objs ); i ++ ) {
46384691 X509_OBJECT * obj ;
46394692 X509 * cert ;
@@ -4661,9 +4714,11 @@ _ssl__SSLContext_get_ca_certs_impl(PySSLContext *self, int binary_form)
46614714 }
46624715 Py_CLEAR (ci );
46634716 }
4717+ sk_X509_OBJECT_pop_free (objs , X509_OBJECT_free );
46644718 return rlist ;
46654719
46664720 error :
4721+ sk_X509_OBJECT_pop_free (objs , X509_OBJECT_free );
46674722 Py_XDECREF (ci );
46684723 Py_XDECREF (rlist );
46694724 return NULL ;
0 commit comments