Skip to content

Commit e669ef5

Browse files
committed
Support empty sigstore passphrases, for cosig compatibility
Signed-off-by: Miloslav Trmač <[email protected]>
1 parent 8905526 commit e669ef5

File tree

3 files changed

+31
-2
lines changed

3 files changed

+31
-2
lines changed

cmd/skopeo/fixtures/empty.passphrase

Whitespace-only changes.

cmd/skopeo/utils.go

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -383,23 +383,28 @@ func (opts *sharedCopyOptions) copyOptions(stdout io.Writer) (*copy.Options, fun
383383
return nil, nil, fmt.Errorf("Only one of --sign-by, --sign-by-sq-fingerprint and --sign-by-sigstore-private-key can be used with --sign-passphrase-file")
384384
}
385385
}
386+
// Simple signing does not really allow empty but present passphrases — but for sigstore, cosign does support creating keys encrypted with an empty passphrase;
387+
// so, at least for that case, we must track the distinction between an empty and a missing passphrase precisely.
386388
var passphrase string
389+
passphraseSet := false
387390
if opts.signPassphraseFile != "" {
388391
p, err := cli.ReadPassphraseFile(opts.signPassphraseFile)
389392
if err != nil {
390393
return nil, nil, err
391394
}
392395
passphrase = p
396+
passphraseSet = true
393397
} else if opts.signBySigstorePrivateKey != "" {
394398
p, err := promptForPassphrase(opts.signBySigstorePrivateKey, os.Stdin, os.Stdout)
395399
if err != nil {
396400
return nil, nil, err
397401
}
398402
passphrase = p
403+
passphraseSet = true
399404
} // opts.signByFingerprint triggers a GPG-agent passphrase prompt, possibly using a more secure channel, so we usually shouldn’t prompt ourselves if no passphrase was explicitly provided.
400405
// With opts.signBySequoiaFingerprint, we don’t prompt for a passphrase (for now??): We don’t know whether the key requires a passphrase.
401406
var passphraseBytes []byte
402-
if passphrase != "" {
407+
if passphraseSet {
403408
passphraseBytes = []byte(passphrase)
404409
}
405410

@@ -432,7 +437,7 @@ func (opts *sharedCopyOptions) copyOptions(stdout io.Writer) (*copy.Options, fun
432437
sqOpts := []simplesequoia.Option{
433438
simplesequoia.WithKeyFingerprint(opts.signBySequoiaFingerprint),
434439
}
435-
if passphrase != "" {
440+
if passphraseSet {
436441
sqOpts = append(sqOpts, simplesequoia.WithPassphrase(passphrase))
437442
}
438443
signer, err := simplesequoia.NewSigner(sqOpts...)

cmd/skopeo/utils_test.go

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -414,6 +414,30 @@ func TestSharedCopyOptionsCopyOptions(t *testing.T) {
414414
ReportWriter: &someStdout,
415415
},
416416
},
417+
{ // --sign-passphrase-file + --sign-by-sigstore-private-key work
418+
options: []string{
419+
"--sign-by-sigstore-private-key", "/some/key/path.private",
420+
"--sign-passphrase-file", passphraseFile.Name(),
421+
},
422+
expected: copy.Options{
423+
SignPassphrase: "test-passphrase",
424+
SignBySigstorePrivateKeyFile: "/some/key/path.private",
425+
SignSigstorePrivateKeyPassphrase: []byte("test-passphrase"),
426+
ReportWriter: &someStdout,
427+
},
428+
},
429+
{ // --sign-passphrase-file + --sign-by-sigstore-private-key work with an empty passphrase
430+
options: []string{
431+
"--sign-by-sigstore-private-key", "/some/key/path.private",
432+
"--sign-passphrase-file", "./fixtures/empty.passphrase",
433+
},
434+
expected: copy.Options{
435+
SignPassphrase: "",
436+
SignBySigstorePrivateKeyFile: "/some/key/path.private",
437+
SignSigstorePrivateKeyPassphrase: []byte(""),
438+
ReportWriter: &someStdout,
439+
},
440+
},
417441
}
418442
// If Sequoia is supported, --sign-passphrase-file + --sign-by-sq-fingerprint work
419443
if buildWithSequoia {

0 commit comments

Comments
 (0)