googleapis / googleapis/google-cloud-python
auth: get_client_cert_and_key() suppresses default SSL fallback on empty callback
- 主要语言
- Python
- 星标
- 5.4k
- 派生
- 1.8k
- 平均合并
- 3 天 4 小时
- 30 天内合并 PR
- 122
描述
In `google.auth.aio.transport.mtls.get_client_cert_and_key()`, providing a `client_cert_callback` causes the function to return `(True, cert, key)` unconditionally. When the callback returns `(None, None)` or empty bytes, the function returns `(True, None, None)`.
This violates the documented contract:
> "if the callback is None or doesn't provide certificate and key, the function tries application default SSL credentials"
Because line 176 returns early, execution never falls through to `await get_client_ssl_credentials()`. Downstream callers such as `AsyncAuthorizedSession.configure_mtls_channel()` receive `has_cert = True` and set `self._is_mtls = True`, but passing `(None, None)` into `make_client_cert_ssl_context()` skips `load_cert_chain()` and returns an SSL context without client certificates while the session treats mTLS as active.
The synchronous implementation in `google.auth.transport._mtls_helper.get_client_cert_and_key()` shares this same behavior.
### Proposed Fix
Guard the callback return value to ensure `cert` and `key` are truthy before returning `has_cert = True`:
```python
if client_cert_callback:
result = client_cert_callback()
if inspect.isawaitable(result):
cert, key = await result
else:
cert, key = result
if cert and key:
return True, cert, key
has_cert, cert, key, _ = await get_client_ssl_credentials()
return has_cert, cert, key
```
The corresponding guard should be applied to `google.auth.transport._mtls_helper.get_client_cert_and_key()`. Unit tests in `tests/transport/aio/test_aio_mtls_helper.py` and `tests/transport/test__mtls_helper.py` should assert that callbacks returning `(None, None)` fall back to default SSL credentials when available, or return `(False, None, None)` when no credentials exist.
贡献指南
评估
这个 Issue 还没有评估数据。