Verify signatures of several passports
Check the Ed25519 signatures of a list of public passports offline, loading the key set once, and print one result per passport.
The script takes passport UUIDs (the part after urn:dpp:) as arguments, loads the key set from
/.well-known/batterypass/keys.json once, and checks each passport as described in
Verify a passport signature offline: canonicalise document with RFC 8785,
compare the SHA-256 with verification.hash, verify the Ed25519 signature with the key named by
verification.key_id. It needs no API key. It exits with status 1 if any passport is not valid, so it fits a
monitoring job or an incoming-goods check.
The cURL tab uses verifyPassport instead: the server checks the
signatures for you, which is quick but relies on the server's answer.
#!/usr/bin/env bash
# verify-many.sh <passport-uuid>...: the server-side check with verifyPassport (needs curl and jq)
for id in "$@"; do
curl -sS "$BATTERYPASS_URL/api/v1/public/passports/$id/verify" |
jq -r --arg id "$id" '"\($id)\t\(if .valid == true then "valid (version \(.version_no))" elif .code then .code else "INVALID" end)"'
done0192f0c4-7d1e-7a3b-9c55-2f1e8d4a6b10 valid
0192f0c4-7d1e-7a3b-9c55-2f1e8d4a6b11 not checked (qr_locked)
0192f0c4-7d1e-7a3b-9c55-2f1e8d4a6b12 error 404not checked means the passport is not public right now (its status is shown), so there is no signed document.
Public reads are limited to 300 requests per minute per client address; for long lists, add a pause or handle
429 as in Handle errors and retries. To verify passports of another
manufacturer, set BATTERYPASS_URL to the address their passports come from.