From 575e6b86bcbb9d7691d0adedeb63f7238ed037ce Mon Sep 17 00:00:00 2001 From: "Pascal S. de Kloe" Date: Sun, 19 Apr 2020 17:25:55 +0200 Subject: [PATCH] FIX: RSA PSS hash length found by @rschoultz. --- check.go | 2 +- check_test.go | 5 +++++ jwt.go | 5 +++++ register.go | 2 +- sign.go | 2 +- 5 files changed, 13 insertions(+), 3 deletions(-) diff --git a/check.go b/check.go index 323cb8f..2ecfe7b 100644 --- a/check.go +++ b/check.go @@ -120,7 +120,7 @@ func RSACheck(token []byte, key *rsa.PublicKey) (*Claims, error) { digest.Write(token[:lastDot]) if alg != "" && alg[0] == 'P' { - err = rsa.VerifyPSS(key, hash, digest.Sum(sig[len(sig):]), sig, nil) + err = rsa.VerifyPSS(key, hash, digest.Sum(sig[len(sig):]), sig, &pSSOptions) } else { err = rsa.VerifyPKCS1v15(key, hash, digest.Sum(sig[len(sig):]), sig) } diff --git a/check_test.go b/check_test.go index be5c9fd..43e5935 100644 --- a/check_test.go +++ b/check_test.go @@ -111,6 +111,11 @@ var goldenRSAs = []struct { token: "eyJhbGciOiJSUzI1NiJ9.eyJjb2RlIjoiMDA3In0.q7I3GX8MUwd_Rrs_NiknGp3org30cBDT4JpvQfHx8TAPZNMeQokWb3iZD-Lu0TkQbZiFWdsRrrYVJO-nI15cvkRiSRtzKD0ilaC-i3VmM6cXu2AGSRhhFR4wAaZ5ZNYicooIVf1D1DLP48UZvT-n1ysuMKRRYrnyypcG8xg4o56UEFHrLL1zvuolIsG_sZN0pnVYUEDxLfXJboPSXDYOpyHSJu36Np6s4d8IsUyr3xX-Tu6-Lktu6_5k7NIVtY8yRHThe8x0UL316E_w1Av4nlECTezUS_vSF42w3rQESPXPwaZEFTxm0ciIRn0Wm0GdLHPaKSyZscgGn64eeai57Q", claims: `{"code":"007"}`, }, + 1: { + key: &testKeyRSA4096.PublicKey, + token: "eyJhbGciOiJQUzM4NCJ9.eyJjb2RlIjoiTUk1In0.SsX-DHgdVT1PXJKC5c_ZmDNcUa3WMtGMGwRTMPJ3cO1z0FK5zoRUDyc47CzCxWjjl-Yqcje7hRtV4gF8j9G_NK3ZDEQLBUMynig1g3V8K_wdqn66Vh0k_aWu9cit34rZPWJEsQ0xIvDzTTUfYH5JibvYqrUk5cc76cOe7h_bgzKvUPrYPcaxLKnH_8-Oc0aLMwgs9UrTJS1F6atWb5yLlnwKce4XqhzsnsX7WJGd8Ngfz_kTRtulRh2oqgh2SHPJ8f5fl049wDVPvtzo8vUphOBc8RwGWd7Ut93tali2N7jOpyoE_DvXLOW9rpjY7JK1uixSd1r25n1eAnqY9yR_mFqUToFTuaSrLGL4VN8drFb2mO7Dtj4uG3yE89tFa0KTYGoPHpUscvq46npdT2iE4jUd641n4h-KmHblVuGHnXEYV0C0MkGHjHS_ygWrNQ58x-6UiHm54NFeGY9c7PWy-28yYM5uKZ5OlFtnVtc5X_yLNkpLligAz_MWG2ueNUAvRJPnVLDa0ZrfvUJ5SdPDP_0y9-gEZ059-xJ21X1F_Mh7Vz8W6XB9zKypY83BH0jxd-3lEh15upq43R08FsecvRCQ9TY7rs1EJjnL6WkWhIWxNY3R9jiGUfFD9gDq5Dnzvy5glDjMqIVFewOhfkj0OacysOkJJeztSRnFBKe7MLQ", + claims: `{"code":"MI5"}`, + }, } func TestRSACheck(t *testing.T) { diff --git a/jwt.go b/jwt.go index 1fe4e2f..79238ae 100644 --- a/jwt.go +++ b/jwt.go @@ -4,6 +4,7 @@ package jwt import ( "crypto" + "crypto/rsa" _ "crypto/sha256" // link into binary _ "crypto/sha512" // link into binary "encoding/base64" @@ -79,6 +80,10 @@ var errNoSecret = errors.New("jwt: empty secret rejected") var encoding = base64.RawURLEncoding +// “The size of the salt value is the same size as the hash function output.” +// — “JSON Web Algorithms (JWA)” RFC 7518, subsection 3.5 +var pSSOptions = rsa.PSSOptions{SaltLength: rsa.PSSSaltLengthEqualsHash} + // Standard (IANA registered) claim names. const ( issuer = "iss" diff --git a/register.go b/register.go index 2bb7127..271dc21 100644 --- a/register.go +++ b/register.go @@ -102,7 +102,7 @@ func (keys *KeyRegister) Check(token []byte) (*Claims, error) { digestSum := digest.Sum(sig[len(sig):]) for _, key := range keyOptions { if alg != "" && alg[0] == 'P' { - err = rsa.VerifyPSS(key, hash, digestSum, sig, nil) + err = rsa.VerifyPSS(key, hash, digestSum, sig, &pSSOptions) } else { err = rsa.VerifyPKCS1v15(key, hash, digestSum, sig) } diff --git a/sign.go b/sign.go index b3edc73..778b925 100644 --- a/sign.go +++ b/sign.go @@ -146,7 +146,7 @@ func (c *Claims) RSASign(alg string, key *rsa.PrivateKey, extraHeaders ...json.R // use signature space as a buffer while not set buf := token[len(token):] if alg != "" && alg[0] == 'P' { - sig, err = rsa.SignPSS(rand.Reader, key, hash, digest.Sum(buf), nil) + sig, err = rsa.SignPSS(rand.Reader, key, hash, digest.Sum(buf), &pSSOptions) } else { sig, err = rsa.SignPKCS1v15(rand.Reader, key, hash, digest.Sum(buf)) }