google-auth 2.55.1__tar.gz → 2.55.2__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (199) hide show
  1. {google_auth-2.55.1/google_auth.egg-info → google_auth-2.55.2}/PKG-INFO +9 -8
  2. {google_auth-2.55.1 → google_auth-2.55.2}/google/auth/_agent_identity_utils.py +55 -18
  3. {google_auth-2.55.1 → google_auth-2.55.2}/google/auth/aio/_helpers.py +10 -1
  4. {google_auth-2.55.1 → google_auth-2.55.2}/google/auth/aio/transport/aiohttp.py +1 -1
  5. {google_auth-2.55.1 → google_auth-2.55.2}/google/auth/aio/transport/mtls.py +25 -39
  6. {google_auth-2.55.1 → google_auth-2.55.2}/google/auth/aio/transport/sessions.py +37 -15
  7. {google_auth-2.55.1 → google_auth-2.55.2}/google/auth/compute_engine/_mtls.py +10 -4
  8. {google_auth-2.55.1 → google_auth-2.55.2}/google/auth/identity_pool.py +29 -24
  9. {google_auth-2.55.1 → google_auth-2.55.2}/google/auth/transport/_aiohttp_requests.py +2 -1
  10. {google_auth-2.55.1 → google_auth-2.55.2}/google/auth/transport/_custom_tls_signer.py +18 -11
  11. {google_auth-2.55.1 → google_auth-2.55.2}/google/auth/transport/_mtls_helper.py +350 -44
  12. {google_auth-2.55.1 → google_auth-2.55.2}/google/auth/transport/grpc.py +23 -17
  13. {google_auth-2.55.1 → google_auth-2.55.2}/google/auth/transport/requests.py +61 -37
  14. {google_auth-2.55.1 → google_auth-2.55.2}/google/auth/transport/urllib3.py +45 -30
  15. {google_auth-2.55.1 → google_auth-2.55.2}/google/auth/version.py +1 -1
  16. {google_auth-2.55.1 → google_auth-2.55.2/google_auth.egg-info}/PKG-INFO +9 -8
  17. {google_auth-2.55.1 → google_auth-2.55.2}/google_auth.egg-info/SOURCES.txt +1 -0
  18. {google_auth-2.55.1 → google_auth-2.55.2}/google_auth.egg-info/requires.txt +16 -6
  19. {google_auth-2.55.1 → google_auth-2.55.2}/setup.py +11 -18
  20. {google_auth-2.55.1 → google_auth-2.55.2}/tests/compute_engine/test__mtls.py +52 -12
  21. {google_auth-2.55.1 → google_auth-2.55.2}/tests/test_agent_identity_utils.py +144 -5
  22. {google_auth-2.55.1 → google_auth-2.55.2}/tests/test_identity_pool.py +6 -7
  23. google_auth-2.55.2/tests/transport/aio/conftest.py +46 -0
  24. {google_auth-2.55.1 → google_auth-2.55.2}/tests/transport/aio/test_aiohttp.py +5 -1
  25. google_auth-2.55.2/tests/transport/aio/test_sessions_mtls.py +348 -0
  26. {google_auth-2.55.1 → google_auth-2.55.2}/tests/transport/test__custom_tls_signer.py +112 -10
  27. {google_auth-2.55.1 → google_auth-2.55.2}/tests/transport/test__mtls_helper.py +615 -22
  28. {google_auth-2.55.1 → google_auth-2.55.2}/tests/transport/test_aio_mtls_helper.py +36 -19
  29. {google_auth-2.55.1 → google_auth-2.55.2}/tests/transport/test_grpc.py +168 -8
  30. {google_auth-2.55.1 → google_auth-2.55.2}/tests/transport/test_requests.py +149 -33
  31. {google_auth-2.55.1 → google_auth-2.55.2}/tests/transport/test_urllib3.py +165 -27
  32. google_auth-2.55.1/tests/transport/aio/test_sessions_mtls.py +0 -142
  33. {google_auth-2.55.1 → google_auth-2.55.2}/LICENSE +0 -0
  34. {google_auth-2.55.1 → google_auth-2.55.2}/MANIFEST.in +0 -0
  35. {google_auth-2.55.1 → google_auth-2.55.2}/README.rst +0 -0
  36. {google_auth-2.55.1 → google_auth-2.55.2}/google/auth/__init__.py +0 -0
  37. {google_auth-2.55.1 → google_auth-2.55.2}/google/auth/_cache.py +0 -0
  38. {google_auth-2.55.1 → google_auth-2.55.2}/google/auth/_cloud_sdk.py +0 -0
  39. {google_auth-2.55.1 → google_auth-2.55.2}/google/auth/_credentials_async.py +0 -0
  40. {google_auth-2.55.1 → google_auth-2.55.2}/google/auth/_credentials_base.py +0 -0
  41. {google_auth-2.55.1 → google_auth-2.55.2}/google/auth/_default.py +0 -0
  42. {google_auth-2.55.1 → google_auth-2.55.2}/google/auth/_default_async.py +0 -0
  43. {google_auth-2.55.1 → google_auth-2.55.2}/google/auth/_exponential_backoff.py +0 -0
  44. {google_auth-2.55.1 → google_auth-2.55.2}/google/auth/_helpers.py +0 -0
  45. {google_auth-2.55.1 → google_auth-2.55.2}/google/auth/_jwt_async.py +0 -0
  46. {google_auth-2.55.1 → google_auth-2.55.2}/google/auth/_oauth2client.py +0 -0
  47. {google_auth-2.55.1 → google_auth-2.55.2}/google/auth/_refresh_worker.py +0 -0
  48. {google_auth-2.55.1 → google_auth-2.55.2}/google/auth/_regional_access_boundary_utils.py +0 -0
  49. {google_auth-2.55.1 → google_auth-2.55.2}/google/auth/_service_account_info.py +0 -0
  50. {google_auth-2.55.1 → google_auth-2.55.2}/google/auth/aio/__init__.py +0 -0
  51. {google_auth-2.55.1 → google_auth-2.55.2}/google/auth/aio/credentials.py +0 -0
  52. {google_auth-2.55.1 → google_auth-2.55.2}/google/auth/aio/transport/__init__.py +0 -0
  53. {google_auth-2.55.1 → google_auth-2.55.2}/google/auth/api_key.py +0 -0
  54. {google_auth-2.55.1 → google_auth-2.55.2}/google/auth/app_engine.py +0 -0
  55. {google_auth-2.55.1 → google_auth-2.55.2}/google/auth/aws.py +0 -0
  56. {google_auth-2.55.1 → google_auth-2.55.2}/google/auth/compute_engine/__init__.py +0 -0
  57. {google_auth-2.55.1 → google_auth-2.55.2}/google/auth/compute_engine/_metadata.py +0 -0
  58. {google_auth-2.55.1 → google_auth-2.55.2}/google/auth/compute_engine/credentials.py +0 -0
  59. {google_auth-2.55.1 → google_auth-2.55.2}/google/auth/credentials.py +0 -0
  60. {google_auth-2.55.1 → google_auth-2.55.2}/google/auth/crypt/__init__.py +0 -0
  61. {google_auth-2.55.1 → google_auth-2.55.2}/google/auth/crypt/_cryptography_rsa.py +0 -0
  62. {google_auth-2.55.1 → google_auth-2.55.2}/google/auth/crypt/_helpers.py +0 -0
  63. {google_auth-2.55.1 → google_auth-2.55.2}/google/auth/crypt/_python_rsa.py +0 -0
  64. {google_auth-2.55.1 → google_auth-2.55.2}/google/auth/crypt/base.py +0 -0
  65. {google_auth-2.55.1 → google_auth-2.55.2}/google/auth/crypt/es.py +0 -0
  66. {google_auth-2.55.1 → google_auth-2.55.2}/google/auth/crypt/es256.py +0 -0
  67. {google_auth-2.55.1 → google_auth-2.55.2}/google/auth/crypt/rsa.py +0 -0
  68. {google_auth-2.55.1 → google_auth-2.55.2}/google/auth/downscoped.py +0 -0
  69. {google_auth-2.55.1 → google_auth-2.55.2}/google/auth/environment_vars.py +0 -0
  70. {google_auth-2.55.1 → google_auth-2.55.2}/google/auth/exceptions.py +0 -0
  71. {google_auth-2.55.1 → google_auth-2.55.2}/google/auth/external_account.py +0 -0
  72. {google_auth-2.55.1 → google_auth-2.55.2}/google/auth/external_account_authorized_user.py +0 -0
  73. {google_auth-2.55.1 → google_auth-2.55.2}/google/auth/iam.py +0 -0
  74. {google_auth-2.55.1 → google_auth-2.55.2}/google/auth/impersonated_credentials.py +0 -0
  75. {google_auth-2.55.1 → google_auth-2.55.2}/google/auth/jwt.py +0 -0
  76. {google_auth-2.55.1 → google_auth-2.55.2}/google/auth/metrics.py +0 -0
  77. {google_auth-2.55.1 → google_auth-2.55.2}/google/auth/pluggable.py +0 -0
  78. {google_auth-2.55.1 → google_auth-2.55.2}/google/auth/py.typed +0 -0
  79. {google_auth-2.55.1 → google_auth-2.55.2}/google/auth/transport/__init__.py +0 -0
  80. {google_auth-2.55.1 → google_auth-2.55.2}/google/auth/transport/_http_client.py +0 -0
  81. {google_auth-2.55.1 → google_auth-2.55.2}/google/auth/transport/_requests_base.py +0 -0
  82. {google_auth-2.55.1 → google_auth-2.55.2}/google/auth/transport/mtls.py +0 -0
  83. {google_auth-2.55.1 → google_auth-2.55.2}/google/oauth2/__init__.py +0 -0
  84. {google_auth-2.55.1 → google_auth-2.55.2}/google/oauth2/_client.py +0 -0
  85. {google_auth-2.55.1 → google_auth-2.55.2}/google/oauth2/_client_async.py +0 -0
  86. {google_auth-2.55.1 → google_auth-2.55.2}/google/oauth2/_credentials_async.py +0 -0
  87. {google_auth-2.55.1 → google_auth-2.55.2}/google/oauth2/_id_token_async.py +0 -0
  88. {google_auth-2.55.1 → google_auth-2.55.2}/google/oauth2/_reauth_async.py +0 -0
  89. {google_auth-2.55.1 → google_auth-2.55.2}/google/oauth2/_service_account_async.py +0 -0
  90. {google_auth-2.55.1 → google_auth-2.55.2}/google/oauth2/challenges.py +0 -0
  91. {google_auth-2.55.1 → google_auth-2.55.2}/google/oauth2/credentials.py +0 -0
  92. {google_auth-2.55.1 → google_auth-2.55.2}/google/oauth2/gdch_credentials.py +0 -0
  93. {google_auth-2.55.1 → google_auth-2.55.2}/google/oauth2/id_token.py +0 -0
  94. {google_auth-2.55.1 → google_auth-2.55.2}/google/oauth2/py.typed +0 -0
  95. {google_auth-2.55.1 → google_auth-2.55.2}/google/oauth2/reauth.py +0 -0
  96. {google_auth-2.55.1 → google_auth-2.55.2}/google/oauth2/service_account.py +0 -0
  97. {google_auth-2.55.1 → google_auth-2.55.2}/google/oauth2/sts.py +0 -0
  98. {google_auth-2.55.1 → google_auth-2.55.2}/google/oauth2/utils.py +0 -0
  99. {google_auth-2.55.1 → google_auth-2.55.2}/google/oauth2/webauthn_handler.py +0 -0
  100. {google_auth-2.55.1 → google_auth-2.55.2}/google/oauth2/webauthn_handler_factory.py +0 -0
  101. {google_auth-2.55.1 → google_auth-2.55.2}/google/oauth2/webauthn_types.py +0 -0
  102. {google_auth-2.55.1 → google_auth-2.55.2}/google_auth.egg-info/dependency_links.txt +0 -0
  103. {google_auth-2.55.1 → google_auth-2.55.2}/google_auth.egg-info/top_level.txt +0 -0
  104. {google_auth-2.55.1 → google_auth-2.55.2}/setup.cfg +0 -0
  105. {google_auth-2.55.1 → google_auth-2.55.2}/tests/__init__.py +0 -0
  106. {google_auth-2.55.1 → google_auth-2.55.2}/tests/aio/test__helpers.py +0 -0
  107. {google_auth-2.55.1 → google_auth-2.55.2}/tests/compute_engine/__init__.py +0 -0
  108. {google_auth-2.55.1 → google_auth-2.55.2}/tests/compute_engine/data/smbios_product_name +0 -0
  109. {google_auth-2.55.1 → google_auth-2.55.2}/tests/compute_engine/data/smbios_product_name_non_google +0 -0
  110. {google_auth-2.55.1 → google_auth-2.55.2}/tests/compute_engine/test__metadata.py +0 -0
  111. {google_auth-2.55.1 → google_auth-2.55.2}/tests/compute_engine/test_credentials.py +0 -0
  112. {google_auth-2.55.1 → google_auth-2.55.2}/tests/conftest.py +0 -0
  113. {google_auth-2.55.1 → google_auth-2.55.2}/tests/crypt/__init__.py +0 -0
  114. {google_auth-2.55.1 → google_auth-2.55.2}/tests/crypt/test__cryptography_rsa.py +0 -0
  115. {google_auth-2.55.1 → google_auth-2.55.2}/tests/crypt/test__python_rsa.py +0 -0
  116. {google_auth-2.55.1 → google_auth-2.55.2}/tests/crypt/test_crypt.py +0 -0
  117. {google_auth-2.55.1 → google_auth-2.55.2}/tests/crypt/test_es.py +0 -0
  118. {google_auth-2.55.1 → google_auth-2.55.2}/tests/crypt/test_es256.py +0 -0
  119. {google_auth-2.55.1 → google_auth-2.55.2}/tests/crypt/test_rsa.py +0 -0
  120. {google_auth-2.55.1 → google_auth-2.55.2}/tests/data/authorized_user.json +0 -0
  121. {google_auth-2.55.1 → google_auth-2.55.2}/tests/data/authorized_user_cloud_sdk.json +0 -0
  122. {google_auth-2.55.1 → google_auth-2.55.2}/tests/data/authorized_user_cloud_sdk_with_quota_project_id.json +0 -0
  123. {google_auth-2.55.1 → google_auth-2.55.2}/tests/data/authorized_user_with_rapt_token.json +0 -0
  124. {google_auth-2.55.1 → google_auth-2.55.2}/tests/data/client_secrets.json +0 -0
  125. {google_auth-2.55.1 → google_auth-2.55.2}/tests/data/context_aware_metadata.json +0 -0
  126. {google_auth-2.55.1 → google_auth-2.55.2}/tests/data/enterprise_cert_invalid.json +0 -0
  127. {google_auth-2.55.1 → google_auth-2.55.2}/tests/data/enterprise_cert_valid.json +0 -0
  128. {google_auth-2.55.1 → google_auth-2.55.2}/tests/data/enterprise_cert_valid_provider.json +0 -0
  129. {google_auth-2.55.1 → google_auth-2.55.2}/tests/data/es256_privatekey.pem +0 -0
  130. {google_auth-2.55.1 → google_auth-2.55.2}/tests/data/es256_public_cert.pem +0 -0
  131. {google_auth-2.55.1 → google_auth-2.55.2}/tests/data/es256_publickey.pem +0 -0
  132. {google_auth-2.55.1 → google_auth-2.55.2}/tests/data/es256_service_account.json +0 -0
  133. {google_auth-2.55.1 → google_auth-2.55.2}/tests/data/es384_privatekey.pem +0 -0
  134. {google_auth-2.55.1 → google_auth-2.55.2}/tests/data/es384_public_cert.pem +0 -0
  135. {google_auth-2.55.1 → google_auth-2.55.2}/tests/data/es384_publickey.pem +0 -0
  136. {google_auth-2.55.1 → google_auth-2.55.2}/tests/data/es384_service_account.json +0 -0
  137. {google_auth-2.55.1 → google_auth-2.55.2}/tests/data/external_account_authorized_user.json +0 -0
  138. {google_auth-2.55.1 → google_auth-2.55.2}/tests/data/external_account_authorized_user_non_gdu.json +0 -0
  139. {google_auth-2.55.1 → google_auth-2.55.2}/tests/data/external_subject_token.json +0 -0
  140. {google_auth-2.55.1 → google_auth-2.55.2}/tests/data/external_subject_token.txt +0 -0
  141. {google_auth-2.55.1 → google_auth-2.55.2}/tests/data/gdch_service_account.json +0 -0
  142. {google_auth-2.55.1 → google_auth-2.55.2}/tests/data/impersonated_service_account_authorized_user_source.json +0 -0
  143. {google_auth-2.55.1 → google_auth-2.55.2}/tests/data/impersonated_service_account_external_account_authorized_user_source.json +0 -0
  144. {google_auth-2.55.1 → google_auth-2.55.2}/tests/data/impersonated_service_account_service_account_source.json +0 -0
  145. {google_auth-2.55.1 → google_auth-2.55.2}/tests/data/impersonated_service_account_with_quota_project.json +0 -0
  146. {google_auth-2.55.1 → google_auth-2.55.2}/tests/data/old_oauth_credentials_py3.pickle +0 -0
  147. {google_auth-2.55.1 → google_auth-2.55.2}/tests/data/other_cert.pem +0 -0
  148. {google_auth-2.55.1 → google_auth-2.55.2}/tests/data/pem_from_pkcs12.pem +0 -0
  149. {google_auth-2.55.1 → google_auth-2.55.2}/tests/data/privatekey.p12 +0 -0
  150. {google_auth-2.55.1 → google_auth-2.55.2}/tests/data/privatekey.pem +0 -0
  151. {google_auth-2.55.1 → google_auth-2.55.2}/tests/data/privatekey.pub +0 -0
  152. {google_auth-2.55.1 → google_auth-2.55.2}/tests/data/public_cert.pem +0 -0
  153. {google_auth-2.55.1 → google_auth-2.55.2}/tests/data/service_account.json +0 -0
  154. {google_auth-2.55.1 → google_auth-2.55.2}/tests/data/service_account_non_gdu.json +0 -0
  155. {google_auth-2.55.1 → google_auth-2.55.2}/tests/data/trust_chain_with_leaf.pem +0 -0
  156. {google_auth-2.55.1 → google_auth-2.55.2}/tests/data/trust_chain_without_leaf.pem +0 -0
  157. {google_auth-2.55.1 → google_auth-2.55.2}/tests/data/trust_chain_wrong_order.pem +0 -0
  158. {google_auth-2.55.1 → google_auth-2.55.2}/tests/oauth2/__init__.py +0 -0
  159. {google_auth-2.55.1 → google_auth-2.55.2}/tests/oauth2/test__client.py +0 -0
  160. {google_auth-2.55.1 → google_auth-2.55.2}/tests/oauth2/test_challenges.py +0 -0
  161. {google_auth-2.55.1 → google_auth-2.55.2}/tests/oauth2/test_credentials.py +0 -0
  162. {google_auth-2.55.1 → google_auth-2.55.2}/tests/oauth2/test_gdch_credentials.py +0 -0
  163. {google_auth-2.55.1 → google_auth-2.55.2}/tests/oauth2/test_id_token.py +0 -0
  164. {google_auth-2.55.1 → google_auth-2.55.2}/tests/oauth2/test_reauth.py +0 -0
  165. {google_auth-2.55.1 → google_auth-2.55.2}/tests/oauth2/test_service_account.py +0 -0
  166. {google_auth-2.55.1 → google_auth-2.55.2}/tests/oauth2/test_sts.py +0 -0
  167. {google_auth-2.55.1 → google_auth-2.55.2}/tests/oauth2/test_utils.py +0 -0
  168. {google_auth-2.55.1 → google_auth-2.55.2}/tests/oauth2/test_webauthn_handler.py +0 -0
  169. {google_auth-2.55.1 → google_auth-2.55.2}/tests/oauth2/test_webauthn_handler_factory.py +0 -0
  170. {google_auth-2.55.1 → google_auth-2.55.2}/tests/oauth2/test_webauthn_types.py +0 -0
  171. {google_auth-2.55.1 → google_auth-2.55.2}/tests/test__cache.py +0 -0
  172. {google_auth-2.55.1 → google_auth-2.55.2}/tests/test__cloud_sdk.py +0 -0
  173. {google_auth-2.55.1 → google_auth-2.55.2}/tests/test__default.py +0 -0
  174. {google_auth-2.55.1 → google_auth-2.55.2}/tests/test__exponential_backoff.py +0 -0
  175. {google_auth-2.55.1 → google_auth-2.55.2}/tests/test__helpers.py +0 -0
  176. {google_auth-2.55.1 → google_auth-2.55.2}/tests/test__oauth2client.py +0 -0
  177. {google_auth-2.55.1 → google_auth-2.55.2}/tests/test__refresh_worker.py +0 -0
  178. {google_auth-2.55.1 → google_auth-2.55.2}/tests/test__regional_access_boundary_utils.py +0 -0
  179. {google_auth-2.55.1 → google_auth-2.55.2}/tests/test__service_account_info.py +0 -0
  180. {google_auth-2.55.1 → google_auth-2.55.2}/tests/test_api_key.py +0 -0
  181. {google_auth-2.55.1 → google_auth-2.55.2}/tests/test_app_engine.py +0 -0
  182. {google_auth-2.55.1 → google_auth-2.55.2}/tests/test_aws.py +0 -0
  183. {google_auth-2.55.1 → google_auth-2.55.2}/tests/test_credentials.py +0 -0
  184. {google_auth-2.55.1 → google_auth-2.55.2}/tests/test_credentials_async.py +0 -0
  185. {google_auth-2.55.1 → google_auth-2.55.2}/tests/test_downscoped.py +0 -0
  186. {google_auth-2.55.1 → google_auth-2.55.2}/tests/test_exceptions.py +0 -0
  187. {google_auth-2.55.1 → google_auth-2.55.2}/tests/test_external_account.py +0 -0
  188. {google_auth-2.55.1 → google_auth-2.55.2}/tests/test_external_account_authorized_user.py +0 -0
  189. {google_auth-2.55.1 → google_auth-2.55.2}/tests/test_iam.py +0 -0
  190. {google_auth-2.55.1 → google_auth-2.55.2}/tests/test_impersonated_credentials.py +0 -0
  191. {google_auth-2.55.1 → google_auth-2.55.2}/tests/test_jwt.py +0 -0
  192. {google_auth-2.55.1 → google_auth-2.55.2}/tests/test_metrics.py +0 -0
  193. {google_auth-2.55.1 → google_auth-2.55.2}/tests/test_packaging.py +0 -0
  194. {google_auth-2.55.1 → google_auth-2.55.2}/tests/test_pluggable.py +0 -0
  195. {google_auth-2.55.1 → google_auth-2.55.2}/tests/transport/__init__.py +0 -0
  196. {google_auth-2.55.1 → google_auth-2.55.2}/tests/transport/aio/test_sessions.py +0 -0
  197. {google_auth-2.55.1 → google_auth-2.55.2}/tests/transport/compliance.py +0 -0
  198. {google_auth-2.55.1 → google_auth-2.55.2}/tests/transport/test__http_client.py +0 -0
  199. {google_auth-2.55.1 → google_auth-2.55.2}/tests/transport/test_mtls.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: google-auth
3
- Version: 2.55.1
3
+ Version: 2.55.2
4
4
  Summary: Google Authentication Library
5
5
  Home-page: https://github.com/googleapis/google-cloud-python/tree/main/packages/google-auth
6
6
  Author: Google Cloud Platform
@@ -27,13 +27,13 @@ Requires-Dist: pyasn1-modules>=0.2.1
27
27
  Requires-Dist: cryptography>=38.0.3
28
28
  Provides-Extra: cryptography
29
29
  Requires-Dist: cryptography>=38.0.3; extra == "cryptography"
30
+ Provides-Extra: pyopenssl
31
+ Requires-Dist: cryptography>=38.0.3; extra == "pyopenssl"
30
32
  Provides-Extra: aiohttp
31
33
  Requires-Dist: aiohttp<4.0.0,>=3.8.0; extra == "aiohttp"
32
34
  Requires-Dist: requests<3.0.0,>=2.20.0; extra == "aiohttp"
33
35
  Provides-Extra: enterprise-cert
34
- Requires-Dist: pyopenssl; extra == "enterprise-cert"
35
- Provides-Extra: pyopenssl
36
- Requires-Dist: pyopenssl>=20.0.0; extra == "pyopenssl"
36
+ Requires-Dist: cryptography>=38.0.3; extra == "enterprise-cert"
37
37
  Provides-Extra: pyjwt
38
38
  Requires-Dist: pyjwt>=2.0; extra == "pyjwt"
39
39
  Provides-Extra: reauth
@@ -41,14 +41,14 @@ Requires-Dist: pyu2f>=0.1.5; extra == "reauth"
41
41
  Provides-Extra: requests
42
42
  Requires-Dist: requests<3.0.0,>=2.20.0; extra == "requests"
43
43
  Provides-Extra: testing
44
- Requires-Dist: grpcio; extra == "testing"
44
+ Requires-Dist: grpcio<2.0.0,>=1.59.0; python_version < "3.14" and extra == "testing"
45
+ Requires-Dist: grpcio<2.0.0,>=1.75.1; python_version >= "3.14" and extra == "testing"
45
46
  Requires-Dist: flask; extra == "testing"
46
47
  Requires-Dist: freezegun; extra == "testing"
47
48
  Requires-Dist: pyjwt>=2.0; extra == "testing"
48
49
  Requires-Dist: pytest; extra == "testing"
49
50
  Requires-Dist: pytest-cov; extra == "testing"
50
51
  Requires-Dist: pytest-localserver; extra == "testing"
51
- Requires-Dist: pyopenssl>=20.0.0; extra == "testing"
52
52
  Requires-Dist: pyu2f>=0.1.5; extra == "testing"
53
53
  Requires-Dist: responses; extra == "testing"
54
54
  Requires-Dist: urllib3; extra == "testing"
@@ -57,13 +57,14 @@ Requires-Dist: aiohttp<4.0.0,>=3.8.0; extra == "testing"
57
57
  Requires-Dist: requests<3.0.0,>=2.20.0; extra == "testing"
58
58
  Requires-Dist: aioresponses; extra == "testing"
59
59
  Requires-Dist: pytest-asyncio; extra == "testing"
60
- Requires-Dist: pyopenssl<24.3.0; extra == "testing"
61
- Requires-Dist: aiohttp<3.10.0; extra == "testing"
62
60
  Provides-Extra: urllib3
63
61
  Requires-Dist: urllib3; extra == "urllib3"
64
62
  Requires-Dist: packaging; extra == "urllib3"
65
63
  Provides-Extra: rsa
66
64
  Requires-Dist: rsa<5,>=3.1.4; extra == "rsa"
65
+ Provides-Extra: grpc
66
+ Requires-Dist: grpcio<2.0.0,>=1.59.0; python_version < "3.14" and extra == "grpc"
67
+ Requires-Dist: grpcio<2.0.0,>=1.75.1; python_version >= "3.14" and extra == "grpc"
67
68
  Dynamic: author
68
69
  Dynamic: author-email
69
70
  Dynamic: classifier
@@ -16,16 +16,15 @@
16
16
 
17
17
  import base64
18
18
  import hashlib
19
- import logging
20
19
  import os
21
20
  import re
21
+ import stat
22
22
  import time
23
23
  from urllib.parse import quote, urlparse
24
+ import warnings
24
25
 
25
26
  from google.auth import environment_vars, exceptions
26
27
 
27
- _LOGGER = logging.getLogger(__name__)
28
-
29
28
  CRYPTOGRAPHY_NOT_FOUND_ERROR = (
30
29
  "The cryptography library is required for certificate-based authentication."
31
30
  "Please install it with `pip install google-auth[cryptography]`."
@@ -58,8 +57,20 @@ _POLLING_INTERVALS = ([_FAST_POLL_INTERVAL] * _FAST_POLL_CYCLES) + (
58
57
 
59
58
 
60
59
  def _is_certificate_file_ready(path):
61
- """Checks if a file exists and is not empty."""
62
- return path and os.path.exists(path) and os.path.getsize(path) > 0
60
+ """Checks if a file exists, is a regular file, and is not empty."""
61
+ if not path:
62
+ return False
63
+ try:
64
+ # Check if the path points to a regular file and is not empty.
65
+ # stat.S_ISREG is used instead of os.path.isfile to avoid swallowing
66
+ # PermissionError exceptions, which the caller needs to propagate.
67
+ st = os.stat(path)
68
+ return stat.S_ISREG(st.st_mode) and st.st_size > 0
69
+ except PermissionError:
70
+ # Propagate PermissionError to let caller handle it (fail-fast or fallback)
71
+ raise
72
+ except OSError:
73
+ return False
63
74
 
64
75
 
65
76
  def get_agent_identity_certificate_path():
@@ -141,13 +152,17 @@ def get_agent_identity_certificate_path():
141
152
 
142
153
  # Log a warning on the first failed attempt to load the certificate file
143
154
  if not has_logged_cert_warning:
144
- _LOGGER.warning(
145
- "Certificate file not ready at %s. Retrying until startup timeout (up to %s seconds total)...",
146
- target_path,
147
- _TOTAL_TIMEOUT,
155
+ warnings.warn(
156
+ f"Certificate file not ready at {target_path}. Retrying until startup timeout (up to {_TOTAL_TIMEOUT} seconds total)..."
148
157
  )
149
158
  has_logged_cert_warning = True
150
159
 
160
+ except PermissionError as e:
161
+ warnings.warn(
162
+ f"Permission denied when accessing certificate config or certificate file: {e}. "
163
+ "Token binding protection cannot be enabled. Falling back to unbound tokens."
164
+ )
165
+ return None
151
166
  except (IOError, ValueError, KeyError) as e:
152
167
  if cert_config_path and os.path.exists(cert_config_path):
153
168
  # If the file exists but has invalid JSON or is unreadable,
@@ -155,12 +170,10 @@ def get_agent_identity_certificate_path():
155
170
  return None
156
171
 
157
172
  if not has_logged_config_warning and cert_config_path:
158
- _LOGGER.warning(
159
- "Certificate config file not found or incomplete: %s (from %s "
160
- "environment variable). Retrying until startup timeout (up to %s seconds total)...",
161
- e,
162
- environment_vars.GOOGLE_API_CERTIFICATE_CONFIG,
163
- _TOTAL_TIMEOUT,
173
+ warnings.warn(
174
+ f"Certificate config file not found or incomplete: {e} (from "
175
+ f"{environment_vars.GOOGLE_API_CERTIFICATE_CONFIG} environment variable). "
176
+ f"Retrying until startup timeout (up to {_TOTAL_TIMEOUT} seconds total)..."
164
177
  )
165
178
  has_logged_config_warning = True
166
179
  pass
@@ -201,12 +214,26 @@ def get_and_parse_agent_identity_certificate():
201
214
  if is_opted_out:
202
215
  return None
203
216
 
217
+ # Respect explicit opt-out of mTLS / client certs
218
+ from google.auth.transport import _mtls_helper
219
+
220
+ env_override = _mtls_helper._check_use_client_cert_env()
221
+ if env_override is False:
222
+ return None
223
+
204
224
  cert_path = get_agent_identity_certificate_path()
205
225
  if not cert_path:
206
226
  return None
207
227
 
208
- with open(cert_path, "rb") as cert_file:
209
- cert_bytes = cert_file.read()
228
+ try:
229
+ with open(cert_path, "rb") as cert_file:
230
+ cert_bytes = cert_file.read()
231
+ except PermissionError as e:
232
+ warnings.warn(
233
+ f"Failed to read agent identity certificate file at {cert_path}: {e}. "
234
+ "Token binding protection cannot be enabled. Falling back to unbound tokens."
235
+ )
236
+ return None
210
237
 
211
238
  return parse_certificate(cert_bytes)
212
239
 
@@ -312,7 +339,17 @@ def should_request_bound_token(cert):
312
339
  ).lower()
313
340
  == "true"
314
341
  )
315
- return is_agent_cert and is_opted_in
342
+ if not (is_agent_cert and is_opted_in):
343
+ return False
344
+
345
+ # Respect explicit opt-out of mTLS / client certs
346
+ from google.auth.transport import _mtls_helper
347
+
348
+ env_override = _mtls_helper._check_use_client_cert_env()
349
+ if env_override is False:
350
+ return False
351
+
352
+ return True
316
353
 
317
354
 
318
355
  def get_cached_cert_fingerprint(cached_cert):
@@ -14,7 +14,6 @@
14
14
 
15
15
  """Helper functions for commonly used utilities."""
16
16
 
17
-
18
17
  import logging
19
18
  from typing import Any
20
19
 
@@ -60,3 +59,13 @@ async def response_log_async(logger: logging.Logger, response: Any) -> None:
60
59
  # json_response = await _parse_response_async(response)
61
60
  json_response = None
62
61
  _helpers._response_log_base(logger, json_response)
62
+
63
+
64
+ def _get_local_addr(connector: Any) -> Any:
65
+ local_addr = getattr(connector, "_local_addr", None)
66
+ if local_addr is not None:
67
+ return local_addr
68
+ local_addr_infos = getattr(connector, "_local_addr_infos", None)
69
+ if local_addr_infos:
70
+ return local_addr_infos[0][4]
71
+ return None
@@ -248,7 +248,7 @@ class Request(transport.Request):
248
248
  limit=getattr(orig_connector, "_limit", 100),
249
249
  limit_per_host=getattr(orig_connector, "_limit_per_host", 0),
250
250
  force_close=getattr(orig_connector, "_force_close", False),
251
- local_addr=getattr(orig_connector, "_local_addr", None),
251
+ local_addr=_helpers_async._get_local_addr(orig_connector),
252
252
  )
253
253
  elif getattr(aiohttp, "UnixConnector", None) and isinstance(
254
254
  orig_connector, getattr(aiohttp, "UnixConnector")
@@ -17,42 +17,18 @@ Helper functions for mTLS in async for discovery of certs.
17
17
  """
18
18
 
19
19
  import asyncio
20
- import contextlib
20
+ import inspect
21
21
  import logging
22
- import os
23
22
  import ssl
24
- import tempfile
25
23
  from typing import Optional
26
24
 
27
25
  from google.auth import exceptions
28
- import google.auth.transport._mtls_helper
26
+ from google.auth.transport._mtls_helper import secure_cert_key_paths
29
27
  import google.auth.transport.mtls
30
28
 
31
29
  _LOGGER = logging.getLogger(__name__)
32
30
 
33
31
 
34
- @contextlib.contextmanager
35
- def _create_temp_file(content: bytes):
36
- """Creates a temporary file with the given content.
37
-
38
- Args:
39
- content (bytes): The content to write to the file.
40
-
41
- Yields:
42
- str: The path to the temporary file.
43
- """
44
- # Create a temporary file that is readable only by the owner.
45
- fd, file_path = tempfile.mkstemp()
46
- try:
47
- with os.fdopen(fd, "wb") as f:
48
- f.write(content)
49
- yield file_path
50
- finally:
51
- # Securely delete the file after use.
52
- if os.path.exists(file_path):
53
- os.remove(file_path)
54
-
55
-
56
32
  def make_client_cert_ssl_context(
57
33
  cert_bytes: bytes, key_bytes: bytes, passphrase: Optional[bytes] = None
58
34
  ) -> ssl.SSLContext:
@@ -71,19 +47,29 @@ def make_client_cert_ssl_context(
71
47
  Raises:
72
48
  google.auth.exceptions.TransportError: If there is an error loading the certificate.
73
49
  """
74
- with _create_temp_file(cert_bytes) as cert_path, _create_temp_file(
75
- key_bytes
76
- ) as key_path:
77
- try:
50
+ try:
51
+ with secure_cert_key_paths(cert_bytes, key_bytes, passphrase=passphrase) as (
52
+ cert_path,
53
+ key_path,
54
+ passphrase_val,
55
+ ):
78
56
  context = ssl.create_default_context(ssl.Purpose.SERVER_AUTH)
79
- context.load_cert_chain(
80
- certfile=cert_path, keyfile=key_path, password=passphrase
81
- )
57
+ if cert_path:
58
+ password = (
59
+ passphrase_val.decode("utf-8")
60
+ if isinstance(passphrase_val, bytes)
61
+ else passphrase_val
62
+ )
63
+ context.load_cert_chain(
64
+ certfile=cert_path,
65
+ keyfile=key_path,
66
+ password=password,
67
+ )
82
68
  return context
83
- except (ssl.SSLError, OSError, IOError, ValueError, RuntimeError) as exc:
84
- raise exceptions.TransportError(
85
- "Failed to load client certificate and key for mTLS."
86
- ) from exc
69
+ except (ssl.SSLError, OSError, IOError, ValueError, RuntimeError, TypeError) as exc:
70
+ raise exceptions.TransportError(
71
+ "Failed to load client certificate and key for mTLS."
72
+ ) from exc
87
73
 
88
74
 
89
75
  async def _run_in_executor(func, *args):
@@ -187,9 +173,9 @@ async def get_client_cert_and_key(client_cert_callback=None):
187
173
  """
188
174
  if client_cert_callback:
189
175
  result = client_cert_callback()
190
- try:
176
+ if inspect.isawaitable(result):
191
177
  cert, key = await result
192
- except TypeError:
178
+ else:
193
179
  cert, key = result
194
180
  return True, cert, key
195
181
 
@@ -17,6 +17,7 @@ from contextlib import asynccontextmanager
17
17
  import functools
18
18
  import time
19
19
  from typing import Mapping, Optional, TYPE_CHECKING, Union
20
+ import warnings
20
21
 
21
22
  from google.auth import _exponential_backoff, exceptions
22
23
  from google.auth.aio import transport
@@ -36,6 +37,7 @@ else:
36
37
  except (ImportError, AttributeError):
37
38
  ClientTimeout = None
38
39
 
40
+
39
41
  # Tracks the internal aiohttp installation and usage
40
42
  try:
41
43
  from google.auth.aio.transport.aiohttp import Request as AiohttpRequest
@@ -150,11 +152,11 @@ class AsyncAuthorizedSession:
150
152
  async def configure_mtls_channel(self, client_cert_callback=None):
151
153
  """Configure the client certificate and key for SSL connection.
152
154
 
153
- The function does nothing unless `GOOGLE_API_USE_CLIENT_CERTIFICATE` is
154
- explicitly set to `true`. In this case if client certificate and key are
155
- successfully obtained (from the given client_cert_callback or from application
156
- default SSL credentials), the underlying transport will be reconfigured
157
- to use mTLS.
155
+ This method configures mTLS if client certificates are explicitly enabled
156
+ (via GOOGLE_API_USE_CLIENT_CERTIFICATE=true) or auto-enabled (when the env
157
+ variable is unset and workload certificates are discovered). In these cases,
158
+ the underlying transport will be reconfigured to use mTLS.
159
+
158
160
  Note: This function does nothing if the `aiohttp` library is not
159
161
  installed.
160
162
  Important: Calling this method will close any ongoing API requests associated
@@ -180,18 +182,16 @@ class AsyncAuthorizedSession:
180
182
  google.auth.transport._mtls_helper.check_use_client_cert
181
183
  )
182
184
  if not use_client_cert:
183
- self._is_mtls = False
184
185
  return
185
186
 
186
187
  try:
187
188
  (
188
- self._is_mtls,
189
+ is_mtls,
189
190
  cert,
190
191
  key,
191
192
  ) = await mtls.get_client_cert_and_key(client_cert_callback)
192
193
 
193
- if self._is_mtls:
194
- self._cached_cert = cert
194
+ if is_mtls:
195
195
  ssl_context = await mtls._run_in_executor(
196
196
  mtls.make_client_cert_ssl_context, cert, key
197
197
  )
@@ -206,13 +206,29 @@ class AsyncAuthorizedSession:
206
206
  old_auth_request = self._auth_request
207
207
  self._auth_request = AiohttpRequest(session=new_session)
208
208
 
209
- await old_auth_request.close()
209
+ try:
210
+ await old_auth_request.close()
211
+ except Exception:
212
+ # Suppress so it doesn't abort the mTLS configuration
213
+ pass
214
+ else:
215
+ is_mtls = False
216
+ warnings.warn(
217
+ "Attempted to establish mTLS, but a custom async transport was provided. "
218
+ "google-auth cannot automatically configure custom transports for mTLS. "
219
+ "Falling back to standard TLS. If your custom transport is not manually "
220
+ "configured for mTLS, you may encounter 401 Unauthorized errors when "
221
+ "using Certificate-Bound Tokens.",
222
+ UserWarning,
223
+ )
224
+
225
+ self._is_mtls = is_mtls
226
+ if is_mtls:
227
+ self._cached_cert = cert
228
+ else:
229
+ self._cached_cert = None
210
230
 
211
- except (
212
- exceptions.ClientCertError,
213
- ImportError,
214
- OSError,
215
- ) as caught_exc:
231
+ except Exception as caught_exc:
216
232
  new_exc = exceptions.MutualTLSChannelError(caught_exc)
217
233
  raise new_exc from caught_exc
218
234
 
@@ -573,4 +589,10 @@ class AsyncAuthorizedSession:
573
589
  """
574
590
  Close the underlying auth request session.
575
591
  """
592
+ if self._mtls_init_task and not self._mtls_init_task.done():
593
+ self._mtls_init_task.cancel()
594
+ try:
595
+ await self._mtls_init_task
596
+ except asyncio.CancelledError:
597
+ pass
576
598
  await self._auth_request.close()
@@ -120,8 +120,9 @@ class MdsMtlsAdapter(HTTPAdapter):
120
120
  self.ssl_context = ssl.create_default_context()
121
121
  self.ssl_context.load_verify_locations(cafile=mds_mtls_config.ca_cert_path)
122
122
  self.ssl_context.load_cert_chain(
123
- certfile=mds_mtls_config.client_combined_cert_path
123
+ certfile=mds_mtls_config.client_combined_cert_path, password=""
124
124
  )
125
+ self._fallback_adapter = HTTPAdapter()
125
126
  super(MdsMtlsAdapter, self).__init__(*args, **kwargs)
126
127
 
127
128
  def init_poolmanager(self, *args, **kwargs):
@@ -146,6 +147,8 @@ class MdsMtlsAdapter(HTTPAdapter):
146
147
  ssl.SSLError,
147
148
  requests.exceptions.SSLError,
148
149
  requests.exceptions.HTTPError,
150
+ requests.exceptions.ConnectionError,
151
+ requests.exceptions.Timeout,
149
152
  ) as e:
150
153
  _LOGGER.warning(
151
154
  "mTLS connection to Compute Engine Metadata server failed. "
@@ -157,6 +160,9 @@ class MdsMtlsAdapter(HTTPAdapter):
157
160
  http_fallback_url = urlunparse(parsed_original_url._replace(scheme="http"))
158
161
  request.url = http_fallback_url
159
162
 
160
- # Use a standard HTTPAdapter for the fallback
161
- http_adapter = HTTPAdapter()
162
- return http_adapter.send(request, **kwargs)
163
+ # Use the cached standard HTTPAdapter for the fallback
164
+ return self._fallback_adapter.send(request, **kwargs)
165
+
166
+ def close(self):
167
+ self._fallback_adapter.close()
168
+ super(MdsMtlsAdapter, self).close()
@@ -152,28 +152,34 @@ class _X509Supplier(SubjectTokenSupplier):
152
152
 
153
153
  @_helpers.copy_docstring(SubjectTokenSupplier)
154
154
  def get_subject_token(self, context, request):
155
- # Import OpennSSL inline because it is an extra import only required by customers
156
- # using mTLS.
157
- from OpenSSL import crypto
155
+ from cryptography import x509
158
156
 
159
- leaf_cert = crypto.load_certificate(
160
- crypto.FILETYPE_PEM, self._leaf_cert_callback()
161
- )
157
+ try:
158
+ leaf_cert_data = self._leaf_cert_callback()
159
+ except Exception as e:
160
+ raise exceptions.RefreshError("Failed to retrieve leaf certificate.") from e
161
+
162
+ try:
163
+ if isinstance(leaf_cert_data, str):
164
+ leaf_cert_data = leaf_cert_data.encode("utf-8")
165
+ leaf_cert = x509.load_pem_x509_certificate(leaf_cert_data)
166
+ except Exception as e:
167
+ raise exceptions.RefreshError("Failed to parse leaf certificate.") from e
162
168
  trust_chain = self._read_trust_chain()
163
169
  cert_chain = []
164
170
 
165
- cert_chain.append(_X509Supplier._encode_cert(leaf_cert))
171
+ cert_chain.append(_encode_cert(leaf_cert))
166
172
 
167
173
  if trust_chain is None or len(trust_chain) == 0:
168
174
  return json.dumps(cert_chain)
169
175
 
170
176
  # Append the first cert if it is not the leaf cert.
171
- first_cert = _X509Supplier._encode_cert(trust_chain[0])
177
+ first_cert = _encode_cert(trust_chain[0])
172
178
  if first_cert != cert_chain[0]:
173
179
  cert_chain.append(first_cert)
174
180
 
175
181
  for i in range(1, len(trust_chain)):
176
- encoded = _X509Supplier._encode_cert(trust_chain[i])
182
+ encoded = _encode_cert(trust_chain[i])
177
183
  # Check if the current cert is the leaf cert and raise an exception if it is.
178
184
  if encoded == cert_chain[0]:
179
185
  raise exceptions.RefreshError(
@@ -184,9 +190,7 @@ class _X509Supplier(SubjectTokenSupplier):
184
190
  return json.dumps(cert_chain)
185
191
 
186
192
  def _read_trust_chain(self):
187
- # Import OpennSSL inline because it is an extra import only required by customers
188
- # using mTLS.
189
- from OpenSSL import crypto
193
+ from cryptography import x509
190
194
 
191
195
  certificate_trust_chain = []
192
196
  # If no trust chain path was provided, return an empty list.
@@ -204,9 +208,7 @@ class _X509Supplier(SubjectTokenSupplier):
204
208
  cert_data = b"-----BEGIN CERTIFICATE-----" + cert_block
205
209
  try:
206
210
  # Load each certificate and add it to the trust chain.
207
- cert = crypto.load_certificate(
208
- crypto.FILETYPE_PEM, cert_data
209
- )
211
+ cert = x509.load_pem_x509_certificate(cert_data)
210
212
  certificate_trust_chain.append(cert)
211
213
  except Exception as e:
212
214
  raise exceptions.RefreshError(
@@ -215,19 +217,22 @@ class _X509Supplier(SubjectTokenSupplier):
215
217
  )
216
218
  ) from e
217
219
  return certificate_trust_chain
218
- except FileNotFoundError:
220
+ except FileNotFoundError as e:
219
221
  raise exceptions.RefreshError(
220
222
  "Trust chain file '{}' was not found.".format(self._trust_chain_path)
221
- )
223
+ ) from e
224
+ except OSError as e:
225
+ raise exceptions.RefreshError(
226
+ "Error accessing trust chain file '{}'.".format(self._trust_chain_path)
227
+ ) from e
228
+
222
229
 
223
- def _encode_cert(cert):
224
- # Import OpennSSL inline because it is an extra import only required by customers
225
- # using mTLS.
226
- from OpenSSL import crypto
230
+ def _encode_cert(cert):
231
+ from cryptography.hazmat.primitives import serialization
227
232
 
228
- return base64.b64encode(
229
- crypto.dump_certificate(crypto.FILETYPE_ASN1, cert)
230
- ).decode("utf-8")
233
+ return base64.b64encode(cert.public_bytes(serialization.Encoding.DER)).decode(
234
+ "utf-8"
235
+ )
231
236
 
232
237
 
233
238
  def _parse_token_data(token_content, format_type="text", subject_token_field_name=None):
@@ -36,6 +36,7 @@ from google.auth.transport import requests
36
36
 
37
37
  _LOGGER = logging.getLogger(__name__)
38
38
 
39
+
39
40
  # Timeout can be re-defined depending on async requirement. Currently made 60s more than
40
41
  # sync timeout.
41
42
  _DEFAULT_TIMEOUT = 180 # in seconds
@@ -250,7 +251,7 @@ class Request(transport.Request):
250
251
  limit=getattr(orig_connector, "_limit", 100),
251
252
  limit_per_host=getattr(orig_connector, "_limit_per_host", 0),
252
253
  force_close=getattr(orig_connector, "_force_close", False),
253
- local_addr=getattr(orig_connector, "_local_addr", None),
254
+ local_addr=_helpers_async._get_local_addr(orig_connector),
254
255
  )
255
256
  elif getattr(aiohttp, "UnixConnector", None) and isinstance(
256
257
  orig_connector, getattr(aiohttp, "UnixConnector")
@@ -21,9 +21,9 @@ import ctypes
21
21
  import json
22
22
  import logging
23
23
  import os
24
+ import ssl
24
25
  import sys
25
-
26
- import cffi # type: ignore
26
+ import sysconfig
27
27
 
28
28
  from google.auth import exceptions
29
29
 
@@ -45,16 +45,23 @@ SIGN_CALLBACK_CTYPE = ctypes.CFUNCTYPE(
45
45
  )
46
46
 
47
47
 
48
- # Cast SSL_CTX* to void*
49
- def _cast_ssl_ctx_to_void_p_pyopenssl(ssl_ctx):
50
- return ctypes.cast(int(cffi.FFI().cast("intptr_t", ssl_ctx)), ctypes.c_void_p)
51
-
52
-
53
48
  # Cast SSL_CTX* to void*
54
49
  def _cast_ssl_ctx_to_void_p_stdlib(context):
55
- return ctypes.c_void_p.from_address(
56
- id(context) + ctypes.sizeof(ctypes.c_void_p) * 2
57
- )
50
+ if not issubclass(type(context), ssl.SSLContext):
51
+ raise TypeError("context must be an instance of ssl.SSLContext, not a mock")
52
+
53
+ if (
54
+ sys.implementation.name != "cpython"
55
+ or hasattr(sys, "getobjects")
56
+ or sysconfig.get_config_var("Py_DEBUG")
57
+ or sysconfig.get_config_var("Py_GIL_DISABLED") == 1
58
+ ):
59
+ raise exceptions.MutualTLSChannelError(
60
+ "Custom TLS signing is only supported on standard release CPython runtimes."
61
+ )
62
+
63
+ offset = sys.getsizeof(object())
64
+ return ctypes.c_void_p.from_address(id(context) + offset)
58
65
 
59
66
 
60
67
  # Load offload library and set up the function types.
@@ -274,7 +281,7 @@ class CustomTlsSigner(object):
274
281
  if not self._offload_lib.ConfigureSslContext(
275
282
  self._sign_callback,
276
283
  ctypes.c_char_p(self._cert),
277
- _cast_ssl_ctx_to_void_p_pyopenssl(ctx._ctx._context),
284
+ _cast_ssl_ctx_to_void_p_stdlib(ctx),
278
285
  ):
279
286
  raise exceptions.MutualTLSChannelError(
280
287
  "failed to configure ECP Offload SSL context"