openssl.cfg: Add OpenSSL library configuration with tests (#2248)

* openssl.cfg: Add OpenSSL library configuration with tests

Reference: https://www.openssl.org/docs/man1.1.1/man3/

* openssl.cfg: Add some configurations for EVP functions

Add alloc/dealloc configuration for EVP_CIPHER_CTX_new and
EVP_CIPHER_CTX_free.
Add configuration for encryption functions that are used in example code
which is added to the tests.
This commit is contained in:
Sebastian 2019-10-31 09:21:08 +01:00 committed by amai2012
parent 181e1baa69
commit 8b2903d5ce
4 changed files with 269 additions and 0 deletions

174
cfg/openssl.cfg Normal file
View File

@ -0,0 +1,174 @@
<?xml version="1.0"?>
<def format="2">
<!-- OpenSSL Library Configuration https://www.openssl.org/ -->
<!-- The OpenSSL library is typically included by "#include <openssl/*.h>" -->
<!-- ########## OpenSSL Types ########## -->
<!-- ########## OpenSSL Macros / Defines ########## -->
<!-- ########## OpenSSL Allocation / Deallocation ########## -->
<resource>
<alloc>EVP_CIPHER_CTX_new</alloc>
<dealloc>EVP_CIPHER_CTX_free</dealloc>
</resource>
<!-- ########## OpenSSL Functions ########## -->
<!-- int BIO_free(BIO *a); -->
<function name="BIO_free">
<noreturn>false</noreturn>
<returnValue type="int"/>
<arg nr="1">
<not-uninit/>
</arg>
</function>
<!-- BIO * BIO_new(const BIO_METHOD *type); -->
<function name="BIO_new">
<noreturn>false</noreturn>
<returnValue type="BIO *"/>
<use-retval/>
<arg nr="1"/>
</function>
<!-- int BIO_printf(BIO *bio, const char *format, ...) -->
<function name="BIO_printf">
<noreturn>false</noreturn>
<returnValue type="int"/>
<leak-ignore/>
<formatstr/>
<arg nr="1">
<not-uninit/>
</arg>
<arg nr="2" direction="in">
<not-uninit/>
<formatstr/>
</arg>
</function>
<!-- int BIO_snprintf(char *buf, size_t n, const char *format, ...) -->
<function name="BIO_snprintf">
<noreturn>false</noreturn>
<returnValue type="int"/>
<leak-ignore/>
<arg nr="1" direction="out">
<minsize type="argvalue" arg="2"/>
</arg>
<arg nr="2" direction="in">
<not-uninit/>
<valid>0:</valid>
</arg>
<formatstr/>
<arg nr="3" direction="in">
<formatstr/>
<not-null/>
<not-uninit/>
</arg>
</function>
<!-- void BIO_vfree(BIO *a); -->
<function name="BIO_vfree">
<noreturn>false</noreturn>
<returnValue type="void"/>
<arg nr="1">
<not-uninit/>
</arg>
</function>
<!-- int BIO_vprintf(BIO *bio, const char *format, va_list args) -->
<function name="BIO_vprintf">
<noreturn>false</noreturn>
<returnValue type="int"/>
<leak-ignore/>
<arg nr="1">
<not-uninit/>
</arg>
<arg nr="2" direction="in">
<not-uninit/>
<formatstr/>
</arg>
<arg nr="3"/>
</function>
<!-- int BIO_vsnprintf(char *buf, size_t n, const char *format, va_list args) -->
<function name="BIO_vsnprintf">
<noreturn>false</noreturn>
<returnValue type="int"/>
<leak-ignore/>
<arg nr="1" direction="out">
<minsize type="argvalue" arg="2"/>
</arg>
<arg nr="2" direction="in">
<not-uninit/>
<valid>0:</valid>
</arg>
<arg nr="3" direction="in">
<not-null/>
<not-uninit/>
<formatstr/>
</arg>
<arg nr="4"/>
</function>
<!-- void EVP_CIPHER_CTX_free(EVP_CIPHER_CTX *ctx); -->
<function name="EVP_CIPHER_CTX_free">
<noreturn>false</noreturn>
<returnValue type="void"/>
<arg nr="1"/>
</function>
<!-- EVP_CIPHER_CTX *EVP_CIPHER_CTX_new(void); -->
<function name="EVP_CIPHER_CTX_new">
<noreturn>false</noreturn>
<returnValue type="EVP_CIPHER_CTX *"/>
<use-retval/>
</function>
<!-- int EVP_CIPHER_CTX_reset(EVP_CIPHER_CTX *ctx); -->
<function name="EVP_CIPHER_CTX_reset">
<noreturn>false</noreturn>
<returnValue type="int"/>
<leak-ignore/>
<arg nr="1">
<not-bool/>
</arg>
</function>
<!-- int EVP_EncryptFinal_ex(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl); -->
<function name="EVP_EncryptFinal_ex">
<noreturn>false</noreturn>
<returnValue type="int"/>
<leak-ignore/>
<arg nr="1"/>
<arg nr="2" direction="out"/>
<arg nr="3" direction="out">
<not-bool/>
</arg>
</function>
<!-- int EVP_EncryptInit_ex(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *type,
ENGINE *impl, const unsigned char *key, const unsigned char *iv); -->
<function name="EVP_EncryptInit_ex">
<noreturn>false</noreturn>
<returnValue type="int"/>
<leak-ignore/>
<arg nr="1"/>
<arg nr="2" direction="in">
<not-uninit/>
</arg>
<arg nr="3">
<not-uninit/>
</arg>
<arg nr="4" direction="in">
<not-uninit/>
</arg>
<arg nr="5" direction="in">
<not-uninit/>
<not-bool/>
</arg>
</function>
<!-- int EVP_EncryptUpdate(EVP_CIPHER_CTX *ctx, unsigned char *out,
int *outl, const unsigned char *in, int inl); -->
<function name="EVP_EncryptUpdate">
<noreturn>false</noreturn>
<returnValue type="int"/>
<leak-ignore/>
<arg nr="1"/>
<arg nr="2" direction="out"/>
<arg nr="3" direction="out"/>
<arg nr="4" direction="in">
<not-uninit/>
<minsize type="argvalue" arg="5"/>
</arg>
<arg nr="5" direction="in">
<not-uninit/>
<not-bool/>
<valid>0:</valid>
</arg>
</function>
</def>

67
test/cfg/openssl.c Normal file
View File

@ -0,0 +1,67 @@
// Test library configuration for openssl.cfg
//
// Usage:
// $ cppcheck --check-library --library=openssl --enable=information --error-exitcode=1 --inline-suppr --suppress=missingIncludeSystem test/cfg/openssl.c
// =>
// No warnings about bad library configuration, unmatched suppressions, etc. exitcode=0
//
#include <openssl/ssl.h>
#include <openssl/bio.h>
#include <string.h>
void valid_code(BIO * bio)
{
BIO_printf(bio, "%d\n", 1);
}
// Example for encrypting a string using IDEA (from https://www.openssl.org/docs/man1.1.1/man3/EVP_CIPHER_CTX_new.html)
int valid_code_do_crypt(char *outfile)
{
unsigned char outbuf[1024];
int outlen, tmplen;
unsigned char key[] = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15};
unsigned char iv[] = {1,2,3,4,5,6,7,8};
char intext[] = "Some Crypto Text";
EVP_CIPHER_CTX *ctx;
FILE *out;
ctx = EVP_CIPHER_CTX_new();
EVP_EncryptInit_ex(ctx, EVP_idea_cbc(), NULL, key, iv);
if (!EVP_EncryptUpdate(ctx, outbuf, &outlen, intext, strlen(intext))) {
/* Error */
EVP_CIPHER_CTX_free(ctx);
return 0;
}
if (!EVP_EncryptFinal_ex(ctx, outbuf + outlen, &tmplen)) {
/* Error */
EVP_CIPHER_CTX_free(ctx);
return 0;
}
outlen += tmplen;
EVP_CIPHER_CTX_free(ctx);
out = fopen(outfile, "wb");
if (out == NULL) {
/* Error */
return 0;
}
fwrite(outbuf, 1, outlen, out);
fclose(out);
return 1;
}
void invalidPrintfArgType_test(BIO * bio)
{
// cppcheck-suppress invalidPrintfArgType_sint
BIO_printf(bio, "%d\n", 5U);
}
void EVP_CIPHER_CTX_new_test()
{
EVP_CIPHER_CTX * ctx = EVP_CIPHER_CTX_new();
printf("%p", ctx);
// cppcheck-suppress resourceLeak
}

View File

@ -338,6 +338,33 @@ else
fi
${CPPCHECK} ${CPPCHECK_OPT} --library=libsigc++ ${DIR}libsigc++.cpp
# openssl.c
set +e
pkg-config --version
PKGCONFIG_RETURNCODE=$?
set -e
if [ $PKGCONFIG_RETURNCODE -ne 0 ]; then
echo "pkg-config needed to retrieve OpenSSL configuration is not available, skipping syntax check."
else
set +e
OPENSSLCONFIG=$(pkg-config --cflags libssl)
OPENSSLCONFIG_RETURNCODE=$?
set -e
if [ $OPENSSLCONFIG_RETURNCODE -eq 0 ]; then
set +e
echo -e "#include <openssl/ssl.h>" | ${CC} ${CC_OPT} ${OPENSSLCONFIG} -x c -
OPENSSLCONFIG_RETURNCODE=$?
set -e
if [ $OPENSSLCONFIG_RETURNCODE -ne 0 ]; then
echo "OpenSSL not completely present or not working, skipping syntax check with ${CC}."
else
echo "OpenSSL found and working, checking syntax with ${CC} now."
${CC} ${CC_OPT} ${OPENSSLCONFIG} ${DIR}openssl.c
fi
fi
fi
${CPPCHECK} ${CPPCHECK_OPT} --library=openssl ${DIR}openssl.c
# Check the syntax of the defines in the configuration files
set +e
xmlstarlet --version

View File

@ -453,6 +453,7 @@ def get_libraries():
'nspr': ['<prtypes.h>', '"prtypes.h"'],
'opengl': ['<GL/gl.h>', '<GL/glu.h>', '<GL/glut.h>'],
'openmp': ['<omp.h>'],
# 'openssl': ['<openssl/'], <= enable after release of version 1.90
'python': ['<Python.h>', '"Python.h"'],
'qt': ['<QApplication>', '<QList>', '<qlist.h>', '<QObject>', '<QString>', '<qstring.h>', '<QWidget>', '<QtWidgets>', '<QtGui'],
'ruby': ['<ruby.h>', '<ruby/', '"ruby.h"'],