>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?

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                           [EMAIL PROTECTED]

Reply via email to