package main import ( "flag" "fmt" "io/ioutil" "os" "dim13.org/signify/file" "dim13.org/signify/key" "dim13.org/signify/zsig" ) // Usage: signify -V [-eqz] [-p pubkey] [-t keytype] [-x sigfile] -m message func verify(args []string) error { opts := flag.NewFlagSet("verify", flag.ExitOnError) var ( embedded = opts.Bool("e", false, "Embed message") quiet = opts.Bool("q", false, "Quiet mode") zip = opts.Bool("z", false, "Verify gzip archive") // TODO pubFile = opts.String("p", "", "Public key file") keyType = opts.String("t", "", "Key type") // TODO sigFile = opts.String("x", "", "Signature file") msgFile = opts.String("m", "", "Message file (required)") ) opts.Parse(args) if *msgFile == "" { opts.Usage() return nil } if *sigFile == "" { *sigFile = file.SigName(*msgFile) } _ = keyType // TODO switch { case *zip && *embedded: return ErrEZ case *zip: if err := verifyGzip(*pubFile, *sigFile); err != nil { return err } case *embedded: if err := verifyEmbedded(*pubFile, *sigFile); err != nil { return err } default: if err := verifyPlain(*pubFile, *sigFile, *msgFile); err != nil { return err } } if !*quiet { fmt.Println("Signature Verified") } return nil } func verifyPlain(pubFile, sigFile, msgFile string) error { msg, err := ioutil.ReadFile(msgFile) if err != nil { return err } sig, _, verifyWith, err := openSig(sigFile) if err != nil { return err } if pubFile == "" { pubFile = verifyWith } pub, err := openPub(pubFile) if err != nil { return err } return sig.Verify(msg, pub) } func verifyEmbedded(pubFile, sigFile string) error { sig, msg, verifyWith, err := openSig(sigFile) if err != nil { return err } if pubFile == "" { pubFile = verifyWith } pub, err := openPub(pubFile) if err != nil { return err } return sig.Verify(msg, pub) } // TODO ugly work-in-progress func verifyGzip(pubFile, sigFile string) error { fd, err := os.Open(sigFile) if err != nil { return err } defer fd.Close() z, err := zsig.NewReader(fd) if err != nil { return err } sig := new(key.Sig) _, msg, err := file.DecodeString(z.Comment, sig) if err != nil { return err } if err := sig.Validate(); err != nil { return err } pub, err := openPub(pubFile) if err != nil { return err } if err := sig.Verify(msg, pub); err != nil { return err } zhead, err := zsig.ParseBytes(msg) if err != nil { return err } return zhead.Verify(z) } func openPub(fname string) (*key.Pub, error) { pub := new(key.Pub) if _, _, err := file.DecodeFile(fname, pub); err != nil { return nil, err } if err := pub.Validate(); err != nil { return nil, err } return pub, nil } func openSig(fname string) (*key.Sig, []byte, string, error) { sig := new(key.Sig) comment, msg, err := file.DecodeFile(fname, sig) if err != nil { return nil, nil, "", err } if err := sig.Validate(); err != nil { return nil, nil, "", err } pubKey := file.PubFile(comment) return sig, msg, pubKey, nil }