From 51e0d4458fc23d961a70c1bf27d7da855201e82b Mon Sep 17 00:00:00 2001
From: Jean-Paul Calderone <exarkun@twistedmatrix.com>
Date: Mon, 17 May 2021 15:05:33 -0400
Subject: [PATCH] Add a direct test for key-loading helper

This exercises whitespace and no-whitespace cases.
---
 src/_zkapauthorizer/tests/strategies.py  | 31 ++++++++++++++++++++++++
 src/_zkapauthorizer/tests/test_plugin.py | 28 +++++++++++++++++++++
 2 files changed, 59 insertions(+)

diff --git a/src/_zkapauthorizer/tests/strategies.py b/src/_zkapauthorizer/tests/strategies.py
index fde7590..77c854a 100644
--- a/src/_zkapauthorizer/tests/strategies.py
+++ b/src/_zkapauthorizer/tests/strategies.py
@@ -35,6 +35,7 @@ from zope.interface import (
 
 from hypothesis.strategies import (
     one_of,
+    sampled_from,
     just,
     none,
     binary,
@@ -915,3 +916,33 @@ def api_auth_tokens():
     authorization tokens.
     """
     return binary(min_size=32, max_size=32).map(b64encode)
+
+
+def ristretto_signing_keys():
+    """
+    Build byte strings holding base64-encoded Ristretto signing keys, perhaps
+    with leading or trailing whitespace.
+    """
+    keys = sampled_from([
+        # A few legit keys
+        b"mkQf85V2vyLQRUYuqRb+Ke6K+M9pOtXm4MslsuCdBgg=",
+        b"6f93OIdZHHAmSIaRXDSIU1UcN+sbDAh41TRPb5DhrgI=",
+        b"k58h8yPT18epw+EKMJhwHFfoM6r3TIExKm4efQHNBgM=",
+        b"rbaAlWZ3NCnl5oZ9meviGfpLbyJpgpuiuFOX0rLnNwQ=",
+    ])
+    whitespace = sampled_from([
+        # maybe no whitespace at all
+        b""
+        # or maybe some
+        b" ",
+        b"\t",
+        b"\n",
+        b"\r\n",
+    ])
+
+    return builds(
+        lambda leading, key, trailing: leading + key + trailing,
+        whitespace,
+        keys,
+        whitespace,
+    )
diff --git a/src/_zkapauthorizer/tests/test_plugin.py b/src/_zkapauthorizer/tests/test_plugin.py
index 0349dde..1d46032 100644
--- a/src/_zkapauthorizer/tests/test_plugin.py
+++ b/src/_zkapauthorizer/tests/test_plugin.py
@@ -110,6 +110,10 @@ from twisted.plugins.zkapauthorizer import (
     storage_server,
 )
 
+from challenge_bypass_ristretto import (
+    SigningKey,
+)
+
 from ..spending import (
     GET_PASSES,
 )
@@ -134,6 +138,10 @@ from ..lease_maintenance import (
     SERVICE_NAME,
 )
 
+from .._plugin import (
+    load_signing_key,
+)
+
 from .strategies import (
     minimal_tahoe_configs,
     tahoe_configs,
@@ -147,6 +155,7 @@ from .strategies import (
     sharenum_sets,
     sizes,
     pass_counts,
+    ristretto_signing_keys,
 )
 from .matchers import (
     Provides,
@@ -662,3 +671,22 @@ class LeaseMaintenanceServiceTests(TestCase):
         been written to the client's configuration directory.
         """
         return self._created_test(get_config, servers_yaml, rootcap=False)
+
+
+class LoadSigningKeyTests(TestCase):
+    """
+    Tests for ``load_signing_key``.
+    """
+    @given(ristretto_signing_keys())
+    def test_valid(self, key_bytes):
+        """
+        A base64-encoded byte string representing a valid Ristretto signing key
+        can be loaded from a file into a ``SigningKey`` object using
+        ``load_signing_key``.
+
+        :param bytes key: A base64-encoded Ristretto signing key.
+        """
+        p = FilePath(self.useFixture(TempDir()).join(b"key"))
+        p.setContent(key_bytes)
+        key = load_signing_key(p)
+        self.assertThat(key, IsInstance(SigningKey))
-- 
GitLab