forked from jsnbuchanan/crowd-funder-for-time-pwa
- Add ES256K signature generation for test claims - Fix signature format to match endorser.ch requirements - Remove dependency on did_generator.sh for signing - Improve JWT creation with proper header and payload structure The changes fix JWT verification issues by: 1. Implementing proper DER to R+S signature conversion 2. Handling secp256k1 private key formatting correctly 3. Using correct base64url encoding for JWT components 4. Adding proper issuer field to JWT payload
117 lines
3.4 KiB
Bash
Executable File
117 lines
3.4 KiB
Bash
Executable File
#!/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 |