Skip to content

Commit

Permalink
jwe.ParseXXX, jwe.Decrypt, jwe.Encrypt
Browse files Browse the repository at this point in the history
  • Loading branch information
Daisuke Maki committed Oct 25, 2024
1 parent 6a27808 commit 946f055
Show file tree
Hide file tree
Showing 2 changed files with 104 additions and 25 deletions.
86 changes: 61 additions & 25 deletions jwe/jwe.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import (
"crypto/ecdh"
"crypto/ecdsa"
"crypto/rsa"
"errors"
"fmt"
"io"
"sync"
Expand Down Expand Up @@ -285,7 +286,11 @@ 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...)
ret, err := encrypt(payload, nil, options...)
if err != nil {
return nil, encryptError{fmt.Errorf(`jwe.Encrypt: %w`, err)}

Check failure on line 291 in jwe/jwe.go

View workflow job for this annotation

GitHub Actions / lint

undefined: encryptError

Check failure on line 291 in jwe/jwe.go

View workflow job for this annotation

GitHub Actions / Smoke [ Go 1.21 / Tags es256k ]

undefined: encryptError

Check failure on line 291 in jwe/jwe.go

View workflow job for this annotation

GitHub Actions / Smoke [ Go 1.21 / Tags stdlib ]

undefined: encryptError

Check failure on line 291 in jwe/jwe.go

View workflow job for this annotation

GitHub Actions / Smoke [ Go 1.22 / Tags stdlib ]

undefined: encryptError

Check failure on line 291 in jwe/jwe.go

View workflow job for this annotation

GitHub Actions / Test [ Go 1.22 / Tags asmbase64 ]

undefined: encryptError

Check failure on line 291 in jwe/jwe.go

View workflow job for this annotation

GitHub Actions / Smoke [ Go 1.22 / Tags goccy ]

undefined: encryptError

Check failure on line 291 in jwe/jwe.go

View workflow job for this annotation

GitHub Actions / Test [ Go 1.21 / Tags es256k ]

undefined: encryptError

Check failure on line 291 in jwe/jwe.go

View workflow job for this annotation

GitHub Actions / Smoke [ Go 1.22 / Tags es256k ]

undefined: encryptError

Check failure on line 291 in jwe/jwe.go

View workflow job for this annotation

GitHub Actions / Test [ Go 1.23 / Tags alltags ]

undefined: encryptError

Check failure on line 291 in jwe/jwe.go

View workflow job for this annotation

GitHub Actions / Smoke [ Go 1.21 / Tags goccy ]

undefined: encryptError

Check failure on line 291 in jwe/jwe.go

View workflow job for this annotation

GitHub Actions / Test [ Go 1.23 / Tags asmbase64 ]

undefined: encryptError

Check failure on line 291 in jwe/jwe.go

View workflow job for this annotation

GitHub Actions / Test [ Go 1.21 / Tags alltags ]

undefined: encryptError

Check failure on line 291 in jwe/jwe.go

View workflow job for this annotation

GitHub Actions / Smoke [ Go 1.22 / Tags alltags ]

undefined: encryptError

Check failure on line 291 in jwe/jwe.go

View workflow job for this annotation

GitHub Actions / Test [ Go 1.21 / Tags goccy ]

undefined: encryptError
}
return ret, nil
}

// EncryptStatic is exactly like Encrypt, except it accepts a static
Expand All @@ -300,9 +305,13 @@ func Encrypt(payload []byte, options ...EncryptOption) ([]byte, error) {
// future changes across minor/micro versions.
func EncryptStatic(payload, cek []byte, options ...EncryptOption) ([]byte, error) {
if len(cek) <= 0 {
return nil, fmt.Errorf(`jwe.EncryptStatic: empty CEK`)
return nil, encryptError{fmt.Errorf(`jwe.EncryptStatic: empty CEK`)}

Check failure on line 308 in jwe/jwe.go

View workflow job for this annotation

GitHub Actions / lint

undefined: encryptError

Check failure on line 308 in jwe/jwe.go

View workflow job for this annotation

GitHub Actions / Smoke [ Go 1.21 / Tags es256k ]

undefined: encryptError

Check failure on line 308 in jwe/jwe.go

View workflow job for this annotation

GitHub Actions / Smoke [ Go 1.21 / Tags stdlib ]

undefined: encryptError

Check failure on line 308 in jwe/jwe.go

View workflow job for this annotation

GitHub Actions / Smoke [ Go 1.22 / Tags stdlib ]

undefined: encryptError

Check failure on line 308 in jwe/jwe.go

View workflow job for this annotation

GitHub Actions / Test [ Go 1.22 / Tags asmbase64 ]

undefined: encryptError

Check failure on line 308 in jwe/jwe.go

View workflow job for this annotation

GitHub Actions / Smoke [ Go 1.22 / Tags goccy ]

undefined: encryptError

Check failure on line 308 in jwe/jwe.go

View workflow job for this annotation

GitHub Actions / Test [ Go 1.21 / Tags es256k ]

undefined: encryptError

Check failure on line 308 in jwe/jwe.go

View workflow job for this annotation

GitHub Actions / Smoke [ Go 1.22 / Tags es256k ]

undefined: encryptError

Check failure on line 308 in jwe/jwe.go

View workflow job for this annotation

GitHub Actions / Test [ Go 1.23 / Tags alltags ]

undefined: encryptError

Check failure on line 308 in jwe/jwe.go

View workflow job for this annotation

GitHub Actions / Smoke [ Go 1.21 / Tags goccy ]

undefined: encryptError

Check failure on line 308 in jwe/jwe.go

View workflow job for this annotation

GitHub Actions / Test [ Go 1.23 / Tags asmbase64 ]

undefined: encryptError

Check failure on line 308 in jwe/jwe.go

View workflow job for this annotation

GitHub Actions / Test [ Go 1.21 / Tags alltags ]

undefined: encryptError

Check failure on line 308 in jwe/jwe.go

View workflow job for this annotation

GitHub Actions / Smoke [ Go 1.22 / Tags alltags ]

undefined: encryptError

Check failure on line 308 in jwe/jwe.go

View workflow job for this annotation

GitHub Actions / Test [ Go 1.21 / Tags goccy ]

undefined: encryptError
}
return encrypt(payload, cek, options...)
ret, err := encrypt(payload, cek, options...)
if err != nil {
return nil, encryptError{fmt.Errorf(`jwe.EncryptStatic: %w`, err)}

Check failure on line 312 in jwe/jwe.go

View workflow job for this annotation

GitHub Actions / lint

undefined: encryptError

Check failure on line 312 in jwe/jwe.go

View workflow job for this annotation

GitHub Actions / Smoke [ Go 1.21 / Tags es256k ]

undefined: encryptError

Check failure on line 312 in jwe/jwe.go

View workflow job for this annotation

GitHub Actions / Smoke [ Go 1.21 / Tags stdlib ]

undefined: encryptError

Check failure on line 312 in jwe/jwe.go

View workflow job for this annotation

GitHub Actions / Smoke [ Go 1.22 / Tags stdlib ]

undefined: encryptError

Check failure on line 312 in jwe/jwe.go

View workflow job for this annotation

GitHub Actions / Test [ Go 1.22 / Tags asmbase64 ]

undefined: encryptError

Check failure on line 312 in jwe/jwe.go

View workflow job for this annotation

GitHub Actions / Smoke [ Go 1.22 / Tags goccy ]

undefined: encryptError

Check failure on line 312 in jwe/jwe.go

View workflow job for this annotation

GitHub Actions / Test [ Go 1.21 / Tags es256k ]

undefined: encryptError

Check failure on line 312 in jwe/jwe.go

View workflow job for this annotation

GitHub Actions / Smoke [ Go 1.22 / Tags es256k ]

undefined: encryptError

Check failure on line 312 in jwe/jwe.go

View workflow job for this annotation

GitHub Actions / Test [ Go 1.23 / Tags alltags ]

undefined: encryptError

Check failure on line 312 in jwe/jwe.go

View workflow job for this annotation

GitHub Actions / Smoke [ Go 1.21 / Tags goccy ]

undefined: encryptError

Check failure on line 312 in jwe/jwe.go

View workflow job for this annotation

GitHub Actions / Test [ Go 1.23 / Tags asmbase64 ]

undefined: encryptError

Check failure on line 312 in jwe/jwe.go

View workflow job for this annotation

GitHub Actions / Test [ Go 1.21 / Tags alltags ]

undefined: encryptError

Check failure on line 312 in jwe/jwe.go

View workflow job for this annotation

GitHub Actions / Smoke [ Go 1.22 / Tags alltags ]

undefined: encryptError

Check failure on line 312 in jwe/jwe.go

View workflow job for this annotation

GitHub Actions / Test [ Go 1.21 / Tags goccy ]

undefined: encryptError
}
return ret, nil
}

// encrypt is separate, so it can receive cek from outside.
Expand Down Expand Up @@ -330,7 +339,7 @@ func encrypt(payload, cek []byte, options ...EncryptOption) ([]byte, error) {
data := option.Value().(*withKey)
v, ok := data.alg.(jwa.KeyEncryptionAlgorithm)
if !ok {
return nil, fmt.Errorf(`jwe.Encrypt: expected alg to be jwa.KeyEncryptionAlgorithm, but got %T`, data.alg)
return nil, fmt.Errorf(`expected alg to be jwa.KeyEncryptionAlgorithm, but got %T`, data.alg)
}

switch v {
Expand All @@ -356,7 +365,7 @@ func encrypt(payload, cek []byte, options ...EncryptOption) ([]byte, error) {
} else {
merged, err := protected.Merge(v)
if err != nil {
return nil, fmt.Errorf(`jwe.Encrypt: failed to merge headers: %w`, err)
return nil, fmt.Errorf(`failed to merge headers: %w`, err)
}
protected = merged
}
Expand All @@ -368,30 +377,30 @@ func encrypt(payload, cek []byte, options ...EncryptOption) ([]byte, error) {
// We need to have at least one builder
switch l := len(builders); {
case l == 0:
return nil, fmt.Errorf(`jwe.Encrypt: missing key encryption builders: use jwe.WithKey() to specify one`)
return nil, fmt.Errorf(`missing key encryption builders: use jwe.WithKey() to specify one`)
case l > 1:
if format == fmtCompact {
return nil, fmt.Errorf(`jwe.Encrypt: cannot use compact serialization when multiple recipients exist (check the number of WithKey() argument, or use WithJSON())`)
return nil, fmt.Errorf(`cannot use compact serialization when multiple recipients exist (check the number of WithKey() argument, or use WithJSON())`)
}
}

if useRawCEK {
if len(builders) != 1 {
return nil, fmt.Errorf(`jwe.Encrypt: multiple recipients for ECDH-ES/DIRECT mode supported`)
return nil, fmt.Errorf(`multiple recipients for ECDH-ES/DIRECT mode supported`)
}
}

// There is exactly one content encrypter.
contentcrypt, err := content_crypt.NewGeneric(calg)
if err != nil {
return nil, fmt.Errorf(`jwe.Encrypt: failed to create AES encrypter: %w`, err)
return nil, fmt.Errorf(`failed to create AES encrypter: %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)
return nil, fmt.Errorf(`failed to generate key: %w`, err)
}
cek = bk.Bytes()
}
Expand All @@ -401,7 +410,7 @@ func encrypt(payload, cek []byte, options ...EncryptOption) ([]byte, error) {
// some builders require hint from the contentcrypt object
r, rawCEK, err := builder.Build(cek, calg, contentcrypt)
if err != nil {
return nil, fmt.Errorf(`jwe.Encrypt: failed to create recipient #%d: %w`, i, err)
return nil, fmt.Errorf(`failed to create recipient #%d: %w`, i, err)
}
recipients[i] = r

Expand All @@ -417,16 +426,16 @@ func encrypt(payload, cek []byte, options ...EncryptOption) ([]byte, error) {
}

if err := protected.Set(ContentEncryptionKey, calg); err != nil {
return nil, fmt.Errorf(`jwe.Encrypt: failed to set "enc" in protected header: %w`, err)
return nil, fmt.Errorf(`failed to set "enc" in protected header: %w`, err)
}

if compression != jwa.NoCompress() {
payload, err = compress(payload)
if err != nil {
return nil, fmt.Errorf(`jwe.Encrypt: failed to compress payload before encryption: %w`, err)
return nil, fmt.Errorf(`failed to compress payload before encryption: %w`, err)
}
if err := protected.Set(CompressionKey, compression); err != nil {
return nil, fmt.Errorf(`jwe.Encrypt: failed to set "zip" in protected header: %w`, err)
return nil, fmt.Errorf(`failed to set "zip" in protected header: %w`, err)
}
}

Expand All @@ -435,7 +444,7 @@ func encrypt(payload, cek []byte, options ...EncryptOption) ([]byte, error) {
if len(recipients) == 1 {
h, err := protected.Merge(recipients[0].Headers())
if err != nil {
return nil, fmt.Errorf(`jwe.Encrypt: failed to merge protected headers: %w`, err)
return nil, fmt.Errorf(`failed to merge protected headers: %w`, err)
}
protected = h
}
Expand Down Expand Up @@ -476,7 +485,7 @@ func encrypt(payload, cek []byte, options ...EncryptOption) ([]byte, error) {
case fmtJSONPretty:
return json.MarshalIndent(msg, "", " ")
default:
return nil, fmt.Errorf(`jwe.Encrypt: invalid serialization`)
return nil, fmt.Errorf(`invalid serialization`)
}
}

Expand Down Expand Up @@ -520,6 +529,14 @@ type decryptCtx struct {
// jwe.Settings(jwe.WithMaxDecompressBufferSize(10*1024*1024)) // changes value globally
// jwe.Decrypt(..., jwe.WithMaxDecompressBufferSize(250*1024)) // changes just for this call
func Decrypt(buf []byte, options ...DecryptOption) ([]byte, error) {
ret, err := decrypt(buf, options...)
if err != nil {
return nil, decryptError{fmt.Errorf(`jwe.Decrypt: %w`, err)}

Check failure on line 534 in jwe/jwe.go

View workflow job for this annotation

GitHub Actions / lint

undefined: decryptError

Check failure on line 534 in jwe/jwe.go

View workflow job for this annotation

GitHub Actions / Smoke [ Go 1.21 / Tags es256k ]

undefined: decryptError

Check failure on line 534 in jwe/jwe.go

View workflow job for this annotation

GitHub Actions / Smoke [ Go 1.21 / Tags stdlib ]

undefined: decryptError

Check failure on line 534 in jwe/jwe.go

View workflow job for this annotation

GitHub Actions / Smoke [ Go 1.22 / Tags stdlib ]

undefined: decryptError

Check failure on line 534 in jwe/jwe.go

View workflow job for this annotation

GitHub Actions / Test [ Go 1.22 / Tags asmbase64 ]

undefined: decryptError

Check failure on line 534 in jwe/jwe.go

View workflow job for this annotation

GitHub Actions / Smoke [ Go 1.22 / Tags goccy ]

undefined: decryptError

Check failure on line 534 in jwe/jwe.go

View workflow job for this annotation

GitHub Actions / Test [ Go 1.21 / Tags es256k ]

undefined: decryptError

Check failure on line 534 in jwe/jwe.go

View workflow job for this annotation

GitHub Actions / Smoke [ Go 1.22 / Tags es256k ]

undefined: decryptError

Check failure on line 534 in jwe/jwe.go

View workflow job for this annotation

GitHub Actions / Test [ Go 1.23 / Tags alltags ]

undefined: decryptError

Check failure on line 534 in jwe/jwe.go

View workflow job for this annotation

GitHub Actions / Smoke [ Go 1.21 / Tags goccy ]

undefined: decryptError

Check failure on line 534 in jwe/jwe.go

View workflow job for this annotation

GitHub Actions / Test [ Go 1.23 / Tags asmbase64 ]

undefined: decryptError

Check failure on line 534 in jwe/jwe.go

View workflow job for this annotation

GitHub Actions / Test [ Go 1.21 / Tags alltags ]

undefined: decryptError

Check failure on line 534 in jwe/jwe.go

View workflow job for this annotation

GitHub Actions / Smoke [ Go 1.22 / Tags alltags ]

undefined: decryptError

Check failure on line 534 in jwe/jwe.go

View workflow job for this annotation

GitHub Actions / Test [ Go 1.21 / Tags goccy ]

undefined: decryptError
}
return ret, nil
}

func decrypt(buf []byte, options ...DecryptOption) ([]byte, error) {
var keyProviders []KeyProvider
var keyUsed interface{}
var cek *[]byte
Expand Down Expand Up @@ -608,12 +625,13 @@ func Decrypt(buf []byte, options ...DecryptOption) ([]byte, error) {
dctx.cek = cek
dctx.maxDecompressBufferSize = perCallMaxDecompressBufferSize

var lastError error
ctx := context.TODO()

errs := make([]error, 0, len(recipients))
for _, recipient := range recipients {
decrypted, err := dctx.try(ctx, recipient, keyUsed)
if err != nil {
lastError = err
errs = append(errs, recipientError{err})

Check failure on line 634 in jwe/jwe.go

View workflow job for this annotation

GitHub Actions / lint

undefined: recipientError

Check failure on line 634 in jwe/jwe.go

View workflow job for this annotation

GitHub Actions / Smoke [ Go 1.21 / Tags es256k ]

undefined: recipientError

Check failure on line 634 in jwe/jwe.go

View workflow job for this annotation

GitHub Actions / Smoke [ Go 1.21 / Tags stdlib ]

undefined: recipientError

Check failure on line 634 in jwe/jwe.go

View workflow job for this annotation

GitHub Actions / Smoke [ Go 1.22 / Tags stdlib ]

undefined: recipientError

Check failure on line 634 in jwe/jwe.go

View workflow job for this annotation

GitHub Actions / Test [ Go 1.22 / Tags asmbase64 ]

undefined: recipientError

Check failure on line 634 in jwe/jwe.go

View workflow job for this annotation

GitHub Actions / Smoke [ Go 1.22 / Tags goccy ]

undefined: recipientError

Check failure on line 634 in jwe/jwe.go

View workflow job for this annotation

GitHub Actions / Test [ Go 1.21 / Tags es256k ]

undefined: recipientError

Check failure on line 634 in jwe/jwe.go

View workflow job for this annotation

GitHub Actions / Smoke [ Go 1.22 / Tags es256k ]

undefined: recipientError

Check failure on line 634 in jwe/jwe.go

View workflow job for this annotation

GitHub Actions / Test [ Go 1.23 / Tags alltags ]

undefined: recipientError

Check failure on line 634 in jwe/jwe.go

View workflow job for this annotation

GitHub Actions / Smoke [ Go 1.21 / Tags goccy ]

undefined: recipientError

Check failure on line 634 in jwe/jwe.go

View workflow job for this annotation

GitHub Actions / Test [ Go 1.23 / Tags asmbase64 ]

undefined: recipientError

Check failure on line 634 in jwe/jwe.go

View workflow job for this annotation

GitHub Actions / Test [ Go 1.21 / Tags alltags ]

undefined: recipientError

Check failure on line 634 in jwe/jwe.go

View workflow job for this annotation

GitHub Actions / Smoke [ Go 1.22 / Tags alltags ]

undefined: recipientError

Check failure on line 634 in jwe/jwe.go

View workflow job for this annotation

GitHub Actions / Test [ Go 1.21 / Tags goccy ]

undefined: recipientError
continue
}
if dst != nil {
Expand All @@ -623,7 +641,7 @@ func Decrypt(buf []byte, options ...DecryptOption) ([]byte, error) {
}
return decrypted, nil
}
return nil, fmt.Errorf(`jwe.Decrypt: failed to decrypt any of the recipients (last error = %w)`, lastError)
return nil, fmt.Errorf(`failed to decrypt any of the recipients: %w`, errors.Join(errs...))
}

func (dctx *decryptCtx) try(ctx context.Context, recipient Recipient, keyUsed interface{}) ([]byte, error) {
Expand Down Expand Up @@ -812,30 +830,48 @@ func Parse(buf []byte, _ ...ParseOption) (*Message, error) {
return parseJSONOrCompact(buf, false)
}

// errors are wrapped within this function, because we call it directly
// from Decrypt as well.
func parseJSONOrCompact(buf []byte, storeProtectedHeaders bool) (*Message, error) {
buf = bytes.TrimSpace(buf)
if len(buf) == 0 {
return nil, fmt.Errorf(`empty buffer`)
return nil, parseError{fmt.Errorf(`jwe.Parse: empty buffer`)}

Check failure on line 838 in jwe/jwe.go

View workflow job for this annotation

GitHub Actions / lint

undefined: parseError

Check failure on line 838 in jwe/jwe.go

View workflow job for this annotation

GitHub Actions / Smoke [ Go 1.21 / Tags es256k ]

undefined: parseError

Check failure on line 838 in jwe/jwe.go

View workflow job for this annotation

GitHub Actions / Smoke [ Go 1.21 / Tags stdlib ]

undefined: parseError

Check failure on line 838 in jwe/jwe.go

View workflow job for this annotation

GitHub Actions / Smoke [ Go 1.22 / Tags stdlib ]

undefined: parseError

Check failure on line 838 in jwe/jwe.go

View workflow job for this annotation

GitHub Actions / Test [ Go 1.22 / Tags asmbase64 ]

undefined: parseError

Check failure on line 838 in jwe/jwe.go

View workflow job for this annotation

GitHub Actions / Smoke [ Go 1.22 / Tags goccy ]

undefined: parseError

Check failure on line 838 in jwe/jwe.go

View workflow job for this annotation

GitHub Actions / Test [ Go 1.21 / Tags es256k ]

undefined: parseError

Check failure on line 838 in jwe/jwe.go

View workflow job for this annotation

GitHub Actions / Smoke [ Go 1.22 / Tags es256k ]

undefined: parseError

Check failure on line 838 in jwe/jwe.go

View workflow job for this annotation

GitHub Actions / Test [ Go 1.23 / Tags alltags ]

undefined: parseError

Check failure on line 838 in jwe/jwe.go

View workflow job for this annotation

GitHub Actions / Smoke [ Go 1.21 / Tags goccy ]

undefined: parseError

Check failure on line 838 in jwe/jwe.go

View workflow job for this annotation

GitHub Actions / Test [ Go 1.23 / Tags asmbase64 ]

undefined: parseError

Check failure on line 838 in jwe/jwe.go

View workflow job for this annotation

GitHub Actions / Test [ Go 1.21 / Tags alltags ]

undefined: parseError

Check failure on line 838 in jwe/jwe.go

View workflow job for this annotation

GitHub Actions / Smoke [ Go 1.22 / Tags alltags ]

undefined: parseError

Check failure on line 838 in jwe/jwe.go

View workflow job for this annotation

GitHub Actions / Test [ Go 1.21 / Tags goccy ]

undefined: parseError
}

var msg *Message
var err error
if buf[0] == '{' {
return parseJSON(buf, storeProtectedHeaders)
msg, err = parseJSON(buf, storeProtectedHeaders)
} else {
msg, err = parseCompact(buf, storeProtectedHeaders)
}

if err != nil {
return nil, parseError{fmt.Errorf(`jwe.Parse: %w`, err)}

Check failure on line 850 in jwe/jwe.go

View workflow job for this annotation

GitHub Actions / lint

undefined: parseError

Check failure on line 850 in jwe/jwe.go

View workflow job for this annotation

GitHub Actions / Smoke [ Go 1.21 / Tags es256k ]

undefined: parseError

Check failure on line 850 in jwe/jwe.go

View workflow job for this annotation

GitHub Actions / Smoke [ Go 1.21 / Tags stdlib ]

undefined: parseError

Check failure on line 850 in jwe/jwe.go

View workflow job for this annotation

GitHub Actions / Smoke [ Go 1.22 / Tags stdlib ]

undefined: parseError

Check failure on line 850 in jwe/jwe.go

View workflow job for this annotation

GitHub Actions / Test [ Go 1.22 / Tags asmbase64 ]

undefined: parseError

Check failure on line 850 in jwe/jwe.go

View workflow job for this annotation

GitHub Actions / Smoke [ Go 1.22 / Tags goccy ]

undefined: parseError

Check failure on line 850 in jwe/jwe.go

View workflow job for this annotation

GitHub Actions / Test [ Go 1.21 / Tags es256k ]

undefined: parseError

Check failure on line 850 in jwe/jwe.go

View workflow job for this annotation

GitHub Actions / Smoke [ Go 1.22 / Tags es256k ]

undefined: parseError

Check failure on line 850 in jwe/jwe.go

View workflow job for this annotation

GitHub Actions / Test [ Go 1.23 / Tags alltags ]

undefined: parseError

Check failure on line 850 in jwe/jwe.go

View workflow job for this annotation

GitHub Actions / Test [ Go 1.23 / Tags asmbase64 ]

undefined: parseError

Check failure on line 850 in jwe/jwe.go

View workflow job for this annotation

GitHub Actions / Smoke [ Go 1.21 / Tags goccy ]

undefined: parseError

Check failure on line 850 in jwe/jwe.go

View workflow job for this annotation

GitHub Actions / Test [ Go 1.21 / Tags alltags ]

undefined: parseError

Check failure on line 850 in jwe/jwe.go

View workflow job for this annotation

GitHub Actions / Smoke [ Go 1.22 / Tags alltags ]

undefined: parseError

Check failure on line 850 in jwe/jwe.go

View workflow job for this annotation

GitHub Actions / Test [ Go 1.21 / Tags goccy ]

undefined: parseError
}
return parseCompact(buf, storeProtectedHeaders)
return msg, nil
}

// ParseString is the same as Parse, but takes a string.
func ParseString(s string) (*Message, error) {
return Parse([]byte(s))
msg, err := Parse([]byte(s))
if err != nil {
return nil, parseError{fmt.Errorf(`jwe.ParseString: %w`, err)}

Check failure on line 859 in jwe/jwe.go

View workflow job for this annotation

GitHub Actions / lint

undefined: parseError

Check failure on line 859 in jwe/jwe.go

View workflow job for this annotation

GitHub Actions / Smoke [ Go 1.21 / Tags es256k ]

undefined: parseError

Check failure on line 859 in jwe/jwe.go

View workflow job for this annotation

GitHub Actions / Smoke [ Go 1.21 / Tags stdlib ]

undefined: parseError

Check failure on line 859 in jwe/jwe.go

View workflow job for this annotation

GitHub Actions / Smoke [ Go 1.22 / Tags stdlib ]

undefined: parseError

Check failure on line 859 in jwe/jwe.go

View workflow job for this annotation

GitHub Actions / Test [ Go 1.22 / Tags asmbase64 ]

undefined: parseError

Check failure on line 859 in jwe/jwe.go

View workflow job for this annotation

GitHub Actions / Smoke [ Go 1.22 / Tags goccy ]

undefined: parseError

Check failure on line 859 in jwe/jwe.go

View workflow job for this annotation

GitHub Actions / Test [ Go 1.21 / Tags es256k ]

undefined: parseError

Check failure on line 859 in jwe/jwe.go

View workflow job for this annotation

GitHub Actions / Smoke [ Go 1.22 / Tags es256k ]

undefined: parseError

Check failure on line 859 in jwe/jwe.go

View workflow job for this annotation

GitHub Actions / Test [ Go 1.23 / Tags alltags ]

undefined: parseError

Check failure on line 859 in jwe/jwe.go

View workflow job for this annotation

GitHub Actions / Test [ Go 1.23 / Tags asmbase64 ]

undefined: parseError

Check failure on line 859 in jwe/jwe.go

View workflow job for this annotation

GitHub Actions / Smoke [ Go 1.21 / Tags goccy ]

undefined: parseError

Check failure on line 859 in jwe/jwe.go

View workflow job for this annotation

GitHub Actions / Test [ Go 1.21 / Tags alltags ]

undefined: parseError

Check failure on line 859 in jwe/jwe.go

View workflow job for this annotation

GitHub Actions / Smoke [ Go 1.22 / Tags alltags ]

undefined: parseError

Check failure on line 859 in jwe/jwe.go

View workflow job for this annotation

GitHub Actions / Test [ Go 1.21 / Tags goccy ]

undefined: parseError
}
return msg, nil
}

// ParseReader is the same as Parse, but takes an io.Reader.
func ParseReader(src io.Reader) (*Message, error) {
buf, err := io.ReadAll(src)
if err != nil {
return nil, fmt.Errorf(`failed to read from io.Reader: %w`, err)
return nil, parseError{fmt.Errorf(`jwe.ParseReader: failed to read from io.Reader: %w`, err)}

Check failure on line 868 in jwe/jwe.go

View workflow job for this annotation

GitHub Actions / lint

undefined: parseError

Check failure on line 868 in jwe/jwe.go

View workflow job for this annotation

GitHub Actions / Smoke [ Go 1.21 / Tags es256k ]

undefined: parseError

Check failure on line 868 in jwe/jwe.go

View workflow job for this annotation

GitHub Actions / Smoke [ Go 1.21 / Tags stdlib ]

undefined: parseError

Check failure on line 868 in jwe/jwe.go

View workflow job for this annotation

GitHub Actions / Smoke [ Go 1.22 / Tags stdlib ]

undefined: parseError

Check failure on line 868 in jwe/jwe.go

View workflow job for this annotation

GitHub Actions / Test [ Go 1.22 / Tags asmbase64 ]

undefined: parseError

Check failure on line 868 in jwe/jwe.go

View workflow job for this annotation

GitHub Actions / Smoke [ Go 1.22 / Tags goccy ]

undefined: parseError

Check failure on line 868 in jwe/jwe.go

View workflow job for this annotation

GitHub Actions / Test [ Go 1.21 / Tags es256k ]

undefined: parseError

Check failure on line 868 in jwe/jwe.go

View workflow job for this annotation

GitHub Actions / Smoke [ Go 1.22 / Tags es256k ]

undefined: parseError

Check failure on line 868 in jwe/jwe.go

View workflow job for this annotation

GitHub Actions / Test [ Go 1.23 / Tags alltags ]

undefined: parseError

Check failure on line 868 in jwe/jwe.go

View workflow job for this annotation

GitHub Actions / Test [ Go 1.23 / Tags asmbase64 ]

undefined: parseError

Check failure on line 868 in jwe/jwe.go

View workflow job for this annotation

GitHub Actions / Smoke [ Go 1.21 / Tags goccy ]

undefined: parseError

Check failure on line 868 in jwe/jwe.go

View workflow job for this annotation

GitHub Actions / Test [ Go 1.21 / Tags alltags ]

undefined: parseError

Check failure on line 868 in jwe/jwe.go

View workflow job for this annotation

GitHub Actions / Smoke [ Go 1.22 / Tags alltags ]

undefined: parseError

Check failure on line 868 in jwe/jwe.go

View workflow job for this annotation

GitHub Actions / Test [ Go 1.21 / Tags goccy ]

undefined: parseError
}
msg, err := Parse(buf)
if err != nil {
return nil, parseError{fmt.Errorf(`jwe.ParseReader: %w`, err)}

Check failure on line 872 in jwe/jwe.go

View workflow job for this annotation

GitHub Actions / Smoke [ Go 1.21 / Tags es256k ]

undefined: parseError

Check failure on line 872 in jwe/jwe.go

View workflow job for this annotation

GitHub Actions / Smoke [ Go 1.21 / Tags stdlib ]

undefined: parseError

Check failure on line 872 in jwe/jwe.go

View workflow job for this annotation

GitHub Actions / Smoke [ Go 1.22 / Tags stdlib ]

undefined: parseError

Check failure on line 872 in jwe/jwe.go

View workflow job for this annotation

GitHub Actions / Test [ Go 1.22 / Tags asmbase64 ]

undefined: parseError

Check failure on line 872 in jwe/jwe.go

View workflow job for this annotation

GitHub Actions / Smoke [ Go 1.22 / Tags goccy ]

undefined: parseError

Check failure on line 872 in jwe/jwe.go

View workflow job for this annotation

GitHub Actions / Test [ Go 1.21 / Tags es256k ]

undefined: parseError

Check failure on line 872 in jwe/jwe.go

View workflow job for this annotation

GitHub Actions / Smoke [ Go 1.22 / Tags es256k ]

undefined: parseError

Check failure on line 872 in jwe/jwe.go

View workflow job for this annotation

GitHub Actions / Test [ Go 1.23 / Tags alltags ]

undefined: parseError

Check failure on line 872 in jwe/jwe.go

View workflow job for this annotation

GitHub Actions / Test [ Go 1.23 / Tags asmbase64 ]

undefined: parseError

Check failure on line 872 in jwe/jwe.go

View workflow job for this annotation

GitHub Actions / Smoke [ Go 1.21 / Tags goccy ]

undefined: parseError

Check failure on line 872 in jwe/jwe.go

View workflow job for this annotation

GitHub Actions / Test [ Go 1.21 / Tags alltags ]

undefined: parseError

Check failure on line 872 in jwe/jwe.go

View workflow job for this annotation

GitHub Actions / Smoke [ Go 1.22 / Tags alltags ]

undefined: parseError

Check failure on line 872 in jwe/jwe.go

View workflow job for this annotation

GitHub Actions / Test [ Go 1.21 / Tags goccy ]

undefined: parseError
}
return Parse(buf)
return msg, nil
}

func parseJSON(buf []byte, storeProtectedHeaders bool) (*Message, error) {
Expand Down
43 changes: 43 additions & 0 deletions jwe/jwe_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -903,3 +903,46 @@ func TestMaxDecompressBufferSize(t *testing.T) {
})
}
}

func TestEncrypt_fail(t *testing.T) {
_, err := jwe.Encrypt([]byte("Lorem Ipsum"), jwe.WithKey(jwa.RSA_OAEP(), nil))
require.Error(t, err, `jwe.Encrypt should fail`)
require.ErrorIs(t, err, jwe.EncryptError(), `error should be of type jwe.EncryptError`)
}

func TestDecrypt_fail(t *testing.T) {
t.Run("no key", func(t *testing.T) {
_, err := jwe.Decrypt([]byte("Lorem Ipsum"), jwe.WithKey(jwa.RSA_OAEP(), nil))
require.Error(t, err, `jwe.Decrypt should fail`)
require.ErrorIs(t, err, jwe.DecryptError(), `error should be of type jwe.DecryptError`)
require.NotErrorIs(t, err, jwe.RecipientError(), `error should NOT be of type jwe.RecipientError`)
})
t.Run("wrong key", func(t *testing.T) {
privkey, err := jwxtest.GenerateRsaJwk()
require.NoError(t, err, `jwxtest.GenerateRsaJwk should succeed`)

encrypted, err := jwe.Encrypt([]byte("Lorem Ipsum"), jwe.WithKey(jwa.RSA_OAEP(), privkey))
require.NoError(t, err, `jwe.Encrypt should succeed`)

wrongPrivkey, err := jwxtest.GenerateRsaJwk()
require.NoError(t, err, `jwxtest.GenerateRsaJwk should succeed`)

_, err = jwe.Decrypt(encrypted, jwe.WithKey(jwa.RSA_OAEP(), wrongPrivkey))
require.Error(t, err, `jwe.Decrypt should fail`)
require.ErrorIs(t, err, jwe.DecryptError(), `error should be of type jwe.DecryptError`)
require.ErrorIs(t, err, jwe.RecipientError(), `error should be of type jwe.RecipientError`)
})
t.Run("malformed JSON", func(t *testing.T) {
privkey, err := jwxtest.GenerateRsaJwk()
require.NoError(t, err, `jwxtest.GenerateRsaJwk should succeed`)

encrypted, err := jwe.Encrypt([]byte("Lorem Ipsum"), jwe.WithKey(jwa.RSA_OAEP(), privkey))
require.NoError(t, err, `jwe.Encrypt should succeed`)

encrypted = encrypted[1:]
_, err = jwe.Decrypt(encrypted, jwe.WithKey(jwa.RSA_OAEP(), privkey))
require.Error(t, err, `jwe.Decrypt should fail`)
require.ErrorIs(t, err, jwe.DecryptError(), `error should be of type jwe.DecryptError`)
require.ErrorIs(t, err, jwe.ParseError(), `error should be of type jwe.ParseError`)
})
}

0 comments on commit 946f055

Please sign in to comment.