| 110 | type JSONWebKeys []jose.JSONWebKey |
| 111 | |
| 112 | func (j JSONWebKeys) VerifySignature(ctx context.Context, jwt string) (payload []byte, err error) { |
| 113 | // Parse using the full list of supported algorithms, prior to restricting based on JWKS |
| 114 | jws, err := jose.ParseSigned(jwt, SupportedAlgorithmsSlice) |
| 115 | if err != nil { |
| 116 | return nil, err |
| 117 | } |
| 118 | |
| 119 | switch len(jws.Signatures) { |
| 120 | case 0: |
| 121 | base.DebugfCtx(ctx, base.KeyAuth, "Rejecting JWT - not signed") |
| 122 | return nil, fmt.Errorf("JWT not signed") |
| 123 | case 1: |
| 124 | default: |
| 125 | base.DebugfCtx(ctx, base.KeyAuth, "Rejecting JWT - multiple signatures on JWT not supported") |
| 126 | return nil, fmt.Errorf("multiple signatures on JWT not supported") |
| 127 | } |
| 128 | |
| 129 | jwtHeaderKID := jws.Signatures[0].Header.KeyID |
| 130 | jwtHeaderALG := jws.Signatures[0].Header.Algorithm |
| 131 | |
| 132 | if jwtHeaderKID == "" && len(j) != 1 { |
| 133 | base.DebugfCtx(ctx, base.KeyAuth, "Rejecting JWT - no 'kid' specified and multiple keys configured") |
| 134 | return nil, fmt.Errorf("no 'kid' specified and multiple keys configured") |
| 135 | } |
| 136 | |
| 137 | for i, key := range j { |
| 138 | if jwtHeaderKID != "" && jwtHeaderKID != key.KeyID { |
| 139 | continue |
| 140 | } |
| 141 | if jwtHeaderALG != key.Algorithm { |
| 142 | continue |
| 143 | } |
| 144 | if key.Use != "" && key.Use != keyUseSigning { |
| 145 | continue |
| 146 | } |
| 147 | payload, err := jws.Verify(&j[i]) |
| 148 | if err != nil { |
| 149 | base.DebugfCtx(ctx, base.KeyAuth, "Rejecting JWT - JWS verify failed: %v", err) |
| 150 | return nil, err |
| 151 | } |
| 152 | return payload, nil |
| 153 | } |
| 154 | |
| 155 | base.DebugfCtx(ctx, base.KeyAuth, "Rejecting JWT - no matching keys found (token alg: %s, kid: %v)", jwtHeaderALG, base.UD(jwtHeaderKID)) |
| 156 | return nil, errors.New("failed to verify id token signature") |
| 157 | } |
| 158 | |
| 159 | type LocalJWTAuthConfig struct { |
| 160 | JWTConfigCommon |