feat: add default client cert source util (#486)
feat: add default client cert source util
diff --git a/google/auth/exceptions.py b/google/auth/exceptions.py
index 9501386..5b61460 100644
--- a/google/auth/exceptions.py
+++ b/google/auth/exceptions.py
@@ -37,4 +37,5 @@
class MutualTLSChannelError(GoogleAuthError):
- """Used to indicate that mutual TLS channel creation is failed."""
+ """Used to indicate that mutual TLS channel creation is failed, or mutual
+ TLS channel credentials is missing or invalid."""
diff --git a/google/auth/transport/mtls.py b/google/auth/transport/mtls.py
new file mode 100644
index 0000000..063b265
--- /dev/null
+++ b/google/auth/transport/mtls.py
@@ -0,0 +1,60 @@
+# Copyright 2020 Google LLC
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+"""Utilites for mutual TLS."""
+
+import six
+
+from google.auth import exceptions
+from google.auth.transport import _mtls_helper
+
+
+def has_default_client_cert_source():
+ """Check if default client SSL credentials exists on the device.
+
+ Returns:
+ bool: indicating if the default client cert source exists.
+ """
+ metadata_path = _mtls_helper._check_dca_metadata_path(
+ _mtls_helper.CONTEXT_AWARE_METADATA_PATH
+ )
+ return metadata_path is not None
+
+
+def default_client_cert_source():
+ """Get a callback which returns the default client SSL credentials.
+
+ Returns:
+ Callable[[], [bytes, bytes]]: A callback which returns the default
+ client certificate bytes and private key bytes, both in PEM format.
+
+ Raises:
+ google.auth.exceptions.DefaultClientCertSourceError: If the default
+ client SSL credentials don't exist or are malformed.
+ """
+ if not has_default_client_cert_source():
+ raise exceptions.MutualTLSChannelError(
+ "Default client cert source doesn't exist"
+ )
+
+ def callback():
+ try:
+ _, cert_bytes, key_bytes = _mtls_helper.get_client_cert_and_key()
+ except (OSError, RuntimeError, ValueError) as caught_exc:
+ new_exc = exceptions.MutualTLSChannelError(caught_exc)
+ six.raise_from(new_exc, caught_exc)
+
+ return cert_bytes, key_bytes
+
+ return callback
diff --git a/google/auth/transport/requests.py b/google/auth/transport/requests.py
index 26096e2..cc0e93b 100644
--- a/google/auth/transport/requests.py
+++ b/google/auth/transport/requests.py
@@ -249,8 +249,8 @@
credentials' headers to the request and refreshing credentials as needed.
This class also supports mutual TLS via :meth:`configure_mtls_channel`
- method. If client_cert_callabck is provided, client certificate and private
- key are loaded using the callback; if client_cert_callabck is None,
+ method. If client_cert_callback is provided, client certificate and private
+ key are loaded using the callback; if client_cert_callback is None,
application default SSL credentials will be used. Exceptions are raised if
there are problems with the certificate, private key, or the loading process,
so it should be called within a try/except block.
@@ -344,11 +344,11 @@
"""Configure the client certificate and key for SSL connection.
If client certificate and key are successfully obtained (from the given
- client_cert_callabck or from application default SSL credentials), a
+ client_cert_callback or from application default SSL credentials), a
:class:`_MutualTlsAdapter` instance will be mounted to "https://" prefix.
Args:
- client_cert_callabck (Optional[Callable[[], (bytes, bytes)]]):
+ client_cert_callback (Optional[Callable[[], (bytes, bytes)]]):
The optional callback returns the client certificate and private
key bytes both in PEM format.
If the callback is None, application default SSL credentials
diff --git a/google/auth/transport/urllib3.py b/google/auth/transport/urllib3.py
index c359f35..3771d84 100644
--- a/google/auth/transport/urllib3.py
+++ b/google/auth/transport/urllib3.py
@@ -202,8 +202,8 @@
credentials' headers to the request and refreshing credentials as needed.
This class also supports mutual TLS via :meth:`configure_mtls_channel`
- method. If client_cert_callabck is provided, client certificate and private
- key are loaded using the callback; if client_cert_callabck is None,
+ method. If client_cert_callback is provided, client certificate and private
+ key are loaded using the callback; if client_cert_callback is None,
application default SSL credentials will be used. Exceptions are raised if
there are problems with the certificate, private key, or the loading process,
so it should be called within a try/except block.
@@ -280,14 +280,14 @@
super(AuthorizedHttp, self).__init__()
- def configure_mtls_channel(self, client_cert_callabck=None):
- """Configures mutual TLS channel using the given client_cert_callabck or
+ def configure_mtls_channel(self, client_cert_callback=None):
+ """Configures mutual TLS channel using the given client_cert_callback or
application default SSL credentials. Returns True if the channel is
mutual TLS and False otherwise. Note that the `http` provided in the
constructor will be overwritten.
Args:
- client_cert_callabck (Optional[Callable[[], (bytes, bytes)]]):
+ client_cert_callback (Optional[Callable[[], (bytes, bytes)]]):
The optional callback returns the client certificate and private
key bytes both in PEM format.
If the callback is None, application default SSL credentials
@@ -308,7 +308,7 @@
try:
found_cert_key, cert, key = transport._mtls_helper.get_client_cert_and_key(
- client_cert_callabck
+ client_cert_callback
)
if found_cert_key: