Skip to content

Commit a733d5a

Browse files
use new methods for building requests
Signed-off-by: Ramon Petgrave <[email protected]>
1 parent 34043a2 commit a733d5a

File tree

2 files changed

+75
-40
lines changed

2 files changed

+75
-40
lines changed

sigstore/_internal/rekor/client.py

Lines changed: 69 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818

1919
from __future__ import annotations
2020

21+
import base64
2122
import json
2223
import logging
2324
from abc import ABC
@@ -26,8 +27,15 @@
2627

2728
import rekor_types
2829
import requests
30+
from cryptography.hazmat.primitives import serialization
31+
from cryptography.x509 import Certificate
2932

3033
from sigstore._internal import USER_AGENT
34+
from sigstore._internal.rekor import (
35+
RekorLogSubmitter,
36+
)
37+
from sigstore.dsse import Envelope
38+
from sigstore.hashes import Hashed
3139
from sigstore.models import LogEntry
3240

3341
_logger = logging.getLogger(__name__)
@@ -216,7 +224,7 @@ def post(
216224
return oldest_entry
217225

218226

219-
class RekorClient:
227+
class RekorClient(RekorLogSubmitter):
220228
"""The internal Rekor client"""
221229

222230
def __init__(self, url: str) -> None:
@@ -261,3 +269,63 @@ def log(self) -> RekorLog:
261269
Returns a `RekorLog` adapter for making requests to a Rekor log.
262270
"""
263271
return RekorLog(f"{self.url}/log", session=self.session)
272+
273+
def create_entry( # type: ignore[override]
274+
self, request: rekor_types.Hashedrekord | rekor_types.Dsse
275+
) -> LogEntry:
276+
"""
277+
Submit the request to Rekor.
278+
"""
279+
return self.log.entries.post(request)
280+
281+
def _build_hashed_rekord_request( # type: ignore[override]
282+
self, hashed_input: Hashed, signature: bytes, certificate: Certificate
283+
) -> rekor_types.Hashedrekord:
284+
"""
285+
Construct a hashed rekord request to submit to Rekor.
286+
"""
287+
return rekor_types.Hashedrekord(
288+
spec=rekor_types.hashedrekord.HashedrekordV001Schema(
289+
signature=rekor_types.hashedrekord.Signature(
290+
content=base64.b64encode(signature).decode(),
291+
public_key=rekor_types.hashedrekord.PublicKey(
292+
content=base64.b64encode(
293+
certificate.public_bytes(
294+
encoding=serialization.Encoding.PEM
295+
)
296+
).decode()
297+
),
298+
),
299+
data=rekor_types.hashedrekord.Data(
300+
hash=rekor_types.hashedrekord.Hash(
301+
algorithm=hashed_input._as_hashedrekord_algorithm(),
302+
value=hashed_input.digest.hex(),
303+
)
304+
),
305+
),
306+
)
307+
308+
def _build_dsse_request( # type: ignore[override]
309+
self, envelope: Envelope, certificate: Certificate
310+
) -> rekor_types.Dsse:
311+
"""
312+
Construct a dsse request to submit to Rekor.
313+
"""
314+
return rekor_types.Dsse(
315+
spec=rekor_types.dsse.DsseSchema(
316+
# NOTE: mypy can't see that this kwarg is correct due to two interacting
317+
# behaviors/bugs (one pydantic, one datamodel-codegen):
318+
# See: <https://github.com/pydantic/pydantic/discussions/7418#discussioncomment-9024927>
319+
# See: <https://github.com/koxudaxi/datamodel-code-generator/issues/1903>
320+
proposed_content=rekor_types.dsse.ProposedContent( # type: ignore[call-arg]
321+
envelope=envelope.to_json(),
322+
verifiers=[
323+
base64.b64encode(
324+
certificate.public_bytes(
325+
encoding=serialization.Encoding.PEM
326+
)
327+
).decode()
328+
],
329+
),
330+
),
331+
)

sigstore/sign.py

Lines changed: 6 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,6 @@
3838

3939
from __future__ import annotations
4040

41-
import base64
4241
import logging
4342
from collections.abc import Iterator
4443
from contextlib import contextmanager
@@ -47,7 +46,7 @@
4746

4847
import cryptography.x509 as x509
4948
import rekor_types
50-
from cryptography.hazmat.primitives import hashes, serialization
49+
from cryptography.hazmat.primitives import hashes
5150
from cryptography.hazmat.primitives.asymmetric import ec
5251
from cryptography.x509.oid import NameOID
5352
from sigstore_protobuf_specs.dev.sigstore.common.v1 import (
@@ -182,7 +181,7 @@ def _finalize_sign(
182181
Perform the common "finalizing" steps in a Sigstore signing flow.
183182
"""
184183
# Submit the proposed entry to the transparency log
185-
entry = self._signing_ctx._rekor.log.entries.post(proposed_entry)
184+
entry = self._signing_ctx._rekor.create_entry(proposed_entry)
186185

187186
_logger.debug(f"Transparency log entry created with index: {entry.log_index}")
188187

@@ -211,26 +210,12 @@ def sign_dsse(
211210
"""
212211
cert = self._signing_cert()
213212

214-
# Prepare inputs
215-
b64_cert = base64.b64encode(
216-
cert.public_bytes(encoding=serialization.Encoding.PEM)
217-
)
218-
219213
# Sign the statement, producing a DSSE envelope
220214
content = dsse._sign(self._private_key, input_)
221215

222216
# Create the proposed DSSE log entry
223-
proposed_entry = rekor_types.Dsse(
224-
spec=rekor_types.dsse.DsseSchema(
225-
# NOTE: mypy can't see that this kwarg is correct due to two interacting
226-
# behaviors/bugs (one pydantic, one datamodel-codegen):
227-
# See: <https://github.com/pydantic/pydantic/discussions/7418#discussioncomment-9024927>
228-
# See: <https://github.com/koxudaxi/datamodel-code-generator/issues/1903>
229-
proposed_content=rekor_types.dsse.ProposedContent( # type: ignore[call-arg]
230-
envelope=content.to_json(),
231-
verifiers=[b64_cert.decode()],
232-
),
233-
),
217+
proposed_entry = self._signing_ctx._rekor._build_dsse_request(
218+
envelope=content, certificate=cert
234219
)
235220

236221
return self._finalize_sign(cert, content, proposed_entry)
@@ -255,11 +240,6 @@ def sign_artifact(
255240

256241
cert = self._signing_cert()
257242

258-
# Prepare inputs
259-
b64_cert = base64.b64encode(
260-
cert.public_bytes(encoding=serialization.Encoding.PEM)
261-
)
262-
263243
# Sign artifact
264244
hashed_input = sha256_digest(input_)
265245

@@ -276,21 +256,8 @@ def sign_artifact(
276256
)
277257

278258
# Create the proposed hashedrekord entry
279-
proposed_entry = rekor_types.Hashedrekord(
280-
spec=rekor_types.hashedrekord.HashedrekordV001Schema(
281-
signature=rekor_types.hashedrekord.Signature(
282-
content=base64.b64encode(artifact_signature).decode(),
283-
public_key=rekor_types.hashedrekord.PublicKey(
284-
content=b64_cert.decode()
285-
),
286-
),
287-
data=rekor_types.hashedrekord.Data(
288-
hash=rekor_types.hashedrekord.Hash(
289-
algorithm=hashed_input._as_hashedrekord_algorithm(),
290-
value=hashed_input.digest.hex(),
291-
)
292-
),
293-
),
259+
proposed_entry = self._signing_ctx._rekor._build_hashed_rekord_request(
260+
hashed_input=hashed_input, signature=artifact_signature, certificate=cert
294261
)
295262

296263
return self._finalize_sign(cert, content, proposed_entry)

0 commit comments

Comments
 (0)