aboutsummaryrefslogtreecommitdiff
path: root/b64file/file.go
diff options
context:
space:
mode:
Diffstat (limited to 'b64file/file.go')
-rw-r--r--b64file/file.go96
1 files changed, 96 insertions, 0 deletions
diff --git a/b64file/file.go b/b64file/file.go
new file mode 100644
index 0000000..ebca8fe
--- /dev/null
+++ b/b64file/file.go
@@ -0,0 +1,96 @@
+// Package file implements signify file format
+package b64file
+
+import (
+ "bufio"
+ "bytes"
+ "encoding"
+ "encoding/base64"
+ "errors"
+ "fmt"
+ "io"
+ "io/ioutil"
+ "os"
+ "strings"
+)
+
+const (
+ ModeSec os.FileMode = 0600
+ ModePub os.FileMode = 0644
+ ModeSig os.FileMode = 0644
+ untrusted = "untrusted comment: "
+)
+
+// Original Error: "invalid comment in %s; must start with 'untrusted comment: '"
+var ErrUntrusted = errors.New("comment must start with 'untrusted comment: '")
+
+func DecodeFile(fname string, u encoding.BinaryUnmarshaler) (string, []byte, error) {
+ fd, err := os.Open(fname)
+ if err != nil {
+ return "", nil, err
+ }
+ defer fd.Close()
+ return Decode(fd, u)
+}
+
+func DecodeString(data string, u encoding.BinaryUnmarshaler) (string, []byte, error) {
+ r := strings.NewReader(data)
+ return Decode(r, u)
+}
+
+func DecodeBytes(data []byte, u encoding.BinaryUnmarshaler) (string, []byte, error) {
+ r := bytes.NewReader(data)
+ return Decode(r, u)
+}
+
+func Decode(r io.Reader, u encoding.BinaryUnmarshaler) (string, []byte, error) {
+ buf := bufio.NewReader(r)
+
+ comment, err := buf.ReadString('\n')
+ if err != nil {
+ return "", nil, err
+ }
+ if !strings.HasPrefix(comment, untrusted) {
+ return "", nil, ErrUntrusted
+ }
+ comment = strings.TrimSpace(comment[len(untrusted):])
+
+ raw, err := buf.ReadString('\n')
+ if err != nil {
+ return "", nil, err
+ }
+ b, err := base64.StdEncoding.DecodeString(raw)
+ if err != nil {
+ return "", nil, err
+ }
+ if err := u.UnmarshalBinary(b); err != nil {
+ return "", nil, err
+ }
+
+ message, err := ioutil.ReadAll(buf)
+ if err != nil {
+ return "", nil, err
+ }
+
+ return comment, message, nil
+}
+
+func EncodeFile(fname string, perm os.FileMode, u encoding.BinaryMarshaler, comment string, msg []byte) 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, u, comment, msg)
+}
+
+func Encode(w io.Writer, u encoding.BinaryMarshaler, comment string, msg []byte) error {
+ raw, err := u.MarshalBinary()
+ if err != nil {
+ return err
+ }
+ fmt.Fprintf(w, "%s%s\n", untrusted, comment)
+ fmt.Fprintf(w, "%s\n", base64.StdEncoding.EncodeToString(raw))
+ w.Write(msg)
+ return nil
+}