diff options
51 files changed, 380 insertions, 226 deletions
diff --git a/.gitignore b/.gitignore index e19ca802cb..88c4d33b68 100644 --- a/.gitignore +++ b/.gitignore @@ -189,7 +189,8 @@ fuzz/*_fuzzer *.gcda *.gcno *.gcov -gl +/gl/* +!/gl/override /GNUmakefile GnuTLS-*-coverage/ gnutls-*.tar.* diff --git a/.travis.yml b/.travis.yml index 026a05f26e..02f641b6a4 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,6 +1,16 @@ os: - osx +osx_image: + # MacOS X 10.15.4 + - xcode11.5 + # MacOS X 10.14.6 + - xcode11.3 + # MacOS X 10.13 + - xcode10.1 + # MacOS X 10.13, Default + - xcode9.4 + language: c compiler: - clang @@ -10,6 +10,7 @@ See the end for copying conditions. ** API and ABI modifications: GNUTLS_CIPHER_AES_128_SIV: Added GNUTLS_CIPHER_AES_256_SIV: Added +GNUTLS_CIPHER_AES_192_GCM: Added gnutls_pkcs7_print_signature_info: Added * Version 3.6.13 (released 2020-03-31) diff --git a/bootstrap.conf b/bootstrap.conf index 4c186d6c37..3abfe10464 100644 --- a/bootstrap.conf +++ b/bootstrap.conf @@ -25,10 +25,10 @@ checkout_only_file= local_gl_dir=gl/override/ required_submodules="tests/suite/tls-fuzzer/python-ecdsa tests/suite/tls-fuzzer/tlsfuzzer tests/suite/tls-fuzzer/tlslite-ng devel/nettle devel/libtasn1" -# Reproduce by: gnulib-tool --import --local-dir=gl/override --lib=libgnu --source-base=gl --m4-base=gl/m4 --doc-base=doc --tests-base=gl/tests --aux-dir=build-aux --with-tests --avoid=alignof-tests --avoid=lock-tests --avoid=lseek-tests --lgpl=2 --no-conditional-dependencies --libtool --macro-prefix=gl --no-vc-files alloca byteswap c-ctype extensions func gendocs getline gettext-h gettimeofday hash-pjw-bare havelib intprops ldd lib-msvc-compat lib-symbol-versions maintainer-makefile manywarnings memmem-simple minmax netdb netinet_in pmccabe2html read-file secure_getenv snprintf stdint strcase strndup strtok_r strverscmp sys_socket sys_stat time_r unistd vasprintf verify vsnprintf warnings +# Reproduce by: gnulib-tool --import --local-dir=gl/override --lib=libgnu --source-base=gl --m4-base=gl/m4 --doc-base=doc --tests-base=gl/tests --aux-dir=build-aux --with-tests --avoid=alignof-tests --avoid=lock-tests --avoid=lseek-tests --lgpl=2 --no-conditional-dependencies --libtool --macro-prefix=gl --no-vc-files alloca attribute byteswap c-ctype extensions fopen-gnu func gendocs getline gettext-h gettimeofday hash-pjw-bare havelib intprops ldd lib-msvc-compat lib-symbol-versions maintainer-makefile manywarnings memmem-simple minmax netdb netinet_in pmccabe2html read-file secure_getenv snprintf stdint strcase strndup strtok_r strverscmp sys_socket sys_stat time_r unistd vasprintf verify vsnprintf warnings gnulib_modules=" -alloca byteswap c-ctype c-strcase extensions func gendocs getline gettext-h gettimeofday hash hash-pjw-bare havelib arpa_inet inet_ntop inet_pton intprops ldd lib-msvc-compat lib-symbol-versions maintainer-makefile manywarnings memmem-simple minmax netdb netinet_in pmccabe2html read-file secure_getenv setsockopt snprintf stdint strcase strdup-posix strndup strtok_r strverscmp sys_socket sys_stat sys_types time_r unistd valgrind-tests vasprintf verify vsnprintf warnings +alloca attribute byteswap c-ctype c-strcase extensions fopen-gnu func gendocs getline gettext-h gettimeofday hash hash-pjw-bare havelib arpa_inet inet_ntop inet_pton intprops ldd lib-msvc-compat lib-symbol-versions maintainer-makefile manywarnings memmem-simple minmax netdb netinet_in pmccabe2html read-file secure_getenv setsockopt snprintf stdint strcase strdup-posix strndup strtok_r strverscmp sys_socket sys_stat sys_types time_r unistd valgrind-tests vasprintf verify vsnprintf warnings " unistring_modules=" diff --git a/configure.ac b/configure.ac index cda77c177e..a09cbfd92d 100644 --- a/configure.ac +++ b/configure.ac @@ -147,7 +147,7 @@ case "$host" in dnl intended minimum runtime version. LDFLAGS="$LDFLAGS -Wl,-no_weak_imports" AC_MSG_CHECKING([whether the linker supports -Wl,-no_weak_imports]) - AC_LINK_IFELSE([AC_LANG_PROGRAM([], [])], + AC_LINK_IFELSE([AC_LANG_PROGRAM([#include <sys/select.h>], [fd_set rfds; FD_ZERO(&rfds); FD_SET(0, &rfds);])], [AC_MSG_RESULT(yes)], [AC_MSG_RESULT(no); LDFLAGS="$save_LDFLAGS"]) ;; *solaris*) @@ -532,6 +532,10 @@ if test "$gl_gcc_warnings" = yes; then gl_WARN_ADD([-fdiagnostics-show-option]) fi +if test "$gl_cv_opt_valgrind_tests" != no; then + gl_WARN_ADD([-fno-builtin-strcmp]) +fi + AC_SUBST([WERROR_CFLAGS]) AC_SUBST([WSTACK_CFLAGS]) AC_SUBST([WARN_CFLAGS]) @@ -1130,7 +1134,6 @@ AC_DEFINE([GNUTLS_INTERNAL_BUILD], 1, [We allow temporarily usage of deprecated AC_DEFINE([fread_file], [_gnutls_fread_file], [static lib rename]) AC_DEFINE([read_file], [_gnutls_read_file], [static lib rename]) -AC_DEFINE([read_binary_file], [_gnutls_read_binary_file], [static lib rename]) dnl configuration options for config file parsing (inih) AC_DEFINE([INI_MAX_LINE], 2048, [inih maximum line size]) diff --git a/devel/libgnutls-latest-x86_64.abi b/devel/libgnutls-latest-x86_64.abi index 8e5e787950..4f8d92b32d 100644 --- a/devel/libgnutls-latest-x86_64.abi +++ b/devel/libgnutls-latest-x86_64.abi @@ -1518,6 +1518,7 @@ <enumerator name='GNUTLS_CIPHER_CHACHA20_32' value='36'/> <enumerator name='GNUTLS_CIPHER_AES_128_SIV' value='37'/> <enumerator name='GNUTLS_CIPHER_AES_256_SIV' value='38'/> + <enumerator name='GNUTLS_CIPHER_AES_192_GCM' value='39'/> <enumerator name='GNUTLS_CIPHER_IDEA_PGP_CFB' value='200'/> <enumerator name='GNUTLS_CIPHER_3DES_PGP_CFB' value='201'/> <enumerator name='GNUTLS_CIPHER_CAST5_PGP_CFB' value='202'/> diff --git a/doc/examples/ex-ocsp-client.c b/doc/examples/ex-ocsp-client.c index 33eff67a6c..f0b56fffe2 100644 --- a/doc/examples/ex-ocsp-client.c +++ b/doc/examples/ex-ocsp-client.c @@ -183,7 +183,7 @@ static gnutls_x509_crt_t load_cert(const char *cert_file) if (ret < 0) exit(1); - data.data = (void *) read_binary_file(cert_file, &size); + data.data = (void *) read_file(cert_file, RF_BINARY, &size); data.size = size; if (!data.data) { diff --git a/doc/examples/ex-pkcs12.c b/doc/examples/ex-pkcs12.c index 7890518f94..0e2b64ee1c 100644 --- a/doc/examples/ex-pkcs12.c +++ b/doc/examples/ex-pkcs12.c @@ -28,7 +28,7 @@ write_pkcs12(const gnutls_datum_t * cert, gnutls_pkcs12_bag_t bag, key_bag; char pkcs12_struct[10 * 1024]; size_t pkcs12_struct_size; - FILE *fd; + FILE *fp; /* A good idea might be to use gnutls_x509_privkey_get_key_id() * to obtain a unique ID. @@ -116,13 +116,13 @@ write_pkcs12(const gnutls_datum_t * cert, return 1; } - fd = fopen(OUTFILE, "w"); - if (fd == NULL) { + fp = fopen(OUTFILE, "w"); + if (fp == NULL) { fprintf(stderr, "cannot open file\n"); return 1; } - fwrite(pkcs12_struct, 1, pkcs12_struct_size, fd); - fclose(fd); + fwrite(pkcs12_struct, 1, pkcs12_struct_size, fp); + fclose(fp); gnutls_pkcs12_bag_deinit(bag); gnutls_pkcs12_bag_deinit(key_bag); diff --git a/gnulib b/gnulib -Subproject 02c8a3da2c4462ecf78944af9f6fd2c986fa536 +Subproject fb64a78174042189f4d012cbd748d565f021cd6 diff --git a/lib/accelerated/aarch64/aarch64-common.c b/lib/accelerated/aarch64/aarch64-common.c index 38cff360b6..82cd8715fe 100644 --- a/lib/accelerated/aarch64/aarch64-common.c +++ b/lib/accelerated/aarch64/aarch64-common.c @@ -207,6 +207,14 @@ void _register_aarch64_crypto(unsigned capabilities) ret = gnutls_crypto_single_cipher_register + (GNUTLS_CIPHER_AES_192_GCM, 90, + &_gnutls_aes_gcm_aarch64, 0); + if (ret < 0) { + gnutls_assert(); + } + + ret = + gnutls_crypto_single_cipher_register (GNUTLS_CIPHER_AES_256_GCM, 90, &_gnutls_aes_gcm_aarch64, 0); if (ret < 0) { diff --git a/lib/accelerated/aarch64/aes-gcm-aarch64.c b/lib/accelerated/aarch64/aes-gcm-aarch64.c index c88fe9759f..01f22136a6 100644 --- a/lib/accelerated/aarch64/aes-gcm-aarch64.c +++ b/lib/accelerated/aarch64/aes-gcm-aarch64.c @@ -83,6 +83,7 @@ aes_gcm_cipher_init(gnutls_cipher_algorithm_t algorithm, void **_ctx, { /* we use key size to distinguish */ if (algorithm != GNUTLS_CIPHER_AES_128_GCM && + algorithm != GNUTLS_CIPHER_AES_192_GCM && algorithm != GNUTLS_CIPHER_AES_256_GCM) return GNUTLS_E_INVALID_REQUEST; diff --git a/lib/accelerated/cryptodev-gcm.c b/lib/accelerated/cryptodev-gcm.c index bd9f1a025d..876756094e 100644 --- a/lib/accelerated/cryptodev-gcm.c +++ b/lib/accelerated/cryptodev-gcm.c @@ -69,6 +69,7 @@ static void aes_gcm_deinit(void *_ctx) static const int cipher_map[] = { [GNUTLS_CIPHER_AES_128_GCM] = CRYPTO_AES_GCM, + [GNUTLS_CIPHER_AES_192_GCM] = CRYPTO_AES_GCM, [GNUTLS_CIPHER_AES_256_GCM] = CRYPTO_AES_GCM, }; diff --git a/lib/accelerated/x86/aes-gcm-x86-aesni.c b/lib/accelerated/x86/aes-gcm-x86-aesni.c index e5110ef528..6c1bb1f6fd 100644 --- a/lib/accelerated/x86/aes-gcm-x86-aesni.c +++ b/lib/accelerated/x86/aes-gcm-x86-aesni.c @@ -60,6 +60,14 @@ static void x86_aes128_set_encrypt_key(void *_ctx, aesni_set_encrypt_key(key, 16*8, ctx); } +static void x86_aes192_set_encrypt_key(void *_ctx, + const uint8_t * key) +{ + AES_KEY *ctx = _ctx; + + aesni_set_encrypt_key(key, 24*8, ctx); +} + static void x86_aes256_set_encrypt_key(void *_ctx, const uint8_t * key) { @@ -74,6 +82,7 @@ aes_gcm_cipher_init(gnutls_cipher_algorithm_t algorithm, void **_ctx, { /* we use key size to distinguish */ if (algorithm != GNUTLS_CIPHER_AES_128_GCM && + algorithm != GNUTLS_CIPHER_AES_192_GCM && algorithm != GNUTLS_CIPHER_AES_256_GCM) return GNUTLS_E_INVALID_REQUEST; @@ -94,6 +103,9 @@ aes_gcm_cipher_setkey(void *_ctx, const void *key, size_t length) if (length == 16) { GCM_SET_KEY(ctx, x86_aes128_set_encrypt_key, x86_aes_encrypt, key); + } else if (length == 24) { + GCM_SET_KEY(ctx, x86_aes192_set_encrypt_key, x86_aes_encrypt, + key); } else if (length == 32) { GCM_SET_KEY(ctx, x86_aes256_set_encrypt_key, x86_aes_encrypt, key); diff --git a/lib/accelerated/x86/aes-gcm-x86-pclmul-avx.c b/lib/accelerated/x86/aes-gcm-x86-pclmul-avx.c index 747a894921..3b4140acb2 100644 --- a/lib/accelerated/x86/aes-gcm-x86-pclmul-avx.c +++ b/lib/accelerated/x86/aes-gcm-x86-pclmul-avx.c @@ -81,6 +81,7 @@ aes_gcm_cipher_init(gnutls_cipher_algorithm_t algorithm, void **_ctx, { /* we use key size to distinguish */ if (algorithm != GNUTLS_CIPHER_AES_128_GCM && + algorithm != GNUTLS_CIPHER_AES_192_GCM && algorithm != GNUTLS_CIPHER_AES_256_GCM) return GNUTLS_E_INVALID_REQUEST; diff --git a/lib/accelerated/x86/aes-gcm-x86-pclmul.c b/lib/accelerated/x86/aes-gcm-x86-pclmul.c index 2225b93376..dc1e68dfe8 100644 --- a/lib/accelerated/x86/aes-gcm-x86-pclmul.c +++ b/lib/accelerated/x86/aes-gcm-x86-pclmul.c @@ -81,6 +81,7 @@ aes_gcm_cipher_init(gnutls_cipher_algorithm_t algorithm, void **_ctx, { /* we use key size to distinguish */ if (algorithm != GNUTLS_CIPHER_AES_128_GCM && + algorithm != GNUTLS_CIPHER_AES_192_GCM && algorithm != GNUTLS_CIPHER_AES_256_GCM) return GNUTLS_E_INVALID_REQUEST; diff --git a/lib/accelerated/x86/aes-gcm-x86-ssse3.c b/lib/accelerated/x86/aes-gcm-x86-ssse3.c index 5580cc2214..f6b14681c9 100644 --- a/lib/accelerated/x86/aes-gcm-x86-ssse3.c +++ b/lib/accelerated/x86/aes-gcm-x86-ssse3.c @@ -69,6 +69,14 @@ static void x86_aes_128_set_encrypt_key(void *_ctx, vpaes_set_encrypt_key(key, 16*8, ctx); } +static void x86_aes_192_set_encrypt_key(void *_ctx, + const uint8_t * key) +{ + AES_KEY *ctx = _ctx; + + vpaes_set_encrypt_key(key, 24*8, ctx); +} + static void x86_aes_256_set_encrypt_key(void *_ctx, const uint8_t * key) { @@ -83,6 +91,7 @@ aes_gcm_cipher_init(gnutls_cipher_algorithm_t algorithm, void **_ctx, { /* we use key size to distinguish */ if (algorithm != GNUTLS_CIPHER_AES_128_GCM && + algorithm != GNUTLS_CIPHER_AES_192_GCM && algorithm != GNUTLS_CIPHER_AES_256_GCM) return GNUTLS_E_INVALID_REQUEST; @@ -103,6 +112,9 @@ aes_gcm_cipher_setkey(void *_ctx, const void *key, size_t keysize) if (keysize == 16) { GCM_SET_KEY(ctx, x86_aes_128_set_encrypt_key, x86_aes_encrypt, key); + } else if (keysize == 24) { + GCM_SET_KEY(ctx, x86_aes_192_set_encrypt_key, x86_aes_encrypt, + key); } else if (keysize == 32) { GCM_SET_KEY(ctx, x86_aes_256_set_encrypt_key, x86_aes_encrypt, key); diff --git a/lib/accelerated/x86/x86-common.c b/lib/accelerated/x86/x86-common.c index 459397c118..3845c6b4c9 100644 --- a/lib/accelerated/x86/x86-common.c +++ b/lib/accelerated/x86/x86-common.c @@ -562,6 +562,14 @@ void register_x86_intel_crypto(unsigned capabilities) ret = gnutls_crypto_single_cipher_register + (GNUTLS_CIPHER_AES_192_GCM, 90, + &_gnutls_aes_gcm_x86_ssse3, 0); + if (ret < 0) { + gnutls_assert(); + } + + ret = + gnutls_crypto_single_cipher_register (GNUTLS_CIPHER_AES_256_GCM, 90, &_gnutls_aes_gcm_x86_ssse3, 0); if (ret < 0) { @@ -755,6 +763,14 @@ void register_x86_intel_crypto(unsigned capabilities) ret = gnutls_crypto_single_cipher_register + (GNUTLS_CIPHER_AES_192_GCM, 80, + &_gnutls_aes_gcm_pclmul_avx, 0); + if (ret < 0) { + gnutls_assert(); + } + + ret = + gnutls_crypto_single_cipher_register (GNUTLS_CIPHER_AES_256_GCM, 80, &_gnutls_aes_gcm_pclmul_avx, 0); if (ret < 0) { @@ -773,6 +789,14 @@ void register_x86_intel_crypto(unsigned capabilities) ret = gnutls_crypto_single_cipher_register + (GNUTLS_CIPHER_AES_192_GCM, 80, + &_gnutls_aes_gcm_pclmul, 0); + if (ret < 0) { + gnutls_assert(); + } + + ret = + gnutls_crypto_single_cipher_register (GNUTLS_CIPHER_AES_256_GCM, 80, &_gnutls_aes_gcm_pclmul, 0); if (ret < 0) { @@ -792,6 +816,14 @@ void register_x86_intel_crypto(unsigned capabilities) ret = gnutls_crypto_single_cipher_register + (GNUTLS_CIPHER_AES_192_GCM, 80, + &_gnutls_aes_gcm_x86_aesni, 0); + if (ret < 0) { + gnutls_assert(); + } + + ret = + gnutls_crypto_single_cipher_register (GNUTLS_CIPHER_AES_256_GCM, 80, &_gnutls_aes_gcm_x86_aesni, 0); if (ret < 0) { diff --git a/lib/algorithms/ciphers.c b/lib/algorithms/ciphers.c index 59dc7ea7fb..d57c1d5dba 100644 --- a/lib/algorithms/ciphers.c +++ b/lib/algorithms/ciphers.c @@ -69,6 +69,15 @@ static const cipher_entry_st algorithms[] = { .explicit_iv = 8, .cipher_iv = 12, .tagsize = 16}, + { .name = "AES-192-GCM", + .id = GNUTLS_CIPHER_AES_192_GCM, + .blocksize = 16, + .keysize = 24, + .type = CIPHER_AEAD, + .implicit_iv = 4, + .explicit_iv = 8, + .cipher_iv = 12, + .tagsize = 16}, { .name = "AES-256-GCM", .id = GNUTLS_CIPHER_AES_256_GCM, .blocksize = 16, diff --git a/lib/auth/psk_passwd.c b/lib/auth/psk_passwd.c index a0427914f9..9a9d68c488 100644 --- a/lib/auth/psk_passwd.c +++ b/lib/auth/psk_passwd.c @@ -155,7 +155,7 @@ _gnutls_psk_pwd_find_entry(gnutls_session_t session, gnutls_datum_t * psk) { gnutls_psk_server_credentials_t cred; - FILE *fd; + FILE *fp; char *line = NULL; size_t line_size = 0; int ret; @@ -203,13 +203,13 @@ _gnutls_psk_pwd_find_entry(gnutls_session_t session, /* Open the selected password file. */ - fd = fopen(cred->password_file, "r"); - if (fd == NULL) { + fp = fopen(cred->password_file, "re"); + if (fp == NULL) { gnutls_assert(); return GNUTLS_E_SRP_PWD_ERROR; } - while (getline(&line, &line_size, fd) > 0) { + while (getline(&line, &line_size, fp) > 0) { if (username_matches(&username_datum, line, line_size)) { ret = pwd_put_values(psk, line); if (ret < 0) { @@ -231,8 +231,8 @@ _gnutls_psk_pwd_find_entry(gnutls_session_t session, ret = 0; cleanup: - if (fd != NULL) - fclose(fd); + if (fp != NULL) + fclose(fp); zeroize_key(line, line_size); free(line); diff --git a/lib/auth/srp_passwd.c b/lib/auth/srp_passwd.c index baa4086e77..49039a66e7 100644 --- a/lib/auth/srp_passwd.c +++ b/lib/auth/srp_passwd.c @@ -193,7 +193,7 @@ static int parse_tpasswd_conf_values(SRP_PWD_ENTRY * entry, char *str) static int pwd_read_conf(const char *pconf_file, SRP_PWD_ENTRY * entry, int idx) { - FILE *fd; + FILE *fp; char *line = NULL; size_t line_size = 0; unsigned i, len; @@ -202,14 +202,14 @@ pwd_read_conf(const char *pconf_file, SRP_PWD_ENTRY * entry, int idx) snprintf(indexstr, sizeof(indexstr), "%u", (unsigned int) idx); - fd = fopen(pconf_file, "r"); - if (fd == NULL) { + fp = fopen(pconf_file, "re"); + if (fp == NULL) { gnutls_assert(); return GNUTLS_E_FILE_ERROR; } len = strlen(indexstr); - while (getline(&line, &line_size, fd) > 0) { + while (getline(&line, &line_size, fp) > 0) { /* move to first ':' */ i = 0; while ((i < line_size) && (line[i] != ':') @@ -234,7 +234,7 @@ pwd_read_conf(const char *pconf_file, SRP_PWD_ENTRY * entry, int idx) cleanup: zeroize_key(line, line_size); free(line); - fclose(fd); + fclose(fp); return ret; } @@ -244,7 +244,7 @@ _gnutls_srp_pwd_read_entry(gnutls_session_t state, char *username, SRP_PWD_ENTRY ** _entry) { gnutls_srp_server_credentials_t cred; - FILE *fd = NULL; + FILE *fp = NULL; char *line = NULL; size_t line_size = 0; unsigned i, len; @@ -308,15 +308,15 @@ _gnutls_srp_pwd_read_entry(gnutls_session_t state, char *username, /* Open the selected password file. */ - fd = fopen(cred->password_file, "r"); - if (fd == NULL) { + fp = fopen(cred->password_file, "re"); + if (fp == NULL) { gnutls_assert(); ret = GNUTLS_E_SRP_PWD_ERROR; goto cleanup; } len = strlen(username); - while (getline(&line, &line_size, fd) > 0) { + while (getline(&line, &line_size, fp) > 0) { /* move to first ':' */ i = 0; while ((i < line_size) && (line[i] != '\0') @@ -372,8 +372,8 @@ found: zeroize_key(line, line_size); free(line); } - if (fd) - fclose(fd); + if (fp) + fclose(fp); return ret; } diff --git a/lib/cert-cred-rawpk.c b/lib/cert-cred-rawpk.c index cfa65eb318..56bc5f6584 100644 --- a/lib/cert-cred-rawpk.c +++ b/lib/cert-cred-rawpk.c @@ -239,8 +239,6 @@ int gnutls_certificate_set_rawpk_key_file(gnutls_certificate_credentials_t cred, gnutls_privkey_t privkey; gnutls_pubkey_t pubkey; gnutls_pcert_st* pcert; - gnutls_datum_t rawpubkey = { NULL, 0 }; // to hold rawpk data from file - size_t key_size; gnutls_str_array_t str_names; unsigned int i; @@ -291,8 +289,13 @@ int gnutls_certificate_set_rawpk_key_file(gnutls_certificate_credentials_t cred, } } else { + gnutls_datum_t rawpubkey; // to hold rawpk data from file + size_t key_size; + /* Read our raw public-key into memory from file */ - rawpubkey.data = (void*) read_binary_file(rawpkfile, &key_size); + rawpubkey.data = (void*) read_file(rawpkfile, + RF_BINARY | RF_SENSITIVE, + &key_size); if (rawpubkey.data == NULL) { gnutls_privkey_deinit(privkey); @@ -307,7 +310,9 @@ int gnutls_certificate_set_rawpk_key_file(gnutls_certificate_credentials_t cred, ret = gnutls_pcert_import_rawpk_raw(pcert, &rawpubkey, format, key_usage, 0); - _gnutls_free_datum(&rawpubkey); + zeroize_key(rawpubkey.data, rawpubkey.size); + free(rawpubkey.data); + rawpubkey.size = 0; if (ret < 0) { gnutls_privkey_deinit(privkey); diff --git a/lib/cert-cred-x509.c b/lib/cert-cred-x509.c index 4e86a59ba6..04aa3169b6 100644 --- a/lib/cert-cred-x509.c +++ b/lib/cert-cred-x509.c @@ -543,7 +543,7 @@ read_cert_file(gnutls_certificate_credentials_t res, return read_cert_url(res, key, certfile); } - data = read_binary_file(certfile, &size); + data = read_file(certfile, RF_BINARY, &size); if (data == NULL) { gnutls_assert(); @@ -588,7 +588,7 @@ _gnutls_read_key_file(gnutls_certificate_credentials_t res, (GNUTLS_E_UNIMPLEMENTED_FEATURE); } - data = read_binary_file(keyfile, &size); + data = read_file(keyfile, RF_BINARY | RF_SENSITIVE, &size); if (data == NULL) { gnutls_assert(); @@ -596,6 +596,7 @@ _gnutls_read_key_file(gnutls_certificate_credentials_t res, } ret = _gnutls_read_key_mem(res, data, size, type, pass, flags, rkey); + zeroize_key(data, size); free(data); return ret; @@ -1447,7 +1448,8 @@ int size_t size; int ret; - p12blob.data = (void *) read_binary_file(pkcs12file, &size); + p12blob.data = (void *) read_file(pkcs12file, RF_BINARY | RF_SENSITIVE, + &size); p12blob.size = (unsigned int) size; if (p12blob.data == NULL) { gnutls_assert(); @@ -1457,7 +1459,9 @@ int ret = gnutls_certificate_set_x509_simple_pkcs12_mem(res, &p12blob, type, password); + zeroize_key(p12blob.data, p12blob.size); free(p12blob.data); + p12blob.size = 0; return ret; } diff --git a/lib/crypto-selftests.c b/lib/crypto-selftests.c index f915b6d744..a589a7747c 100644 --- a/lib/crypto-selftests.c +++ b/lib/crypto-selftests.c @@ -141,6 +141,27 @@ const struct cipher_aead_vectors_st aes128_gcm_vectors[] = { "\x5b\xc9\x4f\xbc\x32\x21\xa5\xdb\x94\xfa\xe9\x5a\xe7\x12\x1a\x47"} }; +const struct cipher_aead_vectors_st aes192_gcm_vectors[] = { + { + .compat_apis = 1, + STR(key, key_size, + "\xfe\xff\xe9\x92\x86\x65\x73\x1c\x6d\x6a\x8f\x94\x67\x30\x83\x08\xfe\xff\xe9\x92\x86\x65\x73\x1c"), + .auth = NULL, + .auth_size = 0, + STR(plaintext, plaintext_size, + "\xd9\x31\x32\x25\xf8\x84\x06\xe5\xa5\x59\x09\xc5\xaf\xf5\x26\x9a\x86\xa7\xa9\x53\x15\x34\xf7\xda\x2e\x4c\x30\x3d\x8a\x31\x8a\x72\x1c\x3c\x0c\x95\x95\x68\x09\x53\x2f\xcf\x0e\x24\x49\xa6\xb5\x25\xb1\x6a\xed\xf5\xaa\x0d\xe6\x57\xba\x63\x7b\x39\x1a\xaf\xd2\x55"), + .ciphertext = + (uint8_t *) + "\x39\x80\xca\x0b\x3c\x00\xe8\x41\xeb\x06\xfa\xc4\x87\x2a\x27\x57\x85\x9e\x1c\xea\xa6\xef\xd9\x84\x62\x85\x93\xb4\x0c\xa1\xe1\x9c\x7d\x77\x3d\x00\xc1\x44\xc5\x25\xac\x61\x9d\x18\xc8\x4a\x3f\x47\x18\xe2\x44\x8b\x2f\xe3\x24\xd9\xcc\xda\x27\x10\xac\xad\xe2\x56", + STR(iv, iv_size, + "\xca\xfe\xba\xbe\xfa\xce\xdb\xad\xde\xca\xf8\x88"), + .tag_size = 16, + .tag = + (void *) + "\x99\x24\xa7\xc8\x58\x73\x36\xbf\xb1\x18\x02\x4d\xb8\x67\x4a\x14"}, + +}; + const struct cipher_aead_vectors_st aes256_gcm_vectors[] = { { .compat_apis = 1, @@ -1984,6 +2005,9 @@ int gnutls_cipher_self_test(unsigned flags, gnutls_cipher_algorithm_t cipher) CASE(GNUTLS_CIPHER_AES_128_GCM, test_cipher_aead, aes128_gcm_vectors); FALLTHROUGH; + CASE(GNUTLS_CIPHER_AES_192_GCM, test_cipher_aead, + aes192_gcm_vectors); + FALLTHROUGH; CASE(GNUTLS_CIPHER_AES_256_GCM, test_cipher_aead, aes256_gcm_vectors); FALLTHROUGH; diff --git a/lib/datum.h b/lib/datum.h index 3d86a0dc72..35b9e3b97c 100644 --- a/lib/datum.h +++ b/lib/datum.h @@ -28,13 +28,13 @@ /* This will copy the provided data in @dat. If the provided data are * NULL or zero-size @dat will be NULL as well. */ -attr_warn_unused_result attr_nonnull((1)) +NODISCARD ATTRIBUTE_NONNULL((1)) int _gnutls_set_datum(gnutls_datum_t * dat, const void *data, size_t data_size); /* This will always return a non-NULL, and zero-terminated string in @dat. */ -attr_warn_unused_result attr_nonnull((1)) +NODISCARD ATTRIBUTE_NONNULL((1)) int _gnutls_set_strdatum(gnutls_datum_t * dat, const void *data, size_t data_size); @@ -48,7 +48,7 @@ void _gnutls_free_datum(gnutls_datum_t * dat) } } -inline static attr_nonnull_all +inline static ATTRIBUTE_NONNULL() void _gnutls_free_temp_key_datum(gnutls_datum_t * dat) { if (dat->data != NULL) { @@ -59,7 +59,7 @@ void _gnutls_free_temp_key_datum(gnutls_datum_t * dat) dat->size = 0; } -inline static attr_nonnull_all +inline static ATTRIBUTE_NONNULL() void _gnutls_free_key_datum(gnutls_datum_t * dat) { if (dat->data != NULL) { diff --git a/lib/file.c b/lib/file.c index cec1281bd1..3ded84913b 100644 --- a/lib/file.c +++ b/lib/file.c @@ -27,13 +27,13 @@ int _gnutls_file_exists(const char *file) { - FILE *fd; + FILE *fp; - fd = fopen(file, "r"); - if (fd == NULL) + fp = fopen(file, "re"); + if (fp == NULL) return -1; - fclose(fd); + fclose(fp); return 0; } @@ -46,6 +46,10 @@ int _gnutls_file_exists(const char *file) * zero terminated but the terminating null is not included in length. * The returned data are allocated using gnutls_malloc(). * + * Note that this function is not designed for reading sensitive materials, + * such as private keys, on practical applications. When the reading fails + * in the middle, the partially loaded content might remain on memory. + * * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise * an error code is returned. * @@ -55,7 +59,7 @@ int gnutls_load_file(const char *filename, gnutls_datum_t * data) { size_t len; - data->data = (void *) read_binary_file(filename, &len); + data->data = (void *) read_file(filename, RF_BINARY, &len); if (data->data == NULL) return GNUTLS_E_FILE_ERROR; diff --git a/lib/fips.c b/lib/fips.c index 75f26f629e..acdd2ec23e 100644 --- a/lib/fips.c +++ b/lib/fips.c @@ -93,7 +93,7 @@ unsigned _gnutls_fips_mode_enabled(void) goto exit; } - fd = fopen(FIPS_KERNEL_FILE, "r"); + fd = fopen(FIPS_KERNEL_FILE, "re"); if (fd != NULL) { f1p = fgetc(fd); fclose(fd); diff --git a/lib/fips.h b/lib/fips.h index 1464c9595b..f76f24da75 100644 --- a/lib/fips.h +++ b/lib/fips.h @@ -138,6 +138,7 @@ static unsigned is_cipher_algo_forbidden(gnutls_cipher_algorithm_t algo) case GNUTLS_CIPHER_AES_256_CBC: case GNUTLS_CIPHER_AES_192_CBC: case GNUTLS_CIPHER_AES_128_GCM: + case GNUTLS_CIPHER_AES_192_GCM: case GNUTLS_CIPHER_AES_256_GCM: case GNUTLS_CIPHER_AES_128_CCM: case GNUTLS_CIPHER_AES_256_CCM: diff --git a/lib/gnutls_int.h b/lib/gnutls_int.h index 9959c82202..4db7a2534d 100644 --- a/lib/gnutls_int.h +++ b/lib/gnutls_int.h @@ -55,6 +55,8 @@ typedef int ssize_t; #include <nettle/memxor.h> +#include "attribute.h" + #define ENABLE_ALIGN16 #ifdef __clang_major @@ -76,26 +78,6 @@ typedef int ssize_t; # define unlikely #endif -#if _GNUTLS_GCC_VERSION >= 30300 -# define attr_nonnull_all __attribute__ ((nonnull)) -# define attr_nonnull(a) __attribute__ ((nonnull a)) -#else -# define attr_nonnull_all -# define attr_nonnull(a) -#endif - -#if _GNUTLS_GCC_VERSION >= 30400 && (_GNUTLS_CLANG_VERSION == 0 || _GNUTLS_CLANG_VERSION >= 40000) -# define attr_warn_unused_result __attribute__((warn_unused_result)) -#else -# define attr_warn_unused_result -#endif - -#if _GNUTLS_GCC_VERSION >= 70100 -# define FALLTHROUGH __attribute__ ((fallthrough)) -#else -# define FALLTHROUGH -#endif - #include <gnutls/gnutls.h> #include <gnutls/dtls.h> #include <gnutls/abstract.h> diff --git a/lib/includes/gnutls/gnutls.h.in b/lib/includes/gnutls/gnutls.h.in index 7d9870996a..264da238a0 100644 --- a/lib/includes/gnutls/gnutls.h.in +++ b/lib/includes/gnutls/gnutls.h.in @@ -143,6 +143,7 @@ extern "C" { * the AEAD interface, and the IV plays a role as * the authentication tag while it is prepended to * the cipher text. + * @GNUTLS_CIPHER_AES_192_GCM: AES in GCM mode with 192-bit keys (AEAD). * * Enumeration of different symmetric encryption algorithms. */ @@ -186,6 +187,7 @@ typedef enum gnutls_cipher_algorithm { GNUTLS_CIPHER_CHACHA20_32 = 36, GNUTLS_CIPHER_AES_128_SIV = 37, GNUTLS_CIPHER_AES_256_SIV = 38, + GNUTLS_CIPHER_AES_192_GCM = 39, /* used only for PGP internals. Ignored in TLS/SSL */ @@ -143,7 +143,7 @@ void _gnutls_nss_keylog_write(gnutls_session_t session, checked_env = 1; keylogfile = secure_getenv("SSLKEYLOGFILE"); if (keylogfile != NULL) - keylog = fopen(keylogfile, "a"); + keylog = fopen(keylogfile, "ae"); } if (keylog) { diff --git a/lib/nettle/cipher.c b/lib/nettle/cipher.c index 70a6509f2b..69ed70213d 100644 --- a/lib/nettle/cipher.c +++ b/lib/nettle/cipher.c @@ -481,6 +481,23 @@ static const struct nettle_cipher_st builtin_ciphers[] = { .set_iv = (setiv_func)gcm_aes128_set_iv, .max_iv_size = GCM_IV_SIZE, }, + { .algo = GNUTLS_CIPHER_AES_192_GCM, + .block_size = AES_BLOCK_SIZE, + .key_size = AES192_KEY_SIZE, + .encrypt_block = (nettle_cipher_func*)aes192_encrypt, + .decrypt_block = (nettle_cipher_func*)aes192_decrypt, + + .ctx_size = sizeof(struct gcm_aes192_ctx), + .encrypt = _gcm_encrypt, + .decrypt = _gcm_decrypt, + .set_encrypt_key = (nettle_set_key_func*)gcm_aes192_set_key, + .set_decrypt_key = (nettle_set_key_func*)gcm_aes192_set_key, + + .tag = (nettle_hash_digest_func*)gcm_aes192_digest, + .auth = (nettle_hash_update_func*)gcm_aes192_update, + .set_iv = (setiv_func)gcm_aes192_set_iv, + .max_iv_size = GCM_IV_SIZE, + }, { .algo = GNUTLS_CIPHER_AES_256_GCM, .block_size = AES_BLOCK_SIZE, .key_size = AES256_KEY_SIZE, @@ -1030,6 +1047,7 @@ wrap_nettle_cipher_setiv(void *_ctx, const void *iv, size_t iv_size) switch (ctx->cipher->algo) { case GNUTLS_CIPHER_AES_128_GCM: + case GNUTLS_CIPHER_AES_192_GCM: case GNUTLS_CIPHER_AES_256_GCM: FIPS_RULE(iv_size < GCM_IV_SIZE, GNUTLS_E_INVALID_REQUEST, "access to short GCM nonce size\n"); break; diff --git a/lib/pkcs11.c b/lib/pkcs11.c index d03bf6e444..fad16aaf4f 100644 --- a/lib/pkcs11.c +++ b/lib/pkcs11.c @@ -889,7 +889,7 @@ static void compat_load(const char *configfile) if (configfile == NULL) configfile = "/etc/gnutls/pkcs11.conf"; - fp = fopen(configfile, "r"); + fp = fopen(configfile, "re"); if (fp == NULL) { gnutls_assert(); return; diff --git a/lib/priority.c b/lib/priority.c index ad99459adb..0a284ae1f1 100644 --- a/lib/priority.c +++ b/lib/priority.c @@ -1304,6 +1304,7 @@ static void _gnutls_update_system_priorities(void) { int ret; struct stat sb; + FILE *fp; if (stat(system_priority_file, &sb) < 0) { _gnutls_debug_log("cfg: unable to access: %s: %d\n", @@ -1321,7 +1322,14 @@ static void _gnutls_update_system_priorities(void) if (system_wide_priority_strings_init != 0) _name_val_array_clear(&system_wide_priority_strings); - ret = ini_parse(system_priority_file, cfg_ini_handler, NULL); + fp = fopen(system_priority_file, "re"); + if (fp == NULL) { + _gnutls_debug_log("cfg: unable to open: %s: %d\n", + system_priority_file, errno); + return; + } + ret = ini_parse_file(fp, cfg_ini_handler, NULL); + fclose(fp); if (ret != 0) { _gnutls_debug_log("cfg: unable to parse: %s: %d\n", system_priority_file, ret); diff --git a/lib/verify-tofu.c b/lib/verify-tofu.c index 36328e04af..5cedeed118 100644 --- a/lib/verify-tofu.c +++ b/lib/verify-tofu.c @@ -326,7 +326,7 @@ static int verify_pubkey(const char *file, const char *host, const char *service, const gnutls_datum_t * pubkey) { - FILE *fd; + FILE *fp; char *line = NULL; size_t line_size = 0; int ret, l2, mismatch = 0; @@ -343,14 +343,14 @@ static int verify_pubkey(const char *file, if (service != NULL) service_len = strlen(service); - fd = fopen(file, "rb"); - if (fd == NULL) { + fp = fopen(file, "rbe"); + if (fp == NULL) { ret = gnutls_assert_val(GNUTLS_E_FILE_ERROR); goto cleanup; } do { - l2 = getline(&line, &line_size, fd); + l2 = getline(&line, &line_size, fp); if (l2 > 0) { ret = parse_line(line, host, host_len, service, @@ -371,8 +371,8 @@ static int verify_pubkey(const char *file, cleanup: free(line); - if (fd != NULL) - fclose(fd); + if (fp != NULL) + fclose(fp); gnutls_free(b64key.data); return ret; @@ -400,7 +400,7 @@ int store_pubkey(const char *db_name, const char *host, const char *service, time_t expiration, const gnutls_datum_t * pubkey) { - FILE *fd = NULL; + FILE *fp = NULL; gnutls_datum_t b64key = { NULL, 0 }; int ret; @@ -414,8 +414,8 @@ int store_pubkey(const char *db_name, const char *host, goto cleanup; } - fd = fopen(db_name, "ab+"); - if (fd == NULL) { + fp = fopen(db_name, "abe+"); + if (fp == NULL) { ret = gnutls_assert_val(GNUTLS_E_FILE_ERROR); goto cleanup; } @@ -425,14 +425,14 @@ int store_pubkey(const char *db_name, const char *host, if (host == NULL) host = "*"; - fprintf(fd, "|g0|%s|%s|%lu|%.*s\n", host, service, + fprintf(fp, "|g0|%s|%s|%lu|%.*s\n", host, service, (unsigned long) expiration, b64key.size, b64key.data); ret = 0; cleanup: - if (fd != NULL) - fclose(fd); + if (fp != NULL) + fclose(fp); gnutls_mutex_unlock(&_gnutls_file_mutex); gnutls_free(b64key.data); @@ -446,11 +446,11 @@ int store_commitment(const char *db_name, const char *host, gnutls_digest_algorithm_t hash_algo, const gnutls_datum_t * hash) { - FILE *fd; + FILE *fp; char buffer[MAX_HASH_SIZE * 2 + 1]; - fd = fopen(db_name, "ab+"); - if (fd == NULL) + fp = fopen(db_name, "abe+"); + if (fp == NULL) return gnutls_assert_val(GNUTLS_E_FILE_ERROR); if (service == NULL) @@ -458,12 +458,12 @@ int store_commitment(const char *db_name, const char *host, if (host == NULL) host = "*"; - fprintf(fd, "|c0|%s|%s|%lu|%u|%s\n", host, service, + fprintf(fp, "|c0|%s|%s|%lu|%u|%s\n", host, service, (unsigned long) expiration, (unsigned) hash_algo, _gnutls_bin2hex(hash->data, hash->size, buffer, sizeof(buffer), NULL)); - fclose(fd); + fclose(fp); return 0; } diff --git a/lib/x509/verify-high2.c b/lib/x509/verify-high2.c index 50020d074c..9820595e97 100644 --- a/lib/x509/verify-high2.c +++ b/lib/x509/verify-high2.c @@ -356,7 +356,7 @@ gnutls_x509_trust_list_add_trust_file(gnutls_x509_trust_list_t list, } else #endif { - cas.data = (void *) read_binary_file(ca_file, &size); + cas.data = (void *) read_file(ca_file, RF_BINARY, &size); if (cas.data == NULL) { gnutls_assert(); return GNUTLS_E_FILE_ERROR; @@ -366,7 +366,7 @@ gnutls_x509_trust_list_add_trust_file(gnutls_x509_trust_list_t list, } if (crl_file) { - crls.data = (void *) read_binary_file(crl_file, &size); + crls.data = (void *) read_file(crl_file, RF_BINARY, &size); if (crls.data == NULL) { gnutls_assert(); return GNUTLS_E_FILE_ERROR; @@ -551,7 +551,7 @@ gnutls_x509_trust_list_remove_trust_file(gnutls_x509_trust_list_t list, } else #endif { - cas.data = (void *) read_binary_file(ca_file, &size); + cas.data = (void *) read_file(ca_file, RF_BINARY, &size); if (cas.data == NULL) { gnutls_assert(); return GNUTLS_E_FILE_ERROR; diff --git a/src/certtool-common.c b/src/certtool-common.c index c76352c9d8..3af2d08080 100644 --- a/src/certtool-common.c +++ b/src/certtool-common.c @@ -270,7 +270,7 @@ gnutls_privkey_t load_private_key(int mand, common_info_st * info) if (gnutls_url_is_supported(info->privkey) != 0) return _load_url_privkey(info->privkey); - dat.data = (void *) read_binary_file(info->privkey, &size); + dat.data = (void *) read_file(info->privkey, RF_BINARY, &size); dat.size = size; if (!dat.data) { @@ -313,7 +313,7 @@ load_x509_private_key(int mand, common_info_st * info) app_exit(1); } - dat.data = (void *) read_binary_file(info->privkey, &size); + dat.data = (void *) read_file(info->privkey, RF_BINARY, &size); dat.size = size; if (!dat.data) { @@ -389,7 +389,7 @@ gnutls_x509_crt_t load_cert(int mand, common_info_st * info) gnutls_x509_crt_t *load_cert_list(int mand, size_t * crt_size, common_info_st * info) { - FILE *fd; + FILE *fp; static gnutls_x509_crt_t *crt; int ret; gnutls_datum_t dat; @@ -409,18 +409,18 @@ gnutls_x509_crt_t *load_cert_list(int mand, size_t * crt_size, return NULL; } - fd = fopen(info->cert, "r"); - if (fd == NULL) { + fp = fopen(info->cert, "r"); + if (fp == NULL) { fprintf(stderr, "Could not open %s\n", info->cert); app_exit(1); } - fix_lbuffer(file_size(fd)); + fix_lbuffer(file_size(fp)); - size = fread(lbuffer, 1, lbuffer_size - 1, fd); + size = fread(lbuffer, 1, lbuffer_size - 1, fp); lbuffer[size] = 0; - fclose(fd); + fclose(fp); dat.data = (void *) lbuffer; dat.size = size; @@ -448,7 +448,7 @@ gnutls_x509_crt_t *load_cert_list(int mand, size_t * crt_size, gnutls_x509_crl_t *load_crl_list(int mand, size_t * crl_size, common_info_st * info) { - FILE *fd; + FILE *fp; static gnutls_x509_crl_t *crl; unsigned int crl_max; int ret; @@ -467,18 +467,18 @@ gnutls_x509_crl_t *load_crl_list(int mand, size_t * crl_size, return NULL; } - fd = fopen(info->crl, "r"); - if (fd == NULL) { + fp = fopen(info->crl, "r"); + if (fp == NULL) { fprintf(stderr, "Could not open %s\n", info->crl); app_exit(1); } - fix_lbuffer(file_size(fd)); + fix_lbuffer(file_size(fp)); - size = fread(lbuffer, 1, lbuffer_size - 1, fd); + size = fread(lbuffer, 1, lbuffer_size - 1, fp); lbuffer[size] = 0; - fclose(fd); + fclose(fp); dat.data = (void *) lbuffer; dat.size = size; @@ -519,7 +519,7 @@ gnutls_x509_crq_t load_request(common_info_st * info) app_exit(1); } - dat.data = (void *) read_binary_file(info->request, &size); + dat.data = (void *) read_file(info->request, RF_BINARY, &size); dat.size = size; if (!dat.data) { @@ -560,7 +560,7 @@ gnutls_privkey_t load_ca_private_key(common_info_st * info) if (gnutls_url_is_supported(info->ca_privkey) != 0) return _load_url_privkey(info->ca_privkey); - dat.data = (void *) read_binary_file(info->ca_privkey, &size); + dat.data = (void *) read_file(info->ca_privkey, RF_BINARY, &size); dat.size = size; if (!dat.data) { @@ -610,7 +610,7 @@ gnutls_x509_crt_t load_ca_cert(unsigned mand, common_info_st * info) return crt; } - dat.data = (void *) read_binary_file(info->ca, &size); + dat.data = (void *) read_file(info->ca, RF_BINARY, &size); dat.size = size; if (!dat.data) { @@ -657,7 +657,7 @@ gnutls_pubkey_t load_pubkey(int mand, common_info_st * info) app_exit(1); } - dat.data = (void *) read_binary_file(info->pubkey, &size); + dat.data = (void *) read_file(info->pubkey, RF_BINARY, &size); dat.size = size; if (!dat.data) { @@ -1090,7 +1090,7 @@ void dh_info(FILE * infile, FILE * outfile, common_info_st * ci) app_exit(1); } - params.data = (void *) fread_file(infile, &size); + params.data = (void *) fread_file(infile, 0, &size); params.size = size; if (params.data == NULL) { diff --git a/src/certtool.c b/src/certtool.c index a46f774114..0e24ac8281 100644 --- a/src/certtool.c +++ b/src/certtool.c @@ -1530,7 +1530,7 @@ void certificate_info(int pubkey, common_info_st * cinfo) gnutls_datum_t pem; unsigned int crt_num; - pem.data = (void *) fread_file(infile, &size); + pem.data = (void *) fread_file(infile, 0, &size); pem.size = size; if (!pem.data) { @@ -1651,7 +1651,7 @@ void crl_info(common_info_st *cinfo) app_exit(1); } - pem.data = (void *) fread_file(infile, &size); + pem.data = (void *) fread_file(infile, 0, &size); pem.size = size; if (!pem.data) { @@ -1723,7 +1723,7 @@ void crq_info(common_info_st *cinfo) app_exit(1); } - pem.data = (void *) fread_file(infile, &size); + pem.data = (void *) fread_file(infile, 0, &size); pem.size = size; if (!pem.data) { @@ -2241,7 +2241,7 @@ static void load_data(common_info_st *cinfo, gnutls_datum_t *data) app_exit(1); } - data->data = (void *) fread_file(fp, &size); + data->data = (void *) fread_file(fp, 0, &size); if (data->data == NULL) { fprintf(stderr, "Error reading data file"); app_exit(1); @@ -2513,7 +2513,7 @@ static void verify_chain(common_info_st * cinfo) app_exit(1); } - buf = (void *) fread_file(infile, &size); + buf = (void *) fread_file(infile, 0, &size); if (buf == NULL) { fprintf(stderr, "Error reading certificate chain"); app_exit(1); @@ -2530,7 +2530,7 @@ static void verify_certificate(common_info_st * cinfo) char *cas = NULL; size_t cert_size; - cert = (void *) fread_file(infile, &cert_size); + cert = (void *) fread_file(infile, 0, &cert_size); if (cert == NULL) { fprintf(stderr, "Error reading certificate chain"); app_exit(1); @@ -2573,7 +2573,7 @@ void verify_crl(common_info_st * cinfo) app_exit(1); } - pem.data = (void *) fread_file(infile, &size); + pem.data = (void *) fread_file(infile, 0, &size); pem.size = size; if (!pem.data) { @@ -2661,7 +2661,7 @@ void verify_pkcs7(common_info_st * cinfo, const char *purpose, unsigned display_ app_exit(1); } - data.data = (void *) fread_file(infile, &size); + data.data = (void *) fread_file(infile, 0, &size); data.size = size; if (!data.data) { @@ -2785,7 +2785,7 @@ void pkcs7_sign(common_info_st * cinfo, unsigned embed) app_exit(1); } - data.data = (void *) fread_file(infile, &size); + data.data = (void *) fread_file(infile, 0, &size); data.size = size; if (!data.data) { @@ -3404,7 +3404,7 @@ void pkcs12_info(common_info_st * cinfo) app_exit(1); } - data.data = (void *) fread_file(infile, &size); + data.data = (void *) fread_file(infile, 0, &size); data.size = size; if (!data.data) { @@ -3593,7 +3593,7 @@ void pkcs8_info(void) size_t size; gnutls_datum_t data; - data.data = (void *) fread_file(infile, &size); + data.data = (void *) fread_file(infile, 0, &size); data.size = size; if (!data.data) { @@ -3618,7 +3618,7 @@ void pkcs7_info(common_info_st *cinfo, unsigned display_data) app_exit(1); } - data.data = (void *) fread_file(infile, &size); + data.data = (void *) fread_file(infile, 0, &size); data.size = size; if (!data.data) { @@ -3787,7 +3787,7 @@ gnutls_pubkey_t find_pubkey(gnutls_x509_crt_t crt, common_info_st * cinfo) pubkey = load_pubkey(0, cinfo); if (pubkey == NULL) { /* load from stdin */ - pem.data = (void *) fread_file(infile, &size); + pem.data = (void *) fread_file(infile, 0, &size); pem.size = size; if (!pem.data) { @@ -3931,7 +3931,7 @@ void certificate_fpr(common_info_st * cinfo) crt = load_cert(0, cinfo); if (crt == NULL) { - pem.data = (void *) fread_file(infile, &size); + pem.data = (void *) fread_file(infile, 0, &size); pem.size = size; if (!pem.data) { @@ -1036,7 +1036,7 @@ static int try_resume(socket_st * hd) fprintf(stderr, "could not open %s\n", OPT_ARG(EARLYDATA)); exit(1); } - edata.data = (void *) fread_file(fp, &size); + edata.data = (void *) fread_file(fp, 0, &size); edata.size = size; fclose(fp); } diff --git a/src/ocsptool.c b/src/ocsptool.c index 3b7940962c..a963de039a 100644 --- a/src/ocsptool.c +++ b/src/ocsptool.c @@ -99,10 +99,9 @@ static void request_info(void) if (HAVE_OPT(LOAD_REQUEST)) dat.data = - (void *) read_binary_file(OPT_ARG(LOAD_REQUEST), - &size); + (void *) read_file(OPT_ARG(LOAD_REQUEST), RF_BINARY, &size); else - dat.data = (void *) fread_file(infile, &size); + dat.data = (void *) fread_file(infile, 0, &size); if (dat.data == NULL) { fprintf(stderr, "error reading request\n"); app_exit(1); @@ -236,10 +235,9 @@ static void response_info(void) if (HAVE_OPT(LOAD_RESPONSE)) dat.data = - (void *) read_binary_file(OPT_ARG(LOAD_RESPONSE), - &size); + (void *) read_file(OPT_ARG(LOAD_RESPONSE), RF_BINARY, &size); else - dat.data = (void *) fread_file(infile, &size); + dat.data = (void *) fread_file(infile, 0, &size); if (dat.data == NULL) { fprintf(stderr, "error reading response\n"); app_exit(1); @@ -348,7 +346,7 @@ static int _verify_response(gnutls_datum_t * data, gnutls_datum_t * nonce, if (HAVE_OPT(LOAD_TRUST)) { dat.data = - (void *) read_binary_file(OPT_ARG(LOAD_TRUST), &size); + (void *) read_file(OPT_ARG(LOAD_TRUST), RF_BINARY, &size); if (dat.data == NULL) { fprintf(stderr, "error reading --load-trust: %s\n", OPT_ARG(LOAD_TRUST)); @@ -524,10 +522,9 @@ static void verify_response(gnutls_datum_t *nonce) if (HAVE_OPT(LOAD_RESPONSE)) dat.data = - (void *) read_binary_file(OPT_ARG(LOAD_RESPONSE), - &size); + (void *) read_file(OPT_ARG(LOAD_RESPONSE), RF_BINARY, &size); else - dat.data = (void *) fread_file(infile, &size); + dat.data = (void *) fread_file(infile, 0, &size); if (dat.data == NULL) { fprintf(stderr, "error reading response\n"); app_exit(1); @@ -141,35 +141,35 @@ int main(int argc, char **argv) static int filecopy(const char *src, const char *dst) { - FILE *fd, *fd2; + FILE *fp, *fp2; char line[5 * 1024]; char *p; - fd = fopen(dst, "w"); - if (fd == NULL) { + fp = fopen(dst, "w"); + if (fp == NULL) { fprintf(stderr, "Cannot open '%s' for write\n", dst); return -1; } - fd2 = fopen(src, "r"); - if (fd2 == NULL) { + fp2 = fopen(src, "r"); + if (fp2 == NULL) { /* empty file */ - fclose(fd); + fclose(fp); return 0; } line[sizeof(line) - 1] = 0; do { - p = fgets(line, sizeof(line) - 1, fd2); + p = fgets(line, sizeof(line) - 1, fp2); if (p == NULL) break; - fputs(line, fd); + fputs(line, fp); } while (1); - fclose(fd); - fclose(fd2); + fclose(fp); + fclose(fp2); return 0; } @@ -178,7 +178,7 @@ static int write_key(const char *username, const char *key, int key_size, const char *passwd_file) { - FILE *fd; + FILE *fp; char line[5 * 1024]; char *p, *pp; char tmpname[1024]; @@ -186,7 +186,7 @@ write_key(const char *username, const char *key, int key_size, /* delete previous entry */ struct stat st; - FILE *fd2; + FILE *fp2; int put; if (strlen(passwd_file) + 5 > sizeof(tmpname)) { @@ -207,25 +207,25 @@ write_key(const char *username, const char *key, int key_size, return -1; } - fd = fopen(passwd_file, "w"); - if (fd == NULL) { + fp = fopen(passwd_file, "w"); + if (fp == NULL) { fprintf(stderr, "Cannot open '%s' for write\n", passwd_file); (void)remove(tmpname); return -1; } - fd2 = fopen(tmpname, "r"); - if (fd2 == NULL) { + fp2 = fopen(tmpname, "r"); + if (fp2 == NULL) { fprintf(stderr, "Cannot open '%s' for read\n", tmpname); (void)remove(tmpname); - fclose(fd); + fclose(fp); return -1; } put = 0; do { - p = fgets(line, sizeof(line) - 1, fd2); + p = fgets(line, sizeof(line) - 1, fp2); if (p == NULL) break; @@ -237,19 +237,19 @@ write_key(const char *username, const char *key, int key_size, MAX(strlen(username), (unsigned int) (pp - p))) == 0) { put = 1; - fprintf(fd, "%s:%s\n", username, key); + fprintf(fp, "%s:%s\n", username, key); } else { - fputs(line, fd); + fputs(line, fp); } } while (1); if (put == 0) { - fprintf(fd, "%s:%s\n", username, key); + fprintf(fp, "%s:%s\n", username, key); } - fclose(fd); - fclose(fd2); + fclose(fp); + fclose(fp2); (void)remove(tmpname); diff --git a/src/serv.c b/src/serv.c index 414cd0546b..57304bc9d3 100644 --- a/src/serv.c +++ b/src/serv.c @@ -219,7 +219,7 @@ static void read_dh_params(void) char tmpdata[2048]; int size; gnutls_datum_t params; - FILE *fd; + FILE *fp; if (gnutls_dh_params_init(&dh_params) < 0) { fprintf(stderr, "Error in dh parameter initialization\n"); @@ -228,15 +228,15 @@ static void read_dh_params(void) /* read the params file */ - fd = fopen(dh_params_file, "r"); - if (fd == NULL) { + fp = fopen(dh_params_file, "r"); + if (fp == NULL) { fprintf(stderr, "Could not open %s\n", dh_params_file); exit(1); } - size = fread(tmpdata, 1, sizeof(tmpdata) - 1, fd); + size = fread(tmpdata, 1, sizeof(tmpdata) - 1, fp); tmpdata[size] = 0; - fclose(fd); + fclose(fp); params.data = (unsigned char *) tmpdata; params.size = size; diff --git a/src/srptool.c b/src/srptool.c index 27821be238..7939f6bfab 100644 --- a/src/srptool.c +++ b/src/srptool.c @@ -74,14 +74,14 @@ static void print_num(const char *msg, const gnutls_datum_t * num) static int generate_create_conf(const char *tpasswd_conf) { - FILE *fd; + FILE *fp; char line[5 * 1024]; int index = 1, srp_idx; gnutls_datum_t g, n; gnutls_datum_t str_g, str_n; - fd = fopen(tpasswd_conf, "w"); - if (fd == NULL) { + fp = fopen(tpasswd_conf, "w"); + if (fp == NULL) { fprintf(stderr, "Cannot open file '%s'\n", tpasswd_conf); return -1; } @@ -119,13 +119,13 @@ static int generate_create_conf(const char *tpasswd_conf) if (gnutls_srp_base64_encode_alloc(&n, &str_n) < 0) { fprintf(stderr, "Could not encode\n"); - fclose(fd); + fclose(fp); return -1; } if (gnutls_srp_base64_encode_alloc(&g, &str_g) < 0) { fprintf(stderr, "Could not encode\n"); - fclose(fd); + fclose(fp); return -1; } @@ -134,11 +134,11 @@ static int generate_create_conf(const char *tpasswd_conf) gnutls_free(str_n.data); gnutls_free(str_g.data); - fwrite(line, 1, strlen(line), fd); + fwrite(line, 1, strlen(line), fp); } - fclose(fd); + fclose(fp); return 0; @@ -211,35 +211,35 @@ _verify_passwd_int(const char *username, const char *passwd, static int filecopy(const char *src, const char *dst) { - FILE *fd, *fd2; + FILE *fp, *fp2; char line[5 * 1024]; char *p; - fd = fopen(dst, "w"); - if (fd == NULL) { + fp = fopen(dst, "w"); + if (fp == NULL) { fprintf(stderr, "Cannot open '%s' for write\n", dst); return -1; } - fd2 = fopen(src, "r"); - if (fd2 == NULL) { + fp2 = fopen(src, "r"); + if (fp2 == NULL) { /* empty file */ - fclose(fd); + fclose(fp); return 0; } line[sizeof(line) - 1] = 0; do { - p = fgets(line, sizeof(line) - 1, fd2); + p = fgets(line, sizeof(line) - 1, fp2); if (p == NULL) break; - fputs(line, fd); + fputs(line, fp); } while (1); - fclose(fd); - fclose(fd2); + fclose(fp); + fclose(fp2); return 0; } @@ -247,18 +247,18 @@ static int filecopy(const char *src, const char *dst) /* accepts password file */ static int find_strchr(const char *username, const char *file) { - FILE *fd; + FILE *fp; char *pos; char line[5 * 1024]; unsigned int i; - fd = fopen(file, "r"); - if (fd == NULL) { + fp = fopen(file, "r"); + if (fp == NULL) { fprintf(stderr, "Cannot open file '%s'\n", file); return -1; } - while (fgets(line, sizeof(line), fd) != NULL) { + while (fgets(line, sizeof(line), fp) != NULL) { /* move to first ':' */ i = 0; while ((line[i] != ':') && (line[i] != '\0') @@ -269,12 +269,12 @@ static int find_strchr(const char *username, const char *file) /* find the index */ pos = strrchr(line, ':'); pos++; - fclose(fd); + fclose(fp); return atoi(pos); } } - fclose(fd); + fclose(fp); return -1; } @@ -285,7 +285,7 @@ static int verify_passwd(const char *conffile, const char *tpasswd, const char *username, const char *passwd) { - FILE *fd; + FILE *fp; char line[5 * 1024]; unsigned int i; gnutls_datum_t g, n; @@ -299,14 +299,14 @@ verify_passwd(const char *conffile, const char *tpasswd, return -1; } - fd = fopen(conffile, "r"); - if (fd == NULL) { + fp = fopen(conffile, "r"); + if (fp == NULL) { fprintf(stderr, "Cannot find %s\n", conffile); return -1; } do { - p = fgets(line, sizeof(line) - 1, fd); + p = fgets(line, sizeof(line) - 1, fp); } while (p != NULL && atoi(p) != iindex); @@ -316,20 +316,20 @@ verify_passwd(const char *conffile, const char *tpasswd, } line[sizeof(line) - 1] = 0; - fclose(fd); + fclose(fp); if ((iindex = read_conf_values(&g, &n, line)) < 0) { fprintf(stderr, "Cannot parse conf file '%s'\n", conffile); return -1; } - fd = fopen(tpasswd, "r"); - if (fd == NULL) { + fp = fopen(tpasswd, "r"); + if (fp == NULL) { fprintf(stderr, "Cannot open file '%s'\n", tpasswd); return -1; } - while (fgets(line, sizeof(line), fd) != NULL) { + while (fgets(line, sizeof(line), fp) != NULL) { /* move to first ':' * This is the actual verifier. */ @@ -342,7 +342,7 @@ verify_passwd(const char *conffile, const char *tpasswd, char *verifier_pos, *salt_pos; pos = strchr(line, ':'); - fclose(fd); + fclose(fp); if (pos == NULL) { fprintf(stderr, "Cannot parse conf file '%s'\n", @@ -369,7 +369,7 @@ verify_passwd(const char *conffile, const char *tpasswd, } } - fclose(fd); + fclose(fp); return -1; } @@ -511,7 +511,7 @@ int crypt_int(const char *username, const char *passwd, int salt_size, const char *tpasswd_conf, const char *tpasswd, int uindex) { - FILE *fd; + FILE *fp; char *cr; gnutls_datum_t g, n; char line[5 * 1024]; @@ -519,14 +519,14 @@ crypt_int(const char *username, const char *passwd, int salt_size, int iindex; char tmpname[1024]; - fd = fopen(tpasswd_conf, "r"); - if (fd == NULL) { + fp = fopen(tpasswd_conf, "r"); + if (fp == NULL) { fprintf(stderr, "Cannot find %s\n", tpasswd_conf); return -1; } do { /* find the specified uindex in file */ - p = fgets(line, sizeof(line) - 1, fd); + p = fgets(line, sizeof(line) - 1, fp); } while (p != NULL && (iindex = atoi(p)) != uindex); @@ -536,7 +536,7 @@ crypt_int(const char *username, const char *passwd, int salt_size, } line[sizeof(line) - 1] = 0; - fclose(fd); + fclose(fp); if ((iindex = read_conf_values(&g, &n, line)) < 0) { fprintf(stderr, "Cannot parse conf file '%s'\n", tpasswd_conf); @@ -550,7 +550,7 @@ crypt_int(const char *username, const char *passwd, int salt_size, } else { /* delete previous entry */ struct stat st; - FILE *fd2; + FILE *fp2; int put; if (strlen(tpasswd) + 5 > sizeof(tmpname)) { @@ -572,16 +572,16 @@ crypt_int(const char *username, const char *passwd, int salt_size, return -1; } - fd = fopen(tpasswd, "w"); - if (fd == NULL) { + fp = fopen(tpasswd, "w"); + if (fp == NULL) { fprintf(stderr, "Cannot open '%s' for write\n", tpasswd); (void)remove(tmpname); return -1; } - fd2 = fopen(tmpname, "r"); - if (fd2 == NULL) { + fp2 = fopen(tmpname, "r"); + if (fp2 == NULL) { fprintf(stderr, "Cannot open '%s' for read\n", tmpname); (void)remove(tmpname); @@ -590,7 +590,7 @@ crypt_int(const char *username, const char *passwd, int salt_size, put = 0; do { - p = fgets(line, sizeof(line) - 1, fd2); + p = fgets(line, sizeof(line) - 1, fp2); if (p == NULL) break; @@ -602,20 +602,20 @@ crypt_int(const char *username, const char *passwd, int salt_size, MAX(strlen(username), (unsigned int) (pp - p))) == 0) { put = 1; - fprintf(fd, "%s:%s:%u\n", username, cr, + fprintf(fp, "%s:%s:%u\n", username, cr, iindex); } else { - fputs(line, fd); + fputs(line, fp); } } while (1); if (put == 0) { - fprintf(fd, "%s:%s:%u\n", username, cr, iindex); + fprintf(fp, "%s:%s:%u\n", username, cr, iindex); } - fclose(fd); - fclose(fd2); + fclose(fp); + fclose(fp2); (void)remove(tmpname); diff --git a/tests/aead-cipher-vec.c b/tests/aead-cipher-vec.c index 10e3db8626..fba9010d9e 100644 --- a/tests/aead-cipher-vec.c +++ b/tests/aead-cipher-vec.c @@ -116,6 +116,7 @@ doit(void) } start("aes-128-gcm", GNUTLS_CIPHER_AES_128_GCM); + start("aes-192-gcm", GNUTLS_CIPHER_AES_192_GCM); start("aes-256-gcm", GNUTLS_CIPHER_AES_256_GCM); start("aes-128-ccm", GNUTLS_CIPHER_AES_128_CCM); if (!gnutls_fips140_mode_enabled()) diff --git a/tests/atfork.c b/tests/atfork.c index 42c4851efd..654519dc7c 100644 --- a/tests/atfork.c +++ b/tests/atfork.c @@ -32,7 +32,6 @@ #include <sys/wait.h> #endif -#include "utils.h" #include <gnutls/gnutls.h> #include <gnutls/crypto.h> @@ -46,6 +45,10 @@ void doit(void) #include "../lib/atfork.h" #include "../lib/atfork.c" +/* utils.h must be loaded after gnutls_int.h, as it redefines some + * macros from gnulib */ +#include "utils.h" + void doit(void) { pid_t pid; diff --git a/tests/mpi.c b/tests/mpi.c index 604024622d..65a0dd0516 100644 --- a/tests/mpi.c +++ b/tests/mpi.c @@ -26,12 +26,15 @@ #include <stdio.h> -#include "utils.h" #include "../lib/gnutls_int.h" #include "../lib/mpi.h" #include "../lib/errors.h" #include "../lib/debug.h" +/* utils.h must be loaded after gnutls_int.h, as it redefines some + * macros from gnulib */ +#include "utils.h" + static void tls_log_func(int level, const char *str) { fprintf(stderr, "|<%d>| %s", level, str); diff --git a/tests/pkcs12_s2k.c b/tests/pkcs12_s2k.c index 7301f293f5..1516afbf35 100644 --- a/tests/pkcs12_s2k.c +++ b/tests/pkcs12_s2k.c @@ -26,11 +26,14 @@ #include <stdio.h> -#include <utils.h> #include "../lib/gnutls_int.h" #include "../lib/x509/x509_int.h" #include "../lib/debug.h" +/* utils.h must be loaded after gnutls_int.h, as it redefines some + * macros from gnulib */ +#include <utils.h> + static void tls_log_func(int level, const char *str) { fprintf(stderr, "|<%d>| %s", level, str); diff --git a/tests/slow/cipher-api-test.c b/tests/slow/cipher-api-test.c index a29963aa5a..17872b7a43 100644 --- a/tests/slow/cipher-api-test.c +++ b/tests/slow/cipher-api-test.c @@ -266,8 +266,10 @@ void start(const char *name, int algo, unsigned aead) void doit(void) { start("aes128-gcm", GNUTLS_CIPHER_AES_128_GCM, 1); + start("aes192-gcm", GNUTLS_CIPHER_AES_192_GCM, 1); start("aes256-gcm", GNUTLS_CIPHER_AES_256_GCM, 1); start("aes128-cbc", GNUTLS_CIPHER_AES_128_CBC, 0); + start("aes192-cbc", GNUTLS_CIPHER_AES_192_CBC, 0); start("aes256-cbc", GNUTLS_CIPHER_AES_256_CBC, 0); start("3des-cbc", GNUTLS_CIPHER_3DES_CBC, 0); if (!gnutls_fips140_mode_enabled()) { diff --git a/tests/slow/cipher-openssl-compat.c b/tests/slow/cipher-openssl-compat.c index 64adf25a45..3d55131e52 100644 --- a/tests/slow/cipher-openssl-compat.c +++ b/tests/slow/cipher-openssl-compat.c @@ -195,6 +195,7 @@ void doit(void) /* ciphers */ cipher_test("aes-128-gcm", GNUTLS_CIPHER_AES_128_GCM, 16); + cipher_test("aes-192-gcm", GNUTLS_CIPHER_AES_192_GCM, 16); cipher_test("aes-256-gcm", GNUTLS_CIPHER_AES_256_GCM, 16); #if OPENSSL_VERSION_NUMBER >= 0x10100000L if (!gnutls_fips140_mode_enabled()) { diff --git a/tests/srp.c b/tests/srp.c index c927e877be..607e52ae46 100644 --- a/tests/srp.c +++ b/tests/srp.c @@ -329,21 +329,21 @@ const char *tpasswd_conf_file = void doit(void) { - FILE *fd; + FILE *fp; - fd = fopen("tpasswd.conf", "w"); - if (fd == NULL) + fp = fopen("tpasswd.conf", "w"); + if (fp == NULL) exit(1); - fwrite(tpasswd_conf_file, 1, strlen(tpasswd_conf_file), fd); - fclose(fd); + fwrite(tpasswd_conf_file, 1, strlen(tpasswd_conf_file), fp); + fclose(fp); - fd = fopen("tpasswd", "w"); - if (fd == NULL) + fp = fopen("tpasswd", "w"); + if (fp == NULL) exit(1); - fwrite(tpasswd_file, 1, strlen(tpasswd_file), fd); - fclose(fd); + fwrite(tpasswd_file, 1, strlen(tpasswd_file), fp); + fclose(fp); start("tls1.2 srp-1024", "NORMAL:-VERS-ALL:+VERS-TLS1.2:-KX-ALL:+SRP", "test", "test", 0); start("tls1.2 srp-1536", "NORMAL:-VERS-ALL:+VERS-TLS1.2:-KX-ALL:+SRP", "test2", "test2", 0); diff --git a/tests/tls13/anti_replay.c b/tests/tls13/anti_replay.c index e0aea00385..506c11596a 100644 --- a/tests/tls13/anti_replay.c +++ b/tests/tls13/anti_replay.c @@ -24,11 +24,14 @@ #include <assert.h> #include <stdint.h> -#include "utils.h" #include "virt-time.h" #include "../../lib/tls13/anti_replay.h" #include "../../lib/system.h" +/* utils.h must be loaded after gnutls_int.h, as it redefines some + * macros from gnulib */ +#include "utils.h" + #define MAX_CLIENT_HELLO_RECORDED 10 struct storage_st { diff --git a/tests/utils.h b/tests/utils.h index 61d6dc9f9e..935368088a 100644 --- a/tests/utils.h +++ b/tests/utils.h @@ -41,13 +41,13 @@ # error tests cannot be compiled with NDEBUG defined #endif -#if _GNUTLS_GCC_VERSION >= 70100 -#define FALLTHROUGH __attribute__ ((fallthrough)) -#endif - #ifndef FALLTHROUGH +#if _GNUTLS_GCC_VERSION >= 70100 +# define FALLTHROUGH __attribute__ ((fallthrough)) +#else # define FALLTHROUGH #endif +#endif /* number of elements within an array */ #define countof(a) (sizeof(a)/sizeof(*(a))) |