Fixes for various build issues with type casting and unused functions. Moved mystrnstr
to wc_port.c. Added some additional argument checks on pwdbased.
This commit is contained in:
parent
e60032b961
commit
1f00ea2115
182
src/ssl.c
182
src/ssl.c
@ -103,26 +103,6 @@
|
||||
#endif
|
||||
|
||||
|
||||
#ifndef WOLFSSL_LEANPSK
|
||||
char* mystrnstr(const char* s1, const char* s2, unsigned int n)
|
||||
{
|
||||
unsigned int s2_len = (unsigned int)XSTRLEN(s2);
|
||||
|
||||
if (s2_len == 0)
|
||||
return (char*)s1;
|
||||
|
||||
while (n >= s2_len && s1[0]) {
|
||||
if (s1[0] == s2[0])
|
||||
if (XMEMCMP(s1, s2, s2_len) == 0)
|
||||
return (char*)s1;
|
||||
s1++;
|
||||
n--;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef WOLFSSL_SESSION_EXPORT
|
||||
#ifdef WOLFSSL_DTLS
|
||||
int wolfSSL_dtls_import(WOLFSSL* ssl, unsigned char* buf, unsigned int sz)
|
||||
@ -3358,8 +3338,8 @@ const WOLFSSL_EVP_CIPHER *wolfSSL_EVP_get_cipherbynid(int id)
|
||||
#ifdef WOLFSSL_AES_256
|
||||
static char *EVP_AES_256_ECB;
|
||||
#endif
|
||||
static const int EVP_AES_SIZE = 11;
|
||||
#endif
|
||||
static const int EVP_AES_SIZE = 11;
|
||||
#endif
|
||||
|
||||
#ifndef NO_DES3
|
||||
@ -3433,6 +3413,8 @@ void wolfSSL_EVP_init(void)
|
||||
#endif /* OPENSSL_EXTRA || OPENSSL_EXTRA_X509_SMALL || HAVE_WEBSERVER */
|
||||
|
||||
|
||||
#ifndef NO_CERTS
|
||||
|
||||
/* our KeyPemToDer password callback, password in userData */
|
||||
static INLINE int OurPasswordCb(char* passwd, int sz, int rw, void* userdata)
|
||||
{
|
||||
@ -3445,8 +3427,6 @@ static INLINE int OurPasswordCb(char* passwd, int sz, int rw, void* userdata)
|
||||
return min((word32)sz, (word32)XSTRLEN((char*)userdata));
|
||||
}
|
||||
|
||||
#ifndef NO_CERTS
|
||||
|
||||
/* Return bytes written to buff or < 0 for error */
|
||||
int wolfSSL_KeyPemToDer(const unsigned char* pem, int pemSz,
|
||||
unsigned char* buff, int buffSz, const char* pass)
|
||||
@ -6339,8 +6319,84 @@ int wolfSSL_CTX_SetTmpDH_file(WOLFSSL_CTX* ctx, const char* fname, int format)
|
||||
|
||||
#endif /* NO_DH */
|
||||
|
||||
|
||||
#endif /* NO_FILESYSTEM */
|
||||
|
||||
|
||||
#if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL) || \
|
||||
defined(HAVE_WEBSERVER)
|
||||
|
||||
static int wolfSSL_EVP_get_hashinfo(const WOLFSSL_EVP_MD* evp,
|
||||
int* pHash, int* pHashSz)
|
||||
{
|
||||
enum wc_HashType hash = WC_HASH_TYPE_NONE;
|
||||
int hashSz;
|
||||
|
||||
if (XSTRLEN(evp) < 3) {
|
||||
/* do not try comparing strings if size is too small */
|
||||
return WOLFSSL_FAILURE;
|
||||
}
|
||||
|
||||
if (XSTRNCMP("SHA", evp, 3) == 0) {
|
||||
if (XSTRLEN(evp) > 3) {
|
||||
#ifndef NO_SHA256
|
||||
if (XSTRNCMP("SHA256", evp, 6) == 0) {
|
||||
hash = WC_HASH_TYPE_SHA256;
|
||||
}
|
||||
else
|
||||
#endif
|
||||
#ifdef WOLFSSL_SHA384
|
||||
if (XSTRNCMP("SHA384", evp, 6) == 0) {
|
||||
hash = WC_HASH_TYPE_SHA384;
|
||||
}
|
||||
else
|
||||
#endif
|
||||
#ifdef WOLFSSL_SHA512
|
||||
if (XSTRNCMP("SHA512", evp, 6) == 0) {
|
||||
hash = WC_HASH_TYPE_SHA512;
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
WOLFSSL_MSG("Unknown SHA hash");
|
||||
}
|
||||
}
|
||||
else {
|
||||
hash = WC_HASH_TYPE_SHA;
|
||||
}
|
||||
}
|
||||
#ifdef WOLFSSL_MD2
|
||||
else if (XSTRNCMP("MD2", evp, 3) == 0) {
|
||||
hash = WC_HASH_TYPE_MD2;
|
||||
}
|
||||
#endif
|
||||
#ifndef NO_MD4
|
||||
else if (XSTRNCMP("MD4", evp, 3) == 0) {
|
||||
hash = WC_HASH_TYPE_MD4;
|
||||
}
|
||||
#endif
|
||||
#ifndef NO_MD5
|
||||
else if (XSTRNCMP("MD5", evp, 3) == 0) {
|
||||
hash = WC_HASH_TYPE_MD5;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (pHash)
|
||||
*pHash = hash;
|
||||
|
||||
hashSz = wc_HashGetDigestSize(hash);
|
||||
if (pHashSz)
|
||||
*pHashSz = hashSz;
|
||||
|
||||
if (hashSz < 0) {
|
||||
return WOLFSSL_FAILURE;
|
||||
}
|
||||
|
||||
return WOLFSSL_SUCCESS;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef OPENSSL_EXTRA
|
||||
/* put SSL type in extra for now, not very common */
|
||||
|
||||
@ -7027,76 +7083,6 @@ void* wolfSSL_X509_get_ext_d2i(const WOLFSSL_X509* x509,
|
||||
}
|
||||
|
||||
|
||||
static int wolfSSL_EVP_get_hashinfo(const WOLFSSL_EVP_MD* evp,
|
||||
int* pHash, int* pHashSz)
|
||||
{
|
||||
enum wc_HashType hash = WC_HASH_TYPE_NONE;
|
||||
int hashSz;
|
||||
|
||||
if (XSTRLEN(evp) < 3) {
|
||||
/* do not try comparing strings if size is too small */
|
||||
return WOLFSSL_FAILURE;
|
||||
}
|
||||
|
||||
if (XSTRNCMP("SHA", evp, 3) == 0) {
|
||||
if (XSTRLEN(evp) > 3) {
|
||||
#ifndef NO_SHA256
|
||||
if (XSTRNCMP("SHA256", evp, 6) == 0) {
|
||||
hash = WC_HASH_TYPE_SHA256;
|
||||
}
|
||||
else
|
||||
#endif
|
||||
#ifdef WOLFSSL_SHA384
|
||||
if (XSTRNCMP("SHA384", evp, 6) == 0) {
|
||||
hash = WC_HASH_TYPE_SHA384;
|
||||
}
|
||||
else
|
||||
#endif
|
||||
#ifdef WOLFSSL_SHA512
|
||||
if (XSTRNCMP("SHA512", evp, 6) == 0) {
|
||||
hash = WC_HASH_TYPE_SHA512;
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
WOLFSSL_MSG("Unknown SHA hash");
|
||||
}
|
||||
}
|
||||
else {
|
||||
hash = WC_HASH_TYPE_SHA;
|
||||
}
|
||||
}
|
||||
#ifdef WOLFSSL_MD2
|
||||
else if (XSTRNCMP("MD2", evp, 3) == 0) {
|
||||
hash = WC_HASH_TYPE_MD2;
|
||||
}
|
||||
#endif
|
||||
#ifndef NO_MD4
|
||||
else if (XSTRNCMP("MD4", evp, 3) == 0) {
|
||||
hash = WC_HASH_TYPE_MD4;
|
||||
}
|
||||
#endif
|
||||
#ifndef NO_MD5
|
||||
else if (XSTRNCMP("MD5", evp, 3) == 0) {
|
||||
hash = WC_HASH_TYPE_MD5;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (pHash)
|
||||
*pHash = hash;
|
||||
|
||||
hashSz = wc_HashGetDigestSize(hash);
|
||||
if (pHashSz)
|
||||
*pHashSz = hashSz;
|
||||
|
||||
if (hashSz < 0) {
|
||||
return WOLFSSL_FAILURE;
|
||||
}
|
||||
|
||||
return WOLFSSL_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
/* this function makes the assumption that out buffer is big enough for digest*/
|
||||
static int wolfSSL_EVP_Digest(unsigned char* in, int inSz, unsigned char* out,
|
||||
unsigned int* outSz, const WOLFSSL_EVP_MD* evp,
|
||||
@ -11822,8 +11808,8 @@ int wolfSSL_set_compression(WOLFSSL* ssl)
|
||||
return ctx->passwd_userdata;
|
||||
}
|
||||
|
||||
#if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL) || \
|
||||
defined(HAVE_WEBSERVER)
|
||||
#if (defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL) || \
|
||||
defined(HAVE_WEBSERVER)) && !defined(NO_PWDBASED)
|
||||
|
||||
int wolfSSL_EVP_BytesToKey(const WOLFSSL_EVP_CIPHER* type,
|
||||
const WOLFSSL_EVP_MD* md, const byte* salt,
|
||||
@ -11866,7 +11852,7 @@ int wolfSSL_set_compression(WOLFSSL* ssl)
|
||||
return ret;
|
||||
}
|
||||
|
||||
#endif /* OPENSSL_EXTRA || OPENSSL_EXTRA_X509_SMALL || HAVE_WEBSERVER */
|
||||
#endif /* !NO_PWDBASED && (OPENSSL_EXTRA || OPENSSL_EXTRA_X509_SMALL || HAVE_WEBSERVER) */
|
||||
#endif /* WOLFSSL_ENCRYPTED_KEYS */
|
||||
|
||||
|
||||
@ -12948,7 +12934,7 @@ int wolfSSL_EVP_MD_type(const WOLFSSL_EVP_MD *md)
|
||||
}
|
||||
}
|
||||
#endif /* WOLFSSL_AES_256 */
|
||||
#endif /* WOLFSSL_AES_CTR */
|
||||
#endif /* WOLFSSL_AES_COUNTER */
|
||||
#ifdef WOLFSSL_AES_128
|
||||
if (ctx->cipherType == AES_128_ECB_TYPE ||
|
||||
(type && XSTRNCMP(type, EVP_AES_128_ECB, EVP_AES_SIZE) == 0)) {
|
||||
|
@ -46,7 +46,7 @@ enum Hash_Sum {
|
||||
SHA384h = 415,
|
||||
SHA512h = 416
|
||||
};
|
||||
#endif
|
||||
#endif /* !NO_ASN */
|
||||
|
||||
int wc_HashGetOID(enum wc_HashType hash_type)
|
||||
{
|
||||
@ -104,7 +104,9 @@ int wc_HashGetOID(enum wc_HashType hash_type)
|
||||
}
|
||||
return oid;
|
||||
}
|
||||
#endif
|
||||
#endif /* !NO_ASN || !NO_DH || HAVE_ECC */
|
||||
|
||||
|
||||
|
||||
/* Get Hash digest size */
|
||||
int wc_HashGetDigestSize(enum wc_HashType hash_type)
|
||||
|
@ -58,19 +58,24 @@ int wc_PBKDF1_ex(byte* key, int keyLen, byte* iv, int ivLen,
|
||||
#else
|
||||
wc_HashAlg hash[1];
|
||||
#endif
|
||||
enum wc_HashType hashT;
|
||||
|
||||
(void)heap;
|
||||
|
||||
err = wc_HashGetDigestSize(hashType);
|
||||
if (key == NULL || keyLen < 0 || passwdLen < 0 || saltLen < 0 ||
|
||||
ivLen < 0 || hashType < 0 || hashType > WC_HASH_TYPE_MAX) {
|
||||
return BAD_FUNC_ARG;
|
||||
}
|
||||
|
||||
if (iterations <= 0)
|
||||
iterations = 1;
|
||||
|
||||
hashT = (enum wc_HashType)hashType;
|
||||
err = wc_HashGetDigestSize(hashT);
|
||||
if (err < 0)
|
||||
return err;
|
||||
diestLen = err;
|
||||
|
||||
if (key == NULL || keyLen < 0 || passwd == NULL || passwdLen == 0 ||
|
||||
iterations < 1) {
|
||||
return BAD_FUNC_ARG;
|
||||
}
|
||||
|
||||
/* initialize hash */
|
||||
#ifdef WOLFSSL_SMALL_STACK
|
||||
hash = (wc_HashAlg*)XMALLOC(sizeof(wc_HashAlg), heap,
|
||||
@ -79,7 +84,7 @@ int wc_PBKDF1_ex(byte* key, int keyLen, byte* iv, int ivLen,
|
||||
return MEMORY_E;
|
||||
#endif
|
||||
|
||||
err = wc_HashInit(hash, hashType);
|
||||
err = wc_HashInit(hash, hashT);
|
||||
if (err != 0) {
|
||||
#ifdef WOLFSSL_SMALL_STACK
|
||||
XFREE(hash, heap, DYNAMIC_TYPE_HASHCTX);
|
||||
@ -93,23 +98,23 @@ int wc_PBKDF1_ex(byte* key, int keyLen, byte* iv, int ivLen,
|
||||
digestLeft = diestLen;
|
||||
/* D_(i - 1) */
|
||||
if (keyOutput) /* first time D_0 is empty */
|
||||
err = wc_HashUpdate(hash, hashType, digest, diestLen);
|
||||
err = wc_HashUpdate(hash, hashT, digest, diestLen);
|
||||
|
||||
/* data */
|
||||
if (err == 0)
|
||||
err = wc_HashUpdate(hash, hashType, passwd, passwdLen);
|
||||
err = wc_HashUpdate(hash, hashT, passwd, passwdLen);
|
||||
/* salt */
|
||||
if (salt && err == 0)
|
||||
err = wc_HashUpdate(hash, hashType, salt, saltLen);
|
||||
err = wc_HashUpdate(hash, hashT, salt, saltLen);
|
||||
|
||||
if (err == 0)
|
||||
err = wc_HashFinal(hash, hashType, digest);
|
||||
err = wc_HashFinal(hash, hashT, digest);
|
||||
|
||||
/* count */
|
||||
if (err == 0) {
|
||||
for (i = 1; i < iterations; i++) {
|
||||
err = wc_HashUpdate(hash, hashType, digest, diestLen);
|
||||
err = wc_HashFinal(hash, hashType, digest);
|
||||
err = wc_HashUpdate(hash, hashT, digest, diestLen);
|
||||
err = wc_HashFinal(hash, hashT, digest);
|
||||
}
|
||||
}
|
||||
|
||||
@ -164,8 +169,19 @@ int wc_PBKDF2(byte* output, const byte* passwd, int pLen, const byte* salt,
|
||||
byte buffer[WC_MAX_DIGEST_SIZE];
|
||||
Hmac hmac[1];
|
||||
#endif
|
||||
enum wc_HashType hashT;
|
||||
|
||||
hLen = wc_HashGetDigestSize(hashType);
|
||||
if (output == NULL || pLen < 0 || sLen < 0 || kLen < 0 ||
|
||||
hashType < 0 || hashType > WC_HASH_TYPE_MAX) {
|
||||
return BAD_FUNC_ARG;
|
||||
}
|
||||
|
||||
if (iterations <= 0)
|
||||
iterations = 1;
|
||||
|
||||
hashT = (enum wc_HashType)hashType;
|
||||
|
||||
hLen = wc_HashGetDigestSize(hashT);
|
||||
if (hLen < 0)
|
||||
return BAD_FUNC_ARG;
|
||||
|
||||
@ -180,7 +196,7 @@ int wc_PBKDF2(byte* output, const byte* passwd, int pLen, const byte* salt,
|
||||
|
||||
ret = wc_HmacInit(hmac, NULL, INVALID_DEVID);
|
||||
if (ret == 0) {
|
||||
ret = wc_HmacSetKey(hmac, hashType, passwd, pLen);
|
||||
ret = wc_HmacSetKey(hmac, hashT, passwd, pLen);
|
||||
|
||||
while (ret == 0 && kLen) {
|
||||
int currentLen;
|
||||
@ -249,9 +265,14 @@ static int DoPKCS12Hash(int hashType, byte* buffer, word32 totalLen,
|
||||
#else
|
||||
wc_HashAlg hash[1];
|
||||
#endif
|
||||
enum wc_HashType hashT;
|
||||
|
||||
if (buffer == NULL || Ai == NULL)
|
||||
if (buffer == NULL || Ai == NULL || hashType < 0 ||
|
||||
hashType > WC_HASH_TYPE_MAX) {
|
||||
return BAD_FUNC_ARG;
|
||||
}
|
||||
|
||||
hashT = (enum wc_HashType)hashType;
|
||||
|
||||
/* initialize hash */
|
||||
#ifdef WOLFSSL_SMALL_STACK
|
||||
@ -261,7 +282,7 @@ static int DoPKCS12Hash(int hashType, byte* buffer, word32 totalLen,
|
||||
return MEMORY_E;
|
||||
#endif
|
||||
|
||||
ret = wc_HashInit(hash, hashType);
|
||||
ret = wc_HashInit(hash, hashT);
|
||||
if (ret != 0) {
|
||||
#ifdef WOLFSSL_SMALL_STACK
|
||||
XFREE(hash, NULL, DYNAMIC_TYPE_HASHCTX);
|
||||
@ -269,16 +290,16 @@ static int DoPKCS12Hash(int hashType, byte* buffer, word32 totalLen,
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = wc_HashUpdate(hash, hashType, buffer, totalLen);
|
||||
ret = wc_HashUpdate(hash, hashT, buffer, totalLen);
|
||||
|
||||
if (ret == 0)
|
||||
ret = wc_HashFinal(hash, hashType, Ai);
|
||||
ret = wc_HashFinal(hash, hashT, Ai);
|
||||
|
||||
for (i = 1; i < iterations; i++) {
|
||||
if (ret == 0)
|
||||
ret = wc_HashUpdate(hash, hashType, Ai, u);
|
||||
ret = wc_HashUpdate(hash, hashT, Ai, u);
|
||||
if (ret == 0)
|
||||
ret = wc_HashFinal(hash, hashType, Ai);
|
||||
ret = wc_HashFinal(hash, hashT, Ai);
|
||||
}
|
||||
|
||||
#ifdef WOLFSSL_SMALL_STACK
|
||||
@ -289,8 +310,9 @@ static int DoPKCS12Hash(int hashType, byte* buffer, word32 totalLen,
|
||||
}
|
||||
|
||||
|
||||
int wc_PKCS12_PBKDF(byte* output, const byte* passwd, int passLen,const byte* salt,
|
||||
int saltLen, int iterations, int kLen, int hashType, int id)
|
||||
int wc_PKCS12_PBKDF(byte* output, const byte* passwd, int passLen,
|
||||
const byte* salt, int saltLen, int iterations, int kLen, int hashType,
|
||||
int id)
|
||||
{
|
||||
return wc_PKCS12_PBKDF_ex(output, passwd, passLen, salt, saltLen,
|
||||
iterations, kLen, hashType, id, NULL);
|
||||
@ -322,18 +344,25 @@ int wc_PKCS12_PBKDF_ex(byte* output, const byte* passwd, int passLen,
|
||||
byte Ai[WC_MAX_DIGEST_SIZE];
|
||||
byte B[WC_MAX_BLOCK_SIZE];
|
||||
#endif
|
||||
enum wc_HashType hashT;
|
||||
|
||||
(void)heap;
|
||||
(void)heap;
|
||||
|
||||
if (output == NULL || passLen < 0 || saltLen < 0 || kLen < 0 ||
|
||||
hashType < 0 || hashType > WC_HASH_TYPE_MAX) {
|
||||
return BAD_FUNC_ARG;
|
||||
}
|
||||
|
||||
if (!iterations)
|
||||
if (iterations <= 0)
|
||||
iterations = 1;
|
||||
|
||||
ret = wc_HashGetDigestSize(hashType);
|
||||
hashT = (enum wc_HashType)hashType;
|
||||
ret = wc_HashGetDigestSize(hashT);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
u = ret;
|
||||
|
||||
ret = wc_HashGetBlockSize(hashType);
|
||||
ret = wc_HashGetBlockSize(hashT);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
v = ret;
|
||||
|
@ -1431,6 +1431,26 @@ time_t XTIME(time_t * timer)
|
||||
#endif /* WOLFSSL_XILINX */
|
||||
#endif /* !NO_ASN_TIME */
|
||||
|
||||
#ifndef WOLFSSL_LEANPSK
|
||||
char* mystrnstr(const char* s1, const char* s2, unsigned int n)
|
||||
{
|
||||
unsigned int s2_len = (unsigned int)XSTRLEN(s2);
|
||||
|
||||
if (s2_len == 0)
|
||||
return (char*)s1;
|
||||
|
||||
while (n >= s2_len && s1[0]) {
|
||||
if (s1[0] == s2[0])
|
||||
if (XMEMCMP(s1, s2, s2_len) == 0)
|
||||
return (char*)s1;
|
||||
s1++;
|
||||
n--;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(WOLFSSL_TI_CRYPT) || defined(WOLFSSL_TI_HASH)
|
||||
#include <wolfcrypt/src/port/ti/ti-ccm.c> /* initialize and Mutex for TI Crypt Engine */
|
||||
#include <wolfcrypt/src/port/ti/ti-hash.c> /* md5, sha1, sha224, sha256 */
|
||||
|
@ -234,8 +234,6 @@ enum Misc_ASN {
|
||||
#endif
|
||||
|
||||
PEM_LINE_LEN = 80, /* PEM line max + fudge */
|
||||
FILE_BUFFER_SIZE = 1024, /* default static file buffer size for input,
|
||||
will use dynamic buffer if not big enough */
|
||||
};
|
||||
|
||||
|
||||
|
@ -296,9 +296,6 @@
|
||||
#define FREE_ARRAY(VAR_NAME, VAR_ITEMS, HEAP) /* nothing to free, its stack */
|
||||
#endif
|
||||
|
||||
#ifndef WOLFSSL_LEANPSK
|
||||
char* mystrnstr(const char* s1, const char* s2, unsigned int n);
|
||||
#endif
|
||||
#if !defined(USE_WOLF_STRTOK) && \
|
||||
(defined(__MINGW32__) || defined(WOLFSSL_TIRTOS))
|
||||
#define USE_WOLF_STRTOK
|
||||
@ -500,6 +497,8 @@
|
||||
WC_HASH_TYPE_SHA3_384 = 12,
|
||||
WC_HASH_TYPE_SHA3_512 = 13,
|
||||
WC_HASH_TYPE_BLAKE2B = 14,
|
||||
|
||||
WC_HASH_TYPE_MAX = WC_HASH_TYPE_BLAKE2B
|
||||
};
|
||||
|
||||
/* settings detection for compile vs runtime math incompatibilities */
|
||||
|
@ -472,6 +472,16 @@ WOLFSSL_API int wolfCrypt_Cleanup(void);
|
||||
#endif
|
||||
#endif /* NO_ASN_TIME */
|
||||
|
||||
#ifndef WOLFSSL_LEANPSK
|
||||
char* mystrnstr(const char* s1, const char* s2, unsigned int n);
|
||||
#endif
|
||||
|
||||
#ifndef FILE_BUFFER_SIZE
|
||||
#define FILE_BUFFER_SIZE 1024 /* default static file buffer size for input,
|
||||
will use dynamic buffer if not big enough */
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
#endif
|
||||
|
Loading…
x
Reference in New Issue
Block a user