aboutsummaryrefslogtreecommitdiff
path: root/main.go
diff options
context:
space:
mode:
authorDimitri Sokolyuk <demon@dim13.org>2017-05-01 16:57:53 +0200
committerDimitri Sokolyuk <demon@dim13.org>2017-05-01 16:57:53 +0200
commiteae17147e143094e48050494b2da570f42d21986 (patch)
treeeecf454787918d8f9a07f630b60b8dbe75fb7540 /main.go
parentd8bd486761d8e90b06a37b0658f81a2ebf3be9a8 (diff)
Reorder package
Diffstat (limited to 'main.go')
-rw-r--r--main.go215
1 files changed, 215 insertions, 0 deletions
diff --git a/main.go b/main.go
new file mode 100644
index 0000000..1144470
--- /dev/null
+++ b/main.go
@@ -0,0 +1,215 @@
+package main
+
+import (
+ "errors"
+ "flag"
+ "fmt"
+ "io/ioutil"
+ "log"
+ "path/filepath"
+
+ "dim13.org/signify/ask"
+ "dim13.org/signify/signify"
+)
+
+/*
+ signify -C [-q] -p pubkey -x sigfile [file ...]
+ signify -G [-n] [-c comment] -p pubkey -s seckey
+ signify -S [-ez] [-x sigfile] -s seckey -m message
+ signify -V [-eqz] [-p pubkey] [-t keytype] [-x sigfile] -m message
+*/
+
+const safePath = "/etc/signify"
+
+var (
+ checksum = flag.Bool("C", false, "Verify a signed checksum list")
+ generate = flag.Bool("G", false, "Generate a new key pair")
+ sign = flag.Bool("S", false, "Sign the specfied message")
+ verify = flag.Bool("V", false, "Verify the message")
+ comment = flag.String("c", "signify", "Comment")
+ embed = flag.Bool("e", false, "Embed the message")
+ msg = flag.String("m", "", "Message file")
+ nopass = flag.Bool("n", false, "No key passphrase")
+ pub = flag.String("p", "", "Public key file")
+ quiet = flag.Bool("q", false, "Quiet mode")
+ sec = flag.String("s", "", "Secret key file")
+ sig = flag.String("x", "", "Signature file")
+ gzip = flag.Bool("z", false, "Sign and verify gzip archives")
+)
+
+var (
+ ErrNamingScheme = errors.New("please use naming scheme of keyname.pub and keyname.sec")
+)
+
+func main() {
+ flag.Parse()
+
+ switch {
+ case *generate:
+ if err := Generate(*pub, *sec, *comment, *nopass); err != nil {
+ log.Fatal(err)
+ }
+ case *sign:
+ if err := Sign(*msg, *sec, *embed); err != nil {
+ log.Fatal(err)
+ }
+ case *verify:
+ if err := Verify(*msg, *pub); err != nil {
+ log.Fatal(err)
+ }
+ default:
+ flag.Usage()
+ }
+}
+
+func Generate(pubFile, secFile, comment string, nopass bool) error {
+ if !NamingScheme(pubFile, secFile) {
+ return ErrNamingScheme
+ }
+
+ pubKey, encKey, err := signify.NewKey()
+ if err != nil {
+ return err
+ }
+
+ if nopass {
+ encKey.KDFRounds = 0
+ }
+ encKey.Kdf(ask.Confirmed)
+
+ encRaw, err := signify.Marshal(encKey)
+ if err != nil {
+ return err
+ }
+
+ sfile := signify.File{
+ Comment: fmt.Sprintf("%s secret key", comment),
+ RawKey: encRaw,
+ }
+ if err := sfile.WriteFile(secFile, signify.SecMode); err != nil {
+ return err
+ }
+
+ pubRaw, err := signify.Marshal(pubKey)
+ if err != nil {
+ return err
+ }
+ pfile := signify.File{
+ Comment: fmt.Sprintf("%s public key", comment),
+ RawKey: pubRaw,
+ }
+ if err := pfile.WriteFile(pubFile, signify.PubMode); err != nil {
+ return err
+ }
+
+ return nil
+}
+
+func OpenEnc(fname string) (*signify.EncKey, error) {
+ f, err := signify.ParseFile(fname)
+ if err != nil {
+ return nil, err
+ }
+ encKey := new(signify.EncKey)
+ if err := signify.Unmarshal(f.RawKey, encKey); err != nil {
+ return nil, err
+ }
+ encKey.Kdf(ask.Password)
+ if err := encKey.Check(); err != nil {
+ return nil, err
+ }
+ return encKey, nil
+}
+
+func OpenPub(fname string) (*signify.PubKey, error) {
+ f, err := signify.ParseFile(fname)
+ if err != nil {
+ return nil, err
+ }
+ pubKey := new(signify.PubKey)
+ if err := signify.Unmarshal(f.RawKey, pubKey); err != nil {
+ return nil, err
+ }
+ if err := pubKey.Check(); err != nil {
+ return nil, err
+ }
+ return pubKey, nil
+}
+
+func OpenSig(fname string) (*signify.Sig, []byte, error) {
+ f, err := signify.ParseFile(fname + ".sig")
+ if err != nil {
+ return nil, nil, err
+ }
+ sig := new(signify.Sig)
+ if err := signify.Unmarshal(f.RawKey, sig); err != nil {
+ return nil, nil, err
+ }
+ if err := sig.Check(); err != nil {
+ return nil, nil, err
+ }
+ if f.Embedded() {
+ return sig, f.Message, nil
+ }
+ msg, err := ioutil.ReadFile(fname)
+ if err != nil {
+ return nil, nil, err
+ }
+ return sig, msg, nil
+}
+
+func Sign(msgFile, secFile string, embed bool) error {
+ encKey, err := OpenEnc(secFile)
+ if err != nil {
+ return err
+ }
+ body, err := ioutil.ReadFile(msgFile)
+ if err != nil {
+ return err
+ }
+ sig := encKey.Sign(body)
+ sigRaw, err := signify.Marshal(sig)
+ if err != nil {
+ return err
+ }
+ sigfile := signify.File{
+ Comment: fmt.Sprintf("verify with %s", ToPub(secFile)), // TODO replace .sec with .pub
+ RawKey: sigRaw,
+ }
+ if embed {
+ sigfile.Message = body
+ }
+ if err := sigfile.WriteFile(msgFile+".sig", signify.PubMode); err != nil {
+ return err
+ }
+ return nil
+}
+
+func Verify(msgFile, pubFile string) error {
+ pubKey, err := OpenPub(pubFile)
+ if err != nil {
+ return err
+ }
+ sig, body, err := OpenSig(msgFile)
+ if err != nil {
+ return err
+ }
+ if err := pubKey.Verify(body, sig); err != nil {
+ return err
+ }
+ log.Println("Signature Verfied")
+ return nil
+}
+
+func NamingScheme(pubFile, secFile string) bool {
+ pubFile = filepath.Base(pubFile)
+ secFile = filepath.Base(secFile)
+ pubExt := filepath.Ext(pubFile)
+ secExt := filepath.Ext(secFile)
+ return pubExt == ".pub" && secExt == ".sec" && pubFile[:len(pubExt)-1] == secFile[:len(secExt)-1]
+}
+
+func ToPub(secFile string) string {
+ ext := filepath.Ext(secFile)
+ return filepath.Base(secFile[:len(ext)-1] + ".pub")
+}