|
| 1 | +#!/bin/bash |
| 2 | +# |
| 3 | +# 03_2_Supporting_Cross_verification-SCRIPT.sh |
| 4 | +# |
| 5 | +# Tests all commands from §3.1, verifying: |
| 6 | +# - XID consistency |
| 7 | +# - Provenance mark consistency |
| 8 | +# - Edge extraction |
| 9 | +# - temporal anchor check |
| 10 | +# |
| 11 | +# Usage: bash 03_2_Supporting_Cross_verification-SCRIPT.sh |
| 12 | +set -e |
| 13 | + |
| 14 | + |
| 15 | +echo "=== LEARNING XIDS §3.2: Supporting Cross Verification ===" |
| 16 | +echo "" |
| 17 | + |
| 18 | +# Configuration |
| 19 | +FETCHED_XID="ur:xid/tpsplftpsplntpsotanshdhdcxhecefsnnionspljpftktetwymnfmcyecveuotktpwenlhyhdpmpykpchcmzchywzoyaylrtpsotansgylftanshflfaohdcxtyjeuyceehntqzmwtdhfoscmguplcyeoaarhcxghreynrlfleynefnbtiodyesattansgrhdcxntesveuelkhdbnwdutynettbaarnnbspgefsvemohtnezeldcncmueldtkjlfxhdhdcxaavsgooxasuobnrdvanbkpfnlgttlnsfdtftisnypfcewzvlehdybemomdeeasbboycscstpsojlhsjyjyihjkjyhsjyinjljtdpjeihkkoycsfncsfdoyastpsotpcxksecisjyjyjojkftdldlioinjyiskpiddmiajljndlfwgmhsiekojliaetdlfwgmhsiekojliaetdljphsktdljnhsinjtdlksiniedmjyksjyoycfaorylftpsplrtpsokscfhsiaiajlkpjtjydpiajpihieihjtjyinhsjzdpioinjyiskpidoyadtpsojpiyjlhsiyftgwjtjzinjtihfpiaiajlkpjtjyoycfaorsldtpsotanshdhdcxhecefsnnionspljpftktetwymnfmcyecveuotktpwenlhyhdpmpykpchcmzchywzoytpsojsjkjkisguiniojtinjtiogrihkkjkgogmgstpsotpcxksenisjyjyjojkftdldlhsjoindmioinjyiskpiddmiajljndlkpjkihjpjkdlfwgmhsiekojliaetdljkjkishejkiniojtinjtiohejeihkkjkoytpsojnjkjkisguiniojtinjtiogrihkktpsotanshftanehsksimjkjkisdpihieeyececehescxfpfpfpfpfxeoglknhsfxehjzhtfygaehglghfeecfpfpfpfpgagwingwjykpiyesisktfyfwimglhdkkimkoimfdgtgrihgsgygrkkknghetfliafdeojygskofdglgrjphdgeihcxfwgmhsiekojliaetfzgthsiadmhsjyjyjzjliahsjzdmjtihjyoytpsojoiyjlhsiyfthsiaiajlkpjtjyglhsjnihtpsoisfwgmhsiekojliaetoytpsojsjkjkisguiniojtinjtiogrihkkghihksjytpsoksimjkjkisdpihieeyececehescxfpfpfpfpfxeoglknhsfxehjzhtfygaehglghfeecfpfpfpfpgagwingwjykpiyesisktfyfwimglhdkkimkoimfdgtgrihgsgygrkkknghetfliafdeojygskofdglgrjphdgeihcxfwgmhsiekojliaetfzgthsiadmhsjyjyjzjliahsjzdmjtihjyoybetpsokoeydyeyendpdyeodpehetghehehftececdpehdyftdydyoytpsokscwiyjlhsiyfthsiaiajlkpjtjyguihjpkoiniaihfdjljnihjohsioihtpsotpcxksdkisjyjyjojkftdldlioinjyiskpiddmiajljndlfwgmhsiekojliaetdlfwgmhsiekojliaetoycscwtpsotpcxksdaisjyjyjojkftdldlhsjoindmioinjyiskpiddmiajljndlkpjkihjpjkdlfwgmhsiekojliaetoycseetpsotpcxjpisjyjyjojkftdldlioinjyiskpiddmiajljnoycfaorntpsotanshdhdcxhecefsnnionspljpftktetwymnfmcyecveuotktpwenlhyhdpmpykpchcmzchywzoyaxtpsotansghtaneidkkaddmdpdpdpdpdpfwfeflgaglcxgugufdcxgugaflglfpghgogmfedpdpdpdpdpbkgoehglgagodyjzfdfpfpfpfpfpgyfpfpfpfygtfpfpfpfpgsiaeogljlgshghfjegtimgoehgtghjefpfpfpfpioengaeneyecdleyfdfpgtflgtehiygrgwdngtiaktjoeejyfpjpgsbkglgdkthtktiyihdykpetiadyjsjyiajzeefpfpfpfpgahthgeceyhthgkskoiaflgofpfpfpfpfpfpfpfpfpfwjtgljlhkghgaehgliofpfpfpfggtfpfpfpfpgsiaeogljlgshghfjebkgtimgoehgtghjefpfpfpfwfpeeglhsjyieghdlidieetidglghgoeskpgsfydnjsgafyecjnishtidfpeedyesglfxjeemhtfehfgmfpidfdgwimieiagdjlecflkofwgldyguiofyenbkengteeishgihiahkjlidfygujtjkjziaksgmhdfxihecgugrgmgyfpiofsfsbkdpdpdpdpdpfeglfycxgugufdcxgugaflglfpghgogmfedpdpdpdpdpbkoyaylrtpsotansgylftanshflfaohdcxolmystmtwyhhgljscpamingewnkplnpssfmnsnlramdwclkpkswmkstbfgdngdtotansgrhdcxsoeymskoiyrseswelubkspfdhllpmyksrpmkcmwzaoplwdlrfhzoropslpnlcmadoycscstpsoisfwgmhsiekojliaetoycsfncsfghdcxvdfpnltylrmowtutatkedsgresehiednenuthnveclgthgutprdlynoeuepkmnwtoycsfzlftpsotngdgmgwhflfaxhdimwpenbadrpkylftpdcysglohkhlwsdwwzfsineodwbgaezowkstehdwsnmtrnrptarooyiybaseldcnfdahehdedkuygrtiescmcxmsrnvtylfhlewegyotayhkfsuramlbpezsaylrcsjyotbysobektlywmprgmmkwspdctlgtodrtsvdbngljzromnfynddpceatkschjltkmslshnhdcxkibamycybshytapagwsfwtcebbvoincphebsvlgyfpehnlckdrstmocmmknsgshdoyaxtpsotansghlfaohdfzurflcmrdtadadakisfgdqzjsvoosahcfahghzebddwcflfgemtkphtpaspwpzsqdcygopyplplytcxvetlsrcpyaaaswiertmhcsluehrtotbtztcntbtkiyrylubzadzcpmbztt" |
| 20 | + |
| 21 | +# (This is a public version of the XID that appears in the BRadvoc8 repo on GitHub) |
| 22 | + |
| 23 | +# Create output directory |
| 24 | +OUTPUT_DIR="output/script-03-2-$(date +%Y%m%d-%H%M%S)" |
| 25 | +mkdir -p "$OUTPUT_DIR" |
| 26 | + |
| 27 | +echo "Step 2: Verify Self Consistency" |
| 28 | +echo "================================" |
| 29 | + |
| 30 | +success=0 |
| 31 | + |
| 32 | +read -a PUBKEY <<< $(envelope xid key all "$FETCHED_XID") |
| 33 | +for i in "${PUBKEY[@]}" |
| 34 | +do |
| 35 | + if envelope verify -v $i $FETCHED_XID >/dev/null 2>&1; then |
| 36 | + echo "✅ One of the signatures verified - XID is self-consistent " |
| 37 | + echo $i |
| 38 | + success=1 |
| 39 | + fi |
| 40 | +done |
| 41 | + |
| 42 | +if [[ -z $success ]] |
| 43 | +then |
| 44 | + echo "❌ Signature FAILED - do not trust!" |
| 45 | + exit 1 |
| 46 | +fi |
| 47 | + |
| 48 | +echo "" |
| 49 | +echo "Step 3: Verify Provenance Consistency" |
| 50 | +echo "=====================================" |
| 51 | + |
| 52 | +PROVENANCE_MARK=$(envelope xid provenance get "$FETCHED_XID") |
| 53 | + |
| 54 | +echo "Provenance mark: $(echo "$PROVENANCE_MARK" | head -c 50)..." |
| 55 | +echo "$PROVENANCE_MARK" > "$OUTPUT_DIR/01-provenance-mark.txt" |
| 56 | + |
| 57 | +echo "" |
| 58 | +echo "Provenance validation:" |
| 59 | +if provenance validate --warn --format json-pretty "$PROVENANCE_MARK" 2>&1 | head -20; then |
| 60 | + echo "✅ Provenance validated" |
| 61 | +else |
| 62 | + echo "⚠️ Provenance validation has issues" |
| 63 | +fi |
| 64 | +echo "" |
| 65 | + |
| 66 | +echo "" |
| 67 | +echo "Step 5: Extract the GitHub Edge" |
| 68 | +echo "==============================" |
| 69 | + |
| 70 | +XID_EDGE=$(envelope xid edge all $FETCHED_XID) |
| 71 | + |
| 72 | +if [ -z "$XID_EDGE" ]; then |
| 73 | + echo "❌ ERROR: No edge found in XID" |
| 74 | + exit 1 |
| 75 | +fi |
| 76 | + |
| 77 | +echo "✅ Found edge:" |
| 78 | +envelope format "$XID_EDGE" |
| 79 | + |
| 80 | +echo "" |
| 81 | +echo "Step 6: Extract the Claimed SSH Key" |
| 82 | +echo "===================================" |
| 83 | + |
| 84 | + |
| 85 | +UNWRAPPED_EDGE=$(envelope extract wrapped "$XID_EDGE") |
| 86 | +EDGE_TARGET=$(envelope assertion find predicate known 'target' "$UNWRAPPED_EDGE") |
| 87 | +EDGE_CLAIM=$(envelope extract object $EDGE_TARGET) |
| 88 | + |
| 89 | +USERNAME=$(envelope assertion find predicate string "foaf:accountName" "$EDGE_CLAIM" | envelope extract object | envelope format | tr -d '"') |
| 90 | +CLAIMED_KEY_UR=$(envelope assertion find predicate string "sshSigningKey" "$EDGE_CLAIM" | envelope extract object | envelope extract ur) |
| 91 | +CLAIMED_KEY_TEXT=$(envelope assertion find predicate string "sshSigningKeyText" "$EDGE_CLAIM" | envelope extract object | envelope format | tr -d '"') |
| 92 | + |
| 93 | +echo "SSH key claimed $USERNAME GitHub account" |
| 94 | +echo "$CLAIMED_KEY_UR" |
| 95 | +echo "$CLAIMED_KEY_TEXT" |
| 96 | + |
| 97 | +echo "" |
| 98 | +if echo "$CLAIMED_KEY_TEXT" | grep -q "ssh-ed25519"; then |
| 99 | + echo "✅ SSH key is ssh-ed25519 as expected" |
| 100 | +else |
| 101 | + echo "❌ ERROR: Could not extract SSH key or is wrong type" |
| 102 | + exit 1 |
| 103 | +fi |
| 104 | + |
| 105 | +echo "" |
| 106 | +echo "Step 7: Query GitHub API" |
| 107 | +echo "========================" |
| 108 | + |
| 109 | +echo "Querying GitHub API for $USERNAME's signing keys..." |
| 110 | +GITHUB_KEYS=$(curl -s "https://api.github.com/users/$USERNAME/ssh_signing_keys") |
| 111 | +GITHUB_KEY=$(echo "$GITHUB_KEYS" | jq -r '.[0].key') |
| 112 | + |
| 113 | +echo "" |
| 114 | +echo "GitHub API response:" |
| 115 | +echo "$GITHUB_KEYS" | jq '.[0] | {key, created_at}' |
| 116 | + |
| 117 | + |
| 118 | +echo "" |
| 119 | +echo "Step 8: Compare Keys" |
| 120 | +echo "====================" |
| 121 | + |
| 122 | +GITHUB_KEY_ARRAY=( $GITHUB_KEY ) |
| 123 | +CLAIMED_KEY_ARRAY=( $CLAIMED_KEY_TEXT ) |
| 124 | + |
| 125 | +echo "Claimed text key: ${CLAIMED_KEY_ARRAY[0]} ${CLAIMED_KEY_ARRAY[1]}" |
| 126 | +echo "GitHub key: ${GITHUB_KEY_ARRAY[0]} ${GITHUB_KEY_ARRAY[1]}" |
| 127 | + |
| 128 | +if [ "${CLAIMED_KEY_ARRAY[0]}" = "${GITHUB_KEY_ARRAY[0]}" ] && |
| 129 | + [ "${CLAIMED_KEY_ARRAY[1]}" = "${GITHUB_KEY_ARRAY[1]}" ]; then |
| 130 | + echo "" |
| 131 | + echo "✅ GITHUB KEY MATCHES - XID claim matches GitHub registry" |
| 132 | +else |
| 133 | + echo "" |
| 134 | + echo "❌ KEYS DO NOT MATCH - GitHub and XID Text Key Do Not Match" |
| 135 | + exit 1; |
| 136 | +fi |
| 137 | + |
| 138 | +EXPORTED_KEY_UR=$(envelope export "$CLAIMED_KEY_UR") |
| 139 | +EXPORTED_KEY_ARRAY=( $EXPORTED_KEY_UR ) |
| 140 | + |
| 141 | +echo "" |
| 142 | +echo "Claimed text key: ${CLAIMED_KEY_ARRAY[0]} ${CLAIMED_KEY_ARRAY[1]}" |
| 143 | +echo "Claimed UR key: ${EXPORTED_KEY_ARRAY[0]} ${EXPORTED_KEY_ARRAY[1]}" |
| 144 | + |
| 145 | +if [ "${CLAIMED_KEY_ARRAY[0]}" = "${EXPORTED_KEY_ARRAY[0]}" ] && |
| 146 | + [ "${CLAIMED_KEY_ARRAY[1]}" = "${EXPORTED_KEY_ARRAY[1]}" ]; then |
| 147 | + echo "" |
| 148 | + echo "✅ KEYS MATCH - Both XID keys match " |
| 149 | +else |
| 150 | + echo "" |
| 151 | + echo "❌ KEYS DO NOT MATCH - XID keys do not match " |
| 152 | + exit 1; |
| 153 | +fi |
| 154 | + |
| 155 | +echo "" |
| 156 | +echo "Step 9: Verify Keys" |
| 157 | +echo "===================" |
| 158 | + |
| 159 | +if envelope verify -v "$CLAIMED_KEY_UR" "$XID_EDGE" >/dev/null 2>&1; then |
| 160 | + echo "✅ silence means success" |
| 161 | +else |
| 162 | + echo "❌ XID edge signature does not match other keys" |
| 163 | + exit 1 |
| 164 | +fi |
| 165 | + |
| 166 | +echo "" |
| 167 | +echo "Step 10: Check GitHub's Timestamp" |
| 168 | +echo "=================================" |
| 169 | + |
| 170 | +GITHUB_CREATED=$(echo "$GITHUB_KEYS" | jq -r '.[0].created_at') |
| 171 | +echo "Key registered on GitHub: $GITHUB_CREATED" |
| 172 | + |
| 173 | + |
| 174 | +echo "" |
| 175 | +echo "Step 11: Cross-Reference Provenance" |
| 176 | +echo "=================================" |
| 177 | + |
| 178 | +CLAIMED_DATE=$(envelope assertion find predicate known "date" "$EDGE_CLAIM" | envelope extract object | envelope format | tr -d '"') |
| 179 | + |
| 180 | +echo "Timeline analysis:" |
| 181 | +echo " - GitHub key registered: $GITHUB_CREATED" |
| 182 | +echo " - XID edge created: $CLAIMED_DATE" |
| 183 | + |
| 184 | + |
| 185 | +echo "" |
| 186 | +echo "Step 12: Check Commit Signatures" |
| 187 | +echo "================================" |
| 188 | + |
| 189 | +echo "Checking commit signatures..." |
| 190 | +COMMIT_URL="https://api.github.com/repos/BRadvoc8/BRadvoc8/commits" |
| 191 | +RECENT_COMMIT=$(curl -s "$COMMIT_URL" | jq -r '.[].sha'|head -1) |
| 192 | +OLD_COMMIT=$(curl -s "$COMMIT_URL" | jq -r '.[].sha'|tail -1) |
| 193 | + |
| 194 | +echo "" |
| 195 | +echo "Most recent commit: $RECENT_COMMIT" |
| 196 | +echo "Recent verification status:" |
| 197 | +curl -s "https://api.github.com/repos/BRadvoc8/BRadvoc8/commits/$RECENT_COMMIT" | \ |
| 198 | + jq '{date: .commit.author.date, verified: .commit.verification.verified, reason: .commit.verification.reason}' |
| 199 | +echo "" |
| 200 | +echo "Older commit: $OLD_COMMIT" |
| 201 | +echo "Old verification status:" |
| 202 | +curl -s "https://api.github.com/repos/BRadvoc8/BRadvoc8/commits/$OLD_COMMIT" | \ |
| 203 | + jq '{date: .commit.author.date, verified: .commit.verification.verified, reason: .commit.verification.reason}' |
| 204 | + |
| 205 | +echo "===============================" |
| 206 | +echo "All Tutorial §3.2 Tests Passed!" |
| 207 | +echo "===============================" |
| 208 | +echo "" |
| 209 | +echo "No files saved" |
0 commit comments