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
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"
|