Dear All,
Compiling master 20140721 both for w32 (with VC++ 9.0 express) and
WCE/ARMv4 target (with EVC4sp4 compiler + WCE 420 SDK),
I found those two cast issues :
1/ crypto/bn/bn_nist.c, function BN_nist_mod_func(...)
clarm.exe /Fotmp32dll_ARMV4\bn_nist.obj -Iinc32 -Itmp32dll_ARMV4 /O1i /
W3 /WX /GF /Gy /nologo -DUNICODE -D_UNICODE -DOPENSSL_SYSNAME_WINCE
-DWIN32_LEAN
_AND_MEAN -DL_ENDIAN -DDSO_WIN32 -DNO_CHMOD -DOPENSSL_SMALL_FOOTPRINT
-D_WIN32_W
CE=420 -DUNDER_CE=420 -DWCE_PLATFORM_STANDARDSDK -DARM -D_ARM_ -DARMV4
-I..\..\.
.\wcecompat\v12\patched3emu/include /MC -DOPENSSL_NO_RC5
-DOPENSSL_NO_MD2 -DOPEN
SSL_NO_KRB5 -DOPENSSL_NO_JPAKE -DOPENSSL_NO_STATIC_ENGINE /Zi
/Fdtmp32dll_ARMV4/
lib -D_WINDLL -D_DLL -DOPENSSL_BUILD_SHLIBCRYPTO -c .\crypto\bn\bn_nist.c
bn_nist.c
c:\users\pdelaage\dvts\contrib\openssl\snap20140721\patch1\crypto\bn\bn_nist.c(1
134) : error C2220: warning treated as error - no object file generated
c:\users\pdelaage\dvts\contrib\openssl\snap20140721\patch1\crypto\bn\bn_nist.c(1
134) : warning C4550: expression evaluates to a function which is
missing an arg
ument list
c:\users\pdelaage\dvts\contrib\openssl\snap20140721\patch1\crypto\bn\bn_nist.c(1
136) : warning C4550: expression evaluates to a function which is
missing an arg
ument list
c:\users\pdelaage\dvts\contrib\openssl\snap20140721\patch1\crypto\bn\bn_nist.c(1
138) : warning C4550: expression evaluates to a function which is
missing an arg
ument list
c:\users\pdelaage\dvts\contrib\openssl\snap20140721\patch1\crypto\bn\bn_nist.c(1
140) : warning C4550: expression evaluates to a function which is
missing an arg
ument list
c:\users\pdelaage\dvts\contrib\openssl\snap20140721\patch1\crypto\bn\bn_nist.c(1
142) : warning C4550: expression evaluates to a function which is
missing an arg
ument list
NMAKE : fatal error U1077: 'clarm.exe' : return code '0x2'
Stop.
CAUSE : The problem comes from the fact that the expressions like
"return BN_nist_mod_192" are interpreted by EVC4sp4 compiler as function
calls with missing args.
FIX : just use typedef and explicit function pointers to avoid the
ambiguity, like this :
typedef int (* pBN_nist_mod_func_t) (BIGNUM *r, const BIGNUM *a, const
BIGNUM *p, BN_CTX *ctx);
int (*BN_nist_mod_func(const BIGNUM *p))(BIGNUM *r, const BIGNUM *a,
const BIGNUM *field, BN_CTX *ctx)
{
pBN_nist_mod_func_t pfn;
if (BN_ucmp(&_bignum_nist_p_192, p) == 0)
pfn = BN_nist_mod_192;
else if (BN_ucmp(&_bignum_nist_p_224, p) == 0)
pfn = BN_nist_mod_224;
else if (BN_ucmp(&_bignum_nist_p_256, p) == 0)
pfn = BN_nist_mod_256;
else if (BN_ucmp(&_bignum_nist_p_384, p) == 0)
pfn = BN_nist_mod_384;
else if (BN_ucmp(&_bignum_nist_p_521, p) == 0)
pfn = BN_nist_mod_521;
else pfn = (pBN_nist_mod_func_t) 0;
return pfn;
}
By the way I suggest that functions returning "pointer to functions"
also use those typedefs in their prototypes, to ease the understanding
and maintenance of the code,
so for example the prototype :
int (*BN_nist_mod_func(const BIGNUM *p))(BIGNUM *r, const BIGNUM *a,
const BIGNUM *field, BN_CTX *ctx)
{...}
could/SHOULD be replaced by :
pBN_nist_mod_func_t BN_nist_mod_func(const BIGNUM *p)
{...}
using the pBN_nist_mod_func_t "pointer to function" type defined a few
lines above.
I also suggest that something like this go in some coding rules guide
one day...
More precisely I suggest that ANY sophisticated "pointer to function"
declaration be explicitely using "pointer to function" type-defs.
2/ crypto\x509v3\v3_scts.c, function timestamp_print(...), line 151,
needs a cast to long for the 4th parameter of the
ASN1_GENERALIZEDTIME_adj(...) function call:
clarm.exe /Fotmp32dll_ARMV4\v3_scts.obj -Iinc32
-Itmp32dll_ARMV4 /O1i /
W3 /WX /GF /Gy /nologo -DUNICODE -D_UNICODE -DOPENSSL_SYSNAME_WINCE
-DWIN32_LEAN
_AND_MEAN -DL_ENDIAN -DDSO_WIN32 -DNO_CHMOD -DOPENSSL_SMALL_FOOTPRINT
-D_WIN32_W
CE=420 -DUNDER_CE=420 -DWCE_PLATFORM_STANDARDSDK -DARM -D_ARM_ -DARMV4
-I..\..\.
.\wcecompat\v12\patched3emu/include /MC -DOPENSSL_NO_RC5
-DOPENSSL_NO_MD2 -DOPEN
SSL_NO_KRB5 -DOPENSSL_NO_JPAKE -DOPENSSL_NO_STATIC_ENGINE /Zi
/Fdtmp32dll_ARMV4/
lib -D_WINDLL -D_DLL -DOPENSSL_BUILD_SHLIBCRYPTO -c
.\crypto\x509v3\v3_scts.c
v3_scts.c
c:\users\pdelaage\dvts\contrib\openssl\snap20140721\patch1\crypto\x509v3\v3_scts
.c(151) : error C2220: warning treated as error - no object file generated
c:\users\pdelaage\dvts\contrib\openssl\snap20140721\patch1\crypto\x509v3\v3_scts
.c(151) : warning C4244: 'function' : conversion from 'unsigned __int64
' to 'lo
ng ', possible loss of data
NMAKE : fatal error U1077: 'clarm.exe' : return code '0x2'
Stop.
CAUSE :
this is related to the prototype in crypto/asn1/asn1.h :
ASN1_GENERALIZEDTIME *ASN1_GENERALIZEDTIME_adj(ASN1_GENERALIZEDTIME *s,
time_t t, int offset_day, long offset_sec);
the 4th parameter must be long, while it is set as something equivalent
to "__int64" at calling time in crypto\x509v3\v3_scts.c, function
timestamp_print(...).
FIX : explicit cast to 'long" here :
"....
ASN1_GENERALIZEDTIME_adj(gen, (time_t)0,
(int)(timestamp / 86400000),
(long) ((timestamp % 86400000) / 1000));
..."
It is interesting to note that this W32/WCE bug is seen by MS EVC4sp4
compiler, and not by MS VC++ 9.0 express edition compiler....
so that, in that example, testing for WCE can help to find bugs in win32...
This is just to mention that compiling the same code in various
platforms and with various tools, can help to improve it for any others,
good to remind in those times of reflexions about roadmap and platform
(un)support.
3/ crypto\x509v3\v3_scts.c, line 65, relating to SCT_TIMESTAMP type
definition :
Line 65 is defined like this :
#if (defined(_WIN32) || defined(_WIN64)) && !defined(__MINGW32__)
But in that case, compiling for WCE leads to get "#define SCT_TIMESTAMP
unsigned long long"
while the W32 version "#define SCT_TIMESTAMP unsigned __int64" should be
ok (as EVC4 supports __int64 for around 10 years...) :
So I suggest that we change the #define at line 65 like this :
#if (defined(_WIN32) || defined(_WIN64) || defined(_WIN32_WCE)) &&
!defined(__MINGW32__)
In that particular case, recent version of MSVC support "long long" as
being equivalent to __int64, ok,
but this is not documented at all in MS EVC4, although it is in fact
also supported there (yes it is), so support is just hazardous...
so it would be safier in WCE to get the __int64 definition instead of
"long long".
I guess that this kind of problem may occur in many places in the code,
for various platforms, so that isolating platform specifics in
port-dedicated sources may help...
at least to deal with some basic types declarations.
For coding rules future guide, I would then also suggest that for TYPE
definition, we use typedef instead of #define, to get stronger type
checking.
Yours sincerely,
Pierre Delaage
______________________________________________________________________
OpenSSL Project http://www.openssl.org
Development Mailing List openssl-dev@openssl.org
Automated List Manager majord...@openssl.org