Skip to content

Commit

Permalink
Allow using a static CEK via EncryptStatic
Browse files Browse the repository at this point in the history
  • Loading branch information
lestrrat committed Nov 15, 2023
1 parent 27d4001 commit e0e9e1d
Show file tree
Hide file tree
Showing 2 changed files with 34 additions and 5 deletions.
29 changes: 24 additions & 5 deletions jwe/jwe.go
Original file line number Diff line number Diff line change
Expand Up @@ -247,6 +247,23 @@ func (b *recipientBuilder) Build(cek []byte, calg jwa.ContentEncryptionAlgorithm
// Look for options that return `jwe.EncryptOption` or `jws.EncryptDecryptOption`
// for a complete list of options that can be passed to this function.
func Encrypt(payload []byte, options ...EncryptOption) ([]byte, error) {
return encrypt(payload, nil, options...)
}

// Encryptstatic is exactly like Encrypt, except it accepts a static
// content encryption key (CEK). DO NOT attempt to use this function unless
// you completely understand the security implications to using static
// CEKs. You have been warned.
func EncryptStatic(payload, cek []byte, options ...EncryptOption) ([]byte, error) {
if len(cek) <= 0 {
return nil, fmt.Errorf(`jwe.EncryptStatic: empty CEK`)
}

Check warning on line 260 in jwe/jwe.go

View check run for this annotation

Codecov / codecov/patch

jwe/jwe.go#L259-L260

Added lines #L259 - L260 were not covered by tests
return encrypt(payload, cek, options...)
}

// encrypt is separate so it can receive cek from outside.
// (but we don't want to receive it in the options slice)
func encrypt(payload, cek []byte, options ...EncryptOption) ([]byte, error) {
// default content encryption algorithm
calg := jwa.A256GCM

Expand Down Expand Up @@ -327,12 +344,14 @@ func Encrypt(payload []byte, options ...EncryptOption) ([]byte, error) {
return nil, fmt.Errorf(`jwe.Encrypt: failed to create AES encrypter: %w`, err)
}

generator := keygen.NewRandom(contentcrypt.KeySize())
bk, err := generator.Generate()
if err != nil {
return nil, fmt.Errorf(`jwe.Encrypt: failed to generate key: %w`, err)
if len(cek) <= 0 {
generator := keygen.NewRandom(contentcrypt.KeySize())
bk, err := generator.Generate()
if err != nil {
return nil, fmt.Errorf(`jwe.Encrypt: failed to generate key: %w`, err)
}

Check warning on line 352 in jwe/jwe.go

View check run for this annotation

Codecov / codecov/patch

jwe/jwe.go#L351-L352

Added lines #L351 - L352 were not covered by tests
cek = bk.Bytes()
}
cek := bk.Bytes()

recipients := make([]Recipient, len(builders))
for i, builder := range builders {
Expand Down
10 changes: 10 additions & 0 deletions jwe/jwe_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -895,6 +895,16 @@ func TestGH1001(t *testing.T) {
require.NoError(t, err, `jwe.Decrypt should succeed`)

require.Equal(t, "Lorem Ipsum", string(decrypted), `decrypted message should match`)
require.NotNil(t, cek, `cek should not be nil`)

reEncrypted, err := jwe.EncryptStatic([]byte("Lorem Ipsum"), cek, jwe.WithKey(jwa.RSA_OAEP, rawKey.PublicKey))
require.NoError(t, err, `jwe.EncryptStatic should succeed`)

cek = []byte(nil)
decrypted, err = jwe.Decrypt(reEncrypted, jwe.WithKey(jwa.RSA_OAEP, rawKey), jwe.WithCEK(&cek))
require.NoError(t, err, `jwe.Decrypt should succeed`)

require.Equal(t, "Lorem Ipsum", string(decrypted), `decrypted message should match`)
require.NotNil(t, cek, `cek should not be nil`)

}

0 comments on commit e0e9e1d

Please sign in to comment.