Skip to content

Commit 071c3a8

Browse files
committed
fix: corpus image generation
Add OptSignWithoutPGPSignatureSalt, which disables randomization of signature generation, and use that in the corpus to generate images deterministically. Update corpus images and related golden files to reflect the signatures generated by the new version of go-crypto.
1 parent 869cab3 commit 071c3a8

File tree

13 files changed

+62
-35
lines changed

13 files changed

+62
-35
lines changed

internal/app/siftool/testdata/TestApp_Info/DataSignature.golden

+1-1
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,6 @@
33
Group ID: NONE
44
Linked ID: 1 (G)
55
Offset: 303104
6-
Size: 1054
6+
Size: 1048
77
Hash Type: SHA-256
88
Entity: 12045C8C0B1004D058DE4BEDA20C27EE7FF7BA84

internal/app/siftool/testdata/TestApp_List/OneGroupSignedPGP.golden

+1-1
Original file line numberDiff line numberDiff line change
@@ -3,4 +3,4 @@ ID |GROUP |LINK |SIF POSITION (start-end) |TYPE
33
------------------------------------------------------------------------------
44
1 |1 |NONE |32768-32772 |FS (Raw/System/386)
55
2 |1 |NONE |36864-40960 |FS (Squashfs/*System/386)
6-
3 |NONE |1 (G) |40960-42014 |Signature (SHA-256)
6+
3 |NONE |1 (G) |40960-42008 |Signature (SHA-256)

internal/app/siftool/testdata/TestApp_List/TwoGroupsSignedPGP.golden

+2-2
Original file line numberDiff line numberDiff line change
@@ -4,5 +4,5 @@ ID |GROUP |LINK |SIF POSITION (start-end) |TYPE
44
1 |1 |NONE |32768-32772 |FS (Raw/System/386)
55
2 |1 |NONE |36864-40960 |FS (Squashfs/*System/386)
66
3 |2 |NONE |40960-303104 |FS (Ext3/System/amd64)
7-
4 |NONE |1 (G) |303104-304158 |Signature (SHA-256)
8-
5 |NONE |2 (G) |304158-305013 |Signature (SHA-256)
7+
4 |NONE |1 (G) |303104-304152 |Signature (SHA-256)
8+
5 |NONE |2 (G) |304152-305001 |Signature (SHA-256)

pkg/integrity/clearsign.go

+6-9
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// Copyright (c) 2020-2023, Sylabs Inc. All rights reserved.
1+
// Copyright (c) 2020-2024, Sylabs Inc. All rights reserved.
22
// This software is licensed under a 3-clause BSD license. Please consult the LICENSE.md file
33
// distributed with the sources of this project regarding your rights to use or distribute this
44
// software.
@@ -11,7 +11,6 @@ import (
1111
"crypto"
1212
"errors"
1313
"io"
14-
"time"
1514

1615
"github.com/ProtonMail/go-crypto/openpgp"
1716
"github.com/ProtonMail/go-crypto/openpgp/clearsign"
@@ -25,14 +24,12 @@ type clearsignEncoder struct {
2524
config *packet.Config
2625
}
2726

28-
// newClearsignEncoder returns an encoder that signs messages in clear-sign format using entity e.
29-
// If timeFunc is not nil, it is used to generate signature timestamps.
30-
func newClearsignEncoder(e *openpgp.Entity, timeFunc func() time.Time) *clearsignEncoder {
27+
// newClearsignEncoder returns an encoder that signs messages in clear-sign format using entity e,
28+
// according to config.
29+
func newClearsignEncoder(e *openpgp.Entity, config *packet.Config) *clearsignEncoder {
3130
return &clearsignEncoder{
32-
e: e,
33-
config: &packet.Config{
34-
Time: timeFunc,
35-
},
31+
e: e,
32+
config: config,
3633
}
3734
}
3835

pkg/integrity/clearsign_test.go

+2-2
Original file line numberDiff line numberDiff line change
@@ -39,12 +39,12 @@ func Test_clearsignEncoder_signMessage(t *testing.T) {
3939
}{
4040
{
4141
name: "EncryptedKey",
42-
en: newClearsignEncoder(encrypted, fixedTime),
42+
en: newClearsignEncoder(encrypted, &packet.Config{Time: fixedTime}),
4343
wantErr: true,
4444
},
4545
{
4646
name: "OK",
47-
en: newClearsignEncoder(e, fixedTime),
47+
en: newClearsignEncoder(e, &packet.Config{Time: fixedTime}),
4848
de: newClearsignDecoder(openpgp.EntityList{e}),
4949
wantHash: crypto.SHA256,
5050
},

pkg/integrity/sign.go

+23-12
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ import (
1717
"time"
1818

1919
"github.com/ProtonMail/go-crypto/openpgp"
20+
"github.com/ProtonMail/go-crypto/openpgp/packet"
2021
"github.com/sigstore/sigstore/pkg/signature"
2122
"github.com/sylabs/sif/v2/pkg/sif"
2223
)
@@ -179,13 +180,14 @@ func (gs *groupSigner) sign(ctx context.Context) (sif.DescriptorInput, error) {
179180
}
180181

181182
type signOpts struct {
182-
ss []signature.Signer
183-
e *openpgp.Entity
184-
groupIDs []uint32
185-
objectIDs [][]uint32
186-
timeFunc func() time.Time
187-
deterministic bool
188-
ctx context.Context //nolint:containedctx
183+
ss []signature.Signer
184+
e *openpgp.Entity
185+
groupIDs []uint32
186+
objectIDs [][]uint32
187+
timeFunc func() time.Time
188+
deterministic bool
189+
ctx context.Context //nolint:containedctx
190+
withoutPGPSignatureSalt bool
189191
}
190192

191193
// SignerOpt are used to configure so.
@@ -257,6 +259,16 @@ func OptSignWithContext(ctx context.Context) SignerOpt {
257259
}
258260
}
259261

262+
// OptSignWithoutPGPSignatureSalt disables the addition of a salt notation for v4 and v5 PGP keys.
263+
// While this increases determinism, it should be used with caution as the salt notation increases
264+
// protection for certain kinds of attacks.
265+
func OptSignWithoutPGPSignatureSalt() SignerOpt {
266+
return func(so *signOpts) error {
267+
so.withoutPGPSignatureSalt = true
268+
return nil
269+
}
270+
}
271+
260272
// withGroupedObjects splits the objects represented by ids into object groups, and calls fn once
261273
// per object group.
262274
func withGroupedObjects(f *sif.FileImage, ids []uint32, fn func(uint32, []uint32) error) error {
@@ -339,11 +351,10 @@ func NewSigner(f *sif.FileImage, opts ...SignerOpt) (*Signer, error) {
339351
case so.ss != nil:
340352
en = newDSSEEncoder(so.ss)
341353
case so.e != nil:
342-
timeFunc := time.Now
343-
if so.timeFunc != nil {
344-
timeFunc = so.timeFunc
345-
}
346-
en = newClearsignEncoder(so.e, timeFunc)
354+
en = newClearsignEncoder(so.e, &packet.Config{
355+
Time: so.timeFunc,
356+
NonDeterministicSignaturesViaNotation: packet.BoolPointer(!so.withoutPGPSignatureSalt),
357+
})
347358
commonOpts = append(commonOpts, optSignGroupFingerprint(so.e.PrimaryKey.Fingerprint))
348359
default:
349360
return nil, fmt.Errorf("integrity: %w", ErrNoKeyMaterial)

pkg/integrity/sign_test.go

+21-3
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ import (
1616
"testing"
1717

1818
"github.com/ProtonMail/go-crypto/openpgp"
19+
"github.com/ProtonMail/go-crypto/openpgp/packet"
1920
"github.com/sylabs/sif/v2/pkg/sif"
2021
)
2122

@@ -195,7 +196,7 @@ func TestNewGroupSigner(t *testing.T) {
195196

196197
for _, tt := range tests {
197198
t.Run(tt.name, func(t *testing.T) {
198-
en := newClearsignEncoder(getTestEntity(t), fixedTime)
199+
en := newClearsignEncoder(getTestEntity(t), &packet.Config{Time: fixedTime})
199200

200201
s, err := newGroupSigner(en, tt.fi, tt.groupID, tt.opts...)
201202
if got, want := err, tt.wantErr; !errors.Is(got, want) {
@@ -254,12 +255,12 @@ func TestGroupSigner_Sign(t *testing.T) {
254255
}
255256

256257
e := getTestEntity(t)
257-
clearsign := newClearsignEncoder(e, fixedTime)
258+
clearsign := newClearsignEncoder(e, &packet.Config{Time: fixedTime})
258259

259260
encrypted := getTestEntity(t)
260261
encrypted.PrivateKey.Encrypted = true
261262

262-
clearsignEncrypted := newClearsignEncoder(encrypted, fixedTime)
263+
clearsignEncrypted := newClearsignEncoder(encrypted, &packet.Config{Time: fixedTime})
263264

264265
tests := []struct {
265266
name string
@@ -449,6 +450,11 @@ func TestNewSigner(t *testing.T) {
449450
},
450451
wantErr: sif.ErrNoObjects,
451452
},
453+
{
454+
name: "NoKeyMaterial",
455+
fi: oneGroupImage,
456+
wantErr: ErrNoKeyMaterial,
457+
},
452458
{
453459
name: "InvalidObjectID",
454460
fi: oneGroupImage,
@@ -820,6 +826,18 @@ func TestSigner_Sign(t *testing.T) {
820826
OptVerifyWithKeyRing(openpgp.EntityList{e}),
821827
},
822828
},
829+
{
830+
name: "OptSignWithoutPGPSignatureSalt",
831+
inputFile: "one-group.sif",
832+
signOpts: []SignerOpt{
833+
OptSignWithEntity(e),
834+
OptSignWithTime(fixedTime),
835+
OptSignWithoutPGPSignatureSalt(),
836+
},
837+
verifyOpts: []VerifierOpt{
838+
OptVerifyWithKeyRing(openpgp.EntityList{e}),
839+
},
840+
},
823841
}
824842

825843
for _, tt := range tests {

pkg/siftool/testdata/Test_command_getInfo/Three/out.golden

+1-1
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,6 @@
33
Group ID: NONE
44
Linked ID: 1 (G)
55
Offset: 40960
6-
Size: 1054
6+
Size: 1048
77
Hash Type: SHA-256
88
Entity: 12045C8C0B1004D058DE4BEDA20C27EE7FF7BA84

pkg/siftool/testdata/Test_command_getList/OneGroupSignedPGP/out.golden

+1-1
Original file line numberDiff line numberDiff line change
@@ -3,4 +3,4 @@ ID |GROUP |LINK |SIF POSITION (start-end) |TYPE
33
------------------------------------------------------------------------------
44
1 |1 |NONE |32768-32772 |FS (Raw/System/386)
55
2 |1 |NONE |36864-40960 |FS (Squashfs/*System/386)
6-
3 |NONE |1 (G) |40960-42014 |Signature (SHA-256)
6+
3 |NONE |1 (G) |40960-42008 |Signature (SHA-256)

pkg/siftool/testdata/Test_command_getList/TwoGroupsSignedPGP/out.golden

+2-2
Original file line numberDiff line numberDiff line change
@@ -4,5 +4,5 @@ ID |GROUP |LINK |SIF POSITION (start-end) |TYPE
44
1 |1 |NONE |32768-32772 |FS (Raw/System/386)
55
2 |1 |NONE |36864-40960 |FS (Squashfs/*System/386)
66
3 |2 |NONE |40960-303104 |FS (Ext3/System/amd64)
7-
4 |NONE |1 (G) |303104-304158 |Signature (SHA-256)
8-
5 |NONE |2 (G) |304158-305013 |Signature (SHA-256)
7+
4 |NONE |1 (G) |303104-304152 |Signature (SHA-256)
8+
5 |NONE |2 (G) |304152-305001 |Signature (SHA-256)

test/images/gen_sifs.go

+2-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// Copyright (c) 2020-2023, Sylabs Inc. All rights reserved.
1+
// Copyright (c) 2020-2024, Sylabs Inc. All rights reserved.
22
// This software is licensed under a 3-clause BSD license. Please consult the LICENSE.md file
33
// distributed with the sources of this project regarding your rights to use or distribute this
44
// software.
@@ -294,6 +294,7 @@ func generateImages() error {
294294
opts = append(opts,
295295
integrity.OptSignWithTime(func() time.Time { return time.Date(2020, 6, 30, 0, 1, 56, 0, time.UTC) }),
296296
integrity.OptSignDeterministic(),
297+
integrity.OptSignWithoutPGPSignatureSalt(),
297298
)
298299

299300
s, err := integrity.NewSigner(f, opts...)

test/images/one-group-signed-pgp.sif

-6 Bytes
Binary file not shown.

test/images/two-groups-signed-pgp.sif

-12 Bytes
Binary file not shown.

0 commit comments

Comments
 (0)