tests fixes and some product advisories tunes ups

This commit is contained in:
master
2026-01-30 07:57:43 +02:00
parent 644887997c
commit 55744f6a39
345 changed files with 26290 additions and 2267 deletions

View File

@@ -0,0 +1,11 @@
# Binary Micro-Witness Golden Demo - SHA-256 Checksums
# Generated: 2026-01-28
# Sprint: SPRINT_0128_001_BinaryIndex_binary_micro_witness
#
# Verify with: sha256sum -c CHECKSUMS.sha256
526283cf498cded25032a2fd1bbf2896ede05e32545bec1ccd38b787ba6ef0d1 *witnesses/libcurl-cve-2023-38545.json
87d7b026b37523abd29d917c22b9ffa0c3e7a3ddcf8db8990eb4d6b9cb35ed91 *witnesses/openssl-cve-2024-0567.json
59ab7b9c5bc01af9f81af8801c90c7123f5d4c503e8bad1be3a3a71c847eebbf *verify.ps1
5e7140744f6421cf6cbf8d707706d8b0fbe7bbb6c43604be38ec088cd19e21a0 *verify.sh
b5538232fdc8936f6a4529254b29d70014f76830c84aa4d977db3c1152c6e5b0 *README.md

View File

@@ -0,0 +1,114 @@
# Binary Micro-Witness Golden Demo
This bundle demonstrates binary-level patch verification using StellaOps micro-witnesses.
## Overview
Binary micro-witnesses provide cryptographic proof that a specific binary contains (or doesn't contain) a security fix. This enables auditors and procurement teams to verify patch status without source code access.
## Contents
```
binary-micro-witness/
├── README.md # This file
├── witnesses/
│ ├── openssl-cve-2024-0567.json # Sample witness for OpenSSL CVE
│ └── libcurl-cve-2023-38545.json # Sample witness for curl CVE
├── verify.ps1 # PowerShell verification script
├── verify.sh # Bash verification script
└── CHECKSUMS.sha256 # Deterministic checksums for all files
```
## Quick Start
### Windows (PowerShell)
```powershell
.\verify.ps1 -WitnessPath witnesses\openssl-cve-2024-0567.json
```
### Linux/macOS (Bash)
```bash
chmod +x verify.sh
./verify.sh witnesses/openssl-cve-2024-0567.json
```
## Threat Model & Scope
### What Micro-Witnesses Prove
- A specific binary (identified by SHA-256) was analyzed
- The analysis compared function-level signatures against known vulnerable/patched versions
- A confidence score indicates how certain the verdict is
### What Micro-Witnesses Do NOT Prove
- That the binary came from a trusted source (that's what SBOM + attestations are for)
- That the analysis is 100% accurate (confidence scores indicate uncertainty)
- That other vulnerabilities don't exist (only the specified CVE is verified)
### Limitations
- Function-level matching can be affected by heavy compiler optimizations
- Inlined functions may not be detected
- Obfuscated binaries may yield "inconclusive" verdicts
## Offline Verification
This bundle is designed for air-gapped environments:
1. No network access required
2. All verification logic is self-contained
3. Checksums allow integrity verification
## Predicate Schema
Witnesses follow the `https://stellaops.dev/predicates/binary-micro-witness@v1` schema:
```json
{
"schemaVersion": "1.0.0",
"binary": {
"digest": "sha256:...",
"filename": "libssl.so.3",
"arch": "linux-amd64"
},
"cve": {
"id": "CVE-2024-0567",
"advisory": "https://..."
},
"verdict": "patched|vulnerable|inconclusive",
"confidence": 0.95,
"evidence": [
{
"function": "SSL_CTX_new",
"state": "patched",
"score": 0.97,
"method": "semantic_ksg"
}
],
"tooling": {
"binaryIndexVersion": "2.1.0",
"lifter": "b2r2",
"matchAlgorithm": "semantic_ksg"
},
"computedAt": "2026-01-28T12:00:00Z"
}
```
## Reproduction
To regenerate witnesses using the StellaOps CLI:
```bash
# Generate a witness
stella witness generate /path/to/libssl.so.3 --cve CVE-2024-0567 --output witness.json
# Verify a witness
stella witness verify witness.json --offline
# Create an air-gapped bundle
stella witness bundle witness.json --output ./bundle
```
## Version Information
- **Demo Version**: 1.0.0
- **Schema Version**: binary-micro-witness@v1
- **Generated**: 2026-01-28
- **Sprint**: SPRINT_0128_001_BinaryIndex_binary_micro_witness

View File

@@ -0,0 +1,204 @@
# Binary Micro-Witness Verification Script
# Sprint: SPRINT_0128_001_BinaryIndex_binary_micro_witness
# Usage: .\verify.ps1 [-WitnessPath <path>] [-VerboseOutput]
[CmdletBinding()]
param(
[Parameter(Position=0)]
[string]$WitnessPath,
[switch]$All,
[switch]$VerboseOutput
)
$ErrorActionPreference = "Stop"
$Script:PassCount = 0
$Script:FailCount = 0
function Write-Status {
param([string]$Status, [string]$Message, [string]$Color = "White")
$symbol = switch ($Status) {
"PASS" { "[OK]"; $Color = "Green" }
"FAIL" { "[FAIL]"; $Color = "Red" }
"SKIP" { "[SKIP]"; $Color = "Yellow" }
"INFO" { "[INFO]"; $Color = "Cyan" }
default { "[-]" }
}
Write-Host "$symbol " -ForegroundColor $Color -NoNewline
Write-Host $Message
}
function Verify-Witness {
param([string]$Path)
Write-Host "`n=== Verifying: $Path ===" -ForegroundColor Cyan
if (-not (Test-Path $Path)) {
Write-Status "FAIL" "Witness file not found: $Path"
$Script:FailCount++
return
}
try {
$witness = Get-Content $Path -Raw | ConvertFrom-Json
} catch {
Write-Status "FAIL" "Failed to parse witness JSON: $_"
$Script:FailCount++
return
}
# Handle both standalone predicate and in-toto statement formats
$predicate = if ($witness.predicate) { $witness.predicate } else { $witness }
# Verify required fields
$requiredFields = @("schemaVersion", "binary", "cve", "verdict", "confidence", "tooling", "computedAt")
$missingFields = @()
foreach ($field in $requiredFields) {
if (-not $predicate.$field) {
$missingFields += $field
}
}
if ($missingFields.Count -gt 0) {
Write-Status "FAIL" "Missing required fields: $($missingFields -join ', ')"
$Script:FailCount++
return
}
Write-Status "PASS" "All required fields present"
# Display witness details
Write-Host "`nWitness Details:" -ForegroundColor White
Write-Host " Binary Digest: $($predicate.binary.digest)"
Write-Host " Binary File: $($predicate.binary.filename)"
Write-Host " CVE: $($predicate.cve.id)"
Write-Host " Verdict: $($predicate.verdict)"
Write-Host " Confidence: $([math]::Round($predicate.confidence * 100, 1))%"
Write-Host " Computed At: $($predicate.computedAt)"
# Verify schema version
if ($predicate.schemaVersion -eq "1.0.0") {
Write-Status "PASS" "Schema version: $($predicate.schemaVersion)"
} else {
Write-Status "SKIP" "Unknown schema version: $($predicate.schemaVersion)"
}
# Verify binary digest format
if ($predicate.binary.digest -match "^sha256:[a-fA-F0-9]{64}$") {
Write-Status "PASS" "Binary digest format valid"
} else {
Write-Status "FAIL" "Invalid binary digest format"
$Script:FailCount++
return
}
# Verify CVE ID format
if ($predicate.cve.id -match "^CVE-\d{4}-\d{4,}$") {
Write-Status "PASS" "CVE ID format valid"
} else {
Write-Status "SKIP" "Non-standard vulnerability ID: $($predicate.cve.id)"
}
# Verify verdict
$validVerdicts = @("patched", "vulnerable", "inconclusive", "partial")
if ($predicate.verdict -in $validVerdicts) {
$verdictColor = switch ($predicate.verdict) {
"patched" { "Green" }
"vulnerable" { "Red" }
"inconclusive" { "Yellow" }
"partial" { "Yellow" }
}
Write-Status "PASS" "Verdict: $($predicate.verdict)" -Color $verdictColor
} else {
Write-Status "FAIL" "Invalid verdict: $($predicate.verdict)"
$Script:FailCount++
return
}
# Verify confidence range
if ($predicate.confidence -ge 0 -and $predicate.confidence -le 1) {
Write-Status "PASS" "Confidence in valid range"
} else {
Write-Status "FAIL" "Confidence out of range: $($predicate.confidence)"
$Script:FailCount++
return
}
# Check evidence
if ($predicate.evidence -and $predicate.evidence.Count -gt 0) {
Write-Status "PASS" "Evidence present: $($predicate.evidence.Count) function(s)"
if ($VerboseOutput) {
Write-Host "`nFunction Evidence:" -ForegroundColor White
foreach ($ev in $predicate.evidence) {
$stateColor = switch ($ev.state) {
"patched" { "Green" }
"vulnerable" { "Red" }
"modified" { "Yellow" }
"unchanged" { "Gray" }
default { "White" }
}
Write-Host " - $($ev.function): " -NoNewline
Write-Host "$($ev.state)" -ForegroundColor $stateColor -NoNewline
Write-Host " (score: $([math]::Round($ev.score * 100, 1))%, method: $($ev.method))"
}
}
} else {
Write-Status "SKIP" "No function-level evidence provided"
}
# Check tooling
Write-Status "INFO" "Tooling: BinaryIndex $($predicate.tooling.binaryIndexVersion), Lifter: $($predicate.tooling.lifter)"
# TODO: Signature verification (not yet implemented)
Write-Status "SKIP" "Signature verification (not yet implemented)"
# TODO: Rekor proof verification (not yet implemented)
Write-Status "SKIP" "Rekor inclusion proof (not yet implemented)"
$Script:PassCount++
Write-Host "`nResult: " -NoNewline
Write-Host "VERIFIED" -ForegroundColor Green
}
# Main
Write-Host "Binary Micro-Witness Verification" -ForegroundColor Cyan
Write-Host "==================================" -ForegroundColor Cyan
Write-Host "Sprint: SPRINT_0128_001_BinaryIndex_binary_micro_witness"
Write-Host ""
if ($All) {
$witnessDir = Join-Path $PSScriptRoot "witnesses"
$witnesses = Get-ChildItem -Path $witnessDir -Filter "*.json" -ErrorAction SilentlyContinue
if ($witnesses.Count -eq 0) {
Write-Host "No witness files found in $witnessDir" -ForegroundColor Yellow
exit 1
}
foreach ($w in $witnesses) {
Verify-Witness -Path $w.FullName
}
} elseif ($WitnessPath) {
Verify-Witness -Path $WitnessPath
} else {
# Default: verify all witnesses
$witnessDir = Join-Path $PSScriptRoot "witnesses"
$witnesses = Get-ChildItem -Path $witnessDir -Filter "*.json" -ErrorAction SilentlyContinue
if ($witnesses.Count -eq 0) {
Write-Host "Usage: .\verify.ps1 [-WitnessPath <path>] [-All] [-Verbose]" -ForegroundColor Yellow
Write-Host ""
Write-Host "Examples:"
Write-Host " .\verify.ps1 witnesses\openssl-cve-2024-0567.json"
Write-Host " .\verify.ps1 -All -Verbose"
exit 1
}
foreach ($w in $witnesses) {
Verify-Witness -Path $w.FullName
}
}
Write-Host "`n==================================" -ForegroundColor Cyan
Write-Host "Summary: $Script:PassCount passed, $Script:FailCount failed" -ForegroundColor $(if ($Script:FailCount -eq 0) { "Green" } else { "Red" })
exit $Script:FailCount

View File

@@ -0,0 +1,238 @@
#!/bin/bash
# Binary Micro-Witness Verification Script
# Sprint: SPRINT_0128_001_BinaryIndex_binary_micro_witness
# Usage: ./verify.sh [witness-path] [-a|--all] [-v|--verbose]
set -e
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
WITNESS_DIR="$SCRIPT_DIR/witnesses"
PASS_COUNT=0
FAIL_COUNT=0
VERBOSE=false
# Colors
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
CYAN='\033[0;36m'
NC='\033[0m' # No Color
print_status() {
local status="$1"
local message="$2"
case "$status" in
PASS) echo -e "${GREEN}[OK]${NC} $message" ;;
FAIL) echo -e "${RED}[FAIL]${NC} $message" ;;
SKIP) echo -e "${YELLOW}[SKIP]${NC} $message" ;;
INFO) echo -e "${CYAN}[INFO]${NC} $message" ;;
*) echo "[-] $message" ;;
esac
}
verify_witness() {
local witness_path="$1"
echo ""
echo -e "${CYAN}=== Verifying: $witness_path ===${NC}"
if [ ! -f "$witness_path" ]; then
print_status "FAIL" "Witness file not found: $witness_path"
((FAIL_COUNT++))
return
fi
# Check if jq is available
if ! command -v jq &> /dev/null; then
echo -e "${YELLOW}Warning: jq not installed. Basic verification only.${NC}"
echo "Install jq for full verification: apt install jq / brew install jq"
# Basic JSON validity check
if python3 -c "import json; json.load(open('$witness_path'))" 2>/dev/null || \
python -c "import json; json.load(open('$witness_path'))" 2>/dev/null; then
print_status "PASS" "Valid JSON"
else
print_status "FAIL" "Invalid JSON"
((FAIL_COUNT++))
return
fi
((PASS_COUNT++))
return
fi
# Parse with jq - handle both standalone predicate and in-toto statement
local predicate
if jq -e '.predicate' "$witness_path" > /dev/null 2>&1; then
predicate=$(jq '.predicate' "$witness_path")
else
predicate=$(jq '.' "$witness_path")
fi
# Extract fields
local schema_version=$(echo "$predicate" | jq -r '.schemaVersion // empty')
local binary_digest=$(echo "$predicate" | jq -r '.binary.digest // empty')
local binary_filename=$(echo "$predicate" | jq -r '.binary.filename // empty')
local cve_id=$(echo "$predicate" | jq -r '.cve.id // empty')
local verdict=$(echo "$predicate" | jq -r '.verdict // empty')
local confidence=$(echo "$predicate" | jq -r '.confidence // empty')
local computed_at=$(echo "$predicate" | jq -r '.computedAt // empty')
local evidence_count=$(echo "$predicate" | jq -r '.evidence | length // 0')
local binary_index_version=$(echo "$predicate" | jq -r '.tooling.binaryIndexVersion // empty')
local lifter=$(echo "$predicate" | jq -r '.tooling.lifter // empty')
# Verify required fields
local missing_fields=""
[ -z "$schema_version" ] && missing_fields="$missing_fields schemaVersion"
[ -z "$binary_digest" ] && missing_fields="$missing_fields binary.digest"
[ -z "$cve_id" ] && missing_fields="$missing_fields cve.id"
[ -z "$verdict" ] && missing_fields="$missing_fields verdict"
[ -z "$confidence" ] && missing_fields="$missing_fields confidence"
[ -z "$computed_at" ] && missing_fields="$missing_fields computedAt"
if [ -n "$missing_fields" ]; then
print_status "FAIL" "Missing required fields:$missing_fields"
((FAIL_COUNT++))
return
fi
print_status "PASS" "All required fields present"
# Display witness details
echo ""
echo "Witness Details:"
echo " Binary Digest: $binary_digest"
echo " Binary File: $binary_filename"
echo " CVE: $cve_id"
echo " Verdict: $verdict"
echo " Confidence: $(echo "$confidence * 100" | bc)%"
echo " Computed At: $computed_at"
# Verify schema version
if [ "$schema_version" = "1.0.0" ]; then
print_status "PASS" "Schema version: $schema_version"
else
print_status "SKIP" "Unknown schema version: $schema_version"
fi
# Verify binary digest format
if [[ "$binary_digest" =~ ^sha256:[a-fA-F0-9]{64}$ ]]; then
print_status "PASS" "Binary digest format valid"
else
print_status "FAIL" "Invalid binary digest format"
((FAIL_COUNT++))
return
fi
# Verify CVE ID format
if [[ "$cve_id" =~ ^CVE-[0-9]{4}-[0-9]{4,}$ ]]; then
print_status "PASS" "CVE ID format valid"
else
print_status "SKIP" "Non-standard vulnerability ID: $cve_id"
fi
# Verify verdict
case "$verdict" in
patched|vulnerable|inconclusive|partial)
print_status "PASS" "Verdict: $verdict"
;;
*)
print_status "FAIL" "Invalid verdict: $verdict"
((FAIL_COUNT++))
return
;;
esac
# Verify confidence range
if (( $(echo "$confidence >= 0 && $confidence <= 1" | bc -l) )); then
print_status "PASS" "Confidence in valid range"
else
print_status "FAIL" "Confidence out of range: $confidence"
((FAIL_COUNT++))
return
fi
# Check evidence
if [ "$evidence_count" -gt 0 ]; then
print_status "PASS" "Evidence present: $evidence_count function(s)"
if [ "$VERBOSE" = true ]; then
echo ""
echo "Function Evidence:"
echo "$predicate" | jq -r '.evidence[] | " - \(.function): \(.state) (score: \(.score * 100 | floor)%, method: \(.method))"'
fi
else
print_status "SKIP" "No function-level evidence provided"
fi
# Check tooling
print_status "INFO" "Tooling: BinaryIndex $binary_index_version, Lifter: $lifter"
# TODO: Signature verification
print_status "SKIP" "Signature verification (not yet implemented)"
# TODO: Rekor proof verification
print_status "SKIP" "Rekor inclusion proof (not yet implemented)"
((PASS_COUNT++))
echo ""
echo -e "Result: ${GREEN}VERIFIED${NC}"
}
# Parse arguments
WITNESS_PATH=""
VERIFY_ALL=false
while [[ $# -gt 0 ]]; do
case $1 in
-a|--all)
VERIFY_ALL=true
shift
;;
-v|--verbose)
VERBOSE=true
shift
;;
-h|--help)
echo "Usage: $0 [witness-path] [-a|--all] [-v|--verbose]"
echo ""
echo "Examples:"
echo " $0 witnesses/openssl-cve-2024-0567.json"
echo " $0 --all --verbose"
exit 0
;;
*)
WITNESS_PATH="$1"
shift
;;
esac
done
# Main
echo -e "${CYAN}Binary Micro-Witness Verification${NC}"
echo -e "${CYAN}==================================${NC}"
echo "Sprint: SPRINT_0128_001_BinaryIndex_binary_micro_witness"
if [ -n "$WITNESS_PATH" ]; then
verify_witness "$WITNESS_PATH"
elif [ "$VERIFY_ALL" = true ] || [ -d "$WITNESS_DIR" ]; then
for witness in "$WITNESS_DIR"/*.json; do
[ -f "$witness" ] && verify_witness "$witness"
done
else
echo "Usage: $0 [witness-path] [-a|--all] [-v|--verbose]"
echo ""
echo "Examples:"
echo " $0 witnesses/openssl-cve-2024-0567.json"
echo " $0 --all --verbose"
exit 1
fi
echo ""
echo -e "${CYAN}==================================${NC}"
if [ $FAIL_COUNT -eq 0 ]; then
echo -e "Summary: ${GREEN}$PASS_COUNT passed${NC}, $FAIL_COUNT failed"
else
echo -e "Summary: $PASS_COUNT passed, ${RED}$FAIL_COUNT failed${NC}"
fi
exit $FAIL_COUNT

View File

@@ -0,0 +1,45 @@
{
"schemaVersion": "1.0.0",
"binary": {
"digest": "sha256:b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3",
"purl": "pkg:deb/debian/curl@8.4.0-2",
"arch": "linux-amd64",
"filename": "libcurl.so.4"
},
"cve": {
"id": "CVE-2023-38545",
"advisory": "https://curl.se/docs/CVE-2023-38545.html",
"patchCommit": "fb4415d8aee6c1"
},
"verdict": "patched",
"confidence": 0.91,
"evidence": [
{
"function": "socks5_resolve_local",
"state": "patched",
"score": 0.95,
"method": "semantic_ksg",
"hash": "sha256:1234abcd"
},
{
"function": "Curl_SOCKS5",
"state": "patched",
"score": 0.88,
"method": "cfg_structural",
"hash": "sha256:5678efgh"
},
{
"function": "socks_state",
"state": "modified",
"score": 0.85,
"method": "semantic_ksg"
}
],
"tooling": {
"binaryIndexVersion": "2.1.0",
"lifter": "b2r2",
"matchAlgorithm": "semantic_ksg",
"normalizationRecipe": "stella-norm-v3"
},
"computedAt": "2026-01-28T12:00:00.000Z"
}

View File

@@ -0,0 +1,49 @@
{
"schemaVersion": "1.0.0",
"binary": {
"digest": "sha256:a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2",
"purl": "pkg:deb/debian/openssl@3.0.11-1~deb12u2",
"arch": "linux-amd64",
"filename": "libssl.so.3"
},
"cve": {
"id": "CVE-2024-0567",
"advisory": "https://www.openssl.org/news/secadv/20240125.txt"
},
"verdict": "patched",
"confidence": 0.94,
"evidence": [
{
"function": "PKCS12_parse",
"state": "patched",
"score": 0.97,
"method": "semantic_ksg",
"hash": "sha256:f1e2d3c4"
},
{
"function": "PKCS12_verify_mac",
"state": "patched",
"score": 0.92,
"method": "semantic_ksg",
"hash": "sha256:a9b8c7d6"
},
{
"function": "SSL_CTX_new",
"state": "unchanged",
"score": 1.0,
"method": "byte_exact"
}
],
"deltaSigDigest": "sha256:deadbeef1234567890abcdef1234567890abcdef1234567890abcdef12345678",
"sbomRef": {
"sbomDigest": "sha256:cafe1234567890abcdef1234567890abcdef1234567890abcdef1234567890ab",
"purl": "pkg:deb/debian/openssl@3.0.11-1~deb12u2"
},
"tooling": {
"binaryIndexVersion": "2.1.0",
"lifter": "b2r2",
"matchAlgorithm": "semantic_ksg",
"normalizationRecipe": "stella-norm-v3"
},
"computedAt": "2026-01-28T12:00:00.000Z"
}