70 lines
3.6 KiB
SQL
70 lines
3.6 KiB
SQL
-- -----------------------------------------------------------------------------
|
|
-- 005_timestamp_evidence.sql
|
|
-- Sprint: SPRINT_20260119_009 Evidence Storage for Timestamps
|
|
-- Task: EVT-002 - PostgreSQL Schema Extension
|
|
-- Description: Schema for storing timestamp and revocation evidence.
|
|
-- -----------------------------------------------------------------------------
|
|
|
|
-- Ensure the evidence schema exists
|
|
CREATE SCHEMA IF NOT EXISTS evidence;
|
|
|
|
-- Timestamp evidence storage
|
|
CREATE TABLE IF NOT EXISTS evidence.timestamp_tokens (
|
|
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
artifact_digest TEXT NOT NULL,
|
|
digest_algorithm TEXT NOT NULL,
|
|
tst_blob BYTEA NOT NULL,
|
|
generation_time TIMESTAMPTZ NOT NULL,
|
|
tsa_name TEXT NOT NULL,
|
|
tsa_policy_oid TEXT NOT NULL,
|
|
serial_number TEXT NOT NULL,
|
|
tsa_chain_pem TEXT NOT NULL,
|
|
ocsp_response BYTEA,
|
|
crl_snapshot BYTEA,
|
|
captured_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
|
provider_name TEXT NOT NULL,
|
|
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
|
CONSTRAINT uq_timestamp_artifact_time UNIQUE (artifact_digest, generation_time)
|
|
);
|
|
|
|
-- Indexes for timestamp queries
|
|
CREATE INDEX IF NOT EXISTS idx_timestamp_artifact ON evidence.timestamp_tokens(artifact_digest);
|
|
CREATE INDEX IF NOT EXISTS idx_timestamp_generation ON evidence.timestamp_tokens(generation_time);
|
|
CREATE INDEX IF NOT EXISTS idx_timestamp_provider ON evidence.timestamp_tokens(provider_name);
|
|
CREATE INDEX IF NOT EXISTS idx_timestamp_created ON evidence.timestamp_tokens(created_at);
|
|
|
|
-- Revocation evidence storage
|
|
CREATE TABLE IF NOT EXISTS evidence.revocation_snapshots (
|
|
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
certificate_fingerprint TEXT NOT NULL,
|
|
source TEXT NOT NULL CHECK (source IN ('Ocsp', 'Crl', 'None')),
|
|
raw_response BYTEA NOT NULL,
|
|
response_time TIMESTAMPTZ NOT NULL,
|
|
valid_until TIMESTAMPTZ NOT NULL,
|
|
status TEXT NOT NULL CHECK (status IN ('Good', 'Revoked', 'Unknown')),
|
|
revocation_time TIMESTAMPTZ,
|
|
reason TEXT,
|
|
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
|
|
);
|
|
|
|
-- Indexes for revocation queries
|
|
CREATE INDEX IF NOT EXISTS idx_revocation_cert ON evidence.revocation_snapshots(certificate_fingerprint);
|
|
CREATE INDEX IF NOT EXISTS idx_revocation_valid ON evidence.revocation_snapshots(valid_until);
|
|
CREATE INDEX IF NOT EXISTS idx_revocation_status ON evidence.revocation_snapshots(status);
|
|
CREATE INDEX IF NOT EXISTS idx_revocation_created ON evidence.revocation_snapshots(created_at);
|
|
|
|
-- Comments
|
|
COMMENT ON TABLE evidence.timestamp_tokens IS 'RFC-3161 TimeStampToken evidence for long-term validation';
|
|
COMMENT ON TABLE evidence.revocation_snapshots IS 'OCSP/CRL certificate revocation evidence snapshots';
|
|
|
|
COMMENT ON COLUMN evidence.timestamp_tokens.artifact_digest IS 'SHA-256 digest of the timestamped artifact';
|
|
COMMENT ON COLUMN evidence.timestamp_tokens.tst_blob IS 'Raw DER-encoded RFC 3161 TimeStampToken';
|
|
COMMENT ON COLUMN evidence.timestamp_tokens.tsa_chain_pem IS 'PEM-encoded TSA certificate chain for LTV';
|
|
COMMENT ON COLUMN evidence.timestamp_tokens.ocsp_response IS 'Stapled OCSP response at signing time';
|
|
COMMENT ON COLUMN evidence.timestamp_tokens.crl_snapshot IS 'CRL snapshot at signing time (fallback for OCSP)';
|
|
|
|
COMMENT ON COLUMN evidence.revocation_snapshots.certificate_fingerprint IS 'SHA-256 fingerprint of the certificate';
|
|
COMMENT ON COLUMN evidence.revocation_snapshots.raw_response IS 'Raw OCSP response or CRL bytes';
|
|
COMMENT ON COLUMN evidence.revocation_snapshots.response_time IS 'thisUpdate from the response';
|
|
COMMENT ON COLUMN evidence.revocation_snapshots.valid_until IS 'nextUpdate from the response';
|