Skip to content

Commit

Permalink
Sign Bundle with a Timestamp Authority (#1216)
Browse files Browse the repository at this point in the history
Co-authored-by: Facundo Tuesca <[email protected]>
Co-authored-by: William Woodruff <[email protected]>
Co-authored-by: William Woodruff <[email protected]>
  • Loading branch information
4 people authored Nov 25, 2024
1 parent d930290 commit 383797a
Show file tree
Hide file tree
Showing 11 changed files with 403 additions and 8 deletions.
15 changes: 15 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,21 @@ jobs:
- name: test
run: make test TEST_ARGS="-vv --showlocals"

- name: test (timestamp-authority)
if: ${{ matrix.conf.os == 'ubuntu-latest' }}
run: |
wget https://github.com/sigstore/timestamp-authority/releases/download/${SIGSTORE_TIMESTAMP}/timestamp-server-linux-amd64 -O /tmp/timestamp-server
chmod +x /tmp/timestamp-server
# Run the TSA in background
/tmp/timestamp-server serve --port 3000 --disable-ntp-monitoring &
export TEST_SIGSTORE_TIMESTAMP_AUTHORITY_URL="http://localhost:3000/api/v1/timestamp"
# Ensure Timestamp Authority tests are not skipped by
# having pytest show skipped tests and verifying ours are running
make test TEST_ARGS="-m timestamp_authority -rs" | tee output
! grep -q "skipping test that requires a Timestamp Authority" output || (echo "ERROR: Found skip message" && exit 1)
env:
SIGSTORE_TIMESTAMP: "v1.2.3"

- name: test (interactive)
if: (github.event_name != 'pull_request') || !github.event.pull_request.head.repo.fork
run: make test-interactive TEST_ARGS="-vv --showlocals"
Expand Down
81 changes: 81 additions & 0 deletions sigstore/_internal/timestamp.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,17 @@
from dataclasses import dataclass
from datetime import datetime

import requests
from rfc3161_client import (
TimestampRequestBuilder,
TimeStampResponse,
decode_timestamp_response,
)

from sigstore._internal import USER_AGENT

CLIENT_TIMEOUT: int = 5


class TimestampSource(enum.Enum):
"""Represents the source of a timestamp."""
Expand All @@ -38,3 +49,73 @@ class TimestampVerificationResult:

source: TimestampSource
time: datetime


class TimestampError(Exception):
"""
A generic error in the TimestampAuthority client.
"""

pass


class TimestampAuthorityClient:
"""Internal client to deal with a Timestamp Authority"""

def __init__(self, url: str) -> None:
"""
Create a new `TimestampAuthorityClient` from the given URL.
"""
self.url = url
self.session = requests.Session()
self.session.headers.update(
{
"Content-Type": "application/timestamp-query",
"User-Agent": USER_AGENT,
}
)

def __del__(self) -> None:
"""
Terminates the underlying network session.
"""
self.session.close()

def request_timestamp(self, signature: bytes) -> TimeStampResponse:
"""
Timestamp the signature using the configured Timestamp Authority.
This method generates a RFC3161 Timestamp Request and sends it to a TSA.
The received response is parsed but *not* cryptographically verified.
Raises a TimestampError on failure.
"""
# Build the timestamp request
try:
timestamp_request = (
TimestampRequestBuilder().data(signature).nonce(nonce=True).build()
)
except ValueError as error:
msg = f"invalid request: {error}"
raise TimestampError(msg)

# Send it to the TSA for signing
try:
response = self.session.post(
self.url,
data=timestamp_request.as_bytes(),
timeout=CLIENT_TIMEOUT,
)
response.raise_for_status()
except requests.RequestException as error:
msg = f"error while sending the request to the TSA: {error}"
raise TimestampError(msg)

# Check that we can parse the response but do not *verify* it
try:
timestamp_response = decode_timestamp_response(response.content)
except ValueError as e:
msg = f"invalid response: {e}"
raise TimestampError(msg)

return timestamp_response
12 changes: 12 additions & 0 deletions sigstore/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@
VerificationMaterial as _VerificationMaterial,
)
from sigstore_protobuf_specs.dev.sigstore.common import v1 as common_v1
from sigstore_protobuf_specs.dev.sigstore.common.v1 import Rfc3161SignedTimestamp
from sigstore_protobuf_specs.dev.sigstore.rekor import v1 as rekor_v1
from sigstore_protobuf_specs.dev.sigstore.rekor.v1 import (
InclusionProof,
Expand Down Expand Up @@ -635,6 +636,7 @@ def _from_parts(
cert: Certificate,
content: common_v1.MessageSignature | dsse.Envelope,
log_entry: LogEntry,
signed_timestamp: Optional[List[TimeStampResponse]] = None,
) -> Bundle:
"""
@private
Expand All @@ -656,4 +658,14 @@ def _from_parts(
tlog_entry = log_entry._to_rekor()
inner.verification_material.tlog_entries = [tlog_entry]

if signed_timestamp is not None:
inner.verification_material.timestamp_verification_data = (
bundle_v1.TimestampVerificationData(
rfc3161_timestamps=[
Rfc3161SignedTimestamp(signed_timestamp=response.as_bytes())
for response in signed_timestamp
]
)
)

return cls(inner)
27 changes: 24 additions & 3 deletions sigstore/sign.py
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@
import logging
from contextlib import contextmanager
from datetime import datetime, timezone
from typing import Iterator, Optional
from typing import Iterator, List, Optional

import cryptography.x509 as x509
import rekor_types
Expand All @@ -62,6 +62,7 @@
)
from sigstore._internal.rekor.client import RekorClient
from sigstore._internal.sct import verify_sct
from sigstore._internal.timestamp import TimestampAuthorityClient, TimestampError
from sigstore._internal.trust import ClientTrustConfig, KeyringPurpose, TrustedRoot
from sigstore._utils import sha256_digest
from sigstore.models import Bundle
Expand Down Expand Up @@ -190,7 +191,17 @@ def _finalize_sign(

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

return Bundle._from_parts(cert, content, entry)
# If the user provided TSA urls, timestamps the response
signed_timestamp = []
for tsa_client in self._signing_ctx._tsa_clients:
try:
signed_timestamp.append(tsa_client.request_timestamp(content.signature))
except TimestampError as e:
_logger.warning(
f"Unable to use {tsa_client.url} to timestamp the bundle. Failed with {e}"
)

return Bundle._from_parts(cert, content, entry, signed_timestamp)

def sign_dsse(
self,
Expand Down Expand Up @@ -296,7 +307,12 @@ class SigningContext:
"""

def __init__(
self, *, fulcio: FulcioClient, rekor: RekorClient, trusted_root: TrustedRoot
self,
*,
fulcio: FulcioClient,
rekor: RekorClient,
trusted_root: TrustedRoot,
tsa_clients: List[TimestampAuthorityClient] | None = None,
):
"""
Create a new `SigningContext`.
Expand All @@ -310,6 +326,7 @@ def __init__(
self._fulcio = fulcio
self._rekor = rekor
self._trusted_root = trusted_root
self._tsa_clients = tsa_clients or []

@classmethod
def production(cls) -> SigningContext:
Expand Down Expand Up @@ -344,6 +361,10 @@ def _from_trust_config(cls, trust_config: ClientTrustConfig) -> SigningContext:
fulcio=FulcioClient(trust_config._inner.signing_config.ca_url),
rekor=RekorClient(trust_config._inner.signing_config.tlog_urls[0]),
trusted_root=trust_config.trusted_root,
tsa_clients=[
TimestampAuthorityClient(tsa_url)
for tsa_url in trust_config._inner.signing_config.tsa_urls
],
)

@contextmanager
Expand Down
4 changes: 2 additions & 2 deletions sigstore/verify/verifier.py
Original file line number Diff line number Diff line change
Expand Up @@ -178,11 +178,11 @@ def _verify_timestamp_authority(
bundle.verification_material.timestamp_verification_data.rfc3161_timestamps
)
if len(timestamp_responses) > MAX_ALLOWED_TIMESTAMP:
msg = f"Too many signed timestamp: {len(timestamp_responses)} > {MAX_ALLOWED_TIMESTAMP}"
msg = f"too many signed timestamp: {len(timestamp_responses)} > {MAX_ALLOWED_TIMESTAMP}"
raise VerificationError(msg)

if len(set(timestamp_responses)) != len(timestamp_responses):
msg = "Duplicate timestamp found"
msg = "duplicate timestamp found"
raise VerificationError(msg)

# The Signer sends a hash of the signature as the messageImprint in a TimeStampReq
Expand Down
124 changes: 124 additions & 0 deletions test/assets/tsa/trust_config.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,124 @@
{
"mediaType": "application/vnd.dev.sigstore.clienttrustconfig.v0.1+json",
"trustedRoot": {
"mediaType": "application/vnd.dev.sigstore.trustedroot+json;version=0.1",
"tlogs": [
{
"baseUrl": "https://rekor.sigstage.dev",
"hashAlgorithm": "SHA2_256",
"publicKey": {
"rawBytes": "MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEDODRU688UYGuy54mNUlaEBiQdTE9nYLr0lg6RXowI/QV/RE1azBn4Eg5/2uTOMbhB1/gfcHzijzFi9Tk+g1Prg==",
"keyDetails": "PKIX_ECDSA_P256_SHA_256",
"validFor": {
"start": "2021-01-12T11:53:27.000Z"
}
},
"logId": {
"keyId": "0y8wo8MtY5wrdiIFohx7sHeI5oKDpK5vQhGHI6G+pJY="
}
}
],
"certificateAuthorities": [
{
"subject": {
"organization": "sigstore.dev",
"commonName": "sigstore"
},
"uri": "https://fulcio.sigstage.dev",
"certChain": {
"certificates": [
{
"rawBytes": "MIICGTCCAaCgAwIBAgITJta/okfgHvjabGm1BOzuhrwA1TAKBggqhkjOPQQDAzAqMRUwEwYDVQQKEwxzaWdzdG9yZS5kZXYxETAPBgNVBAMTCHNpZ3N0b3JlMB4XDTIyMDQxNDIxMzg0MFoXDTMyMDMyMjE2NTA0NVowNzEVMBMGA1UEChMMc2lnc3RvcmUuZGV2MR4wHAYDVQQDExVzaWdzdG9yZS1pbnRlcm1lZGlhdGUwdjAQBgcqhkjOPQIBBgUrgQQAIgNiAASosAySWJQ/tK5r8T5aHqavk0oI+BKQbnLLdmOMRXHQF/4Hx9KtNfpcdjH9hNKQSBxSlLFFN3tvFCco0qFBzWYwZtsYsBe1l91qYn/9VHFTaEVwYQWIJEEvrs0fvPuAqjajezB5MA4GA1UdDwEB/wQEAwIBBjATBgNVHSUEDDAKBggrBgEFBQcDAzASBgNVHRMBAf8ECDAGAQH/AgEAMB0GA1UdDgQWBBRxhjCmFHxib/n31vQFGn9f/+tvrDAfBgNVHSMEGDAWgBT/QjK6aH2rOnCv3AzUGuI+h49mZTAKBggqhkjOPQQDAwNnADBkAjAM1lbKkcqQlE/UspMTbWNo1y2TaJ44tx3l/FJFceTSdDZ+0W1OHHeU4twie/lq8XgCMHQxgEv26xNNiAGyPXbkYgrDPvbOqp0UeWX4mJnLSrBr3aN/KX1SBrKQu220FmVL0Q=="
},
{
"rawBytes": "MIIB9jCCAXugAwIBAgITDdEJvluliE0AzYaIE4jTMdnFTzAKBggqhkjOPQQDAzAqMRUwEwYDVQQKEwxzaWdzdG9yZS5kZXYxETAPBgNVBAMTCHNpZ3N0b3JlMB4XDTIyMDMyNTE2NTA0NloXDTMyMDMyMjE2NTA0NVowKjEVMBMGA1UEChMMc2lnc3RvcmUuZGV2MREwDwYDVQQDEwhzaWdzdG9yZTB2MBAGByqGSM49AgEGBSuBBAAiA2IABMo9BUNk9QIYisYysC24+2OytoV72YiLonYcqR3yeVnYziPt7Xv++CYE8yoCTiwedUECCWKOcvQKRCJZb9ht4Hzy+VvBx36hK+C6sECCSR0x6pPSiz+cTk1f788ZjBlUZaNjMGEwDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFP9CMrpofas6cK/cDNQa4j6Hj2ZlMB8GA1UdIwQYMBaAFP9CMrpofas6cK/cDNQa4j6Hj2ZlMAoGCCqGSM49BAMDA2kAMGYCMQD+kojuzMwztNay9Ibzjuk//ZL5m6T2OCsm45l1lY004pcb984L926BowodoirFMcMCMQDIJtFHhP/1D3a+M3dAGomOb6O4CmTry3TTPbPsAFnv22YA0Y+P21NVoxKDjdu0tkw="
}
]
},
"validFor": {
"start": "2022-04-14T21:38:40.000Z"
}
}
],
"timestampAuthorities": [
{
"subject": {
"organization": "local",
"commonName": "Test TSA Timestamping"
},
"certChain": {
"certificates": [
{
"rawBytes": "MIIFRTCCAy2gAwIBAgIUCmn2Vl7XF50OeM7Y1oM/vFAFK3kwDQYJKoZIhvcNAQELBQAwMDEeMBwGA1UEAwwVVGVzdCBUU0EgSW50ZXJtZWRpYXRlMQ4wDAYDVQQKDAVsb2NhbDAeFw0yNDExMDcxNDU5NDBaFw0zMzExMDUxNDU5NDBaMDAxHjAcBgNVBAMMFVRlc3QgVFNBIFRpbWVzdGFtcGluZzEOMAwGA1UECgwFbG9jYWwwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDiSD0m8J8ZGMS/Et2SqooLUCpwiAX9Ay/KOYCMFXr6ujAKOZGPQgASY7kdB1zA+dkHmoOxbF8kASVoFlwYzgnAvH9YpiVT9iVCRgF/sAutbdHYmOtPLpyB15PPiwnxB/PIk1d6e/WOh0Vn2ZX0juVJKb2B59FpzG1CXn9WGT7C1qVpXM+UtdRxxpug/lLBeDle5Uo/ffxGZfy5FsdlXTCFzkiqjf0cEIIxoEHxhOjxGjt2pPDuq7PLV0N0AWIhu7FU29fUePsS6TTk+8OS2Z8XQn8YHmgQMgqJF4fsv0ytTsNv5qPV2NEUi9Em7IemFFnfW5HktazmrqF7Ly/YPVv35X9zgT898YAVgd0+PaUqVgWEWv/hpV6kmXoNTxCcMqixbNQGxVWT9N5EMBZgc9yXesKFpHIb7cF/diloytxBOvnwm9PShBz6/KOfq17WPvOqK1UC4fMmdzppaXDuhOa4GhNoPUeo646oMFafpSoR1HG6Fom71oIxJ8Q63IxAFRdoKyioBlTuPDFXgIk3Ckv3+PVkJIl1imF33tnYut5OF+pMbrlf4I2Op4+n0CDsmRg9BBQBxIXoP2ziRIputnISW7uS55ViTkfO7mZRBIJzz2ZqX9igCkTvA1wMZzLeRbow2tkwRaTHYg4uQTGJuWMAkJRz27FjswVu1dIC27g7uQIDAQABo1cwVTAMBgNVHRMBAf8EAjAAMA4GA1UdDwEB/wQEAwIHgDAWBgNVHSUBAf8EDDAKBggrBgEFBQcDCDAdBgNVHQ4EFgQU6LppB2yaoGV18BzPLiq5NGHTecwwDQYJKoZIhvcNAQELBQADggIBAOAZhkQF9aC5oUA2cXtBRoYoXnPILrbdIvVQvfe3IOUAhF5QvjrVwtBffR8ZxrSSn/8t0rtXy6BZQas95YD0ObspemMocKSsPYo01qnuCX5757LSvTpYPERVt6TpKVV39Y59xlmuUjlyQH0Ufrsh8Qs8ejPQwDUWmDwetBnrZfDV36AgCAjlS3QSQQt+iYb6x13jYGZ9Wj/HUqSaUlJqqtuzbbIMZy8FSHLjle5m2Np2Wubwn3a3z+xTYVN+gWDFWtEamDprRxQ6oswXmINv8cZd79cMZbFS7j2Crnni58uVLxMQAcSNBEnQTChTdD6JzUjHiSzpaSTn/txfP9M/rMTSDokqPgfhpWcB93sw0X5Inv2nsqMN6U8b28F0+ciBP7dKVPTM8ypfVpAJ0OtGijkGda6cfYbcXCTTMZFAnMPenfVMN9TtljZ/lOdaNLuaRVKcOJvrHLqv4Mau+9TPkd8Xn5YWVCxtYr/xhKdaHfQ2KGr987CP6hKoIAPPIebQWjd1jrrlm1ESebcm1pGTWiNyGhKUUaFsKt96xmtGa3ov3OfcygSDGdPAIy5LlWyfdEX9rwoqTi+s6EELabj2C6ICCUYwqr6quaQrvhdJ84Oqs5Tn3hkcrroJtLPQBtYNGjHZtJLyXZ/wEAUciWTSyLinVABhBdXzTlUnwO9wkxdx"
},
{
"rawBytes": "MIIFPTCCAyWgAwIBAgIUEP4pDZweTUQeXvhyu1e4kJaJ9FAwDQYJKoZIhvcNAQELBQAwKDEWMBQGA1UEAwwNVGVzdCBUU0EgUm9vdDEOMAwGA1UECgwFbG9jYWwwHhcNMjQxMTA3MTQ1ODU2WhcNMzQxMTA1MTQ1ODU2WjAwMR4wHAYDVQQDDBVUZXN0IFRTQSBJbnRlcm1lZGlhdGUxDjAMBgNVBAoMBWxvY2FsMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEA4kg9JvCfGRjEvxLdkqqKC1AqcIgF/QMvyjmAjBV6+rowCjmRj0IAEmO5HQdcwPnZB5qDsWxfJAElaBZcGM4JwLx/WKYlU/YlQkYBf7ALrW3R2JjrTy6cgdeTz4sJ8QfzyJNXenv1jodFZ9mV9I7lSSm9gefRacxtQl5/Vhk+wtalaVzPlLXUccaboP5SwXg5XuVKP338RmX8uRbHZV0whc5Iqo39HBCCMaBB8YTo8Ro7dqTw7quzy1dDdAFiIbuxVNvX1Hj7Euk05PvDktmfF0J/GB5oEDIKiReH7L9MrU7Db+aj1djRFIvRJuyHphRZ31uR5LWs5q6hey8v2D1b9+V/c4E/PfGAFYHdPj2lKlYFhFr/4aVepJl6DU8QnDKosWzUBsVVk/TeRDAWYHPcl3rChaRyG+3Bf3YpaMrcQTr58JvT0oQc+vyjn6te1j7zqitVAuHzJnc6aWlw7oTmuBoTaD1HqOuOqDBWn6UqEdRxuhaJu9aCMSfEOtyMQBUXaCsoqAZU7jwxV4CJNwpL9/j1ZCSJdYphd97Z2LreThfqTG65X+CNjqePp9Ag7JkYPQQUAcSF6D9s4kSKbrZyElu7kueVYk5Hzu5mUQSCc89mal/YoApE7wNcDGcy3kW6MNrZMEWkx2IOLkExibljAJCUc9uxY7MFbtXSAtu4O7kCAwEAAaNXMFUwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwEwYDVR0lBAwwCgYIKwYBBQUHAwgwHQYDVR0OBBYEFOi6aQdsmqBldfAczy4quTRh03nMMA0GCSqGSIb3DQEBCwUAA4ICAQC+6pAcMuxSx32C69fxLYyUYvj6A66DsXuNnzY/CqgHzyD+vUF7oS1tfoU81BcjY9+cSQkCO6teBbsrjKpFmnpWf5grHWaW/qFf4+tg1i8oPnJ9XDPn9U12M9mYk/xK0GM7xXK+1dMfkrI50RUtIhfIe7N+OzBVtOtJIUoItSapZeXDvTtScf50XdS73kBlr7VFIrKlfAm3C+G+wL8MiMg1254srhtfvzP6RVPy/uUZRh+F8NWVMcAl3IrSsBkDdDHFbJcD+tHmN9NQ9I4/51PcStXFPpl0k6EvadQMZ6Ep6HHfsJUdfRIHWxP9BYwXURO7bmmlai9M+Do9LHY0lb8s9fGXkgi0p9aKgFZb0uLfqsrlQjFqpZOv3GFmcwXfc5IOC//1dJO6kL37nTiv4yHEzSzgbq6xyYEy6gJSo+Zgnd10f1y8fCXhzHFNNBNQHC6jvT63mo/RlH27zJHCHEvx39B9GwYRNEdS2MDSVuJ5RcVgA9E44LXxq++r9y5LvviC+aV5H9WgJOlJU0+ZSPJTSfAdY/MMqvIB+kelFCk32qQzAH9e2Nb4AF63aDEv6iIT39+A82ZWVZwTrAy0cPPNIfKuiUtQQ0m/yyuMVRme0ZesZYtTCx2879DzmIrYhng53xN34SPfos/cm0JqIwViJUqB5/cVNosj53uflgOJ7g=="
},
{
"rawBytes": "MIIFQTCCAymgAwIBAgIUOcx13OBKeYy2jy6faZcez0+NmQYwDQYJKoZIhvcNAQELBQAwKDEWMBQGA1UEAwwNVGVzdCBUU0EgUm9vdDEOMAwGA1UECgwFbG9jYWwwHhcNMjQxMTA3MTQ1ODQyWhcNMzQxMTA1MTQ1ODQyWjAoMRYwFAYDVQQDDA1UZXN0IFRTQSBSb290MQ4wDAYDVQQKDAVsb2NhbDCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAOJIPSbwnxkYxL8S3ZKqigtQKnCIBf0DL8o5gIwVevq6MAo5kY9CABJjuR0HXMD52Qeag7FsXyQBJWgWXBjOCcC8f1imJVP2JUJGAX+wC61t0diY608unIHXk8+LCfEH88iTV3p79Y6HRWfZlfSO5UkpvYHn0WnMbUJef1YZPsLWpWlcz5S11HHGm6D+UsF4OV7lSj99/EZl/LkWx2VdMIXOSKqN/RwQgjGgQfGE6PEaO3ak8O6rs8tXQ3QBYiG7sVTb19R4+xLpNOT7w5LZnxdCfxgeaBAyCokXh+y/TK1Ow2/mo9XY0RSL0Sbsh6YUWd9bkeS1rOauoXsvL9g9W/flf3OBPz3xgBWB3T49pSpWBYRa/+GlXqSZeg1PEJwyqLFs1AbFVZP03kQwFmBz3Jd6woWkchvtwX92KWjK3EE6+fCb09KEHPr8o5+rXtY+86orVQLh8yZ3OmlpcO6E5rgaE2g9R6jrjqgwVp+lKhHUcboWibvWgjEnxDrcjEAVF2grKKgGVO48MVeAiTcKS/f49WQkiXWKYXfe2di63k4X6kxuuV/gjY6nj6fQIOyZGD0EFAHEheg/bOJEim62chJbu5LnlWJOR87uZlEEgnPPZmpf2KAKRO8DXAxnMt5FujDa2TBFpMdiDi5BMYm5YwCQlHPbsWOzBW7V0gLbuDu5AgMBAAGjYzBhMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBToumkHbJqgZXXwHM8uKrk0YdN5zDAfBgNVHSMEGDAWgBToumkHbJqgZXXwHM8uKrk0YdN5zDANBgkqhkiG9w0BAQsFAAOCAgEARUUincNj6OEbvE0shsaKo4ZeffEgnSzTlSBdYASQeCs130lyXsQVwZkyL4IrPsICE9lYN57QvXEPXYi0d+kQvVdBSm4vmoWSZdxe6GEj5CJ3k4hb/uyEgcrvgUSO+33v3L/sRYfIax/8y+1oxSgFcmSml6hMmHlH0q9/Yjfsv6ys5iifipQrXOD9yBcvLIKHMovrVD+BCjirz1a1g5CneTePhLDNzk0Kbvqc+sNWEDlzQzmHjeKHgDTrJj1OcFpUfsZOrFMscXCGVVA/eB5YOrFbTvtKdzy7d9UN+/PUCqZt1dcYzlk75ww2bFgRXt1GhzUqRolblTRWeLmwIkjDpyRaA1C5MXhWie7XT7G52SoGSPzjSSvo7hPqO8eW1fHK/qv4LTxX1o2yVyKpsoeV/SSybbzwq7ZeGDBeMrfCXktQLFqDwqnGMjlJsx0MkKVaDOR9Y4dz6P9YlGo7qDamw6wwbNvsJRTNkeNQyfZPyBBDW/I+gK95EisTu2zblfT6ie64ckeIjvv7UxtRQFxEMWNoeMT5E3SZNOMH4zSbQGQhCtXg1s4ssS2w2AYJ8CRJiOGfe1Pa30zQVbOACXEYO0z9R1ED5xSRck93GIss2BVUL92+sdnk6JxJLKQH8icN3jX3dsM0i+dm1TxTW1flVZGGpR0xLbgRuNnQI4YCLOg="
}
]
},
"validFor": {
"start": "2024-11-07T14:59:40.000Z",
"end": "2033-11-05T14:59:40.000Z"
}
}
],
"ctlogs": [
{
"baseUrl": "https://ctfe.sigstage.dev/test",
"hashAlgorithm": "SHA2_256",
"publicKey": {
"rawBytes": "MIICCgKCAgEA27A2MPQXm0I0v7/Ly5BIauDjRZF5Jor9vU+QheoE2UIIsZHcyYq3slHzSSHy2lLj1ZD2d91CtJ492ZXqnBmsr4TwZ9jQ05tW2mGIRI8u2DqN8LpuNYZGz/f9SZrjhQQmUttqWmtu3UoLfKz6NbNXUnoo+NhZFcFRLXJ8VporVhuiAmL7zqT53cXR3yQfFPCUDeGnRksnlhVIAJc3AHZZSHQJ8DEXMhh35TVv2nYhTI3rID7GwjXXw4ocz7RGDD37ky6p39Tl5NB71gT1eSqhZhGHEYHIPXraEBd5+3w9qIuLWlp5Ej/K6Mu4ELioXKCUimCbwy+Cs8UhHFlqcyg4AysOHJwIadXIa8LsY51jnVSGrGOEBZevopmQPNPtyfFY3dmXSS+6Z3RD2Gd6oDnNGJzpSyEk410Ag5uvNDfYzJLCWX9tU8lIxNwdFYmIwpd89HijyRyoGnoJ3entd63cvKfuuix5r+GHyKp1Xm1L5j5AWM6P+z0xigwkiXnt+adexAl1J9wdDxv/pUFEESRF4DG8DFGVtbdH6aR1A5/vD4krO4tC1QYUSeyL5Mvsw8WRqIFHcXtgybtxylljvNcGMV1KXQC8UFDmpGZVDSHx6v3e/BHMrZ7gjoCCfVMZ/cFcQi0W2AIHPYEMH/C95J2r4XbHMRdYXpovpOoT5Ca78gsCAwEAAQ==",
"keyDetails": "PKCS1_RSA_PKCS1V5",
"validFor": {
"start": "2021-03-14T00:00:00.000Z",
"end": "2022-07-31T00:00:00.000Z"
}
},
"logId": {
"keyId": "G3wUKk6ZK6ffHh/FdCRUE2wVekyzHEEIpSG4savnv0w="
}
},
{
"baseUrl": "https://ctfe.sigstage.dev/2022",
"hashAlgorithm": "SHA2_256",
"publicKey": {
"rawBytes": "MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEh99xuRi6slBFd8VUJoK/rLigy4bYeSYWO/fE6Br7r0D8NpMI94+A63LR/WvLxpUUGBpY8IJA3iU2telag5CRpA==",
"keyDetails": "PKIX_ECDSA_P256_SHA_256",
"validFor": {
"start": "2022-07-01T00:00:00.000Z",
"end": "2022-07-31T00:00:00.000Z"
}
},
"logId": {
"keyId": "++JKOMQt7SJ3ynUHnCfnDhcKP8/58J4TueMqXuk3HmA="
}
},
{
"baseUrl": "https://ctfe.sigstage.dev/2022-2",
"hashAlgorithm": "SHA2_256",
"publicKey": {
"rawBytes": "MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE8gEDKNme8AnXuPBgHjrtXdS6miHqc24CRblNEOFpiJRngeq8Ko73Y+K18yRYVf1DXD4AVLwvKyzdNdl5n0jUSQ==",
"keyDetails": "PKIX_ECDSA_P256_SHA_256",
"validFor": {
"start": "2022-07-01T00:00:00.000Z"
}
},
"logId": {
"keyId": "KzC83GiIyeLh2CYpXnQfSDkxlgLynDPLXkNA/rKshno="
}
}
]
},
"signing_config": {
"ca_url": "https://fulcio.sigstage.dev",
"tlog_urls": [
"https://rekor.sigstage.dev"
],
"tsa_urls": [
"placeholder-value"
]
}
}
Loading

0 comments on commit 383797a

Please sign in to comment.