// Package file implements signify file format package file 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 }