Fixed import paths due to go-lib restructuring; updated with gofmt.
This commit is contained in:
parent
1ef7ecaf6a
commit
7015d03394
3 changed files with 188 additions and 133 deletions
9
.gitignore
vendored
9
.gitignore
vendored
|
@ -24,6 +24,13 @@ _testmain.go
|
|||
*.prof
|
||||
vendor/*
|
||||
|
||||
# gg vendor management
|
||||
# vendor management
|
||||
vendor/src/*
|
||||
vendor/pkg/*
|
||||
src/*
|
||||
bin/*
|
||||
|
||||
.??*.sw?
|
||||
*.pub
|
||||
*.key
|
||||
*.sig
|
||||
|
|
BIN
sigtool
BIN
sigtool
Binary file not shown.
302
sigtool.go
302
sigtool.go
|
@ -13,15 +13,16 @@
|
|||
// suitability for any purpose.
|
||||
|
||||
package main
|
||||
import (
|
||||
"os"
|
||||
"io"
|
||||
"fmt"
|
||||
"path"
|
||||
|
||||
// Our pkg
|
||||
"github.com/opencoff/go-lib/options"
|
||||
"github.com/opencoff/go-lib/sign"
|
||||
import (
|
||||
"fmt"
|
||||
"io"
|
||||
"os"
|
||||
"path"
|
||||
|
||||
"github.com/opencoff/go-options"
|
||||
"github.com/opencoff/go-sign"
|
||||
"github.com/opencoff/go-utils"
|
||||
)
|
||||
|
||||
// This will be filled in by "build"
|
||||
|
@ -31,15 +32,16 @@ var Z string = path.Base(os.Args[0])
|
|||
|
||||
// die with error
|
||||
func die(f string, v ...interface{}) {
|
||||
z := fmt.Sprintf("%s: %s", Z, f)
|
||||
s := fmt.Sprintf(z, v...)
|
||||
if n := len(s); s[n-1] != '\n' { s += "\n" }
|
||||
z := fmt.Sprintf("%s: %s", Z, f)
|
||||
s := fmt.Sprintf(z, v...)
|
||||
if n := len(s); s[n-1] != '\n' {
|
||||
s += "\n"
|
||||
}
|
||||
|
||||
os.Stderr.WriteString(s)
|
||||
os.Exit(1)
|
||||
os.Stderr.WriteString(s)
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
|
||||
// Option parsing spec for the main program
|
||||
var Maindesc = fmt.Sprintf(`
|
||||
Usage: %s [options] command [options ..] [args ..]
|
||||
|
@ -57,7 +59,6 @@ sign sign, s Sign a file with a private key
|
|||
verify verify, v Verify a signature against a file and public key
|
||||
--`, Z, Z)
|
||||
|
||||
|
||||
// Option parsing spec for key gen
|
||||
var Gendesc = fmt.Sprintf(`
|
||||
Usage: %s generate [options] path-prefix
|
||||
|
@ -70,6 +71,7 @@ help -h,--help Show this help message and exit
|
|||
pw -p,--passwd Ask for a passphrase to encrypt the private key
|
||||
comment= -c=,--comment= Use 'C' as the text comment for the keys []
|
||||
envpw= -e=E,--env-pass=E Use passphrase from environment var E []
|
||||
force -F,--force Overwrite the output file if it exists [false]
|
||||
--
|
||||
--
|
||||
*
|
||||
|
@ -91,7 +93,6 @@ output=- -o=F,--output=F Write signature to file F [STDOUT]
|
|||
*
|
||||
--`, Z)
|
||||
|
||||
|
||||
// Option parsing spec for signature verification
|
||||
var Verifydesc = fmt.Sprintf(`
|
||||
Usage: %s verify [options] pubkey sig file
|
||||
|
@ -106,166 +107,213 @@ quiet -q,--quiet Don't show any output, exit with status code
|
|||
*
|
||||
--`, Z)
|
||||
|
||||
|
||||
|
||||
|
||||
// Run the generate command
|
||||
func gen(s *options.Spec, opt *options.Options) {
|
||||
if opt.GetBool("help") {
|
||||
s.PrintUsageAndExit()
|
||||
}
|
||||
if opt.GetBool("help") {
|
||||
s.PrintUsageAndExit()
|
||||
}
|
||||
|
||||
if len(opt.Args) < 1 {
|
||||
s.PrintUsageWithError(fmt.Errorf("Missing path-prefix."))
|
||||
}
|
||||
if len(opt.Args) < 1 {
|
||||
s.PrintUsageWithError(fmt.Errorf("Missing path-prefix."))
|
||||
}
|
||||
|
||||
bn := opt.Args[0]
|
||||
|
||||
var pw string
|
||||
var comm string
|
||||
var err error
|
||||
if exists(bn) && !opt.GetBool("force") {
|
||||
die("%s: Public/Private key files (%s.key, %s.pub) exist. Won't overwrite!", Z, bn, bn)
|
||||
}
|
||||
|
||||
if pwenv, ok := opt.Get("envpw"); ok {
|
||||
pw = os.Getenv(pwenv)
|
||||
} else if opt.GetBool("pw") {
|
||||
pw, err = sign.Askpass("Enter passphrase for private key", true)
|
||||
if err != nil { die("%s: %s", Z, err) }
|
||||
}
|
||||
var pw string
|
||||
var comm string
|
||||
var err error
|
||||
|
||||
comm, _ = opt.Get("comment")
|
||||
if pwenv, ok := opt.Get("envpw"); ok {
|
||||
pw = os.Getenv(pwenv)
|
||||
} else if opt.GetBool("pw") {
|
||||
pw, err = utils.Askpass("Enter passphrase for private key", true)
|
||||
if err != nil {
|
||||
die("%s: %s", Z, err)
|
||||
}
|
||||
}
|
||||
|
||||
kp, err := sign.NewKeypair()
|
||||
if err != nil { die("%s: %s", Z, err) }
|
||||
comm, _ = opt.Get("comment")
|
||||
|
||||
bn := opt.Args[0]
|
||||
kp, err := sign.NewKeypair()
|
||||
if err != nil {
|
||||
die("%s: %s", Z, err)
|
||||
}
|
||||
|
||||
err = kp.Serialize(bn, comm, pw)
|
||||
if err != nil { die("%s: %s", Z, err) }
|
||||
err = kp.Serialize(bn, comm, pw)
|
||||
if err != nil {
|
||||
die("%s: %s", Z, err)
|
||||
}
|
||||
}
|
||||
|
||||
// Return true if $bn.key or $bn.pub exist; false otherwise
|
||||
func exists(bn string) bool {
|
||||
pk := bn + ".pub"
|
||||
sk := bn + ".key"
|
||||
|
||||
if _, err := os.Stat(pk); err == nil {
|
||||
return true
|
||||
}
|
||||
if _, err := os.Stat(sk); err == nil {
|
||||
return true
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
// Run the 'sign' command.
|
||||
func signify(s *options.Spec, opt *options.Options) {
|
||||
if opt.GetBool("help") {
|
||||
s.PrintUsageAndExit()
|
||||
}
|
||||
if opt.GetBool("help") {
|
||||
s.PrintUsageAndExit()
|
||||
}
|
||||
|
||||
if len(opt.Args) < 2 {
|
||||
s.PrintUsageWithError(fmt.Errorf("Missing arguments (key? file?)"))
|
||||
}
|
||||
if len(opt.Args) < 2 {
|
||||
s.PrintUsageWithError(fmt.Errorf("Missing arguments (key? file?)"))
|
||||
}
|
||||
|
||||
var pw string
|
||||
var err error
|
||||
var fd io.Writer = os.Stdout
|
||||
var pw string
|
||||
var err error
|
||||
var fd io.Writer = os.Stdout
|
||||
|
||||
if pwenv, ok := opt.Get("envpw"); ok {
|
||||
pw = os.Getenv(pwenv)
|
||||
} else if opt.GetBool("pw") {
|
||||
pw, err = sign.Askpass("Enter passphrase for private key", false)
|
||||
if err != nil { die("%s: %s", Z, err) }
|
||||
}
|
||||
if pwenv, ok := opt.Get("envpw"); ok {
|
||||
pw = os.Getenv(pwenv)
|
||||
} else if opt.GetBool("pw") {
|
||||
pw, err = utils.Askpass("Enter passphrase for private key", false)
|
||||
if err != nil {
|
||||
die("%s: %s", Z, err)
|
||||
}
|
||||
}
|
||||
|
||||
if outf, ok := opt.Get("output"); ok {
|
||||
if outf != "-" {
|
||||
fdx, err := os.OpenFile(outf, os.O_CREATE|os.O_TRUNC|os.O_WRONLY, 0644)
|
||||
if err != nil { die("%s: Can't create output file %s: %s", Z, outf, err) }
|
||||
defer fdx.Close()
|
||||
if outf, ok := opt.Get("output"); ok {
|
||||
if outf != "-" {
|
||||
fdx, err := os.OpenFile(outf, os.O_CREATE|os.O_TRUNC|os.O_WRONLY, 0644)
|
||||
if err != nil {
|
||||
die("%s: Can't create output file %s: %s", Z, outf, err)
|
||||
}
|
||||
defer fdx.Close()
|
||||
|
||||
fd = fdx
|
||||
}
|
||||
}
|
||||
fd = fdx
|
||||
}
|
||||
}
|
||||
|
||||
kn := opt.Args[0]
|
||||
fn := opt.Args[1]
|
||||
kn := opt.Args[0]
|
||||
fn := opt.Args[1]
|
||||
|
||||
pk, err := sign.ReadPrivateKey(kn, pw)
|
||||
if err != nil { die("%s: %s", Z, err) }
|
||||
pk, err := sign.ReadPrivateKey(kn, pw)
|
||||
if err != nil {
|
||||
die("%s: %s", Z, err)
|
||||
}
|
||||
|
||||
sig, err := pk.SignFile(fn)
|
||||
if err != nil { die("%s: %s", Z, err) }
|
||||
sig, err := pk.SignFile(fn)
|
||||
if err != nil {
|
||||
die("%s: %s", Z, err)
|
||||
}
|
||||
|
||||
sigo, err := sig.Serialize(fmt.Sprintf("inpfile=%s", fn))
|
||||
sigo, err := sig.Serialize(fmt.Sprintf("inpfile=%s", fn))
|
||||
|
||||
fd.Write(sigo)
|
||||
fd.Write(sigo)
|
||||
}
|
||||
|
||||
// Verify signature on a given file
|
||||
func verify(s *options.Spec, opt *options.Options) {
|
||||
if opt.GetBool("help") {
|
||||
s.PrintUsageAndExit()
|
||||
}
|
||||
if opt.GetBool("help") {
|
||||
s.PrintUsageAndExit()
|
||||
}
|
||||
|
||||
if len(opt.Args) < 3 {
|
||||
s.PrintUsageWithError(fmt.Errorf("Missing arguments (key? file? pubkey?)"))
|
||||
}
|
||||
if len(opt.Args) < 3 {
|
||||
s.PrintUsageWithError(fmt.Errorf("Missing arguments (key? file? pubkey?)"))
|
||||
}
|
||||
|
||||
pn := opt.Args[0]
|
||||
sn := opt.Args[1]
|
||||
fn := opt.Args[2]
|
||||
pn := opt.Args[0]
|
||||
sn := opt.Args[1]
|
||||
fn := opt.Args[2]
|
||||
|
||||
sig, err := sign.ReadSignature(sn)
|
||||
if err != nil { die("%s: Can't read signature '%s': %s", Z, sn, err) }
|
||||
sig, err := sign.ReadSignature(sn)
|
||||
if err != nil {
|
||||
die("%s: Can't read signature '%s': %s", Z, sn, err)
|
||||
}
|
||||
|
||||
pk, err := sign.ReadPublicKey(pn)
|
||||
if err != nil { die("%s: %s", Z, err) }
|
||||
pk, err := sign.ReadPublicKey(pn)
|
||||
if err != nil {
|
||||
die("%s: %s", Z, err)
|
||||
}
|
||||
|
||||
if !sig.IsPKMatch(pk) { die("Wrong public key '%s' for verifying '%s'", pn, sn) }
|
||||
if !sig.IsPKMatch(pk) {
|
||||
die("Wrong public key '%s' for verifying '%s'", pn, sn)
|
||||
}
|
||||
|
||||
ok, err := pk.VerifyFile(fn, sig)
|
||||
if err != nil { die("%s: %s", Z, err) }
|
||||
ok, err := pk.VerifyFile(fn, sig)
|
||||
if err != nil {
|
||||
die("%s: %s", Z, err)
|
||||
}
|
||||
|
||||
exit := 0
|
||||
if !ok { exit = 1 }
|
||||
exit := 0
|
||||
if !ok {
|
||||
exit = 1
|
||||
}
|
||||
|
||||
if !opt.GetBool("quiet") {
|
||||
if ok {
|
||||
fmt.Printf("%s: Signature %s verified\n", fn, sn)
|
||||
} else {
|
||||
fmt.Printf("%s: Signature %s verification FAILURE\n", fn, sn)
|
||||
}
|
||||
}
|
||||
if !opt.GetBool("quiet") {
|
||||
if ok {
|
||||
fmt.Printf("%s: Signature %s verified\n", fn, sn)
|
||||
} else {
|
||||
fmt.Printf("%s: Signature %s verification failure\n", fn, sn)
|
||||
}
|
||||
}
|
||||
|
||||
os.Exit(exit)
|
||||
os.Exit(exit)
|
||||
}
|
||||
|
||||
|
||||
func main() {
|
||||
|
||||
var env = []string{}
|
||||
var env = []string{}
|
||||
|
||||
spec := options.MustParse(Maindesc)
|
||||
gspec := options.MustParse(Gendesc)
|
||||
sspec := options.MustParse(Signdesc)
|
||||
vspec := options.MustParse(Verifydesc)
|
||||
spec := options.MustParse(Maindesc)
|
||||
gspec := options.MustParse(Gendesc)
|
||||
sspec := options.MustParse(Signdesc)
|
||||
vspec := options.MustParse(Verifydesc)
|
||||
|
||||
opts, err := spec.Interpret(os.Args, env)
|
||||
if err != nil { die("%s", err) }
|
||||
opts, err := spec.Interpret(os.Args, env)
|
||||
if err != nil {
|
||||
die("%s", err)
|
||||
}
|
||||
|
||||
if opts.GetBool("help") { spec.PrintUsageAndExit() }
|
||||
if opts.GetBool("ver") {
|
||||
fmt.Printf("%s: %s\n", Z, Version)
|
||||
os.Exit(0)
|
||||
}
|
||||
if opts.GetBool("help") {
|
||||
spec.PrintUsageAndExit()
|
||||
}
|
||||
if opts.GetBool("ver") {
|
||||
fmt.Printf("%s: %s\n", Z, Version)
|
||||
os.Exit(0)
|
||||
}
|
||||
|
||||
switch opts.Command {
|
||||
case "gen":
|
||||
o, err := gspec.Interpret(opts.Args, env)
|
||||
if err != nil { die("%s", err) }
|
||||
gen(gspec, o)
|
||||
switch opts.Command {
|
||||
case "gen":
|
||||
o, err := gspec.Interpret(opts.Args, env)
|
||||
if err != nil {
|
||||
die("%s", err)
|
||||
}
|
||||
gen(gspec, o)
|
||||
|
||||
case "sign":
|
||||
ox, err := sspec.Interpret(opts.Args, env)
|
||||
if err != nil { die("%s", err) }
|
||||
signify(sspec, ox)
|
||||
case "sign":
|
||||
ox, err := sspec.Interpret(opts.Args, env)
|
||||
if err != nil {
|
||||
die("%s", err)
|
||||
}
|
||||
signify(sspec, ox)
|
||||
|
||||
case "verify":
|
||||
ox, err := vspec.Interpret(opts.Args, env)
|
||||
if err != nil { die("%s", err) }
|
||||
verify(vspec, ox)
|
||||
case "verify":
|
||||
ox, err := vspec.Interpret(opts.Args, env)
|
||||
if err != nil {
|
||||
die("%s", err)
|
||||
}
|
||||
verify(vspec, ox)
|
||||
|
||||
default:
|
||||
die("%s: Forgot to add code for command %s", Z, opts.Command)
|
||||
}
|
||||
default:
|
||||
die("%s: Forgot to add code for command %s", Z, opts.Command)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// vim: ft=go:sw=4:ts=4:expandtab:tw=78:
|
||||
// vim: ft=go:sw=8:ts=8:noexpandtab:tw=98:
|
||||
|
|
Loading…
Add table
Reference in a new issue