Compare commits
1
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
969a707487 |
+20
-4
@@ -172,11 +172,22 @@ func parseStatusLine(statusOutput, keyword string) ([]string, bool) {
|
||||
func gpgSign(
|
||||
ctx context.Context, data []byte, keyID GPGKeyID,
|
||||
) ([]byte, string, error) {
|
||||
// The signature goes to stdout, so the status lines go to stderr.
|
||||
tmpDir, err := os.MkdirTemp("", "mfer-gpg-sign-*")
|
||||
if err != nil {
|
||||
return nil, "", fmt.Errorf("failed to create temp dir: %w", err)
|
||||
}
|
||||
|
||||
defer func() { _ = os.RemoveAll(tmpDir) }()
|
||||
|
||||
sigFile := filepath.Join(tmpDir, "signature.asc")
|
||||
|
||||
// The signature goes to sigFile, so --status-fd 1 can send gpg's status
|
||||
// lines to stdout; its messages go to stderr.
|
||||
stdout, stderr, err := runGPG(ctx, bytes.NewReader(data),
|
||||
"--detach-sign",
|
||||
gpgOptArmor,
|
||||
gpgOptStatusFD, "2",
|
||||
"--output", sigFile,
|
||||
gpgOptStatusFD, "1",
|
||||
"--local-user", string(keyID),
|
||||
)
|
||||
if err != nil {
|
||||
@@ -185,12 +196,17 @@ func gpgSign(
|
||||
|
||||
// The last argument of SIG_CREATED is the fingerprint of the key that
|
||||
// made the signature.
|
||||
created, ok := parseStatusLine(stderr.String(), "SIG_CREATED")
|
||||
created, ok := parseStatusLine(stdout.String(), "SIG_CREATED")
|
||||
if !ok {
|
||||
return nil, "", fmt.Errorf("%w: %s", errSigningKeyNotReported, stderr.String())
|
||||
}
|
||||
|
||||
return stdout.Bytes(), created[len(created)-1], nil
|
||||
sig, err := os.ReadFile(sigFile) //nolint:gosec // G304: inside tmpDir, made above
|
||||
if err != nil {
|
||||
return nil, "", fmt.Errorf("failed to read signature: %w", err)
|
||||
}
|
||||
|
||||
return sig, created[len(created)-1], nil
|
||||
}
|
||||
|
||||
// gpgExportPublicKey exports the public key for the specified key ID.
|
||||
|
||||
+4
-1
@@ -210,6 +210,8 @@ func TestGPGOptionLikeKeyIDIsNotAnOption(t *testing.T) {
|
||||
assert.NotContains(t, string(fpr), "gpg (GnuPG)")
|
||||
}
|
||||
|
||||
// TestGPGSignInvalidKey signs with a key that has no secret key in the
|
||||
// keyring. The error must hold gpg's messages and none of its status lines.
|
||||
func TestGPGSignInvalidKey(t *testing.T) {
|
||||
// Set up test environment (we need GNUPGHOME set)
|
||||
_, gpgHome := testGPGEnv(t)
|
||||
@@ -218,7 +220,8 @@ func TestGPGSignInvalidKey(t *testing.T) {
|
||||
data := []byte("test data")
|
||||
_, _, err := gpgSign(context.Background(), data,
|
||||
GPGKeyID("NONEXISTENT_KEY_ID_12345"))
|
||||
assert.Error(t, err)
|
||||
require.Error(t, err)
|
||||
assert.NotContains(t, err.Error(), gpgStatusPrefix)
|
||||
}
|
||||
|
||||
func TestBuilderWithSigning(t *testing.T) {
|
||||
|
||||
Reference in New Issue
Block a user