-
Notifications
You must be signed in to change notification settings - Fork 1.1k
Add ability to generate a certificate from an existing key. #1416
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -15,6 +15,7 @@ type keygenFlags struct { | |
| set *flag.FlagSet | ||
| outKeyPath *string | ||
| outPubPath *string | ||
| inKeyPath *string | ||
| curve *string | ||
| p11url *string | ||
| } | ||
|
|
@@ -24,6 +25,7 @@ func newKeygenFlags() *keygenFlags { | |
| cf.set.Usage = func() {} | ||
| cf.outPubPath = cf.set.String("out-pub", "", "Required: path to write the public key to") | ||
| cf.outKeyPath = cf.set.String("out-key", "", "Required: path to write the private key to") | ||
| cf.inKeyPath = cf.set.String("in-key", "", "Optional: Path to existing private key") | ||
| cf.curve = cf.set.String("curve", "25519", "ECDH Curve (25519, P256)") | ||
| cf.p11url = p11Flag(cf.set) | ||
| return &cf | ||
|
|
@@ -40,7 +42,9 @@ func keygen(args []string, out io.Writer, errOut io.Writer) error { | |
|
|
||
| if !isP11 { | ||
| if err = mustFlagString("out-key", cf.outKeyPath); err != nil { | ||
| return err | ||
| if *cf.inKeyPath == "" { | ||
| return err | ||
| } | ||
| } | ||
| } | ||
| if err = mustFlagString("out-pub", cf.outPubPath); err != nil { | ||
|
|
@@ -59,8 +63,22 @@ func keygen(args []string, out io.Writer, errOut io.Writer) error { | |
| } else { | ||
| switch *cf.curve { | ||
| case "25519", "X25519", "Curve25519", "CURVE25519": | ||
| pub, rawPriv = x25519Keypair() | ||
| curve = cert.Curve_CURVE25519 | ||
| if *cf.inKeyPath == "" { | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Do you think this ought to be it's own "command"? Making this a bonus feature of Also, many users encrypt their private keys, we may need to support that. I think there's a helper function for this.... somewhere?
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yes, I did spot the helper, I threw this together as a Proof-Of-Concept and without knowing if this feature was desired. I'll add encrypted keys and a new subcommand. |
||
| pub, rawPriv = x25519Keypair() | ||
| curve = cert.Curve_CURVE25519 | ||
| } else { | ||
| rawBytes, err := os.ReadFile(*cf.inKeyPath) | ||
| if err != nil { | ||
| return err | ||
| } | ||
|
|
||
| rawPriv, _, _, err = cert.UnmarshalPrivateKeyFromPEM(rawBytes) | ||
| if err != nil { | ||
| return err | ||
| } | ||
| pub, _ = x25519KeyFromPriv(rawPriv) | ||
|
|
||
| } | ||
| case "P256": | ||
| pub, rawPriv = p256Keypair() | ||
| curve = cert.Curve_P256 | ||
|
|
@@ -81,7 +99,7 @@ func keygen(args []string, out io.Writer, errOut io.Writer) error { | |
| if err != nil { | ||
| return fmt.Errorf("error while getting public key: %w", err) | ||
| } | ||
| } else { | ||
| } else if *cf.inKeyPath == "" { | ||
| err = os.WriteFile(*cf.outKeyPath, cert.MarshalPrivateKeyToPEM(curve, rawPriv), 0600) | ||
| if err != nil { | ||
| return fmt.Errorf("error while writing out-key: %s", err) | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -404,6 +404,14 @@ func newKeypair(curve cert.Curve) ([]byte, []byte) { | |
| } | ||
| } | ||
|
|
||
| func x25519KeyFromPriv(priv []byte) ([]byte, []byte) { | ||
| pubkey, err := curve25519.X25519(priv, curve25519.Basepoint) | ||
| if err != nil { | ||
| panic(err) | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. In most cases, I prefer to bubble the error back up and let the caller decide to panic
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Well the original function I modeled this one from (similar name in the same file) didn't bubble err, so I didn't do it either. That being said its a relatively minor fix, which I will implement. |
||
| } | ||
| return pubkey, priv | ||
| } | ||
|
|
||
| func x25519Keypair() ([]byte, []byte) { | ||
| privkey := make([]byte, 32) | ||
| if _, err := io.ReadFull(rand.Reader, privkey); err != nil { | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd really like to have this feature, but I think if we're going to add it, we need to support P256 as well.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
On it. My particular use case was Curve25519 but I don't see too much trouble adding this for P256 too.