Skip to content

Commit

Permalink
Add support for RSA-OAEP-384 and RSA-OAEP-512 (#1142)
Browse files Browse the repository at this point in the history
  • Loading branch information
Hannes-Kunnen authored Jun 19, 2024
1 parent 639d231 commit 84cf8ec
Show file tree
Hide file tree
Showing 8 changed files with 111 additions and 9 deletions.
2 changes: 1 addition & 1 deletion internal/jwxtest/jwxtest.go
Original file line number Diff line number Diff line change
Expand Up @@ -286,7 +286,7 @@ func EncryptJweFile(ctx context.Context, payload []byte, keyalg jwa.KeyEncryptio
var keyif interface{}

switch keyalg {
case jwa.RSA1_5, jwa.RSA_OAEP, jwa.RSA_OAEP_256:
case jwa.RSA1_5, jwa.RSA_OAEP, jwa.RSA_OAEP_256, jwa.RSA_OAEP_384, jwa.RSA_OAEP_512:
var rawkey rsa.PrivateKey
if err := key.Raw(&rawkey); err != nil {
return "", nil, fmt.Errorf(`failed to obtain raw key: %w`, err)
Expand Down
4 changes: 4 additions & 0 deletions jwa/key_encryption_gen.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

80 changes: 80 additions & 0 deletions jwa/key_encryption_gen_test.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion jwe/decrypt.go
Original file line number Diff line number Diff line change
Expand Up @@ -278,7 +278,7 @@ func (d *decrypter) BuildKeyDecrypter() (keyenc.Decrypter, error) {
}

return keyenc.NewRSAPKCS15Decrypt(alg, &privkey, cipher.KeySize()/2), nil
case jwa.RSA_OAEP, jwa.RSA_OAEP_256:
case jwa.RSA_OAEP, jwa.RSA_OAEP_256, jwa.RSA_OAEP_384, jwa.RSA_OAEP_512:
var privkey rsa.PrivateKey
if err := keyconv.RSAPrivateKey(&privkey, d.privkey); err != nil {
return nil, fmt.Errorf(`*rsa.PrivateKey is required as the key to build %s key decrypter: %w`, alg, err)
Expand Down
16 changes: 12 additions & 4 deletions jwe/internal/keyenc/keyenc.go
Original file line number Diff line number Diff line change
Expand Up @@ -390,7 +390,7 @@ func (kw ECDHESDecrypt) Decrypt(enckey []byte) ([]byte, error) {
// NewRSAOAEPEncrypt creates a new key encrypter using RSA OAEP
func NewRSAOAEPEncrypt(alg jwa.KeyEncryptionAlgorithm, pubkey *rsa.PublicKey) (*RSAOAEPEncrypt, error) {
switch alg {
case jwa.RSA_OAEP, jwa.RSA_OAEP_256:
case jwa.RSA_OAEP, jwa.RSA_OAEP_256, jwa.RSA_OAEP_384, jwa.RSA_OAEP_512:
default:
return nil, fmt.Errorf("invalid RSA OAEP encrypt algorithm (%s)", alg)
}
Expand Down Expand Up @@ -462,8 +462,12 @@ func (e RSAOAEPEncrypt) EncryptKey(cek []byte) (keygen.ByteSource, error) {
hash = sha1.New()
case jwa.RSA_OAEP_256:
hash = sha256.New()
case jwa.RSA_OAEP_384:
hash = sha512.New384()
case jwa.RSA_OAEP_512:
hash = sha512.New()
default:
return nil, fmt.Errorf(`failed to generate key encrypter for RSA-OAEP: RSA_OAEP/RSA_OAEP_256 required`)
return nil, fmt.Errorf(`failed to generate key encrypter for RSA-OAEP: RSA_OAEP/RSA_OAEP_256/RSA_OAEP_384/RSA_OAEP_512 required`)
}
encrypted, err := rsa.EncryptOAEP(hash, rand.Reader, e.pubkey, cek, []byte{})
if err != nil {
Expand Down Expand Up @@ -536,7 +540,7 @@ func (d RSAPKCS15Decrypt) Decrypt(enckey []byte) ([]byte, error) {
// NewRSAOAEPDecrypt creates a new key decrypter using RSA OAEP
func NewRSAOAEPDecrypt(alg jwa.KeyEncryptionAlgorithm, privkey *rsa.PrivateKey) (*RSAOAEPDecrypt, error) {
switch alg {
case jwa.RSA_OAEP, jwa.RSA_OAEP_256:
case jwa.RSA_OAEP, jwa.RSA_OAEP_256, jwa.RSA_OAEP_384, jwa.RSA_OAEP_512:
default:
return nil, fmt.Errorf("invalid RSA OAEP decrypt algorithm (%s)", alg)
}
Expand All @@ -560,8 +564,12 @@ func (d RSAOAEPDecrypt) Decrypt(enckey []byte) ([]byte, error) {
hash = sha1.New()
case jwa.RSA_OAEP_256:
hash = sha256.New()
case jwa.RSA_OAEP_384:
hash = sha512.New384()
case jwa.RSA_OAEP_512:
hash = sha512.New()
default:
return nil, fmt.Errorf(`failed to generate key encrypter for RSA-OAEP: RSA_OAEP/RSA_OAEP_256 required`)
return nil, fmt.Errorf(`failed to generate key encrypter for RSA-OAEP: RSA_OAEP/RSA_OAEP_256/RSA_OAEP_384/RSA_OAEP_512 required`)
}
return rsa.DecryptOAEP(hash, rand.Reader, d.privkey, enckey, []byte{})
}
Expand Down
2 changes: 1 addition & 1 deletion jwe/jwe.go
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,7 @@ func (b *recipientBuilder) Build(cek []byte, calg jwa.ContentEncryptionAlgorithm
return nil, nil, fmt.Errorf(`failed to create RSA PKCS encrypter: %w`, err)
}
enc = v
case jwa.RSA_OAEP, jwa.RSA_OAEP_256:
case jwa.RSA_OAEP, jwa.RSA_OAEP_256, jwa.RSA_OAEP_384, jwa.RSA_OAEP_512:
var pubkey rsa.PublicKey
if err := keyconv.RSAPublicKey(&pubkey, rawKey); err != nil {
return nil, nil, fmt.Errorf(`failed to generate public key from key (%T): %w`, rawKey, err)
Expand Down
4 changes: 2 additions & 2 deletions jwx_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -188,7 +188,7 @@ func TestJoseCompatibility(t *testing.T) {

var tests []interopTest

for _, keyenc := range []jwa.KeyEncryptionAlgorithm{jwa.RSA1_5, jwa.RSA_OAEP, jwa.RSA_OAEP_256} {
for _, keyenc := range []jwa.KeyEncryptionAlgorithm{jwa.RSA1_5, jwa.RSA_OAEP, jwa.RSA_OAEP_256, jwa.RSA_OAEP_384, jwa.RSA_OAEP_512} {
if !set.Has(keyenc.String()) {
t.Logf("jose does not support key encryption algorithm %q: skipping", keyenc)
continue
Expand Down Expand Up @@ -297,7 +297,7 @@ func joseInteropTest(ctx context.Context, spec interopTest, t *testing.T) {

t.Run("Parse JWK via jwx", func(t *testing.T) {
switch spec.alg {
case jwa.RSA1_5, jwa.RSA_OAEP, jwa.RSA_OAEP_256:
case jwa.RSA1_5, jwa.RSA_OAEP, jwa.RSA_OAEP_256, jwa.RSA_OAEP_384, jwa.RSA_OAEP_512:
var rawkey rsa.PrivateKey
if !assert.NoError(t, jwxJwk.Raw(&rawkey), `jwk.Raw should succeed`) {
return
Expand Down
10 changes: 10 additions & 0 deletions tools/cmd/genjwa/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -249,6 +249,16 @@ func _main() error {
value: "RSA-OAEP-256",
comment: `RSA-OAEP-SHA256`,
},
{
name: `RSA_OAEP_384`,
value: "RSA-OAEP-384",
comment: `RSA-OAEP-SHA384`,
},
{
name: `RSA_OAEP_512`,
value: "RSA-OAEP-512",
comment: `RSA-OAEP-SHA512`,
},
{
name: `A128KW`,
value: "A128KW",
Expand Down

0 comments on commit 84cf8ec

Please sign in to comment.