smimesign/main.go

131 строка
4.1 KiB
Go
Исходник Постоянная ссылка Обычный вид История

//go:generate goversioninfo -file-version=$GIT_VERSION -ver-major=$VERSION_MAJOR -ver-minor=$VERSION_MINOR -ver-patch=$VERSION_PATCH -platform-specific=true windows-installer/versioninfo.json
2017-11-22 18:31:25 +03:00
package main
import (
"fmt"
"io"
2017-11-22 18:31:25 +03:00
"os"
"github.com/github/smimesign/certstore"
2017-11-22 18:31:25 +03:00
"github.com/pborman/getopt/v2"
2017-11-29 23:50:15 +03:00
"github.com/pkg/errors"
2017-11-22 18:31:25 +03:00
)
var (
2018-09-12 20:06:29 +03:00
// This can be set at build time by running
// go build -ldflags "-X main.versionString=$(git describe --tags)"
versionString = "undefined"
// default timestamp authority URL. This can be set at build time by running
// go build -ldflags "-X main.defaultTSA=${https://whatever}"
defaultTSA = ""
2017-11-22 18:31:25 +03:00
// Action flags
2017-11-29 22:36:08 +03:00
helpFlag = getopt.BoolLong("help", 'h', "print this help message")
2018-09-12 20:06:29 +03:00
versionFlag = getopt.BoolLong("version", 'v', "print the version number")
2017-11-29 22:36:08 +03:00
signFlag = getopt.BoolLong("sign", 's', "make a signature")
verifyFlag = getopt.BoolLong("verify", 0, "verify a signature")
listKeysFlag = getopt.BoolLong("list-keys", 0, "show keys")
2017-11-22 18:31:25 +03:00
// Option flags
localUserOpt = getopt.StringLong("local-user", 'u', "", "use USER-ID to sign", "USER-ID")
detachSignFlag = getopt.BoolLong("detach-sign", 'b', "make a detached signature")
armorFlag = getopt.BoolLong("armor", 'a', "create ascii armored output")
statusFdOpt = getopt.IntLong("status-fd", 0, -1, "write special status strings to the file descriptor n.", "n")
keyFormatOpt = getopt.EnumLong("keyid-format", 0, []string{"long"}, "long", "select how to display key IDs.", "{long}")
2018-07-26 20:51:42 +03:00
tsaOpt = getopt.StringLong("timestamp-authority", 't', defaultTSA, "URL of RFC3161 timestamp authority to use for timestamping", "url")
2018-09-06 00:27:35 +03:00
includeCertsOpt = getopt.IntLong("include-certs", 0, -2, "-3 is the same as -2, but ommits issuer when cert has Authority Information Access extension. -2 includes all certs except root. -1 includes all certs. 0 includes no certs. 1 includes leaf cert. >1 includes n from the leaf. Default -2.", "n")
// Remaining arguments
fileArgs []string
2017-11-28 23:05:00 +03:00
2017-11-29 23:50:15 +03:00
idents []certstore.Identity
// these are changed in tests
stdin io.ReadCloser = os.Stdin
stdout io.WriteCloser = os.Stdout
stderr io.WriteCloser = os.Stderr
2017-11-22 18:31:25 +03:00
)
func main() {
if err := runCommand(); err != nil {
2018-09-05 21:12:08 +03:00
fmt.Fprintln(os.Stderr, err)
os.Exit(1)
}
}
2017-11-28 23:05:00 +03:00
func runCommand() error {
2017-11-28 23:05:00 +03:00
// Parse CLI args
2018-07-26 20:51:42 +03:00
getopt.HelpColumn = 40
2017-11-22 18:31:25 +03:00
getopt.SetParameters("[files]")
getopt.Parse()
2017-11-22 21:41:34 +03:00
fileArgs = getopt.Args()
2017-11-22 18:31:25 +03:00
if *helpFlag {
getopt.Usage()
return nil
2017-11-29 23:50:15 +03:00
}
2018-09-12 20:06:29 +03:00
if *versionFlag {
fmt.Println(versionString)
return nil
}
2017-11-29 23:50:15 +03:00
// Open certificate store
store, err := certstore.Open()
if err != nil {
return errors.Wrap(err, "failed to open certificate store")
2017-11-29 23:50:15 +03:00
}
defer store.Close()
// Get list of identities
idents, err = store.Identities()
if err != nil {
return errors.Wrap(err, "failed to get identities from certificate store")
2017-11-29 23:50:15 +03:00
}
for _, ident := range idents {
defer ident.Close()
}
if *signFlag {
2018-09-12 20:06:29 +03:00
if *verifyFlag || *listKeysFlag {
return errors.New("specify --help, --sign, --verify, or --list-keys")
2017-11-22 18:31:25 +03:00
} else if len(*localUserOpt) == 0 {
return errors.New("specify a USER-ID to sign with")
2017-11-22 18:31:25 +03:00
} else {
return commandSign()
2017-11-22 18:31:25 +03:00
}
2017-11-29 23:50:15 +03:00
}
if *verifyFlag {
2018-09-12 20:06:29 +03:00
if *signFlag || *listKeysFlag {
return errors.New("specify --help, --sign, --verify, or --list-keys")
2017-11-22 18:31:25 +03:00
} else if len(*localUserOpt) > 0 {
return errors.New("local-user cannot be specified for verification")
2017-11-22 18:31:25 +03:00
} else if *detachSignFlag {
return errors.New("detach-sign cannot be specified for verification")
2017-11-22 18:31:25 +03:00
} else if *armorFlag {
return errors.New("armor cannot be specified for verification")
2017-11-22 18:31:25 +03:00
} else {
return commandVerify()
2017-11-22 18:31:25 +03:00
}
2017-11-29 23:50:15 +03:00
}
if *listKeysFlag {
2018-09-12 20:06:29 +03:00
if *signFlag || *verifyFlag {
return errors.New("specify --help, --sign, --verify, or --list-keys")
2017-11-29 22:36:08 +03:00
} else if len(*localUserOpt) > 0 {
return errors.New("local-user cannot be specified for list-keys")
2017-11-29 22:36:08 +03:00
} else if *detachSignFlag {
return errors.New("detach-sign cannot be specified for list-keys")
2017-11-29 22:36:08 +03:00
} else if *armorFlag {
return errors.New("armor cannot be specified for list-keys")
2017-11-29 22:36:08 +03:00
} else {
return commandListKeys()
2017-11-29 22:36:08 +03:00
}
2017-11-22 18:31:25 +03:00
}
return errors.New("specify --help, --sign, --verify, or --list-keys")
2017-11-22 18:31:25 +03:00
}