RE: Adding parameters to passphrase callbacks.
-Original Message- From: Ben Laurie [mailto:[EMAIL PROTECTED]] Sent: Tuesday, June 15, 1999 5:35 AM To: [EMAIL PROTECTED] Subject: Re: Adding parameters to passphrase callbacks. Bodo Moeller wrote: "Wade L. Scholine" [EMAIL PROTECTED]: An alternative not mentioned is to make the callback type have a variable number of arguments, like typedef int (*password_cb(char *buf, int size, int rwflag, ...)); where the arg list is terminated with a null pointer constant or something. This would still break existing code, but which would allow for more or less arbitrary parameters to callbacks. [...] Actually this version, while looking reasonably at first sight, does not work at all: The library cannot know with parameter list should be used when calling the callback functions. After all, the extra parameters are not for data that the library thinks the callback should know about, but for data about which the library knows nothing, but which the application wants to "tunnel" to its callback functions. I presume the intention was that ... would either be a void *, or nothing. In which case, passing the extra parameter is strictly incorrect (you shouldn't access parameters that weren't actually passed) but likely to be harmless. However, I prefer the alternative, so I'm only saying this for correctness. Actually, the intention was that ... would be arbitrary stuff, with a NULL to mark the end. I'm now convinced that it was a dumb idea. Thanks. __ OpenSSL Project http://www.openssl.org Development Mailing List [EMAIL PROTECTED] Automated List Manager [EMAIL PROTECTED]
Re: Adding parameters to passphrase callbacks.
Bodo Moeller wrote: On Tue, Jun 15, 1999 at 05:37:27PM +0100, Ben Laurie wrote: Under Windoze, callbacks are traditionally declared with CALLBACK in the prototype, which, I think, uses Pascal linkage (the afore-mentioned "non-C" calling convention). But many of the callback pointers in OpenSSL have just "int (*)()" declarations where they are called. Thus, using CALLBACK declarations to define the callback functions wouldn't work anyway, and compatibility problems that would arise for the CALLBACK calling convention are not really an issue for us. I couldn't remember, so I mentioned it while I was thinking of it. No big deal. Cheers, Ben. -- http://www.apache-ssl.org/ben.html "My grandfather once told me that there are two kinds of people: those who work and those who take the credit. He told me to try to be in the first group; there was less competition there." - Indira Gandhi __ OpenSSL Project http://www.openssl.org Development Mailing List [EMAIL PROTECTED] Automated List Manager [EMAIL PROTECTED]
Re: Adding parameters to passphrase callbacks.
Bodo Moeller wrote: [...] #undef PEM_read_PrivateKey EVP_PKEY *PEM_read_PrivateKey(FILE *fp,EVP_PKEY **x, pem_password_cb *cb) { return PEM_read_PrivateKey_ex(fp, x, cb, NULL); } two notes: 1) on compilers that support inlining, defining the above function with *static* qualifiers in the include file would build the same executable, avoiding the additional define/undef coding. 2) some compiler, specially on NT, like to call dynamically linked function with non-C calling conventions (because someone noticed that a few nanoseconds can be saved when it is the callee to free the stack, rather than the caller). This must be avoided, because the callback will end up being called with one more (NULL) parameter. Ciao Ale __ OpenSSL Project http://www.openssl.org Development Mailing List [EMAIL PROTECTED] Automated List Manager [EMAIL PROTECTED]
Re: Adding parameters to passphrase callbacks.
Bodo Moeller wrote: "Wade L. Scholine" [EMAIL PROTECTED]: An alternative not mentioned is to make the callback type have a variable number of arguments, like typedef int (*password_cb(char *buf, int size, int rwflag, ...)); where the arg list is terminated with a null pointer constant or something. This would still break existing code, but which would allow for more or less arbitrary parameters to callbacks. [...] Actually this version, while looking reasonably at first sight, does not work at all: The library cannot know with parameter list should be used when calling the callback functions. After all, the extra parameters are not for data that the library thinks the callback should know about, but for data about which the library knows nothing, but which the application wants to "tunnel" to its callback functions. I presume the intention was that ... would either be a void *, or nothing. In which case, passing the extra parameter is strictly incorrect (you shouldn't access parameters that weren't actually passed) but likely to be harmless. However, I prefer the alternative, so I'm only saying this for correctness. A void* parameter seems to be the way to go; and with the extra #defines for the then-historical three-parameter form, it won't hurt existing C programs too much. To achieve compatibility on other than C sourcecode level, we can add function stubs using the old function names, e.g. as follows (with the implementation in a new, separate file, so that it won't be linked into applications that use the macros): /* include/openssl/pem.h */ #undef PEM_read_PrivateKey EVP_PKEY *PEM_read_PrivateKey(FILE *fp,EVP_PKEY **x, pem_password_cb *); EVP_PKEY *PEM_read_PrivateKey_ex(FILE *fp,EVP_PKEY **x,pem_password_cb*,void*); #define PEM_read_PrivateKey(fp,pkeyp,callback) \ PEM_read_PrivateKey_ex(fp,pkeyp,callback,NULL) Go for it. /* crypto/pem/pem_stubs.c */ #include openssl/pem.h #undef PEM_read_PrivateKey EVP_PKEY *PEM_read_PrivateKey(FILE *fp,EVP_PKEY **x, pem_password_cb *cb) { return PEM_read_PrivateKey_ex(fp, x, cb, NULL); } Not sure there's much point in this, but if you want... Cheers, Ben. -- http://www.apache-ssl.org/ben.html "My grandfather once told me that there are two kinds of people: those who work and those who take the credit. He told me to try to be in the first group; there was less competition there." - Indira Gandhi __ OpenSSL Project http://www.openssl.org Development Mailing List [EMAIL PROTECTED] Automated List Manager [EMAIL PROTECTED]
Re: Adding parameters to passphrase callbacks.
On Tue, Jun 15, 1999 at 10:03:18AM +0200, Alessandro Vesely wrote: Bodo Moeller wrote: [...] #undef PEM_read_PrivateKey EVP_PKEY *PEM_read_PrivateKey(FILE *fp,EVP_PKEY **x, pem_password_cb *cb) { return PEM_read_PrivateKey_ex(fp, x, cb, NULL); } two notes: 1) on compilers that support inlining, defining the above function with *static* qualifiers in the include file would build the same executable, avoiding the additional define/undef coding. Function definitions don't belong into exported header files; there is no need at all to define the above as an inline function if we have a macro of that effect. The point in defining it as a function is to produce object code that can be linked to programs which used the old header files. 2) some compiler, specially on NT, like to call dynamically linked function with non-C calling conventions (because someone noticed that a few nanoseconds can be saved when it is the callee to free the stack, rather than the caller). This must be avoided, because the callback will end up being called with one more (NULL) parameter. The callback function is not dynamically linked, it is passed as a function pointer. The functions that *take* such a function parameter will be dynamically linked, but if we have two versions of them (a new one with _ex suffix, and the old one with the same prototype that it always had) there can be no problems of this kind. However you are right if "strange" calling conventions apply also to the callback function itself (i.e. to the one which is passed as a function pointer); but I don't think this is likely to be an actual problem, given that the library currently relies on that calling functions without having a declaration of the argument list (which, I think, is equivalent to calling a function with variable parameters, although I'm not really sure of this) works as expected. __ OpenSSL Project http://www.openssl.org Development Mailing List [EMAIL PROTECTED] Automated List Manager [EMAIL PROTECTED]
Re: Adding parameters to passphrase callbacks.
On Tue, Jun 15, 1999 at 10:35:22AM +0100, Ben Laurie wrote: /* crypto/pem/pem_stubs.c */ #include openssl/pem.h #undef PEM_read_PrivateKey EVP_PKEY *PEM_read_PrivateKey(FILE *fp,EVP_PKEY **x, pem_password_cb *cb) { return PEM_read_PrivateKey_ex(fp, x, cb, NULL); } Not sure there's much point in this, but if you want... I don't really know how necessary this is, but given that the OpenSSL libraries are sometimes used for non-C programs we would break less applications. __ OpenSSL Project http://www.openssl.org Development Mailing List [EMAIL PROTECTED] Automated List Manager [EMAIL PROTECTED]
Re: Adding parameters to passphrase callbacks.
On Tue, Jun 15, 1999 at 05:37:27PM +0100, Ben Laurie wrote: Under Windoze, callbacks are traditionally declared with CALLBACK in the prototype, which, I think, uses Pascal linkage (the afore-mentioned "non-C" calling convention). But many of the callback pointers in OpenSSL have just "int (*)()" declarations where they are called. Thus, using CALLBACK declarations to define the callback functions wouldn't work anyway, and compatibility problems that would arise for the CALLBACK calling convention are not really an issue for us. __ OpenSSL Project http://www.openssl.org Development Mailing List [EMAIL PROTECTED] Automated List Manager [EMAIL PROTECTED]
Re: Adding parameters to passphrase callbacks.
"Wade L. Scholine" [EMAIL PROTECTED]: An alternative not mentioned is to make the callback type have a variable number of arguments, like typedef int (*password_cb(char *buf, int size, int rwflag, ...)); where the arg list is terminated with a null pointer constant or something. This would still break existing code, but which would allow for more or less arbitrary parameters to callbacks. [...] Actually this version, while looking reasonably at first sight, does not work at all: The library cannot know with parameter list should be used when calling the callback functions. After all, the extra parameters are not for data that the library thinks the callback should know about, but for data about which the library knows nothing, but which the application wants to "tunnel" to its callback functions. A void* parameter seems to be the way to go; and with the extra #defines for the then-historical three-parameter form, it won't hurt existing C programs too much. To achieve compatibility on other than C sourcecode level, we can add function stubs using the old function names, e.g. as follows (with the implementation in a new, separate file, so that it won't be linked into applications that use the macros): /* include/openssl/pem.h */ #undef PEM_read_PrivateKey EVP_PKEY *PEM_read_PrivateKey(FILE *fp,EVP_PKEY **x, pem_password_cb *); EVP_PKEY *PEM_read_PrivateKey_ex(FILE *fp,EVP_PKEY **x,pem_password_cb*,void*); #define PEM_read_PrivateKey(fp,pkeyp,callback) \ PEM_read_PrivateKey_ex(fp,pkeyp,callback,NULL) /* crypto/pem/pem_stubs.c */ #include openssl/pem.h #undef PEM_read_PrivateKey EVP_PKEY *PEM_read_PrivateKey(FILE *fp,EVP_PKEY **x, pem_password_cb *cb) { return PEM_read_PrivateKey_ex(fp, x, cb, NULL); } __ OpenSSL Project http://www.openssl.org Development Mailing List [EMAIL PROTECTED] Automated List Manager [EMAIL PROTECTED]
RE: Adding parameters to passphrase callbacks.
An alternative not mentioned is to make the callback type have a variable number of arguments, like This requires all callbacks to be written as varargs programs. (It often also means a different, slower, calling sequence.) This would still break existing code, but which would allow for more or less arbitrary parameters to callbacks. The "void*" approach does this as well. You create a struct that has the data you need, pass the address of that the void*, and in the callback cast the void* back to your custom struct. This is common practice (e.g., X "context", pthread_create "arg" parameter, Win32 ulParam (sic :)) and while it's not typesafe, it is the best alternative. /r$ __ OpenSSL Project http://www.openssl.org Development Mailing List [EMAIL PROTECTED] Automated List Manager [EMAIL PROTECTED]
Re: Adding parameters to passphrase callbacks.
Hi Steve, Received: from celocom.com Tue, 8 Jun 1999 20:57:29 + [...] 3. Do something evil with the cb parameter... looks like the easy way to go, although quite unelegant. EVP_PKEY *PEM_read_PrivateKey(FILE *fp,EVP_PKEY **x, void *x); This has a companion "default callback": int default_pem_callback(void *x, char *buf, int size, int rwflag); This needs a bit more explanation. Any function calling PEM_read_PrivateKey() in the "old way" will end up calling the default_pem_callback() which retains the old behaviour: treating 'x' as a passphrase callback in the "old way". Anything that wants to pass parameters to the callback can replace the default_pem_callback() and interpret the 'x' parameter in any appropriate way. This does however lose typechecking of the 'x' parameter and is a bit awkward to use. Interpreting a void * as a function pointer might also be a potential problem. It is not completely clear to me. Perhaps an example would illustrate better the point? Let me try... the client code just defines the callback int my_smart_callback(char *buf, int num, int w, void *arg) { my_arg_type * my_arg = (my_arg_type*) arg; // etc... } and then uses it as follows: evil thing; int (*obscure_pointer)(); my_arg_type arg; RSA *rsa; // ... // set arg values, e.g. arg.value_1 = 1; obscure_pointer = PEM_the_evil(my_smart_callback, arg, thing); rsa = PEM_read_RSAPrivateKey(in, NULL, obscure_pointer); // ... Really, only the evil is necessary, since obscure_pointer, which is the address of the thing, might be a temporary value, as in rsa = PEM_read_RSAPrivateKey(in, NULL, PEM_the_evil(my_smart_callback, arg, thing)); that function should prepare the evil thing and cast its address for the client int (*PEM_the_evil(int (*smart_callback)(), void *arg, evil *thing))() { memset(thing, 0, sizeof *thing); // do some other tricky stuff in order to be // 100% sure this thing cannot be a real function, // and finally thing-smart_callback = smart_callback; thing-arg = arg; return (int (*)()) thing; } now it is possible for worker functions that actually dereference the callback arguments to do their work quite safely, e.g. int PEM_some_function(int (*callback)(), ...) { evil *thing; int klen; char buf[PEM_BUFSIZE]; // ... if (callback == NULL) klen = def_callback(buf, PEM_BUFSIZE, 0); else if ((thing = check_for_the_evil_thing(callback)) != NULL) klen = (*thing-smart_callback)(buf, PEM_BUFSIZE, 0, thing-arg) else // old callback klen = (*callback)(buf, PEM_BUFSIZE, 0); // ... } All that assumes that the evil is defined as some chnk of data, followed by its useful values, e.g. typedef struct evil_struct { unsigned char stuff[128]; int (*smart_callback)(); void *arg; } evil; Finally, check_for_the_evil_thing will return NULL unless its parameter actually points to an evil object. In the latter case it casts the address for the worker function. The disadvantage of this approach is that the hack to discriminate between a honest old callback and the evil must be verified separately for each different architecture. Coding a jump to an impossible place could be an idea, e.g. static void the_dummy_function() { the_dummy_function(): the_dummy_function(): } static void set_evil_check_stuff(evil *thing) // called from PEM_the_evil { memcpy(thing, the_dummy_function, 32); } evil *check_for_the_evil_thing(int (*thing)()) { if (memcmp(thing, the_dummy_function, 32) != 0) return NULL; // more checks... return (evil*)thing; } However, care must be taken against similar techniques used for chunking code, optimizations, code being dynamically changed as a result of dynamic linking and the like. But then, I'm new to this crypto code and I'm talking to experts: what about including a signature in the evil thing? This does however have the advantage that existing code will still work and the neccessary functionality is available. Anyway thats three options, none of which IMHO is ideal. Any alternative solutions or comments anyone? Ciao Ale __ OpenSSL Project http://www.openssl.org Development Mailing List [EMAIL PROTECTED] Automated List Manager [EMAIL PROTECTED]
Re: Adding parameters to passphrase callbacks.
Dr Stephen Henson wrote: From time to time someone needs to pass a parameter to a passphrase callback. For example the prompt for the password can be set to a meaningful phrase or the passphrase itself could be set by this method. Currently this isn't directly possible and the only solutions are messy. IMHO it's about time this issue was resolved one way or the other. There are several possible solutions, some break existing code and others might be considered a bit "naughty". But first a bit more info about the way things are handled... All the passphrase callbacks are function pointers which look like: int pem_password_cb(char *buf, int size, int rwflag); 'buf' is the buffer to write the passphrase to, 'size' is the maximum length of the passphrase and 'rwflag' is set to '1' if the passphrase should be verified by asking for it twice (e.g. when setting or changing a passphrase as opposed to checking an existing one). They return the length of the password or a value =0 to indicate an error. Typically a callback is passed to a function like this: EVP_PKEY *PEM_read_PrivateKey(FILE *fp,EVP_PKEY **x, pem_password_cb *); OK enough backround. Here are a few possible solutions. 1. Just add an extra parameter. With this method the callback would become: int pem_password_cb(char *buf, int size, int rwflag, void *arg); and would be called like this: EVP_PKEY *PEM_read_PrivateKey(FILE *fp,EVP_PKEY **x, pem_password_cb *, void *arg); This main problem with this is anything existing code calling PEM_read_PrivateKey() should choke with a compilation error. The fix is trivial though: set the extra parameter to NULL and add an ignored parameter in the callback (if used). This does at least have the advantage that it solves the problem and catches any code using the "old way": that is everything at present. 2. Add a set of extra functions: EVP_PKEY *PEM_read_PrivateKey_ex(FILE *fp,EVP_PKEY **x, pem_password_cb_ex *, void *arg); int pem_password_cb_ex(char *buf, int size, int rwflag, void *arg); This might be considered overkill, would double the number of PEM functions needed and have lots of PEM 'legacy' functions using the old method that would have to stay. It would however retain compatability with existing code. 3. Do something evil with the cb parameter... EVP_PKEY *PEM_read_PrivateKey(FILE *fp,EVP_PKEY **x, void *x); This has a companion "default callback": int default_pem_callback(void *x, char *buf, int size, int rwflag); This needs a bit more explanation. Any function calling PEM_read_PrivateKey() in the "old way" will end up calling the default_pem_callback() which retains the old behaviour: treating 'x' as a passphrase callback in the "old way". Anything that wants to pass parameters to the callback can replace the default_pem_callback() and interpret the 'x' parameter in any appropriate way. This does however lose typechecking of the 'x' parameter and is a bit awkward to use. Interpreting a void * as a function pointer might also be a potential problem. This does however have the advantage that existing code will still work and the neccessary functionality is available. Anyway thats three options, none of which IMHO is ideal. Any alternative solutions or comments anyone? I think 3 is too disgusting to contemplate. 1 is OK with me: we regularly break all existing code, anyway (speaking of which, I tried to get demos/selfsign.c going the other day, but X509v3 support has changed so drastically I couldn't easily figure out how!). If you are concerned about existing code, then I'd vote for 2, but I'm not hugely keen on the precedent or the bloat. The other possibility I can think of is to add an "extra data" pointer to EVP_PKEY instead. Cheers, Ben. -- http://www.apache-ssl.org/ben.html "My grandfather once told me that there are two kinds of people: those who work and those who take the credit. He told me to try to be in the first group; there was less competition there." - Indira Gandhi __ OpenSSL Project http://www.openssl.org Development Mailing List [EMAIL PROTECTED] Automated List Manager [EMAIL PROTECTED]
Re: Adding parameters to passphrase callbacks.
At 21:54 08.06.99 +0100, you wrote: Hallo, From time to time someone needs to pass a parameter to a passphrase callback. For example the prompt for the password can be set to a meaningful phrase or the passphrase itself could be set by this method. Currently this isn't directly possible and the only solutions are messy. 2. Add a set of extra functions: EVP_PKEY *PEM_read_PrivateKey_ex(FILE *fp,EVP_PKEY **x, pem_password_cb_ex *, void *arg); int pem_password_cb_ex(char *buf, int size, int rwflag, void *arg); This might be considered overkill, would double the number of PEM functions needed and have lots of PEM 'legacy' functions using the old method that would have to stay. It would however retain compatability with existing code. We could do domething like #define PEM_read_PrivateKey(fp,pkeyp,callback)\ PEM_read_PrivateKey_ex(fp,pkeyp,callback,NULL) Would be no overkill, cause we still have only one set of functions I would prefer that... (I myself planned to do something like that...) 3. Do something evil with the cb parameter... EVP_PKEY *PEM_read_PrivateKey(FILE *fp,EVP_PKEY **x, void *x);# [...} This needs a bit more explanation. Any function calling PEM_read_PrivateKey() in the "old way" will end up calling the default_pem_callback() which retains the old behaviour: treating 'x' as a passphrase callback in the "old way". Anything that wants to pass parameters to the callback can replace the default_pem_callback() and interpret the 'x' parameter in any appropriate way. This does however lose typechecking of the 'x' parameter and is a bit awkward to use. Interpreting a void * as a function pointer might also be a potential problem. No please ! By Goetz -- Goetz Babin-Ebell mailto:[EMAIL PROTECTED] TC Trust Center for Security http://www.trustcenter.de in Data Networks GmbH Tel.: +49-40-766 29 3301 Am Werder 1 / 21073 Hamburg / Germany Fax.: +49-40-766 29 577 __ OpenSSL Project http://www.openssl.org Development Mailing List [EMAIL PROTECTED] Automated List Manager [EMAIL PROTECTED]
Re: Adding parameters to passphrase callbacks.
Hi Steve, Received: from celocom.com Tue, 8 Jun 1999 20:57:29 + [...] 3. Do something evil with the cb parameter... looks like the easy way to go, although quite unelegant. EVP_PKEY *PEM_read_PrivateKey(FILE *fp,EVP_PKEY **x, void *x); This has a companion "default callback": int default_pem_callback(void *x, char *buf, int size, int rwflag); This needs a bit more explanation. Any function calling PEM_read_PrivateKey() in the "old way" will end up calling the default_pem_callback() which retains the old behaviour: treating 'x' as a passphrase callback in the "old way". Anything that wants to pass parameters to the callback can replace the default_pem_callback() and interpret the 'x' parameter in any appropriate way. This does however lose typechecking of the 'x' parameter and is a bit awkward to use. Interpreting a void * as a function pointer might also be a potential problem. It is not completely clear to me. Perhaps an example would illustrate better the point? Let me try... the client code just defines the callback int my_smart_callback(char *buf, int num, int w, void *arg) { my_arg_type * my_arg = (my_arg_type*) arg; // etc... } and then uses it as follows: evil thing; int (*obscure_pointer)(); my_arg_type arg; RSA *rsa; // ... // set arg values, e.g. arg.value_1 = 1; obscure_pointer = PEM_the_evil(my_smart_callback, arg, thing); rsa = PEM_read_RSAPrivateKey(in, NULL, obscure_pointer); // ... Really, only the evil is necessary, since obscure_pointer, which is the address of the thing, might be a temporary value, as in rsa = PEM_read_RSAPrivateKey(in, NULL, PEM_the_evil(my_smart_callback, arg, thing)); that function should prepare the evil thing and cast its address for the client int (*PEM_the_evil(int (*smart_callback)(), void *arg, evil *thing))() { memset(thing, 0, sizeof *thing); // do some other tricky stuff in order to be // 100% sure this thing cannot be a real function, // and finally thing-smart_callback = smart_callback; thing-arg = arg; return (int (*)()) thing; } now it is possible for worker functions that actually dereference the callback arguments to do their work quite safely, e.g. int PEM_some_function(int (*callback)(), ...) { evil *thing; int klen; char buf[PEM_BUFSIZE]; // ... if (callback == NULL) klen = def_callback(buf, PEM_BUFSIZE, 0); else if ((thing = check_for_the_evil_thing(callback)) != NULL) klen = (*thing-smart_callback)(buf, PEM_BUFSIZE, 0, thing-arg) else // old callback klen = (*callback)(buf, PEM_BUFSIZE, 0); // ... } All that assumes that the evil is defined as some chnk of data, followed by its useful values, e.g. typedef struct evil_struct { unsigned char stuff[128]; int (*smart_callback)(); void *arg; } evil; Finally, check_for_the_evil_thing will return NULL unless its parameter actually points to an evil object. In the latter case it casts the address for the worker function. The disadvantage of this approach is that the hack to discriminate between a honest old callback and the evil must be verified separately for each different architecture. Coding a jump to an impossible place could be an idea, e.g. static void the_dummy_function() { the_dummy_function(): the_dummy_function(): } static void set_evil_check_stuff(evil *thing) // called from PEM_the_evil { memcpy(thing, the_dummy_function, 32); } evil *check_for_the_evil_thing(int (*thing)()) { if (memcmp(thing, the_dummy_function, 32) != 0) return NULL; // more checks... return (evil*)thing; } However, care must be taken against similar techniques used for chunking code, optimizations, code being dynamically changed as a result of dynamic linking and the like. But then, I'm new to this crypto code and I'm talking to experts: what about including a signature in the evil thing? This does however have the advantage that existing code will still work and the neccessary functionality is available. Anyway thats three options, none of which IMHO is ideal. Any alternative solutions or comments anyone? Ciao Ale (sorry if this message has possibly been duplicated) __ OpenSSL Project http://www.openssl.org Development Mailing List [EMAIL PROTECTED] Automated List Manager [EMAIL PROTECTED]
Re: Adding parameters to passphrase callbacks.
At 10:26 09.06.99 +0100, you wrote: Dr Stephen Henson wrote: I think 3 is too disgusting to contemplate. 1 is OK with me: we regularly break all existing code, anyway (speaking of which, I tried to get demos/selfsign.c going the other day, but X509v3 support has changed so drastically I couldn't easily figure out how!). If you are concerned about existing code, then I'd vote for 2, but I'm not hugely keen on the precedent or the bloat. The other possibility I can think of is to add an "extra data" pointer to EVP_PKEY instead. But this way you couldn't do PKey = PEM_read_PrivateKey(fp,NULL,cb) and let PEM_read_PrivateKey() handle the allocation for you By Goetz -- Goetz Babin-Ebell mailto:[EMAIL PROTECTED] TC Trust Center for Security http://www.trustcenter.de in Data Networks GmbH Tel.: +49-40-766 29 3301 Am Werder 1 / 21073 Hamburg / Germany Fax.: +49-40-766 29 577 __ OpenSSL Project http://www.openssl.org Development Mailing List [EMAIL PROTECTED] Automated List Manager [EMAIL PROTECTED]
Re: Adding parameters to passphrase callbacks.
Goetz Babin-Ebell wrote: We could do domething like #define PEM_read_PrivateKey(fp,pkeyp,callback)\ PEM_read_PrivateKey_ex(fp,pkeyp,callback,NULL) Would be no overkill, cause we still have only one set of functions Oh yes. That's sensible. Cheers, Ben. -- http://www.apache-ssl.org/ben.html "My grandfather once told me that there are two kinds of people: those who work and those who take the credit. He told me to try to be in the first group; there was less competition there." - Indira Gandhi __ OpenSSL Project http://www.openssl.org Development Mailing List [EMAIL PROTECTED] Automated List Manager [EMAIL PROTECTED]
Re: Adding parameters to passphrase callbacks.
In article [EMAIL PROTECTED] you wrote: From time to time someone needs to pass a parameter to a passphrase [...] 1. Just add an extra parameter. With this method the callback would become: int pem_password_cb(char *buf, int size, int rwflag, void *arg); [...] +1, this is ok for me, because straight forward and with OpenSSL 0.9.x never mind about API changes. Better to do it now than later with any OpenSSL 1.0.x. Ralf S. Engelschall [EMAIL PROTECTED] www.engelschall.com __ OpenSSL Project http://www.openssl.org Development Mailing List [EMAIL PROTECTED] Automated List Manager [EMAIL PROTECTED]
Re: Adding parameters to passphrase callbacks.
Ben Laurie wrote: Dr Stephen Henson wrote: From time to time someone needs to pass a parameter to a passphrase callback. For example the prompt for the password can be set to a meaningful phrase or the passphrase itself could be set by this method. Currently this isn't directly possible and the only solutions are messy. IMHO it's about time this issue was resolved one way or the other. There are several possible solutions, some break existing code and others might be considered a bit "naughty". But first a bit more info about the way things are handled... All the passphrase callbacks are function pointers which look like: int pem_password_cb(char *buf, int size, int rwflag); 'buf' is the buffer to write the passphrase to, 'size' is the maximum length of the passphrase and 'rwflag' is set to '1' if the passphrase should be verified by asking for it twice (e.g. when setting or changing a passphrase as opposed to checking an existing one). They return the length of the password or a value =0 to indicate an error. Typically a callback is passed to a function like this: EVP_PKEY *PEM_read_PrivateKey(FILE *fp,EVP_PKEY **x, pem_password_cb *); OK enough backround. Here are a few possible solutions. 1. Just add an extra parameter. With this method the callback would become: int pem_password_cb(char *buf, int size, int rwflag, void *arg); and would be called like this: EVP_PKEY *PEM_read_PrivateKey(FILE *fp,EVP_PKEY **x, pem_password_cb *, void *arg); This main problem with this is anything existing code calling PEM_read_PrivateKey() should choke with a compilation error. The fix is trivial though: set the extra parameter to NULL and add an ignored parameter in the callback (if used). This does at least have the advantage that it solves the problem and catches any code using the "old way": that is everything at present. 2. Add a set of extra functions: EVP_PKEY *PEM_read_PrivateKey_ex(FILE *fp,EVP_PKEY **x, pem_password_cb_ex *, void *arg); int pem_password_cb_ex(char *buf, int size, int rwflag, void *arg); This might be considered overkill, would double the number of PEM functions needed and have lots of PEM 'legacy' functions using the old method that would have to stay. It would however retain compatability with existing code. 3. Do something evil with the cb parameter... EVP_PKEY *PEM_read_PrivateKey(FILE *fp,EVP_PKEY **x, void *x); This has a companion "default callback": int default_pem_callback(void *x, char *buf, int size, int rwflag); This needs a bit more explanation. Any function calling PEM_read_PrivateKey() in the "old way" will end up calling the default_pem_callback() which retains the old behaviour: treating 'x' as a passphrase callback in the "old way". Anything that wants to pass parameters to the callback can replace the default_pem_callback() and interpret the 'x' parameter in any appropriate way. This does however lose typechecking of the 'x' parameter and is a bit awkward to use. Interpreting a void * as a function pointer might also be a potential problem. This does however have the advantage that existing code will still work and the neccessary functionality is available. Anyway thats three options, none of which IMHO is ideal. Any alternative solutions or comments anyone? I think 3 is too disgusting to contemplate. Yes I thought you'd like it :-) 1 is OK with me: we regularly break all existing code, I don't think anyone has broken code to this degree yet. It will probably end up breaking just about anything that reads in a private key or several other kinds of PEM file. anyway (speaking of which, I tried to get demos/selfsign.c going the other day, but X509v3 support has changed so drastically I couldn't easily figure out how!). Ugh. I didn't see that. It's using the old V3 pack stuff which is rather horrible for things like bit strings. I'll fix it for the new code. If you are concerned about existing code, then I'd vote for 2, but I'm not hugely keen on the precedent or the bloat. I'm not that concerned. The other possibility I can think of is to add an "extra data" pointer to EVP_PKEY instead. Unfortunately this has to work with all PEM read/write functions not just EVP_PKEY. Steve. -- Dr Stephen N. Henson. http://www.drh-consultancy.demon.co.uk/ Personal Email: [EMAIL PROTECTED] Senior crypto engineer, Celo Communications: http://www.celocom.com/ Core developer of the OpenSSL project: http://www.openssl.org/ Business Email: [EMAIL PROTECTED] PGP key: via homepage. __ OpenSSL Project http://www.openssl.org Development Mailing List [EMAIL PROTECTED] Automated List Manager
Re: Adding parameters to passphrase callbacks.
From: Ben Laurie [EMAIL PROTECTED] ben Goetz Babin-Ebell wrote: ben We could do domething like ben ben #define PEM_read_PrivateKey(fp,pkeyp,callback)\ ben PEM_read_PrivateKey_ex(fp,pkeyp,callback,NULL) ben ben Would be no overkill, cause we still have only one set of functions ben ben Oh yes. That's sensible. I know that we don't care much about API changes in 0.9.x. However, I hope changes like that won't happen when you do care. The reason is that it would break linkage to older versions of shareable libraries (DLL's, shareable images, whatever you wanna call it). Whenever we start to care about such things, PEM_read_PrivateKey would have to be a wrapper function, not a macro. Until such discipline is established, I do not dare unleash the changes to create shareable libraries under VMS (I've most of it prepared), because I know it will be used by the VMS community the minute it shows up, and there will be a lot of whining as soon as it starts breaking (and it will break horribly if mistreated). I already get a lot of whining because of "my" changes to the DES API. And if one looks at what has changed and how, it's quite messy... -- Richard Levitte \ Spannvägen 38, II \ [EMAIL PROTECTED] Redakteur@Stacken \ S-161 43 BROMMA \ T: +46-8-26 52 47 \ SWEDEN \ or +46-708-26 53 44 Procurator Odiosus Ex Infernis -- [EMAIL PROTECTED] Unsolicited commercial email is subject to an archival fee of $400. See http://www.stacken.kth.se/~levitte/mail/ for more info. __ OpenSSL Project http://www.openssl.org Development Mailing List [EMAIL PROTECTED] Automated List Manager [EMAIL PROTECTED]
Re: Adding parameters to passphrase callbacks.
Richard Levitte - VMS Whacker wrote: From: Ben Laurie [EMAIL PROTECTED] ben Goetz Babin-Ebell wrote: ben We could do domething like ben ben #define PEM_read_PrivateKey(fp,pkeyp,callback)\ ben PEM_read_PrivateKey_ex(fp,pkeyp,callback,NULL) ben ben Would be no overkill, cause we still have only one set of functions ben ben Oh yes. That's sensible. I know that we don't care much about API changes in 0.9.x. However, I hope changes like that won't happen when you do care. The reason is that it would break linkage to older versions of shareable libraries (DLL's, shareable images, whatever you wanna call it). Whenever we start to care about such things, PEM_read_PrivateKey would have to be a wrapper function, not a macro. Of course. Cheers, Ben. -- http://www.apache-ssl.org/ben.html "My grandfather once told me that there are two kinds of people: those who work and those who take the credit. He told me to try to be in the first group; there was less competition there." - Indira Gandhi __ OpenSSL Project http://www.openssl.org Development Mailing List [EMAIL PROTECTED] Automated List Manager [EMAIL PROTECTED]
RE: Adding parameters to passphrase callbacks.
-Original Message- From: Dr Stephen Henson [mailto:[EMAIL PROTECTED]] Sent: Tuesday, June 08, 1999 4:54 PM To: [EMAIL PROTECTED] Subject: Adding parameters to passphrase callbacks. From time to time someone needs to pass a parameter to a passphrase callback. For example the prompt for the password can be set to a meaningful phrase or the passphrase itself could be set by this method. Currently this isn't directly possible and the only solutions are messy. IMHO it's about time this issue was resolved one way or the other. An alternative not mentioned is to make the callback type have a variable number of arguments, like typedef int (*password_cb(char *buf, int size, int rwflag, ...)); where the arg list is terminated with a null pointer constant or something. This would still break existing code, but which would allow for more or less arbitrary parameters to callbacks. You could combine this with Goetz's idea about #defining the old name to be a call to the new one with the terminating constant after rwflag. __ OpenSSL Project http://www.openssl.org Development Mailing List [EMAIL PROTECTED] Automated List Manager [EMAIL PROTECTED]