Commit bd41f24f authored by Sietse Ringers's avatar Sietse Ringers
Browse files

Simplify JWT signature detection function

parent 689445a5
......@@ -2,7 +2,6 @@ package irmaserver
import (
......@@ -177,6 +176,13 @@ func jwtAuthenticate(
return false, nil, "", nil
requestorJwt := string(body)
// We need to establish the signature method with which the JWT was signed. We do this by just
// inspecting the JWT header here, before the signature is verified (which is done below). I suppose
// it would be more idiomatic to have the KeyFunc which is fed to jwt.ParseWithClaims() perform this
// task, but then the KeyFunc would need access to all public keys here instead of the ones belonging
// to the signature algorithm we are expecting (specified by signatureAlg). Security-wise it makes no
// difference: either way the alg header is examined before the signature is verified.
alg, err := jwtSignatureAlg(requestorJwt)
if err != nil || alg != signatureAlg {
// If err != nil, ie. we failed to determine the JWT signature algorithm, we assume that the
......@@ -184,7 +190,8 @@ func jwtAuthenticate(
return false, nil, "", nil
// Verify JWT signature
// Verify JWT signature. We do not yet store the JWT contents here, because we need to know the session type first
// before we can construct a struct instance of the appropriate type into which to unmarshal the JWT contents.
claims := &jwt.StandardClaims{}
token, err := jwt.ParseWithClaims(requestorJwt, claims, jwtKeyExtractor(keys))
if err != nil {
......@@ -208,30 +215,9 @@ func jwtAuthenticate(
func jwtSignatureAlg(j string) (string, error) {
var (
alg string
header map[string]interface{}
i interface{}
ok bool
bts []byte
err error
segments := strings.Split(j, ".")
if len(segments) == 0 {
return "", errors.New("invalid jwt, not enough segments")
if bts, err = jwt.DecodeSegment(segments[0]); err != nil {
return "", errors.WrapPrefix(err, "failed to base64-decode jwt header", 0)
if err := json.Unmarshal(bts, &header); err != nil {
return "", errors.WrapPrefix(err, "failed to json-deserialize jwt header", 0)
if i, ok = header["alg"]; !ok {
return "", errors.New("alg field not found in jwt header")
if alg, ok = i.(string); !ok {
return "", errors.New("alg field in jwt was not a string")
token, _, err := new(jwt.Parser).ParseUnverified(j, &jwt.StandardClaims{})
if err != nil {
return "", err
return alg, nil
return token.Method.Alg(), nil
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment