Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Can't decode JWKSet if thumbprint is not 20 bytes (incorrect number of bytes) #54

Closed
Leonti opened this issue Aug 9, 2017 · 12 comments
Closed

Comments

@Leonti
Copy link

Leonti commented Aug 9, 2017

Hi!
While trying to decode JWKSet from Auth0 I stumbled on an issue when decoding fails because x5t is more than 20 bytes (I'm getting Left "Error in $.keys[0].x5t: incorrect number of bytes").
Here is the value:

"x5t":"RTBFQjE3MEU0QjQ2M0FCNkYxRTEwMUIwNTJFOUY1NDgyMjgzRTI1NQ"

The decoded value for this is:

E0EB170E4B463AB6F1E101B052E9F5482283E255

It has 40 characters in hex, so I think it will be 20 bytes when in binary.

This is the JWK set coming from https://auth0.com

The full set if needed:

{  
   "keys":[  
      {  
         "alg":"RS256",
         "kty":"RSA",
         "use":"sig",
         "x5c":[  
            "MIIDATCCAemgAwIBAgIJFZEwRAGW4NzQMA0GCSqGSIb3DQEBCwUAMB4xHDAaBgNVBAMTE2xlb250aS5hdS5hdXRoMC5jb20wHhcNMTcwNzA5MDk1OTU3WhcNMzEwMzE4MDk1OTU3WjAeMRwwGgYDVQQDExNsZW9udGkuYXUuYXV0aDAuY29tMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEApSUFVpIv+kiRsIw6M9R2JqXFofwHM7JXo022PkDFiIsgu1UtKV4ubLssA3hrmJAx1n+jSENifzMEl6ppyh4cmnTbV5XVKNjUm8D7+DsKYebTaf5tbvTTCiil7t4YMWcwIbHudF6j6NFDxXy3c2A0oCOA7+edMOVXXKAbE6/QyE+Z59pa2PkEFWQbE13R4GXewHqtOmuzBj0bKN9mj37tPAaAluizhrE60sK97Xn49wIizunJlquUJycoF093adz0nfJRk/scchID0Dg+MgDNePLUtfCEkGMYDPgwepDUfsOaQDNlssxRGxaFgrK3U6ASMSLkoqP2gCcX9t+uWbO/9QIDAQABo0IwQDAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBT8lWNl0h7CwDPWEN/WVzh55xwYBjAOBgNVHQ8BAf8EBAMCAoQwDQYJKoZIhvcNAQELBQADggEBAFWJRIuxuPAfX8chXZ2ZEXK+70DGMbw42XWZxNCnhAaPWftPcybvws24LWdxVrYCOngTIQo5ezOsELVjn6mO8TDHvp5L8oeGLCLyTHe4sTw+7rKjV9wyS5DH6xH/40h8CuUEyXghiMAE6r5weCcUQ9r21VpNvLdK+O9LSwnBUCcjOqM4RFazbeVqVMjGWOCP/j9nHpPW5/18YHTTUV5pIrS/STzlGaQ/oeu7GImQSea/Zxsgmw+bkSyT/p5eyDOrlMcc3fwB1LJB72oA3hYj44ndj9gel8dQzWwNb3YKeDbDDUHjGyEfcW+D9HYDAtmgRedOxAt4YGVa7abjwUvfWos="
         ],
         "n":"pSUFVpIv-kiRsIw6M9R2JqXFofwHM7JXo022PkDFiIsgu1UtKV4ubLssA3hrmJAx1n-jSENifzMEl6ppyh4cmnTbV5XVKNjUm8D7-DsKYebTaf5tbvTTCiil7t4YMWcwIbHudF6j6NFDxXy3c2A0oCOA7-edMOVXXKAbE6_QyE-Z59pa2PkEFWQbE13R4GXewHqtOmuzBj0bKN9mj37tPAaAluizhrE60sK97Xn49wIizunJlquUJycoF093adz0nfJRk_scchID0Dg-MgDNePLUtfCEkGMYDPgwepDUfsOaQDNlssxRGxaFgrK3U6ASMSLkoqP2gCcX9t-uWbO_9Q",
         "e":"AQAB",
         "kid":"RTBFQjE3MEU0QjQ2M0FCNkYxRTEwMUIwNTJFOUY1NDgyMjgzRTI1NQ",
         "x5t":"RTBFQjE3MEU0QjQ2M0FCNkYxRTEwMUIwNTJFOUY1NDgyMjgzRTI1NQ"
      }
   ]
}

Cheers,
Leonti

@frasertweedale
Copy link
Owner

frasertweedale commented Aug 9, 2017

This is a bug in auth0. Per https://tools.ietf.org/html/rfc7517#section-4.8:

4.8.  "x5t" (X.509 Certificate SHA-1 Thumbprint) Parameter

   The "x5t" (X.509 certificate SHA-1 thumbprint) parameter is a
   base64url-encoded SHA-1 thumbprint (a.k.a. digest) of the DER
   encoding of an X.509 certificate [RFC5280].

Therefore the unencoded datum must be 20-bytes in size.

@frasertweedale
Copy link
Owner

Thanks for your report, but you should raise the issue with auth0. Good luck!

@Leonti
Copy link
Author

Leonti commented Aug 9, 2017

Thanks!
I asked the question on their support forum :)
I doubt they will change their implementation, but I'd like to know the explanation why they implemented it this way.

@wraithm
Copy link

wraithm commented Jan 8, 2018

@Leonti Did you ever end up getting anywhere with auth0? I just ran into the same issue. What did you end up doing?

@Leonti
Copy link
Author

Leonti commented Jan 9, 2018

@wraithm Unfortunately there is no progress from their side:
https://community.auth0.com/questions/7227/certificate-thumbprint-is-longer-than-20-bytes

This what I ended up doing unfortunately:

jwksFix :: ByteString -> ByteString  
jwksFix = replace (L.toStrict "x5t") (L.toStrict "x5t_unused") . L.toStrict

It basically removes thumbprint field so it's not decoded anymore
At least it still verifies certificate and audience, good enough for my use case.

@frasertweedale
Copy link
Owner

Fair enough. Be aware that if the x5t parameter appears in the JWS Protected Header (including any JWS containing the x5t parameter that uses the Compact Serialization) this approach will not work.

Another option is to actually decode the hex-encoded thumbprint and re-encode it properly. But again that will only work when it is in the unprotected header.

@wraithm
Copy link

wraithm commented Jan 10, 2018

I wrote the x5t re-encoding code. @frasertweedale, is this what you were roughly thinking?:

import           Control.Monad
import           Data.Aeson
import           Data.HashMap.Strict              as H
import           Data.Text.Encoding
import           Data.ByteString.Lazy             (ByteString)
import qualified Data.ByteString.Base16           as B16
import qualified Data.ByteString.Base64.URL       as B64
import qualified Crypto.JOSE.JWK                  as JWK

auth0TokenFix :: ByteString -> Maybe JWK.JWKSet
auth0TokenFix jwksBs = do
    jwks <- mapM (modifyx5tField <=< fromObject)
        =<< fromArray =<< H.lookup "keys"
        =<< fromObject =<< decode jwksBs
    decode . encode $ object [ "keys" .= jwks ]
  where
    x5tField = "x5t"
    modifyx5tField o = flip (H.insert x5tField) o . String . b64HexToB64 <$> (fromJSONString =<< H.lookup x5tField o)
    b64HexToB64 = decodeUtf8 . B64.encode . fst . B16.decode . B64.decodeLenient . encodeUtf8

    fromJSONString (String s) = Just s
    fromJSONString _          = Nothing
    fromArray (Array xs) = Just xs
    fromArray _          = Nothing
    fromObject (Object o) = Just o
    fromObject _          = Nothing

@frasertweedale
Copy link
Owner

frasertweedale commented Jan 10, 2018 via email

@tmcgilchrist
Copy link
Contributor

Is it worth linking that snippet along side the auth0 being broken comment?

@frasertweedale
Copy link
Owner

@ocramz
Copy link

ocramz commented Apr 26, 2020

IIUC this has been fixed upstream with signing key rotation :

https://community.auth0.com/t/jwk-certificate-thumbprint-is-invalid/16070/22

@frasertweedale
Copy link
Owner

Wow! Only took 2.5 years... Thanks for the update @ocramz.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants