Skip to content

Commit

Permalink
DecryptMulti: handle decompression error (#19)
Browse files Browse the repository at this point in the history
In 7d3b437, a lint was fixed in this function: `err` was ineffectually
assigned to. However, the fix should have been to handle the error
rather than to ignore it with `_`.
  • Loading branch information
jsha committed Nov 17, 2023
1 parent ca9011b commit 053c9bf
Show file tree
Hide file tree
Showing 2 changed files with 56 additions and 2 deletions.
10 changes: 8 additions & 2 deletions crypter.go
Expand Up @@ -496,9 +496,12 @@ func (obj JSONWebEncryption) Decrypt(decryptionKey interface{}) ([]byte, error)
// The "zip" header parameter may only be present in the protected header.
if comp := obj.protected.getCompression(); comp != "" {
plaintext, err = decompress(comp, plaintext)
if err != nil {
return nil, fmt.Errorf("go-jose/go-jose: failed to decompress plaintext: %v", err)
}
}

return plaintext, err
return plaintext, nil
}

// DecryptMulti decrypts and validates the object and returns the plaintexts,
Expand Down Expand Up @@ -569,7 +572,10 @@ func (obj JSONWebEncryption) DecryptMulti(decryptionKey interface{}) (int, Heade

// The "zip" header parameter may only be present in the protected header.
if comp := obj.protected.getCompression(); comp != "" {
plaintext, _ = decompress(comp, plaintext)
plaintext, err = decompress(comp, plaintext)
if err != nil {
return -1, Header{}, nil, fmt.Errorf("go-jose/go-jose: failed to decompress plaintext: %v", err)
}
}

sanitized, err := headers.sanitized()
Expand Down
48 changes: 48 additions & 0 deletions crypter_test.go
Expand Up @@ -23,11 +23,13 @@ import (
"crypto/elliptic"
"crypto/rand"
"crypto/rsa"
"encoding/hex"
"fmt"
"io"
"math/big"
"reflect"
"regexp"
"strings"
"testing"
)

Expand All @@ -40,6 +42,52 @@ var ecTestKey521, _ = ecdsa.GenerateKey(elliptic.P521(), rand.Reader)

var ed25519PublicKey, ed25519PrivateKey, _ = ed25519.GenerateKey(rand.Reader)

func TestCompressionError(t *testing.T) {
testKey, _ := hex.DecodeString("0c5433f844097b2e910db9b3638ff824")

// // This code was used to provide the test vector `jweBytes` below,
// // by running with a local modification of crypter.go to set "zip" to "DEF"
// // in the protected header, but not actually compress the payload.
// keyAlg := A128KW
// encAlg := A128GCM
// rcpt := Recipient{Algorithm: keyAlg, Key: testKey}
// enc, err := NewEncrypter(encAlg, rcpt, &EncrypterOptions{Compression: DEFLATE})
// if err != nil {
// t.Fatal(err)
// }
// jwe, err := enc.Encrypt([]byte("Lorem ipsum dolor sit amet"))
// if err != nil {
// t.Fatal(err)
// }
// t.Logf(jwe.FullSerialize())

jweBytes := `{
"protected":"eyJhbGciOiJBMTI4S1ciLCJlbmMiOiJBMTI4R0NNIiwiemlwIjoiREVGIn0",
"encrypted_key":"0ZJRSSVctBhIpWvT9Ke2Z-KvSby-kjmi",
"iv":"4nuUbYF0BR0KPz1v",
"ciphertext":"luLq8QTsJEXbZdRvEzIiHWEitTZTORZqXIk",
"tag":"S1j6wvSGtTUCXhED91lUGQ"
}`
jwe, err := ParseEncrypted(jweBytes)
if err != nil {
t.Fatal(err)
}
_, err = jwe.Decrypt(testKey)
if err == nil {
t.Fatal("expected error on decompression failure")
}
if !strings.Contains(err.Error(), "failed to decompress plaintext: flate: corrupt input") {
t.Errorf("expected flate error, got %s", err)
}
_, _, _, err = jwe.DecryptMulti(testKey)
if err == nil {
t.Fatal("expected error on decompression failure")
}
if !strings.Contains(err.Error(), "failed to decompress plaintext: flate: corrupt input") {
t.Errorf("expected flate error, got %s", err)
}
}

func RoundtripJWE(keyAlg KeyAlgorithm, encAlg ContentEncryption, compressionAlg CompressionAlgorithm, serializer func(*JSONWebEncryption) (string, error), corrupter func(*JSONWebEncryption) bool, aad []byte, encryptionKey interface{}, decryptionKey interface{}) error {
var rcpt Recipient
switch keyAlg {
Expand Down

0 comments on commit 053c9bf

Please sign in to comment.