Browse Source
- 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 payloadpull/127/head
1 changed files with 117 additions and 0 deletions
@ -0,0 +1,117 @@ |
|||
#!/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 |
Loading…
Reference in new issue