package signify import ( "bufio" "bytes" "encoding/base64" "errors" "fmt" "io" "io/ioutil" "os" "strings" ) type EncFile struct { Comment string Key *EncKey } type PubFile struct { Comment string Key *PubKey } type SigFile struct { Comment string Sig *Sig Message string } type File struct { Comment string RawKey []byte Message []byte } const ( commentHdr = "untrusted comment:" sigFrom = "signature from %s" ) var ( ErrCommentSize = errors.New("comment line to long") ErrUntrustedComment = errors.New("expected untrusted comment") ) func checkComment(comment string) error { // compatibility with original version if len(comment) > 1024 { return ErrCommentSize } if !strings.HasPrefix(comment, commentHdr) { return ErrUntrustedComment } return nil } func (f *File) Embedded() bool { return len(f.Message) > 0 } func (f *File) ReadFrom(r io.Reader) error { buf := bufio.NewReader(r) comment, err := buf.ReadString('\n') if err != nil { return err } if err := checkComment(comment); err != nil { return err } f.Comment = strings.TrimSpace(comment[len(commentHdr):]) raw, err := buf.ReadString('\n') if err != nil { return err } f.RawKey, err = base64.StdEncoding.DecodeString(raw) if err != nil { return err } f.Message, err = ioutil.ReadAll(buf) if err != nil { return err } return nil } func Parse(b []byte) (*File, error) { r := bytes.NewReader(b) f := new(File) return f, f.ReadFrom(r) } func ParseFile(fname string) (*File, error) { fd, err := os.Open(fname) if err != nil { return nil, err } defer fd.Close() f := new(File) return f, f.ReadFrom(fd) } func (f File) Bytes() ([]byte, error) { buf := new(bytes.Buffer) err := f.WriteTo(buf) if err != nil { return nil, err } return buf.Bytes(), nil } func (f File) WriteTo(w io.Writer) error { fmt.Fprintln(w, commentHdr, f.Comment) fmt.Fprintln(w, base64.StdEncoding.EncodeToString(f.RawKey)) if f.Message != nil { w.Write(f.Message) } return nil } const ( SecMode os.FileMode = 0600 PubMode os.FileMode = 0644 ) func (f File) WriteFile(fname string, perm os.FileMode) error { fd, err := os.OpenFile(fname, os.O_WRONLY|os.O_CREATE, perm) if err != nil { return err } defer fd.Close() return f.WriteTo(fd) }