diff --git a/go/gen/fb/serial/commit.go b/go/gen/fb/serial/commit.go index 3dbca73ff6..01b41213a9 100644 --- a/go/gen/fb/serial/commit.go +++ b/go/gen/fb/serial/commit.go @@ -190,14 +190,6 @@ func (rcv *Commit) Description() []byte { return nil } -func (rcv *Commit) Signature() []byte { - o := flatbuffers.UOffsetT(rcv._tab.Offset(22)) - if o != 0 { - return rcv._tab.ByteVector(o + rcv._tab.Pos) - } - return nil -} - func (rcv *Commit) TimestampMillis() uint64 { o := flatbuffers.UOffsetT(rcv._tab.Offset(18)) if o != 0 { @@ -222,6 +214,14 @@ func (rcv *Commit) MutateUserTimestampMillis(n int64) bool { return rcv._tab.MutateInt64Slot(20, n) } +func (rcv *Commit) Signature() []byte { + o := flatbuffers.UOffsetT(rcv._tab.Offset(22)) + if o != 0 { + return rcv._tab.ByteVector(o + rcv._tab.Pos) + } + return nil +} + const CommitNumFields = 10 func CommitStart(builder *flatbuffers.Builder) { @@ -266,7 +266,6 @@ func CommitAddUserTimestampMillis(builder *flatbuffers.Builder, userTimestampMil func CommitAddSignature(builder *flatbuffers.Builder, signature flatbuffers.UOffsetT) { builder.PrependUOffsetTSlot(9, flatbuffers.UOffsetT(signature), 0) } - func CommitEnd(builder *flatbuffers.Builder) flatbuffers.UOffsetT { return builder.EndObject() } diff --git a/go/libraries/utils/gpg/sign.go b/go/libraries/utils/gpg/sign.go index a26323819b..fd8521d54b 100644 --- a/go/libraries/utils/gpg/sign.go +++ b/go/libraries/utils/gpg/sign.go @@ -11,56 +11,55 @@ import ( "strings" ) -func Sign(ctx context.Context, keyId string, message []byte) ([]byte, error) { - args := []string{"--clear-sign", "-u", keyId} +func execGpgAndReadOutput(ctx context.Context, in []byte, args []string) (*bytes.Buffer, *bytes.Buffer, error) { cmdStr := fmt.Sprintf("gpg %s", strings.Join(args, " ")) cmd := exec.CommandContext(ctx, "gpg", args...) stdOut, err := cmd.StdoutPipe() if err != nil { - return nil, fmt.Errorf("failed to get stdout for command '%s': %w", cmdStr, err) + return nil, nil, fmt.Errorf("failed to get stdout for command '%s': %w", cmdStr, err) } stdErr, err := cmd.StderrPipe() if err != nil { - return nil, fmt.Errorf("failed to get stderr for command '%s': %w", cmdStr, err) + return nil, nil, fmt.Errorf("failed to get stderr for command '%s': %w", cmdStr, err) } stdIn, err := cmd.StdinPipe() if err != nil { - return nil, fmt.Errorf("failed to get stdin for command '%s': %w", cmdStr, err) + return nil, nil, fmt.Errorf("failed to get stdin for command '%s': %w", cmdStr, err) } err = cmd.Start() if err != nil { - return nil, fmt.Errorf("failed to start command '%s': %w", cmdStr, err) + return nil, nil, fmt.Errorf("failed to start command '%s': %w", cmdStr, err) } eg, egCtx := errgroup.WithContext(ctx) outBuf := listenToOut(egCtx, eg, stdOut) errBuf := listenToOut(egCtx, eg, stdErr) - n, err := io.Copy(stdIn, strings.NewReader(string(message))) + n, err := io.Copy(stdIn, strings.NewReader(string(in))) if err != nil { - return nil, fmt.Errorf("failed to write stdin for command '%s': %w", cmdStr, err) - } else if n < int64(len(message)) { - return nil, fmt.Errorf("failed to write stdin for command '%s': EOF before all bytes written", cmd) + return nil, nil, fmt.Errorf("failed to write stdin for command '%s': %w", cmdStr, err) + } else if n < int64(len(in)) { + return nil, nil, fmt.Errorf("failed to write stdin for command '%s': EOF before all bytes written", cmd) } err = stdIn.Close() if err != nil { - return nil, fmt.Errorf("failed to close stdin for command '%s': %w", cmdStr, err) + return nil, nil, fmt.Errorf("failed to close stdin for command '%s': %w", cmdStr, err) } for { state, err := cmd.Process.Wait() if err != nil { - return nil, fmt.Errorf("failed to wait for command '%s': %w", cmdStr, err) + return nil, nil, fmt.Errorf("failed to wait for command '%s': %w", cmdStr, err) } if state.Exited() { if state.ExitCode() != 0 { - return nil, fmt.Errorf("command '%s' exited with code %d. stdout: '%s', stderr: '%s'", cmdStr, state.ExitCode(), outBuf.String(), errBuf.String()) + return nil, nil, fmt.Errorf("command '%s' exited with code %d. stdout: '%s', stderr: '%s'", cmdStr, state.ExitCode(), outBuf.String(), errBuf.String()) } break @@ -69,7 +68,27 @@ func Sign(ctx context.Context, keyId string, message []byte) ([]byte, error) { err = eg.Wait() if err != nil { - return nil, fmt.Errorf("failed to read output for command '%s': %w", cmdStr, err) + return nil, nil, fmt.Errorf("failed to read output for command '%s': %w", cmdStr, err) + } + + return outBuf, errBuf, nil +} + +func Sign(ctx context.Context, keyId string, message []byte) ([]byte, error) { + args := []string{"--clear-sign", "-u", keyId} + outBuf, _, err := execGpgAndReadOutput(ctx, message, args) + if err != nil { + return nil, err + } + + return outBuf.Bytes(), nil +} + +func Verify(ctx context.Context, signature []byte) ([]byte, error) { + args := []string{"--verify"} + outBuf, _, err := execGpgAndReadOutput(ctx, signature, args) + if err != nil { + return nil, err } return outBuf.Bytes(), nil diff --git a/go/serial/commit.fbs b/go/serial/commit.fbs index 92f70a0899..58239bb848 100644 --- a/go/serial/commit.fbs +++ b/go/serial/commit.fbs @@ -28,6 +28,7 @@ table Commit { description:string (required); timestamp_millis:uint64; user_timestamp_millis:int64; + signature:string; } // KEEP THIS IN SYNC WITH fileidentifiers.go