Reordering new API's that have a libctx, propq

SHANE LONTIS shane.lontis at oracle.com
Sun Sep 6 21:40:53 UTC 2020


The example given was EVP_PKEY_get_() and from the API name it is fairly clear what the first param should be EVP_PKEY *pkey (the API tells you this).

For the fetch case, I still think that the algorithm is the most important param.
Libctx, propq are optional parameters as far as I am concerned.

If it is decided that the libctx is more important then the API should really be something like this..
OSSL_LIBCTX_MD_fetch(), (and I dont know if that is a good idea.)..

In some places where libctx is used it is a second class parameter whose only job is to perform a sub task of fetching during a bigger operation (such as in a load),
And in these cases it should not be the first parameter..

Shane

> On 6 Sep 2020, at 4:02 pm, Richard Levitte <levitte at openssl.org> wrote:
> 
> There are many red herrings in here, and I would argue that trying to
> be too uniform in the way you think about all functions may be
> harmful, because not all functions are classified the same.
> 
> We cannot deny that many of our interfaces have an OOP flair.  We may
> be programming in C, but we very obviously have that kind of pattern,
> a "poor man's OOP" in C.  So speaking about our interfaces in OOP
> terms is not far fetched, as long as we keep in mind that we can only
> take the argument so far.
> 
> I would argue that EVP_XXX_get_whatever() / EVP_XXX_get_whatever() are
> classic accessors, and I assume that we have all been brought up with
> the description of "this" as the hidden first argument to any class
> method in C++, so it's not very far fetched to emulate that in C by
> making the instance you want details from or change details of as the
> (explicit) first argument.
> 
> I would further argue that EVP_XXX_fetch() is a constructor (of an
> instance of EVP_XXX), and that with the assumption that there is no
> "this" in a constructor, the discussion about the arguments and their
> order must be different.
> 
> What I hear, even though not in such terms, is an argument of the
> what the library context is and how that should affect the interface.
> In relation to EVP_XXX_fetch(), it seems to be more of a factory (or
> strictly speaking, the pool of resources, with hidden factory
> functions), and depending on the factory model you lean on, it might
> or might not be sensible to have it as first argument.  My you, I'm
> trying quite hard to see it from a fresh user experience (as far as I
> can imagine it...  after all, 20ish years with my fingers deep in
> OpenSSL entrails makes you not so fresh).
> 
> I think, BTW, that this really comes down to how we view the library
> context.  So far, I've seen all these interpretations (not all said
> explicitly, but clearly visible in code or how we argue about it):
> 
> - framework
> - scope (I'm unsure if that differs much from framework)
> - factory / factory pool
> - bag of resources
> 
> Personally, I have zero problems viewing it as all of these combined,
> but that requires us to be clear on how it's used in different places.
> 
> Cheers,
> Richard
> 
> On Sat, 05 Sep 2020 23:18:21 +0200,
> Tim Hudson wrote:
>> 
>> 
>> On Sun, Sep 6, 2020 at 6:55 AM Richard Levitte <levitte at openssl.org> wrote:
>> 
>>    I'd rank the algorithm name as the most important, it really can't do
>>    anything of value without it.
>> 
>> It also cannot do anything without knowing which libctx to use. Look at the implementation.
>> Without the libctx there is no "from-where" to specify. 
>> 
>> This is again hitting the concept of where do things come from and what is a default.
>> Once "global" disappears as such, logically everything comes from a libctx.
>> 
>> Your argument is basically "what" is more important than "from" or "where".
>> And the specific context here is where you see "from" or "where" can be defaulted to a value so it
>> can be deduced so it isn't (as) important in the API.
>> 
>> That would basically indicate you would (applying the same pattern/rule in a different context)
>> change:
>> 
>> int EVP_PKEY_get_int_param(EVP_PKEY *pkey, const char *key_name, int *out);
>> 
>> To the following (putting what you want as the most important rather than from):
>> 
>> int EVP_PKEY_get_int_param(char *key_name, EVP_PKEY *pkey, int *out);
>> 
>> Or pushing it right to the end after the output parameter:
>> 
>> int EVP_PKEY_get_int_param(char *key_name, int *out,EVP_PKEY *pkey);
>> 
>> The context of where things come from is actually the most critical item in any of the APIs we
>> have.
>> Even though what you want to get from where you want to get it is in the point of the API call you
>> need to specify where from first as that context sets the frame of the call.
>> 
>> Think of it around this way - we could have an implementation where we remember the last key that
>> we have used and allow you to simply indicate you use the last key or if we didn't want the last
>> key used to be able to specify it via a non-NULL pointer. This isn't that unusual an API but not
>> something I'm suggesting we add - just trying to get the point across that you are still thinking
>> of global and libctx as something super special with an exception in its handling rather than
>> applying a general rule which is pretty much what we use everywhere else.
>> 
>> And in which case where you generally don't provide a reference as there is some default meaning
>> for it in general and can provide a reference for that sort of API would this make sense to you:
>> 
>> int EVP_PKEY_get_int_param(char *key_name, int *out,EVP_PKEY *pkey);
>> 
>> If pkey is NULL then you use the last key that you referenced, if it is not then you use the
>> specified pkey. For the application the specific key_name is the most important thing (using your
>> argument that basically states the "what" is what counts). 
>> 
>> I would suggest that you really would still want to place the EVP_PKEY first - even if you had a
>> defaulting mechanism of referring to the last key used. Conceptually you always have to have
>> knowledge of from-where when you are performing a function. And that *context* is what is the most
>> important.
>> 
>> Tim.
>> 
>> 
> -- 
> Richard Levitte         levitte at openssl.org
> OpenSSL Project         https://urldefense.com/v3/__http://www.openssl.org/*levitte/__;fg!!GqivPVa7Brio!LBMCWzrxlPIM4uha9erT3Uyg_OADMapJ5oKM9cxIb8jSiKZk6rXTcJIPq5PFwnOnwQ$ 

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://mta.openssl.org/pipermail/openssl-project/attachments/20200907/cea56226/attachment.html>


More information about the openssl-project mailing list