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

[jwe] Decryption using an algorithm that uses the "p2c" header with the WithUseNumber option fails #1140

Closed
Hannes-Kunnen opened this issue Jun 17, 2024 · 3 comments · Fixed by #1141
Assignees

Comments

@Hannes-Kunnen
Copy link
Contributor

Describe the bug

Decrypting an encrypted payload with any algorithm that requires the p2c (PBES2 count) header using the jwe.Decrypt function will fail if the jwx.WithUseNumber(true) decoder option is set.

Go version:
go version go1.22.0 linux/amd64

To Reproduce / Expected behavior

package main

import (
	"fmt"
	"github.com/lestrrat-go/jwx/v2"
	"github.com/lestrrat-go/jwx/v2/jwa"
	"github.com/lestrrat-go/jwx/v2/jwe"
	"github.com/lestrrat-go/jwx/v2/jwk"
)

func init() {
	jwx.DecoderSettings(jwx.WithUseNumber(true))
}

func main() {
	key, err := jwk.FromRaw([]byte("secure-key"))
	if err != nil {
		fmt.Println(err)
		return
	}

	var encrypted []byte
	encrypted, err = jwe.Encrypt(
		[]byte("test-encryption-payload"),
		jwe.WithKey(jwa.PBES2_HS256_A128KW, key),
	)
	if err != nil {
		fmt.Println(err)
		return
	}

	_, err = jwe.Decrypt(encrypted, jwe.WithKey(jwa.PBES2_HS256_A128KW, key))
	if err != nil {
		fmt.Println(err)
		return
	}

	fmt.Println("success")
}

See Go Playground

Expected behavior: I expected this code to print the success message.
Actual behavior: I get the following error: jwe.Decrypt: failed to decrypt any of the recipients (last error = jwe.Decrypt: tried 1 keys, but failed to match any of the keys with recipient (last error = unexpected type for 'p2c': json.Number))

Additional context
I think I found the issue and a possible solution.
The issue seems the be located in these lines:

jwx/jwe/jwe.go

Lines 748 to 751 in 611d914

countFlt, ok := count.(float64)
if !ok {
return nil, fmt.Errorf("unexpected type for 'p2c': %T", count)
}

Because the option jwx.WithUseNumber(true) is used the type here is json.Number instead of float64. This code could be updated to support the json.Number type like this:

var countFlt float64
switch typedCount := count.(type) {
case json.Number:
	countFlt, err = typedCount.Float64()
	if err != nil {
		return nil, fmt.Errorf(`failed to parse 'p2c': %w`, err)
	}
case float64:
	countFlt = typedCount
default:
	return nil, fmt.Errorf("unexpected type for 'p2c': %T", count)
}

I am however not familiar with this code base, so it's possible that I'm missing a better solution.

@lestrrat
Copy link
Collaborator

Thank you! Nice catch.
Will see how to fix...

@lestrrat
Copy link
Collaborator

lestrrat commented Jun 17, 2024

@Hannes-Kunnen Thanks for the nice report and analysis! Much appreciated.
Please check PR #1141 and let me know if it fixes your problem.

BTW I didn't use your suggested fix for mainly one reason: Instead of reacting to what the JSON values are, I wanted to be pedantic about what we expect based on our internal settings. That is, I wanted to only convert to json.Number when we are expecting it, not when the input somehow turned out to be json.Number -- which could potentially be by mistake.

@Hannes-Kunnen
Copy link
Contributor Author

That makes more sense and will fix the issue!

lestrrat added a commit that referenced this issue Jun 17, 2024
…) (#1141)

* Fix conversion in JWE when WithUseNumber global settings is used (#1140)

* Add Changes
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

Successfully merging a pull request may close this issue.

2 participants