#!/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 # 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 # Create private key PEM file echo "-----BEGIN EC PRIVATE KEY-----" > "$tmpdir/private.pem" ( echo "302e0201010420" # Private key header echo -n "$private_key" # Private key bytes echo "a00706052b8104000a" # secp256k1 OID ) | xxd -r -p | base64 >> "$tmpdir/private.pem" echo "-----END EC PRIVATE KEY-----" >> "$tmpdir/private.pem" # Write message to file echo -n "$message" > "$tmpdir/message.txt" # Sign message and get DER format signature openssl dgst -sha256 -sign "$tmpdir/private.pem" "$tmpdir/message.txt" > "$tmpdir/signature.der" # Convert DER signature to R+S format der_sig=$(xxd -p -c 256 "$tmpdir/signature.der") # Parse DER structure if [[ $der_sig =~ ^30([0-9a-f]{2})02([0-9a-f]{2})([0-9a-f]*)02([0-9a-f]{2})([0-9a-f]*)$ ]]; then r_val="${BASH_REMATCH[3]}" s_val="${BASH_REMATCH[5]}" # Remove leading zeros r_val=${r_val#"00"} s_val=${s_val#"00"} # Pad to 64 chars r_val=$(printf "%064s" "$r_val" | tr ' ' '0') s_val=$(printf "%064s" "$s_val" | tr ' ' '0') # Take last 64 chars if longer r_val=${r_val:(-64)} s_val=${s_val:(-64)} # Concatenate R+S and convert to base64url echo -n "${r_val}${s_val}" | xxd -r -p | base64 -w 0 | tr '/+' '_-' | tr -d '=' else echo "Error: Invalid DER signature format" >&2 return 1 fi } # Create a test claim payload create_claim_payload() { local issuer_did="$1" local subject_did="$2" # Create registration claim with issuer as agent cat << EOF { "@context": "https://schema.org", "@type": "TestClaim", "agent": { "did": "$issuer_did" }, "participant": { "did": "$subject_did" }, "object": "test.endorser.ch" } EOF } # Create and sign JWT create_jwt() { local claim="$1" local issuer_did="$2" local private_key="$3" # Create header and payload local header='{"typ":"JWT","alg":"ES256K"}' local payload="{\"iat\":$(date +%s),\"exp\":$(($(date +%s) + 300)),\"sub\":\"TestClaim\",\"vc\":{\"@context\":[\"https://www.w3.org/2018/credentials/v1\"],\"type\":[\"VerifiableCredential\"],\"credentialSubject\":$claim},\"iss\":\"$issuer_did\"}" # 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 local signature=$(sign_message "$message" "$private_key") # Return complete JWT echo "$message.$signature" } # Main execution echo "Generating test claim..." # Create claim payload claim=$(create_claim_payload "$ISSUER_DID" "$CONTACT1_DID") echo "Claim payload:" echo "$claim" | jq '.' # Create and sign JWT echo "Generating signed JWT..." jwt=$(create_jwt "$claim" "$ISSUER_DID" "$ISSUER_KEY") echo -e "\nGenerated JWT: ${jwt:0:50}..." echo "$jwt" # Output just the JWT for piping