aboutsummaryrefslogtreecommitdiff
path: root/file/file.go
diff options
context:
space:
mode:
authorDimitri Sokolyuk <demon@dim13.org>2017-05-01 17:01:09 +0200
committerDimitri Sokolyuk <demon@dim13.org>2017-05-01 17:01:09 +0200
commit4cc92b5f712abe7b9522a48b701a7af90eaa134b (patch)
tree010870686ebd22488cfe1c7ac848188edb797ce5 /file/file.go
parenteae17147e143094e48050494b2da570f42d21986 (diff)
Rename sig package
Diffstat (limited to 'file/file.go')
-rw-r--r--file/file.go93
1 files changed, 93 insertions, 0 deletions
diff --git a/file/file.go b/file/file.go
new file mode 100644
index 0000000..ed1a93b
--- /dev/null
+++ b/file/file.go
@@ -0,0 +1,93 @@
+// Package sig implements signify file format
+package file
+
+import (
+ "bytes"
+ "encoding/base64"
+ "errors"
+ "fmt"
+ "io"
+ "io/ioutil"
+ "os"
+ "strings"
+)
+
+var ErrComment = errors.New("expected untrusted comment")
+
+// Block represents a encoded signify key or signature
+//
+// The encoded form is:
+// untrusted comment: comment
+// base64-encoded key
+// optional message
+type Block struct {
+ Comment string
+ Bytes []byte
+ Message []byte
+}
+
+const untrusted = "untrusted comment:"
+
+func Encode(w io.Writer, b *Block) error {
+ fmt.Fprintln(w, untrusted, b.Comment)
+ fmt.Fprintln(w, base64.StdEncoding.EncodeToString(b.Bytes))
+ w.Write(b.Message)
+ return nil
+}
+
+func EncodeToMemory(b *Block) []byte {
+ buf := new(bytes.Buffer)
+ Encode(buf, b)
+ return buf.Bytes()
+}
+
+func Decode(data []byte) (*Block, error) {
+ r := bytes.NewBuffer(data)
+ comment, err := r.ReadString('\n')
+ if err != nil {
+ return nil, err
+ }
+ if !strings.HasPrefix(comment, untrusted) {
+ return nil, ErrComment
+ }
+ raw, err := r.ReadString('\n')
+ if err != nil {
+ return nil, err
+ }
+ b, err := base64.StdEncoding.DecodeString(raw)
+ if err != nil {
+ return nil, err
+ }
+ message, err := ioutil.ReadAll(r)
+ if err != nil {
+ return nil, err
+ }
+ return &Block{
+ Comment: strings.TrimSpace(comment[len(untrusted):]),
+ Bytes: b,
+ Message: message,
+ }, nil
+}
+
+func DecodeFile(fname string) (*Block, error) {
+ body, err := ioutil.ReadFile(fname)
+ if err != nil {
+ return nil, err
+ }
+ return Decode(body)
+}
+
+const (
+ SecMode os.FileMode = 0600
+ PubMode os.FileMode = 0644
+ SigMode os.FileMode = 0644
+)
+
+func EncodeFile(fname string, perm os.FileMode, b *Block) error {
+ fd, err := os.OpenFile(fname, os.O_WRONLY|os.O_CREATE|os.O_EXCL, perm)
+ if err != nil {
+ return err
+ }
+ defer fd.Close()
+ return Encode(fd, b)
+}