-
-
Save mlesaout/c1effd7961ecf6e4ca8330f74a97432a to your computer and use it in GitHub Desktop.
OpenWrt specific shell (ash) script to decode JWT token and verify it's signature. Based on https://gist.github.com/stokito/f2d7ea0b300f14638a9063559384ec89
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/ash | |
# Usage: cat /id_token.txt | jwt-decode.sh --no-verify-sig" > jwt_payload.json | |
. /usr/share/libubox/jshn.sh | |
base64_padding() | |
{ | |
local len=$(( ${#1} % 4 )) | |
local padded_b64='' | |
if [ ${len} = 2 ]; then | |
padded_b64="${1}==" | |
elif [ ${len} = 3 ]; then | |
padded_b64="${1}=" | |
else | |
padded_b64="${1}" | |
fi | |
echo -n "$padded_b64" | |
} | |
base64url_to_b64() | |
{ | |
base64_padding "${1}" | tr -- '-_' '+/' | |
} | |
# read the JWT from stdin and split by comma into three variables | |
IFS='.' read -r JWT_HEADER_B64URL JWT_PAYLOAD_B64URL JWT_SIGNATURE_B64URL | |
JWT_PAYLOAD_B64=$(base64url_to_b64 "${JWT_PAYLOAD_B64URL}") | |
JWT_PAYLOAD=$(echo "${JWT_PAYLOAD_B64}" | base64 -d) | |
if [ "$1" != "--no-verify-sig" ]; then | |
if [ -z $(command -v openssl) ]; then | |
>&2 echo "Error 2: To verify signature install openssl-util" | |
exit 2 | |
fi | |
JWT_HEADER_B64=$(base64url_to_b64 "${JWT_HEADER_B64URL}") | |
JWT_SIGNATURE_B64=$(base64url_to_b64 "${JWT_SIGNATURE_B64URL}") | |
JWT_HEADER=$(echo "${JWT_HEADER_B64}" | base64 -d) | |
json_init | |
json_load "$JWT_HEADER" | |
json_get_var JWT_ALG alg | |
json_get_var JWT_KID kid | |
# verify signature | |
if [ "${JWT_ALG}" = "RS256" ]; then | |
PUB_KEY_FILE="/var/tmp/oauth/$JWT_KID.key.pub.pem" | |
if [ ! -f $PUB_KEY_FILE ]; then | |
>&2 echo "No pub key $JWT_KID" | |
json_init | |
json_load "$JWT_PAYLOAD" | |
json_get_var JWT_ISS iss | |
if [ $JWT_ISS = "https://accounts.google.com" ]; then | |
mkdir -p /var/tmp/oauth/ | |
# use old jwks_url which return certs in PEM format | |
OAUTH_CERTS_URL="https://www.googleapis.com/oauth2/v1/certs" | |
echo "Fetch it from $OAUTH_CERTS_URL" | |
wget $OAUTH_CERTS_URL -q -O /tmp/jwks.json | |
CERT_FILE="/tmp/$JWT_KID.crt" | |
jsonfilter -i /tmp/jwks.json -e "@.$JWT_KID" > "$CERT_FILE" | |
rm /tmp/jwks.json | |
openssl x509 -pubkey -in "$CERT_FILE" -noout > "$PUB_KEY_FILE" | |
rm "$CERT_FILE" | |
else | |
>&2 echo "Error 4: Unable to get public key" | |
exit 4 | |
fi | |
fi | |
SIG_FILE=$(mktemp) | |
echo -n "$JWT_SIGNATURE_B64" | base64 -d > "${SIG_FILE}" | |
JWT_BODY=$(echo -n "$JWT_HEADER_B64URL.$JWT_PAYLOAD_B64URL") | |
JWT_SIG_VERIFY_ERR=$(echo -n "$JWT_BODY" | openssl dgst -sha256 -verify "${PUB_KEY_FILE}" -signature "${SIG_FILE}") | |
JWT_SIG_VERIFY_CODE=$? | |
rm "${SIG_FILE}" | |
if [ ${JWT_SIG_VERIFY_CODE} -ne 0 ]; then | |
>&2 echo "Error 1: Bad Signature: Code $JWT_SIG_VERIFY_CODE $JWT_SIG_VERIFY_ERR" | |
exit 1 | |
fi | |
else | |
>&2 echo "Error 3: Unsupported signature algorithm $JWT_ALG" | |
exit 3 | |
fi | |
fi | |
echo -n "${JWT_PAYLOAD}" |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment