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.
- {google_auth-2.55.1/google_auth.egg-info → google_auth-2.55.2}/PKG-INFO +9 -8
- {google_auth-2.55.1 → google_auth-2.55.2}/google/auth/_agent_identity_utils.py +55 -18
- {google_auth-2.55.1 → google_auth-2.55.2}/google/auth/aio/_helpers.py +10 -1
- {google_auth-2.55.1 → google_auth-2.55.2}/google/auth/aio/transport/aiohttp.py +1 -1
- {google_auth-2.55.1 → google_auth-2.55.2}/google/auth/aio/transport/mtls.py +25 -39
- {google_auth-2.55.1 → google_auth-2.55.2}/google/auth/aio/transport/sessions.py +37 -15
- {google_auth-2.55.1 → google_auth-2.55.2}/google/auth/compute_engine/_mtls.py +10 -4
- {google_auth-2.55.1 → google_auth-2.55.2}/google/auth/identity_pool.py +29 -24
- {google_auth-2.55.1 → google_auth-2.55.2}/google/auth/transport/_aiohttp_requests.py +2 -1
- {google_auth-2.55.1 → google_auth-2.55.2}/google/auth/transport/_custom_tls_signer.py +18 -11
- {google_auth-2.55.1 → google_auth-2.55.2}/google/auth/transport/_mtls_helper.py +350 -44
- {google_auth-2.55.1 → google_auth-2.55.2}/google/auth/transport/grpc.py +23 -17
- {google_auth-2.55.1 → google_auth-2.55.2}/google/auth/transport/requests.py +61 -37
- {google_auth-2.55.1 → google_auth-2.55.2}/google/auth/transport/urllib3.py +45 -30
- {google_auth-2.55.1 → google_auth-2.55.2}/google/auth/version.py +1 -1
- {google_auth-2.55.1 → google_auth-2.55.2/google_auth.egg-info}/PKG-INFO +9 -8
- {google_auth-2.55.1 → google_auth-2.55.2}/google_auth.egg-info/SOURCES.txt +1 -0
- {google_auth-2.55.1 → google_auth-2.55.2}/google_auth.egg-info/requires.txt +16 -6
- {google_auth-2.55.1 → google_auth-2.55.2}/setup.py +11 -18
- {google_auth-2.55.1 → google_auth-2.55.2}/tests/compute_engine/test__mtls.py +52 -12
- {google_auth-2.55.1 → google_auth-2.55.2}/tests/test_agent_identity_utils.py +144 -5
- {google_auth-2.55.1 → google_auth-2.55.2}/tests/test_identity_pool.py +6 -7
- google_auth-2.55.2/tests/transport/aio/conftest.py +46 -0
- {google_auth-2.55.1 → google_auth-2.55.2}/tests/transport/aio/test_aiohttp.py +5 -1
- google_auth-2.55.2/tests/transport/aio/test_sessions_mtls.py +348 -0
- {google_auth-2.55.1 → google_auth-2.55.2}/tests/transport/test__custom_tls_signer.py +112 -10
- {google_auth-2.55.1 → google_auth-2.55.2}/tests/transport/test__mtls_helper.py +615 -22
- {google_auth-2.55.1 → google_auth-2.55.2}/tests/transport/test_aio_mtls_helper.py +36 -19
- {google_auth-2.55.1 → google_auth-2.55.2}/tests/transport/test_grpc.py +168 -8
- {google_auth-2.55.1 → google_auth-2.55.2}/tests/transport/test_requests.py +149 -33
- {google_auth-2.55.1 → google_auth-2.55.2}/tests/transport/test_urllib3.py +165 -27
- google_auth-2.55.1/tests/transport/aio/test_sessions_mtls.py +0 -142
- {google_auth-2.55.1 → google_auth-2.55.2}/LICENSE +0 -0
- {google_auth-2.55.1 → google_auth-2.55.2}/MANIFEST.in +0 -0
- {google_auth-2.55.1 → google_auth-2.55.2}/README.rst +0 -0
- {google_auth-2.55.1 → google_auth-2.55.2}/google/auth/__init__.py +0 -0
- {google_auth-2.55.1 → google_auth-2.55.2}/google/auth/_cache.py +0 -0
- {google_auth-2.55.1 → google_auth-2.55.2}/google/auth/_cloud_sdk.py +0 -0
- {google_auth-2.55.1 → google_auth-2.55.2}/google/auth/_credentials_async.py +0 -0
- {google_auth-2.55.1 → google_auth-2.55.2}/google/auth/_credentials_base.py +0 -0
- {google_auth-2.55.1 → google_auth-2.55.2}/google/auth/_default.py +0 -0
- {google_auth-2.55.1 → google_auth-2.55.2}/google/auth/_default_async.py +0 -0
- {google_auth-2.55.1 → google_auth-2.55.2}/google/auth/_exponential_backoff.py +0 -0
- {google_auth-2.55.1 → google_auth-2.55.2}/google/auth/_helpers.py +0 -0
- {google_auth-2.55.1 → google_auth-2.55.2}/google/auth/_jwt_async.py +0 -0
- {google_auth-2.55.1 → google_auth-2.55.2}/google/auth/_oauth2client.py +0 -0
- {google_auth-2.55.1 → google_auth-2.55.2}/google/auth/_refresh_worker.py +0 -0
- {google_auth-2.55.1 → google_auth-2.55.2}/google/auth/_regional_access_boundary_utils.py +0 -0
- {google_auth-2.55.1 → google_auth-2.55.2}/google/auth/_service_account_info.py +0 -0
- {google_auth-2.55.1 → google_auth-2.55.2}/google/auth/aio/__init__.py +0 -0
- {google_auth-2.55.1 → google_auth-2.55.2}/google/auth/aio/credentials.py +0 -0
- {google_auth-2.55.1 → google_auth-2.55.2}/google/auth/aio/transport/__init__.py +0 -0
- {google_auth-2.55.1 → google_auth-2.55.2}/google/auth/api_key.py +0 -0
- {google_auth-2.55.1 → google_auth-2.55.2}/google/auth/app_engine.py +0 -0
- {google_auth-2.55.1 → google_auth-2.55.2}/google/auth/aws.py +0 -0
- {google_auth-2.55.1 → google_auth-2.55.2}/google/auth/compute_engine/__init__.py +0 -0
- {google_auth-2.55.1 → google_auth-2.55.2}/google/auth/compute_engine/_metadata.py +0 -0
- {google_auth-2.55.1 → google_auth-2.55.2}/google/auth/compute_engine/credentials.py +0 -0
- {google_auth-2.55.1 → google_auth-2.55.2}/google/auth/credentials.py +0 -0
- {google_auth-2.55.1 → google_auth-2.55.2}/google/auth/crypt/__init__.py +0 -0
- {google_auth-2.55.1 → google_auth-2.55.2}/google/auth/crypt/_cryptography_rsa.py +0 -0
- {google_auth-2.55.1 → google_auth-2.55.2}/google/auth/crypt/_helpers.py +0 -0
- {google_auth-2.55.1 → google_auth-2.55.2}/google/auth/crypt/_python_rsa.py +0 -0
- {google_auth-2.55.1 → google_auth-2.55.2}/google/auth/crypt/base.py +0 -0
- {google_auth-2.55.1 → google_auth-2.55.2}/google/auth/crypt/es.py +0 -0
- {google_auth-2.55.1 → google_auth-2.55.2}/google/auth/crypt/es256.py +0 -0
- {google_auth-2.55.1 → google_auth-2.55.2}/google/auth/crypt/rsa.py +0 -0
- {google_auth-2.55.1 → google_auth-2.55.2}/google/auth/downscoped.py +0 -0
- {google_auth-2.55.1 → google_auth-2.55.2}/google/auth/environment_vars.py +0 -0
- {google_auth-2.55.1 → google_auth-2.55.2}/google/auth/exceptions.py +0 -0
- {google_auth-2.55.1 → google_auth-2.55.2}/google/auth/external_account.py +0 -0
- {google_auth-2.55.1 → google_auth-2.55.2}/google/auth/external_account_authorized_user.py +0 -0
- {google_auth-2.55.1 → google_auth-2.55.2}/google/auth/iam.py +0 -0
- {google_auth-2.55.1 → google_auth-2.55.2}/google/auth/impersonated_credentials.py +0 -0
- {google_auth-2.55.1 → google_auth-2.55.2}/google/auth/jwt.py +0 -0
- {google_auth-2.55.1 → google_auth-2.55.2}/google/auth/metrics.py +0 -0
- {google_auth-2.55.1 → google_auth-2.55.2}/google/auth/pluggable.py +0 -0
- {google_auth-2.55.1 → google_auth-2.55.2}/google/auth/py.typed +0 -0
- {google_auth-2.55.1 → google_auth-2.55.2}/google/auth/transport/__init__.py +0 -0
- {google_auth-2.55.1 → google_auth-2.55.2}/google/auth/transport/_http_client.py +0 -0
- {google_auth-2.55.1 → google_auth-2.55.2}/google/auth/transport/_requests_base.py +0 -0
- {google_auth-2.55.1 → google_auth-2.55.2}/google/auth/transport/mtls.py +0 -0
- {google_auth-2.55.1 → google_auth-2.55.2}/google/oauth2/__init__.py +0 -0
- {google_auth-2.55.1 → google_auth-2.55.2}/google/oauth2/_client.py +0 -0
- {google_auth-2.55.1 → google_auth-2.55.2}/google/oauth2/_client_async.py +0 -0
- {google_auth-2.55.1 → google_auth-2.55.2}/google/oauth2/_credentials_async.py +0 -0
- {google_auth-2.55.1 → google_auth-2.55.2}/google/oauth2/_id_token_async.py +0 -0
- {google_auth-2.55.1 → google_auth-2.55.2}/google/oauth2/_reauth_async.py +0 -0
- {google_auth-2.55.1 → google_auth-2.55.2}/google/oauth2/_service_account_async.py +0 -0
- {google_auth-2.55.1 → google_auth-2.55.2}/google/oauth2/challenges.py +0 -0
- {google_auth-2.55.1 → google_auth-2.55.2}/google/oauth2/credentials.py +0 -0
- {google_auth-2.55.1 → google_auth-2.55.2}/google/oauth2/gdch_credentials.py +0 -0
- {google_auth-2.55.1 → google_auth-2.55.2}/google/oauth2/id_token.py +0 -0
- {google_auth-2.55.1 → google_auth-2.55.2}/google/oauth2/py.typed +0 -0
- {google_auth-2.55.1 → google_auth-2.55.2}/google/oauth2/reauth.py +0 -0
- {google_auth-2.55.1 → google_auth-2.55.2}/google/oauth2/service_account.py +0 -0
- {google_auth-2.55.1 → google_auth-2.55.2}/google/oauth2/sts.py +0 -0
- {google_auth-2.55.1 → google_auth-2.55.2}/google/oauth2/utils.py +0 -0
- {google_auth-2.55.1 → google_auth-2.55.2}/google/oauth2/webauthn_handler.py +0 -0
- {google_auth-2.55.1 → google_auth-2.55.2}/google/oauth2/webauthn_handler_factory.py +0 -0
- {google_auth-2.55.1 → google_auth-2.55.2}/google/oauth2/webauthn_types.py +0 -0
- {google_auth-2.55.1 → google_auth-2.55.2}/google_auth.egg-info/dependency_links.txt +0 -0
- {google_auth-2.55.1 → google_auth-2.55.2}/google_auth.egg-info/top_level.txt +0 -0
- {google_auth-2.55.1 → google_auth-2.55.2}/setup.cfg +0 -0
- {google_auth-2.55.1 → google_auth-2.55.2}/tests/__init__.py +0 -0
- {google_auth-2.55.1 → google_auth-2.55.2}/tests/aio/test__helpers.py +0 -0
- {google_auth-2.55.1 → google_auth-2.55.2}/tests/compute_engine/__init__.py +0 -0
- {google_auth-2.55.1 → google_auth-2.55.2}/tests/compute_engine/data/smbios_product_name +0 -0
- {google_auth-2.55.1 → google_auth-2.55.2}/tests/compute_engine/data/smbios_product_name_non_google +0 -0
- {google_auth-2.55.1 → google_auth-2.55.2}/tests/compute_engine/test__metadata.py +0 -0
- {google_auth-2.55.1 → google_auth-2.55.2}/tests/compute_engine/test_credentials.py +0 -0
- {google_auth-2.55.1 → google_auth-2.55.2}/tests/conftest.py +0 -0
- {google_auth-2.55.1 → google_auth-2.55.2}/tests/crypt/__init__.py +0 -0
- {google_auth-2.55.1 → google_auth-2.55.2}/tests/crypt/test__cryptography_rsa.py +0 -0
- {google_auth-2.55.1 → google_auth-2.55.2}/tests/crypt/test__python_rsa.py +0 -0
- {google_auth-2.55.1 → google_auth-2.55.2}/tests/crypt/test_crypt.py +0 -0
- {google_auth-2.55.1 → google_auth-2.55.2}/tests/crypt/test_es.py +0 -0
- {google_auth-2.55.1 → google_auth-2.55.2}/tests/crypt/test_es256.py +0 -0
- {google_auth-2.55.1 → google_auth-2.55.2}/tests/crypt/test_rsa.py +0 -0
- {google_auth-2.55.1 → google_auth-2.55.2}/tests/data/authorized_user.json +0 -0
- {google_auth-2.55.1 → google_auth-2.55.2}/tests/data/authorized_user_cloud_sdk.json +0 -0
- {google_auth-2.55.1 → google_auth-2.55.2}/tests/data/authorized_user_cloud_sdk_with_quota_project_id.json +0 -0
- {google_auth-2.55.1 → google_auth-2.55.2}/tests/data/authorized_user_with_rapt_token.json +0 -0
- {google_auth-2.55.1 → google_auth-2.55.2}/tests/data/client_secrets.json +0 -0
- {google_auth-2.55.1 → google_auth-2.55.2}/tests/data/context_aware_metadata.json +0 -0
- {google_auth-2.55.1 → google_auth-2.55.2}/tests/data/enterprise_cert_invalid.json +0 -0
- {google_auth-2.55.1 → google_auth-2.55.2}/tests/data/enterprise_cert_valid.json +0 -0
- {google_auth-2.55.1 → google_auth-2.55.2}/tests/data/enterprise_cert_valid_provider.json +0 -0
- {google_auth-2.55.1 → google_auth-2.55.2}/tests/data/es256_privatekey.pem +0 -0
- {google_auth-2.55.1 → google_auth-2.55.2}/tests/data/es256_public_cert.pem +0 -0
- {google_auth-2.55.1 → google_auth-2.55.2}/tests/data/es256_publickey.pem +0 -0
- {google_auth-2.55.1 → google_auth-2.55.2}/tests/data/es256_service_account.json +0 -0
- {google_auth-2.55.1 → google_auth-2.55.2}/tests/data/es384_privatekey.pem +0 -0
- {google_auth-2.55.1 → google_auth-2.55.2}/tests/data/es384_public_cert.pem +0 -0
- {google_auth-2.55.1 → google_auth-2.55.2}/tests/data/es384_publickey.pem +0 -0
- {google_auth-2.55.1 → google_auth-2.55.2}/tests/data/es384_service_account.json +0 -0
- {google_auth-2.55.1 → google_auth-2.55.2}/tests/data/external_account_authorized_user.json +0 -0
- {google_auth-2.55.1 → google_auth-2.55.2}/tests/data/external_account_authorized_user_non_gdu.json +0 -0
- {google_auth-2.55.1 → google_auth-2.55.2}/tests/data/external_subject_token.json +0 -0
- {google_auth-2.55.1 → google_auth-2.55.2}/tests/data/external_subject_token.txt +0 -0
- {google_auth-2.55.1 → google_auth-2.55.2}/tests/data/gdch_service_account.json +0 -0
- {google_auth-2.55.1 → google_auth-2.55.2}/tests/data/impersonated_service_account_authorized_user_source.json +0 -0
- {google_auth-2.55.1 → google_auth-2.55.2}/tests/data/impersonated_service_account_external_account_authorized_user_source.json +0 -0
- {google_auth-2.55.1 → google_auth-2.55.2}/tests/data/impersonated_service_account_service_account_source.json +0 -0
- {google_auth-2.55.1 → google_auth-2.55.2}/tests/data/impersonated_service_account_with_quota_project.json +0 -0
- {google_auth-2.55.1 → google_auth-2.55.2}/tests/data/old_oauth_credentials_py3.pickle +0 -0
- {google_auth-2.55.1 → google_auth-2.55.2}/tests/data/other_cert.pem +0 -0
- {google_auth-2.55.1 → google_auth-2.55.2}/tests/data/pem_from_pkcs12.pem +0 -0
- {google_auth-2.55.1 → google_auth-2.55.2}/tests/data/privatekey.p12 +0 -0
- {google_auth-2.55.1 → google_auth-2.55.2}/tests/data/privatekey.pem +0 -0
- {google_auth-2.55.1 → google_auth-2.55.2}/tests/data/privatekey.pub +0 -0
- {google_auth-2.55.1 → google_auth-2.55.2}/tests/data/public_cert.pem +0 -0
- {google_auth-2.55.1 → google_auth-2.55.2}/tests/data/service_account.json +0 -0
- {google_auth-2.55.1 → google_auth-2.55.2}/tests/data/service_account_non_gdu.json +0 -0
- {google_auth-2.55.1 → google_auth-2.55.2}/tests/data/trust_chain_with_leaf.pem +0 -0
- {google_auth-2.55.1 → google_auth-2.55.2}/tests/data/trust_chain_without_leaf.pem +0 -0
- {google_auth-2.55.1 → google_auth-2.55.2}/tests/data/trust_chain_wrong_order.pem +0 -0
- {google_auth-2.55.1 → google_auth-2.55.2}/tests/oauth2/__init__.py +0 -0
- {google_auth-2.55.1 → google_auth-2.55.2}/tests/oauth2/test__client.py +0 -0
- {google_auth-2.55.1 → google_auth-2.55.2}/tests/oauth2/test_challenges.py +0 -0
- {google_auth-2.55.1 → google_auth-2.55.2}/tests/oauth2/test_credentials.py +0 -0
- {google_auth-2.55.1 → google_auth-2.55.2}/tests/oauth2/test_gdch_credentials.py +0 -0
- {google_auth-2.55.1 → google_auth-2.55.2}/tests/oauth2/test_id_token.py +0 -0
- {google_auth-2.55.1 → google_auth-2.55.2}/tests/oauth2/test_reauth.py +0 -0
- {google_auth-2.55.1 → google_auth-2.55.2}/tests/oauth2/test_service_account.py +0 -0
- {google_auth-2.55.1 → google_auth-2.55.2}/tests/oauth2/test_sts.py +0 -0
- {google_auth-2.55.1 → google_auth-2.55.2}/tests/oauth2/test_utils.py +0 -0
- {google_auth-2.55.1 → google_auth-2.55.2}/tests/oauth2/test_webauthn_handler.py +0 -0
- {google_auth-2.55.1 → google_auth-2.55.2}/tests/oauth2/test_webauthn_handler_factory.py +0 -0
- {google_auth-2.55.1 → google_auth-2.55.2}/tests/oauth2/test_webauthn_types.py +0 -0
- {google_auth-2.55.1 → google_auth-2.55.2}/tests/test__cache.py +0 -0
- {google_auth-2.55.1 → google_auth-2.55.2}/tests/test__cloud_sdk.py +0 -0
- {google_auth-2.55.1 → google_auth-2.55.2}/tests/test__default.py +0 -0
- {google_auth-2.55.1 → google_auth-2.55.2}/tests/test__exponential_backoff.py +0 -0
- {google_auth-2.55.1 → google_auth-2.55.2}/tests/test__helpers.py +0 -0
- {google_auth-2.55.1 → google_auth-2.55.2}/tests/test__oauth2client.py +0 -0
- {google_auth-2.55.1 → google_auth-2.55.2}/tests/test__refresh_worker.py +0 -0
- {google_auth-2.55.1 → google_auth-2.55.2}/tests/test__regional_access_boundary_utils.py +0 -0
- {google_auth-2.55.1 → google_auth-2.55.2}/tests/test__service_account_info.py +0 -0
- {google_auth-2.55.1 → google_auth-2.55.2}/tests/test_api_key.py +0 -0
- {google_auth-2.55.1 → google_auth-2.55.2}/tests/test_app_engine.py +0 -0
- {google_auth-2.55.1 → google_auth-2.55.2}/tests/test_aws.py +0 -0
- {google_auth-2.55.1 → google_auth-2.55.2}/tests/test_credentials.py +0 -0
- {google_auth-2.55.1 → google_auth-2.55.2}/tests/test_credentials_async.py +0 -0
- {google_auth-2.55.1 → google_auth-2.55.2}/tests/test_downscoped.py +0 -0
- {google_auth-2.55.1 → google_auth-2.55.2}/tests/test_exceptions.py +0 -0
- {google_auth-2.55.1 → google_auth-2.55.2}/tests/test_external_account.py +0 -0
- {google_auth-2.55.1 → google_auth-2.55.2}/tests/test_external_account_authorized_user.py +0 -0
- {google_auth-2.55.1 → google_auth-2.55.2}/tests/test_iam.py +0 -0
- {google_auth-2.55.1 → google_auth-2.55.2}/tests/test_impersonated_credentials.py +0 -0
- {google_auth-2.55.1 → google_auth-2.55.2}/tests/test_jwt.py +0 -0
- {google_auth-2.55.1 → google_auth-2.55.2}/tests/test_metrics.py +0 -0
- {google_auth-2.55.1 → google_auth-2.55.2}/tests/test_packaging.py +0 -0
- {google_auth-2.55.1 → google_auth-2.55.2}/tests/test_pluggable.py +0 -0
- {google_auth-2.55.1 → google_auth-2.55.2}/tests/transport/__init__.py +0 -0
- {google_auth-2.55.1 → google_auth-2.55.2}/tests/transport/aio/test_sessions.py +0 -0
- {google_auth-2.55.1 → google_auth-2.55.2}/tests/transport/compliance.py +0 -0
- {google_auth-2.55.1 → google_auth-2.55.2}/tests/transport/test__http_client.py +0 -0
- {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.
|
|
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:
|
|
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
|
-
|
|
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
|
-
|
|
145
|
-
"Certificate file not ready at
|
|
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
|
-
|
|
159
|
-
"Certificate config file not found or incomplete:
|
|
160
|
-
"environment variable).
|
|
161
|
-
|
|
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
|
-
|
|
209
|
-
|
|
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
|
-
|
|
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=
|
|
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
|
|
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
|
-
|
|
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
|
-
|
|
75
|
-
key_bytes
|
|
76
|
-
|
|
77
|
-
|
|
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
|
-
|
|
80
|
-
|
|
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
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
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
|
-
|
|
176
|
+
if inspect.isawaitable(result):
|
|
191
177
|
cert, key = await result
|
|
192
|
-
|
|
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
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
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
|
-
|
|
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
|
|
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
|
-
|
|
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
|
|
161
|
-
|
|
162
|
-
|
|
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
|
-
|
|
156
|
-
# using mTLS.
|
|
157
|
-
from OpenSSL import crypto
|
|
155
|
+
from cryptography import x509
|
|
158
156
|
|
|
159
|
-
|
|
160
|
-
|
|
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(
|
|
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 =
|
|
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 =
|
|
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
|
-
|
|
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 =
|
|
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
|
-
|
|
224
|
-
|
|
225
|
-
# using mTLS.
|
|
226
|
-
from OpenSSL import crypto
|
|
230
|
+
def _encode_cert(cert):
|
|
231
|
+
from cryptography.hazmat.primitives import serialization
|
|
227
232
|
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
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=
|
|
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
|
-
|
|
56
|
-
|
|
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
|
-
|
|
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"
|