-
Notifications
You must be signed in to change notification settings - Fork 1.7k
refactor(auth): replace pyOpenSSL with standard ssl and cryptography #16976
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
19f9699
48f4e26
41282b8
1704dd8
a6882e4
f9a741a
04776d6
980527e
105b02a
0a9e02d
7b77812
31ae507
759f6c2
9c31523
30dd701
3eaaf22
56cde12
22e7f0d
1305d2f
3ff3750
21d0254
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -152,13 +152,15 @@ def __init__(self, trust_chain_path, leaf_cert_callback): | |
|
|
||
| @_helpers.copy_docstring(SubjectTokenSupplier) | ||
| def get_subject_token(self, context, request): | ||
| # Import OpennSSL inline because it is an extra import only required by customers | ||
| # using mTLS. | ||
| from OpenSSL import crypto | ||
| from cryptography import x509 | ||
|
|
||
| leaf_cert = crypto.load_certificate( | ||
| crypto.FILETYPE_PEM, self._leaf_cert_callback() | ||
| ) | ||
| try: | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This wraps too much code in the parse error. The callback can fail for config or file-read reasons, but because it is inside this Can we call the callback before this parse |
||
| leaf_cert_data = self._leaf_cert_callback() | ||
| if isinstance(leaf_cert_data, str): | ||
| leaf_cert_data = leaf_cert_data.encode("utf-8") | ||
| leaf_cert = x509.load_pem_x509_certificate(leaf_cert_data) | ||
| except Exception as e: | ||
| raise exceptions.RefreshError("Failed to parse leaf certificate.") from e | ||
| trust_chain = self._read_trust_chain() | ||
| cert_chain = [] | ||
|
|
||
|
|
@@ -184,9 +186,7 @@ def get_subject_token(self, context, request): | |
| return json.dumps(cert_chain) | ||
|
|
||
| def _read_trust_chain(self): | ||
| # Import OpennSSL inline because it is an extra import only required by customers | ||
| # using mTLS. | ||
| from OpenSSL import crypto | ||
| from cryptography import x509 | ||
|
|
||
| certificate_trust_chain = [] | ||
| # If no trust chain path was provided, return an empty list. | ||
|
|
@@ -204,9 +204,7 @@ def _read_trust_chain(self): | |
| cert_data = b"-----BEGIN CERTIFICATE-----" + cert_block | ||
| try: | ||
| # Load each certificate and add it to the trust chain. | ||
| cert = crypto.load_certificate( | ||
| crypto.FILETYPE_PEM, cert_data | ||
| ) | ||
| cert = x509.load_pem_x509_certificate(cert_data) | ||
|
nbayati marked this conversation as resolved.
|
||
| certificate_trust_chain.append(cert) | ||
| except Exception as e: | ||
| raise exceptions.RefreshError( | ||
|
|
@@ -215,19 +213,21 @@ def _read_trust_chain(self): | |
| ) | ||
| ) from e | ||
| return certificate_trust_chain | ||
| except FileNotFoundError: | ||
| except FileNotFoundError as e: | ||
| raise exceptions.RefreshError( | ||
| "Trust chain file '{}' was not found.".format(self._trust_chain_path) | ||
| ) | ||
| ) from e | ||
| except OSError as e: | ||
| raise exceptions.RefreshError( | ||
| "Error accessing trust chain file '{}'.".format(self._trust_chain_path) | ||
| ) from e | ||
|
|
||
| def _encode_cert(cert): | ||
| # Import OpennSSL inline because it is an extra import only required by customers | ||
| # using mTLS. | ||
| from OpenSSL import crypto | ||
| from cryptography.hazmat.primitives import serialization | ||
|
|
||
| return base64.b64encode( | ||
| crypto.dump_certificate(crypto.FILETYPE_ASN1, cert) | ||
| ).decode("utf-8") | ||
| return base64.b64encode(cert.public_bytes(serialization.Encoding.DER)).decode( | ||
| "utf-8" | ||
| ) | ||
|
|
||
|
|
||
| def _parse_token_data(token_content, format_type="text", subject_token_field_name=None): | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -23,8 +23,6 @@ | |
| import os | ||
| import sys | ||
|
|
||
| import cffi # type: ignore | ||
|
|
||
| from google.auth import exceptions | ||
|
|
||
| _LOGGER = logging.getLogger(__name__) | ||
|
|
@@ -45,13 +43,12 @@ | |
| ) | ||
|
|
||
|
|
||
| # Cast SSL_CTX* to void* | ||
| def _cast_ssl_ctx_to_void_p_pyopenssl(ssl_ctx): | ||
| return ctypes.cast(int(cffi.FFI().cast("intptr_t", ssl_ctx)), ctypes.c_void_p) | ||
|
|
||
|
|
||
| # Cast SSL_CTX* to void* | ||
| def _cast_ssl_ctx_to_void_p_stdlib(context): | ||
| if sys.implementation.name != "cpython" or hasattr(sys, "getobjects"): | ||
| raise exceptions.MutualTLSChannelError( | ||
| "Custom TLS signing is only supported on standard release CPython runtimes." | ||
| ) | ||
| return ctypes.c_void_p.from_address( | ||
| id(context) + ctypes.sizeof(ctypes.c_void_p) * 2 | ||
| ) | ||
|
|
@@ -274,7 +271,7 @@ def attach_to_ssl_context(self, ctx): | |
| if not self._offload_lib.ConfigureSslContext( | ||
| self._sign_callback, | ||
| ctypes.c_char_p(self._cert), | ||
| _cast_ssl_ctx_to_void_p_pyopenssl(ctx._ctx._context), | ||
| _cast_ssl_ctx_to_void_p_stdlib(ctx), | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The stdlib C pointer arithmetic hack
Remediation: import sys
if sys.implementation.name != "cpython" or hasattr(sys, "getobjects"):
raise exceptions.MutualTLSChannelError(
"Custom TLS signing is only supported on standard release CPython runtimes."
)
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Done! I'm glad we're catching some of these existing issues and cleaning things up as part of this PR 🎉 |
||
| ): | ||
| raise exceptions.MutualTLSChannelError( | ||
| "failed to configure ECP Offload SSL context" | ||
|
|
||
Uh oh!
There was an error while loading. Please reload this page.