2018-09-18 20:10:48 +03:00
//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"
2018-07-26 17:56:36 +03:00
"io"
2017-11-22 18:31:25 +03:00
"os"
2021-09-29 21:21:04 +03:00
"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"
2018-07-17 00:06:26 +03:00
// 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
2018-07-26 17:56:36 +03:00
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" )
2018-07-26 17:56:36 +03:00
// Remaining arguments
fileArgs [ ] string
2017-11-28 23:05:00 +03:00
2017-11-29 23:50:15 +03:00
idents [ ] certstore . Identity
2018-07-26 17:56:36 +03:00
// 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 ( ) {
2018-09-05 21:07:20 +03:00
if err := runCommand ( ) ; err != nil {
2018-09-05 21:12:08 +03:00
fmt . Fprintln ( os . Stderr , err )
2018-09-05 21:07:20 +03:00
os . Exit ( 1 )
}
}
2017-11-28 23:05:00 +03:00
2018-09-05 21:07:20 +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 {
2018-09-05 21:07:20 +03:00
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 {
2018-09-05 21:07:20 +03:00
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 {
2018-09-05 21:07:20 +03:00
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 {
2018-09-05 21:07:20 +03:00
return errors . New ( "specify --help, --sign, --verify, or --list-keys" )
2017-11-22 18:31:25 +03:00
} else if len ( * localUserOpt ) == 0 {
2018-09-05 21:07:20 +03:00
return errors . New ( "specify a USER-ID to sign with" )
2017-11-22 18:31:25 +03:00
} else {
2018-09-05 21:07:20 +03:00
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 {
2018-09-05 21:07:20 +03:00
return errors . New ( "specify --help, --sign, --verify, or --list-keys" )
2017-11-22 18:31:25 +03:00
} else if len ( * localUserOpt ) > 0 {
2018-09-05 21:07:20 +03:00
return errors . New ( "local-user cannot be specified for verification" )
2017-11-22 18:31:25 +03:00
} else if * detachSignFlag {
2018-09-05 21:07:20 +03:00
return errors . New ( "detach-sign cannot be specified for verification" )
2017-11-22 18:31:25 +03:00
} else if * armorFlag {
2018-09-05 21:07:20 +03:00
return errors . New ( "armor cannot be specified for verification" )
2017-11-22 18:31:25 +03:00
} else {
2018-09-05 21:07:20 +03:00
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 {
2018-09-05 21:07:20 +03:00
return errors . New ( "specify --help, --sign, --verify, or --list-keys" )
2017-11-29 22:36:08 +03:00
} else if len ( * localUserOpt ) > 0 {
2018-09-05 21:07:20 +03:00
return errors . New ( "local-user cannot be specified for list-keys" )
2017-11-29 22:36:08 +03:00
} else if * detachSignFlag {
2018-09-05 21:07:20 +03:00
return errors . New ( "detach-sign cannot be specified for list-keys" )
2017-11-29 22:36:08 +03:00
} else if * armorFlag {
2018-09-05 21:07:20 +03:00
return errors . New ( "armor cannot be specified for list-keys" )
2017-11-29 22:36:08 +03:00
} else {
2018-09-05 21:07:20 +03:00
return commandListKeys ( )
2017-11-29 22:36:08 +03:00
}
2017-11-22 18:31:25 +03:00
}
2018-07-26 17:56:36 +03:00
2018-09-05 21:07:20 +03:00
return errors . New ( "specify --help, --sign, --verify, or --list-keys" )
2017-11-22 18:31:25 +03:00
}