Skip to content

Commit

Permalink
increase coverage; remove unused _verify_gpg_sig_using_ssl
Browse files Browse the repository at this point in the history
  • Loading branch information
dholth committed Aug 22, 2023
1 parent 586bd44 commit ffc223d
Show file tree
Hide file tree
Showing 2 changed files with 47 additions and 42 deletions.
44 changes: 2 additions & 42 deletions conda_content_trust/root_signing.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@
from securesystemslib.gpg import functions as gpg_funcs

SSLIB_AVAILABLE = True
except ImportError:
except ImportError: # pragma: no cover
SSLIB_AVAILABLE = False

from .common import (
Expand Down Expand Up @@ -234,11 +234,7 @@ def sign_root_metadata_dict_via_gpg(root_signable, gpg_key_fingerprint):

# Make sure it's the right format.
if not is_a_signable(root_signable):
raise TypeError(
"Expected a signable dictionary; the given file "
+ str(root_md_fname)
+ " failed the check."
)
raise TypeError("Expected a signable dictionary.")
# TODO: Add root-specific checks.

# Canonicalize and serialize the data, putting it in the form we expect to
Expand Down Expand Up @@ -341,42 +337,6 @@ def fetch_keyval_from_gpg(fingerprint):
return key_parameters["keyval"]["public"]["q"]


def _verify_gpg_sig_using_ssl(signature, gpg_key_fingerprint, key_value, data):
"""
THIS IS PROVIDED ONLY FOR TESTING PURPOSES.
We will verify signatures using our own code in conda_content_trust.authentication, not
by using the securesystemslib.gpg.functions.verify_signature call that
sits here.
Wraps securesystemslib.gpg.functions.verify_signature. to format the
arguments in a manner ssl will like (i.e. conforming to
securesystemslib.formats.GPG_SIGNATURE_SCHEMA).
"""
if not SSLIB_AVAILABLE:
# TODO✅: Consider a missing-optional-dependency exception class.
raise Exception(
"verifygpg_sig_using_ssl requires the securesystemslib "
"library, which appears to be unavailable."
)

checkformat_key(key_value)

# This function validates these two args in the process of formatting them.
ssl_format_key = gpg_pubkey_in_ssl_format(gpg_key_fingerprint, key_value)

securesystemslib.formats.GPG_SIGNATURE_SCHEMA.check_match(signature)
securesystemslib.formats._GPG_ED25519_PUBKEY_SCHEMA.check_match(ssl_format_key)

# TODO: ✅ Validate sig (ssl-format gpg sig dict) and content (bytes).

# Note: if we change the signature format to deviate from what ssl uses,
# then we need to correct it here if we're going to use ssl.

validity = gpg_funcs.verify_signature(signature, ssl_format_key, data)

return validity


def _gpg_pubkey_in_ssl_format(fingerprint, q):
"""
THIS IS PROVIDED ONLY FOR TESTING PURPOSES.
Expand Down
45 changes: 45 additions & 0 deletions tests/test_root.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
pytest tests/test_root.py
"""
import copy
import json

import pytest

Expand Down Expand Up @@ -118,6 +119,7 @@ def test_gpg_signing_with_unknown_fingerprint():
# testing suite we're using provides.
try:
gpg_sig = root_signing.sign_via_gpg(b"1234", SAMPLE_UNKNOWN_FINGERPRINT)
assert gpg_sig # minimal "not empty" check
except securesystemslib.gpg.exceptions.CommandError as e:
# TODO✅: This is a clumsy check. It's a shame we don't get better
# than CommandError(), but this will do for now.
Expand Down Expand Up @@ -164,6 +166,11 @@ def test_root_gen_sign_verify():

gpg_sig = root_signing.sign_via_gpg(canonical_signed_portion, SAMPLE_FINGERPRINT)

gpg_sig_with_fingerprint = root_signing.sign_via_gpg(
canonical_signed_portion, SAMPLE_FINGERPRINT, include_fingerprint=True
)
assert "see_also" in gpg_sig_with_fingerprint

signed_rmd = copy.deepcopy(rmd)

signed_rmd["signatures"][SAMPLE_KEYVAL] = gpg_sig
Expand Down Expand Up @@ -259,3 +266,41 @@ def test_verify_existing_root_md():
# TODO ✅: Add a v2 of root to this test, and verify static v2 via v1 as
# well. Also add failure modes (verifying valid v2 using v0
# expectations.)


def test_no_sslib(mocker):
"""
Coverage for "we don't have sslib" exceptions.
"""
mocker.patch("conda_content_trust.root_signing.SSLIB_AVAILABLE", False)
with pytest.raises(Exception, match="securesystemslib"):
root_signing.sign_via_gpg(None, None) # type: ignore
with pytest.raises(Exception, match="securesystemslib"):
root_signing.sign_root_metadata_dict_via_gpg(None, None) # type: ignore
with pytest.raises(Exception, match="securesystemslib"):
root_signing.fetch_keyval_from_gpg(None) # type: ignore


def test_sign_root_metadata_dict_via_gpg():
with pytest.raises(TypeError, match="signable"):
root_signing.sign_root_metadata_dict_via_gpg({}, "")

signable = signing.wrap_as_signable({})
root_signing.sign_root_metadata_dict_via_gpg(signable, SAMPLE_FINGERPRINT)


def test_sign_root_metadata_via_gpg(tmp_path):
md_path = tmp_path / "metadata.json"
signable = signing.wrap_as_signable({})
md_path.write_text(json.dumps(signable))
root_signing.sign_root_metadata_via_gpg(md_path, SAMPLE_FINGERPRINT)
signed = json.loads(md_path.read_text())
assert signed != signable # at least it was updated?


def test_gpg_pubkey_in_ssl_format():
sample_pubkey = "0f" * 32
pubkey_formatted = root_signing._gpg_pubkey_in_ssl_format(
SAMPLE_FINGERPRINT, sample_pubkey
)
assert pubkey_formatted["keyval"]["public"]["q"] == sample_pubkey

0 comments on commit ffc223d

Please sign in to comment.