Avery Pennarun <[EMAIL PROTECTED]>:
> On Thu, Jun 13, 2002 at 01:26:42PM +0200, Bodo Moeller via RT wrote:
>> [[EMAIL PROTECTED] - Thu Jun  6 18:39:34 2002]:

>>> It appears the openssl guys goofed in 0.97beta.  The prototype for the
>>> d2i_RSAPrivateKey function in 0.9.6c, which I use, is like this:
>>> 
>>>     d2i_RSAPrivateKey(RSA **a, unsigned char **pp, long length);
>>>     
>>> ie., without a const on the second parameter.  The const should have
>>> been done like this (I think):
>>>     const unsigned char * const *pp
>>> ...which would be entirely backwards-compatible with old versions of
>>> openssl.

>> Could you explain why you think this would improve compatibility
>> (compared with 'const unsigned char **pp', which is how 'pp' should
>> be declared in 0.9.7-beta1, although the exact definition is
>> hidden behind macros)?

> Any variable that could be passed to a function taking "unsigned char **"
> could also be passed to a function taking "const unsigned char * const *". 
> Thus, using the above declaration would make openssl's api 100%
> source-compatible with previous versions, while promising an increased level
> of constness.
> 
> Using "const unsigned char **", however, is not 100% api-compatible, because
> you can't safely pass an "unsigned char **" to it, for complicated reasons
> explained in the URL I sent earlier.

[http://www.geocrawler.com/archives/3/362/1997/9/0/2036587/]

I see, so this is an C++ speciality.  As far as C is concerned, the
types should be incompatible between any of these three variants, but
compilers tend not to look that close (and otherwise you'd use a
cast).  Writing code that tries to change a 'const char' object as
shown at the above URL is possible -- the actual assignment is
illegal, but in general the compiler cannot catch this.


>> In fact the second 'const' would be wrong because the pointer that
>> 'pp' points to is updated to reflect how much of the encoded data
>> has been processed by the d2i_... function.  I.e., it is not
>> at all constant.

> Now, you caught me there.  The change I proposed earlier (adding an additional
> "const") would fix API compatibility, but promises a level of constness that
> you're not actually providing.
> 
> Unfortunately, I don't know a way around it: the problem is that the beta1
> level of constness looks right, but doesn't _actually_ promise the constness
> that it looks like it does, due to the crazy hackery described in the URL I
> sent earlier.

Prototypes alone don't really guarantee constness anyway.  If a
function is passed a 'const int *' pointer and knows somehow that the
object pointed to is not 'const' (i.e. the pointer was 'int *'
originally), it may cast the pointer back to 'int *' and modify the
object.

>                It also makes the API incompatible with older versions.  I
> can't pass the address of "unsigned char *p" to the new function.

I guess you'll have to include a cast to the new type depending on the
value of OPENSSL_VERSION_NUMBER.  I know this is ugly, but I don't
think we should un-constify the prototype to avoid such problems.
(In fact we'll have to make various other prototype changes to clean
up the API, for example 'int' quite often should be 'size_t' etc.)


-- 
Bodo M�ller <[EMAIL PROTECTED]>
PGP http://www.informatik.tu-darmstadt.de/TI/Mitarbeiter/moeller/0x36d2c658.html
* TU Darmstadt, Theoretische Informatik, Alexanderstr. 10, D-64283 Darmstadt
* Tel. +49-6151-16-6628, Fax +49-6151-16-6036
______________________________________________________________________
OpenSSL Project                                 http://www.openssl.org
Development Mailing List                       [EMAIL PROTECTED]
Automated List Manager                           [EMAIL PROTECTED]

Reply via email to