diff options
Diffstat (limited to 'third_party/go/git-appraise/review/gpg/signable.go')
-rw-r--r-- | third_party/go/git-appraise/review/gpg/signable.go | 129 |
1 files changed, 0 insertions, 129 deletions
diff --git a/third_party/go/git-appraise/review/gpg/signable.go b/third_party/go/git-appraise/review/gpg/signable.go deleted file mode 100644 index 776764c6fc10..000000000000 --- a/third_party/go/git-appraise/review/gpg/signable.go +++ /dev/null @@ -1,129 +0,0 @@ -// Package gpg provides an interface and an abstraction with which to sign and -// verify review requests and comments. -package gpg - -import ( - "bytes" - "encoding/json" - "fmt" - "io/ioutil" - "os" - "os/exec" -) - -const placeholder = "gpgsig" - -// Sig provides an abstraction around shelling out to GPG to sign the -// content it's given. -type Sig struct { - // Sig holds an object's content's signature. - Sig string `json:"signature,omitempty"` -} - -// Signable is an interfaces which provides the pointer to the signable -// object's stringified signature. -// -// This pointer is used by `Sign` and `Verify` to replace its contents with -// `placeholder` or the signature itself for the purposes of signing or -// verifying. -type Signable interface { - Signature() *string -} - -// Signature is `Sig`'s implementation of `Signable`. Through this function, an -// object which needs to implement `Signable` need only embed `Sig` -// anonymously. See, e.g., review/request.go. -func (s *Sig) Signature() *string { - return &s.Sig -} - -// Sign uses gpg to sign the contents of a request and deposit it into the -// signature key of the request. -func Sign(key string, s Signable) error { - // First we retrieve the pointer and write `placeholder` as its value. - sigPtr := s.Signature() - *sigPtr = placeholder - - // Marshal the content and sign it. - content, err := json.Marshal(s) - if err != nil { - return err - } - sig, err := signContent(key, content) - if err != nil { - return err - } - - // Write the signature as the new value at the pointer. - *sigPtr = sig.String() - return nil -} - -func signContent(key string, content []byte) (*bytes.Buffer, - error) { - var stdout, stderr bytes.Buffer - cmd := exec.Command("gpg", "-u", key, "--detach-sign", "--armor") - cmd.Stdin = bytes.NewReader(content) - cmd.Stdout = &stdout - cmd.Stderr = &stderr - err := cmd.Run() - return &stdout, err -} - -// Verify verifies the signatures on the request and its comments with the -// given key. -func Verify(s Signable) error { - // Retrieve the pointer. - sigPtr := s.Signature() - // Copy its contents. - sig := *sigPtr - // Overwrite the value with the placeholder. - *sigPtr = placeholder - - defer func() { *sigPtr = sig }() - - // 1. Marshal the content into JSON. - // 2. Write the signature and the content to temp files. - // 3. Use gpg to verify the signature. - content, err := json.Marshal(s) - if err != nil { - return err - } - sigFile, err := ioutil.TempFile("", "sig") - if err != nil { - return err - } - defer os.Remove(sigFile.Name()) - _, err = sigFile.Write([]byte(sig)) - if err != nil { - return err - } - err = sigFile.Close() - if err != nil { - return err - } - - contentFile, err := ioutil.TempFile("", "content") - if err != nil { - return err - } - defer os.Remove(contentFile.Name()) - _, err = contentFile.Write(content) - if err != nil { - return err - } - err = contentFile.Close() - if err != nil { - return err - } - - var stdout, stderr bytes.Buffer - cmd := exec.Command("gpg", "--verify", sigFile.Name(), contentFile.Name()) - cmd.Stdout = &stdout - cmd.Stderr = &stderr - err = cmd.Run() - if err != nil { - return fmt.Errorf("%s", stderr.String()) - } - return nil -} |