Skip to content

EVP: Adapt EVP_PKEY checking, comparing and copying for provider keys#10807

Closed
levitte wants to merge 12 commits intoopenssl:masterfrom
levitte:provider-key-check+cmp+dup
Closed

EVP: Adapt EVP_PKEY checking, comparing and copying for provider keys#10807
levitte wants to merge 12 commits intoopenssl:masterfrom
levitte:provider-key-check+cmp+dup

Conversation

@levitte
Copy link
Member

@levitte levitte commented Jan 10, 2020

This affects the following function, which can now deal with provider
side domain parameters and keys:

  • EVP_PKEY_copy_parameters()
  • EVP_PKEY_missing_parameters()
  • EVP_PKEY_cmp_parameters()
  • EVP_PKEY_cmp()

This also adds the necessary EVP_KEYMGMT interfaces to support those functions, and the implementations for RSA, DSA and DH.

@levitte levitte added branch: master Applies to master branch approval: review pending This pull request needs review by a committer labels Jan 10, 2020
@levitte
Copy link
Member Author

levitte commented Jan 10, 2020

Together with #10557, #10803, #10805 and #10806, this got evp_test to pass in the #10797 torture test

@levitte
Copy link
Member Author

levitte commented Jan 13, 2020

There was a small fixup needed, but other than that, at least my personal tests go through. Final review?

Copy link
Member

Choose a reason for hiding this comment

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

What is the purpose of the assignment to i here?

Copy link
Member Author

Choose a reason for hiding this comment

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

Must be old cruft. Removing.

Copy link
Member

Choose a reason for hiding this comment

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

Doesn't seem to have been removed.

Copy link
Member Author

Choose a reason for hiding this comment

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

Nope, but if you read the comment a couple of lines up, I think the reason will become clear 😉

Copy link
Member

Choose a reason for hiding this comment

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

Wouldnt if (!ossl_assert())
return 0;
be better?

@mattcaswell
Copy link
Member

Travis failures also look relevant.

@levitte levitte changed the title EVP: Adapt EVP_PKEY checking, comparing and copying for provider keys [WIP, Pending #10837] EVP: Adapt EVP_PKEY checking, comparing and copying for provider keys Jan 14, 2020
@levitte
Copy link
Member Author

levitte commented Jan 14, 2020

After all the excellent remarks from @mattcaswell, I've had the time to rethink this PR, and have refactored it quite a bit.

Also, this is now pending #10837. (not any more, that one has been merged)

@levitte levitte changed the title [WIP, Pending #10837] EVP: Adapt EVP_PKEY checking, comparing and copying for provider keys [WIP, Pending #10837, #10850] EVP: Adapt EVP_PKEY checking, comparing and copying for provider keys Jan 15, 2020
@levitte levitte force-pushed the provider-key-check+cmp+dup branch 2 times, most recently from 3870a24 to f069026 Compare January 15, 2020 12:25
@levitte levitte changed the title [WIP, Pending #10837, #10850] EVP: Adapt EVP_PKEY checking, comparing and copying for provider keys [WIP, Pending #10850] EVP: Adapt EVP_PKEY checking, comparing and copying for provider keys Jan 15, 2020
@levitte levitte force-pushed the provider-key-check+cmp+dup branch 2 times, most recently from f7604a9 to b980b8c Compare January 18, 2020 04:30
@levitte levitte changed the title [WIP, Pending #10850] EVP: Adapt EVP_PKEY checking, comparing and copying for provider keys [WIP] EVP: Adapt EVP_PKEY checking, comparing and copying for provider keys Jan 18, 2020
@levitte levitte force-pushed the provider-key-check+cmp+dup branch from 64341d5 to 890ea03 Compare January 20, 2020 09:42
@levitte levitte changed the title [WIP] EVP: Adapt EVP_PKEY checking, comparing and copying for provider keys EVP: Adapt EVP_PKEY checking, comparing and copying for provider keys Jan 20, 2020
@levitte
Copy link
Member Author

levitte commented Jan 20, 2020

I believe this PR got the last little nudge it needed to be complete enough.

Copy link
Member

Choose a reason for hiding this comment

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

Doesn't seem to have been removed.

Copy link
Member

Choose a reason for hiding this comment

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

This doesn's seem to quite make sense...why do we check provdata2 == NULL? I would have expected:

if (provdata1 != NULL && provdata2 != NULL)

Copy link
Member Author

Choose a reason for hiding this comment

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

Good point.

Copy link
Member

Choose a reason for hiding this comment

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

Wouldn't this up ref be better inside the if block below? That way you don't have to then down-ref it in the else block. Or alternatively place it immediately before the final assignment to->pkeys[0].keymgmt = keymgmt_to

Copy link
Member Author

Choose a reason for hiding this comment

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

I'll have another look. Thanks for the heads up

Copy link
Member

Choose a reason for hiding this comment

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

So iskey, cmpkey and dupkey are mandatory?

Copy link
Member Author

Choose a reason for hiding this comment

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

Yes.

Copy link
Member

Choose a reason for hiding this comment

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

The NULL here for the libctx parameter seems wrong

Copy link
Member

Choose a reason for hiding this comment

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

I'm quite confused by what you are trying to do here...we just seem to be trying to export the key data to "whatever", regardless of whether the key already exists in a provider?

Copy link
Member Author

Choose a reason for hiding this comment

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

Not "whatever". To a keymgmt that corresponds to the type of the from key, and only if it's not already exported to the keymgmt of that key.

Copy link
Member Author

Choose a reason for hiding this comment

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

What libctx would you pass to evp_pkey_make_provided?

Copy link
Member

Choose a reason for hiding this comment

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

I'm not sure, but this is problematic. If you're trying to copy parameters from one key to another for a key type that does not exist in the default provider (but does in some other libctx) then its not going to work.

Copy link
Member

Choose a reason for hiding this comment

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

So a copy parameters operation frees any pre-existing key data? Is that the correct semantics?

Copy link
Member Author

Choose a reason for hiding this comment

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

frees any pre-existing key data

Just the legacy bits, and only if from doesn't have any legacy bits... but I need to have another look at the evp_pkey_make_provided call...

Copy link
Member

Choose a reason for hiding this comment

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

Again, I'm concerned about the use of the default libctx here. What if the default libctx doesn't have a provider for this type of key loaded?

Copy link
Member

Choose a reason for hiding this comment

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

"is or contains"...I'm not sure I understand this. Please explain?

Copy link
Member

Choose a reason for hiding this comment

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

What is this file?

Copy link
Member Author

Choose a reason for hiding this comment

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

Oops, stray

Copy link
Member

Choose a reason for hiding this comment

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

What is this file?

Copy link
Member Author

Choose a reason for hiding this comment

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

Oops, stray

Copy link
Member

@slontis slontis Jan 22, 2020

Choose a reason for hiding this comment

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

Do all entries in pk->pkeys[i] have the same domainparams setting?
If they do then maybe it should not be stored in the array.
If they dont then this logic is incorrect.

Copy link
Member Author

Choose a reason for hiding this comment

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

When I designed this cache, I did intend for it to be able to hold a mixture, but that turned out difficult / flawed. That's why you see these indicators on a per cache item basis, and you're right, it can be taken out from there. I think that's a topic for a separate PR, though...

Copy link
Member

Choose a reason for hiding this comment

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

I really dislike this being called _cmp()
cmp() to me means return 0 if equal.

Copy link
Member Author

Choose a reason for hiding this comment

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

The public name will not change, obviously, but feel free to suggest a better name for this function.

Copy link
Member

Choose a reason for hiding this comment

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

equals() ?

Copy link
Member

Choose a reason for hiding this comment

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

The old code checked for ameth == NULL (Maybe put that back in just in case)

Copy link
Member

Choose a reason for hiding this comment

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

maybe remove is or

Copy link
Member

Choose a reason for hiding this comment

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

if it does

Copy link
Member

Choose a reason for hiding this comment

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

Should this be ||

Copy link
Member

@slontis slontis Jan 22, 2020

Choose a reason for hiding this comment

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

OR
return == 0
&& == 0

Copy link
Member

Choose a reason for hiding this comment

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

Not sure why you need these null checks : BN_cmp returns 0 if both NULL or if they are equal otherwise it returns -1 or 1 dependent on a < b.. So the cmp()==0 should be sufficient.

Copy link
Member Author

Choose a reason for hiding this comment

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

I hadn't looked at BN_cmp's behavior. Thanks for the heads up

Copy link
Member

Choose a reason for hiding this comment

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

If we can set keys up via setparams would it be possible to only have the private key bit?

Copy link
Member Author

Choose a reason for hiding this comment

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

The general assumption with openssl is that a valid key pair always has the public half. A lot will fall apart if that doesn't hold true.

Copy link
Member

Choose a reason for hiding this comment

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

hmm this is an interesting check... Are we only interested in the public key comparison here?

Copy link
Member Author

Choose a reason for hiding this comment

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

I basically copied the code from dh_ameth.c. Interestingly enough, the legacy function pointer is called pub_cmp, so it's a bit more explicit. I was thinking that it would be up to the provider to decide exactly how detailed the comparison should be. In this implementation, I chose to do like we did before. For some implementations where the private half is hidden (typically HSMs), this would be the only possible comparison.

With the assumption that the private half actually corresponds to the public part, this comparison is enough. I suppose that key validation will ensure this validity?

Copy link
Member

Choose a reason for hiding this comment

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

||'s

Copy link
Member

Choose a reason for hiding this comment

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

OR...
return BN_cmp() == 0
&& BN_cmp() == 0...

@levitte levitte force-pushed the provider-key-check+cmp+dup branch from 4e77c05 to 3e3cd5b Compare January 26, 2020 16:26
This applies both to domain parameters and actual keys
This affects the following function, which can now deal with provider
side domain parameters and keys:

- EVP_PKEY_copy_parameters()
- EVP_PKEY_missing_parameters()
- EVP_PKEY_cmp_parameters()
- EVP_PKEY_cmp()
-
With ex_data support in DSA keys gone for the FIPS module, there's no
need to create a key with a library context as input, i.e. we can go
back to normal DSA_new().

Also, we avoid using DSAparams_dup(), as that does a lot of ASN.1
magic that we don't actually need.  Just duplicate P, G and Q.
- DSA_get0_p()
- DSA_get0_q()
- DSA_get0_g()
- DSA_get0_pub_key()
- DSA_get0_priv_key()
…er keys

This helps in some cases where it's not terribly important if the
provider data is a set of domain parameters or a keypair.  -1 is used
by EVP_PKEY_copy_parameters(), which allows copying from provider data
that's a keypair just as well as domain parameters.

This means that providers can't really have a strict separation
between keypairs and domain parameters, as the former is increasingly
assumed to contain the latter.
@levitte levitte force-pushed the provider-key-check+cmp+dup branch from 3e3cd5b to b2eb8e3 Compare January 28, 2020 16:08
@levitte
Copy link
Member Author

levitte commented Jan 30, 2020

I've realized that this needs reworking on a deeper level than I thought. Most of all, functions like EVP_PKEY_copy_parameters can't be implemented as a duplicating function, and it needs KEYMGMT support to import domain parameters into an already existing key. The consequence is that the KEYMGMT libcrypto <-> provider interface needs to be somewhat redesigned.

Thank you all for the feedback here, it will absolutely work as valuable input for the redesign.

PR coming up!

@levitte
Copy link
Member Author

levitte commented Jan 31, 2020

PR took a little longer than I expected. However, I've raised an issue, see #10979

@levitte
Copy link
Member Author

levitte commented Feb 3, 2020

#11006 is the new KEYMGMT design. I'll work that one into this one.

@levitte
Copy link
Member Author

levitte commented Feb 6, 2020

Killing this in favor of #11025

@levitte levitte closed this Feb 6, 2020
@levitte levitte deleted the provider-key-check+cmp+dup branch February 6, 2020 09:05
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

approval: review pending This pull request needs review by a committer branch: master Applies to master branch

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants