@@ -1881,12 +1881,6 @@ class X509StoreContext:
18811881 of a certificate in a described context. For describing such a context, see
18821882 :class:`X509Store`.
18831883
1884- :ivar _store_ctx: The underlying X509_STORE_CTX structure used by this
1885- instance. It is dynamically allocated and automatically garbage
1886- collected.
1887- :ivar _store: See the ``store`` ``__init__`` parameter.
1888- :ivar _cert: See the ``certificate`` ``__init__`` parameter.
1889- :ivar _chain: See the ``chain`` ``__init__`` parameter.
18901884 :param X509Store store: The certificates which will be trusted for the
18911885 purposes of any verifications.
18921886 :param X509 certificate: The certificate to be verified.
@@ -1901,15 +1895,9 @@ def __init__(
19011895 certificate : X509 ,
19021896 chain : Optional [Sequence [X509 ]] = None ,
19031897 ) -> None :
1904- store_ctx = _lib .X509_STORE_CTX_new ()
1905- self ._store_ctx = _ffi .gc (store_ctx , _lib .X509_STORE_CTX_free )
19061898 self ._store = store
19071899 self ._cert = certificate
19081900 self ._chain = self ._build_certificate_stack (chain )
1909- # Make the store context available for use after instantiating this
1910- # class by initializing it now. Per testing, subsequent calls to
1911- # :meth:`_init` have no adverse affect.
1912- self ._init ()
19131901
19141902 @staticmethod
19151903 def _build_certificate_stack (
@@ -1941,28 +1929,8 @@ def cleanup(s: Any) -> None:
19411929
19421930 return stack
19431931
1944- def _init (self ) -> None :
1945- """
1946- Set up the store context for a subsequent verification operation.
1947-
1948- Calling this method more than once without first calling
1949- :meth:`_cleanup` will leak memory.
1950- """
1951- ret = _lib .X509_STORE_CTX_init (
1952- self ._store_ctx , self ._store ._store , self ._cert ._x509 , self ._chain
1953- )
1954- if ret <= 0 :
1955- _raise_current_error ()
1956-
1957- def _cleanup (self ) -> None :
1958- """
1959- Internally cleans up the store context.
1960-
1961- The store context can then be reused with a new call to :meth:`_init`.
1962- """
1963- _lib .X509_STORE_CTX_cleanup (self ._store_ctx )
1964-
1965- def _exception_from_context (self ) -> X509StoreContextError :
1932+ @staticmethod
1933+ def _exception_from_context (store_ctx : Any ) -> X509StoreContextError :
19661934 """
19671935 Convert an OpenSSL native context error failure into a Python
19681936 exception.
@@ -1972,21 +1940,45 @@ def _exception_from_context(self) -> X509StoreContextError:
19721940 """
19731941 message = _ffi .string (
19741942 _lib .X509_verify_cert_error_string (
1975- _lib .X509_STORE_CTX_get_error (self . _store_ctx )
1943+ _lib .X509_STORE_CTX_get_error (store_ctx )
19761944 )
19771945 ).decode ("utf-8" )
19781946 errors = [
1979- _lib .X509_STORE_CTX_get_error (self . _store_ctx ),
1980- _lib .X509_STORE_CTX_get_error_depth (self . _store_ctx ),
1947+ _lib .X509_STORE_CTX_get_error (store_ctx ),
1948+ _lib .X509_STORE_CTX_get_error_depth (store_ctx ),
19811949 message ,
19821950 ]
19831951 # A context error should always be associated with a certificate, so we
19841952 # expect this call to never return :class:`None`.
1985- _x509 = _lib .X509_STORE_CTX_get_current_cert (self . _store_ctx )
1953+ _x509 = _lib .X509_STORE_CTX_get_current_cert (store_ctx )
19861954 _cert = _lib .X509_dup (_x509 )
19871955 pycert = X509 ._from_raw_x509_ptr (_cert )
19881956 return X509StoreContextError (message , errors , pycert )
19891957
1958+ def _verify_certificate (self ) -> Any :
1959+ """
1960+ Verifies the certificate and runs an X509_STORE_CTX containing the
1961+ results.
1962+
1963+ :raises X509StoreContextError: If an error occurred when validating a
1964+ certificate in the context. Sets ``certificate`` attribute to
1965+ indicate which certificate caused the error.
1966+ """
1967+ store_ctx = _lib .X509_STORE_CTX_new ()
1968+ _openssl_assert (store_ctx != _ffi .NULL )
1969+ store_ctx = _ffi .gc (store_ctx , _lib .X509_STORE_CTX_free )
1970+
1971+ ret = _lib .X509_STORE_CTX_init (
1972+ store_ctx , self ._store ._store , self ._cert ._x509 , self ._chain
1973+ )
1974+ _openssl_assert (ret == 1 )
1975+
1976+ ret = _lib .X509_verify_cert (store_ctx )
1977+ if ret <= 0 :
1978+ raise self ._exception_from_context (store_ctx )
1979+
1980+ return store_ctx
1981+
19901982 def set_store (self , store : X509Store ) -> None :
19911983 """
19921984 Set the context's X.509 store.
@@ -2008,17 +2000,7 @@ def verify_certificate(self) -> None:
20082000 certificate in the context. Sets ``certificate`` attribute to
20092001 indicate which certificate caused the error.
20102002 """
2011- # Always re-initialize the store context in case
2012- # :meth:`verify_certificate` is called multiple times.
2013- #
2014- # :meth:`_init` is called in :meth:`__init__` so _cleanup is called
2015- # before _init to ensure memory is not leaked.
2016- self ._cleanup ()
2017- self ._init ()
2018- ret = _lib .X509_verify_cert (self ._store_ctx )
2019- self ._cleanup ()
2020- if ret <= 0 :
2021- raise self ._exception_from_context ()
2003+ self ._verify_certificate ()
20222004
20232005 def get_verified_chain (self ) -> List [X509 ]:
20242006 """
@@ -2031,20 +2013,10 @@ def get_verified_chain(self) -> List[X509]:
20312013
20322014 .. versionadded:: 20.0
20332015 """
2034- # Always re-initialize the store context in case
2035- # :meth:`verify_certificate` is called multiple times.
2036- #
2037- # :meth:`_init` is called in :meth:`__init__` so _cleanup is called
2038- # before _init to ensure memory is not leaked.
2039- self ._cleanup ()
2040- self ._init ()
2041- ret = _lib .X509_verify_cert (self ._store_ctx )
2042- if ret <= 0 :
2043- self ._cleanup ()
2044- raise self ._exception_from_context ()
2016+ store_ctx = self ._verify_certificate ()
20452017
20462018 # Note: X509_STORE_CTX_get1_chain returns a deep copy of the chain.
2047- cert_stack = _lib .X509_STORE_CTX_get1_chain (self . _store_ctx )
2019+ cert_stack = _lib .X509_STORE_CTX_get1_chain (store_ctx )
20482020 _openssl_assert (cert_stack != _ffi .NULL )
20492021
20502022 result = []
@@ -2056,7 +2028,6 @@ def get_verified_chain(self) -> List[X509]:
20562028
20572029 # Free the stack but not the members which are freed by the X509 class.
20582030 _lib .sk_X509_free (cert_stack )
2059- self ._cleanup ()
20602031 return result
20612032
20622033
0 commit comments