From 73a07e7665ceb5ea35b33091e286774e4f5ab04e Mon Sep 17 00:00:00 2001 From: Gibheer Date: Wed, 14 Jan 2015 21:42:37 +0100 Subject: add api for public keys This enables pkictl to generate public keys from private keys in the rsa and ecdsa format. --- main.go | 10 ++++++++-- private_key.go | 5 ++++- public_key.go | 46 ++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 58 insertions(+), 3 deletions(-) create mode 100644 public_key.go diff --git a/main.go b/main.go index bbb7caa..8329d47 100644 --- a/main.go +++ b/main.go @@ -13,6 +13,7 @@ const ( TypeLabelRSA = "RSA PRIVATE KEY" TypeLabelECDSA = "EC PRIVATE KEY" TypeLabelCSR = "CERTIFICATE REQUEST" + TypeLabelPubKey = "PUBLIC KEY" ) var ( @@ -24,11 +25,13 @@ func main() { crash_with_help(1, "No module selected!") } switch os.Args[1] { - case "create-private": create_private_key() + case "create-private": create_private_key() case "create-cert-sign": create_sign_request() + case "create-public": create_public_key() case "help": print_modules() case "info": info_on_file() - case "sign": sign_request() + case "sign-request": sign_request() + case "sign-input": sign_input() default: crash_with_help(1, "Command not supported!") } } @@ -37,6 +40,8 @@ func main() { func info_on_file() {} // sign a certificate request to create a new certificate func sign_request() {} +// sign a message with a private key +func sign_input() {} // open stream for given path func open_output_stream(path string) (io.WriteCloser, error) { @@ -57,6 +62,7 @@ func print_modules() { fmt.Printf(`Usage: %s command args where 'command' is one of: create-private create a new private key + create-public create a public key from a private one create-cert-sign create a new certificate sign request help show this help info get info on a file diff --git a/private_key.go b/private_key.go index ae5b90a..5e32ca8 100644 --- a/private_key.go +++ b/private_key.go @@ -1,6 +1,7 @@ package main import ( + "crypto" "crypto/elliptic" "crypto/ecdsa" "crypto/rand" @@ -15,7 +16,9 @@ import ( ) type ( - PrivateKey interface {} + PrivateKey interface { + Public() crypto.PublicKey + } CreateFlags struct { CryptType string // rsa or ecdsa diff --git a/public_key.go b/public_key.go new file mode 100644 index 0000000..fc1ea23 --- /dev/null +++ b/public_key.go @@ -0,0 +1,46 @@ +package main + +import ( + "crypto/x509" + "encoding/pem" + "flag" + "fmt" + "io" + "os" +) + +type ( + PublicKeyFlags struct { + PrivateKeyPath string + Output string + + output_stream io.WriteCloser // the actual stream to the output + } +) + +func create_public_key() { + var err error + flags := parse_public_key_flags() + flags.output_stream, err = open_output_stream(flags.Output) + if err != nil { + crash_with_help(2, fmt.Sprintf("Error when creating file %s: %s", flags.Output, err)) + } + priv_key := load_private_key(flags.PrivateKeyPath) + marshal, err := x509.MarshalPKIXPublicKey(priv_key.Public()) + if err != nil { + crash_with_help(2, fmt.Sprintf("Problems marshalling the public key: %s", err)) + } + + block := &pem.Block{Type: TypeLabelPubKey, Bytes: marshal} + pem.Encode(flags.output_stream, block) +} + +func parse_public_key_flags() PublicKeyFlags { + flags := PublicKeyFlags{} + fs := flag.NewFlagSet("create-public", flag.ExitOnError) + fs.StringVar(&flags.PrivateKeyPath, "private-key", "", "path to the private key file") + fs.StringVar(&flags.Output, "output", "STDOUT", "path where the generated csr should be stored") + fs.Parse(os.Args[2:]) + + return flags +} -- cgit v1.2.3-70-g09d2