You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

175 lines
4.8 KiB

#!/bin/bash
# Source the environment with DIDs
if [ ! -f .generated/test-env.sh ]; then
echo "Error: No test environment found. Run run-deeplink-tests.sh first"
exit 1
fi
source .generated/test-env.sh
# Verify we have the required DIDs
if [ -z "$CONTACT1_DID" ] || [ -z "$CONTACT1_KEY" ]; then
echo "Error: Contact1 DID info not found in environment"
exit 1
fi
# Use CONTACT1 as the issuer since we know it's registered
REGISTERED_DID="$CONTACT1_DID"
REGISTERED_KEY="$CONTACT1_KEY"
# Default API URL (can be overridden by environment)
API_URL=${ENDORSER_API_URL:-"https://test-api.endorser.ch/api/v2/claim"}
# Function to sign a message using ES256K
sign_message() {
local message="$1"
local private_key="$2"
local tmpdir
# Create temporary directory
tmpdir=$(mktemp -d)
trap 'rm -rf "$tmpdir"' EXIT
# Debug output
echo "Signing message: $message" >&2
echo "Using private key: $private_key" >&2
# Hash the message with SHA-256
echo -n "$message" | openssl dgst -sha256 -binary > "$tmpdir/message.hash"
# Sign the hash directly using the private key
# This avoids OpenSSL's PEM format issues with secp256k1
python3 -c "
import sys
from eth_keys import keys
import hashlib
# Read message hash
with open('$tmpdir/message.hash', 'rb') as f:
message_hash = f.read()
# Create private key object
private_key_bytes = bytes.fromhex('$private_key')
private_key = keys.PrivateKey(private_key_bytes)
# Sign the message hash
signature = private_key.sign_msg_hash(message_hash)
# Output R and S values as hex
print(f'{hex(signature.r)[2:]:0>64}')
print(f'{hex(signature.s)[2:]:0>64}')
" > "$tmpdir/signature.txt"
# Read R and S values
{ read -r r_val; read -r s_val; } < "$tmpdir/signature.txt"
# Debug R and S values
echo "R value: $r_val" >&2
echo "S value: $s_val" >&2
# Concatenate R+S and convert to base64url
echo -n "${r_val}${s_val}" | xxd -r -p | base64 -w 0 | tr '/+' '_-' | tr -d '='
}
# Create a test claim payload
create_claim_payload() {
local issuer_did="$1"
# Create a test claim matching the app's structure
cat << EOF
{
"@context": "https://schema.org",
"@type": "TestClaim",
"identifier": "test-claim-$(date +%s)",
"name": "Test Claim",
"description": "Generated test claim",
"agent": {
"did": "$issuer_did"
}
}
EOF
}
# Create and sign JWT
create_jwt() {
local claim="$1"
local issuer_did="$2"
local private_key="$3"
# Create header and payload matching the app's structure
local header='{"typ":"JWT","alg":"ES256K"}'
local payload="{\"iat\":$(date +%s),\"exp\":$(($(date +%s) + 300)),\"iss\":\"$issuer_did\",\"vc\":{\"@context\":[\"https://www.w3.org/2018/credentials/v1\"],\"type\":[\"VerifiableCredential\"],\"credentialSubject\":$claim}}"
# Base64url encode header and payload
local header_b64=$(echo -n "$header" | base64 -w 0 | tr '/+' '_-' | tr -d '=')
local payload_b64=$(echo -n "$payload" | base64 -w 0 | tr '/+' '_-' | tr -d '=')
# Create message to sign
local message="$header_b64.$payload_b64"
# Sign message using eth_keys (same as did-jwt library)
local signature=$(python3 -c "
from eth_keys import keys
import hashlib
# Create private key object
private_key_bytes = bytes.fromhex('$private_key')
private_key = keys.PrivateKey(private_key_bytes)
# Hash the message
message_hash = hashlib.sha256('$message'.encode()).digest()
# Sign using ES256K
signature = private_key.sign_msg_hash(message_hash)
# Format as R+S concatenated and base64url encoded
import base64
signature_bytes = signature.r.to_bytes(32, 'big') + signature.s.to_bytes(32, 'big')
print(base64.urlsafe_b64encode(signature_bytes).decode().rstrip('='))
")
# Return complete JWT
echo "$message.$signature"
}
# Function to register claim with API
register_claim() {
local jwt="$1"
echo "Registering claim with API..."
response=$(curl -s -X POST "$API_URL" \
-H "Content-Type: application/json" \
-d "{\"jwtEncoded\":\"$jwt\"}")
# Check response
if echo "$response" | jq -e '.success' >/dev/null 2>&1; then
echo "Registration successful!"
echo "Response:"
echo "$response" | jq '.'
return 0
else
echo "Registration failed!"
echo "Error: $(echo "$response" | jq -r '.error.message // empty')"
echo "Full response:"
echo "$response" | jq '.' || echo "$response"
return 1
fi
}
# Main execution
echo "Generating test claim..."
# Create claim payload
claim=$(create_claim_payload "$REGISTERED_DID")
echo "Claim payload:"
echo "$claim" | jq '.'
# Create and sign JWT
echo "Generating signed JWT..."
jwt=$(create_jwt "$claim" "$REGISTERED_DID" "$REGISTERED_KEY")
# Output just the JWT for piping
echo "$jwt"
# Register the claim
register_claim "$jwt"