diff options
Diffstat (limited to 'private_key.go')
-rw-r--r-- | private_key.go | 160 |
1 files changed, 24 insertions, 136 deletions
diff --git a/private_key.go b/private_key.go index 785b305..07ec3f8 100644 --- a/private_key.go +++ b/private_key.go @@ -1,145 +1,33 @@ package main -// generate an ecdsa or rsa private key - import ( - "crypto" - "crypto/elliptic" - "crypto/ecdsa" - "crypto/rand" - "crypto/rsa" - "crypto/x509" - "encoding/pem" - "flag" - "fmt" - "io" - "io/ioutil" - "os" + "errors" + "github.com/gibheer/pkilib" ) -type ( - CreateFlags struct { - CryptType string // rsa or ecdsa - CryptLength int // the bit length - Output string // a path or stream to output the private key to - - output_stream io.WriteCloser // the actual stream to the output - } +const ( + TypeLabelRSA = "RSA PRIVATE KEY" + TypeLabelECDSA = "EC PRIVATE KEY" ) -// create a new private key -func create_private_key() { - flags := parse_create_flags() - - var err error - 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)) - } - defer flags.output_stream.Close() - - switch flags.CryptType { - case "rsa": create_private_key_rsa(flags) - case "ecdsa": create_private_key_ecdsa(flags) - default: crash_with_help(2, fmt.Sprintf("%s not supported!", flags.CryptType)) - } -} - -// generate a rsa private key -func create_private_key_rsa(flags CreateFlags) { - if flags.CryptLength < 2048 { - crash_with_help(2, "Length is smaller than 2048!") - } - - priv, err := rsa.GenerateKey( rand.Reader, flags.CryptLength) - if err != nil { - fmt.Fprintln(os.Stderr, "Error: ", err) - os.Exit(3) - } - marshal := x509.MarshalPKCS1PrivateKey(priv) - block := &pem.Block{Type: TypeLabelRSA, Bytes: marshal} - pem.Encode(flags.output_stream, block) -} - -// generate a ecdsa private key -func create_private_key_ecdsa(flags CreateFlags) { - var curve elliptic.Curve - switch flags.CryptLength { - case 224: curve = elliptic.P224() - case 256: curve = elliptic.P256() - case 384: curve = elliptic.P384() - case 521: curve = elliptic.P521() - default: crash_with_help(2, "Unsupported crypt length!") - } - - priv, err := ecdsa.GenerateKey(curve, rand.Reader) - if err != nil { - fmt.Fprintln(os.Stderr, "Error: ", err) - os.Exit(3) - } - marshal, err := x509.MarshalECPrivateKey(priv) - if err != nil { - crash_with_help(2, fmt.Sprintf("Problems marshalling the private key: %s", err)) - } - block := &pem.Block{Type: TypeLabelECDSA, Bytes: marshal} - pem.Encode(flags.output_stream, block) -} - -// parse the flags to create a private key -func parse_create_flags() CreateFlags { - flags := CreateFlags{} - fs := flag.NewFlagSet("create-private", flag.ExitOnError) - fs.StringVar(&flags.CryptType, "type", "ecdsa", "which type to use to encrypt key (rsa, ecdsa)") - fs.IntVar(&flags.CryptLength, "length", 521, fmt.Sprintf( - "%i - %i for rsa; %v for ecdsa", RsaLowerLength, RsaUpperLength, EcdsaLength,)) - fs.StringVar(&flags.Output, "output", "STDOUT", "filename to store the private key") - fs.Parse(os.Args[2:]) - - return flags -} - -// load the private key stored at `path` -func load_private_key(path string) crypto.Signer { - if path == "" { - crash_with_help(2, "No path to private key supplied!") - } - - file, err := os.Open(path) - if err != nil { - crash_with_help(3, fmt.Sprintf("Error when opening private key: %s", err)) - } - defer file.Close() - - data, err := ioutil.ReadAll(file) - if err != nil { - crash_with_help(3, fmt.Sprintf("Error when reading private key: %s", err)) - } - - block, _ := pem.Decode(data) - if block.Type == TypeLabelRSA { - return load_private_key_rsa(block) - } else if block.Type == TypeLabelECDSA { - return load_private_key_ecdsa(block) - } else { - crash_with_help(2, "No valid private key file! Only RSA and ECDSA keys are allowed!") - return nil - } -} - -// parse rsa private key -func load_private_key_rsa(block *pem.Block) crypto.Signer { - key, err := x509.ParsePKCS1PrivateKey(block.Bytes) - if err != nil { - crash_with_help(3, fmt.Sprintf("Error parsing private key: %s", err)) - } - return key -} +var ( + ErrNoPKFound = errors.New("no private key found") +) -// parse ecdsa private key -func load_private_key_ecdsa(block *pem.Block) crypto.Signer { - key, err := x509.ParseECPrivateKey(block.Bytes) - if err != nil { - crash_with_help(3, fmt.Sprintf("Error parsing private key: %s", err)) - } - return key +// Read the private key from the path and try to figure out which type of key it +// might be. +func ReadPrivateKeyFile(path string) (pkilib.PrivateKey, error) { + raw_pk, err := readSectionFromFile(path, TypeLabelECDSA) + if err == nil { + pk, err := pkilib.LoadPrivateKeyEcdsa(raw_pk) + if err != nil { return nil, err } + return pk, nil + } + raw_pk, err = readSectionFromFile(path, TypeLabelRSA) + if err == nil { + pk, err := pkilib.LoadPrivateKeyRsa(raw_pk) + if err != nil { return nil, err } + return pk, nil + } + return nil, ErrNoPKFound } |