diff options
author | Gibheer <gibheer+git@zero-knowledge.org> | 2016-10-01 21:56:29 +0200 |
---|---|---|
committer | Gibheer <gibheer+git@zero-knowledge.org> | 2016-10-01 21:56:29 +0200 |
commit | d01892150eed9d58210eb40b7c005d5fa8e93238 (patch) | |
tree | f9d37f3d5b4f0d9afd01755801826713f47d83c3 /flags.go | |
parent | faaf7d8859895767b5e64d32c14d561d6fdb5a14 (diff) |
rework program flow
This commit is a complete rebuild of pkictl. Before everything was all
over the place and adding new commands was kind of a hassle.
Now each command has its own file and can be adjusted on a command
basis. Options are still used by the same name, but can now use
different descriptions.
Diffstat (limited to 'flags.go')
-rw-r--r-- | flags.go | 320 |
1 files changed, 0 insertions, 320 deletions
diff --git a/flags.go b/flags.go deleted file mode 100644 index 31d4e67..0000000 --- a/flags.go +++ /dev/null @@ -1,320 +0,0 @@ -package main - -// This file handles the complete parameter assignment, as some parameters are -// often used by multiple functions. - -import ( - "encoding/base64" - "fmt" - "io" - "net" - "os" - "reflect" - "strings" - - "github.com/gibheer/pki" -) - -type ( - // a container go gather all incoming flags for further processing - paramContainer struct { - outputPath string // path to output whatever is generated - inputPath string // path to an input resource - cryptType string // type of something (private key) - length int // the length of something (private key) - privateKeyPath string // path to the private key - publicKeyPath string // path to the public key - signRequestPath string // path to the certificate sign request - certificateFlags certiticateRequestRawFlags // container for certificate related flags - signature string // a base64 encoded signature - certGeneration certGenerationRaw // all certificate generation flags - caPath string // path to a certificate authority - } - - flagCheck func() error -) - -var ( - CmdRoot = &Command{ - Short: "A tool to manage keys and certificates.", - Long: `This tool provides a way to manage private and public keys, create -certificate requests and certificates and sign/verify messages.`, - } - - CmdCreatePublicKey = &Command{ - Use: "create-public", - Short: "create a public key from a private key", - Long: "Create a public key derived from a private key.", - Example: "create-public -private-key=foo.ecdsa", - Run: create_public_key, - } - - CmdSignInput = &Command{ - Use: "sign-input", - Short: "sign a text using a private key", - Long: "Create a signature using a private key", - Example: "sign-input -private-key=foo.ecdsa -input=textfile", - Run: sign_input, - } - - CmdVerifyInput = &Command{ - Use: "verify-input", - Short: "verify a text using a signature", - Long: "Verify a text using a signature and a public key.", - Example: "verify-input -public-key=foo.ecdsa.pub -input=textfile -signature=abc456", - Run: verify_input, - } - - CmdCreateSignRequest = &Command{ - Use: "create-sign-request", - Short: "create a certificate sign request", - Long: "Create a certificate sign request.", - Example: "create-sign-request -private-key=foo.ecdsa -common-name=foo -serial=1", - Run: create_sign_request, - } - - // variable to hold the raw arguments before checking - flagContainer *paramContainer - - // loaded private key - FlagPrivateKey pki.PrivateKey - // loaded public key - FlagPublicKey pki.PublicKey - // the IO handler for input - FlagInput io.ReadCloser - // the IO handler for output - FlagOutput io.WriteCloser - // signature from the args - FlagSignature []byte - // a certificate filled with the parameters - FlagCertificateRequestData *pki.CertificateData - // the certificate sign request - FlagCertificateSignRequest *pki.CertificateRequest - // the ca/certificate to use - FlagCertificate *pki.Certificate -) - -func InitFlags() { - flagContainer = ¶mContainer{} - CmdRoot.AddCommand( - CmdCreatePrivateKey, - CmdCreatePublicKey, - CmdSignInput, - CmdVerifyInput, - CmdCreateSignRequest, - CmdCreateCert, - ) - - // private-key - InitFlagOutput(CmdCreatePrivateKey) - InitFlagPrivateKeyGeneration(CmdCreatePrivateKey) - // public-key - InitFlagOutput(CmdCreatePublicKey) - InitFlagPrivateKey(CmdCreatePublicKey) - // sign-input - InitFlagInput(CmdSignInput) - InitFlagPrivateKey(CmdSignInput) - InitFlagOutput(CmdSignInput) - // verify-input - InitFlagInput(CmdVerifyInput) - InitFlagPublicKey(CmdVerifyInput) - InitFlagOutput(CmdVerifyInput) - InitFlagSignature(CmdVerifyInput) - // create-sign-request - InitFlagPrivateKey(CmdCreateSignRequest) - InitFlagOutput(CmdCreateSignRequest) - InitFlagCertificateFields(CmdCreateSignRequest) - // create-certificate - InitFlagCA(CmdCreateCert) - InitFlagCert(CmdCreateCert) - InitFlagCSR(CmdCreateCert) - InitFlagOutput(CmdCreateCert) - InitFlagPrivateKey(CmdCreateCert) -} - -// check if all checks are successful -func checkFlags(checks ...flagCheck) error { - for _, check := range checks { - if err := check(); err != nil { - return err - } - } - return nil -} - -// check if either of the inserted checks is successful -func checkFlagsEither(checks ...flagCheck) flagCheck { - return func() error { - errors := make([]error, 0) - for _, check := range checks { - if err := check(); err != nil { - errors = append(errors, err) - } - } - // it is a success, if any check is successful - if len(checks)-len(errors) > 0 { - return nil - } - return errors[0] - } -} - -// add the public key flag -func InitFlagPublicKey(cmd *Command) { - cmd.Flags().StringVar(&flagContainer.publicKeyPath, "public-key", "", "path to the public key (required)") -} - -// parse public key flag -func checkPublicKey() error { - if flagContainer.publicKeyPath == "" { - return fmt.Errorf("No public key given!") - } - - pu, err := ReadPublicKeyFile(flagContainer.publicKeyPath) - if err != nil { - return fmt.Errorf("Error reading public key: %s", err) - } - FlagPublicKey = pu - return nil -} - -// initialize the output flag -func InitFlagOutput(cmd *Command) { - cmd.Flags().StringVar(&flagContainer.outputPath, "output", "STDOUT", "path to the output or STDOUT") -} - -// parse the output parameter and open the file handle -func checkOutput() error { - if flagContainer.outputPath == "STDOUT" { - FlagOutput = os.Stdout - return nil - } - var err error - FlagOutput, err = os.OpenFile( - flagContainer.outputPath, - os.O_WRONLY|os.O_APPEND|os.O_CREATE, // do not kill users files! - 0600, - ) - if err != nil { - return err - } - return nil -} - -// add the input parameter to load resources from -func InitFlagInput(cmd *Command) { - cmd.Flags().StringVar(&flagContainer.inputPath, "input", "STDIN", "path to the input or STDIN") -} - -// parse the input parameter and open the file handle -func checkInput() error { - if flagContainer.inputPath == "STDIN" { - FlagInput = os.Stdin - return nil - } - var err error - FlagInput, err = os.Open(flagContainer.inputPath) - if err != nil { - return err - } - return nil -} - -// add the signature flag to load a signature from a signing process -func InitFlagSignature(cmd *Command) { - cmd.Flags().StringVar(&flagContainer.signature, "signature", "", "the base64 encoded signature to use for verification") -} - -// parse the signature flag -func checkSignature() error { - var err error - FlagSignature, err = base64.StdEncoding.DecodeString(flagContainer.signature) - if err != nil { - return err - } - return nil -} - -// add the certificate fields to the flags -func InitFlagCertificateFields(cmd *Command) { - cmd.Flags().StringVar( - &flagContainer.certificateFlags.manual.serialNumber, - "serial", "1", "unique serial number of the CA") - cmd.Flags().StringVar( - &flagContainer.certificateFlags.manual.commonName, - "common-name", "", "common name of the entity to certify") - cmd.Flags().StringVar( - &flagContainer.certificateFlags.manual.dnsNames, - "dns-names", "", "comma separated list of alternative fqdn entries for the entity") - cmd.Flags().StringVar( - &flagContainer.certificateFlags.manual.emailAddresses, - "email-address", "", "comma separated list of alternative email entries for the entity") - cmd.Flags().StringVar( - &flagContainer.certificateFlags.manual.ipAddresses, - "ip-address", "", "comma separated list of alternative ip entries for the entity") - cmd.Flags().StringVar( - &flagContainer.certificateFlags.automatic.Country, - "country", "", "comma separated list of countries the entitiy resides in") - cmd.Flags().StringVar( - &flagContainer.certificateFlags.automatic.Organization, - "organization", "", "comma separated list of organizations the entity belongs to") - cmd.Flags().StringVar( - &flagContainer.certificateFlags.automatic.OrganizationalUnit, - "organization-unit", "", "comma separated list of organization units or departments the entity belongs to") - cmd.Flags().StringVar( - &flagContainer.certificateFlags.automatic.Locality, - "locality", "", "comma separated list of localities or cities the entity resides in") - cmd.Flags().StringVar( - &flagContainer.certificateFlags.automatic.Province, - "province", "", "comma separated list of provinces the entity resides in") - cmd.Flags().StringVar( - &flagContainer.certificateFlags.automatic.StreetAddress, - "street-address", "", "comma separated list of street addresses the entity resides in") - cmd.Flags().StringVar( - &flagContainer.certificateFlags.automatic.PostalCode, - "postal-code", "", "comma separated list of postal codes of the localities") -} - -// parse the certificate fields into a raw certificate -func checkCertificateFields() error { - FlagCertificateRequestData = pki.NewCertificateData() - // convert the automatic flags - container_type := reflect.ValueOf(&flagContainer.certificateFlags.automatic).Elem() - cert_data_type := reflect.ValueOf(&FlagCertificateRequestData.Subject).Elem() - - for _, field := range []string{"Country", "Organization", "OrganizationalUnit", - "Locality", "Province", "StreetAddress", "PostalCode"} { - field_value := container_type.FieldByName(field).String() - if field_value == "" { - continue - } - target := cert_data_type.FieldByName(field) - target.Set(reflect.ValueOf(strings.Split(field_value, ","))) - } - - // convert the manual flags - data := FlagCertificateRequestData - raw_data := flagContainer.certificateFlags.manual - data.Subject.SerialNumber = raw_data.serialNumber - data.Subject.CommonName = raw_data.commonName - if raw_data.dnsNames != "" { - data.DNSNames = strings.Split(raw_data.dnsNames, ",") - } - if raw_data.emailAddresses != "" { - data.EmailAddresses = strings.Split(raw_data.emailAddresses, ",") - } - - if raw_data.ipAddresses == "" { - return nil - } - raw_ips := strings.Split(raw_data.ipAddresses, ",") - data.IPAddresses = make([]net.IP, len(raw_ips)) - for i, ip := range raw_ips { - data.IPAddresses[i] = net.ParseIP(ip) - if data.IPAddresses[i] == nil { - return fmt.Errorf("'%s' is not a valid IP", ip) - } - } - - return nil -} |