aboutsummaryrefslogtreecommitdiff
path: root/cmd_sign.go
blob: 74398c3610b7f2a5dff31381a24dea3f542eb45a (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
package main

import (
	"context"
	"flag"
	"io/ioutil"
	"log"

	"dim13.org/signify/b64file"
	"dim13.org/signify/zsig"
	"github.com/google/subcommands"
)

// Usage: signify -S [-ez] [-x sigfile] -s seckey -m message

type signCmd struct {
	embed   bool
	zip     bool
	sigFile string
	secFile string
	msgFile string
}

func (m *signCmd) Name() string     { return "sign" }
func (m *signCmd) Synopsis() string { return "sign file" }
func (m *signCmd) Usage() string {
	return "sign [-ez] [-x sigfile] -s seckey -m message\n"
}

func (m *signCmd) SetFlags(f *flag.FlagSet) {
	f.BoolVar(&m.embed, "e", false, "embed the message")
	f.BoolVar(&m.zip, "z", false, "sign gzip archive") // TODO
	f.StringVar(&m.sigFile, "x", "", "signature file")
	f.StringVar(&m.secFile, "s", "", "secret file (required)")
	f.StringVar(&m.msgFile, "m", "", "message file (required)")
}

func (m *signCmd) Execute(ctx context.Context, f *flag.FlagSet, args ...interface{}) subcommands.ExitStatus {
	if m.secFile == "" || m.msgFile == "" {
		f.Usage()
		return subcommands.ExitUsageError
	}
	if m.sigFile == "" {
		m.sigFile = SigName(m.msgFile)
	}

	var err error
	switch {
	case m.zip && m.embed:
		f.Usage()
		return subcommands.ExitUsageError
	case m.zip:
		err = m.zipped()
	case m.embed:
		err = m.embedded()
	default:
		err = m.plain()
	}
	if err != nil {
		log.Println(err)
		return subcommands.ExitFailure
	}

	return subcommands.ExitSuccess
}

func (m *signCmd) plain() error {
	sec, err := openSec(m.secFile)
	if err != nil {
		return err
	}
	msg, err := ioutil.ReadFile(m.msgFile)
	if err != nil {
		return err
	}
	sig := sec.Sign(msg)
	comment := VerifyWith(m.secFile)
	fd, err := Create(m.sigFile, ModeSig)
	if err != nil {
		return err
	}
	defer fd.Close()
	return b64file.Encode(fd, sig, comment, nil)
}

func (m *signCmd) embedded() error {
	sec, err := openSec(m.secFile)
	if err != nil {
		return err
	}
	msg, err := ioutil.ReadFile(m.msgFile)
	if err != nil {
		return err
	}
	sig := sec.Sign(msg)
	comment := VerifyWith(m.secFile)
	fd, err := Create(m.sigFile, ModeSig)
	if err != nil {
		return err
	}
	fd.Close()
	return b64file.Encode(fd, sig, comment, msg)
}

// TODO
func (m *signCmd) zipped() error {
	fd, err := Open(m.msgFile)
	if err != nil {
		return err
	}
	defer fd.Close()
	z, err := zsig.NewReader(fd)
	if err != nil {
		return err
	}
	log.Println(z)
	zhead, err := zsig.NewHeader(z)
	if err != nil {
		return err
	}
	log.Println(zhead)
	body, err := zhead.MarshalText()
	if err != nil {
		return err
	}
	log.Println(body)
	return nil
}