180 lines
6.2 KiB
Bash
Executable File
180 lines
6.2 KiB
Bash
Executable File
#!/bin/bash
|
|
|
|
# Test SUP-03: Padding Payload Handling
|
|
# Tests: Type 2 payload with padding bytes and double decryption
|
|
|
|
set -e
|
|
|
|
TEST_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
source "$TEST_DIR/helpers/timing_utils.sh"
|
|
source "$TEST_DIR/helpers/event_utils.sh"
|
|
|
|
# Load test configuration
|
|
KEYS_FILE="$TEST_DIR/fixtures/test_keys.json"
|
|
RELAYS_FILE="$TEST_DIR/fixtures/test_relays.json"
|
|
|
|
# Extract keys
|
|
BUILDER_PRIVKEY=$(jq -r '.builder.privkey' "$KEYS_FILE")
|
|
THROWER_A_PRIVKEY=$(jq -r '.thrower_a.privkey' "$KEYS_FILE")
|
|
THROWER_A_PUBKEY=$(jq -r '.thrower_a.pubkey' "$KEYS_FILE")
|
|
THROWER_B_PRIVKEY=$(jq -r '.thrower_b.privkey' "$KEYS_FILE")
|
|
THROWER_B_PUBKEY=$(jq -r '.thrower_b.pubkey' "$KEYS_FILE")
|
|
|
|
# Extract relays
|
|
THROWER_A_RELAY=$(jq -r '.test_scenarios.multi_hop_2.thrower_a_relay' "$RELAYS_FILE")
|
|
THROWER_B_RELAY=$(jq -r '.test_scenarios.multi_hop_2.thrower_b_relay' "$RELAYS_FILE")
|
|
FINAL_RELAY=$(jq -r '.test_scenarios.multi_hop_2.final_relay' "$RELAYS_FILE")
|
|
|
|
echo "=== SUP-03: Padding Payload Test ==="
|
|
echo "Thrower A: $THROWER_A_PUBKEY → $THROWER_A_RELAY"
|
|
echo "Thrower B: $THROWER_B_PUBKEY → $THROWER_B_RELAY"
|
|
echo "Final Relay: $FINAL_RELAY"
|
|
echo ""
|
|
|
|
# Test parameters
|
|
DELAY_A=2
|
|
DELAY_B=2
|
|
PADDING_BYTES=1024
|
|
AUDIT_TAG="test-padding-$(date +%s)"
|
|
TEST_CONTENT="Padding test message at $(date)"
|
|
|
|
echo "Step 1: Create inner kind 1 event"
|
|
INNER_EVENT=$(create_test_event "$BUILDER_PRIVKEY" "$TEST_CONTENT")
|
|
INNER_EVENT_ID=$(echo "$INNER_EVENT" | jq -r '.id')
|
|
echo "Created inner event: $INNER_EVENT_ID"
|
|
echo ""
|
|
|
|
echo "Step 2: Create routing payload for Thrower B (final hop)"
|
|
ROUTING_B=$(create_routing_payload "$INNER_EVENT" "$FINAL_RELAY" "$DELAY_B" "null" "$AUDIT_TAG")
|
|
ENCRYPTED_B=$(encrypt_payload "$BUILDER_PRIVKEY" "$THROWER_B_PUBKEY" "$ROUTING_B")
|
|
WRAPPER_B=$(create_routing_event "$BUILDER_PRIVKEY" "$THROWER_B_PUBKEY" "$ENCRYPTED_B")
|
|
echo "Created routing for Thrower B"
|
|
echo ""
|
|
|
|
echo "Step 3: Create routing payload for Thrower A WITH PADDING INSTRUCTION"
|
|
echo "Instructing Thrower A to add ${PADDING_BYTES} bytes of padding"
|
|
ROUTING_A=$(create_routing_payload "$WRAPPER_B" "$THROWER_B_RELAY" "$DELAY_A" "$THROWER_B_PUBKEY" "$AUDIT_TAG" "$PADDING_BYTES")
|
|
echo ""
|
|
|
|
# Verify padding instruction is in the payload
|
|
if ! echo "$ROUTING_A" | grep -q "add_padding_bytes"; then
|
|
echo "ERROR: Padding instruction not found in routing payload"
|
|
exit 1
|
|
fi
|
|
echo "✓ Padding instruction included: add_padding_bytes=$PADDING_BYTES"
|
|
echo ""
|
|
|
|
echo "Step 4: Encrypt and wrap for Thrower A"
|
|
ENCRYPTED_A=$(encrypt_payload "$BUILDER_PRIVKEY" "$THROWER_A_PUBKEY" "$ROUTING_A")
|
|
WRAPPER_A=$(create_routing_event "$BUILDER_PRIVKEY" "$THROWER_A_PUBKEY" "$ENCRYPTED_A")
|
|
WRAPPER_A_ID=$(echo "$WRAPPER_A" | jq -r '.id')
|
|
echo "Created routing event: $WRAPPER_A_ID"
|
|
echo ""
|
|
|
|
echo "Step 5: Publish to Thrower A"
|
|
PUBLISH_TIME=$(get_timestamp)
|
|
publish_event "$WRAPPER_A" "$THROWER_A_RELAY"
|
|
echo "Published at: $(date -d @$PUBLISH_TIME)"
|
|
echo ""
|
|
|
|
echo "Step 6: Monitor for intermediate event on Thrower B's relay"
|
|
echo "This event should be a Type 2 payload (with padding)"
|
|
echo "Monitoring $THROWER_B_RELAY for kind 22222 events to Thrower B..."
|
|
echo ""
|
|
|
|
# Wait for Thrower A to process and forward
|
|
sleep $((DELAY_A + 5))
|
|
|
|
# Try to find the forwarded event on Thrower B's relay
|
|
# This is tricky because we need to find kind 22222 events with p-tag for Thrower B
|
|
INTERMEDIATE_FOUND=false
|
|
INTERMEDIATE_EVENT=$(nak req --relay "$THROWER_B_RELAY" -k 22222 --tag "p,$THROWER_B_PUBKEY" --limit 10 --timeout 5 2>/dev/null | \
|
|
jq -s 'sort_by(.created_at) | reverse | .[0]' 2>/dev/null || echo "{}")
|
|
|
|
if [ "$(echo "$INTERMEDIATE_EVENT" | jq -r '.id')" != "null" ] && [ "$(echo "$INTERMEDIATE_EVENT" | jq -r '.id')" != "" ]; then
|
|
INTERMEDIATE_FOUND=true
|
|
INTERMEDIATE_ID=$(echo "$INTERMEDIATE_EVENT" | jq -r '.id')
|
|
echo "✓ Found intermediate event: $INTERMEDIATE_ID"
|
|
|
|
# Check size - should be larger due to padding
|
|
INTERMEDIATE_SIZE=$(echo "$INTERMEDIATE_EVENT" | jq -r '.content' | wc -c)
|
|
echo " Intermediate event content size: ${INTERMEDIATE_SIZE} bytes"
|
|
echo " (Should be larger than original due to padding)"
|
|
else
|
|
echo "⚠ Could not verify intermediate event (may have been processed already)"
|
|
fi
|
|
echo ""
|
|
|
|
echo "Step 7: Monitor for final event on destination relay"
|
|
echo "Monitoring $FINAL_RELAY for inner event $INNER_EVENT_ID..."
|
|
echo ""
|
|
|
|
TIMEOUT=$((DELAY_A + DELAY_B + 30))
|
|
FOUND=false
|
|
START_MONITOR=$(get_timestamp)
|
|
|
|
while [ $(($(get_timestamp) - START_MONITOR)) -lt $TIMEOUT ]; do
|
|
if query_event "$INNER_EVENT_ID" "$FINAL_RELAY" 2 | grep -q "$INNER_EVENT_ID"; then
|
|
ARRIVAL_TIME=$(get_timestamp)
|
|
FOUND=true
|
|
break
|
|
fi
|
|
sleep 1
|
|
done
|
|
|
|
if [ "$FOUND" = false ]; then
|
|
echo "ERROR: Inner event not found on final relay within ${TIMEOUT}s"
|
|
echo "This indicates:"
|
|
echo " - Thrower A may not have added padding correctly"
|
|
echo " - Thrower B may not have handled Type 2 payload correctly"
|
|
echo " - Double decryption may have failed"
|
|
exit 1
|
|
fi
|
|
|
|
echo "✓ Inner event found on final relay"
|
|
echo ""
|
|
|
|
echo "Step 8: Verify timing"
|
|
ACTUAL_DELAY=$((ARRIVAL_TIME - PUBLISH_TIME))
|
|
EXPECTED_DELAY=$((DELAY_A + DELAY_B))
|
|
echo "Actual delay: ${ACTUAL_DELAY}s"
|
|
echo "Expected minimum: ${EXPECTED_DELAY}s"
|
|
|
|
if [ $ACTUAL_DELAY -lt $EXPECTED_DELAY ]; then
|
|
echo "ERROR: Event arrived too early!"
|
|
exit 1
|
|
fi
|
|
echo ""
|
|
|
|
echo "Step 9: Verify event content"
|
|
FINAL_EVENT=$(query_event "$INNER_EVENT_ID" "$FINAL_RELAY" 5)
|
|
FINAL_CONTENT=$(echo "$FINAL_EVENT" | jq -r '.content')
|
|
|
|
if [ "$FINAL_CONTENT" != "$TEST_CONTENT" ]; then
|
|
echo "ERROR: Content mismatch!"
|
|
echo "Expected: $TEST_CONTENT"
|
|
echo "Got: $FINAL_CONTENT"
|
|
exit 1
|
|
fi
|
|
|
|
echo "Content verified: $FINAL_CONTENT"
|
|
echo ""
|
|
|
|
echo "=== TEST PASSED ==="
|
|
echo "✓ Padding instruction processed by Thrower A"
|
|
echo "✓ Type 2 payload created with ${PADDING_BYTES} bytes padding"
|
|
echo "✓ Thrower B performed double decryption"
|
|
echo "✓ Padding discarded correctly"
|
|
echo "✓ Inner event delivered successfully"
|
|
echo "✓ Content preserved through padding layer"
|
|
echo ""
|
|
|
|
echo "Key Observations:"
|
|
if [ "$INTERMEDIATE_FOUND" = true ]; then
|
|
echo " - Intermediate event size increased due to padding"
|
|
fi
|
|
echo " - Double decryption handled correctly"
|
|
echo " - Timing constraints respected"
|
|
echo ""
|
|
|
|
exit 0 |