Skip to content
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

notary key generate shouldn't be restricted to root keys #1134

Merged
merged 2 commits into from
May 30, 2017

Conversation

endophage
Copy link
Contributor

It also gains the -o/--output flag, which if provided will cause the public and private key to be output to the filepath specified in the flag with the .pub and .priv file extensions respectively.

Signed-off-by: David Lawrence [email protected] (github: endophage)

@endophage endophage force-pushed the generate_delegation_keys branch 3 times, most recently from 4b2a686 to 4070365 Compare April 7, 2017 07:27
Copy link
Contributor

@ecordell ecordell left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a great addition :) I have a few UX concerns but I'm excited that this is being added.

@@ -14,10 +14,13 @@ import (
store "github.com/docker/notary/storage"
"github.com/docker/notary/trustmanager"
"github.com/docker/notary/tuf/data"
tufutils "github.com/docker/notary/tuf/utils"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think in other packages this is tufUtils

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Did a search in the project, it's consistently tufutils (all lower case)

@@ -38,7 +41,7 @@ var cmdRotateKeyTemplate = usageTemplate{
Long: `Generates a new key for the given Globally Unique Name and role (one of "snapshot", "targets", "root", or "timestamp"). If rotating to a server-managed key, a new key is requested from the server rather than generated. If the generation or key request is successful, the key rotation is immediately published. No other changes, even if they are staged, will be published.`,
}

var cmdKeyGenerateRootKeyTemplate = usageTemplate{
var cmdKeyGenerateKeyTemplate = usageTemplate{
Use: "generate [ algorithm ]",
Short: "Generates a new root key with a given algorithm.",
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should update the description

cmd.AddCommand(cmdKeyGenerateRootKeyTemplate.ToCommand(k.keysGenerateRootKey))
cmdGenerate := cmdKeyGenerateKeyTemplate.ToCommand(k.keysGenerate)
cmdGenerate.Flags().StringVarP(
&k.outFile,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should --output only output the public key? Or at least have different flags for pub/priv out?

I'm just thinking about the case where you're storing in a yubikey but still want the public part output to a file.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is to work in tandem with the PR to update notary add which allows keys to be provided on the CLI. My expectation is this would be used to generate delegation keys, which at the moment is a pain as they have to be generated with OpenSSL.

@@ -159,7 +170,7 @@ func (k *keyCommander) keysList(cmd *cobra.Command, args []string) error {
return nil
}

func (k *keyCommander) keysGenerateRootKey(cmd *cobra.Command, args []string) error {
func (k *keyCommander) keysGenerate(cmd *cobra.Command, args []string) error {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Shouldn't this take a role now?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The command functions have a set signature required to meet one of the Cobra interfaces. It can't be changed.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Right! I meant as one of the command args, which you took care of.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah sorry, misunderstood!

}
cs := cryptoservice.NewCryptoService(ks...)

pubKey, err := cs.Create(data.CanonicalRootRole, "", algorithm)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think the UX is a little confusing - it generates a root key if no output is defined?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, I wasn't sure about how to handle that. I didn't want to add a flag while I was uncertain about whether we'd be following up the PKCS#8 stuff with a PR to remove roles and guns from the PEMs.

Having seen how people use Notary, and have trouble using Notary, one of the things I wanted to discuss at DockerCon was how much we try to farm out some of the data management. We're not doing any special with keys so would it be more obvious for users if we just made them manage their own keys? Key management right now is almost too magic... We'd still need integrations for things like Yubikeys, but maybe a user would provide CLI args saying "Use Slot 3", rather than all the automatic detection we do right now.

@endophage endophage force-pushed the generate_delegation_keys branch 2 times, most recently from 51c1203 to a18a003 Compare April 7, 2017 17:39
@ecordell
Copy link
Contributor

ecordell commented Apr 7, 2017

@endophage this looks good to me if there's an extra test or two coming

@endophage endophage force-pushed the generate_delegation_keys branch 2 times, most recently from 23acee6 to 78d6438 Compare April 7, 2017 18:36
@endophage
Copy link
Contributor Author

@ecordell test added to cover the new functionality.

"storage (e.g. a Yubikey) is available, the key will be stored both " +
"on hardware and on disk (so that it can be backed up). Please make " +
"sure to back up and then remove this on-key disk immediately" +
"afterwards. If a `--output` file name is provided, two files will " +
Copy link
Contributor

@cyli cyli Apr 11, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Non-blocking grammar nit: Maybe something like: "If the --output flag is provided, two files will be written to disk relative to the current working directory (as opposed to in Notary's default on-disk key storage): the public key as <output>.pub and a private key as <output>.priv."?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If --output is absolute is won't be relative to the cwd :-P I didn't want to get into the intricacies and was relying on user general knowledge of CLI tools to make sensible assumptions about providing paths to a tool.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think that still may be the term, though. If you give something a relative link, it's relative to X, but absolute is always just absolute. I totally understand why we may want to leave that part out, though.

But would it make sense to include the rest of the above? I just mainly wanted to directly state that the extensions will be appended to whatever output file name the user gives us.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I can rephrase to make that clearer

@cyli
Copy link
Contributor

cyli commented Apr 11, 2017

Since there are no restrictions on which roles can be used for generateRole, we can generate targets/timestamp/snapshot keys as well. For those, should we also accept a GUN, or do we basically not really care about GUNs for those for now?

Also, could we add one more test for generating a delegation key without passing --output? In particular, could we also include this in the yubikey tests to make sure that the generated key also gets added to the yubikey? I tried it manually, and it didn’t work for me, but I think my setup is completely broken :( (I think maybe setting up the gpg-agent has interfered with piv stuff for me)


// if we had an outfile set, we'll write 2 files with the given name, appending .pub and .priv for the
// public and private keys respectively
return generateKeyToFile(k.generateRole, algorithm, k.getRetriever(), k.outFile)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This seems to only write the keys to a file, but does not store the key in the yubikey, if it's available.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh is that what the key will not be stored in Notary's key storage means? Neither the key storage disk or the yubikey? Could we clarify that in the docstring for the command? I thought providing an outfile would back up the keys to a different location, but also write to the yubikey.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, it only outputs to the provided file and doesn't store it anywhere else. I'm trying to reduce the magic of the commands. It would still be possible to subsequently notary key import to load the key in to a yubikey.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

At some point, not in this PR, I wonder if it'd make sense to just generate the key directly in the yubikey if available unless --output is provided (no backups - the output can be your backup, since we've had issues where folks would prefer not having the key anywhere else).

@endophage endophage force-pushed the generate_delegation_keys branch from 78d6438 to 911ffa0 Compare April 11, 2017 23:03
@endophage
Copy link
Contributor Author

endophage commented Apr 11, 2017

@cyli it came up in the PCKS#8 PR, I think GUNs in the key PEMs are going to be deprecated. Especially as keys are used across repos it become less relevant.

@cyli
Copy link
Contributor

cyli commented Apr 12, 2017

I think GUNs in the key PEMs are going to be deprecated. Especially as keys are used across repos it become less relevant.

That makes sense, thanks

@endophage
Copy link
Contributor Author

@ecordell @riyazdf @cyli was there anything else I can do here? (will rebase it now)

@endophage endophage force-pushed the generate_delegation_keys branch from 911ffa0 to 296c3bd Compare May 1, 2017 23:38
@cyli
Copy link
Contributor

cyli commented May 2, 2017

@endophage Are we expecting that this PR allows non-root keys to be imported into the yubikey?

@endophage
Copy link
Contributor Author

I wasn't planning on doing that here.

@cyli
Copy link
Contributor

cyli commented May 2, 2017

@endophage Er sorry, not import, but that the generated non-root keys will be stored in the yubikey? I think if so, we may need to remove https://github.com/docker/notary/blob/master/trustmanager/yubikey/yubikeystore.go#L704, because currently generated keys that aren't root won't get stored in the yubikey.

If not, and the plan is to do that in another PR, could we please update the description and maybe the CLI description for key generation to say that for easier change tracking?

@endophage
Copy link
Contributor Author

Same answer, wasn't planning to make any changes to the yubikey logic in this PR.

@cyli
Copy link
Contributor

cyli commented May 3, 2017

@endophage This LGTM with the caveat of updating the CLI docstring to make it clear that only root keys will be generated and put into the yubikey for now. I know the next one is probably coming soon, but if it gets delayed or if we have a release between this one and when that one comes, it may be confusing for users who may expect otherwise.

Long: "Generates a new root key with a given algorithm. If hardware key storage (e.g. a Yubikey) is available, the key will be stored both on hardware and on disk (so that it can be backed up). Please make sure to back up and then remove this on-key disk immediately afterwards.",
Short: "Generates a new key with a given algorithm.",
Long: "Generates a new key with a given algorithm. If hardware key " +
"storage (e.g. a Yubikey) is available, the key will be stored both " +
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Proposed amendment:

Generates a new key with a given algorithm. If the key is a root key and hardware key storage (e.g. a Yubikey) is available...


pubKey, err := cs.Create(data.RoleName(k.generateRole), "", algorithm)
if err != nil {
return fmt.Errorf("Failed to create a new root key: %v", err)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

s/"root key"/k.generateRole

}
cs := cryptoservice.NewCryptoService(ks...)

pubKey, err := cs.Create(data.RoleName(k.generateRole), "", algorithm)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is empty GUN intended? I noticed a comment about GUNs in PEMs being potentially deprecated but lost track if it was referring to this.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This would be necessary for the "templating", right?

Perhaps this PR should remove the GUN checks when parsing PEM files, too?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think but I'm not certain we have those checks in a few scattered places. With the PRs coming in for providing certs and keys on the CLI, I'd rather hold off on making those changes here to keep potential conflicts down.

return errors.New("no password provided")
}

privFile := strings.Join([]string{outFile, "priv"}, ".")
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm wondering if we should use .key instead, so that manually moving the key and importing should just work? .priv is conceptually fine with me, just that I'd like to add a notary key import test for it if we want to keep it that way.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the cfssl defaults are:

private: <name>-key.pem
public: <name>.pem

which seems reasonable to me, though I don't have a strong preference

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm happy to go with the cfssl filenames for consistency.

@ecordell
Copy link
Contributor

ecordell commented May 9, 2017

To clarify my approval: LGTM after @riyazdf's comments are addressed

Excited to see this in! This is a solid UX improvement.

@endophage endophage force-pushed the generate_delegation_keys branch 3 times, most recently from c7a45bb to b97f9ee Compare May 15, 2017 20:28
return nil
}

// if we had an outfile set, we'll write 2 files with the given name, appending .pub and .priv for the
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: this should be .pem and -key.pem

@@ -30,6 +30,7 @@ import (
"github.com/docker/notary/trustpinning"
"github.com/docker/notary/tuf/data"
"github.com/docker/notary/tuf/utils"
"path/filepath"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: can we put this import into the first block?

require.NoError(t, err)
assertNumKeys(t, tempDir, 0, 1, false) // key shouldn't be written to store and won't show up in keylist

// test that we can read the keys we created
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

could we additionally test a key rotate and/or key import to check that the notary CLI can ingest the key directly?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added a test for import.

@riyazdf
Copy link
Contributor

riyazdf commented May 25, 2017

jenkins, test this please

David Lawrence added 2 commits May 30, 2017 11:03
Signed-off-by: David Lawrence <[email protected]> (github: endophage)
@endophage endophage force-pushed the generate_delegation_keys branch from b97f9ee to ade502a Compare May 30, 2017 18:06
@endophage endophage merged commit 18ed13f into notaryproject:master May 30, 2017
@endophage endophage deleted the generate_delegation_keys branch May 30, 2017 21:56
@riyazdf
Copy link
Contributor

riyazdf commented Jul 11, 2017

@rubenmachuca FYI - you might have posted some personal information on a comment you left here. I've deleted the original comment, please reach out (my email is in my signoffs) if you have additional questions

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants