@ -22,7 +22,7 @@
# ENDORSER_API_URL - API endpoint (defaults to test)
# ENDORSER_API_URL - API endpoint (defaults to test)
# DEBUG - Enable debug logging when set to 1
# DEBUG - Enable debug logging when set to 1
# Add debug logging function
# Enhanced debug logging
debug_log( ) {
debug_log( ) {
if [ " ${ DEBUG :- 0 } " = "1" ] ; then
if [ " ${ DEBUG :- 0 } " = "1" ] ; then
echo " DEBUG: $* " >& 2
echo " DEBUG: $* " >& 2
@ -71,7 +71,7 @@ payload=$(jq -n \
sub: $sub ,
sub: $sub ,
iat: ( $iat | tonumber) ,
iat: ( $iat | tonumber) ,
exp: ( $exp | tonumber)
exp: ( $exp | tonumber)
} ' )
} ' )
# Base64url encode header and payload
# Base64url encode header and payload
# Header specifies ES256K-R algorithm for Ethereum compatibility
# Header specifies ES256K-R algorithm for Ethereum compatibility
@ -82,6 +82,15 @@ payload_b64=$(echo -n "$payload" | base64 -w 0 | tr '/+' '_-' | tr -d '=')
# Create message to sign (header.payload)
# Create message to sign (header.payload)
message = " $header_b64 . $payload_b64 "
message = " $header_b64 . $payload_b64 "
# Add debug points
debug_log "Creating JWT with:"
debug_log " ADMIN_DID: $ADMIN_DID "
debug_log " API_URL: $API_URL "
debug_log " Payload: $payload "
debug_log " Header base64: $header_b64 "
debug_log " Payload base64: $payload_b64 "
debug_log " Message to sign: $message "
# Create temporary directory for key operations
# Create temporary directory for key operations
# Uses trap to ensure cleanup on exit
# Uses trap to ensure cleanup on exit
TMPDIR = $( mktemp -d)
TMPDIR = $( mktemp -d)
@ -114,6 +123,10 @@ if [[ $der_sig =~ ^30([0-9a-f]{2})02([0-9a-f]{2})([0-9a-f]*)02([0-9a-f]{2})([0-9
s_len = " ${ BASH_REMATCH [4] } "
s_len = " ${ BASH_REMATCH [4] } "
s_val = " ${ BASH_REMATCH [5] } "
s_val = " ${ BASH_REMATCH [5] } "
debug_log "Raw signature values:"
debug_log " R ( ${# r_val } chars): $r_val "
debug_log " S ( ${# s_val } chars): $s_val "
# Convert lengths to decimal
# Convert lengths to decimal
r_len_dec = $(( 16# $r_len ))
r_len_dec = $(( 16# $r_len ))
s_len_dec = $(( 16# $s_len ))
s_len_dec = $(( 16# $s_len ))
@ -132,49 +145,134 @@ if [[ $der_sig =~ ^30([0-9a-f]{2})02([0-9a-f]{2})([0-9a-f]*)02([0-9a-f]{2})([0-9
s_val = $( printf "%064s" " $s_val " | tr ' ' '0' ) # Left pad
s_val = $( printf "%064s" " $s_val " | tr ' ' '0' ) # Left pad
fi
fi
# Ensure both values are exactly 64 characters
r_val = $( printf "%064s" " $r_val " | tr ' ' '0' )
s_val = $( printf "%064s" " $s_val " | tr ' ' '0' )
debug_log "Normalized values:"
debug_log " R ( ${# r_val } chars): $r_val "
debug_log " S ( ${# s_val } chars): $s_val "
# Create final signature
# Create final signature
concat_sig = " ${ r_val } ${ s_val } "
concat_sig = " ${ r_val } ${ s_val } "
# Debug the DER parsing
debug_log "DER Signature Analysis:"
debug_log " Full DER: $der_sig "
debug_log " Sequence length: ${ BASH_REMATCH [1] } "
debug_log " R length: $r_len ( $r_len_dec bytes) "
debug_log " S length: $s_len ( $s_len_dec bytes) "
# Debug signature components
debug_log "Signature components:"
debug_log " R value: $r_val (length: ${# r_val } ) "
debug_log " S value: $s_val (length: ${# s_val } ) "
debug_log " Concatenated: $concat_sig (length: ${# concat_sig } ) "
# Try both normal and high-S value signatures
s_val_alt = ""
if [ $s_len_dec -gt 32 ] ; then
# Store alternative S value
s_val_alt = " $s_val "
# Calculate N - s for high-S values
n = "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141"
# Use Python for hex math to avoid bc issues
normalized_s = $( python3 -c "
n = int( '$n' , 16)
s = int( '${s_val}' , 16)
result = hex( n - s) [ 2:] .zfill( 64)
print( result.lower( ) )
" 2>/dev/null || echo " ERROR" )
if [ " $normalized_s " = "ERROR" ] ; then
debug_log " Failed to normalize S value"
# Keep original s_val if normalization fails
s_val_alt = ""
else
s_val = $( printf "%064s" " $normalized_s " | tr ' ' '0' | tr '[:upper:]' '[:lower:]' )
debug_log " Normalized S value: $s_val "
fi
fi
# Calculate recovery bit (v)
# Calculate recovery bit (v)
# Try each possible recovery value (0-3) until we find one that works
# Try each possible recovery value (0-3) until we find one that works
for v in { 0..3} ; do
for v in { 0..3} ; do
recovery_sig = $( printf "%s%02x" " $concat_sig " " $v " )
# Try both S values if we have an alternative
debug_log " Trying recovery bit $v : $recovery_sig "
s_values = ( " $s_val " )
if [ -n " $s_val_alt " ] ; then
# Convert to base64url
s_values += ( " $s_val_alt " )
signature = $( echo -n " $recovery_sig " | xxd -r -p | base64 -w 0 | tr '/+' '_-' | tr -d '=' )
fi
# Create JWT with this signature
for current_s in " ${ s_values [@] } " ; do
JWT = " $message . $signature "
concat_sig = " ${ r_val } ${ current_s } "
debug_log " Trying with S value: $current_s "
# Test the JWT against the API
response = $( curl -s -X GET " $API_URL " \
recovery_sig = $( printf "%s%02x" " $concat_sig " " $v " )
-H "Content-Type: application/json" \
debug_log " Recovery attempt $v : "
-H " Authorization: Bearer $JWT " )
debug_log " Concatenated signature: $concat_sig "
debug_log " Recovery signature: $recovery_sig "
# Check if the JWT worked
debug_log " Recovery signature length: ${# recovery_sig } "
if ! echo " $response " | grep -q "JWT_VERIFY_FAILED" ; then
echo "JWT Token:"
# Ensure signature is exactly 65 bytes (130 hex chars)
echo " $JWT "
if [ ${# recovery_sig } -ne 130 ] ; then
echo
debug_log " Invalid signature length: ${# recovery_sig } , expected 130 "
echo "Export command:"
continue
echo " export TOKEN=' $JWT ' "
fi
echo
if [ -n " $CHECK_DID " ] ; then
# Convert hex to binary, then to base64url
# Check if specific DID is in the list
signature = $( echo -n " $recovery_sig " | xxd -r -p 2>/dev/null | base64 -w 0 | tr '/+' '_-' | tr -d '=' )
if echo " $response " | jq -e --arg did " $CHECK_DID " 'contains([$did])' > /dev/null; then
debug_log " Base64URL signature: $signature "
echo " ✅ DID $CHECK_DID is in the list "
exit 0
# Create JWT with this signature
JWT = " $message . $signature "
debug_log " Testing JWT: $JWT "
# Test the JWT against the API
response = $( curl -s -X GET " $API_URL " \
-H "Content-Type: application/json" \
-H " Authorization: Bearer $JWT " )
debug_log " API Response: $response "
# Check if the JWT worked
if ! echo " $response " | grep -q "JWT.*failed" ; then
echo "JWT Token:"
echo " $JWT "
debug_log " Success with v= $v and S= ${ current_s : 0 : 8 } ... "
echo
echo "Export command:"
echo " export TOKEN=' $JWT ' "
echo
if [ -n " $CHECK_DID " ] ; then
# Check if specific DID is in the list
if echo " $response " | jq -e --arg did " $CHECK_DID " 'contains([$did])' > /dev/null; then
echo " ✅ DID $CHECK_DID is in the list "
exit 0
else
echo " ❌ DID $CHECK_DID is not in the list "
echo "Attempting to add visibility..."
# Request visibility
visibility_response = $( curl -s -X POST \
'http://test-api.endorser.ch/api/report/canSeeMe' \
-H " Authorization: Bearer $JWT " \
-H "Content-Type: application/json" \
-d " {\"did\": \" $CHECK_DID \"} " )
if echo " $visibility_response " | grep -q "error" ; then
echo "❌ Failed to add visibility:"
echo " $visibility_response " | jq '.' --indent 2
exit 1
else
echo "✅ Successfully requested visibility. Please try checking again."
exit 0
fi
fi
else
else
echo " ❌ DID $CHECK_DID is not in the list "
# Show full list of visible DIDs
exit 1
echo " $response " | jq '.' --indent 2
fi
fi
else
exit 0
# Show full list of visible DIDs
echo " $response " | jq '.' --indent 2
fi
fi
exit 0
done
fi
done
done
echo "Error: Could not find valid recovery bit"
echo "Error: Could not find valid recovery bit"