Skip to content
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

Ensure Kubespawner internal SSL secret is correctly encoded as base64 #828

Merged
merged 4 commits into from
Mar 28, 2024

Conversation

manics
Copy link
Member

@manics manics commented Mar 27, 2024

test_spawn_internal_ssl is failing on the main branch.

This additional (currently failing) test suggests the certificates in the Kubernetes secret is not correctly encoded as base64:

_______________________ test_spawner_internal_ssl_secret _______________________
ssl_app = <jupyterhub.app.JupyterHub object at 0x7f7b728bbb10>
config = {'KubeSpawner': {'namespace': 'kubespawner-test', 'cmd': ['jupyterhub-singleuser'], 'start_timeout': 180, 'environment': {'JUPYTERHUB_API_TOKEN': 'test-secret-token', 'JUPYTERHUB_CLIENT_ID': 'ignored'}}}
    async def test_spawner_internal_ssl_secret(
        ssl_app,
        config,
    ):
        spawner = KubeSpawner(
            config=config,
            user=MockUser(name="ssl"),
            internal_ssl=True,
            internal_trust_bundles=ssl_app.internal_trust_bundles,
            internal_certs_location=ssl_app.internal_certs_location,
            _mock=True,
        )
        # initialize ssl config
        hub_paths = await spawner.create_certs()
    
        spawner.cert_paths = await spawner.move_certs(hub_paths)
    
        # Validate that certificates were correctly encoded as base64
        manifest = spawner.get_secret_manifest(None)
        for _, secret in manifest.data.items():
>           base64.b64decode(secret, validate=True)
/home/runner/work/kubespawner/kubespawner/tests/test_spawner.py:389: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
s = b'LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSURKekNDQWcrZ0F3SUJBZ0lCQURBTkJna3Foa2lHOXcwQkFRc0ZBREFSTVE4d0RRWURWUVFEREFa...VrNkF0K2ZjTzRSa3lmYVl5VzhzRmpHbGhrSjZOelB0bmdGRWZLK0R0YkxkalR4YzkvOElxCmhCSWVidmc9Ci0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0K'
altchars = None, validate = True
    def b64decode(s, altchars=None, validate=False):
        """Decode the Base64 encoded bytes-like object or ASCII string s.
    
        Optional altchars must be a bytes-like object or ASCII string of length 2
        which specifies the alternative alphabet used instead of the '+' and '/'
        characters.
    
        The result is returned as a bytes object.  A binascii.Error is raised if
        s is incorrectly padded.
    
        If validate is False (the default), characters that are neither in the
        normal base-64 alphabet nor the alternative alphabet are discarded prior
        to the padding check.  If validate is True, these non-alphabet characters
        in the input result in a binascii.Error.
        For more information about the strict base64 check, see:
    
        https://docs.python.org/3.11/library/binascii.html#binascii.a2b_base64
        """
        s = _bytes_from_decode_data(s)
        if altchars is not None:
            altchars = _bytes_from_decode_data(altchars)
            assert len(altchars) == 2, repr(altchars)
            s = s.translate(bytes.maketrans(altchars, b'+/'))
>       return binascii.a2b_base64(s, strict_mode=validate)
E       binascii.Error: Excess data after padding
/opt/hostedtoolcache/Python/3.11.8/x64/lib/python3.11/base64.py:88: Error

This seems to be caused by the base64 encoded notebooks-ca_trust.crt containing a == in the middle, followed by more encoded data. == should only appear as padding at the end.

@manics manics added the bug label Mar 27, 2024
@consideRatio
Copy link
Member

@manics wiee nice work debugging this!

Otherwise you can end up with `==` padding in the middle of the encoded secret data, which is invalid base64.
@manics manics changed the title Validate the Kubespawner secret is correctly encoded as base64 Ensure Kubespawner internal SSL secret is correctly encoded as base64 Mar 28, 2024
@consideRatio
Copy link
Member

Did you understand if there were a regression, or if this never worked?

@manics
Copy link
Member Author

manics commented Mar 28, 2024

My best guess is a dependency or default configuration changed somewhere, which changed the length of the generated certificate, resulting in padding being added when it previously wasn't needed.

@consideRatio consideRatio merged commit f30b2a5 into jupyterhub:main Mar 28, 2024
9 checks passed
@manics manics deleted the internal-ssl-test-failure branch March 28, 2024 19:34
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants