diff options
Diffstat (limited to 'pkg/integrity/clearsign_test.go')
-rw-r--r-- | pkg/integrity/clearsign_test.go | 158 |
1 files changed, 95 insertions, 63 deletions
diff --git a/pkg/integrity/clearsign_test.go b/pkg/integrity/clearsign_test.go index 6620884..1131424 100644 --- a/pkg/integrity/clearsign_test.go +++ b/pkg/integrity/clearsign_test.go @@ -1,4 +1,4 @@ -// Copyright (c) 2020-2021, Sylabs Inc. All rights reserved. +// Copyright (c) 2020-2022, Sylabs Inc. All rights reserved. // This software is licensed under a 3-clause BSD license. Please consult the LICENSE.md file // distributed with the sources of this project regarding your rights to use or distribute this // software. @@ -21,31 +21,31 @@ import ( "github.com/sebdah/goldie/v2" ) -type testType struct { - One int - Two int -} +var testMessage = `{"One":1,"Two":2} +` -func TestSignAndEncodeJSON(t *testing.T) { +func Test_clearsignEncoder_signMessage(t *testing.T) { e := getTestEntity(t) - // Fake an encrypted key. - encryptedKey := *e.PrivateKey - encryptedKey.Encrypted = true + encrypted := getTestEntity(t) + encrypted.PrivateKey.Encrypted = true tests := []struct { - name string - key *packet.PrivateKey - hash crypto.Hash - wantErr bool + name string + en *clearsignEncoder + wantErr bool + wantHash crypto.Hash }{ - {name: "EncryptedKey", key: &encryptedKey, wantErr: true}, - {name: "DefaultHash", key: e.PrivateKey}, - {name: "SHA1", key: e.PrivateKey, hash: crypto.SHA1}, - {name: "SHA224", key: e.PrivateKey, hash: crypto.SHA224}, - {name: "SHA256", key: e.PrivateKey, hash: crypto.SHA256}, - {name: "SHA384", key: e.PrivateKey, hash: crypto.SHA384}, - {name: "SHA512", key: e.PrivateKey, hash: crypto.SHA512}, + { + name: "EncryptedKey", + en: newClearsignEncoder(encrypted, fixedTime), + wantErr: true, + }, + { + name: "OK", + en: newClearsignEncoder(e, fixedTime), + wantHash: crypto.SHA256, + }, } for _, tt := range tests { @@ -53,17 +53,16 @@ func TestSignAndEncodeJSON(t *testing.T) { t.Run(tt.name, func(t *testing.T) { b := bytes.Buffer{} - config := packet.Config{ - DefaultHash: tt.hash, - Time: fixedTime, - } - - err := signAndEncodeJSON(&b, testType{1, 2}, tt.key, &config) + ht, err := tt.en.signMessage(&b, strings.NewReader(testMessage)) if got, want := err, tt.wantErr; (got != nil) != want { t.Fatalf("got error %v, wantErr %v", got, want) } if err == nil { + if got, want := ht, tt.wantHash; got != want { + t.Errorf("got hash %v, want %v", got, want) + } + g := goldie.New(t, goldie.WithTestNameForDir(true)) g.Assert(t, tt.name, b.Bytes()) } @@ -71,11 +70,9 @@ func TestSignAndEncodeJSON(t *testing.T) { } } -func TestVerifyAndDecodeJSON(t *testing.T) { +func Test_clearsignDecoder_verifyMessage(t *testing.T) { e := getTestEntity(t) - testValue := testType{1, 2} - // This is used to corrupt the plaintext. corruptClearsign := func(w io.Writer, s string) error { _, err := strings.NewReplacer(`{"One":1,"Two":2}`, `{"One":2,"Two":4}`).WriteString(w, s) @@ -110,22 +107,63 @@ func TestVerifyAndDecodeJSON(t *testing.T) { tests := []struct { name string hash crypto.Hash - el openpgp.EntityList corrupter func(w io.Writer, s string) error - output interface{} + de *clearsignDecoder wantErr error wantEntity *openpgp.Entity }{ - {name: "ErrUnknownIssuer", el: openpgp.EntityList{}, wantErr: pgperrors.ErrUnknownIssuer}, - {name: "CorruptedClearsign", el: openpgp.EntityList{e}, corrupter: corruptClearsign}, - {name: "CorruptedSignature", el: openpgp.EntityList{e}, corrupter: corruptSignature}, - {name: "VerifyOnly", el: openpgp.EntityList{e}, wantEntity: e}, - {name: "DefaultHash", el: openpgp.EntityList{e}, output: &testType{}, wantEntity: e}, - {name: "SHA1", hash: crypto.SHA1, el: openpgp.EntityList{e}, output: &testType{}, wantEntity: e}, - {name: "SHA224", hash: crypto.SHA224, el: openpgp.EntityList{e}, output: &testType{}, wantEntity: e}, - {name: "SHA256", hash: crypto.SHA256, el: openpgp.EntityList{e}, output: &testType{}, wantEntity: e}, - {name: "SHA384", hash: crypto.SHA384, el: openpgp.EntityList{e}, output: &testType{}, wantEntity: e}, - {name: "SHA512", hash: crypto.SHA512, el: openpgp.EntityList{e}, output: &testType{}, wantEntity: e}, + { + name: "UnknownIssuer", + de: newClearsignDecoder(openpgp.EntityList{}), + wantErr: pgperrors.ErrUnknownIssuer, + }, + { + name: "CorruptedClearsign", + corrupter: corruptClearsign, + de: newClearsignDecoder(openpgp.EntityList{e}), + wantErr: pgperrors.SignatureError("hash tag doesn't match"), + }, + { + name: "CorruptedSignature", + corrupter: corruptSignature, + de: newClearsignDecoder(openpgp.EntityList{e}), + wantErr: pgperrors.StructuralError("signature subpacket truncated"), + }, + { + name: "DefaultHash", + de: newClearsignDecoder(openpgp.EntityList{e}), + wantEntity: e, + }, + { + name: "SHA1", + hash: crypto.SHA1, + de: newClearsignDecoder(openpgp.EntityList{e}), + wantErr: pgperrors.StructuralError("hash algorithm mismatch with cleartext message headers"), + }, + { + name: "SHA224", + hash: crypto.SHA224, + de: newClearsignDecoder(openpgp.EntityList{e}), + wantEntity: e, + }, + { + name: "SHA256", + hash: crypto.SHA256, + de: newClearsignDecoder(openpgp.EntityList{e}), + wantEntity: e, + }, + { + name: "SHA384", + hash: crypto.SHA384, + de: newClearsignDecoder(openpgp.EntityList{e}), + wantEntity: e, + }, + { + name: "SHA512", + hash: crypto.SHA512, + de: newClearsignDecoder(openpgp.EntityList{e}), + wantEntity: e, + }, } for _, tt := range tests { @@ -133,10 +171,15 @@ func TestVerifyAndDecodeJSON(t *testing.T) { t.Run(tt.name, func(t *testing.T) { b := bytes.Buffer{} - config := packet.Config{ - DefaultHash: tt.hash, + // Sign and encode message. + en := clearsignEncoder{ + e: e, + config: &packet.Config{ + DefaultHash: tt.hash, + Time: fixedTime, + }, } - err := signAndEncodeJSON(&b, testValue, e.PrivateKey, &config) + h, err := en.signMessage(&b, strings.NewReader(testMessage)) if err != nil { t.Fatal(err) } @@ -150,31 +193,20 @@ func TestVerifyAndDecodeJSON(t *testing.T) { } } - // Verify and decode. - e, rest, err := verifyAndDecodeJSON(b.Bytes(), tt.output, tt.el) - - // Shouldn't be any trailing bytes. - if n := len(rest); n != 0 { - t.Errorf("%v trailing bytes", n) - } + // Decode and verify message. + var vr VerifyResult + message, err := tt.de.verifyMessage(bytes.NewReader(b.Bytes()), h, &vr) - // Verify the error (if any) is appropriate. - if tt.corrupter == nil { - if got, want := err, tt.wantErr; !errors.Is(got, want) { - t.Fatalf("got error %v, want %v", got, want) - } - } else if err == nil { - t.Errorf("got nil error despite corruption") + if got, want := err, tt.wantErr; !errors.Is(got, want) { + t.Fatalf("got error %v, want %v", got, want) } if err == nil { - if tt.output != nil { - if got, want := tt.output, &testValue; !reflect.DeepEqual(got, want) { - t.Errorf("got value %v, want %v", got, want) - } + if got, want := string(message), testMessage; got != want { + t.Errorf("got message %v, want %v", got, want) } - if got, want := e, tt.wantEntity; !reflect.DeepEqual(got, want) { + if got, want := vr.e, tt.wantEntity; !reflect.DeepEqual(got, want) { t.Errorf("got entity %+v, want %+v", got, want) } } |