Skip to content

Commit

Permalink
Merge pull request #813 from jku/upgrade-sigstore
Browse files Browse the repository at this point in the history
Upgrade sigstore dependency
  • Loading branch information
lukpueh committed Jun 4, 2024
2 parents bc6f882 + 6fae4c8 commit 5e734e4
Show file tree
Hide file tree
Showing 7 changed files with 49 additions and 44 deletions.
9 changes: 4 additions & 5 deletions .github/workflows/test-sigstore.yml
Original file line number Diff line number Diff line change
@@ -1,11 +1,10 @@
name: Run Sigstore Signer tests

on:
## Disabled temporarily: #781
#push:
# branches:
# - main
#pull_request:
push:
branches:
- main
pull_request:
workflow_dispatch:

permissions: {}
Expand Down
3 changes: 0 additions & 3 deletions mypy.ini
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,6 @@ ignore_missing_imports = True
[mypy-asn1crypto.*]
ignore_missing_imports = True

[mypy-sigstore.*]
ignore_missing_imports = True

[mypy-sigstore_protobuf_specs.*]
ignore_missing_imports = True

Expand Down
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ azurekms = ["azure-identity", "azure-keyvault-keys", "cryptography>=40.0.0"]
awskms = ["boto3", "botocore", "cryptography>=40.0.0"]
hsm = ["asn1crypto", "cryptography>=40.0.0", "PyKCS11"]
PySPX = ["PySPX>=0.5.0"]
sigstore = ["sigstore~=2.0"]
sigstore = ["sigstore~=3.0"]
vault = ["hvac", "cryptography>=40.0.0"]

[tool.hatch.version]
Expand Down
2 changes: 1 addition & 1 deletion requirements-sigstore.txt
Original file line number Diff line number Diff line change
@@ -1 +1 @@
sigstore==2.1.5
sigstore==3.0.0
61 changes: 27 additions & 34 deletions securesystemslib/signer/_sigstore_signer.py
Original file line number Diff line number Diff line change
@@ -1,13 +1,7 @@
"""Signer implementation for project sigstore.
NOTE: SigstoreSigner and -Key are disabled temporarily around
the Securesystemslib 1.0 release as the cyclic dependency
(securesystemslib -> sigstore-python -> tuf -> securesystemslib)
is problematic during API deprecations.
See issue #781.
"""

import io
import json
import logging
from typing import Any, Dict, Optional, Tuple
from urllib import parse
Expand Down Expand Up @@ -66,37 +60,38 @@ def to_dict(self) -> Dict:

def verify_signature(self, signature: Signature, data: bytes) -> None:
# pylint: disable=import-outside-toplevel,import-error
result = None
try:
from sigstore.verify import VerificationMaterials, Verifier
from sigstore.errors import VerificationError as SigstoreVerifyError
from sigstore.models import Bundle
from sigstore.verify import Verifier
from sigstore.verify.policy import Identity
from sigstore_protobuf_specs.dev.sigstore.bundle.v1 import Bundle
except ImportError as e:
raise VerificationError(IMPORT_ERROR) from e

try:
verifier = Verifier.production()
identity = Identity(
identity=self.keyval["identity"], issuer=self.keyval["issuer"]
)
bundle = Bundle().from_dict(signature.unrecognized_fields["bundle"])
materials = VerificationMaterials.from_bundle(
input_=io.BytesIO(data), bundle=bundle, offline=True
)
result = verifier.verify(materials, identity)
bundle_data = signature.unrecognized_fields["bundle"]
bundle = Bundle.from_json(json.dumps(bundle_data))

except Exception as e:
logger.info("Key %s failed to verify sig: %s", self.keyid, str(e))
raise VerificationError(
f"Unknown failure to verify signature by {self.keyid}"
) from e
verifier.verify_artifact(data, bundle, identity)

if not result:
except SigstoreVerifyError as e:
logger.info(
"Key %s failed to verify sig: %s",
self.keyid,
getattr(result, "reason", ""),
e,
)
raise UnverifiedSignatureError(
f"Failed to verify signature by {self.keyid}"
)
) from e
except Exception as e:
logger.info("Key %s failed to verify sig: %s", self.keyid, str(e))
raise VerificationError(
f"Unknown failure to verify signature by {self.keyid}"
) from e


class SigstoreSigner(Signer):
Expand Down Expand Up @@ -189,9 +184,9 @@ def from_priv_key_uri(

key_identity = public_key.keyval["identity"]
key_issuer = public_key.keyval["issuer"]
if key_issuer != token.expected_certificate_subject:
if key_issuer != token.federated_issuer:
raise ValueError(
f"Signer identity issuer {token.expected_certificate_subject} "
f"Signer identity issuer {token.federated_issuer} "
f"did not match key: {key_issuer}"
)
# TODO: should check ambient identity too: unfortunately IdentityToken does
Expand Down Expand Up @@ -246,9 +241,7 @@ def import_via_auth(cls) -> Tuple[str, SigstoreKey]:

# authenticate to get the identity and issuer
token = Issuer.production().identity_token()
return cls.import_(
token.identity, token.expected_certificate_subject, False
)
return cls.import_(token.identity, token.federated_issuer, False)

def sign(self, payload: bytes) -> Signature:
"""Signs payload using the OIDC token on the signer instance.
Expand All @@ -273,12 +266,12 @@ def sign(self, payload: bytes) -> Signature:

context = SigningContext.production()
with context.signer(self._token) as sigstore_signer:
result = sigstore_signer.sign(io.BytesIO(payload))

bundle = result.to_bundle()

bundle = sigstore_signer.sign_artifact(payload)
# We want to access the actual signature, see
# https://github.com/sigstore/protobuf-specs/blob/main/protos/sigstore_bundle.proto
bundle_json = json.loads(bundle.to_json())
return Signature(
self.public_key.keyid,
bundle.message_signature.signature.hex(),
{"bundle": bundle.to_dict()},
bundle_json["messageSignature"]["signature"],
{"bundle": bundle_json},
)
15 changes: 15 additions & 0 deletions tests/check_sigstore_signer.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,10 @@
from tempfile import TemporaryDirectory
from unittest import mock

from securesystemslib.exceptions import (
UnverifiedSignatureError,
VerificationError,
)
from securesystemslib.signer import (
SIGNER_FOR_URI_SCHEME,
Signer,
Expand Down Expand Up @@ -100,8 +104,19 @@ def test_sign(self):
signer = Signer.from_priv_key_uri(uri, public_key)

sig = signer.sign(b"data")

# Successful verification
public_key.verify_signature(sig, b"data")

# Signature mismatch
with self.assertRaises(UnverifiedSignatureError):
public_key.verify_signature(sig, b"incorrect data")

# Broken bundle
sig.unrecognized_fields["bundle"]["verificationMaterial"] = None
with self.assertRaises(VerificationError):
public_key.verify_signature(sig, b"data")


if __name__ == "__main__":
unittest.main(verbosity=4, buffer=False)
1 change: 1 addition & 0 deletions tox.ini
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@ commands =
deps =
-r{toxinidir}/requirements-pinned.txt
-r{toxinidir}/requirements-lint.txt
-r{toxinidir}/requirements-sigstore.txt
commands =
black --check --diff .
isort --check --diff .
Expand Down

0 comments on commit 5e734e4

Please sign in to comment.