From ce485d99b3e9a581854a43296bbfce063240dfaf Mon Sep 17 00:00:00 2001 From: Hideki Miyazaki Date: Thu, 11 Feb 2021 11:37:50 +0900 Subject: [PATCH 01/16] implemented L_FILE_LOAD case --- src/ssl.c | 88 ++++++++++++++++++++++++++++++++++++++++++++++++--- wolfssl/ssl.h | 2 ++ 2 files changed, 85 insertions(+), 5 deletions(-) diff --git a/src/ssl.c b/src/ssl.c index 5bcbe43ee..64dc9b623 100644 --- a/src/ssl.c +++ b/src/ssl.c @@ -24818,16 +24818,33 @@ int wolfSSL_X509_LOOKUP_ctrl(WOLFSSL_X509_LOOKUP *ctx, int cmd, const char *argc, long argl, char **ret) { /* control commands: - * X509_L_FILE_LOAD, X509_L_ADD_DIR, X509_L_ADD_STORE, X509_L_LOAD_STORE + * X509_L_FILE_LOAD, X509_L_ADD_DIR + * X509_L_ADD_STORE, X509_L_LOAD_STORE */ + int lret = WOLFSSL_FAILURE; - /* returns -1 if the X509_LOOKUP doesn't have an associated X509_LOOKUP_METHOD */ - - + /* returns FAILURE + *if the X509_LOOKUP doesn't have an associated X509_LOOKUP_METHOD */ if (ctx != NULL) { switch (cmd) { case WOLFSSL_X509_L_FILE_LOAD: + if (argl == WOLFSSL_FILETYPE_PEM) { +#ifdef HAVE_CRL + lret = wolfSSL_X509_load_cert_crl_file(ctx, argc, + X509_FILETYPE_PEM); +#else + lret = 0; +#endif + } else { + lret = wolfSSL_X509_LOOKUP_load_file(ctx, argc, (int)argl); + } + /* expects to return a number of processed cert or crl file */ + if (lret != 0) + lret = WOLFSSL_SUCCESS; + else + lret = WOLFSSL_FAILURE; + break; case WOLFSSL_X509_L_ADD_DIR: case WOLFSSL_X509_L_ADD_STORE: case WOLFSSL_X509_L_LOAD_STORE: @@ -24841,7 +24858,7 @@ int wolfSSL_X509_LOOKUP_ctrl(WOLFSSL_X509_LOOKUP *ctx, int cmd, (void)argc; (void)argl; (void)ret; - return WOLFSSL_FAILURE; + return lret; } @@ -26253,6 +26270,67 @@ WOLFSSL_API int wolfSSL_X509_load_crl_file(WOLFSSL_X509_LOOKUP *ctx, WOLFSSL_LEAVE("wolfSSL_X509_load_crl_file", ret); return ret; } + +WOLFSSL_API int wolfSSL_X509_load_cert_crl_file(WOLFSSL_X509_LOOKUP *ctx, + const char *file, int type) +{ + STACK_OF(WOLFSSL_X509_INFO) *info; + WOLFSSL_X509_INFO *info_tmp; + WOLFSSL_BIO *bio; + + int i; + int cnt = 0; + int num = 0; + + WOLFSSL_ENTER("wolfSSL_X509_load_ceretificate_crl_file"); + + if (type != WOLFSSL_FILETYPE_PEM) { + cnt = wolfSSL_X509_LOOKUP_load_file(ctx, file, type); + } else { +#ifdef OPENSSL_ALL + bio = wolfSSL_BIO_new_file(file, "rb"); + if(!bio) { + WOLFSSL_MSG("wolfSSL_BIO_new error"); + return cnt; + } + + info = wolfSSL_PEM_X509_INFO_read_bio(bio, NULL, NULL, NULL); + + wolfSSL_BIO_free(bio); + + if (!info) { + WOLFSSL_MSG("wolfSSL_PEM_X509_INFO_read_bio error"); + return cnt; + } + + for (i=0; i < num; i++) { + info_tmp = wolfSSL_sk_X509_INFO_value(info, i); + + if (info_tmp->x509) { + wolfSSL_X509_STORE_add_cert(ctx->store, info_tmp->x509); + cnt ++; + } + + if (info_tmp->crl) { + wolfSSL_X509_STORE_add_cert(ctx->store, info_tmp->x509); + cnt ++; + } + } + wolfSSL_sk_X509_INFO_pop_free(info, X509_INFO_free); +#else + (void)i; + (void)cnt; + (void)num; + (void)info_tmp; + (void)info; + (void)bio; +#endif + } + + WOLFSSL_LEAVE("wolfSSL_X509_load_ceretificate_crl_file", count); + return cnt; +} + #endif /* !NO_FILESYSTEM */ diff --git a/wolfssl/ssl.h b/wolfssl/ssl.h index a6697e8bc..1e593213e 100644 --- a/wolfssl/ssl.h +++ b/wolfssl/ssl.h @@ -1590,6 +1590,8 @@ WOLFSSL_API int wolfSSL_X509_VERIFY_PARAM_set1(WOLFSSL_X509_VERIFY_PARAM* to, const WOLFSSL_X509_VERIFY_PARAM* from); WOLFSSL_API int wolfSSL_X509_load_crl_file(WOLFSSL_X509_LOOKUP *ctx, const char *file, int type); +WOLFSSL_API int wolfSSL_X509_load_cert_crl_file(WOLFSSL_X509_LOOKUP *ctx, + const char *file, int type); #endif WOLFSSL_API WOLFSSL_X509_REVOKED* wolfSSL_X509_CRL_get_REVOKED(WOLFSSL_X509_CRL*); WOLFSSL_API WOLFSSL_X509_REVOKED* wolfSSL_sk_X509_REVOKED_value( From b4a573ca98b446ec8c5b05f57c467e641e4acb11 Mon Sep 17 00:00:00 2001 From: Hideki Miyazaki Date: Mon, 15 Feb 2021 15:47:03 +0900 Subject: [PATCH 02/16] Initial implemented X509_LOOKUP_ctrl L_ADD_DIR --- examples/client/client.c | 73 ++- examples/server/server.c | 74 ++- scripts/crl-revoked.test | 89 +++- src/crl.c | 14 + src/internal.c | 229 +++++++++- src/ssl.c | 869 ++++++++++++++++++++++++++++++++---- tests/api.c | 417 ++++++++++++++++- wolfcrypt/src/asn.c | 80 ++++ wolfcrypt/src/wc_port.c | 71 +-- wolfssl/internal.h | 13 + wolfssl/ssl.h | 55 +++ wolfssl/test.h | 2 + wolfssl/wolfcrypt/asn.h | 2 + wolfssl/wolfcrypt/types.h | 2 + wolfssl/wolfcrypt/wc_port.h | 18 +- 15 files changed, 1879 insertions(+), 129 deletions(-) diff --git a/examples/client/client.c b/examples/client/client.c index e47cf054f..11f2c92b6 100644 --- a/examples/client/client.c +++ b/examples/client/client.c @@ -949,7 +949,7 @@ static int ClientRead(WOLFSSL* ssl, char* reply, int replyLen, int mustRead, /* 4. add the same message into Japanese section */ /* (will be translated later) */ /* 5. add printf() into suitable position of Usage() */ -static const char* client_usage_msg[][66] = { +static const char* client_usage_msg[][67] = { /* English */ { " NOTE: All files relative to wolfSSL home dir\n", /* 0 */ @@ -1120,8 +1120,15 @@ static const char* client_usage_msg[][66] = { #ifdef HAVE_CURVE448 "-8 Use X448 for key exchange\n", /* 66 */ #endif -#ifdef HAVE_CRL - "-C Disable CRL\n", +#if defined(OPENSSL_ALL) && defined(WOLFSSL_CERT_GEN) && \ + (defined(WOLFSSL_CERT_REQ) || defined(OLFSSL_CERT_EXT)) && \ + !defined(NO_FILESYSTEM) && !defined(NO_WOLFSSL_DIR) + "-9 Use hash dir look up for certificate loading\n" + " loading from /certs folder\n" + " files in the folder would have the form \"hash.N\" file name\n" + " e.g symbolic link to the file at certs folder\n" + " ln -s ca-cert.pem `openssl x509 -in ca-cert.pem -hash -noout`.0\n", + /* 67 */ #endif NULL, }, @@ -1294,8 +1301,19 @@ static const char* client_usage_msg[][66] = { #ifdef HAVE_TRUSTED_CA "-5 信頼できる認証局の鍵表示を使用する\n", /* 63 */ #endif + "-6 WANT_WRITE エラーを全てのIO 送信でシュミレートします\n", #ifdef HAVE_CURVE448 "-8 Use X448 for key exchange\n", /* 66 */ +#endif +#if defined(OPENSSL_ALL) && defined(WOLFSSL_CERT_GEN) && \ + (defined(WOLFSSL_CERT_REQ) || defined(OLFSSL_CERT_EXT)) && \ + !defined(NO_FILESYSTEM) && !defined(NO_WOLFSSL_DIR) + "-9 証明書の読み込みに hash dir 機能を使用する\n" + " /certs フォルダーからロードします\n" + " フォルダー中のファイルは、\"hash.N\"[N:0-9]名である必要があります\n" + " 以下の例ではca-cert.pemにシンボリックリンクを設定します\n" + " ln -s ca-cert.pem `openssl x509 -in ca-cert.pem -hash -noout`.0\n", + /* 67 */ #endif NULL, }, @@ -1465,9 +1483,15 @@ static void Usage(void) #ifdef HAVE_TRUSTED_CA printf("%s", msg[++msgid]); /* -5 */ #endif + printf("%s", msg[++msgid]); /* -6 */ #ifdef HAVE_CURVE448 printf("%s", msg[++msgid]); /* -8 */ #endif +#if defined(OPENSSL_ALL) && defined(WOLFSSL_CERT_GEN) && \ + (defined(WOLFSSL_CERT_REQ) || defined(OLFSSL_CERT_EXT)) && \ + !defined(NO_FILESYSTEM) && !defined(NO_WOLFSSL_DIR) + printf("%s", msg[++msgid]); /* -9 */ +#endif } THREAD_RETURN WOLFSSL_THREAD client_test(void* args) @@ -1601,6 +1625,11 @@ THREAD_RETURN WOLFSSL_THREAD client_test(void* args) #ifdef HAVE_WNR const char* wnrConfigFile = wnrConfig; +#endif +#if defined(OPENSSL_ALL) && defined(WOLFSSL_CERT_GEN) && \ + (defined(WOLFSSL_CERT_REQ) || defined(OLFSSL_CERT_EXT)) && \ + !defined(NO_FILESYSTEM) && !defined(NO_WOLFSSL_DIR) + int useCertFolder = 0; #endif char buffer[WOLFSSL_MAX_ERROR_SZ]; @@ -1686,7 +1715,7 @@ THREAD_RETURN WOLFSSL_THREAD client_test(void* args) while ((ch = mygetopt(argc, argv, "?:" "ab:c:defgh:i;jk:l:mnop:q:rstuv:wxyz" "A:B:CDE:F:GH:IJKL:M:NO:PQRS:TUVW:XYZ:" - "01:23:4568" + "01:23:45689" "@#")) != -1) { switch (ch) { case '?' : @@ -2162,7 +2191,13 @@ THREAD_RETURN WOLFSSL_THREAD client_test(void* args) #endif #endif break; - + case '9' : +#if defined(OPENSSL_ALL) && defined(WOLFSSL_CERT_GEN) && \ + (defined(WOLFSSL_CERT_REQ) || defined(OLFSSL_CERT_EXT)) && \ + !defined(NO_FILESYSTEM) && !defined(NO_WOLFSSL_DIR) + useCertFolder = 1; + break; +#endif case '@' : { #ifdef HAVE_WC_INTROSPECTION @@ -2622,6 +2657,29 @@ THREAD_RETURN WOLFSSL_THREAD client_test(void* args) } if (!usePsk && !useAnon && !useVerifyCb && myVerifyAction != VERIFY_FORCE_FAIL) { + #if defined(OPENSSL_ALL) && defined(WOLFSSL_CERT_GEN) && \ + (defined(WOLFSSL_CERT_REQ) || defined(OLFSSL_CERT_EXT)) && \ + !defined(NO_FILESYSTEM) && !defined(NO_WOLFSSL_DIR) + if (useCertFolder) { + WOLFSSL_X509_STORE *store; + WOLFSSL_X509_LOOKUP *lookup; + + store = wolfSSL_CTX_get_cert_store(ctx); + if (store == NULL) { + wolfSSL_CTX_free(ctx); ctx = NULL; + err_sys("can't get WOLFSSL_X509_STORE"); + } + lookup = wolfSSL_X509_STORE_add_lookup(store, X509_LOOKUP_hash_dir()); + if (lookup == NULL) { + wolfSSL_CTX_free(ctx); ctx = NULL; + err_sys("can't add lookup"); + } + if (wolfSSL_X509_LOOKUP_ctrl(lookup, WOLFSSL_X509_L_ADD_DIR, caCertFolder, + X509_FILETYPE_PEM, NULL) != WOLFSSL_SUCCESS) { + err_sys("X509_LOOKUP_ctrl w/ L_ADD_DIR failed"); + } + } else { + #endif #ifdef NO_FILESYSTEM if (wolfSSL_CTX_load_verify_buffer(ctx, ca_cert_der_2048, sizeof_ca_cert_der_2048, SSL_FILETYPE_ASN1) != WOLFSSL_SUCCESS) { @@ -2669,6 +2727,11 @@ THREAD_RETURN WOLFSSL_THREAD client_test(void* args) } } #endif /* WOLFSSL_TRUST_PEER_CERT && !NO_FILESYSTEM */ + #if defined(OPENSSL_ALL) && defined(WOLFSSL_CERT_GEN) && \ + (defined(WOLFSSL_CERT_REQ) || defined(OLFSSL_CERT_EXT)) && \ + !defined(NO_FILESYSTEM) && !defined(NO_WOLFSSL_DIR) + } + #endif } if (useVerifyCb || myVerifyAction == VERIFY_FORCE_FAIL || myVerifyAction == VERIFY_USE_PREVERFIY) { diff --git a/examples/server/server.c b/examples/server/server.c index d69b276c7..092f86345 100644 --- a/examples/server/server.c +++ b/examples/server/server.c @@ -582,7 +582,7 @@ static void ServerWrite(WOLFSSL* ssl, const char* output, int outputLen) /* 4. add the same message into Japanese section */ /* (will be translated later) */ /* 5. add printf() into suitable position of Usage() */ -static const char* server_usage_msg[][56] = { +static const char* server_usage_msg[][57] = { /* English */ { " NOTE: All files relative to wolfSSL home dir\n", /* 0 */ @@ -705,6 +705,16 @@ static const char* server_usage_msg[][56] = { /* 55 */ #ifdef HAVE_CURVE448 "-8 Pre-generate Key share using Curve448 only\n", /* 56 */ +#endif +#if defined(OPENSSL_ALL) && defined(WOLFSSL_CERT_GEN) && \ + (defined(WOLFSSL_CERT_REQ) || defined(OLFSSL_CERT_EXT)) && \ + !defined(NO_FILESYSTEM) && !defined(NO_WOLFSSL_DIR) + "-9 Use hash dir look up for certificate loading\n" + " loading from /certs folder\n" + " files in the folder would have the form \"hash.N\" file name\n" + " e.g symbolic link to the file at certs folder\n" + " ln -s client-ca.pem `openssl x509 -in client-ca.pem -hash -noout`.0\n", + /* 57 */ #endif NULL, }, @@ -838,6 +848,16 @@ static const char* server_usage_msg[][56] = { /* 55 */ #ifdef HAVE_CURVE448 "-8 Pre-generate Key share using Curve448 only\n", /* 56 */ +#endif +#if defined(OPENSSL_ALL) && defined(WOLFSSL_CERT_GEN) && \ + (defined(WOLFSSL_CERT_REQ) || defined(OLFSSL_CERT_EXT)) && \ + !defined(NO_FILESYSTEM) && !defined(NO_WOLFSSL_DIR) + "-9 証明書の読み込みに hash dir 機能を使用する\n" + " /certs フォルダーからロードします\n" + " フォルダー中のファイルは、\"hash.N\"[N:0-9]名である必要があります\n" + " 以下の例ではca-cert.pemにシンボリックリンクを設定します\n" + " ln -s client-ca.pem `openssl x509 -in client-ca.pem -hash -noout`.0\n", + /* 57 */ #endif NULL, }, @@ -966,9 +986,15 @@ static void Usage(void) #ifdef HAVE_TRUSTED_CA printf("%s", msg[++msgId]); /* -5 */ #endif /* HAVE_TRUSTED_CA */ + printf("%s", msg[++msgId]); /* -6 */ #ifdef HAVE_CURVE448 printf("%s", msg[++msgId]); /* -8 */ #endif +#if defined(OPENSSL_ALL) && defined(WOLFSSL_CERT_GEN) && \ + (defined(WOLFSSL_CERT_REQ) || defined(OLFSSL_CERT_EXT)) && \ + !defined(NO_FILESYSTEM) && !defined(NO_WOLFSSL_DIR) + printf("%s", msg[++msgId]); /* -9 */ +#endif } THREAD_RETURN WOLFSSL_THREAD server_test(void* args) @@ -1126,6 +1152,11 @@ THREAD_RETURN WOLFSSL_THREAD server_test(void* args) #ifdef HAVE_ENCRYPT_THEN_MAC int disallowETM = 0; #endif +#if defined(OPENSSL_ALL) && defined(WOLFSSL_CERT_GEN) && \ + (defined(WOLFSSL_CERT_REQ) || defined(OLFSSL_CERT_EXT)) && \ + !defined(NO_FILESYSTEM) && !defined(NO_WOLFSSL_DIR) + int useCertFolder = 0; +#endif ((func_args*)args)->return_code = -1; /* error state */ @@ -1191,8 +1222,8 @@ THREAD_RETURN WOLFSSL_THREAD server_test(void* args) while ((ch = mygetopt(argc, argv, "?:" "abc:defgijk:l:mnop:q:rstuv:wxy" "A:B:C:D:E:FGH:IJKL:MNO:PQR:S:T;UVYZ:" - "01:23:4:568" - "@#")) != -1) { + "01:23:4:5689" + "@#")) != -1) { switch (ch) { case '?' : if(myoptarg!=NULL) { @@ -1620,7 +1651,13 @@ THREAD_RETURN WOLFSSL_THREAD server_test(void* args) #endif #endif break; - + case '9' : +#if defined(OPENSSL_ALL) && defined(WOLFSSL_CERT_GEN) && \ + (defined(WOLFSSL_CERT_REQ) || defined(OLFSSL_CERT_EXT)) && \ + !defined(NO_FILESYSTEM) && !defined(NO_WOLFSSL_DIR) + useCertFolder = 1; + break; +#endif case '@' : { #ifdef HAVE_WC_INTROSPECTION @@ -2011,7 +2048,29 @@ THREAD_RETURN WOLFSSL_THREAD server_test(void* args) #ifdef TEST_BEFORE_DATE verify_flags |= WOLFSSL_LOAD_FLAG_DATE_ERR_OKAY; #endif - + #if defined(OPENSSL_ALL) && defined(WOLFSSL_CERT_GEN) && \ + (defined(WOLFSSL_CERT_REQ) || defined(OLFSSL_CERT_EXT)) && \ + !defined(NO_FILESYSTEM) && !defined(NO_WOLFSSL_DIR) + if (useCertFolder) { + WOLFSSL_X509_STORE *store; + WOLFSSL_X509_LOOKUP *lookup; + + store = wolfSSL_CTX_get_cert_store(ctx); + if (store == NULL) { + wolfSSL_CTX_free(ctx); ctx = NULL; + err_sys("can't get WOLFSSL_X509_STORE"); + } + lookup = wolfSSL_X509_STORE_add_lookup(store, X509_LOOKUP_hash_dir()); + if (lookup == NULL) { + wolfSSL_CTX_free(ctx); ctx = NULL; + err_sys("can't add lookup"); + } + if (wolfSSL_X509_LOOKUP_ctrl(lookup, WOLFSSL_X509_L_ADD_DIR, caCertFolder, + X509_FILETYPE_PEM, NULL) != WOLFSSL_SUCCESS) { + err_sys("X509_LOOKUP_ctrl w/ L_ADD_DIR failed"); + } + } else { + #endif if (wolfSSL_CTX_load_verify_locations_ex(ctx, verifyCert, 0, verify_flags) != WOLFSSL_SUCCESS) { err_sys_ex(catastrophic, @@ -2026,6 +2085,11 @@ THREAD_RETURN WOLFSSL_THREAD server_test(void* args) } } #endif /* WOLFSSL_TRUST_PEER_CERT */ + #if defined(OPENSSL_ALL) && defined(WOLFSSL_CERT_GEN) && \ + (defined(WOLFSSL_CERT_REQ) || defined(OLFSSL_CERT_EXT)) && \ + !defined(NO_FILESYSTEM) && !defined(NO_WOLFSSL_DIR) + } + #endif } #endif diff --git a/scripts/crl-revoked.test b/scripts/crl-revoked.test index 9d7f7eba0..46d511a1c 100755 --- a/scripts/crl-revoked.test +++ b/scripts/crl-revoked.test @@ -107,9 +107,13 @@ run_test() { echo "" echo "Successful Revocation!!!!" echo "" - exit_code=0 - echo "exiting with $exit_code" - exit $exit_code + if [ $exit_hash_dir_code -ne 0 ]; then + exit_code=1 + else + exit_code=0 + echo "exiting with $exit_code" + exit $exit_code + fi ;; *) echo "" @@ -120,9 +124,88 @@ run_test() { esac } +run_hashdir_test() { + echo -e "\n\nHash dir with CRL and Certificate loading" + remove_ready_file + # create hashed cert and crl + pushd ${CERT_DIR} + # ca file + ca_hash_name=`openssl x509 -in ca-cert.pem -hash -noout` + if [ -f "$ca_hash_name".0 ]; then + rm "$ca_hash_name".0 + fi + ln -s ca-cert.pem "$ca_hash_name".0 + # crl file + crl_hash_name=`openssl crl -in ./crl/crl.pem -hash -noout` + if [ -f "$crl_hash_name".r0 ]; then + rm "$crl_hash_name".r0 + fi + ln -s ./crl/crl.pem "$crl_hash_name".r0 + popd + + # starts the server on crl_port, -R generates ready file to be used as a + # mutex lock, -c loads the revoked certificate. We capture the processid + # into the variable server_pid + ./examples/server/server -R $ready_file -p $crl_port \ + -c ${CERT_DIR}/server-revoked-cert.pem \ + -k ${CERT_DIR}/server-revoked-key.pem & + server_pid=$! + while [ ! -s $ready_file -a "$counter" -lt 20 ]; do + echo -e "waiting for ready file..." + sleep 0.1 + counter=$((counter+ 1)) + done + + # get created port 0 ephemeral port + crl_port="$(cat $ready_file)" + + # starts client on crl_port and captures the output from client + capture_out=$(./examples/client/client -p $crl_port -9 2>&1) + client_result=$? + + wait $server_pid + server_result=$? + + case "$capture_out" in + *$revocation_code*) + # only exit with zero on detection of the expected error code + echo "" + echo "Successful Revocation!!!! with hash dir" + echo "" + exit_hash_dir_code=0 + ;; + *) + echo "" + echo "Certificate was not revoked saw this instead: $capture_out" + echo "" + echo "configure with --enable-crl and run this script again" + echo "" + exit_hash_dir_code=1 + esac + + # clean up hashed cert and crl + pushd ${CERT_DIR} + rm "$ca_hash_name".0 + rm "$crl_hash_name".r0 + popd + +} ######### begin program ######### +# Check for enabling hash dir feature +./examples/client/client -? 2>&1 | grep -- 'hash dir' +if [ $? -eq 0 ]; then + hash_dir=yes + exit_hash_dir_code=1 +fi + +if [ "$hash_dir" = "yes" ]; then + run_hashdir_test +else + exit_hash_dir_code=0 +fi + # run the test run_test diff --git a/src/crl.c b/src/crl.c index 34f6281a8..5d6c7da61 100644 --- a/src/crl.c +++ b/src/crl.c @@ -364,6 +364,20 @@ int CheckCertCRL(WOLFSSL_CRL* crl, DecodedCert* cert) } #endif +#if defined(OPENSSL_ALL) && defined(WOLFSSL_CERT_GEN) && \ + (defined(WOLFSSL_CERT_REQ) || defined(OLFSSL_CERT_EXT)) && \ + !defined(NO_FILESYSTEM) && !defined(NO_WOLFSSL_DIR) + if (foundEntry == 0) { + if (crl->cm->x509_store_p != NULL) { + ret = LoadCrlCertByIssuer(crl->cm->x509_store_p, + (WOLFSSL_X509_NAME*)cert->issuerName, X509_LU_CRL); + if (ret == WOLFSSL_SUCCESS) { + /* try again */ + ret = CheckCertCRLList(crl, cert, &foundEntry); + } + } + } +#endif if (foundEntry == 0) { WOLFSSL_MSG("Couldn't find CRL for status check"); ret = CRL_MISSING; diff --git a/src/internal.c b/src/internal.c index b020213b9..d8c45cbf7 100644 --- a/src/internal.c +++ b/src/internal.c @@ -1809,7 +1809,9 @@ int InitSSL_Ctx(WOLFSSL_CTX* ctx, WOLFSSL_METHOD* method, void* heap) #ifdef OPENSSL_EXTRA /* setup WOLFSSL_X509_STORE */ ctx->x509_store.cm = ctx->cm; - + /* set pointer back to x509 store */ + ctx->cm->x509_store_p = &ctx->x509_store; + /* WOLFSSL_X509_VERIFY_PARAM */ if ((ctx->param = (WOLFSSL_X509_VERIFY_PARAM*)XMALLOC( sizeof(WOLFSSL_X509_VERIFY_PARAM), @@ -1818,6 +1820,13 @@ int InitSSL_Ctx(WOLFSSL_CTX* ctx, WOLFSSL_METHOD* method, void* heap) return MEMORY_E; } XMEMSET(ctx->param, 0, sizeof(WOLFSSL_X509_VERIFY_PARAM)); + /* WOLFSS_X509_LOOKUP */ + if ((ctx->x509_store.lookup.dirs = (WOLFSSL_BY_DIR*)XMALLOC(sizeof(WOLFSSL_BY_DIR), + ctx->heap, DYNAMIC_TYPE_OPENSSL)) == NULL) { + WOLFSSL_MSG("ctx-x509_store.lookup.dir memory allocation error"); + return MEMORY_E; + } + XMEMSET(ctx->x509_store.lookup.dirs, 0, sizeof(WOLFSSL_BY_DIR)); #endif #endif @@ -1969,6 +1978,15 @@ void SSL_CtxResourceFree(WOLFSSL_CTX* ctx) if (ctx->param) { XFREE(ctx->param, ctx->heap, DYNAMIC_TYPE_OPENSSL); } + + if (ctx->x509_store.lookup.dirs) { +#if defined(OPENSSL_ALL) && !defined(NO_FILESYSTEM) && !defined(NO_WOLFSSL_DIR) + if (!ctx->x509_store.lookup.dirs->dir_entry) { + wolfSSL_sk_BY_DIR_entry_free(ctx->x509_store.lookup.dirs->dir_entry); + } +#endif + XFREE(ctx->x509_store.lookup.dirs, ctx->heap, DYNAMIC_TYPE_OPENSSL); + } #endif #ifdef WOLFSSL_STATIC_EPHEMERAL #ifndef NO_DH @@ -10555,6 +10573,176 @@ static void FreeProcPeerCertArgs(WOLFSSL* ssl, void* pArgs) args->dCert = NULL; } } +#if defined(OPENSSL_ALL) && defined(WOLFSSL_CERT_GEN) && \ + (defined(WOLFSSL_CERT_REQ) || defined(OLFSSL_CERT_EXT)) && \ + !defined(NO_FILESYSTEM) && !defined(NO_WOLFSSL_DIR) +/* load certificate file which has .(r)N[0..N] in the folder */ +/* (r), in the case of CRL file */ +int LoadCrlCertByIssuer(WOLFSSL_X509_STORE* store, X509_NAME* issuer, int type) +{ + const int MAX_SUFFIX = 10; + int ret = WOLFSSL_SUCCESS; + WOLFSSL_X509_LOOKUP* lookup = &store->lookup; + WOLFSSL_BY_DIR_entry* entry; + WOLFSSL_BY_DIR_HASH hash_tmp; + WOLFSSL_BY_DIR_HASH* ph = NULL; + WOLFSSL_X509* x509; + unsigned long hash = 0; + char* filename = NULL; + const char* post = ""; + byte* pbuf = NULL; + int len, num, i, index; + byte suffix = 0; + int retHash = NOT_COMPILED_IN; + byte dgt[WC_MAX_DIGEST_SIZE]; + + WOLFSSL_ENTER("LoadCrlCertByIssuer"); + + /* sanity check */ + if (store == NULL || lookup->dirs == NULL || lookup->type != 1 + || (type != X509_LU_X509 && type != X509_LU_CRL)) { + return WOLFSSL_FAILURE; + } + + len = wolfSSL_i2d_X509_NAME_canon(issuer, &pbuf); + if (len > 0) { + #ifndef NO_SHA + retHash = wc_ShaHash((const byte*)pbuf, len, dgt); + #endif + if (retHash == 0) { + /* 4 bytes in small endian as unsigned long */ + hash = (((unsigned long)dgt[3] << 24) | + ((unsigned long)dgt[2] << 16) | + ((unsigned long)dgt[1] << 8) | + ((unsigned long)dgt[0])); + } else { + WOLFSSL_MSG("failed hash operation"); + return WOLFSSL_FAILURE; + } + } + + /* try to load each hashed name file in path */ +#if !defined(NO_FILESYSTE) && !defined(NO_WOLFSSL_DIR) + + if (type == X509_LU_CRL) { + post = "r"; + } + + num = wolfSSL_sk_BY_DIR_entry_num(lookup->dirs->dir_entry); + + for (i=0; idirs->dir_entry, i); + + len = XSTRLEN(entry->dir_name) + 13; + + if (filename != NULL) { + XFREE(filename, NULL, DYNAMIC_TYPE_OPENSSL); + } + + filename = (char*)XMALLOC(len, NULL, DYNAMIC_TYPE_OPENSSL); + if (filename == NULL) { + WOLFSSL_MSG("memory allcation error"); + return MEMORY_E; + } + + if (type == X509_LU_CRL && entry->hashes != NULL) { + /* lock the list */ + if (wc_LockMutex(&lookup->dirs->lock) != 0) { + WOLFSSL_MSG("wc_LockMutex cdir Lock error"); + return BAD_MUTEX_E; + } + + hash_tmp.hash_value = hash; + index = wolfSSL_sk_BY_DIR_HASH_find(entry->hashes, &hash_tmp); + if (index >= 0) { + WOLFSSL_MSG("find hashed CRL in list"); + ph = wolfSSL_sk_BY_DIR_HASH_value(entry->hashes, index); + suffix = ph->last_suffix; + } else { + ph = NULL; + suffix = 0; + } + + wc_UnLockMutex(&lookup->dirs->lock); + } + + for (; suffix < MAX_SUFFIX;suffix++) { + /* /folder-path/.(r)N[0..9] */ + XSNPRINTF(filename, len, "%s/%08lx.%s%d", entry->dir_name, + hash, post, suffix); + if(wc_FileExists(filename) == 0/*0 file exists */) { + + if (type == X509_LU_X509) { + x509 = wolfSSL_X509_load_certificate_file(filename, + WOLFSSL_FILETYPE_PEM); + if (x509 != NULL) { + ret = wolfSSL_X509_STORE_add_cert(store, x509); + } else { + WOLFSSL_MSG("failed to load certificate\n"); + ret = WOLFSSL_FAILURE; + break; + } + } +#ifdef HAVE_CRL + else if (type == X509_LU_CRL) { + ret = wolfSSL_X509_load_crl_file(&store->lookup, filename, + WOLFSSL_FILETYPE_PEM); + printf("return load crl file %d\n", ret); + if (ret != WOLFSSL_SUCCESS) { + WOLFSSL_MSG("failed to load CRL\n"); + break; + } + } +#else + else if (type == X509_LU_CRL) { + WOLFSSL_MSG("CRL is not supported"); + ret = WOLFSSL_FAILURE; + break; + } +#endif + } else + break; + } + + if (type == X509_LU_CRL) { + if (wc_LockMutex(&lookup->dirs->lock) != 0) { + WOLFSSL_MSG("wc_LockMutex cdir Lock error"); + return BAD_MUTEX_E; + } + if (ph == NULL) { + ph = wolfSSL_BY_DIR_HASH_new(); + if (ph == NULL) { + WOLFSSL_MSG("failed to allocate hash stack"); + ret = WOLFSSL_FAILURE; + } else { + ph->hash_value = hash; + ph->last_suffix = suffix; + + ret = wolfSSL_sk_BY_DIR_HASH_push(entry->hashes, ph); + } + } + wc_UnLockMutex(&lookup->dirs->lock); + } + + XFREE(filename, NULL, DYNAMIC_TYPE_OPENSSL); + } +#else + (void) type; + (void) ret; + (void) x509; + (void) filename; + (void) suffix; + (void) num; + (void) i; + ret = WOLFSSL_NOT_IMPLEMENTED; +#endif + WOLFSSL_LEAVE("LoadCrlCertByIssuer", ret); + + return ret; +} +#endif + static int ProcessPeerCertParse(WOLFSSL* ssl, ProcPeerCertArgs* args, int certType, int verify, byte** pSubjectHash, int* pAlreadySigner) @@ -10651,6 +10839,45 @@ static int ProcessPeerCertParse(WOLFSSL* ssl, ProcPeerCertArgs* args, /* Parse Certificate */ ret = ParseCertRelative(args->dCert, certType, verify, ssl->ctx->cm); +#if defined(OPENSSL_ALL) && defined(WOLFSSL_CERT_GEN) && \ + (defined(WOLFSSL_CERT_REQ) || defined(OLFSSL_CERT_EXT)) && \ + !defined(NO_FILESYSTEM) && !defined(NO_WOLFSSL_DIR) + if (ret == ASN_NO_SIGNER_E) { + WOLFSSL_MSG("try to load certificate if hash dir is set"); + if (ssl->ctx->x509_store_pt != NULL) { + ret = LoadCrlCertByIssuer(ssl->ctx->x509_store_pt, + (WOLFSSL_X509_NAME*)args->dCert->issuerName, + X509_LU_X509); + } else { + ret = LoadCrlCertByIssuer(&ssl->ctx->x509_store, + (WOLFSSL_X509_NAME*)args->dCert->issuerName, + X509_LU_X509); + } + + if (ret == WOLFSSL_SUCCESS) { + /* re try Parse Certificate */ + InitDecodedCert(args->dCert, cert->buffer, cert->length, ssl->heap); + args->dCertInit = 1; + args->dCert->sigCtx.devId = ssl->devId; + #ifdef WOLFSSL_ASYNC_CRYPT + args->dCert->sigCtx.asyncCtx = ssl; + #endif + #ifdef HAVE_PK_CALLBACKS + /* setup the PK callback context */ + ret = InitSigPkCb(ssl, &args->dCert->sigCtx); + if (ret != 0) + return ret; + #endif + ret = ParseCertRelative(args->dCert, certType, verify, + ssl->ctx->cm); + } else { + WOLFSSL_MSG("failed to load certificate from hash folder"); + /* restore return code */ + ret = ASN_NO_SIGNER_E; + } + } +#endif + /* perform below checks for date failure cases */ if (ret == 0 || ret == ASN_BEFORE_DATE_E || ret == ASN_AFTER_DATE_E) { /* get subject and determine if already loaded */ diff --git a/src/ssl.c b/src/ssl.c index 64dc9b623..11f47938e 100644 --- a/src/ssl.c +++ b/src/ssl.c @@ -15821,6 +15821,7 @@ int wolfSSL_set_compression(WOLFSSL* ssl) ctx->x509_store.cache = str->cache; ctx->x509_store_pt = str; /* take ownership of store and free it with CTX free */ + ctx->cm->x509_store_p = ctx->x509_store_pt; } @@ -23132,6 +23133,21 @@ int wolfSSL_X509_cmp(const WOLFSSL_X509 *a, const WOLFSSL_X509 *b) #if !defined(NO_CERTS) && (defined(OPENSSL_EXTRA) || \ defined(OPENSSL_EXTRA_X509_SMALL)) + int wolfSSL_ASN1_STRING_copy(WOLFSSL_ASN1_STRING* dest, + const WOLFSSL_ASN1_STRING* src) + { + if (src == NULL || dest == NULL) { + return WOLFSSL_FAILURE; + } + dest->type = src->type; + if(wolfSSL_ASN1_STRING_set(dest, src->data, src->length) + != WOLFSSL_SUCCESS) { + return WOLFSSL_FAILURE; + } + dest->flags = src->flags; + + return WOLFSSL_SUCCESS; + } /* Creates a new WOLFSSL_ASN1_STRING structure given the input type. * * type is the type of set when WOLFSSL_ASN1_STRING is created @@ -24813,6 +24829,111 @@ WOLFSSL_X509_LOOKUP_METHOD* wolfSSL_X509_LOOKUP_file(void) return &meth; } +static int x509AddCertDir(void *p, const char *argc, long argl) +{ + WOLFSSL_ENTER("x509AddCertDir"); + + (void)argl; +#if defined(OPENSSL_ALL) && !defined(NO_FILESYSTEM) && !defined(NO_WOLFSSL_DIR) + WOLFSSL_BY_DIR *ctx = (WOLFSSL_BY_DIR*)p; + WOLFSSL_BY_DIR_entry *entry; + size_t pathLen; + int i, num; + const char* c; +#ifdef WOLFSSL_SMALL_STACK + char *buf; +#else + char buf[MAX_FILENAME_SZ]; +#endif + + pathLen = 0; + c = argc; + /* zero length */ + if (c == NULL || *c == '\0') return WOLFSSL_FAILURE; + +#ifdef WOLFSSL_SMALL_STACK + buf = (char*)XMALLOC(MAX_FILENAME_SZ, NULL, DYNAMIC_TYPE_OPENSSL); + if (buf == NULL) { + WOLFSSL_LEAVE("x509AddCertDir", MEMORY_E); + return MEMORY_E; + } +#endif + + XMEMSET(buf, 0, MAX_FILENAME_SZ); + + do { + if (*c == SEPARATOR_CHAR || *c == '\0') { + + num = wolfSSL_sk_BY_DIR_entry_num(ctx->dir_entry); + + for (i=0; idir_entry, i); + + if (XSTRLEN(entry->dir_name) == pathLen && + XSTRNCMP(entry->dir_name, buf, pathLen) == 0) { + WOLFSSL_MSG("dir entry found"); + break; + } + } + + if (num == -1 || i == num) { + WOLFSSL_MSG("no entry found"); + + if (ctx->dir_entry == NULL) { + ctx->dir_entry = wolfSSL_sk_BY_DIR_entry_new_null(); + + if (ctx->dir_entry == NULL) { + WOLFSSL_MSG("failed to allocate dir_entry"); + return 0; + } + } + + entry = wolfSSL_BY_DIR_entry_new(); + if (entry == NULL) { + WOLFSSL_MSG("failed to allocate dir entry"); + return 0; + } + entry->dir_type = argl; + entry->dir_name = (char*)XMALLOC(pathLen + 1/* \0 termination*/ + , NULL, DYNAMIC_TYPE_OPENSSL); + entry->hashes = wolfSSL_sk_BY_DIR_HASH_new_null(); + if (entry->dir_name == NULL || entry->hashes == NULL) { + WOLFSSL_MSG("failed to allocate dir name"); + wolfSSL_BY_DIR_entry_free(entry); + return 0; + } + + XSTRNCPY(entry->dir_name, buf, pathLen); + entry->dir_name[pathLen] = '\0'; + + if (wolfSSL_sk_BY_DIR_entry_push(ctx->dir_entry, entry) + != WOLFSSL_SUCCESS) { + wolfSSL_BY_DIR_entry_free(entry); + return 0; + } + } + /* skip separator */ + if (*c == SEPARATOR_CHAR) c++; + + pathLen = 0; + XMEMSET(buf, 0, MAX_FILENAME_SZ); + } + buf[pathLen++] = *c; + + } while(*c++ != '\0'); + +#ifdef WOLFSSL_SMALL_STACK + XFREE(buf, 0, DYNAMIC_TYPE_OPENSSL); +#endif + + return WOLFSSL_SUCCESS; +#else + (void)p; + (void)argc; + return WOLFSSL_NOT_IMPLEMENTED; +#endif +} int wolfSSL_X509_LOOKUP_ctrl(WOLFSSL_X509_LOOKUP *ctx, int cmd, const char *argc, long argl, char **ret) @@ -24823,41 +24944,43 @@ int wolfSSL_X509_LOOKUP_ctrl(WOLFSSL_X509_LOOKUP *ctx, int cmd, */ int lret = WOLFSSL_FAILURE; + WOLFSSL_ENTER("wolfSSL_X509_LOOKUP_ctrl"); +#if !defined(NO_FILESYSTEM) /* returns FAILURE *if the X509_LOOKUP doesn't have an associated X509_LOOKUP_METHOD */ if (ctx != NULL) { switch (cmd) { case WOLFSSL_X509_L_FILE_LOAD: - if (argl == WOLFSSL_FILETYPE_PEM) { -#ifdef HAVE_CRL - lret = wolfSSL_X509_load_cert_crl_file(ctx, argc, - X509_FILETYPE_PEM); -#else - lret = 0; -#endif - } else { - lret = wolfSSL_X509_LOOKUP_load_file(ctx, argc, (int)argl); - } /* expects to return a number of processed cert or crl file */ - if (lret != 0) - lret = WOLFSSL_SUCCESS; - else - lret = WOLFSSL_FAILURE; + lret = wolfSSL_X509_load_cert_crl_file(ctx, argc, argl) > 0 ? + WOLFSSL_SUCCESS : WOLFSSL_FAILURE; break; case WOLFSSL_X509_L_ADD_DIR: + /* store directory loaction to use it later */ +#if !defined(NO_WOLFSSL_DIR) + lret = x509AddCertDir(ctx->dirs, argc, argl); +#else + lret = WOLFSSL_NOT_IMPLEMENTED +#endif + break; case WOLFSSL_X509_L_ADD_STORE: case WOLFSSL_X509_L_LOAD_STORE: - return WOLFSSL_SUCCESS; + return WOLFSSL_NOT_IMPLEMENTED; default: break; } - } - - (void)argc; (void)argl; (void)ret; - + (void)ret; +#else + (void)ctx; + (void)argc; + (void)argl; + (void)ret; + (void)cmd; + lret = WOLFSSL_NOT_IMPLEMENTED; +#endif return lret; } @@ -24869,10 +24992,10 @@ WOLFSSL_X509_LOOKUP* wolfSSL_X509_STORE_add_lookup(WOLFSSL_X509_STORE* store, if (store == NULL) return NULL; - /* Method is a dummy value and is not needed. */ - (void)m; /* Make sure the lookup has a back reference to the store. */ store->lookup.store = store; + /* store a type to know which method wants to be used for */ + store->lookup.type = m->type; return &store->lookup; } @@ -25727,7 +25850,13 @@ WOLFSSL_X509_STORE* wolfSSL_X509_STORE_new(void) NULL, DYNAMIC_TYPE_OPENSSL)) == NULL) { goto err_exit; } - + XMEMSET(store->param, 0, sizeof(WOLFSSL_X509_VERIFY_PARAM)); + if ((store->lookup.dirs = (WOLFSSL_BY_DIR*)XMALLOC(sizeof(WOLFSSL_BY_DIR), + NULL, DYNAMIC_TYPE_OPENSSL)) == NULL) { + WOLFSSL_MSG("store->lookup.dir memory allocation error"); + goto err_exit; + } + XMEMSET(store->lookup.dirs, 0, sizeof(WOLFSSL_BY_DIR)); #endif return store; @@ -25753,6 +25882,16 @@ void wolfSSL_X509_STORE_free(WOLFSSL_X509_STORE* store) XFREE(store->param, NULL, DYNAMIC_TYPE_OPENSSL); store->param = NULL; } + + if (store->lookup.dirs != NULL) { +#if defined(OPENSSL_ALL) && !defined(NO_FILESYSTEM) && !defined(NO_WOLFSSL_DIR) + if (!store->lookup.dirs->dir_entry) { + wolfSSL_sk_BY_DIR_entry_free(store->lookup.dirs->dir_entry); + } +#endif + XFREE(store->lookup.dirs, NULL, DYNAMIC_TYPE_OPENSSL); + store->lookup.dirs = NULL; + } #endif XFREE(store, NULL, DYNAMIC_TYPE_X509_STORE); } @@ -26166,6 +26305,87 @@ WOLFSSL_X509 *wolfSSL_d2i_X509_fp(XFILE fp, WOLFSSL_X509 **x509) WOLFSSL_ENTER("wolfSSL_d2i_X509_fp"); return (WOLFSSL_X509 *)wolfSSL_d2i_X509_fp_ex(fp, (void **)x509, CERT_TYPE); } + +WOLFSSL_API int wolfSSL_X509_load_cert_crl_file(WOLFSSL_X509_LOOKUP *ctx, + const char *file, int type) +{ + STACK_OF(WOLFSSL_X509_INFO) *info; + WOLFSSL_X509_INFO *info_tmp; + WOLFSSL_BIO *bio; + WOLFSSL_X509 *x509 = NULL; + + int i; + int cnt = 0; + int num = 0; + + WOLFSSL_ENTER("wolfSSL_X509_load_ceretificate_crl_file"); + + if (type != WOLFSSL_FILETYPE_PEM) { + x509 = wolfSSL_X509_load_certificate_file(file, type); + if (x509 != NULL) { + if (wolfSSL_X509_STORE_add_cert(ctx->store, x509) + == WOLFSSL_SUCCESS) { + cnt++; + } else { + WOLFSSL_MSG("wolfSSL_X509_STORE_add_cert error"); + } + } else { + WOLFSSL_MSG("wolfSSL_X509_load_certificate_file error"); + } + + } else { +#ifdef OPENSSL_ALL + bio = wolfSSL_BIO_new_file(file, "rb"); + if(!bio) { + WOLFSSL_MSG("wolfSSL_BIO_new error"); + return cnt; + } + + info = wolfSSL_PEM_X509_INFO_read_bio(bio, NULL, NULL, NULL); + + wolfSSL_BIO_free(bio); + + if (!info) { + WOLFSSL_MSG("wolfSSL_PEM_X509_INFO_read_bio error"); + return cnt; + } + num = wolfSSL_sk_X509_INFO_num(info); + for (i=0; i < num; i++) { + info_tmp = wolfSSL_sk_X509_INFO_value(info, i); + + if (info_tmp->x509) { + if(wolfSSL_X509_STORE_add_cert(ctx->store, info_tmp->x509) == + WOLFSSL_SUCCESS) { + cnt ++; + } else { + WOLFSSL_MSG("wolfSSL_X509_STORE_add_cert failed"); + } + } +#ifdef HAVE_CRL + if (info_tmp->crl) { + if(wolfSSL_X509_STORE_add_crl(ctx->store, info_tmp->crl) == + WOLFSSL_SUCCESS) { + cnt ++; + } else { + WOLFSSL_MSG("wolfSSL_X509_STORE_add_crl failed"); + } + } +#endif + } + wolfSSL_sk_X509_INFO_pop_free(info, X509_INFO_free); +#else + (void)i; + (void)cnt; + (void)num; + (void)info_tmp; + (void)info; + (void)bio; +#endif + } + + WOLFSSL_LEAVE("wolfSSL_X509_load_ceretificate_crl_file", cnt); + return cnt; +} #endif /* !NO_FILESYSTEM */ @@ -26271,65 +26491,7 @@ WOLFSSL_API int wolfSSL_X509_load_crl_file(WOLFSSL_X509_LOOKUP *ctx, return ret; } -WOLFSSL_API int wolfSSL_X509_load_cert_crl_file(WOLFSSL_X509_LOOKUP *ctx, - const char *file, int type) -{ - STACK_OF(WOLFSSL_X509_INFO) *info; - WOLFSSL_X509_INFO *info_tmp; - WOLFSSL_BIO *bio; - int i; - int cnt = 0; - int num = 0; - - WOLFSSL_ENTER("wolfSSL_X509_load_ceretificate_crl_file"); - - if (type != WOLFSSL_FILETYPE_PEM) { - cnt = wolfSSL_X509_LOOKUP_load_file(ctx, file, type); - } else { -#ifdef OPENSSL_ALL - bio = wolfSSL_BIO_new_file(file, "rb"); - if(!bio) { - WOLFSSL_MSG("wolfSSL_BIO_new error"); - return cnt; - } - - info = wolfSSL_PEM_X509_INFO_read_bio(bio, NULL, NULL, NULL); - - wolfSSL_BIO_free(bio); - - if (!info) { - WOLFSSL_MSG("wolfSSL_PEM_X509_INFO_read_bio error"); - return cnt; - } - - for (i=0; i < num; i++) { - info_tmp = wolfSSL_sk_X509_INFO_value(info, i); - - if (info_tmp->x509) { - wolfSSL_X509_STORE_add_cert(ctx->store, info_tmp->x509); - cnt ++; - } - - if (info_tmp->crl) { - wolfSSL_X509_STORE_add_cert(ctx->store, info_tmp->x509); - cnt ++; - } - } - wolfSSL_sk_X509_INFO_pop_free(info, X509_INFO_free); -#else - (void)i; - (void)cnt; - (void)num; - (void)info_tmp; - (void)info; - (void)bio; -#endif - } - - WOLFSSL_LEAVE("wolfSSL_X509_load_ceretificate_crl_file", count); - return cnt; -} #endif /* !NO_FILESYSTEM */ @@ -41390,6 +41552,168 @@ static int ConvertNIDToWolfSSL(int nid) } } +#if defined(OPENSSL_ALL) +static int wolfSSL_ASN1_STRING_canon(WOLFSSL_ASN1_STRING* asn_out, + const WOLFSSL_ASN1_STRING* asn_in) +{ + char* dst; + char* src; + int i, len; + + switch (asn_in->type) { + case MBSTRING_UTF8: + case V_ASN1_PRINTABLESTRING: + break; + default: + WOLFSSL_MSG("just copy string"); + return wolfSSL_ASN1_STRING_copy(asn_out, asn_in); + } + /* type is set as UTF8 */ + asn_out->type = MBSTRING_UTF8; + asn_out->length = wolfSSL_ASN1_STRING_to_UTF8( + (unsigned char**)&asn_out->data + , (WOLFSSL_ASN1_STRING*)asn_in); + + if (asn_out->length < 0) { + return WOLFSSL_FAILURE; + } + /* point to the last */ + dst = asn_out->data + asn_out->length; + /* point to the start */ + src = asn_out->data; + + len = asn_out->length; + + /* trimming spaces at the head and tail */ + dst--; + for (; (len > 0 && XISSPACE(*dst));len--) { + dst--; + } + for (; (len > 0 && XISSPACE(*src));len--){ + src++; + } + + /* point to the start */ + dst = asn_out->data; + + for (i = 0; i < len;dst++, i++) { + if (!XISASCII(*src)) { + /* keep non-ascii code */ + *dst = *src++; + } else if (XISSPACE(*src)) { + *dst = 0x20; /* space */ + /* remove the rest of spaces */ + while (XISSPACE(*++src) && i++ < len); + } else { + *dst = XTOLOWER(*src++); + } + } + /* put actual length */ + asn_out->length = dst - asn_out->data; + return WOLFSSL_SUCCESS; +} +/* this is to converts the x509 name structure into canonical DER format +* , which has the following rules: +* convert to UTF8 +* convert to lower case +* multi-spaces collapsed +* leading SEQUENCE hader is skipped +*/ +int wolfSSL_i2d_X509_NAME_canon(WOLFSSL_X509_NAME* name, unsigned char** out) +{ + int totalBytes = 0, i, idx; + byte *output, *local = NULL; +#ifdef WOLFSSL_SMALL_STACK + EncodedName* names = NULL; +#else + EncodedName names[MAX_NAME_ENTRIES]; +#endif + + if (out == NULL || name == NULL) + return BAD_FUNC_ARG; + +#ifdef WOLFSSL_SMALL_STACK + names = (EncodedName*)XMALLOC(sizeof(EncodedName) * MAX_NAME_ENTRIES, NULL, + DYNAMIC_TYPE_TMP_BUFFER); + if (names == NULL) + return MEMORY_E; +#endif + + XMEMSET(names, 0, sizeof(EncodedName) * MAX_NAME_ENTRIES); + + for (i = 0; i < MAX_NAME_ENTRIES; i++) { + WOLFSSL_X509_NAME_ENTRY* entry; + int ret; + + entry = wolfSSL_X509_NAME_get_entry(name, i); + if (entry != NULL && entry->set == 1) { + const char* nameStr; + WOLFSSL_ASN1_STRING* data; + WOLFSSL_ASN1_STRING* cano_data; + + cano_data = wolfSSL_ASN1_STRING_new(); + if (cano_data == NULL) + return MEMORY_E; + + data = wolfSSL_X509_NAME_ENTRY_get_data(entry); + if (data == NULL) { + #ifdef WOLFSSL_SMALL_STACK + XFREE(names, NULL, DYNAMIC_TYPE_TMP_BUFFER); + #endif + wolfSSL_ASN1_STRING_free(cano_data); + WOLFSSL_MSG("Error getting entry data"); + return WOLFSSL_FATAL_ERROR; + } + if (wolfSSL_ASN1_STRING_canon(cano_data, data) != WOLFSSL_SUCCESS) { + return WOLFSSL_FAILURE; + } + nameStr = (const char*)wolfSSL_ASN1_STRING_data(cano_data); + + ret = wc_EncodeName_cano(&names[i], nameStr, CTC_UTF8, + ConvertNIDToWolfSSL(entry->nid)); + if (ret < 0) { + #ifdef WOLFSSL_SMALL_STACK + XFREE(names, NULL, DYNAMIC_TYPE_TMP_BUFFER); + #endif + wolfSSL_ASN1_STRING_free(cano_data); + WOLFSSL_MSG("EncodeName failed"); + return WOLFSSL_FATAL_ERROR; + } + totalBytes += ret; + } + } + + /* skip header */ + /* check if using buffer passed in */ + if (*out == NULL) { + *out = local = (unsigned char*)XMALLOC(totalBytes, NULL, + DYNAMIC_TYPE_OPENSSL); + if (*out == NULL) { + return MEMORY_E; + } + } + output = *out; + idx = 0; + + for (i = 0; i < MAX_NAME_ENTRIES; i++) { + if (names[i].used) { + XMEMCPY(output + idx, names[i].encoded, names[i].totalLen); + idx += names[i].totalLen; + } + } + +#ifdef WOLFSSL_SMALL_STACK + XFREE(names, NULL, DYNAMIC_TYPE_TMP_BUFFER); +#endif + + /* used existing buffer passed in, so increment pointer */ + if (local == NULL) { + *out += totalBytes; + } + return totalBytes; +} +#endif + /* Converts the x509 name structure into DER format. * * out pointer to either a pre setup buffer or a pointer to null for @@ -45970,6 +46294,391 @@ void wolfSSL_sk_SSL_CIPHER_free(WOLF_STACK_OF(WOLFSSL_CIPHER)* sk) } } +#if defined(OPENSSL_ALL) && !defined(NO_FILESYSTEM) && !defined(NO_WOLFSSL_DIR) +/* WOLFSSL_BY_DIR_HASH stuff */ +WOLFSSL_BY_DIR_HASH* wolfSSL_BY_DIR_HASH_new(void) +{ + WOLFSSL_BY_DIR_HASH* dir_hash; + + WOLFSSL_ENTER("wolfSSL_BY_DIR_HASH_new"); + + dir_hash = (WOLFSSL_BY_DIR_HASH*)XMALLOC(sizeof(WOLFSSL_BY_DIR_HASH), NULL, + DYNAMIC_TYPE_OPENSSL); + if (dir_hash) { + XMEMSET(dir_hash, 0, sizeof(WOLFSSL_BY_DIR_HASH)); + } + return dir_hash; +} + +void wolfSSL_BY_DIR_HASH_free(WOLFSSL_BY_DIR_HASH* dir_hash) +{ + if (dir_hash == NULL) + return; + + XFREE(dir_hash, NULL, DYNAMIC_TYPE_OPENSSL); +} + +WOLFSSL_STACK* wolfSSL_sk_BY_DIR_HASH_new_null(void) +{ + WOLFSSL_STACK* sk = wolfSSL_sk_new_node(NULL); + + WOLFSSL_ENTER("wolfSSL_sk_BY_DIR_HASH_new_null"); + + if (sk) { + sk->type = STACK_TYPE_BY_DIR_hash; + } + return sk; +} + +/* returns value less than 0 on fail to match + * On a successful match the priority level found is returned + */ +int wolfSSL_sk_BY_DIR_HASH_find( + WOLF_STACK_OF(WOLFSSL_BY_DIR_HASH)* sk, const WOLFSSL_BY_DIR_HASH* toFind) +{ + WOLFSSL_STACK* next; + int i, sz; + + WOLFSSL_ENTER("wolfSSL_sk_BY_DIR_HASH_find"); + + if (sk == NULL || toFind == NULL) { + return WOLFSSL_FAILURE; + } + + sz = wolfSSL_sk_BY_DIR_HASH_num(sk); + next = sk; + for (i = 0; i < sz && next != NULL; i++) { + if (next->data.dir_hash->hash_value == toFind->hash_value) { + return sz - i; /* reverse because stack pushed highest on first */ + } + next = next->next; + } + return -1; +} + +int wolfSSL_sk_BY_DIR_HASH_num(const WOLF_STACK_OF(WOLFSSL_BY_DIR_HASH) *sk) +{ + WOLFSSL_ENTER("wolfSSL_sk_WOLFSSL_BY_DIR_HASH_num"); + + if (sk == NULL) + return -1; + return (int)sk->num; +} + +WOLFSSL_BY_DIR_HASH* wolfSSL_sk_BY_DIR_HASH_value( + const WOLF_STACK_OF(WOLFSSL_BY_DIR_HASH) *sk, int i) +{ + WOLFSSL_ENTER("wolfSSL_sk_BY_DIR_HASH_value"); + + for (; sk != NULL && i > 0; i--) + sk = sk->next; + + if (i != 0 || sk == NULL) + return NULL; + return sk->data.dir_hash; +} + +WOLFSSL_BY_DIR_HASH* wolfSSL_sk_BY_DIR_HASH_pop( + WOLF_STACK_OF(WOLFSSL_BY_DIR_HASH)* sk) +{ + WOLFSSL_STACK* node; + WOLFSSL_BY_DIR_HASH* hash; + + WOLFSSL_ENTER("wolfSSL_sk_BY_DIR_HASH_pop"); + + if (sk == NULL) { + return NULL; + } + + node = sk->next; + hash = sk->data.dir_hash; + + if (node != NULL) { /* update sk and remove node from stack */ + sk->data.dir_hash = node->data.dir_hash; + sk->next = node->next; + wolfSSL_sk_free_node(node); + } + else { /* last x509 in stack */ + sk->data.dir_hash = NULL; + } + + if (sk->num > 0) { + sk->num -= 1; + } + + return hash; +} + +void wolfSSL_sk_BY_DIR_HASH_pop_free(WOLF_STACK_OF(BY_DIR_HASH)* sk, + void (*f) (WOLFSSL_BY_DIR_HASH*)) +{ + WOLFSSL_STACK* node; + + WOLFSSL_ENTER("wolfSSL_sk_BY_DIR_HASH_pop_free"); + + if (sk == NULL) { + return; + } + + /* parse through stack freeing each node */ + node = sk->next; + while (node && sk->num > 1) { + WOLFSSL_STACK* tmp = node; + node = node->next; + + if (f) + f(tmp->data.dir_hash); + else + wolfSSL_BY_DIR_HASH_free(tmp->data.dir_hash); + tmp->data.dir_hash = NULL; + XFREE(tmp, NULL, DYNAMIC_TYPE_OPENSSL); + sk->num -= 1; + } + + /* free head of stack */ + if (sk->num == 1) { + if (f) + f(sk->data.dir_hash); + else + wolfSSL_BY_DIR_HASH_free(sk->data.dir_hash); + sk->data.dir_hash = NULL; + } + XFREE(sk, NULL, DYNAMIC_TYPE_OPENSSL); +} + +void wolfSSL_sk_BY_DIR_HASH_free(WOLF_STACK_OF(WOLFSSL_BY_DIR_HASH) *sk) +{ + wolfSSL_sk_BY_DIR_HASH_pop_free(sk, NULL); +} + + +/* Adds the WOLFSSL_BY_DIR_HASH to the stack "sk". "sk" takes control of "in" and + * tries to free it when the stack is free'd. + * + * return 1 on success 0 on fail + */ +int wolfSSL_sk_BY_DIR_HASH_push(WOLF_STACK_OF(WOLFSSL_BY_DIR_HASH)* sk, + WOLFSSL_BY_DIR_HASH* in) +{ + WOLFSSL_STACK* node; + + WOLFSSL_ENTER("wolfSSL_sk_BY_DIR_HASH_push"); + + if (sk == NULL || in == NULL) { + return WOLFSSL_FAILURE; + } + + /* no previous values in stack */ + if (sk->data.dir_hash == NULL) { + sk->data.dir_hash = in; + sk->num += 1; + return WOLFSSL_SUCCESS; + } + + /* stack already has value(s) create a new node and add more */ + node = (WOLFSSL_STACK*)XMALLOC(sizeof(WOLFSSL_STACK), NULL, + DYNAMIC_TYPE_OPENSSL); + if (node == NULL) { + WOLFSSL_MSG("Memory error"); + return WOLFSSL_FAILURE; + } + XMEMSET(node, 0, sizeof(WOLFSSL_STACK)); + + /* push new obj onto head of stack */ + node->data.dir_hash = sk->data.dir_hash; + node->next = sk->next; + node->type = sk->type; + sk->next = node; + sk->data.dir_hash = in; + sk->num += 1; + + return WOLFSSL_SUCCESS; +} + + +/* WOLFSSL_BY_DIR_entry stuff */ +WOLFSSL_BY_DIR_entry* wolfSSL_BY_DIR_entry_new(void) +{ + WOLFSSL_BY_DIR_entry* entry; + + WOLFSSL_ENTER("wolfSSL_BY_DIR_entry_new"); + + entry = (WOLFSSL_BY_DIR_entry*)XMALLOC(sizeof(WOLFSSL_BY_DIR_entry), NULL, + DYNAMIC_TYPE_OPENSSL); + + if (entry) { + XMEMSET(entry, 0, sizeof(WOLFSSL_BY_DIR_entry)); + } + return entry; +} + +void wolfSSL_BY_DIR_entry_free(WOLFSSL_BY_DIR_entry* entry) +{ + WOLFSSL_ENTER("wolfSSL_BY_DIR_entry_free"); + + if (entry == NULL) + return; + + if (entry->hashes) { + wolfSSL_sk_BY_DIR_HASH_free(entry->hashes); + } + + if (entry->dir_name != NULL) { + XFREE(entry->dir_name, NULL, DYNAMIC_TYPE_OPENSSL); + } + + XFREE(entry, NULL, DYNAMIC_TYPE_OPENSSL); +} + +WOLFSSL_STACK* wolfSSL_sk_BY_DIR_entry_new_null(void) +{ + WOLFSSL_STACK* sk = wolfSSL_sk_new_node(NULL); + + WOLFSSL_ENTER("wolfSSL_sk_BY_DIR_entry_new_null"); + + if (sk) { + sk->type = STACK_TYPE_BY_DIR_entry; + } + return sk; +} + +int wolfSSL_sk_BY_DIR_entry_num(const WOLF_STACK_OF(WOLFSSL_BY_DIR_entry) *sk) +{ + WOLFSSL_ENTER("wolfSSL_sk_BY_DIR_entry_num"); + + if (sk == NULL) + return -1; + return (int)sk->num; +} + +WOLFSSL_BY_DIR_entry* wolfSSL_sk_BY_DIR_entry_value( + const WOLF_STACK_OF(WOLFSSL_BY_DIR_entry) *sk, int i) +{ + WOLFSSL_ENTER("wolfSSL_sk_BY_DIR_entry_value"); + + for (; sk != NULL && i > 0; i--) + sk = sk->next; + + if (i != 0 || sk == NULL) + return NULL; + return sk->data.dir_entry; +} + +WOLFSSL_BY_DIR_entry* wolfSSL_sk_BY_DIR_entry_pop( + WOLF_STACK_OF(WOLFSSL_BY_DIR_entry)* sk) +{ + WOLFSSL_STACK* node; + WOLFSSL_BY_DIR_entry* entry; + + WOLFSSL_ENTER("wolfSSL_sk_BY_DIR_entry_pop"); + + if (sk == NULL) { + return NULL; + } + + node = sk->next; + entry = sk->data.dir_entry; + + if (node != NULL) { /* update sk and remove node from stack */ + sk->data.dir_entry = node->data.dir_entry; + sk->next = node->next; + wolfSSL_sk_free_node(node); + } + else { /* last x509 in stack */ + sk->data.dir_entry = NULL; + } + + if (sk->num > 0) { + sk->num -= 1; + } + + return entry; +} + +void wolfSSL_sk_BY_DIR_entry_pop_free(WOLF_STACK_OF(WOLFSSL_BY_DIR_entry)* sk, + void (*f) (WOLFSSL_BY_DIR_entry*)) +{ + WOLFSSL_STACK* node; + + WOLFSSL_ENTER("wolfSSL_sk_BY_DIR_entry_pop_free"); + + if (sk == NULL) { + return; + } + + /* parse through stack freeing each node */ + node = sk->next; + while (node && sk->num > 1) { + WOLFSSL_STACK* tmp = node; + node = node->next; + + if (f) + f(tmp->data.dir_entry); + else + wolfSSL_BY_DIR_entry_free(tmp->data.dir_entry); + tmp->data.dir_entry = NULL; + XFREE(tmp, NULL, DYNAMIC_TYPE_OPENSSL); + sk->num -= 1; + } + + /* free head of stack */ + if (sk->num == 1) { + if (f) + f(sk->data.dir_entry); + else + wolfSSL_BY_DIR_entry_free(sk->data.dir_entry); + sk->data.dir_entry = NULL; + } + XFREE(sk, NULL, DYNAMIC_TYPE_OPENSSL); +} + +void wolfSSL_sk_BY_DIR_entry_free(WOLF_STACK_OF(wolfSSL_BY_DIR_entry) *sk) +{ + wolfSSL_sk_BY_DIR_entry_pop_free(sk, NULL); +} + +/* Adds the wolfSSL_BY_DIR_entry to the stack "sk". "sk" takes control of "in" and + * tries to free it when the stack is free'd. + * + * return 1 on success 0 on fail + */ +int wolfSSL_sk_BY_DIR_entry_push(WOLF_STACK_OF(WOLFSSL_BY_DIR_entry)* sk, + WOLFSSL_BY_DIR_entry* in) +{ + WOLFSSL_STACK* node; + + if (sk == NULL || in == NULL) { + return WOLFSSL_FAILURE; + } + + /* no previous values in stack */ + if (sk->data.dir_entry == NULL) { + sk->data.dir_entry = in; + sk->num += 1; + return WOLFSSL_SUCCESS; + } + + /* stack already has value(s) create a new node and add more */ + node = (WOLFSSL_STACK*)XMALLOC(sizeof(WOLFSSL_STACK), NULL, + DYNAMIC_TYPE_OPENSSL); + if (node == NULL) { + WOLFSSL_MSG("Memory error"); + return WOLFSSL_FAILURE; + } + XMEMSET(node, 0, sizeof(WOLFSSL_STACK)); + + /* push new obj onto head of stack */ + node->data.dir_entry = sk->data.dir_entry; + node->next = sk->next; + node->type = sk->type; + sk->next = node; + sk->data.dir_entry = in; + sk->num += 1; + + return WOLFSSL_SUCCESS; +} + +#endif /* OPENSSL_ALL */ int wolfSSL_sk_X509_INFO_num(const WOLF_STACK_OF(WOLFSSL_X509_INFO) *sk) { diff --git a/tests/api.c b/tests/api.c index dde3d5406..c0ee92ddb 100644 --- a/tests/api.c +++ b/tests/api.c @@ -25732,6 +25732,137 @@ static void test_wolfSSL_X509_NAME(void) #endif /* defined(OPENSSL_EXTRA) && !defined(NO_DES3) */ } +static void test_wolfSSL_sk_X509_BY_DIR_HASH(void) +{ +#if defined(OPENSSL_ALL) && !defined(NO_FILESYSTEM) && !defined(NO_WOLFSSL_DIR) + STACK_OF(WOLFSSL_BY_DIR_HASH) *hash_stack; + WOLFSSL_BY_DIR_HASH *hash1; + WOLFSSL_BY_DIR_HASH *hash2; + WOLFSSL_BY_DIR_HASH *h; + const unsigned long dummy_hash[2] = { + 0x12345678, + 0x9abcdef0 + }; + int i, num; + + printf(testingFmt, "test_wolfSSL_sk_X509_BY_DIR_HASH"); + + /* new */ + AssertNotNull(hash1 = wolfSSL_BY_DIR_HASH_new()); + hash1->hash_value = dummy_hash[0]; + + AssertNotNull(hash2 = wolfSSL_BY_DIR_HASH_new()); + hash2->hash_value = dummy_hash[1]; + + AssertNotNull(hash_stack = wolfSSL_sk_BY_DIR_HASH_new_null()); + + /* push */ + AssertIntEQ(wolfSSL_sk_BY_DIR_HASH_push(NULL, NULL), + WOLFSSL_FAILURE); + AssertIntEQ(wolfSSL_sk_BY_DIR_HASH_push(NULL, hash1), + WOLFSSL_FAILURE); + AssertIntEQ(wolfSSL_sk_BY_DIR_HASH_push(hash_stack, NULL), + WOLFSSL_FAILURE); + + AssertIntEQ(wolfSSL_sk_BY_DIR_HASH_push(hash_stack, hash1), + WOLFSSL_SUCCESS); + AssertIntEQ(wolfSSL_sk_BY_DIR_HASH_push(hash_stack, + hash2), WOLFSSL_SUCCESS); + /* num and value */ + AssertIntEQ((num = wolfSSL_sk_BY_DIR_HASH_num(hash_stack)), 2); + for (i = 0; i < num; i++) { + AssertNotNull(h = wolfSSL_sk_BY_DIR_HASH_value(hash_stack, i)); + AssertTrue(h->hash_value == dummy_hash[num - i - 1]); + } + + /* pop */ + AssertNotNull(h = wolfSSL_sk_BY_DIR_HASH_pop(hash_stack)); + AssertIntEQ((num = wolfSSL_sk_BY_DIR_HASH_num(hash_stack)), 1); + + /* find */ + AssertIntEQ(wolfSSL_sk_BY_DIR_HASH_find(NULL, NULL), + WOLFSSL_FAILURE); + AssertIntEQ(wolfSSL_sk_BY_DIR_HASH_find(NULL, hash1), + WOLFSSL_FAILURE); + AssertIntEQ(wolfSSL_sk_BY_DIR_HASH_find(hash_stack, NULL), + WOLFSSL_FAILURE); + + AssertIntEQ(wolfSSL_sk_BY_DIR_HASH_push(hash_stack, hash2), + 1); + + /* free */ + wolfSSL_sk_BY_DIR_HASH_free(hash_stack); + + printf(resultFmt, passed); +#endif +} + + +static void test_wolfSSL_sk_X509_BY_DIR(void) +{ +#if defined(OPENSSL_ALL) && !defined(NO_FILESYSTEM) && !defined(NO_WOLFSSL_DIR) + STACK_OF(WOLFSSL_BY_DIR_entry) *entry_stack; + WOLFSSL_BY_DIR_entry *entry1; + WOLFSSL_BY_DIR_entry *entry2; + WOLFSSL_BY_DIR_entry *ent; + const char* dummy_dir[2] = { + "/hoge/hoge/foo/foo", + "/foo1/hoge2/abc/defg" + }; + int i, num; + size_t len; + + printf(testingFmt, "test_wolfSSL_X509_sk_BY_DIR"); + + /* new */ + AssertNotNull(entry1 = wolfSSL_BY_DIR_entry_new()); + len = XSTRLEN(dummy_dir[0]); + entry1->dir_name = (char*)XMALLOC(len + 1, NULL, DYNAMIC_TYPE_OPENSSL); + AssertNotNull(entry1->dir_name); + XMEMSET(entry1->dir_name, 0, len + 1); + XSTRNCPY(entry1->dir_name, dummy_dir[0], len + 1); + + AssertNotNull(entry2 = wolfSSL_BY_DIR_entry_new()); + len = XSTRLEN(dummy_dir[1]); + entry2->dir_name = (char*)XMALLOC(len + 1, NULL, DYNAMIC_TYPE_OPENSSL); + AssertNotNull(entry2->dir_name); + XMEMSET(entry2->dir_name, 0, len + 1); + XSTRNCPY(entry2->dir_name, dummy_dir[1], len + 1); + + AssertNotNull(entry_stack = wolfSSL_sk_BY_DIR_entry_new_null()); + + /* push */ + AssertIntEQ(wolfSSL_sk_BY_DIR_entry_push(NULL, NULL), + WOLFSSL_FAILURE); + AssertIntEQ(wolfSSL_sk_BY_DIR_entry_push(NULL, entry1), + WOLFSSL_FAILURE); + AssertIntEQ(wolfSSL_sk_BY_DIR_entry_push(entry_stack, NULL), + WOLFSSL_FAILURE); + + AssertIntEQ(wolfSSL_sk_BY_DIR_entry_push(entry_stack, entry1), + WOLFSSL_SUCCESS); + AssertIntEQ(wolfSSL_sk_BY_DIR_entry_push(entry_stack, + entry2), WOLFSSL_SUCCESS); + /* num and value */ + AssertIntEQ((num = wolfSSL_sk_BY_DIR_entry_num(entry_stack)), 2); + for (i = 0; i < num; i++) { + AssertNotNull(ent = wolfSSL_sk_BY_DIR_entry_value(entry_stack, i)); + len = XSTRLEN(dummy_dir[num - i - 1]); + AssertTrue(XSTRLEN(ent->dir_name) == len); + AssertIntEQ(XSTRNCMP(ent->dir_name, dummy_dir[num - i - 1], len), 0); + } + + /* pop */ + AssertNotNull(ent = wolfSSL_sk_BY_DIR_entry_pop(entry_stack)); + AssertIntEQ((len = wolfSSL_sk_BY_DIR_entry_num(entry_stack)), 1); + + /* free */ + wolfSSL_sk_BY_DIR_entry_free(entry_stack); + + printf(resultFmt, passed); +#endif +} + #ifndef NO_BIO static void test_wolfSSL_X509_INFO(void) { @@ -27967,7 +28098,286 @@ static int verify_cb(int ok, X509_STORE_CTX *ctx) } #endif +static void test_wolfSSL_X509_Name_canon(void) +{ +#if defined(OPENSSL_ALL) && !defined(NO_CERTS) && \ + !defined(NO_FILESYSTEM) && !defined(NO_SHA) && \ + defined(WOLFSSL_CERT_GEN) && \ + (defined(WOLFSSL_CERT_REQ) || defined(OLFSSL_CERT_EXT)) + + const long ex_hash1 = 0x0fdb2da4; + const long ex_hash2 = 0x9f3e8c9e; + X509_NAME *name = NULL; + X509 *x509 = NULL; + FILE* file = NULL; + unsigned long hash = 0; + byte digest[WC_MAX_DIGEST_SIZE] = {0}; + byte *pbuf = NULL; + word32 len = 0; + (void) ex_hash2; + printf(testingFmt, "test_wolfSSL_X509_Name_canon()"); + file = XFOPEN(caCertFile, "rb"); + AssertNotNull(file); + AssertNotNull(x509 = PEM_read_X509(file, NULL, NULL, NULL)); + AssertNotNull(name = X509_get_issuer_name(x509)); + + AssertIntGT((len = wolfSSL_i2d_X509_NAME_canon(name, &pbuf)), 0); + AssertIntEQ(wc_ShaHash((const byte*)pbuf, (word32)len, digest), 0); + + hash = (((unsigned long)digest[3] << 24) | + ((unsigned long)digest[2] << 16) | + ((unsigned long)digest[1] << 8) | + ((unsigned long)digest[0])); + AssertIntEQ(hash, ex_hash1); + + XFCLOSE(file); + X509_free(x509); + XFREE(pbuf, NULL, DYNAMIC_TYPE_OPENSSL); + pbuf = NULL; + + file = XFOPEN(cliCertFile, "rb"); + AssertNotNull(file); + AssertNotNull(x509 = PEM_read_X509(file, NULL, NULL, NULL)); + AssertNotNull(name = X509_get_issuer_name(x509)); + + AssertIntGT((len = wolfSSL_i2d_X509_NAME_canon(name, &pbuf)), 0); + AssertIntEQ(wc_ShaHash((const byte*)pbuf, (word32)len, digest), 0); + + hash = (((unsigned long)digest[3] << 24) | + ((unsigned long)digest[2] << 16) | + ((unsigned long)digest[1] << 8) | + ((unsigned long)digest[0])); + + AssertIntEQ(hash, ex_hash2); + + XFCLOSE(file); + X509_free(x509); + XFREE(pbuf, NULL, DYNAMIC_TYPE_OPENSSL); + + printf(resultFmt, passed); + +#endif + +} + +static void test_wolfSSL_X509_LOOKUP_ctrl_hash_dir(void) +{ +#if defined(OPENSSL_ALL) && !defined(NO_FILESYSTEM) && !defined(NO_WOLFSSL_DIR) + const int MAX_DIR = 4; + const char paths[][32] = { + "./certs/ed25519", + "./certs/ecc", + "./certs/crl", + "./certs/", + }; + + char CertCrl_path[MAX_FILENAME_SZ]; + char *p; + X509_STORE* str; + X509_LOOKUP* lookup; + WOLFSSL_BY_DIR_entry *dir; + WOLFSSL_STACK* sk = NULL; + int num = 0, len, total_len, i; + + (void) sk; + (void) num; + + printf(testingFmt, "test_wolfSSL_X509_LOOKUP_ctrl_hash_dir()"); + + XMEMSET(CertCrl_path, 0, MAX_FILENAME_SZ); + + /* illegal string */ + AssertNotNull((str = wolfSSL_X509_STORE_new())); + AssertNotNull(lookup = X509_STORE_add_lookup(str, X509_LOOKUP_file())); + AssertIntEQ(X509_LOOKUP_ctrl(lookup, X509_L_ADD_DIR, "", + SSL_FILETYPE_PEM,NULL), 0); + + /* free store */ + X509_STORE_free(str); + + /* short folder string */ + AssertNotNull((str = wolfSSL_X509_STORE_new())); + AssertNotNull(lookup = X509_STORE_add_lookup(str, X509_LOOKUP_file())); + AssertIntEQ(X509_LOOKUP_ctrl(lookup, X509_L_ADD_DIR, "./", + SSL_FILETYPE_PEM,NULL), 1); + AssertNotNull(sk = lookup->dirs->dir_entry); + AssertIntEQ((num = wolfSSL_sk_BY_DIR_entry_num(sk)), 1); + + dir = wolfSSL_sk_BY_DIR_entry_value(sk, 0); + printf("dir->dir_name %s\n", dir->dir_name); + AssertIntEQ(XSTRLEN((const char*)dir->dir_name), XSTRLEN("./")); + AssertIntEQ(XMEMCMP(dir->dir_name, "./", + XSTRLEN((const char*)dir->dir_name)), 0); + + /* free store */ + X509_STORE_free(str); + + /* typical function check */ + p = &CertCrl_path[0]; + total_len = 0; + + for(i = MAX_DIR - 1; i>=0 && total_len < MAX_FILENAME_SZ; i--) { + len = XSTRLEN((const char*)&paths[i]); + total_len += len; + XSTRNCPY(p, paths[i], MAX_FILENAME_SZ - total_len); + p += len; + if (i != 0) *(p++) = SEPARATOR_CHAR; + } + + AssertNotNull((str = wolfSSL_X509_STORE_new())); + AssertNotNull(lookup = X509_STORE_add_lookup(str, X509_LOOKUP_file())); + AssertIntEQ(X509_LOOKUP_ctrl(lookup, X509_L_ADD_DIR, CertCrl_path, + SSL_FILETYPE_PEM,NULL), 1); + AssertNotNull(sk = lookup->dirs->dir_entry); + AssertIntEQ((num = wolfSSL_sk_BY_DIR_entry_num(sk)), MAX_DIR); + + for(i = 0; idir_name), XSTRLEN(paths[i])); + AssertIntEQ(XMEMCMP(dir->dir_name, paths[i], + XSTRLEN((const char*)dir->dir_name)), 0); + } + + X509_STORE_free(str); + + printf(resultFmt, passed); +#endif + +} + +static void test_wolfSSL_X509_LOOKUP_ctrl_file(void) +{ +#if defined(OPENSSL_ALL) && !defined(NO_CERTS) && \ + !defined(NO_FILESYSTEM) && !defined(NO_RSA) && \ + defined(WOLFSSL_SIGNER_DER_CERT) + + X509_STORE_CTX* ctx; + X509_STORE* str; + X509_LOOKUP* lookup; + + X509* cert1; + X509* x509Ca; + X509* x509Svr; + X509* issuer; + + WOLFSSL_STACK* sk = NULL; + X509_NAME* caName; + X509_NAME* issuerName; + + FILE* file1 = NULL; + int i, cert_count, cmp; + + char der[] = "certs/ca-cert.der"; + +#ifdef HAVE_CRL + char pem[][100] = { + "./certs/crl/crl.pem", + "./certs/crl/crl2.pem", + "./certs/crl/caEccCrl.pem", + "./certs/crl/eccCliCRL.pem", + "./certs/crl/eccSrvCRL.pem", + "" + }; +#endif + printf(testingFmt, "test_wolfSSL_X509_LOOKUP_ctrl_file()"); + AssertNotNull(file1=fopen("./certs/ca-cert.pem", "rb")); + + AssertNotNull(cert1 = wolfSSL_PEM_read_X509(file1, NULL, NULL, NULL)); + fclose(file1); + + AssertNotNull(ctx = X509_STORE_CTX_new()); + AssertNotNull((str = wolfSSL_X509_STORE_new())); + AssertNotNull(lookup = X509_STORE_add_lookup(str, X509_LOOKUP_file())); + AssertIntEQ(X509_LOOKUP_ctrl(lookup, X509_L_FILE_LOAD, caCertFile, + SSL_FILETYPE_PEM,NULL), 1); + AssertNotNull(sk = wolfSSL_CertManagerGetCerts(str->cm)); + AssertIntEQ((cert_count = sk_X509_num(sk)), 1); + + /* check if CA cert is loaded into the store */ + for (i = 0; i < cert_count; i++) { + x509Ca = sk_X509_value(sk, i); + AssertIntEQ(0, wolfSSL_X509_cmp(x509Ca, cert1)); + } + + AssertNotNull((x509Svr = + wolfSSL_X509_load_certificate_file(svrCertFile, SSL_FILETYPE_PEM))); + + AssertIntEQ(X509_STORE_CTX_init(ctx, str, x509Svr, NULL), SSL_SUCCESS); + + AssertNull(X509_STORE_CTX_get0_current_issuer(NULL)); + issuer = X509_STORE_CTX_get0_current_issuer(ctx); + AssertNotNull(issuer); + + caName = X509_get_subject_name(x509Ca); + AssertNotNull(caName); + issuerName = X509_get_subject_name(issuer); + AssertNotNull(issuerName); + cmp = X509_NAME_cmp(caName, issuerName); + AssertIntEQ(cmp, 0); + + /* load der format */ + X509_STORE_free(str); + sk_X509_free(sk); + + AssertNotNull((str = wolfSSL_X509_STORE_new())); + AssertNotNull(lookup = X509_STORE_add_lookup(str, X509_LOOKUP_file())); + AssertIntEQ(X509_LOOKUP_ctrl(lookup, X509_L_FILE_LOAD, der, + SSL_FILETYPE_ASN1,NULL), 1); + AssertNotNull(sk = wolfSSL_CertManagerGetCerts(str->cm)); + AssertIntEQ((cert_count = sk_X509_num(sk)), 1); + + /* check if CA cert is loaded into the store */ + for (i = 0; i < cert_count; i++) { + x509Ca = sk_X509_value(sk, i); + AssertIntEQ(0, wolfSSL_X509_cmp(x509Ca, cert1)); + } + +#ifdef HAVE_CRL + /* once feeing store */ + wolfSSL_X509_STORE_free(str); + str = NULL; + + AssertNotNull(str = wolfSSL_X509_STORE_new()); + AssertNotNull(lookup = X509_STORE_add_lookup(str, X509_LOOKUP_file())); + AssertIntEQ(X509_LOOKUP_ctrl(lookup, X509_L_FILE_LOAD, caCertFile, + SSL_FILETYPE_PEM,NULL), 1); + AssertIntEQ(X509_LOOKUP_ctrl(lookup, X509_L_FILE_LOAD, + "certs/server-revoked-cert.pem", + SSL_FILETYPE_PEM,NULL), 1); + if (str) { + AssertIntEQ(wolfSSL_CertManagerVerify(str->cm, svrCertFile, + WOLFSSL_FILETYPE_PEM), 1); + /* since store hasn't yet known the revoked cert*/ + AssertIntEQ(wolfSSL_CertManagerVerify(str->cm, + "certs/server-revoked-cert.pem", + WOLFSSL_FILETYPE_PEM), 1); + } + for (i = 0; pem[i][0] != '\0'; i++) + { + AssertIntEQ(X509_LOOKUP_ctrl(lookup, X509_L_FILE_LOAD, pem[i], + SSL_FILETYPE_PEM, NULL), 1); + } + + if (str) { + /* since store knows crl list */ + AssertIntEQ(wolfSSL_CertManagerVerify(str->cm, + "certs/server-revoked-cert.pem", + WOLFSSL_FILETYPE_PEM ), CRL_CERT_REVOKED); + } + +#endif + X509_free(issuer); + X509_STORE_CTX_free(ctx); + X509_free(x509Svr); + X509_STORE_free(str); + sk_X509_free(sk); + X509_free(x509Ca); + X509_free(cert1); + + printf(resultFmt, passed); +#endif +} static void test_wolfSSL_X509_STORE_CTX_get0_current_issuer(void) { #if defined(OPENSSL_EXTRA) && !defined(NO_RSA) @@ -39608,7 +40018,7 @@ static void test_wolfSSL_X509_load_crl_file(void) WOLFSSL_X509_STORE* store; WOLFSSL_X509_LOOKUP* lookup; - printf(testingFmt, "wolfSSL_X509_laod_crl_file"); + printf(testingFmt, "wolfSSL_X509_load_crl_file"); AssertNotNull(store = wolfSSL_X509_STORE_new()); AssertNotNull(lookup = X509_STORE_add_lookup(store, X509_LOOKUP_file())); @@ -41649,6 +42059,8 @@ void ApiTest(void) #ifndef NO_BIO test_wolfSSL_X509_INFO(); #endif + test_wolfSSL_sk_X509_BY_DIR_HASH(); + test_wolfSSL_sk_X509_BY_DIR(); test_wolfSSL_X509_subject_name_hash(); test_wolfSSL_X509_issuer_name_hash(); test_wolfSSL_X509_check_host(); @@ -41698,6 +42110,9 @@ void ApiTest(void) test_generate_cookie(); test_wolfSSL_X509_STORE_set_flags(); test_wolfSSL_X509_LOOKUP_load_file(); + test_wolfSSL_X509_Name_canon(); + test_wolfSSL_X509_LOOKUP_ctrl_file(); + test_wolfSSL_X509_LOOKUP_ctrl_hash_dir(); test_wolfSSL_X509_NID(); test_wolfSSL_X509_STORE_CTX_set_time(); test_wolfSSL_get0_param(); diff --git a/wolfcrypt/src/asn.c b/wolfcrypt/src/asn.c index f70c69a86..dea8abaf8 100644 --- a/wolfcrypt/src/asn.c +++ b/wolfcrypt/src/asn.c @@ -13172,6 +13172,86 @@ int wc_EncodeName(EncodedName* name, const char* nameStr, char nameType, return idx; } +/* +* this wrappes wc_EncodeName for EMAIL OID + */ +int wc_EncodeName_cano(EncodedName* name, const char* nameStr, char nameType, + byte type) +{ + word32 idx = 0; + + if (nameStr) { + /* bottom up */ + byte firstLen[1 + MAX_LENGTH_SZ]; + byte secondLen[MAX_LENGTH_SZ]; + byte sequence[MAX_SEQ_SZ]; + byte set[MAX_SET_SZ]; + + int strLen = (int)XSTRLEN(nameStr); + int thisLen = strLen; + int firstSz, secondSz, seqSz, setSz; + + const byte EMAIL_OID[] = { 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, + 0x01, 0x09, 0x01, 0x0c }; + + if (type != ASN_EMAIL_NAME) { + return wc_EncodeName(name, nameStr, nameType, type); + } + + if (strLen == 0) { /* no user data for this item */ + name->used = 0; + return 0; + } + secondSz = SetLength(strLen, secondLen); + thisLen += secondSz; + thisLen += EMAIL_JOINT_LEN; + firstSz = EMAIL_JOINT_LEN; + thisLen++; /* id type */ + firstSz = SetObjectId(firstSz, firstLen); + thisLen += firstSz; + + seqSz = SetSequence(thisLen, sequence); + thisLen += seqSz; + setSz = SetSet(thisLen, set); + thisLen += setSz; + + if (thisLen > (int)sizeof(name->encoded)) { + return BUFFER_E; + } + + /* store it */ + idx = 0; + /* set */ + XMEMCPY(name->encoded, set, setSz); + idx += setSz; + /* seq */ + XMEMCPY(name->encoded + idx, sequence, seqSz); + idx += seqSz; + /* asn object id */ + XMEMCPY(name->encoded + idx, firstLen, firstSz); + idx += firstSz; + /* email joint id */ + XMEMCPY(name->encoded + idx, EMAIL_OID, sizeof(EMAIL_OID)); + idx += (int)sizeof(EMAIL_OID); + /* second length */ + XMEMCPY(name->encoded + idx, secondLen, secondSz); + idx += secondSz; + /* str value */ + XMEMCPY(name->encoded + idx, nameStr, strLen); + idx += strLen; + + name->type = type; + name->totalLen = idx; + name->used = 1; + } + else + name->used = 0; + + return idx; +} + + + /* encode CertName into output, return total bytes written */ int SetName(byte* output, word32 outputSz, CertName* name) { diff --git a/wolfcrypt/src/wc_port.c b/wolfcrypt/src/wc_port.c index 2e6dc17ac..aada029ae 100644 --- a/wolfcrypt/src/wc_port.c +++ b/wolfcrypt/src/wc_port.c @@ -415,6 +415,39 @@ int wc_FileLoad(const char* fname, unsigned char** buf, size_t* bufLen, #if !defined(NO_WOLFSSL_DIR) && \ !defined(WOLFSSL_NUCLEUS) && !defined(WOLFSSL_NUCLEUS_1_2) +/* File Handling Helper */ +/* returns 0 if file exists, WC_ISFILEEXIST_NOFILE if file doesn't exist */ +int wc_FileExists(const char* fname) +{ + struct ReadDirCtx ctx; + + if (fname == NULL) + return 0; + + if (XSTAT(fname, &ctx.s) != 0) { + WOLFSSL_MSG("stat on name failed"); + return BAD_PATH_ERROR; + }else +#if defined(USE_WINDOWS_API) + if (ctx.s.st_mode & _S_IFREG) { + return 0; + } +#elif defined(WOLFSSL_ZEPHYR) + if (ctx.s.type == FS_DIR_ENTRY_FILE) { + return 0; + } + +#elif defined(WOLFSSL_TELIT_M2MB) + if (ctx.s.st_mode & M2MB_S_IFREG) { + return 0; + } +#else + if (S_ISREG(ctx.s.st_mode)) { + return 0; + } +#endif + return WC_ISFILEEXIST_NOFILE; +} /* File Handling Helpers */ /* returns 0 if file found, WC_READDIR_NOFILE if no files or negative error */ @@ -485,11 +518,7 @@ int wc_ReadDirFirst(ReadDirCtx* ctx, const char* path, char** name) * of earlier check it is known that dnameLen is less than * MAX_FILENAME_SZ - (pathLen + 2) so dnameLen +1 will fit */ XSTRNCPY(ctx->name + pathLen + 1, ctx->entry.name, dnameLen + 1); - if (fs_stat(ctx->name, &ctx->s) != 0) { - WOLFSSL_MSG("stat on name failed"); - ret = BAD_PATH_ERROR; - break; - } else if (ctx->s.type == FS_DIR_ENTRY_FILE) { + if ((ret = wc_FileExists(ctx->name)) == 0) { if (name) *name = ctx->name; return 0; @@ -517,12 +546,7 @@ int wc_ReadDirFirst(ReadDirCtx* ctx, const char* path, char** name) * MAX_FILENAME_SZ - (pathLen + 2) so dnameLen +1 will fit */ XSTRNCPY(ctx->name + pathLen + 1, ctx->entry->d_name, dnameLen + 1); - if (m2mb_fs_stat(ctx->name, &ctx->s) != 0) { - WOLFSSL_MSG("stat on name failed"); - ret = BAD_PATH_ERROR; - break; - } - else if (ctx->s.st_mode & M2MB_S_IFREG) { + if ((ret = wc_FileExists(ctx->name)) == 0) { if (name) *name = ctx->name; return 0; @@ -549,11 +573,7 @@ int wc_ReadDirFirst(ReadDirCtx* ctx, const char* path, char** name) * of earlier check it is known that dnameLen is less than * MAX_FILENAME_SZ - (pathLen + 2) so dnameLen +1 will fit */ XSTRNCPY(ctx->name + pathLen + 1, ctx->entry->d_name, dnameLen + 1); - if (stat(ctx->name, &ctx->s) != 0) { - WOLFSSL_MSG("stat on name failed"); - ret = BAD_PATH_ERROR; - break; - } else if (S_ISREG(ctx->s.st_mode)) { + if ((ret = wc_FileExists(ctx->name)) == 0) { if (name) *name = ctx->name; return 0; @@ -615,11 +635,7 @@ int wc_ReadDirNext(ReadDirCtx* ctx, const char* path, char** name) * MAX_FILENAME_SZ - (pathLen + 2) so that dnameLen +1 will fit */ XSTRNCPY(ctx->name + pathLen + 1, ctx->entry.name, dnameLen + 1); - if (fs_stat(ctx->name, &ctx->s) != 0) { - WOLFSSL_MSG("stat on name failed"); - ret = BAD_PATH_ERROR; - break; - } else if (ctx->s.type == FS_DIR_ENTRY_FILE) { + if ((ret = wc_FileExists(ctx->name)) == 0) { if (name) *name = ctx->name; return 0; @@ -641,12 +657,7 @@ int wc_ReadDirNext(ReadDirCtx* ctx, const char* path, char** name) * MAX_FILENAME_SZ - (pathLen + 2) so dnameLen +1 will fit */ XSTRNCPY(ctx->name + pathLen + 1, ctx->entry->d_name, dnameLen + 1); - if (m2mb_fs_stat(ctx->name, &ctx->s) != 0) { - WOLFSSL_MSG("stat on name failed"); - ret = BAD_PATH_ERROR; - break; - } - else if (ctx->s.st_mode & M2MB_S_IFREG) { + if ((ret = wc_FileExists(ctx->name)) == 0) { if (name) *name = ctx->name; return 0; @@ -667,11 +678,7 @@ int wc_ReadDirNext(ReadDirCtx* ctx, const char* path, char** name) * MAX_FILENAME_SZ - (pathLen + 2) so that dnameLen +1 will fit */ XSTRNCPY(ctx->name + pathLen + 1, ctx->entry->d_name, dnameLen + 1); - if (stat(ctx->name, &ctx->s) != 0) { - WOLFSSL_MSG("stat on name failed"); - ret = BAD_PATH_ERROR; - break; - } else if (S_ISREG(ctx->s.st_mode)) { + if ((ret = wc_FileExists(ctx->name)) == 0) { if (name) *name = ctx->name; return 0; diff --git a/wolfssl/internal.h b/wolfssl/internal.h index 9246f66e9..2b5a492b3 100644 --- a/wolfssl/internal.h +++ b/wolfssl/internal.h @@ -2066,6 +2066,9 @@ struct WOLFSSL_CERT_MANAGER { #endif #if defined(HAVE_ECC) || defined(HAVE_ED25519) || defined(HAVE_ED448) short minEccKeySz; /* minimum allowed ECC key size */ +#endif +#if defined(OPENSSL_EXTRA) + WOLFSSL_X509_STORE *x509_store_p; /* pointer back to x509 store */ #endif wolfSSL_Mutex refMutex; /* reference count mutex */ int refCount; /* reference count */ @@ -3691,6 +3694,8 @@ typedef struct Arrays { #define STACK_TYPE_X509_NAME 9 #define STACK_TYPE_CONF_VALUE 10 #define STACK_TYPE_X509_INFO 11 +#define STACK_TYPE_BY_DIR_entry 12 +#define STACK_TYPE_BY_DIR_hash 13 struct WOLFSSL_STACK { unsigned long num; /* number of nodes in stack @@ -3716,6 +3721,8 @@ struct WOLFSSL_STACK { void* generic; char* string; WOLFSSL_GENERAL_NAME* gn; + WOLFSSL_BY_DIR_entry* dir_entry; + WOLFSSL_BY_DIR_HASH* dir_hash; } data; void* heap; /* memory heap hint */ WOLFSSL_STACK* next; @@ -4811,6 +4818,12 @@ WOLFSSL_LOCAL void FreeKey(WOLFSSL* ssl, int type, void** pKey); WOLFSSL_LOCAL int wolfSSL_AsyncPush(WOLFSSL* ssl, WC_ASYNC_DEV* asyncDev); #endif +#if defined(OPENSSL_ALL) && defined(WOLFSSL_CERT_GEN) && \ + (defined(WOLFSSL_CERT_REQ) || defined(OLFSSL_CERT_EXT)) && \ + !defined(NO_FILESYSTEM) && !defined(NO_WOLFSSL_DIR) +WOLFSSL_LOCAL int LoadCrlCertByIssuer(WOLFSSL_X509_STORE* store, + X509_NAME* issuer, int Type); +#endif #ifdef __cplusplus } /* extern "C" */ diff --git a/wolfssl/ssl.h b/wolfssl/ssl.h index 1e593213e..22ea2f5a4 100644 --- a/wolfssl/ssl.h +++ b/wolfssl/ssl.h @@ -192,6 +192,9 @@ typedef struct WOLFSSL_ASN1_OBJECT WOLFSSL_ASN1_OBJECT; typedef struct WOLFSSL_ASN1_OTHERNAME WOLFSSL_ASN1_OTHERNAME; typedef struct WOLFSSL_X509V3_CTX WOLFSSL_X509V3_CTX; typedef struct WOLFSSL_v3_ext_method WOLFSSL_v3_ext_method; +typedef struct WOLFSSL_BY_DIR WOLFSSL_BY_DIR; +typedef struct WOLFSSL_BY_DIR_entry WOLFSSL_BY_DIR_entry; +typedef struct WOLFSSL_BY_DIR_HASH WOLFSSL_BY_DIR_HASH; typedef struct WOLFSSL_ASN1_STRING WOLFSSL_ASN1_STRING; typedef struct WOLFSSL_dynlock_value WOLFSSL_dynlock_value; @@ -276,7 +279,21 @@ struct WOLFSSL_X509V3_CTX { WOLFSSL_X509* x509; }; +struct WOLFSSL_BY_DIR_HASH { + unsigned long hash_value; + int last_suffix; +}; +struct WOLFSSL_BY_DIR_entry { + char* dir_name; + int dir_type; + WOLF_STACK_OF(WOLFSSL_BY_DIR_HASH) *hashes; +}; + +struct WOLFSSL_BY_DIR { + WOLF_STACK_OF(WOLFSSL_BY_DIR_entry) *dir_entry; + wolfSSL_Mutex lock; /* dir list lock */ +}; struct WOLFSSL_ASN1_OBJECT { void* heap; @@ -531,6 +548,8 @@ struct WOLFSSL_X509_LOOKUP_METHOD { struct WOLFSSL_X509_LOOKUP { WOLFSSL_X509_STORE *store; + int type; + WOLFSSL_BY_DIR* dirs; }; struct WOLFSSL_X509_STORE { @@ -1421,6 +1440,8 @@ WOLFSSL_API void wolfSSL_X509_STORE_set_verify_cb(WOLFSSL_X509_STORE *st, WOLFSSL_X509_STORE_CTX_verify_cb verify_cb); WOLFSSL_API int wolfSSL_i2d_X509_NAME(WOLFSSL_X509_NAME* n, unsigned char** out); +WOLFSSL_API int wolfSSL_i2d_X509_NAME_canon(WOLFSSL_X509_NAME* name, + unsigned char** out); WOLFSSL_API WOLFSSL_X509_NAME *wolfSSL_d2i_X509_NAME(WOLFSSL_X509_NAME **name, unsigned char **in, long length); #ifndef NO_RSA @@ -1499,6 +1520,8 @@ WOLFSSL_API int wolfSSL_ASN1_STRING_set(WOLFSSL_ASN1_STRING* asn1, const void* data, int dataSz); WOLFSSL_API unsigned char* wolfSSL_ASN1_STRING_data(WOLFSSL_ASN1_STRING*); WOLFSSL_API int wolfSSL_ASN1_STRING_length(WOLFSSL_ASN1_STRING*); +WOLFSSL_API int wolfSSL_ASN1_STRING_copy(WOLFSSL_ASN1_STRING* dst, + const WOLFSSL_ASN1_STRING* src); WOLFSSL_API int wolfSSL_X509_verify_cert(WOLFSSL_X509_STORE_CTX*); WOLFSSL_API const char* wolfSSL_X509_verify_cert_error_string(long); WOLFSSL_API int wolfSSL_X509_get_signature_type(WOLFSSL_X509*); @@ -3828,6 +3851,38 @@ WOLFSSL_API int wolfSSL_sk_CONF_VALUE_push(WOLF_STACK_OF(WOLFSSL_CONF_VALUE)* sk WOLFSSL_CONF_VALUE* val); #endif /* OPENSSL_ALL || HAVE_STUNNEL || WOLFSSL_NGINX || WOLFSSL_HAPROXY || OPENSSL_EXTRA || HAVE_LIGHTY */ +#if defined(OPENSSL_ALL) && !defined(NO_FILESYSTEM) && !defined(NO_WOLFSSL_DIR) +WOLFSSL_API WOLFSSL_BY_DIR_HASH* wolfSSL_BY_DIR_HASH_new(void); +WOLFSSL_API void wolfSSL_BY_DIR_HASH_free(WOLFSSL_BY_DIR_HASH* dir_hash); +WOLFSSL_API WOLFSSL_STACK* wolfSSL_sk_BY_DIR_HASH_new_null(void); +WOLFSSL_API int wolfSSL_sk_BY_DIR_HASH_find( + WOLF_STACK_OF(WOLFSSL_BY_DIR_HASH)* sk, const WOLFSSL_BY_DIR_HASH* toFind); +WOLFSSL_API int wolfSSL_sk_BY_DIR_HASH_num(const WOLF_STACK_OF(WOLFSSL_BY_DIR_HASH) *sk); +WOLFSSL_API WOLFSSL_BY_DIR_HASH* wolfSSL_sk_BY_DIR_HASH_value( + const WOLF_STACK_OF(WOLFSSL_BY_DIR_HASH) *sk, int i); +WOLFSSL_API WOLFSSL_BY_DIR_HASH* wolfSSL_sk_BY_DIR_HASH_pop( + WOLF_STACK_OF(WOLFSSL_BY_DIR_HASH)* sk); +WOLFSSL_API void wolfSSL_sk_BY_DIR_HASH_pop_free(WOLF_STACK_OF(WOLFSSL_BY_DIR_HASH)* sk, + void (*f) (WOLFSSL_BY_DIR_HASH*)); +WOLFSSL_API void wolfSSL_sk_BY_DIR_HASH_free(WOLF_STACK_OF(WOLFSSL_BY_DIR_HASH) *sk); +WOLFSSL_API int wolfSSL_sk_BY_DIR_HASH_push(WOLF_STACK_OF(WOLFSSL_BY_DIR_HASH)* sk, + WOLFSSL_BY_DIR_HASH* in); +/* WOLFSSL_BY_DIR_entry stuff */ +WOLFSSL_API WOLFSSL_BY_DIR_entry* wolfSSL_BY_DIR_entry_new(void); +WOLFSSL_API void wolfSSL_BY_DIR_entry_free(WOLFSSL_BY_DIR_entry* entry); +WOLFSSL_API WOLFSSL_STACK* wolfSSL_sk_BY_DIR_entry_new_null(void); +WOLFSSL_API int wolfSSL_sk_BY_DIR_entry_num(const WOLF_STACK_OF(WOLFSSL_BY_DIR_entry) *sk); +WOLFSSL_API WOLFSSL_BY_DIR_entry* wolfSSL_sk_BY_DIR_entry_value( + const WOLF_STACK_OF(WOLFSSL_BY_DIR_entry) *sk, int i); +WOLFSSL_API WOLFSSL_BY_DIR_entry* wolfSSL_sk_BY_DIR_entry_pop( + WOLF_STACK_OF(WOLFSSL_BY_DIR_entry)* sk); +WOLFSSL_API void wolfSSL_sk_BY_DIR_entry_pop_free(WOLF_STACK_OF(wolfSSL_BY_DIR_entry)* sk, + void (*f) (WOLFSSL_BY_DIR_entry*)); +WOLFSSL_API void wolfSSL_sk_BY_DIR_entry_free(WOLF_STACK_OF(wolfSSL_BY_DIR_entry) *sk); +WOLFSSL_API int wolfSSL_sk_BY_DIR_entry_push(WOLF_STACK_OF(wolfSSL_BY_DIR_entry)* sk, + WOLFSSL_BY_DIR_entry* in); +#endif /* OPENSSL_ALL && !NO_FILESYSTEM && !NO_WOLFSSL_DIR */ + #if defined(OPENSSL_EXTRA) || defined(WOLFSSL_WPAS_SMALL) WOLFSSL_API WOLFSSL_ASN1_BIT_STRING* wolfSSL_ASN1_BIT_STRING_new(void); WOLFSSL_API void wolfSSL_ASN1_BIT_STRING_free(WOLFSSL_ASN1_BIT_STRING*); diff --git a/wolfssl/test.h b/wolfssl/test.h index 50a5c96a2..16fe232ce 100644 --- a/wolfssl/test.h +++ b/wolfssl/test.h @@ -349,6 +349,7 @@ #define cliEd448CertFile "certs/ed448/client-ed448.pem" #define cliEd448KeyFile "certs/ed448/client-ed448-priv.pem" #define caEd448CertFile "certs/ed448/ca-ed448.pem" +#define caCertFolder "certs/" #ifdef HAVE_WNR /* Whitewood netRandom default config file */ #define wnrConfig "wnr-example.conf" @@ -382,6 +383,7 @@ #define cliEd448CertFile "./certs/ed448/client-ed448.pem" #define cliEd448KeyFile "./certs/ed448/client-ed448-priv.pem" #define caEd448CertFile "./certs/ed448/ca-ed448.pem" +#define caCertFolder "./certs/" #ifdef HAVE_WNR /* Whitewood netRandom default config file */ #define wnrConfig "./wnr-example.conf" diff --git a/wolfssl/wolfcrypt/asn.h b/wolfssl/wolfcrypt/asn.h index ddac56b34..1ad8176b2 100644 --- a/wolfssl/wolfcrypt/asn.h +++ b/wolfssl/wolfcrypt/asn.h @@ -1173,6 +1173,8 @@ WOLFSSL_LOCAL int wc_OBJ_sn2nid(const char *sn); WOLFSSL_LOCAL int wc_EncodeName(EncodedName* name, const char* nameStr, char nameType, byte type); +WOLFSSL_LOCAL int wc_EncodeName_cano(EncodedName* name, const char* nameStr, + char nameType, byte type); /* ASN.1 helper functions */ #ifdef WOLFSSL_CERT_GEN WOLFSSL_ASN_API int SetName(byte* output, word32 outputSz, CertName* name); diff --git a/wolfssl/wolfcrypt/types.h b/wolfssl/wolfcrypt/types.h index e1d4aa2da..494d20df2 100644 --- a/wolfssl/wolfcrypt/types.h +++ b/wolfssl/wolfcrypt/types.h @@ -659,6 +659,8 @@ decouple library dependencies with standard string, memory and so on. #endif #ifdef OPENSSL_ALL #define XISALNUM(c) isalnum((c)) + #define XISASCII(c) isascii((c)) + #define XISSPACE(c) isspace((c)) #endif /* needed by wolfSSL_check_domain_name() */ #define XTOLOWER(c) tolower((c)) diff --git a/wolfssl/wolfcrypt/wc_port.h b/wolfssl/wolfcrypt/wc_port.h index 8a41f4b99..36c858f53 100644 --- a/wolfssl/wolfcrypt/wc_port.h +++ b/wolfssl/wolfcrypt/wc_port.h @@ -676,14 +676,25 @@ WOLFSSL_API int wolfCrypt_Cleanup(void); #define XFGETS fgets #define XFPRINTF fprintf - #if !defined(USE_WINDOWS_API) && !defined(NO_WOLFSSL_DIR)\ + #if !defined(NO_WOLFSSL_DIR)\ && !defined(WOLFSSL_NUCLEUS) && !defined(WOLFSSL_NUCLEUS_1_2) + #if defined(USE_WINDOWS_API) + #define XSTAT _stat + #define SEPARATOR_CHAR ';' + #elif defined(WOLFSSL_ZEPHYR) + #define XSTAT fs_stat + #elif defined(WOLFSSL_TELIT_M2MB) + #define XSTAT m2mb_fs_stat + #else #include #include #include #define XWRITE write #define XREAD read #define XCLOSE close + #define XSTAT stat + #define SEPARATOR_CHAR ':' + #endif #endif #endif @@ -732,7 +743,7 @@ WOLFSSL_API int wolfCrypt_Cleanup(void); #else struct dirent* entry; DIR* dir; - struct stat s; + struct XSTAT s; #endif char name[MAX_FILENAME_SZ]; } ReadDirCtx; @@ -743,6 +754,9 @@ WOLFSSL_API int wolfCrypt_Cleanup(void); WOLFSSL_API int wc_ReadDirNext(ReadDirCtx* ctx, const char* path, char** name); WOLFSSL_API void wc_ReadDirClose(ReadDirCtx* ctx); #endif /* !NO_WOLFSSL_DIR */ + #define WC_ISFILEEXIST_NOFILE -1 + + WOLFSSL_API int wc_FileExists(const char* fname); #endif /* !NO_FILESYSTEM */ From 39b0c4eaf8f966ad3f290b41635fe3a4dfc04d1b Mon Sep 17 00:00:00 2001 From: Hideki Miyazaki Date: Fri, 5 Mar 2021 15:14:56 +0900 Subject: [PATCH 03/16] fixed sanitize errors --- src/internal.c | 98 ++++++++++++++++++++++++++------------------- src/ssl.c | 14 +++++-- tests/api.c | 30 +++++++------- wolfcrypt/src/asn.c | 2 - 4 files changed, 80 insertions(+), 64 deletions(-) diff --git a/src/internal.c b/src/internal.c index d8c45cbf7..feab76786 100644 --- a/src/internal.c +++ b/src/internal.c @@ -1981,7 +1981,7 @@ void SSL_CtxResourceFree(WOLFSSL_CTX* ctx) if (ctx->x509_store.lookup.dirs) { #if defined(OPENSSL_ALL) && !defined(NO_FILESYSTEM) && !defined(NO_WOLFSSL_DIR) - if (!ctx->x509_store.lookup.dirs->dir_entry) { + if (ctx->x509_store.lookup.dirs->dir_entry) { wolfSSL_sk_BY_DIR_entry_free(ctx->x509_store.lookup.dirs->dir_entry); } #endif @@ -10619,6 +10619,7 @@ int LoadCrlCertByIssuer(WOLFSSL_X509_STORE* store, X509_NAME* issuer, int type) WOLFSSL_MSG("failed hash operation"); return WOLFSSL_FAILURE; } + wolfSSL_OPENSSL_free(pbuf); } /* try to load each hashed name file in path */ @@ -10633,8 +10634,9 @@ int LoadCrlCertByIssuer(WOLFSSL_X509_STORE* store, X509_NAME* issuer, int type) for (i=0; idirs->dir_entry, i); - - len = XSTRLEN(entry->dir_name) + 13; + /*/.(r)N\0 */ + /*112345678 1 1 1 1 => 13 */ + len = (int)XSTRLEN(entry->dir_name) + 13; if (filename != NULL) { XFREE(filename, NULL, DYNAMIC_TYPE_OPENSSL); @@ -10678,6 +10680,7 @@ int LoadCrlCertByIssuer(WOLFSSL_X509_STORE* store, X509_NAME* issuer, int type) WOLFSSL_FILETYPE_PEM); if (x509 != NULL) { ret = wolfSSL_X509_STORE_add_cert(store, x509); + wolfSSL_X509_free(x509); } else { WOLFSSL_MSG("failed to load certificate\n"); ret = WOLFSSL_FAILURE; @@ -10839,45 +10842,6 @@ static int ProcessPeerCertParse(WOLFSSL* ssl, ProcPeerCertArgs* args, /* Parse Certificate */ ret = ParseCertRelative(args->dCert, certType, verify, ssl->ctx->cm); -#if defined(OPENSSL_ALL) && defined(WOLFSSL_CERT_GEN) && \ - (defined(WOLFSSL_CERT_REQ) || defined(OLFSSL_CERT_EXT)) && \ - !defined(NO_FILESYSTEM) && !defined(NO_WOLFSSL_DIR) - if (ret == ASN_NO_SIGNER_E) { - WOLFSSL_MSG("try to load certificate if hash dir is set"); - if (ssl->ctx->x509_store_pt != NULL) { - ret = LoadCrlCertByIssuer(ssl->ctx->x509_store_pt, - (WOLFSSL_X509_NAME*)args->dCert->issuerName, - X509_LU_X509); - } else { - ret = LoadCrlCertByIssuer(&ssl->ctx->x509_store, - (WOLFSSL_X509_NAME*)args->dCert->issuerName, - X509_LU_X509); - } - - if (ret == WOLFSSL_SUCCESS) { - /* re try Parse Certificate */ - InitDecodedCert(args->dCert, cert->buffer, cert->length, ssl->heap); - args->dCertInit = 1; - args->dCert->sigCtx.devId = ssl->devId; - #ifdef WOLFSSL_ASYNC_CRYPT - args->dCert->sigCtx.asyncCtx = ssl; - #endif - #ifdef HAVE_PK_CALLBACKS - /* setup the PK callback context */ - ret = InitSigPkCb(ssl, &args->dCert->sigCtx); - if (ret != 0) - return ret; - #endif - ret = ParseCertRelative(args->dCert, certType, verify, - ssl->ctx->cm); - } else { - WOLFSSL_MSG("failed to load certificate from hash folder"); - /* restore return code */ - ret = ASN_NO_SIGNER_E; - } - } -#endif - /* perform below checks for date failure cases */ if (ret == 0 || ret == ASN_BEFORE_DATE_E || ret == ASN_AFTER_DATE_E) { /* get subject and determine if already loaded */ @@ -11309,6 +11273,31 @@ int ProcessPeerCerts(WOLFSSL* ssl, byte* input, word32* inOutIdx, ret = ProcessPeerCertParse(ssl, args, CERT_TYPE, !ssl->options.verifyNone ? VERIFY : NO_VERIFY, &subjectHash, &alreadySigner); +#if defined(OPENSSL_ALL) && defined(WOLFSSL_CERT_GEN) && \ + (defined(WOLFSSL_CERT_REQ) || defined(OLFSSL_CERT_EXT)) && \ + !defined(NO_FILESYSTEM) && !defined(NO_WOLFSSL_DIR) + if (ret == ASN_NO_SIGNER_E) { + WOLFSSL_MSG("try to load certificate if hash dir is set"); + if (ssl->ctx->x509_store_pt != NULL) { + ret = LoadCrlCertByIssuer(ssl->ctx->x509_store_pt, + (WOLFSSL_X509_NAME*)args->dCert->issuerName, + X509_LU_X509); + } else { + ret = LoadCrlCertByIssuer(&ssl->ctx->x509_store, + (WOLFSSL_X509_NAME*)args->dCert->issuerName, + X509_LU_X509); + } + if (ret == WOLFSSL_SUCCESS) { + FreeDecodedCert(args->dCert); + args->dCertInit = 0; + /* once again */ + ret = ProcessPeerCertParse(ssl, args, CERT_TYPE, + !ssl->options.verifyNone ? VERIFY : NO_VERIFY, + &subjectHash, &alreadySigner); + } else + ret = ASN_NO_SIGNER_E; + } +#endif #ifdef WOLFSSL_ASYNC_CRYPT if (ret == WC_PENDING_E) goto exit_ppc; @@ -11502,6 +11491,31 @@ int ProcessPeerCerts(WOLFSSL* ssl, byte* input, word32* inOutIdx, ret = ProcessPeerCertParse(ssl, args, CERT_TYPE, !ssl->options.verifyNone ? VERIFY : NO_VERIFY, &subjectHash, &alreadySigner); +#if defined(OPENSSL_ALL) && defined(WOLFSSL_CERT_GEN) && \ + (defined(WOLFSSL_CERT_REQ) || defined(OLFSSL_CERT_EXT)) && \ + !defined(NO_FILESYSTEM) && !defined(NO_WOLFSSL_DIR) + if (ret == ASN_NO_SIGNER_E) { + WOLFSSL_MSG("try to load certificate if hash dir is set"); + if (ssl->ctx->x509_store_pt != NULL) { + ret = LoadCrlCertByIssuer(ssl->ctx->x509_store_pt, + (WOLFSSL_X509_NAME*)args->dCert->issuerName, + X509_LU_X509); + } else { + ret = LoadCrlCertByIssuer(&ssl->ctx->x509_store, + (WOLFSSL_X509_NAME*)args->dCert->issuerName, + X509_LU_X509); + } + if (ret == WOLFSSL_SUCCESS) { + FreeDecodedCert(args->dCert); + args->dCertInit = 0; + /* once again */ + ret = ProcessPeerCertParse(ssl, args, CERT_TYPE, + !ssl->options.verifyNone ? VERIFY : NO_VERIFY, + &subjectHash, &alreadySigner); + } else + ret = ASN_NO_SIGNER_E; + } +#endif #ifdef WOLFSSL_ASYNC_CRYPT if (ret == WC_PENDING_E) goto exit_ppc; diff --git a/src/ssl.c b/src/ssl.c index 11f47938e..9d86f16ba 100644 --- a/src/ssl.c +++ b/src/ssl.c @@ -24894,7 +24894,7 @@ static int x509AddCertDir(void *p, const char *argc, long argl) WOLFSSL_MSG("failed to allocate dir entry"); return 0; } - entry->dir_type = argl; + entry->dir_type = (int)argl; entry->dir_name = (char*)XMALLOC(pathLen + 1/* \0 termination*/ , NULL, DYNAMIC_TYPE_OPENSSL); entry->hashes = wolfSSL_sk_BY_DIR_HASH_new_null(); @@ -24953,7 +24953,7 @@ int wolfSSL_X509_LOOKUP_ctrl(WOLFSSL_X509_LOOKUP *ctx, int cmd, switch (cmd) { case WOLFSSL_X509_L_FILE_LOAD: /* expects to return a number of processed cert or crl file */ - lret = wolfSSL_X509_load_cert_crl_file(ctx, argc, argl) > 0 ? + lret = wolfSSL_X509_load_cert_crl_file(ctx, argc, (int)argl) > 0 ? WOLFSSL_SUCCESS : WOLFSSL_FAILURE; break; case WOLFSSL_X509_L_ADD_DIR: @@ -25885,7 +25885,7 @@ void wolfSSL_X509_STORE_free(WOLFSSL_X509_STORE* store) if (store->lookup.dirs != NULL) { #if defined(OPENSSL_ALL) && !defined(NO_FILESYSTEM) && !defined(NO_WOLFSSL_DIR) - if (!store->lookup.dirs->dir_entry) { + if (store->lookup.dirs->dir_entry) { wolfSSL_sk_BY_DIR_entry_free(store->lookup.dirs->dir_entry); } #endif @@ -26329,6 +26329,8 @@ WOLFSSL_API int wolfSSL_X509_load_cert_crl_file(WOLFSSL_X509_LOOKUP *ctx, } else { WOLFSSL_MSG("wolfSSL_X509_STORE_add_cert error"); } + wolfSSL_X509_free(x509); + x509 = NULL; } else { WOLFSSL_MSG("wolfSSL_X509_load_certificate_file error"); } @@ -41609,7 +41611,7 @@ static int wolfSSL_ASN1_STRING_canon(WOLFSSL_ASN1_STRING* asn_out, } } /* put actual length */ - asn_out->length = dst - asn_out->data; + asn_out->length = (int)(dst - asn_out->data); return WOLFSSL_SUCCESS; } /* this is to converts the x509 name structure into canonical DER format @@ -41680,6 +41682,8 @@ int wolfSSL_i2d_X509_NAME_canon(WOLFSSL_X509_NAME* name, unsigned char** out) return WOLFSSL_FATAL_ERROR; } totalBytes += ret; + wolfSSL_OPENSSL_free(cano_data->data); + wolfSSL_ASN1_STRING_free(cano_data); } } @@ -42820,6 +42824,8 @@ err: } XFREE(pem, 0, DYNAMIC_TYPE_PEM); + if (der) + FreeDer(&der); return WOLFSSL_SUCCESS; err: if (pem) diff --git a/tests/api.c b/tests/api.c index c0ee92ddb..823c4033b 100644 --- a/tests/api.c +++ b/tests/api.c @@ -25855,6 +25855,7 @@ static void test_wolfSSL_sk_X509_BY_DIR(void) /* pop */ AssertNotNull(ent = wolfSSL_sk_BY_DIR_entry_pop(entry_stack)); AssertIntEQ((len = wolfSSL_sk_BY_DIR_entry_num(entry_stack)), 1); + wolfSSL_BY_DIR_entry_free(ent); /* free */ wolfSSL_sk_BY_DIR_entry_free(entry_stack); @@ -28205,7 +28206,6 @@ static void test_wolfSSL_X509_LOOKUP_ctrl_hash_dir(void) AssertIntEQ((num = wolfSSL_sk_BY_DIR_entry_num(sk)), 1); dir = wolfSSL_sk_BY_DIR_entry_value(sk, 0); - printf("dir->dir_name %s\n", dir->dir_name); AssertIntEQ(XSTRLEN((const char*)dir->dir_name), XSTRLEN("./")); AssertIntEQ(XMEMCMP(dir->dir_name, "./", XSTRLEN((const char*)dir->dir_name)), 0); @@ -28218,7 +28218,7 @@ static void test_wolfSSL_X509_LOOKUP_ctrl_hash_dir(void) total_len = 0; for(i = MAX_DIR - 1; i>=0 && total_len < MAX_FILENAME_SZ; i--) { - len = XSTRLEN((const char*)&paths[i]); + len = (int)XSTRLEN((const char*)&paths[i]); total_len += len; XSTRNCPY(p, paths[i], MAX_FILENAME_SZ - total_len); p += len; @@ -28315,10 +28315,13 @@ static void test_wolfSSL_X509_LOOKUP_ctrl_file(void) AssertNotNull(issuerName); cmp = X509_NAME_cmp(caName, issuerName); AssertIntEQ(cmp, 0); - + /* load der format */ + X509_free(issuer); + X509_STORE_CTX_free(ctx); X509_STORE_free(str); sk_X509_free(sk); + X509_free(x509Svr); AssertNotNull((str = wolfSSL_X509_STORE_new())); AssertNotNull(lookup = X509_STORE_add_lookup(str, X509_LOOKUP_file())); @@ -28326,18 +28329,17 @@ static void test_wolfSSL_X509_LOOKUP_ctrl_file(void) SSL_FILETYPE_ASN1,NULL), 1); AssertNotNull(sk = wolfSSL_CertManagerGetCerts(str->cm)); AssertIntEQ((cert_count = sk_X509_num(sk)), 1); - /* check if CA cert is loaded into the store */ for (i = 0; i < cert_count; i++) { x509Ca = sk_X509_value(sk, i); AssertIntEQ(0, wolfSSL_X509_cmp(x509Ca, cert1)); } + X509_STORE_free(str); + sk_X509_free(sk); + X509_free(cert1); + #ifdef HAVE_CRL - /* once feeing store */ - wolfSSL_X509_STORE_free(str); - str = NULL; - AssertNotNull(str = wolfSSL_X509_STORE_new()); AssertNotNull(lookup = X509_STORE_add_lookup(str, X509_LOOKUP_file())); AssertIntEQ(X509_LOOKUP_ctrl(lookup, X509_L_FILE_LOAD, caCertFile, @@ -28365,15 +28367,11 @@ static void test_wolfSSL_X509_LOOKUP_ctrl_file(void) "certs/server-revoked-cert.pem", WOLFSSL_FILETYPE_PEM ), CRL_CERT_REVOKED); } - -#endif - X509_free(issuer); - X509_STORE_CTX_free(ctx); - X509_free(x509Svr); + X509_STORE_free(str); - sk_X509_free(sk); - X509_free(x509Ca); - X509_free(cert1); + +#endif + printf(resultFmt, passed); #endif diff --git a/wolfcrypt/src/asn.c b/wolfcrypt/src/asn.c index dea8abaf8..dabc1e20a 100644 --- a/wolfcrypt/src/asn.c +++ b/wolfcrypt/src/asn.c @@ -9791,7 +9791,6 @@ int ParseCertRelative(DecodedCert* cert, int type, int verify, void* cm) } } #endif - if (cert->srcIdx < cert->sigIndex) { #ifndef ALLOW_V1_EXTENSIONS if (cert->version < 2) { @@ -9820,7 +9819,6 @@ int ParseCertRelative(DecodedCert* cert, int type, int verify, void* cm) /* advance past extensions */ cert->srcIdx = cert->sigIndex; } - if ((ret = GetAlgoId(cert->source, &cert->srcIdx, #ifdef WOLFSSL_CERT_REQ !cert->isCSR ? &confirmOID : &cert->signatureOID, From e73b06e797113c052e45bf07ad6e8159c131f769 Mon Sep 17 00:00:00 2001 From: Hideki Miyazaki Date: Sat, 6 Mar 2021 19:28:25 +0900 Subject: [PATCH 04/16] add comments and description to new function and API --- src/internal.c | 10 +++++++--- src/ssl.c | 43 +++++++++++++++++++++---------------------- wolfcrypt/src/asn.c | 7 +++---- 3 files changed, 31 insertions(+), 29 deletions(-) diff --git a/src/internal.c b/src/internal.c index feab76786..e131fe3a1 100644 --- a/src/internal.c +++ b/src/internal.c @@ -10576,8 +10576,12 @@ static void FreeProcPeerCertArgs(WOLFSSL* ssl, void* pArgs) #if defined(OPENSSL_ALL) && defined(WOLFSSL_CERT_GEN) && \ (defined(WOLFSSL_CERT_REQ) || defined(OLFSSL_CERT_EXT)) && \ !defined(NO_FILESYSTEM) && !defined(NO_WOLFSSL_DIR) -/* load certificate file which has .(r)N[0..N] in the folder */ +/* load certificate file which has the form .(r)N[0..N] */ +/* in the folder. */ /* (r), in the case of CRL file */ +/* @param store a pointer to X509_STORE structure */ +/* @param issuer a pointer to X509_NAME that presents issuer */ +/* @param type X509_LU_X509 or X509_LU_CRL */ int LoadCrlCertByIssuer(WOLFSSL_X509_STORE* store, X509_NAME* issuer, int type) { const int MAX_SUFFIX = 10; @@ -10599,8 +10603,8 @@ int LoadCrlCertByIssuer(WOLFSSL_X509_STORE* store, X509_NAME* issuer, int type) WOLFSSL_ENTER("LoadCrlCertByIssuer"); /* sanity check */ - if (store == NULL || lookup->dirs == NULL || lookup->type != 1 - || (type != X509_LU_X509 && type != X509_LU_CRL)) { + if (store == NULL || issuer == NULL || lookup->dirs == NULL || + lookup->type != 1 || (type != X509_LU_X509 && type != X509_LU_CRL)) { return WOLFSSL_FAILURE; } diff --git a/src/ssl.c b/src/ssl.c index 9d86f16ba..c1d0811b3 100644 --- a/src/ssl.c +++ b/src/ssl.c @@ -26492,9 +26492,6 @@ WOLFSSL_API int wolfSSL_X509_load_crl_file(WOLFSSL_X509_LOOKUP *ctx, WOLFSSL_LEAVE("wolfSSL_X509_load_crl_file", ret); return ret; } - - - #endif /* !NO_FILESYSTEM */ @@ -41614,12 +41611,16 @@ static int wolfSSL_ASN1_STRING_canon(WOLFSSL_ASN1_STRING* asn_out, asn_out->length = (int)(dst - asn_out->data); return WOLFSSL_SUCCESS; } + /* this is to converts the x509 name structure into canonical DER format * , which has the following rules: * convert to UTF8 * convert to lower case * multi-spaces collapsed * leading SEQUENCE hader is skipped +* @param name a pointer to X509_NAME that is to be converted +* @param out a pointer to conveted data +* @return a number of converted bytes, otherwise <0 error code */ int wolfSSL_i2d_X509_NAME_canon(WOLFSSL_X509_NAME* name, unsigned char** out) { @@ -46301,7 +46302,7 @@ void wolfSSL_sk_SSL_CIPHER_free(WOLF_STACK_OF(WOLFSSL_CIPHER)* sk) } #if defined(OPENSSL_ALL) && !defined(NO_FILESYSTEM) && !defined(NO_WOLFSSL_DIR) -/* WOLFSSL_BY_DIR_HASH stuff */ +/* create an instance of WOLFSSL_BY_DIR_HASH structure */ WOLFSSL_BY_DIR_HASH* wolfSSL_BY_DIR_HASH_new(void) { WOLFSSL_BY_DIR_HASH* dir_hash; @@ -46315,7 +46316,7 @@ WOLFSSL_BY_DIR_HASH* wolfSSL_BY_DIR_HASH_new(void) } return dir_hash; } - +/* release a WOLFSSL_BY_DIR_HASH resource */ void wolfSSL_BY_DIR_HASH_free(WOLFSSL_BY_DIR_HASH* dir_hash) { if (dir_hash == NULL) @@ -46323,7 +46324,7 @@ void wolfSSL_BY_DIR_HASH_free(WOLFSSL_BY_DIR_HASH* dir_hash) XFREE(dir_hash, NULL, DYNAMIC_TYPE_OPENSSL); } - +/* create an instance of WOLFSSL_STACK for STACK_TYPE_BY_DIR_hash */ WOLFSSL_STACK* wolfSSL_sk_BY_DIR_HASH_new_null(void) { WOLFSSL_STACK* sk = wolfSSL_sk_new_node(NULL); @@ -46361,7 +46362,7 @@ int wolfSSL_sk_BY_DIR_HASH_find( } return -1; } - +/* return a number of WOLFSSL_BY_DIR_HASH in stack */ int wolfSSL_sk_BY_DIR_HASH_num(const WOLF_STACK_OF(WOLFSSL_BY_DIR_HASH) *sk) { WOLFSSL_ENTER("wolfSSL_sk_WOLFSSL_BY_DIR_HASH_num"); @@ -46370,7 +46371,7 @@ int wolfSSL_sk_BY_DIR_HASH_num(const WOLF_STACK_OF(WOLFSSL_BY_DIR_HASH) *sk) return -1; return (int)sk->num; } - +/* return WOLFSSL_BY_DIR_HASH instance at i */ WOLFSSL_BY_DIR_HASH* wolfSSL_sk_BY_DIR_HASH_value( const WOLF_STACK_OF(WOLFSSL_BY_DIR_HASH) *sk, int i) { @@ -46383,7 +46384,7 @@ WOLFSSL_BY_DIR_HASH* wolfSSL_sk_BY_DIR_HASH_value( return NULL; return sk->data.dir_hash; } - +/* pop WOLFSSL_BY_DIR_HASH instance, and remove its node from stack */ WOLFSSL_BY_DIR_HASH* wolfSSL_sk_BY_DIR_HASH_pop( WOLF_STACK_OF(WOLFSSL_BY_DIR_HASH)* sk) { @@ -46414,7 +46415,8 @@ WOLFSSL_BY_DIR_HASH* wolfSSL_sk_BY_DIR_HASH_pop( return hash; } - +/* release all contents in stack, and then release stack itself */ +/* it uses function when it is passed */ void wolfSSL_sk_BY_DIR_HASH_pop_free(WOLF_STACK_OF(BY_DIR_HASH)* sk, void (*f) (WOLFSSL_BY_DIR_HASH*)) { @@ -46451,13 +46453,11 @@ void wolfSSL_sk_BY_DIR_HASH_pop_free(WOLF_STACK_OF(BY_DIR_HASH)* sk, } XFREE(sk, NULL, DYNAMIC_TYPE_OPENSSL); } - +/* release all contents in stack, and then release stack itself */ void wolfSSL_sk_BY_DIR_HASH_free(WOLF_STACK_OF(WOLFSSL_BY_DIR_HASH) *sk) { wolfSSL_sk_BY_DIR_HASH_pop_free(sk, NULL); } - - /* Adds the WOLFSSL_BY_DIR_HASH to the stack "sk". "sk" takes control of "in" and * tries to free it when the stack is free'd. * @@ -46500,9 +46500,7 @@ int wolfSSL_sk_BY_DIR_HASH_push(WOLF_STACK_OF(WOLFSSL_BY_DIR_HASH)* sk, return WOLFSSL_SUCCESS; } - - -/* WOLFSSL_BY_DIR_entry stuff */ +/* create an instance of WOLFSSL_BY_DIR_entry structure */ WOLFSSL_BY_DIR_entry* wolfSSL_BY_DIR_entry_new(void) { WOLFSSL_BY_DIR_entry* entry; @@ -46517,7 +46515,7 @@ WOLFSSL_BY_DIR_entry* wolfSSL_BY_DIR_entry_new(void) } return entry; } - +/* release a WOLFSSL_BY_DIR_entry resource */ void wolfSSL_BY_DIR_entry_free(WOLFSSL_BY_DIR_entry* entry) { WOLFSSL_ENTER("wolfSSL_BY_DIR_entry_free"); @@ -46547,7 +46545,7 @@ WOLFSSL_STACK* wolfSSL_sk_BY_DIR_entry_new_null(void) } return sk; } - +/* return a number of WOLFSSL_BY_DIR_entry in stack */ int wolfSSL_sk_BY_DIR_entry_num(const WOLF_STACK_OF(WOLFSSL_BY_DIR_entry) *sk) { WOLFSSL_ENTER("wolfSSL_sk_BY_DIR_entry_num"); @@ -46556,7 +46554,7 @@ int wolfSSL_sk_BY_DIR_entry_num(const WOLF_STACK_OF(WOLFSSL_BY_DIR_entry) *sk) return -1; return (int)sk->num; } - +/* return WOLFSSL_BY_DIR_entry instance at i */ WOLFSSL_BY_DIR_entry* wolfSSL_sk_BY_DIR_entry_value( const WOLF_STACK_OF(WOLFSSL_BY_DIR_entry) *sk, int i) { @@ -46569,7 +46567,7 @@ WOLFSSL_BY_DIR_entry* wolfSSL_sk_BY_DIR_entry_value( return NULL; return sk->data.dir_entry; } - +/* pop WOLFSSL_BY_DIR_entry instance first, and remove its node from stack */ WOLFSSL_BY_DIR_entry* wolfSSL_sk_BY_DIR_entry_pop( WOLF_STACK_OF(WOLFSSL_BY_DIR_entry)* sk) { @@ -46600,7 +46598,8 @@ WOLFSSL_BY_DIR_entry* wolfSSL_sk_BY_DIR_entry_pop( return entry; } - +/* release all contents in stack, and then release stack itself */ +/* it uses function when it is passed */ void wolfSSL_sk_BY_DIR_entry_pop_free(WOLF_STACK_OF(WOLFSSL_BY_DIR_entry)* sk, void (*f) (WOLFSSL_BY_DIR_entry*)) { @@ -46637,7 +46636,7 @@ void wolfSSL_sk_BY_DIR_entry_pop_free(WOLF_STACK_OF(WOLFSSL_BY_DIR_entry)* sk, } XFREE(sk, NULL, DYNAMIC_TYPE_OPENSSL); } - +/* release all contents in stack, and then release stack itself */ void wolfSSL_sk_BY_DIR_entry_free(WOLF_STACK_OF(wolfSSL_BY_DIR_entry) *sk) { wolfSSL_sk_BY_DIR_entry_pop_free(sk, NULL); diff --git a/wolfcrypt/src/asn.c b/wolfcrypt/src/asn.c index dabc1e20a..5c3f651df 100644 --- a/wolfcrypt/src/asn.c +++ b/wolfcrypt/src/asn.c @@ -9791,6 +9791,7 @@ int ParseCertRelative(DecodedCert* cert, int type, int verify, void* cm) } } #endif + if (cert->srcIdx < cert->sigIndex) { #ifndef ALLOW_V1_EXTENSIONS if (cert->version < 2) { @@ -9819,6 +9820,7 @@ int ParseCertRelative(DecodedCert* cert, int type, int verify, void* cm) /* advance past extensions */ cert->srcIdx = cert->sigIndex; } + if ((ret = GetAlgoId(cert->source, &cert->srcIdx, #ifdef WOLFSSL_CERT_REQ !cert->isCSR ? &confirmOID : &cert->signatureOID, @@ -13169,9 +13171,8 @@ int wc_EncodeName(EncodedName* name, const char* nameStr, char nameType, return idx; } - /* -* this wrappes wc_EncodeName for EMAIL OID + * this wrappes wc_EncodeName for EMAIL OID */ int wc_EncodeName_cano(EncodedName* name, const char* nameStr, char nameType, byte type) @@ -13248,8 +13249,6 @@ int wc_EncodeName_cano(EncodedName* name, const char* nameStr, char nameType, return idx; } - - /* encode CertName into output, return total bytes written */ int SetName(byte* output, word32 outputSz, CertName* name) { From cb0f082e392b20bcc975032927135408204b8704 Mon Sep 17 00:00:00 2001 From: Hideki Miyazaki Date: Mon, 8 Mar 2021 09:31:42 +0900 Subject: [PATCH 05/16] simplified wc_EncodeName* --- wolfcrypt/src/asn.c | 106 +++++++++++++------------------------------- 1 file changed, 30 insertions(+), 76 deletions(-) diff --git a/wolfcrypt/src/asn.c b/wolfcrypt/src/asn.c index 5c3f651df..ed93c64f3 100644 --- a/wolfcrypt/src/asn.c +++ b/wolfcrypt/src/asn.c @@ -13048,11 +13048,11 @@ int FlattenAltNames(byte* output, word32 outputSz, const DNS_entry* names) * nameStr value to be encoded * nameType type of encoding i.e CTC_UTF8 * type id of attribute i.e ASN_COMMON_NAME - * + * emailType type of email i.e CTC_UTF8 * returns length on success */ -int wc_EncodeName(EncodedName* name, const char* nameStr, char nameType, - byte type) +static int wc_EncodeName_ex(EncodedName* name, const char* nameStr, char nameType, + byte type, byte emailType) { word32 idx = 0; /* bottom up */ @@ -13127,11 +13127,12 @@ int wc_EncodeName(EncodedName* name, const char* nameStr, char nameType, case ASN_EMAIL_NAME: { const byte EMAIL_OID[] = { - 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x01, 0x16 + 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x01 }; /* email joint id */ XMEMCPY(name->encoded + idx, EMAIL_OID, sizeof(EMAIL_OID)); idx += (int)sizeof(EMAIL_OID); + name->encoded[idx++] = emailType; break; } @@ -13171,84 +13172,37 @@ int wc_EncodeName(EncodedName* name, const char* nameStr, char nameType, return idx; } -/* - * this wrappes wc_EncodeName for EMAIL OID + +/* canonical encoding one attribute of the name (issuer/subject) + * call we_EncodeName_ex with CTC_UTF8 for email type + * + * name structure to hold result of encoding + * nameStr value to be encoded + * nameType type of encoding i.e CTC_UTF8 + * type id of attribute i.e ASN_COMMON_NAME + * + * returns length on success */ int wc_EncodeName_cano(EncodedName* name, const char* nameStr, char nameType, byte type) { - word32 idx = 0; - - if (nameStr) { - /* bottom up */ - byte firstLen[1 + MAX_LENGTH_SZ]; - byte secondLen[MAX_LENGTH_SZ]; - byte sequence[MAX_SEQ_SZ]; - byte set[MAX_SET_SZ]; - - int strLen = (int)XSTRLEN(nameStr); - int thisLen = strLen; - int firstSz, secondSz, seqSz, setSz; - - const byte EMAIL_OID[] = { 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, - 0x01, 0x09, 0x01, 0x0c }; - - if (type != ASN_EMAIL_NAME) { - return wc_EncodeName(name, nameStr, nameType, type); - } - - if (strLen == 0) { /* no user data for this item */ - name->used = 0; - return 0; - } - secondSz = SetLength(strLen, secondLen); - thisLen += secondSz; - thisLen += EMAIL_JOINT_LEN; - firstSz = EMAIL_JOINT_LEN; - thisLen++; /* id type */ - firstSz = SetObjectId(firstSz, firstLen); - thisLen += firstSz; - - seqSz = SetSequence(thisLen, sequence); - thisLen += seqSz; - setSz = SetSet(thisLen, set); - thisLen += setSz; - - if (thisLen > (int)sizeof(name->encoded)) { - return BUFFER_E; - } - - /* store it */ - idx = 0; - /* set */ - XMEMCPY(name->encoded, set, setSz); - idx += setSz; - /* seq */ - XMEMCPY(name->encoded + idx, sequence, seqSz); - idx += seqSz; - /* asn object id */ - XMEMCPY(name->encoded + idx, firstLen, firstSz); - idx += firstSz; - /* email joint id */ - XMEMCPY(name->encoded + idx, EMAIL_OID, sizeof(EMAIL_OID)); - idx += (int)sizeof(EMAIL_OID); - /* second length */ - XMEMCPY(name->encoded + idx, secondLen, secondSz); - idx += secondSz; - /* str value */ - XMEMCPY(name->encoded + idx, nameStr, strLen); - idx += strLen; - - name->type = type; - name->totalLen = idx; - name->used = 1; - } - else - name->used = 0; - - return idx; + return wc_EncodeName_ex(name, nameStr, nameType, type, 0x0c/* CTC_UTF8 */); } +/* Encodes one attribute of the name (issuer/subject) + * call we_EncodeName_ex with 0x16, IA5String for email type + * name structure to hold result of encoding + * nameStr value to be encoded + * nameType type of encoding i.e CTC_UTF8 + * type id of attribute i.e ASN_COMMON_NAME + * + * returns length on success + */ +int wc_EncodeName(EncodedName* name, const char* nameStr, char nameType, + byte type) +{ + return wc_EncodeName_ex(name, nameStr, nameType, type, 0x16); +} /* encode CertName into output, return total bytes written */ int SetName(byte* output, word32 outputSz, CertName* name) { From a13784abe1e987405279b00fdd685e90f5748ca2 Mon Sep 17 00:00:00 2001 From: Hideki Miyazaki Date: Tue, 9 Mar 2021 08:08:43 +0900 Subject: [PATCH 06/16] fixed jenkins failure --- src/internal.c | 5 +++-- src/ssl.c | 1 + 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/src/internal.c b/src/internal.c index e131fe3a1..6c006cd05 100644 --- a/src/internal.c +++ b/src/internal.c @@ -1821,8 +1821,9 @@ int InitSSL_Ctx(WOLFSSL_CTX* ctx, WOLFSSL_METHOD* method, void* heap) } XMEMSET(ctx->param, 0, sizeof(WOLFSSL_X509_VERIFY_PARAM)); /* WOLFSS_X509_LOOKUP */ - if ((ctx->x509_store.lookup.dirs = (WOLFSSL_BY_DIR*)XMALLOC(sizeof(WOLFSSL_BY_DIR), - ctx->heap, DYNAMIC_TYPE_OPENSSL)) == NULL) { + if ((ctx->x509_store.lookup.dirs = + (WOLFSSL_BY_DIR*)XMALLOC(sizeof(WOLFSSL_BY_DIR), + heap, DYNAMIC_TYPE_OPENSSL)) == NULL) { WOLFSSL_MSG("ctx-x509_store.lookup.dir memory allocation error"); return MEMORY_E; } diff --git a/src/ssl.c b/src/ssl.c index c1d0811b3..33f36f7e6 100644 --- a/src/ssl.c +++ b/src/ssl.c @@ -24979,6 +24979,7 @@ int wolfSSL_X509_LOOKUP_ctrl(WOLFSSL_X509_LOOKUP *ctx, int cmd, (void)argl; (void)ret; (void)cmd; + (void)x509AddCertDir; lret = WOLFSSL_NOT_IMPLEMENTED; #endif return lret; From 2d79578eda702a4eb40a44a2ef4e82657cdefb01 Mon Sep 17 00:00:00 2001 From: Hideki Miyazaki Date: Tue, 9 Mar 2021 11:54:48 +0900 Subject: [PATCH 07/16] addressed jenkins failure fix missing mutex initialization --- src/internal.c | 46 ++++++++++++++++++++++--------------- src/ssl.c | 4 ++++ wolfssl/wolfcrypt/wc_port.h | 2 ++ 3 files changed, 34 insertions(+), 18 deletions(-) diff --git a/src/internal.c b/src/internal.c index 6c006cd05..806157809 100644 --- a/src/internal.c +++ b/src/internal.c @@ -1828,6 +1828,11 @@ int InitSSL_Ctx(WOLFSSL_CTX* ctx, WOLFSSL_METHOD* method, void* heap) return MEMORY_E; } XMEMSET(ctx->x509_store.lookup.dirs, 0, sizeof(WOLFSSL_BY_DIR)); + if (wc_InitMutex(&ctx->x509_store.lookup.dirs->lock) != 0) { + WOLFSSL_MSG("Bad mutex init"); + XFREE(ctx->x509_store.lookup.dirs, heap, DYNAMIC_TYPE_OPENSSL); + return BAD_MUTEX_E; + } #endif #endif @@ -10653,7 +10658,8 @@ int LoadCrlCertByIssuer(WOLFSSL_X509_STORE* store, X509_NAME* issuer, int type) return MEMORY_E; } - if (type == X509_LU_CRL && entry->hashes != NULL) { + if (type == X509_LU_CRL && entry->hashes != NULL && + wolfSSL_sk_BY_DIR_HASH_num(entry->hashes) > 0) { /* lock the list */ if (wc_LockMutex(&lookup->dirs->lock) != 0) { WOLFSSL_MSG("wc_LockMutex cdir Lock error"); @@ -10696,7 +10702,6 @@ int LoadCrlCertByIssuer(WOLFSSL_X509_STORE* store, X509_NAME* issuer, int type) else if (type == X509_LU_CRL) { ret = wolfSSL_X509_load_crl_file(&store->lookup, filename, WOLFSSL_FILETYPE_PEM); - printf("return load crl file %d\n", ret); if (ret != WOLFSSL_SUCCESS) { WOLFSSL_MSG("failed to load CRL\n"); break; @@ -10713,24 +10718,29 @@ int LoadCrlCertByIssuer(WOLFSSL_X509_STORE* store, X509_NAME* issuer, int type) break; } - if (type == X509_LU_CRL) { - if (wc_LockMutex(&lookup->dirs->lock) != 0) { - WOLFSSL_MSG("wc_LockMutex cdir Lock error"); - return BAD_MUTEX_E; - } - if (ph == NULL) { - ph = wolfSSL_BY_DIR_HASH_new(); - if (ph == NULL) { - WOLFSSL_MSG("failed to allocate hash stack"); - ret = WOLFSSL_FAILURE; - } else { - ph->hash_value = hash; - ph->last_suffix = suffix; - - ret = wolfSSL_sk_BY_DIR_HASH_push(entry->hashes, ph); + if (suffix == MAX_SUFFIX) { + WOLFSSL_MSG("not found file"); + ret = WOLFSSL_FAILURE; + } else { + if (type == X509_LU_CRL) { + if (wc_LockMutex(&lookup->dirs->lock) != 0) { + WOLFSSL_MSG("wc_LockMutex cdir Lock error"); + return BAD_MUTEX_E; } + if (ph == NULL) { + ph = wolfSSL_BY_DIR_HASH_new(); + if (ph == NULL) { + WOLFSSL_MSG("failed to allocate hash stack"); + ret = WOLFSSL_FAILURE; + } else { + ph->hash_value = hash; + ph->last_suffix = suffix; + + ret = wolfSSL_sk_BY_DIR_HASH_push(entry->hashes, ph); + } + } + wc_UnLockMutex(&lookup->dirs->lock); } - wc_UnLockMutex(&lookup->dirs->lock); } XFREE(filename, NULL, DYNAMIC_TYPE_OPENSSL); diff --git a/src/ssl.c b/src/ssl.c index 33f36f7e6..e640cb7ae 100644 --- a/src/ssl.c +++ b/src/ssl.c @@ -25858,6 +25858,10 @@ WOLFSSL_X509_STORE* wolfSSL_X509_STORE_new(void) goto err_exit; } XMEMSET(store->lookup.dirs, 0, sizeof(WOLFSSL_BY_DIR)); + if (wc_InitMutex(&store->lookup.dirs->lock) != 0) { + WOLFSSL_MSG("Bad mutex init"); + goto err_exit; + } #endif return store; diff --git a/wolfssl/wolfcrypt/wc_port.h b/wolfssl/wolfcrypt/wc_port.h index 36c858f53..e91e64d25 100644 --- a/wolfssl/wolfcrypt/wc_port.h +++ b/wolfssl/wolfcrypt/wc_port.h @@ -679,6 +679,7 @@ WOLFSSL_API int wolfCrypt_Cleanup(void); #if !defined(NO_WOLFSSL_DIR)\ && !defined(WOLFSSL_NUCLEUS) && !defined(WOLFSSL_NUCLEUS_1_2) #if defined(USE_WINDOWS_API) + #include #define XSTAT _stat #define SEPARATOR_CHAR ';' #elif defined(WOLFSSL_ZEPHYR) @@ -730,6 +731,7 @@ WOLFSSL_API int wolfCrypt_Cleanup(void); #ifdef USE_WINDOWS_API WIN32_FIND_DATAA FindFileData; HANDLE hFind; + struct XSTAT s; #elif defined(WOLFSSL_ZEPHYR) struct fs_dirent entry; struct fs_dir_t dir; From f9c9de585570dc128ee29c86d8a27fc3be05e925 Mon Sep 17 00:00:00 2001 From: Hideki Miyazaki Date: Wed, 10 Mar 2021 23:33:18 +0900 Subject: [PATCH 08/16] free Mutex --- src/internal.c | 2 ++ src/ssl.c | 1 + 2 files changed, 3 insertions(+) diff --git a/src/internal.c b/src/internal.c index 806157809..3bb4c8eb7 100644 --- a/src/internal.c +++ b/src/internal.c @@ -1990,7 +1990,9 @@ void SSL_CtxResourceFree(WOLFSSL_CTX* ctx) if (ctx->x509_store.lookup.dirs->dir_entry) { wolfSSL_sk_BY_DIR_entry_free(ctx->x509_store.lookup.dirs->dir_entry); } + #endif + wc_FreeMutex(&ctx->x509_store.lookup.dirs->lock); XFREE(ctx->x509_store.lookup.dirs, ctx->heap, DYNAMIC_TYPE_OPENSSL); } #endif diff --git a/src/ssl.c b/src/ssl.c index e640cb7ae..9e3ddef3a 100644 --- a/src/ssl.c +++ b/src/ssl.c @@ -25894,6 +25894,7 @@ void wolfSSL_X509_STORE_free(WOLFSSL_X509_STORE* store) wolfSSL_sk_BY_DIR_entry_free(store->lookup.dirs->dir_entry); } #endif + wc_FreeMutex(&store->lookup.dirs->lock); XFREE(store->lookup.dirs, NULL, DYNAMIC_TYPE_OPENSSL); store->lookup.dirs = NULL; } From 4650aaf4fbfbfb25bd3bd2d55dc16a53bbb9b94a Mon Sep 17 00:00:00 2001 From: Hideki Miyazaki Date: Thu, 11 Mar 2021 15:43:54 +0900 Subject: [PATCH 09/16] addressed review comments part 1 --- examples/client/client.c | 14 ++--- examples/server/server.c | 14 ++--- src/crl.c | 2 +- src/internal.c | 66 ++++++++++++---------- src/ssl.c | 109 +++++++++++++++++++++++++++--------- tests/api.c | 2 +- wolfcrypt/src/asn.c | 4 +- wolfcrypt/src/wc_port.c | 2 +- wolfssl/internal.h | 2 +- wolfssl/wolfcrypt/asn.h | 2 +- wolfssl/wolfcrypt/wc_port.h | 2 + 11 files changed, 142 insertions(+), 77 deletions(-) diff --git a/examples/client/client.c b/examples/client/client.c index 11f2c92b6..1944ea447 100644 --- a/examples/client/client.c +++ b/examples/client/client.c @@ -1121,7 +1121,7 @@ static const char* client_usage_msg[][67] = { "-8 Use X448 for key exchange\n", /* 66 */ #endif #if defined(OPENSSL_ALL) && defined(WOLFSSL_CERT_GEN) && \ - (defined(WOLFSSL_CERT_REQ) || defined(OLFSSL_CERT_EXT)) && \ + (defined(WOLFSSL_CERT_REQ) || defined(WOLFSSL_CERT_EXT)) && \ !defined(NO_FILESYSTEM) && !defined(NO_WOLFSSL_DIR) "-9 Use hash dir look up for certificate loading\n" " loading from /certs folder\n" @@ -1306,7 +1306,7 @@ static const char* client_usage_msg[][67] = { "-8 Use X448 for key exchange\n", /* 66 */ #endif #if defined(OPENSSL_ALL) && defined(WOLFSSL_CERT_GEN) && \ - (defined(WOLFSSL_CERT_REQ) || defined(OLFSSL_CERT_EXT)) && \ + (defined(WOLFSSL_CERT_REQ) || defined(WOLFSSL_CERT_EXT)) && \ !defined(NO_FILESYSTEM) && !defined(NO_WOLFSSL_DIR) "-9 証明書の読み込みに hash dir 機能を使用する\n" " /certs フォルダーからロードします\n" @@ -1488,7 +1488,7 @@ static void Usage(void) printf("%s", msg[++msgid]); /* -8 */ #endif #if defined(OPENSSL_ALL) && defined(WOLFSSL_CERT_GEN) && \ - (defined(WOLFSSL_CERT_REQ) || defined(OLFSSL_CERT_EXT)) && \ + (defined(WOLFSSL_CERT_REQ) || defined(WOLFSSL_CERT_EXT)) && \ !defined(NO_FILESYSTEM) && !defined(NO_WOLFSSL_DIR) printf("%s", msg[++msgid]); /* -9 */ #endif @@ -1627,7 +1627,7 @@ THREAD_RETURN WOLFSSL_THREAD client_test(void* args) const char* wnrConfigFile = wnrConfig; #endif #if defined(OPENSSL_ALL) && defined(WOLFSSL_CERT_GEN) && \ - (defined(WOLFSSL_CERT_REQ) || defined(OLFSSL_CERT_EXT)) && \ + (defined(WOLFSSL_CERT_REQ) || defined(WOLFSSL_CERT_EXT)) && \ !defined(NO_FILESYSTEM) && !defined(NO_WOLFSSL_DIR) int useCertFolder = 0; #endif @@ -2193,7 +2193,7 @@ THREAD_RETURN WOLFSSL_THREAD client_test(void* args) break; case '9' : #if defined(OPENSSL_ALL) && defined(WOLFSSL_CERT_GEN) && \ - (defined(WOLFSSL_CERT_REQ) || defined(OLFSSL_CERT_EXT)) && \ + (defined(WOLFSSL_CERT_REQ) || defined(WOLFSSL_CERT_EXT)) && \ !defined(NO_FILESYSTEM) && !defined(NO_WOLFSSL_DIR) useCertFolder = 1; break; @@ -2658,7 +2658,7 @@ THREAD_RETURN WOLFSSL_THREAD client_test(void* args) if (!usePsk && !useAnon && !useVerifyCb && myVerifyAction != VERIFY_FORCE_FAIL) { #if defined(OPENSSL_ALL) && defined(WOLFSSL_CERT_GEN) && \ - (defined(WOLFSSL_CERT_REQ) || defined(OLFSSL_CERT_EXT)) && \ + (defined(WOLFSSL_CERT_REQ) || defined(WOLFSSL_CERT_EXT)) && \ !defined(NO_FILESYSTEM) && !defined(NO_WOLFSSL_DIR) if (useCertFolder) { WOLFSSL_X509_STORE *store; @@ -2728,7 +2728,7 @@ THREAD_RETURN WOLFSSL_THREAD client_test(void* args) } #endif /* WOLFSSL_TRUST_PEER_CERT && !NO_FILESYSTEM */ #if defined(OPENSSL_ALL) && defined(WOLFSSL_CERT_GEN) && \ - (defined(WOLFSSL_CERT_REQ) || defined(OLFSSL_CERT_EXT)) && \ + (defined(WOLFSSL_CERT_REQ) || defined(WOLFSSL_CERT_EXT)) && \ !defined(NO_FILESYSTEM) && !defined(NO_WOLFSSL_DIR) } #endif diff --git a/examples/server/server.c b/examples/server/server.c index 092f86345..ae5fe4eab 100644 --- a/examples/server/server.c +++ b/examples/server/server.c @@ -707,7 +707,7 @@ static const char* server_usage_msg[][57] = { "-8 Pre-generate Key share using Curve448 only\n", /* 56 */ #endif #if defined(OPENSSL_ALL) && defined(WOLFSSL_CERT_GEN) && \ - (defined(WOLFSSL_CERT_REQ) || defined(OLFSSL_CERT_EXT)) && \ + (defined(WOLFSSL_CERT_REQ) || defined(WOLFSSL_CERT_EXT)) && \ !defined(NO_FILESYSTEM) && !defined(NO_WOLFSSL_DIR) "-9 Use hash dir look up for certificate loading\n" " loading from /certs folder\n" @@ -850,7 +850,7 @@ static const char* server_usage_msg[][57] = { "-8 Pre-generate Key share using Curve448 only\n", /* 56 */ #endif #if defined(OPENSSL_ALL) && defined(WOLFSSL_CERT_GEN) && \ - (defined(WOLFSSL_CERT_REQ) || defined(OLFSSL_CERT_EXT)) && \ + (defined(WOLFSSL_CERT_REQ) || defined(WOLFSSL_CERT_EXT)) && \ !defined(NO_FILESYSTEM) && !defined(NO_WOLFSSL_DIR) "-9 証明書の読み込みに hash dir 機能を使用する\n" " /certs フォルダーからロードします\n" @@ -991,7 +991,7 @@ static void Usage(void) printf("%s", msg[++msgId]); /* -8 */ #endif #if defined(OPENSSL_ALL) && defined(WOLFSSL_CERT_GEN) && \ - (defined(WOLFSSL_CERT_REQ) || defined(OLFSSL_CERT_EXT)) && \ + (defined(WOLFSSL_CERT_REQ) || defined(WOLFSSL_CERT_EXT)) && \ !defined(NO_FILESYSTEM) && !defined(NO_WOLFSSL_DIR) printf("%s", msg[++msgId]); /* -9 */ #endif @@ -1153,7 +1153,7 @@ THREAD_RETURN WOLFSSL_THREAD server_test(void* args) int disallowETM = 0; #endif #if defined(OPENSSL_ALL) && defined(WOLFSSL_CERT_GEN) && \ - (defined(WOLFSSL_CERT_REQ) || defined(OLFSSL_CERT_EXT)) && \ + (defined(WOLFSSL_CERT_REQ) || defined(WOLFSSL_CERT_EXT)) && \ !defined(NO_FILESYSTEM) && !defined(NO_WOLFSSL_DIR) int useCertFolder = 0; #endif @@ -1653,7 +1653,7 @@ THREAD_RETURN WOLFSSL_THREAD server_test(void* args) break; case '9' : #if defined(OPENSSL_ALL) && defined(WOLFSSL_CERT_GEN) && \ - (defined(WOLFSSL_CERT_REQ) || defined(OLFSSL_CERT_EXT)) && \ + (defined(WOLFSSL_CERT_REQ) || defined(WOLFSSL_CERT_EXT)) && \ !defined(NO_FILESYSTEM) && !defined(NO_WOLFSSL_DIR) useCertFolder = 1; break; @@ -2049,7 +2049,7 @@ THREAD_RETURN WOLFSSL_THREAD server_test(void* args) verify_flags |= WOLFSSL_LOAD_FLAG_DATE_ERR_OKAY; #endif #if defined(OPENSSL_ALL) && defined(WOLFSSL_CERT_GEN) && \ - (defined(WOLFSSL_CERT_REQ) || defined(OLFSSL_CERT_EXT)) && \ + (defined(WOLFSSL_CERT_REQ) || defined(WOLFSSL_CERT_EXT)) && \ !defined(NO_FILESYSTEM) && !defined(NO_WOLFSSL_DIR) if (useCertFolder) { WOLFSSL_X509_STORE *store; @@ -2086,7 +2086,7 @@ THREAD_RETURN WOLFSSL_THREAD server_test(void* args) } #endif /* WOLFSSL_TRUST_PEER_CERT */ #if defined(OPENSSL_ALL) && defined(WOLFSSL_CERT_GEN) && \ - (defined(WOLFSSL_CERT_REQ) || defined(OLFSSL_CERT_EXT)) && \ + (defined(WOLFSSL_CERT_REQ) || defined(WOLFSSL_CERT_EXT)) && \ !defined(NO_FILESYSTEM) && !defined(NO_WOLFSSL_DIR) } #endif diff --git a/src/crl.c b/src/crl.c index 5d6c7da61..fd96c4390 100644 --- a/src/crl.c +++ b/src/crl.c @@ -365,7 +365,7 @@ int CheckCertCRL(WOLFSSL_CRL* crl, DecodedCert* cert) #endif #if defined(OPENSSL_ALL) && defined(WOLFSSL_CERT_GEN) && \ - (defined(WOLFSSL_CERT_REQ) || defined(OLFSSL_CERT_EXT)) && \ + (defined(WOLFSSL_CERT_REQ) || defined(WOLFSSL_CERT_EXT)) && \ !defined(NO_FILESYSTEM) && !defined(NO_WOLFSSL_DIR) if (foundEntry == 0) { if (crl->cm->x509_store_p != NULL) { diff --git a/src/internal.c b/src/internal.c index 3bb4c8eb7..01e905de7 100644 --- a/src/internal.c +++ b/src/internal.c @@ -1820,16 +1820,18 @@ int InitSSL_Ctx(WOLFSSL_CTX* ctx, WOLFSSL_METHOD* method, void* heap) return MEMORY_E; } XMEMSET(ctx->param, 0, sizeof(WOLFSSL_X509_VERIFY_PARAM)); - /* WOLFSS_X509_LOOKUP */ + /* WOLFSSL_X509_LOOKUP */ if ((ctx->x509_store.lookup.dirs = (WOLFSSL_BY_DIR*)XMALLOC(sizeof(WOLFSSL_BY_DIR), heap, DYNAMIC_TYPE_OPENSSL)) == NULL) { WOLFSSL_MSG("ctx-x509_store.lookup.dir memory allocation error"); + XFREE(ctx->param, heap, DYNAMIC_TYPE_OPENSSL); return MEMORY_E; } XMEMSET(ctx->x509_store.lookup.dirs, 0, sizeof(WOLFSSL_BY_DIR)); if (wc_InitMutex(&ctx->x509_store.lookup.dirs->lock) != 0) { WOLFSSL_MSG("Bad mutex init"); + XFREE(ctx->param, heap, DYNAMIC_TYPE_OPENSSL); XFREE(ctx->x509_store.lookup.dirs, heap, DYNAMIC_TYPE_OPENSSL); return BAD_MUTEX_E; } @@ -10582,17 +10584,18 @@ static void FreeProcPeerCertArgs(WOLFSSL* ssl, void* pArgs) } } #if defined(OPENSSL_ALL) && defined(WOLFSSL_CERT_GEN) && \ - (defined(WOLFSSL_CERT_REQ) || defined(OLFSSL_CERT_EXT)) && \ + (defined(WOLFSSL_CERT_REQ) || defined(WOLFSSL_CERT_EXT)) && \ !defined(NO_FILESYSTEM) && !defined(NO_WOLFSSL_DIR) -/* load certificate file which has the form .(r)N[0..N] */ -/* in the folder. */ -/* (r), in the case of CRL file */ -/* @param store a pointer to X509_STORE structure */ -/* @param issuer a pointer to X509_NAME that presents issuer */ -/* @param type X509_LU_X509 or X509_LU_CRL */ +/* load certificate file which has the form .(r)N[0..N] */ +/* in the folder. */ +/* (r), in the case of CRL file */ +/* @param store a pointer to X509_STORE structure */ +/* @param issuer a pointer to X509_NAME that presents an issuer */ +/* @param type X509_LU_X509 or X509_LU_CRL */ +/* @return WOLFSSL_SUCCESS on successful, otherwise WOLFSSL_FAILURE */ int LoadCrlCertByIssuer(WOLFSSL_X509_STORE* store, X509_NAME* issuer, int type) { - const int MAX_SUFFIX = 10; + const int MAX_SUFFIX = 10;/* The number comes from CA_TABLE_SIZE=10 */ int ret = WOLFSSL_SUCCESS; WOLFSSL_X509_LOOKUP* lookup = &store->lookup; WOLFSSL_BY_DIR_entry* entry; @@ -10622,7 +10625,7 @@ int LoadCrlCertByIssuer(WOLFSSL_X509_STORE* store, X509_NAME* issuer, int type) retHash = wc_ShaHash((const byte*)pbuf, len, dgt); #endif if (retHash == 0) { - /* 4 bytes in small endian as unsigned long */ + /* 4 bytes in little endian as unsigned long */ hash = (((unsigned long)dgt[3] << 24) | ((unsigned long)dgt[2] << 16) | ((unsigned long)dgt[1] << 8) | @@ -10635,7 +10638,7 @@ int LoadCrlCertByIssuer(WOLFSSL_X509_STORE* store, X509_NAME* issuer, int type) } /* try to load each hashed name file in path */ -#if !defined(NO_FILESYSTE) && !defined(NO_WOLFSSL_DIR) +#if !defined(NO_FILESYSTEM) && !defined(NO_WOLFSSL_DIR) if (type == X509_LU_CRL) { post = "r"; @@ -10646,19 +10649,6 @@ int LoadCrlCertByIssuer(WOLFSSL_X509_STORE* store, X509_NAME* issuer, int type) for (i=0; idirs->dir_entry, i); - /*/.(r)N\0 */ - /*112345678 1 1 1 1 => 13 */ - len = (int)XSTRLEN(entry->dir_name) + 13; - - if (filename != NULL) { - XFREE(filename, NULL, DYNAMIC_TYPE_OPENSSL); - } - - filename = (char*)XMALLOC(len, NULL, DYNAMIC_TYPE_OPENSSL); - if (filename == NULL) { - WOLFSSL_MSG("memory allcation error"); - return MEMORY_E; - } if (type == X509_LU_CRL && entry->hashes != NULL && wolfSSL_sk_BY_DIR_HASH_num(entry->hashes) > 0) { @@ -10682,7 +10672,25 @@ int LoadCrlCertByIssuer(WOLFSSL_X509_STORE* store, X509_NAME* issuer, int type) wc_UnLockMutex(&lookup->dirs->lock); } - for (; suffix < MAX_SUFFIX;suffix++) { + /* Additional buffer length for file name memory allocation : */ + /* / .(r)N\0 */ + /*|1| 8 |1|1|1|1| => 13 */ + len = (int)XSTRLEN(entry->dir_name) + 13; + if (filename != NULL) { + XFREE(filename, NULL, DYNAMIC_TYPE_OPENSSL); + } + + filename = (char*)XMALLOC(len, NULL, DYNAMIC_TYPE_OPENSSL); + if (filename == NULL) { + WOLFSSL_MSG("memory allocation error"); + return MEMORY_E; + } + + /* set as FAILURE, if successfuly loading cert of CRL, this becomes */ + /* WOLFSSL_SUCCESS */ + ret = WOLFSSL_FAILURE; + + for (; suffix < MAX_SUFFIX; suffix++) { /* /folder-path/.(r)N[0..9] */ XSNPRINTF(filename, len, "%s/%08lx.%s%d", entry->dir_name, hash, post, suffix); @@ -10720,7 +10728,7 @@ int LoadCrlCertByIssuer(WOLFSSL_X509_STORE* store, X509_NAME* issuer, int type) break; } - if (suffix == MAX_SUFFIX) { + if (ret != WOLFSSL_SUCCESS) { WOLFSSL_MSG("not found file"); ret = WOLFSSL_FAILURE; } else { @@ -11291,7 +11299,7 @@ int ProcessPeerCerts(WOLFSSL* ssl, byte* input, word32* inOutIdx, !ssl->options.verifyNone ? VERIFY : NO_VERIFY, &subjectHash, &alreadySigner); #if defined(OPENSSL_ALL) && defined(WOLFSSL_CERT_GEN) && \ - (defined(WOLFSSL_CERT_REQ) || defined(OLFSSL_CERT_EXT)) && \ + (defined(WOLFSSL_CERT_REQ) || defined(WOLFSSL_CERT_EXT)) && \ !defined(NO_FILESYSTEM) && !defined(NO_WOLFSSL_DIR) if (ret == ASN_NO_SIGNER_E) { WOLFSSL_MSG("try to load certificate if hash dir is set"); @@ -11312,7 +11320,7 @@ int ProcessPeerCerts(WOLFSSL* ssl, byte* input, word32* inOutIdx, !ssl->options.verifyNone ? VERIFY : NO_VERIFY, &subjectHash, &alreadySigner); } else - ret = ASN_NO_SIGNER_E; + ret = ASN_NO_SIGNER_E; } #endif #ifdef WOLFSSL_ASYNC_CRYPT @@ -11509,7 +11517,7 @@ int ProcessPeerCerts(WOLFSSL* ssl, byte* input, word32* inOutIdx, !ssl->options.verifyNone ? VERIFY : NO_VERIFY, &subjectHash, &alreadySigner); #if defined(OPENSSL_ALL) && defined(WOLFSSL_CERT_GEN) && \ - (defined(WOLFSSL_CERT_REQ) || defined(OLFSSL_CERT_EXT)) && \ + (defined(WOLFSSL_CERT_REQ) || defined(WOLFSSL_CERT_EXT)) && \ !defined(NO_FILESYSTEM) && !defined(NO_WOLFSSL_DIR) if (ret == ASN_NO_SIGNER_E) { WOLFSSL_MSG("try to load certificate if hash dir is set"); diff --git a/src/ssl.c b/src/ssl.c index 9e3ddef3a..ac8cef9fb 100644 --- a/src/ssl.c +++ b/src/ssl.c @@ -24829,6 +24829,13 @@ WOLFSSL_X509_LOOKUP_METHOD* wolfSSL_X509_LOOKUP_file(void) return &meth; } +/* set directory path to load certificate or CRL which have the hash.N form */ +/* for late use */ +/* @param ctx a pointer to WOLFSSL_BY_DIR structure */ +/* @param argc directory path */ +/* @param argl file type, either WOLFSSL_FILETYPE_PEM or */ +/* WOLFSSL_FILETYPE_ASN1 */ +/* @return WOLFSSL_SUCCESS on successful, othewise negative or zero */ static int x509AddCertDir(void *p, const char *argc, long argl) { WOLFSSL_ENTER("x509AddCertDir"); @@ -24885,6 +24892,9 @@ static int x509AddCertDir(void *p, const char *argc, long argl) if (ctx->dir_entry == NULL) { WOLFSSL_MSG("failed to allocate dir_entry"); + #ifdef WOLFSSL_SMALL_STACK + XFREE(buf, 0, DYNAMIC_TYPE_OPENSSL); + #endif return 0; } } @@ -24892,6 +24902,9 @@ static int x509AddCertDir(void *p, const char *argc, long argl) entry = wolfSSL_BY_DIR_entry_new(); if (entry == NULL) { WOLFSSL_MSG("failed to allocate dir entry"); + #ifdef WOLFSSL_SMALL_STACK + XFREE(buf, 0, DYNAMIC_TYPE_OPENSSL); + #endif return 0; } entry->dir_type = (int)argl; @@ -24901,6 +24914,9 @@ static int x509AddCertDir(void *p, const char *argc, long argl) if (entry->dir_name == NULL || entry->hashes == NULL) { WOLFSSL_MSG("failed to allocate dir name"); wolfSSL_BY_DIR_entry_free(entry); + #ifdef WOLFSSL_SMALL_STACK + XFREE(buf, 0, DYNAMIC_TYPE_OPENSSL); + #endif return 0; } @@ -24910,6 +24926,9 @@ static int x509AddCertDir(void *p, const char *argc, long argl) if (wolfSSL_sk_BY_DIR_entry_push(ctx->dir_entry, entry) != WOLFSSL_SUCCESS) { wolfSSL_BY_DIR_entry_free(entry); + #ifdef WOLFSSL_SMALL_STACK + XFREE(buf, 0, DYNAMIC_TYPE_OPENSSL); + #endif return 0; } } @@ -24935,20 +24954,25 @@ static int x509AddCertDir(void *p, const char *argc, long argl) #endif } +/* set additional data to X509_LOOKUP */ +/* @param ctx a pointer to X509_LOOKUP structure */ +/* @param cmd control command : */ +/* X509_L_FILE_LOAD, X509_L_ADD_DIR X509_L_ADD_STORE or */ +/* X509_L_LOAD_STORE */ +/* @param argc arguments for the control command */ +/* @param argl arguments for the control command */ +/* @param **ret return value of the control command */ +/* @return WOLFSSL_SUCCESS on successful, othewise WOLFSSL_FAILURE */ +/* note: WOLFSSL_X509_L_ADD_STORE and WOLFSSL_X509_L_LOAD_STORE have not*/ +/* yet implemented. It retutns WOLFSSL_NOT_IMPLEMENTED */ +/* when those control commands are passed. */ int wolfSSL_X509_LOOKUP_ctrl(WOLFSSL_X509_LOOKUP *ctx, int cmd, const char *argc, long argl, char **ret) { - /* control commands: - * X509_L_FILE_LOAD, X509_L_ADD_DIR - * X509_L_ADD_STORE, X509_L_LOAD_STORE - */ int lret = WOLFSSL_FAILURE; WOLFSSL_ENTER("wolfSSL_X509_LOOKUP_ctrl"); #if !defined(NO_FILESYSTEM) - /* returns FAILURE - *if the X509_LOOKUP doesn't have an associated X509_LOOKUP_METHOD */ - if (ctx != NULL) { switch (cmd) { case WOLFSSL_X509_L_FILE_LOAD: @@ -24990,7 +25014,7 @@ WOLFSSL_X509_LOOKUP* wolfSSL_X509_STORE_add_lookup(WOLFSSL_X509_STORE* store, WOLFSSL_X509_LOOKUP_METHOD* m) { WOLFSSL_ENTER("SSL_X509_STORE_add_lookup"); - if (store == NULL) + if (store == NULL || m == NULL) return NULL; /* Make sure the lookup has a back reference to the store. */ @@ -26311,7 +26335,11 @@ WOLFSSL_X509 *wolfSSL_d2i_X509_fp(XFILE fp, WOLFSSL_X509 **x509) WOLFSSL_ENTER("wolfSSL_d2i_X509_fp"); return (WOLFSSL_X509 *)wolfSSL_d2i_X509_fp_ex(fp, (void **)x509, CERT_TYPE); } - +/* load certificate or CRL file, and add it to the STORE */ +/* @param ctx a pointer to X509_LOOKUP structure */ +/* @param file file name to load */ +/* @param type WOLFSSL_FILETYPE_PEM or WOLFSSL_FILETYPE_ASN1 */ +/* @return a number of loading CRL or certificate, otherwise zero */ WOLFSSL_API int wolfSSL_X509_load_cert_crl_file(WOLFSSL_X509_LOOKUP *ctx, const char *file, int type) { @@ -26324,8 +26352,14 @@ WOLFSSL_API int wolfSSL_X509_load_cert_crl_file(WOLFSSL_X509_LOOKUP *ctx, int cnt = 0; int num = 0; - WOLFSSL_ENTER("wolfSSL_X509_load_ceretificate_crl_file"); - + WOLFSSL_ENTER("wolfSSL_X509_load_cert_crl_file"); + + /* stanity check */ + if (ctx == NULL || file == NULL) { + WOLFSSL_MSG("bad arguments"); + return 0; + } + if (type != WOLFSSL_FILETYPE_PEM) { x509 = wolfSSL_X509_load_certificate_file(file, type); if (x509 != NULL) { @@ -41558,6 +41592,14 @@ static int ConvertNIDToWolfSSL(int nid) } #if defined(OPENSSL_ALL) +/* Convert ASN1 input string into canonical ASN1 string */ +/* , which has the following rules: */ +/* convert to UTF8 */ +/* convert to lower case */ +/* multi-spaces collapsed */ +/* @param asn_out a pointer to ASN1_STRING to be converted */ +/* @param asn_in a pointer to input ASN1_STRING */ +/* @return WOLFSSL_SUCCESS on successful converted, otherwise <=0 error code*/ static int wolfSSL_ASN1_STRING_canon(WOLFSSL_ASN1_STRING* asn_out, const WOLFSSL_ASN1_STRING* asn_in) { @@ -41565,6 +41607,14 @@ static int wolfSSL_ASN1_STRING_canon(WOLFSSL_ASN1_STRING* asn_out, char* src; int i, len; + WOLFSSL_ENTER("wolfSSL_ASN1_STRING_canon"); + + /* sanity check */ + if (asn_out == NULL || asn_in == NULL) { + WOLFSSL_MSG("invalid function arguments"); + return BAD_FUNC_ARG; + } + switch (asn_in->type) { case MBSTRING_UTF8: case V_ASN1_PRINTABLESTRING: @@ -41594,7 +41644,7 @@ static int wolfSSL_ASN1_STRING_canon(WOLFSSL_ASN1_STRING* asn_out, for (; (len > 0 && XISSPACE(*dst));len--) { dst--; } - for (; (len > 0 && XISSPACE(*src));len--){ + for (; (len > 0 && XISSPACE(*src));len--) { src++; } @@ -41618,16 +41668,15 @@ static int wolfSSL_ASN1_STRING_canon(WOLFSSL_ASN1_STRING* asn_out, return WOLFSSL_SUCCESS; } -/* this is to converts the x509 name structure into canonical DER format -* , which has the following rules: -* convert to UTF8 -* convert to lower case -* multi-spaces collapsed -* leading SEQUENCE hader is skipped -* @param name a pointer to X509_NAME that is to be converted -* @param out a pointer to conveted data -* @return a number of converted bytes, otherwise <0 error code -*/ +/* This is to convert the x509 name structure into canonical DER format */ +/* , which has the following rules: */ +/* convert to UTF8 */ +/* convert to lower case */ +/* multi-spaces collapsed */ +/* leading SEQUENCE hader is skipped */ +/* @param name a pointer to X509_NAME that is to be converted */ +/* @param out a pointer to conveted data */ +/* @return a number of converted bytes, otherwise <=0 error code */ int wolfSSL_i2d_X509_NAME_canon(WOLFSSL_X509_NAME* name, unsigned char** out) { int totalBytes = 0, i, idx; @@ -41661,8 +41710,12 @@ int wolfSSL_i2d_X509_NAME_canon(WOLFSSL_X509_NAME* name, unsigned char** out) WOLFSSL_ASN1_STRING* cano_data; cano_data = wolfSSL_ASN1_STRING_new(); - if (cano_data == NULL) + if (cano_data == NULL) { + #ifdef WOLFSSL_SMALL_STACK + XFREE(names, NULL, DYNAMIC_TYPE_TMP_BUFFER); + #endif return MEMORY_E; + } data = wolfSSL_X509_NAME_ENTRY_get_data(entry); if (data == NULL) { @@ -41678,7 +41731,7 @@ int wolfSSL_i2d_X509_NAME_canon(WOLFSSL_X509_NAME* name, unsigned char** out) } nameStr = (const char*)wolfSSL_ASN1_STRING_data(cano_data); - ret = wc_EncodeName_cano(&names[i], nameStr, CTC_UTF8, + ret = wc_EncodeNameCanonical(&names[i], nameStr, CTC_UTF8, ConvertNIDToWolfSSL(entry->nid)); if (ret < 0) { #ifdef WOLFSSL_SMALL_STACK @@ -46371,7 +46424,7 @@ int wolfSSL_sk_BY_DIR_HASH_find( /* return a number of WOLFSSL_BY_DIR_HASH in stack */ int wolfSSL_sk_BY_DIR_HASH_num(const WOLF_STACK_OF(WOLFSSL_BY_DIR_HASH) *sk) { - WOLFSSL_ENTER("wolfSSL_sk_WOLFSSL_BY_DIR_HASH_num"); + WOLFSSL_ENTER("wolfSSL_sk_BY_DIR_HASH_num"); if (sk == NULL) return -1; @@ -46421,8 +46474,10 @@ WOLFSSL_BY_DIR_HASH* wolfSSL_sk_BY_DIR_HASH_pop( return hash; } -/* release all contents in stack, and then release stack itself */ -/* it uses function when it is passed */ +/* release all contents in stack, and then release stack itself. */ +/* Second argument is a function pointer to release resouces. */ +/* It calls the function to release resouces when t is passed */ +/* instead of wolfSSL_BY_DIR_HASH_free(). */ void wolfSSL_sk_BY_DIR_HASH_pop_free(WOLF_STACK_OF(BY_DIR_HASH)* sk, void (*f) (WOLFSSL_BY_DIR_HASH*)) { diff --git a/tests/api.c b/tests/api.c index 823c4033b..8f7b7121b 100644 --- a/tests/api.c +++ b/tests/api.c @@ -28104,7 +28104,7 @@ static void test_wolfSSL_X509_Name_canon(void) #if defined(OPENSSL_ALL) && !defined(NO_CERTS) && \ !defined(NO_FILESYSTEM) && !defined(NO_SHA) && \ defined(WOLFSSL_CERT_GEN) && \ - (defined(WOLFSSL_CERT_REQ) || defined(OLFSSL_CERT_EXT)) + (defined(WOLFSSL_CERT_REQ) || defined(WOLFSSL_CERT_EXT)) const long ex_hash1 = 0x0fdb2da4; const long ex_hash2 = 0x9f3e8c9e; diff --git a/wolfcrypt/src/asn.c b/wolfcrypt/src/asn.c index ed93c64f3..c2af80e85 100644 --- a/wolfcrypt/src/asn.c +++ b/wolfcrypt/src/asn.c @@ -13174,7 +13174,7 @@ static int wc_EncodeName_ex(EncodedName* name, const char* nameStr, char nameTyp } /* canonical encoding one attribute of the name (issuer/subject) - * call we_EncodeName_ex with CTC_UTF8 for email type + * call wc_EncodeName_ex with CTC_UTF8 for email type * * name structure to hold result of encoding * nameStr value to be encoded @@ -13183,7 +13183,7 @@ static int wc_EncodeName_ex(EncodedName* name, const char* nameStr, char nameTyp * * returns length on success */ -int wc_EncodeName_cano(EncodedName* name, const char* nameStr, char nameType, +int wc_EncodeNameCanonical(EncodedName* name, const char* nameStr, char nameType, byte type) { return wc_EncodeName_ex(name, nameStr, nameType, type, 0x0c/* CTC_UTF8 */); diff --git a/wolfcrypt/src/wc_port.c b/wolfcrypt/src/wc_port.c index aada029ae..3a30d198a 100644 --- a/wolfcrypt/src/wc_port.c +++ b/wolfcrypt/src/wc_port.c @@ -427,7 +427,7 @@ int wc_FileExists(const char* fname) if (XSTAT(fname, &ctx.s) != 0) { WOLFSSL_MSG("stat on name failed"); return BAD_PATH_ERROR; - }else + } else #if defined(USE_WINDOWS_API) if (ctx.s.st_mode & _S_IFREG) { return 0; diff --git a/wolfssl/internal.h b/wolfssl/internal.h index 2b5a492b3..14a95d165 100644 --- a/wolfssl/internal.h +++ b/wolfssl/internal.h @@ -4819,7 +4819,7 @@ WOLFSSL_LOCAL void FreeKey(WOLFSSL* ssl, int type, void** pKey); #endif #if defined(OPENSSL_ALL) && defined(WOLFSSL_CERT_GEN) && \ - (defined(WOLFSSL_CERT_REQ) || defined(OLFSSL_CERT_EXT)) && \ + (defined(WOLFSSL_CERT_REQ) || defined(WOLFSSL_CERT_EXT)) && \ !defined(NO_FILESYSTEM) && !defined(NO_WOLFSSL_DIR) WOLFSSL_LOCAL int LoadCrlCertByIssuer(WOLFSSL_X509_STORE* store, X509_NAME* issuer, int Type); diff --git a/wolfssl/wolfcrypt/asn.h b/wolfssl/wolfcrypt/asn.h index 1ad8176b2..446148a7a 100644 --- a/wolfssl/wolfcrypt/asn.h +++ b/wolfssl/wolfcrypt/asn.h @@ -1173,7 +1173,7 @@ WOLFSSL_LOCAL int wc_OBJ_sn2nid(const char *sn); WOLFSSL_LOCAL int wc_EncodeName(EncodedName* name, const char* nameStr, char nameType, byte type); -WOLFSSL_LOCAL int wc_EncodeName_cano(EncodedName* name, const char* nameStr, +WOLFSSL_LOCAL int wc_EncodeNameCanonical(EncodedName* name, const char* nameStr, char nameType, byte type); /* ASN.1 helper functions */ #ifdef WOLFSSL_CERT_GEN diff --git a/wolfssl/wolfcrypt/wc_port.h b/wolfssl/wolfcrypt/wc_port.h index e91e64d25..3da8f90c8 100644 --- a/wolfssl/wolfcrypt/wc_port.h +++ b/wolfssl/wolfcrypt/wc_port.h @@ -684,8 +684,10 @@ WOLFSSL_API int wolfCrypt_Cleanup(void); #define SEPARATOR_CHAR ';' #elif defined(WOLFSSL_ZEPHYR) #define XSTAT fs_stat + #define SEPARATOR_CHAR ':' #elif defined(WOLFSSL_TELIT_M2MB) #define XSTAT m2mb_fs_stat + #define SEPARATOR_CHAR ':' #else #include #include From 84368eed3f19ea24054a6c59ce8bb9095c93e9e6 Mon Sep 17 00:00:00 2001 From: Hideki Miyazaki Date: Thu, 11 Mar 2021 16:51:36 +0900 Subject: [PATCH 10/16] addressed review comment part 2 moving BY_DIR_xxx functions to internal --- src/internal.c | 387 +++++++++++++++++++++++++++++++++++++++++++++ src/ssl.c | 386 -------------------------------------------- tests/api.c | 153 +----------------- wolfssl/internal.h | 31 ++++ wolfssl/ssl.h | 32 ---- 5 files changed, 419 insertions(+), 570 deletions(-) diff --git a/src/internal.c b/src/internal.c index 01e905de7..74e0dd2f2 100644 --- a/src/internal.c +++ b/src/internal.c @@ -31601,6 +31601,393 @@ int wolfSSL_GetMaxRecordSize(WOLFSSL* ssl, int maxFragment) return maxFragment; } +#if defined(OPENSSL_ALL) && !defined(NO_FILESYSTEM) && !defined(NO_WOLFSSL_DIR) +/* create an instance of WOLFSSL_BY_DIR_HASH structure */ +WOLFSSL_BY_DIR_HASH* wolfSSL_BY_DIR_HASH_new(void) +{ + WOLFSSL_BY_DIR_HASH* dir_hash; + + WOLFSSL_ENTER("wolfSSL_BY_DIR_HASH_new"); + + dir_hash = (WOLFSSL_BY_DIR_HASH*)XMALLOC(sizeof(WOLFSSL_BY_DIR_HASH), NULL, + DYNAMIC_TYPE_OPENSSL); + if (dir_hash) { + XMEMSET(dir_hash, 0, sizeof(WOLFSSL_BY_DIR_HASH)); + } + return dir_hash; +} +/* release a WOLFSSL_BY_DIR_HASH resource */ +void wolfSSL_BY_DIR_HASH_free(WOLFSSL_BY_DIR_HASH* dir_hash) +{ + if (dir_hash == NULL) + return; + + XFREE(dir_hash, NULL, DYNAMIC_TYPE_OPENSSL); +} +/* create an instance of WOLFSSL_STACK for STACK_TYPE_BY_DIR_hash */ +WOLFSSL_STACK* wolfSSL_sk_BY_DIR_HASH_new_null(void) +{ + WOLFSSL_STACK* sk = wolfSSL_sk_new_node(NULL); + + WOLFSSL_ENTER("wolfSSL_sk_BY_DIR_HASH_new_null"); + + if (sk) { + sk->type = STACK_TYPE_BY_DIR_hash; + } + return sk; +} + +/* returns value less than 0 on fail to match + * On a successful match the priority level found is returned + */ +int wolfSSL_sk_BY_DIR_HASH_find( + WOLF_STACK_OF(WOLFSSL_BY_DIR_HASH)* sk, const WOLFSSL_BY_DIR_HASH* toFind) +{ + WOLFSSL_STACK* next; + int i, sz; + + WOLFSSL_ENTER("wolfSSL_sk_BY_DIR_HASH_find"); + + if (sk == NULL || toFind == NULL) { + return WOLFSSL_FAILURE; + } + + sz = wolfSSL_sk_BY_DIR_HASH_num(sk); + next = sk; + for (i = 0; i < sz && next != NULL; i++) { + if (next->data.dir_hash->hash_value == toFind->hash_value) { + return sz - i; /* reverse because stack pushed highest on first */ + } + next = next->next; + } + return -1; +} +/* return a number of WOLFSSL_BY_DIR_HASH in stack */ +int wolfSSL_sk_BY_DIR_HASH_num(const WOLF_STACK_OF(WOLFSSL_BY_DIR_HASH) *sk) +{ + WOLFSSL_ENTER("wolfSSL_sk_BY_DIR_HASH_num"); + + if (sk == NULL) + return -1; + return (int)sk->num; +} +/* return WOLFSSL_BY_DIR_HASH instance at i */ +WOLFSSL_BY_DIR_HASH* wolfSSL_sk_BY_DIR_HASH_value( + const WOLF_STACK_OF(WOLFSSL_BY_DIR_HASH) *sk, int i) +{ + WOLFSSL_ENTER("wolfSSL_sk_BY_DIR_HASH_value"); + + for (; sk != NULL && i > 0; i--) + sk = sk->next; + + if (i != 0 || sk == NULL) + return NULL; + return sk->data.dir_hash; +} +/* pop WOLFSSL_BY_DIR_HASH instance, and remove its node from stack */ +WOLFSSL_BY_DIR_HASH* wolfSSL_sk_BY_DIR_HASH_pop( + WOLF_STACK_OF(WOLFSSL_BY_DIR_HASH)* sk) +{ + WOLFSSL_STACK* node; + WOLFSSL_BY_DIR_HASH* hash; + + WOLFSSL_ENTER("wolfSSL_sk_BY_DIR_HASH_pop"); + + if (sk == NULL) { + return NULL; + } + + node = sk->next; + hash = sk->data.dir_hash; + + if (node != NULL) { /* update sk and remove node from stack */ + sk->data.dir_hash = node->data.dir_hash; + sk->next = node->next; + wolfSSL_sk_free_node(node); + } + else { /* last x509 in stack */ + sk->data.dir_hash = NULL; + } + + if (sk->num > 0) { + sk->num -= 1; + } + + return hash; +} +/* release all contents in stack, and then release stack itself. */ +/* Second argument is a function pointer to release resouces. */ +/* It calls the function to release resouces when t is passed */ +/* instead of wolfSSL_BY_DIR_HASH_free(). */ +void wolfSSL_sk_BY_DIR_HASH_pop_free(WOLF_STACK_OF(BY_DIR_HASH)* sk, + void (*f) (WOLFSSL_BY_DIR_HASH*)) +{ + WOLFSSL_STACK* node; + + WOLFSSL_ENTER("wolfSSL_sk_BY_DIR_HASH_pop_free"); + + if (sk == NULL) { + return; + } + + /* parse through stack freeing each node */ + node = sk->next; + while (node && sk->num > 1) { + WOLFSSL_STACK* tmp = node; + node = node->next; + + if (f) + f(tmp->data.dir_hash); + else + wolfSSL_BY_DIR_HASH_free(tmp->data.dir_hash); + tmp->data.dir_hash = NULL; + XFREE(tmp, NULL, DYNAMIC_TYPE_OPENSSL); + sk->num -= 1; + } + + /* free head of stack */ + if (sk->num == 1) { + if (f) + f(sk->data.dir_hash); + else + wolfSSL_BY_DIR_HASH_free(sk->data.dir_hash); + sk->data.dir_hash = NULL; + } + XFREE(sk, NULL, DYNAMIC_TYPE_OPENSSL); +} +/* release all contents in stack, and then release stack itself */ +void wolfSSL_sk_BY_DIR_HASH_free(WOLF_STACK_OF(WOLFSSL_BY_DIR_HASH) *sk) +{ + wolfSSL_sk_BY_DIR_HASH_pop_free(sk, NULL); +} +/* Adds the WOLFSSL_BY_DIR_HASH to the stack "sk". "sk" takes control of "in" and + * tries to free it when the stack is free'd. + * + * return 1 on success 0 on fail + */ +int wolfSSL_sk_BY_DIR_HASH_push(WOLF_STACK_OF(WOLFSSL_BY_DIR_HASH)* sk, + WOLFSSL_BY_DIR_HASH* in) +{ + WOLFSSL_STACK* node; + + WOLFSSL_ENTER("wolfSSL_sk_BY_DIR_HASH_push"); + + if (sk == NULL || in == NULL) { + return WOLFSSL_FAILURE; + } + + /* no previous values in stack */ + if (sk->data.dir_hash == NULL) { + sk->data.dir_hash = in; + sk->num += 1; + return WOLFSSL_SUCCESS; + } + + /* stack already has value(s) create a new node and add more */ + node = (WOLFSSL_STACK*)XMALLOC(sizeof(WOLFSSL_STACK), NULL, + DYNAMIC_TYPE_OPENSSL); + if (node == NULL) { + WOLFSSL_MSG("Memory error"); + return WOLFSSL_FAILURE; + } + XMEMSET(node, 0, sizeof(WOLFSSL_STACK)); + + /* push new obj onto head of stack */ + node->data.dir_hash = sk->data.dir_hash; + node->next = sk->next; + node->type = sk->type; + sk->next = node; + sk->data.dir_hash = in; + sk->num += 1; + + return WOLFSSL_SUCCESS; +} +/* create an instance of WOLFSSL_BY_DIR_entry structure */ +WOLFSSL_BY_DIR_entry* wolfSSL_BY_DIR_entry_new(void) +{ + WOLFSSL_BY_DIR_entry* entry; + + WOLFSSL_ENTER("wolfSSL_BY_DIR_entry_new"); + + entry = (WOLFSSL_BY_DIR_entry*)XMALLOC(sizeof(WOLFSSL_BY_DIR_entry), NULL, + DYNAMIC_TYPE_OPENSSL); + + if (entry) { + XMEMSET(entry, 0, sizeof(WOLFSSL_BY_DIR_entry)); + } + return entry; +} +/* release a WOLFSSL_BY_DIR_entry resource */ +void wolfSSL_BY_DIR_entry_free(WOLFSSL_BY_DIR_entry* entry) +{ + WOLFSSL_ENTER("wolfSSL_BY_DIR_entry_free"); + + if (entry == NULL) + return; + + if (entry->hashes) { + wolfSSL_sk_BY_DIR_HASH_free(entry->hashes); + } + + if (entry->dir_name != NULL) { + XFREE(entry->dir_name, NULL, DYNAMIC_TYPE_OPENSSL); + } + + XFREE(entry, NULL, DYNAMIC_TYPE_OPENSSL); +} + +WOLFSSL_STACK* wolfSSL_sk_BY_DIR_entry_new_null(void) +{ + WOLFSSL_STACK* sk = wolfSSL_sk_new_node(NULL); + + WOLFSSL_ENTER("wolfSSL_sk_BY_DIR_entry_new_null"); + + if (sk) { + sk->type = STACK_TYPE_BY_DIR_entry; + } + return sk; +} +/* return a number of WOLFSSL_BY_DIR_entry in stack */ +int wolfSSL_sk_BY_DIR_entry_num(const WOLF_STACK_OF(WOLFSSL_BY_DIR_entry) *sk) +{ + WOLFSSL_ENTER("wolfSSL_sk_BY_DIR_entry_num"); + + if (sk == NULL) + return -1; + return (int)sk->num; +} +/* return WOLFSSL_BY_DIR_entry instance at i */ +WOLFSSL_BY_DIR_entry* wolfSSL_sk_BY_DIR_entry_value( + const WOLF_STACK_OF(WOLFSSL_BY_DIR_entry) *sk, int i) +{ + WOLFSSL_ENTER("wolfSSL_sk_BY_DIR_entry_value"); + + for (; sk != NULL && i > 0; i--) + sk = sk->next; + + if (i != 0 || sk == NULL) + return NULL; + return sk->data.dir_entry; +} +/* pop WOLFSSL_BY_DIR_entry instance first, and remove its node from stack */ +WOLFSSL_BY_DIR_entry* wolfSSL_sk_BY_DIR_entry_pop( + WOLF_STACK_OF(WOLFSSL_BY_DIR_entry)* sk) +{ + WOLFSSL_STACK* node; + WOLFSSL_BY_DIR_entry* entry; + + WOLFSSL_ENTER("wolfSSL_sk_BY_DIR_entry_pop"); + + if (sk == NULL) { + return NULL; + } + + node = sk->next; + entry = sk->data.dir_entry; + + if (node != NULL) { /* update sk and remove node from stack */ + sk->data.dir_entry = node->data.dir_entry; + sk->next = node->next; + wolfSSL_sk_free_node(node); + } + else { /* last x509 in stack */ + sk->data.dir_entry = NULL; + } + + if (sk->num > 0) { + sk->num -= 1; + } + + return entry; +} +/* release all contents in stack, and then release stack itself. */ +/* Second argument is a function pointer to release resouces. */ +/* It calls the function to release resouces when t is passed */ +/* instead of wolfSSL_BY_DIR_entry_free(). */ +void wolfSSL_sk_BY_DIR_entry_pop_free(WOLF_STACK_OF(WOLFSSL_BY_DIR_entry)* sk, + void (*f) (WOLFSSL_BY_DIR_entry*)) +{ + WOLFSSL_STACK* node; + + WOLFSSL_ENTER("wolfSSL_sk_BY_DIR_entry_pop_free"); + + if (sk == NULL) { + return; + } + + /* parse through stack freeing each node */ + node = sk->next; + while (node && sk->num > 1) { + WOLFSSL_STACK* tmp = node; + node = node->next; + + if (f) + f(tmp->data.dir_entry); + else + wolfSSL_BY_DIR_entry_free(tmp->data.dir_entry); + tmp->data.dir_entry = NULL; + XFREE(tmp, NULL, DYNAMIC_TYPE_OPENSSL); + sk->num -= 1; + } + + /* free head of stack */ + if (sk->num == 1) { + if (f) + f(sk->data.dir_entry); + else + wolfSSL_BY_DIR_entry_free(sk->data.dir_entry); + sk->data.dir_entry = NULL; + } + XFREE(sk, NULL, DYNAMIC_TYPE_OPENSSL); +} +/* release all contents in stack, and then release stack itself */ +void wolfSSL_sk_BY_DIR_entry_free(WOLF_STACK_OF(wolfSSL_BY_DIR_entry) *sk) +{ + wolfSSL_sk_BY_DIR_entry_pop_free(sk, NULL); +} + +/* Adds the wolfSSL_BY_DIR_entry to the stack "sk". "sk" takes control of "in" and + * tries to free it when the stack is free'd. + * + * return 1 on success 0 on fail + */ +int wolfSSL_sk_BY_DIR_entry_push(WOLF_STACK_OF(WOLFSSL_BY_DIR_entry)* sk, + WOLFSSL_BY_DIR_entry* in) +{ + WOLFSSL_STACK* node; + + if (sk == NULL || in == NULL) { + return WOLFSSL_FAILURE; + } + + /* no previous values in stack */ + if (sk->data.dir_entry == NULL) { + sk->data.dir_entry = in; + sk->num += 1; + return WOLFSSL_SUCCESS; + } + + /* stack already has value(s) create a new node and add more */ + node = (WOLFSSL_STACK*)XMALLOC(sizeof(WOLFSSL_STACK), NULL, + DYNAMIC_TYPE_OPENSSL); + if (node == NULL) { + WOLFSSL_MSG("Memory error"); + return WOLFSSL_FAILURE; + } + XMEMSET(node, 0, sizeof(WOLFSSL_STACK)); + + /* push new obj onto head of stack */ + node->data.dir_entry = sk->data.dir_entry; + node->next = sk->next; + node->type = sk->type; + sk->next = node; + sk->data.dir_entry = in; + sk->num += 1; + + return WOLFSSL_SUCCESS; +} + +#endif /* OPENSSL_ALL */ #undef ERROR_OUT diff --git a/src/ssl.c b/src/ssl.c index ac8cef9fb..0b73fe825 100644 --- a/src/ssl.c +++ b/src/ssl.c @@ -46360,392 +46360,6 @@ void wolfSSL_sk_SSL_CIPHER_free(WOLF_STACK_OF(WOLFSSL_CIPHER)* sk) } } -#if defined(OPENSSL_ALL) && !defined(NO_FILESYSTEM) && !defined(NO_WOLFSSL_DIR) -/* create an instance of WOLFSSL_BY_DIR_HASH structure */ -WOLFSSL_BY_DIR_HASH* wolfSSL_BY_DIR_HASH_new(void) -{ - WOLFSSL_BY_DIR_HASH* dir_hash; - - WOLFSSL_ENTER("wolfSSL_BY_DIR_HASH_new"); - - dir_hash = (WOLFSSL_BY_DIR_HASH*)XMALLOC(sizeof(WOLFSSL_BY_DIR_HASH), NULL, - DYNAMIC_TYPE_OPENSSL); - if (dir_hash) { - XMEMSET(dir_hash, 0, sizeof(WOLFSSL_BY_DIR_HASH)); - } - return dir_hash; -} -/* release a WOLFSSL_BY_DIR_HASH resource */ -void wolfSSL_BY_DIR_HASH_free(WOLFSSL_BY_DIR_HASH* dir_hash) -{ - if (dir_hash == NULL) - return; - - XFREE(dir_hash, NULL, DYNAMIC_TYPE_OPENSSL); -} -/* create an instance of WOLFSSL_STACK for STACK_TYPE_BY_DIR_hash */ -WOLFSSL_STACK* wolfSSL_sk_BY_DIR_HASH_new_null(void) -{ - WOLFSSL_STACK* sk = wolfSSL_sk_new_node(NULL); - - WOLFSSL_ENTER("wolfSSL_sk_BY_DIR_HASH_new_null"); - - if (sk) { - sk->type = STACK_TYPE_BY_DIR_hash; - } - return sk; -} - -/* returns value less than 0 on fail to match - * On a successful match the priority level found is returned - */ -int wolfSSL_sk_BY_DIR_HASH_find( - WOLF_STACK_OF(WOLFSSL_BY_DIR_HASH)* sk, const WOLFSSL_BY_DIR_HASH* toFind) -{ - WOLFSSL_STACK* next; - int i, sz; - - WOLFSSL_ENTER("wolfSSL_sk_BY_DIR_HASH_find"); - - if (sk == NULL || toFind == NULL) { - return WOLFSSL_FAILURE; - } - - sz = wolfSSL_sk_BY_DIR_HASH_num(sk); - next = sk; - for (i = 0; i < sz && next != NULL; i++) { - if (next->data.dir_hash->hash_value == toFind->hash_value) { - return sz - i; /* reverse because stack pushed highest on first */ - } - next = next->next; - } - return -1; -} -/* return a number of WOLFSSL_BY_DIR_HASH in stack */ -int wolfSSL_sk_BY_DIR_HASH_num(const WOLF_STACK_OF(WOLFSSL_BY_DIR_HASH) *sk) -{ - WOLFSSL_ENTER("wolfSSL_sk_BY_DIR_HASH_num"); - - if (sk == NULL) - return -1; - return (int)sk->num; -} -/* return WOLFSSL_BY_DIR_HASH instance at i */ -WOLFSSL_BY_DIR_HASH* wolfSSL_sk_BY_DIR_HASH_value( - const WOLF_STACK_OF(WOLFSSL_BY_DIR_HASH) *sk, int i) -{ - WOLFSSL_ENTER("wolfSSL_sk_BY_DIR_HASH_value"); - - for (; sk != NULL && i > 0; i--) - sk = sk->next; - - if (i != 0 || sk == NULL) - return NULL; - return sk->data.dir_hash; -} -/* pop WOLFSSL_BY_DIR_HASH instance, and remove its node from stack */ -WOLFSSL_BY_DIR_HASH* wolfSSL_sk_BY_DIR_HASH_pop( - WOLF_STACK_OF(WOLFSSL_BY_DIR_HASH)* sk) -{ - WOLFSSL_STACK* node; - WOLFSSL_BY_DIR_HASH* hash; - - WOLFSSL_ENTER("wolfSSL_sk_BY_DIR_HASH_pop"); - - if (sk == NULL) { - return NULL; - } - - node = sk->next; - hash = sk->data.dir_hash; - - if (node != NULL) { /* update sk and remove node from stack */ - sk->data.dir_hash = node->data.dir_hash; - sk->next = node->next; - wolfSSL_sk_free_node(node); - } - else { /* last x509 in stack */ - sk->data.dir_hash = NULL; - } - - if (sk->num > 0) { - sk->num -= 1; - } - - return hash; -} -/* release all contents in stack, and then release stack itself. */ -/* Second argument is a function pointer to release resouces. */ -/* It calls the function to release resouces when t is passed */ -/* instead of wolfSSL_BY_DIR_HASH_free(). */ -void wolfSSL_sk_BY_DIR_HASH_pop_free(WOLF_STACK_OF(BY_DIR_HASH)* sk, - void (*f) (WOLFSSL_BY_DIR_HASH*)) -{ - WOLFSSL_STACK* node; - - WOLFSSL_ENTER("wolfSSL_sk_BY_DIR_HASH_pop_free"); - - if (sk == NULL) { - return; - } - - /* parse through stack freeing each node */ - node = sk->next; - while (node && sk->num > 1) { - WOLFSSL_STACK* tmp = node; - node = node->next; - - if (f) - f(tmp->data.dir_hash); - else - wolfSSL_BY_DIR_HASH_free(tmp->data.dir_hash); - tmp->data.dir_hash = NULL; - XFREE(tmp, NULL, DYNAMIC_TYPE_OPENSSL); - sk->num -= 1; - } - - /* free head of stack */ - if (sk->num == 1) { - if (f) - f(sk->data.dir_hash); - else - wolfSSL_BY_DIR_HASH_free(sk->data.dir_hash); - sk->data.dir_hash = NULL; - } - XFREE(sk, NULL, DYNAMIC_TYPE_OPENSSL); -} -/* release all contents in stack, and then release stack itself */ -void wolfSSL_sk_BY_DIR_HASH_free(WOLF_STACK_OF(WOLFSSL_BY_DIR_HASH) *sk) -{ - wolfSSL_sk_BY_DIR_HASH_pop_free(sk, NULL); -} -/* Adds the WOLFSSL_BY_DIR_HASH to the stack "sk". "sk" takes control of "in" and - * tries to free it when the stack is free'd. - * - * return 1 on success 0 on fail - */ -int wolfSSL_sk_BY_DIR_HASH_push(WOLF_STACK_OF(WOLFSSL_BY_DIR_HASH)* sk, - WOLFSSL_BY_DIR_HASH* in) -{ - WOLFSSL_STACK* node; - - WOLFSSL_ENTER("wolfSSL_sk_BY_DIR_HASH_push"); - - if (sk == NULL || in == NULL) { - return WOLFSSL_FAILURE; - } - - /* no previous values in stack */ - if (sk->data.dir_hash == NULL) { - sk->data.dir_hash = in; - sk->num += 1; - return WOLFSSL_SUCCESS; - } - - /* stack already has value(s) create a new node and add more */ - node = (WOLFSSL_STACK*)XMALLOC(sizeof(WOLFSSL_STACK), NULL, - DYNAMIC_TYPE_OPENSSL); - if (node == NULL) { - WOLFSSL_MSG("Memory error"); - return WOLFSSL_FAILURE; - } - XMEMSET(node, 0, sizeof(WOLFSSL_STACK)); - - /* push new obj onto head of stack */ - node->data.dir_hash = sk->data.dir_hash; - node->next = sk->next; - node->type = sk->type; - sk->next = node; - sk->data.dir_hash = in; - sk->num += 1; - - return WOLFSSL_SUCCESS; -} -/* create an instance of WOLFSSL_BY_DIR_entry structure */ -WOLFSSL_BY_DIR_entry* wolfSSL_BY_DIR_entry_new(void) -{ - WOLFSSL_BY_DIR_entry* entry; - - WOLFSSL_ENTER("wolfSSL_BY_DIR_entry_new"); - - entry = (WOLFSSL_BY_DIR_entry*)XMALLOC(sizeof(WOLFSSL_BY_DIR_entry), NULL, - DYNAMIC_TYPE_OPENSSL); - - if (entry) { - XMEMSET(entry, 0, sizeof(WOLFSSL_BY_DIR_entry)); - } - return entry; -} -/* release a WOLFSSL_BY_DIR_entry resource */ -void wolfSSL_BY_DIR_entry_free(WOLFSSL_BY_DIR_entry* entry) -{ - WOLFSSL_ENTER("wolfSSL_BY_DIR_entry_free"); - - if (entry == NULL) - return; - - if (entry->hashes) { - wolfSSL_sk_BY_DIR_HASH_free(entry->hashes); - } - - if (entry->dir_name != NULL) { - XFREE(entry->dir_name, NULL, DYNAMIC_TYPE_OPENSSL); - } - - XFREE(entry, NULL, DYNAMIC_TYPE_OPENSSL); -} - -WOLFSSL_STACK* wolfSSL_sk_BY_DIR_entry_new_null(void) -{ - WOLFSSL_STACK* sk = wolfSSL_sk_new_node(NULL); - - WOLFSSL_ENTER("wolfSSL_sk_BY_DIR_entry_new_null"); - - if (sk) { - sk->type = STACK_TYPE_BY_DIR_entry; - } - return sk; -} -/* return a number of WOLFSSL_BY_DIR_entry in stack */ -int wolfSSL_sk_BY_DIR_entry_num(const WOLF_STACK_OF(WOLFSSL_BY_DIR_entry) *sk) -{ - WOLFSSL_ENTER("wolfSSL_sk_BY_DIR_entry_num"); - - if (sk == NULL) - return -1; - return (int)sk->num; -} -/* return WOLFSSL_BY_DIR_entry instance at i */ -WOLFSSL_BY_DIR_entry* wolfSSL_sk_BY_DIR_entry_value( - const WOLF_STACK_OF(WOLFSSL_BY_DIR_entry) *sk, int i) -{ - WOLFSSL_ENTER("wolfSSL_sk_BY_DIR_entry_value"); - - for (; sk != NULL && i > 0; i--) - sk = sk->next; - - if (i != 0 || sk == NULL) - return NULL; - return sk->data.dir_entry; -} -/* pop WOLFSSL_BY_DIR_entry instance first, and remove its node from stack */ -WOLFSSL_BY_DIR_entry* wolfSSL_sk_BY_DIR_entry_pop( - WOLF_STACK_OF(WOLFSSL_BY_DIR_entry)* sk) -{ - WOLFSSL_STACK* node; - WOLFSSL_BY_DIR_entry* entry; - - WOLFSSL_ENTER("wolfSSL_sk_BY_DIR_entry_pop"); - - if (sk == NULL) { - return NULL; - } - - node = sk->next; - entry = sk->data.dir_entry; - - if (node != NULL) { /* update sk and remove node from stack */ - sk->data.dir_entry = node->data.dir_entry; - sk->next = node->next; - wolfSSL_sk_free_node(node); - } - else { /* last x509 in stack */ - sk->data.dir_entry = NULL; - } - - if (sk->num > 0) { - sk->num -= 1; - } - - return entry; -} -/* release all contents in stack, and then release stack itself */ -/* it uses function when it is passed */ -void wolfSSL_sk_BY_DIR_entry_pop_free(WOLF_STACK_OF(WOLFSSL_BY_DIR_entry)* sk, - void (*f) (WOLFSSL_BY_DIR_entry*)) -{ - WOLFSSL_STACK* node; - - WOLFSSL_ENTER("wolfSSL_sk_BY_DIR_entry_pop_free"); - - if (sk == NULL) { - return; - } - - /* parse through stack freeing each node */ - node = sk->next; - while (node && sk->num > 1) { - WOLFSSL_STACK* tmp = node; - node = node->next; - - if (f) - f(tmp->data.dir_entry); - else - wolfSSL_BY_DIR_entry_free(tmp->data.dir_entry); - tmp->data.dir_entry = NULL; - XFREE(tmp, NULL, DYNAMIC_TYPE_OPENSSL); - sk->num -= 1; - } - - /* free head of stack */ - if (sk->num == 1) { - if (f) - f(sk->data.dir_entry); - else - wolfSSL_BY_DIR_entry_free(sk->data.dir_entry); - sk->data.dir_entry = NULL; - } - XFREE(sk, NULL, DYNAMIC_TYPE_OPENSSL); -} -/* release all contents in stack, and then release stack itself */ -void wolfSSL_sk_BY_DIR_entry_free(WOLF_STACK_OF(wolfSSL_BY_DIR_entry) *sk) -{ - wolfSSL_sk_BY_DIR_entry_pop_free(sk, NULL); -} - -/* Adds the wolfSSL_BY_DIR_entry to the stack "sk". "sk" takes control of "in" and - * tries to free it when the stack is free'd. - * - * return 1 on success 0 on fail - */ -int wolfSSL_sk_BY_DIR_entry_push(WOLF_STACK_OF(WOLFSSL_BY_DIR_entry)* sk, - WOLFSSL_BY_DIR_entry* in) -{ - WOLFSSL_STACK* node; - - if (sk == NULL || in == NULL) { - return WOLFSSL_FAILURE; - } - - /* no previous values in stack */ - if (sk->data.dir_entry == NULL) { - sk->data.dir_entry = in; - sk->num += 1; - return WOLFSSL_SUCCESS; - } - - /* stack already has value(s) create a new node and add more */ - node = (WOLFSSL_STACK*)XMALLOC(sizeof(WOLFSSL_STACK), NULL, - DYNAMIC_TYPE_OPENSSL); - if (node == NULL) { - WOLFSSL_MSG("Memory error"); - return WOLFSSL_FAILURE; - } - XMEMSET(node, 0, sizeof(WOLFSSL_STACK)); - - /* push new obj onto head of stack */ - node->data.dir_entry = sk->data.dir_entry; - node->next = sk->next; - node->type = sk->type; - sk->next = node; - sk->data.dir_entry = in; - sk->num += 1; - - return WOLFSSL_SUCCESS; -} - -#endif /* OPENSSL_ALL */ - int wolfSSL_sk_X509_INFO_num(const WOLF_STACK_OF(WOLFSSL_X509_INFO) *sk) { WOLFSSL_ENTER("wolfSSL_sk_X509_INFO_num"); diff --git a/tests/api.c b/tests/api.c index 8f7b7121b..5f38b6446 100644 --- a/tests/api.c +++ b/tests/api.c @@ -25732,138 +25732,6 @@ static void test_wolfSSL_X509_NAME(void) #endif /* defined(OPENSSL_EXTRA) && !defined(NO_DES3) */ } -static void test_wolfSSL_sk_X509_BY_DIR_HASH(void) -{ -#if defined(OPENSSL_ALL) && !defined(NO_FILESYSTEM) && !defined(NO_WOLFSSL_DIR) - STACK_OF(WOLFSSL_BY_DIR_HASH) *hash_stack; - WOLFSSL_BY_DIR_HASH *hash1; - WOLFSSL_BY_DIR_HASH *hash2; - WOLFSSL_BY_DIR_HASH *h; - const unsigned long dummy_hash[2] = { - 0x12345678, - 0x9abcdef0 - }; - int i, num; - - printf(testingFmt, "test_wolfSSL_sk_X509_BY_DIR_HASH"); - - /* new */ - AssertNotNull(hash1 = wolfSSL_BY_DIR_HASH_new()); - hash1->hash_value = dummy_hash[0]; - - AssertNotNull(hash2 = wolfSSL_BY_DIR_HASH_new()); - hash2->hash_value = dummy_hash[1]; - - AssertNotNull(hash_stack = wolfSSL_sk_BY_DIR_HASH_new_null()); - - /* push */ - AssertIntEQ(wolfSSL_sk_BY_DIR_HASH_push(NULL, NULL), - WOLFSSL_FAILURE); - AssertIntEQ(wolfSSL_sk_BY_DIR_HASH_push(NULL, hash1), - WOLFSSL_FAILURE); - AssertIntEQ(wolfSSL_sk_BY_DIR_HASH_push(hash_stack, NULL), - WOLFSSL_FAILURE); - - AssertIntEQ(wolfSSL_sk_BY_DIR_HASH_push(hash_stack, hash1), - WOLFSSL_SUCCESS); - AssertIntEQ(wolfSSL_sk_BY_DIR_HASH_push(hash_stack, - hash2), WOLFSSL_SUCCESS); - /* num and value */ - AssertIntEQ((num = wolfSSL_sk_BY_DIR_HASH_num(hash_stack)), 2); - for (i = 0; i < num; i++) { - AssertNotNull(h = wolfSSL_sk_BY_DIR_HASH_value(hash_stack, i)); - AssertTrue(h->hash_value == dummy_hash[num - i - 1]); - } - - /* pop */ - AssertNotNull(h = wolfSSL_sk_BY_DIR_HASH_pop(hash_stack)); - AssertIntEQ((num = wolfSSL_sk_BY_DIR_HASH_num(hash_stack)), 1); - - /* find */ - AssertIntEQ(wolfSSL_sk_BY_DIR_HASH_find(NULL, NULL), - WOLFSSL_FAILURE); - AssertIntEQ(wolfSSL_sk_BY_DIR_HASH_find(NULL, hash1), - WOLFSSL_FAILURE); - AssertIntEQ(wolfSSL_sk_BY_DIR_HASH_find(hash_stack, NULL), - WOLFSSL_FAILURE); - - AssertIntEQ(wolfSSL_sk_BY_DIR_HASH_push(hash_stack, hash2), - 1); - - /* free */ - wolfSSL_sk_BY_DIR_HASH_free(hash_stack); - - printf(resultFmt, passed); -#endif -} - - -static void test_wolfSSL_sk_X509_BY_DIR(void) -{ -#if defined(OPENSSL_ALL) && !defined(NO_FILESYSTEM) && !defined(NO_WOLFSSL_DIR) - STACK_OF(WOLFSSL_BY_DIR_entry) *entry_stack; - WOLFSSL_BY_DIR_entry *entry1; - WOLFSSL_BY_DIR_entry *entry2; - WOLFSSL_BY_DIR_entry *ent; - const char* dummy_dir[2] = { - "/hoge/hoge/foo/foo", - "/foo1/hoge2/abc/defg" - }; - int i, num; - size_t len; - - printf(testingFmt, "test_wolfSSL_X509_sk_BY_DIR"); - - /* new */ - AssertNotNull(entry1 = wolfSSL_BY_DIR_entry_new()); - len = XSTRLEN(dummy_dir[0]); - entry1->dir_name = (char*)XMALLOC(len + 1, NULL, DYNAMIC_TYPE_OPENSSL); - AssertNotNull(entry1->dir_name); - XMEMSET(entry1->dir_name, 0, len + 1); - XSTRNCPY(entry1->dir_name, dummy_dir[0], len + 1); - - AssertNotNull(entry2 = wolfSSL_BY_DIR_entry_new()); - len = XSTRLEN(dummy_dir[1]); - entry2->dir_name = (char*)XMALLOC(len + 1, NULL, DYNAMIC_TYPE_OPENSSL); - AssertNotNull(entry2->dir_name); - XMEMSET(entry2->dir_name, 0, len + 1); - XSTRNCPY(entry2->dir_name, dummy_dir[1], len + 1); - - AssertNotNull(entry_stack = wolfSSL_sk_BY_DIR_entry_new_null()); - - /* push */ - AssertIntEQ(wolfSSL_sk_BY_DIR_entry_push(NULL, NULL), - WOLFSSL_FAILURE); - AssertIntEQ(wolfSSL_sk_BY_DIR_entry_push(NULL, entry1), - WOLFSSL_FAILURE); - AssertIntEQ(wolfSSL_sk_BY_DIR_entry_push(entry_stack, NULL), - WOLFSSL_FAILURE); - - AssertIntEQ(wolfSSL_sk_BY_DIR_entry_push(entry_stack, entry1), - WOLFSSL_SUCCESS); - AssertIntEQ(wolfSSL_sk_BY_DIR_entry_push(entry_stack, - entry2), WOLFSSL_SUCCESS); - /* num and value */ - AssertIntEQ((num = wolfSSL_sk_BY_DIR_entry_num(entry_stack)), 2); - for (i = 0; i < num; i++) { - AssertNotNull(ent = wolfSSL_sk_BY_DIR_entry_value(entry_stack, i)); - len = XSTRLEN(dummy_dir[num - i - 1]); - AssertTrue(XSTRLEN(ent->dir_name) == len); - AssertIntEQ(XSTRNCMP(ent->dir_name, dummy_dir[num - i - 1], len), 0); - } - - /* pop */ - AssertNotNull(ent = wolfSSL_sk_BY_DIR_entry_pop(entry_stack)); - AssertIntEQ((len = wolfSSL_sk_BY_DIR_entry_num(entry_stack)), 1); - wolfSSL_BY_DIR_entry_free(ent); - - /* free */ - wolfSSL_sk_BY_DIR_entry_free(entry_stack); - - printf(resultFmt, passed); -#endif -} - #ifndef NO_BIO static void test_wolfSSL_X509_INFO(void) { @@ -28177,12 +28045,10 @@ static void test_wolfSSL_X509_LOOKUP_ctrl_hash_dir(void) char *p; X509_STORE* str; X509_LOOKUP* lookup; - WOLFSSL_BY_DIR_entry *dir; WOLFSSL_STACK* sk = NULL; - int num = 0, len, total_len, i; + int len, total_len, i; (void) sk; - (void) num; printf(testingFmt, "test_wolfSSL_X509_LOOKUP_ctrl_hash_dir()"); @@ -28203,13 +28069,6 @@ static void test_wolfSSL_X509_LOOKUP_ctrl_hash_dir(void) AssertIntEQ(X509_LOOKUP_ctrl(lookup, X509_L_ADD_DIR, "./", SSL_FILETYPE_PEM,NULL), 1); AssertNotNull(sk = lookup->dirs->dir_entry); - AssertIntEQ((num = wolfSSL_sk_BY_DIR_entry_num(sk)), 1); - - dir = wolfSSL_sk_BY_DIR_entry_value(sk, 0); - AssertIntEQ(XSTRLEN((const char*)dir->dir_name), XSTRLEN("./")); - AssertIntEQ(XMEMCMP(dir->dir_name, "./", - XSTRLEN((const char*)dir->dir_name)), 0); - /* free store */ X509_STORE_free(str); @@ -28230,14 +28089,6 @@ static void test_wolfSSL_X509_LOOKUP_ctrl_hash_dir(void) AssertIntEQ(X509_LOOKUP_ctrl(lookup, X509_L_ADD_DIR, CertCrl_path, SSL_FILETYPE_PEM,NULL), 1); AssertNotNull(sk = lookup->dirs->dir_entry); - AssertIntEQ((num = wolfSSL_sk_BY_DIR_entry_num(sk)), MAX_DIR); - - for(i = 0; idir_name), XSTRLEN(paths[i])); - AssertIntEQ(XMEMCMP(dir->dir_name, paths[i], - XSTRLEN((const char*)dir->dir_name)), 0); - } X509_STORE_free(str); @@ -42057,8 +41908,6 @@ void ApiTest(void) #ifndef NO_BIO test_wolfSSL_X509_INFO(); #endif - test_wolfSSL_sk_X509_BY_DIR_HASH(); - test_wolfSSL_sk_X509_BY_DIR(); test_wolfSSL_X509_subject_name_hash(); test_wolfSSL_X509_issuer_name_hash(); test_wolfSSL_X509_check_host(); diff --git a/wolfssl/internal.h b/wolfssl/internal.h index 14a95d165..2ac3904b6 100644 --- a/wolfssl/internal.h +++ b/wolfssl/internal.h @@ -4824,6 +4824,37 @@ WOLFSSL_LOCAL void FreeKey(WOLFSSL* ssl, int type, void** pKey); WOLFSSL_LOCAL int LoadCrlCertByIssuer(WOLFSSL_X509_STORE* store, X509_NAME* issuer, int Type); #endif +#if defined(OPENSSL_ALL) && !defined(NO_FILESYSTEM) && !defined(NO_WOLFSSL_DIR) +WOLFSSL_LOCAL WOLFSSL_BY_DIR_HASH* wolfSSL_BY_DIR_HASH_new(void); +WOLFSSL_LOCAL void wolfSSL_BY_DIR_HASH_free(WOLFSSL_BY_DIR_HASH* dir_hash); +WOLFSSL_LOCAL WOLFSSL_STACK* wolfSSL_sk_BY_DIR_HASH_new_null(void); +WOLFSSL_LOCAL int wolfSSL_sk_BY_DIR_HASH_find( + WOLF_STACK_OF(WOLFSSL_BY_DIR_HASH)* sk, const WOLFSSL_BY_DIR_HASH* toFind); +WOLFSSL_LOCAL int wolfSSL_sk_BY_DIR_HASH_num(const WOLF_STACK_OF(WOLFSSL_BY_DIR_HASH) *sk); +WOLFSSL_LOCAL WOLFSSL_BY_DIR_HASH* wolfSSL_sk_BY_DIR_HASH_value( + const WOLF_STACK_OF(WOLFSSL_BY_DIR_HASH) *sk, int i); +WOLFSSL_LOCAL WOLFSSL_BY_DIR_HASH* wolfSSL_sk_BY_DIR_HASH_pop( + WOLF_STACK_OF(WOLFSSL_BY_DIR_HASH)* sk); +WOLFSSL_LOCAL void wolfSSL_sk_BY_DIR_HASH_pop_free(WOLF_STACK_OF(WOLFSSL_BY_DIR_HASH)* sk, + void (*f) (WOLFSSL_BY_DIR_HASH*)); +WOLFSSL_LOCAL void wolfSSL_sk_BY_DIR_HASH_free(WOLF_STACK_OF(WOLFSSL_BY_DIR_HASH) *sk); +WOLFSSL_LOCAL int wolfSSL_sk_BY_DIR_HASH_push(WOLF_STACK_OF(WOLFSSL_BY_DIR_HASH)* sk, + WOLFSSL_BY_DIR_HASH* in); +/* WOLFSSL_BY_DIR_entry stuff */ +WOLFSSL_LOCAL WOLFSSL_BY_DIR_entry* wolfSSL_BY_DIR_entry_new(void); +WOLFSSL_LOCAL void wolfSSL_BY_DIR_entry_free(WOLFSSL_BY_DIR_entry* entry); +WOLFSSL_LOCAL WOLFSSL_STACK* wolfSSL_sk_BY_DIR_entry_new_null(void); +WOLFSSL_LOCAL int wolfSSL_sk_BY_DIR_entry_num(const WOLF_STACK_OF(WOLFSSL_BY_DIR_entry) *sk); +WOLFSSL_LOCAL WOLFSSL_BY_DIR_entry* wolfSSL_sk_BY_DIR_entry_value( + const WOLF_STACK_OF(WOLFSSL_BY_DIR_entry) *sk, int i); +WOLFSSL_LOCAL WOLFSSL_BY_DIR_entry* wolfSSL_sk_BY_DIR_entry_pop( + WOLF_STACK_OF(WOLFSSL_BY_DIR_entry)* sk); +WOLFSSL_LOCAL void wolfSSL_sk_BY_DIR_entry_pop_free(WOLF_STACK_OF(wolfSSL_BY_DIR_entry)* sk, + void (*f) (WOLFSSL_BY_DIR_entry*)); +WOLFSSL_LOCAL void wolfSSL_sk_BY_DIR_entry_free(WOLF_STACK_OF(wolfSSL_BY_DIR_entry) *sk); +WOLFSSL_LOCAL int wolfSSL_sk_BY_DIR_entry_push(WOLF_STACK_OF(wolfSSL_BY_DIR_entry)* sk, + WOLFSSL_BY_DIR_entry* in); +#endif /* OPENSSL_ALL && !NO_FILESYSTEM && !NO_WOLFSSL_DIR */ #ifdef __cplusplus } /* extern "C" */ diff --git a/wolfssl/ssl.h b/wolfssl/ssl.h index 22ea2f5a4..961b1fb1a 100644 --- a/wolfssl/ssl.h +++ b/wolfssl/ssl.h @@ -3851,38 +3851,6 @@ WOLFSSL_API int wolfSSL_sk_CONF_VALUE_push(WOLF_STACK_OF(WOLFSSL_CONF_VALUE)* sk WOLFSSL_CONF_VALUE* val); #endif /* OPENSSL_ALL || HAVE_STUNNEL || WOLFSSL_NGINX || WOLFSSL_HAPROXY || OPENSSL_EXTRA || HAVE_LIGHTY */ -#if defined(OPENSSL_ALL) && !defined(NO_FILESYSTEM) && !defined(NO_WOLFSSL_DIR) -WOLFSSL_API WOLFSSL_BY_DIR_HASH* wolfSSL_BY_DIR_HASH_new(void); -WOLFSSL_API void wolfSSL_BY_DIR_HASH_free(WOLFSSL_BY_DIR_HASH* dir_hash); -WOLFSSL_API WOLFSSL_STACK* wolfSSL_sk_BY_DIR_HASH_new_null(void); -WOLFSSL_API int wolfSSL_sk_BY_DIR_HASH_find( - WOLF_STACK_OF(WOLFSSL_BY_DIR_HASH)* sk, const WOLFSSL_BY_DIR_HASH* toFind); -WOLFSSL_API int wolfSSL_sk_BY_DIR_HASH_num(const WOLF_STACK_OF(WOLFSSL_BY_DIR_HASH) *sk); -WOLFSSL_API WOLFSSL_BY_DIR_HASH* wolfSSL_sk_BY_DIR_HASH_value( - const WOLF_STACK_OF(WOLFSSL_BY_DIR_HASH) *sk, int i); -WOLFSSL_API WOLFSSL_BY_DIR_HASH* wolfSSL_sk_BY_DIR_HASH_pop( - WOLF_STACK_OF(WOLFSSL_BY_DIR_HASH)* sk); -WOLFSSL_API void wolfSSL_sk_BY_DIR_HASH_pop_free(WOLF_STACK_OF(WOLFSSL_BY_DIR_HASH)* sk, - void (*f) (WOLFSSL_BY_DIR_HASH*)); -WOLFSSL_API void wolfSSL_sk_BY_DIR_HASH_free(WOLF_STACK_OF(WOLFSSL_BY_DIR_HASH) *sk); -WOLFSSL_API int wolfSSL_sk_BY_DIR_HASH_push(WOLF_STACK_OF(WOLFSSL_BY_DIR_HASH)* sk, - WOLFSSL_BY_DIR_HASH* in); -/* WOLFSSL_BY_DIR_entry stuff */ -WOLFSSL_API WOLFSSL_BY_DIR_entry* wolfSSL_BY_DIR_entry_new(void); -WOLFSSL_API void wolfSSL_BY_DIR_entry_free(WOLFSSL_BY_DIR_entry* entry); -WOLFSSL_API WOLFSSL_STACK* wolfSSL_sk_BY_DIR_entry_new_null(void); -WOLFSSL_API int wolfSSL_sk_BY_DIR_entry_num(const WOLF_STACK_OF(WOLFSSL_BY_DIR_entry) *sk); -WOLFSSL_API WOLFSSL_BY_DIR_entry* wolfSSL_sk_BY_DIR_entry_value( - const WOLF_STACK_OF(WOLFSSL_BY_DIR_entry) *sk, int i); -WOLFSSL_API WOLFSSL_BY_DIR_entry* wolfSSL_sk_BY_DIR_entry_pop( - WOLF_STACK_OF(WOLFSSL_BY_DIR_entry)* sk); -WOLFSSL_API void wolfSSL_sk_BY_DIR_entry_pop_free(WOLF_STACK_OF(wolfSSL_BY_DIR_entry)* sk, - void (*f) (WOLFSSL_BY_DIR_entry*)); -WOLFSSL_API void wolfSSL_sk_BY_DIR_entry_free(WOLF_STACK_OF(wolfSSL_BY_DIR_entry) *sk); -WOLFSSL_API int wolfSSL_sk_BY_DIR_entry_push(WOLF_STACK_OF(wolfSSL_BY_DIR_entry)* sk, - WOLFSSL_BY_DIR_entry* in); -#endif /* OPENSSL_ALL && !NO_FILESYSTEM && !NO_WOLFSSL_DIR */ - #if defined(OPENSSL_EXTRA) || defined(WOLFSSL_WPAS_SMALL) WOLFSSL_API WOLFSSL_ASN1_BIT_STRING* wolfSSL_ASN1_BIT_STRING_new(void); WOLFSSL_API void wolfSSL_ASN1_BIT_STRING_free(WOLFSSL_ASN1_BIT_STRING*); From c5327866a4800c580d72bf1724b84a89e9fcf035 Mon Sep 17 00:00:00 2001 From: Hideki Miyazaki Date: Fri, 12 Mar 2021 08:35:39 +0900 Subject: [PATCH 11/16] addressed review comments part 3 --- src/internal.c | 1 + src/ssl.c | 16 ++++++++-------- wolfssl/internal.h | 15 +++++++++++++++ wolfssl/ssl.h | 20 ++++---------------- 4 files changed, 28 insertions(+), 24 deletions(-) diff --git a/src/internal.c b/src/internal.c index 74e0dd2f2..adf29955a 100644 --- a/src/internal.c +++ b/src/internal.c @@ -10735,6 +10735,7 @@ int LoadCrlCertByIssuer(WOLFSSL_X509_STORE* store, X509_NAME* issuer, int type) if (type == X509_LU_CRL) { if (wc_LockMutex(&lookup->dirs->lock) != 0) { WOLFSSL_MSG("wc_LockMutex cdir Lock error"); + XFREE(filename, NULL, DYNAMIC_TYPE_OPENSSL); return BAD_MUTEX_E; } if (ph == NULL) { diff --git a/src/ssl.c b/src/ssl.c index 0b73fe825..b08fe0967 100644 --- a/src/ssl.c +++ b/src/ssl.c @@ -24836,13 +24836,12 @@ WOLFSSL_X509_LOOKUP_METHOD* wolfSSL_X509_LOOKUP_file(void) /* @param argl file type, either WOLFSSL_FILETYPE_PEM or */ /* WOLFSSL_FILETYPE_ASN1 */ /* @return WOLFSSL_SUCCESS on successful, othewise negative or zero */ -static int x509AddCertDir(void *p, const char *argc, long argl) +static int x509AddCertDir(WOLFSSL_BY_DIR *ctx, const char *argc, long argl) { WOLFSSL_ENTER("x509AddCertDir"); (void)argl; #if defined(OPENSSL_ALL) && !defined(NO_FILESYSTEM) && !defined(NO_WOLFSSL_DIR) - WOLFSSL_BY_DIR *ctx = (WOLFSSL_BY_DIR*)p; WOLFSSL_BY_DIR_entry *entry; size_t pathLen; int i, num; @@ -24855,8 +24854,9 @@ static int x509AddCertDir(void *p, const char *argc, long argl) pathLen = 0; c = argc; - /* zero length */ - if (c == NULL || *c == '\0') return WOLFSSL_FAILURE; + /* sanity check, zero length */ + if (ctx == NULL || c == NULL || *c == '\0') + return WOLFSSL_FAILURE; #ifdef WOLFSSL_SMALL_STACK buf = (char*)XMALLOC(MAX_FILENAME_SZ, NULL, DYNAMIC_TYPE_OPENSSL); @@ -24948,7 +24948,7 @@ static int x509AddCertDir(void *p, const char *argc, long argl) return WOLFSSL_SUCCESS; #else - (void)p; + (void)ctx; (void)argc; return WOLFSSL_NOT_IMPLEMENTED; #endif @@ -41641,17 +41641,17 @@ static int wolfSSL_ASN1_STRING_canon(WOLFSSL_ASN1_STRING* asn_out, /* trimming spaces at the head and tail */ dst--; - for (; (len > 0 && XISSPACE(*dst));len--) { + for (; (len > 0 && XISSPACE(*dst)); len--) { dst--; } - for (; (len > 0 && XISSPACE(*src));len--) { + for (; (len > 0 && XISSPACE(*src)); len--) { src++; } /* point to the start */ dst = asn_out->data; - for (i = 0; i < len;dst++, i++) { + for (i = 0; i < len; dst++, i++) { if (!XISASCII(*src)) { /* keep non-ascii code */ *dst = *src++; diff --git a/wolfssl/internal.h b/wolfssl/internal.h index 2ac3904b6..14fa0dc90 100644 --- a/wolfssl/internal.h +++ b/wolfssl/internal.h @@ -1684,6 +1684,21 @@ WOLFSSL_LOCAL ProtocolVersion MakeTLSv1_3(void); #endif #endif +struct WOLFSSL_BY_DIR_HASH { + unsigned long hash_value; + int last_suffix; +}; + +struct WOLFSSL_BY_DIR_entry { + char* dir_name; + int dir_type; + WOLF_STACK_OF(WOLFSSL_BY_DIR_HASH) *hashes; +}; + +struct WOLFSSL_BY_DIR { + WOLF_STACK_OF(WOLFSSL_BY_DIR_entry) *dir_entry; + wolfSSL_Mutex lock; /* dir list lock */ +}; /* wolfSSL method type */ struct WOLFSSL_METHOD { diff --git a/wolfssl/ssl.h b/wolfssl/ssl.h index 961b1fb1a..5b6c26687 100644 --- a/wolfssl/ssl.h +++ b/wolfssl/ssl.h @@ -143,6 +143,10 @@ typedef struct WOLFSSL_X509_STORE_CTX WOLFSSL_X509_STORE_CTX; typedef int (*WOLFSSL_X509_STORE_CTX_verify_cb)(int, WOLFSSL_X509_STORE_CTX *); +typedef struct WOLFSSL_BY_DIR_HASH WOLFSSL_BY_DIR_HASH; +typedef struct WOLFSSL_BY_DIR_entry WOLFSSL_BY_DIR_entry; +typedef struct WOLFSSL_BY_DIR WOLFSSL_BY_DIR; + /* redeclare guard */ #define WOLFSSL_TYPES_DEFINED @@ -279,22 +283,6 @@ struct WOLFSSL_X509V3_CTX { WOLFSSL_X509* x509; }; -struct WOLFSSL_BY_DIR_HASH { - unsigned long hash_value; - int last_suffix; -}; - -struct WOLFSSL_BY_DIR_entry { - char* dir_name; - int dir_type; - WOLF_STACK_OF(WOLFSSL_BY_DIR_HASH) *hashes; -}; - -struct WOLFSSL_BY_DIR { - WOLF_STACK_OF(WOLFSSL_BY_DIR_entry) *dir_entry; - wolfSSL_Mutex lock; /* dir list lock */ -}; - struct WOLFSSL_ASN1_OBJECT { void* heap; const unsigned char* obj; From 7b81ff1bc6b90625276067d71ed25a48676ea047 Mon Sep 17 00:00:00 2001 From: Hideki Miyazaki Date: Fri, 12 Mar 2021 09:03:35 +0900 Subject: [PATCH 12/16] fixed api testing for hash dir --- tests/api.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/tests/api.c b/tests/api.c index 5f38b6446..7cecf86e4 100644 --- a/tests/api.c +++ b/tests/api.c @@ -28068,7 +28068,10 @@ static void test_wolfSSL_X509_LOOKUP_ctrl_hash_dir(void) AssertNotNull(lookup = X509_STORE_add_lookup(str, X509_LOOKUP_file())); AssertIntEQ(X509_LOOKUP_ctrl(lookup, X509_L_ADD_DIR, "./", SSL_FILETYPE_PEM,NULL), 1); + #if defined(WOLFSSL_INT_H) + /* only available when including internal.h */ AssertNotNull(sk = lookup->dirs->dir_entry); + #endif /* free store */ X509_STORE_free(str); @@ -28088,7 +28091,10 @@ static void test_wolfSSL_X509_LOOKUP_ctrl_hash_dir(void) AssertNotNull(lookup = X509_STORE_add_lookup(str, X509_LOOKUP_file())); AssertIntEQ(X509_LOOKUP_ctrl(lookup, X509_L_ADD_DIR, CertCrl_path, SSL_FILETYPE_PEM,NULL), 1); + #if defined(WOLFSSL_INT_H) + /* only available when including internal.h */ AssertNotNull(sk = lookup->dirs->dir_entry); + #endif X509_STORE_free(str); From ffa6a80725b174c03343edf495b266b6b498db85 Mon Sep 17 00:00:00 2001 From: Hideki Miyazaki Date: Thu, 18 Mar 2021 08:12:19 +0900 Subject: [PATCH 13/16] addressed review comments part 4 --- src/crl.c | 2 +- src/internal.c | 23 +++++++++++++---------- wolfcrypt/src/asn.c | 2 +- wolfcrypt/src/wc_port.c | 9 ++++----- wolfssl/internal.h | 2 +- wolfssl/ssl.h | 3 --- wolfssl/wolfcrypt/wc_port.h | 4 ++++ 7 files changed, 24 insertions(+), 21 deletions(-) diff --git a/src/crl.c b/src/crl.c index fd96c4390..cb99ec1c7 100644 --- a/src/crl.c +++ b/src/crl.c @@ -369,7 +369,7 @@ int CheckCertCRL(WOLFSSL_CRL* crl, DecodedCert* cert) !defined(NO_FILESYSTEM) && !defined(NO_WOLFSSL_DIR) if (foundEntry == 0) { if (crl->cm->x509_store_p != NULL) { - ret = LoadCrlCertByIssuer(crl->cm->x509_store_p, + ret = LoadCertByIssuer(crl->cm->x509_store_p, (WOLFSSL_X509_NAME*)cert->issuerName, X509_LU_CRL); if (ret == WOLFSSL_SUCCESS) { /* try again */ diff --git a/src/internal.c b/src/internal.c index adf29955a..58ce4c826 100644 --- a/src/internal.c +++ b/src/internal.c @@ -10593,11 +10593,11 @@ static void FreeProcPeerCertArgs(WOLFSSL* ssl, void* pArgs) /* @param issuer a pointer to X509_NAME that presents an issuer */ /* @param type X509_LU_X509 or X509_LU_CRL */ /* @return WOLFSSL_SUCCESS on successful, otherwise WOLFSSL_FAILURE */ -int LoadCrlCertByIssuer(WOLFSSL_X509_STORE* store, X509_NAME* issuer, int type) +int LoadCertByIssuer(WOLFSSL_X509_STORE* store, X509_NAME* issuer, int type) { const int MAX_SUFFIX = 10;/* The number comes from CA_TABLE_SIZE=10 */ int ret = WOLFSSL_SUCCESS; - WOLFSSL_X509_LOOKUP* lookup = &store->lookup; + WOLFSSL_X509_LOOKUP* lookup; WOLFSSL_BY_DIR_entry* entry; WOLFSSL_BY_DIR_HASH hash_tmp; WOLFSSL_BY_DIR_HASH* ph = NULL; @@ -10611,11 +10611,14 @@ int LoadCrlCertByIssuer(WOLFSSL_X509_STORE* store, X509_NAME* issuer, int type) int retHash = NOT_COMPILED_IN; byte dgt[WC_MAX_DIGEST_SIZE]; - WOLFSSL_ENTER("LoadCrlCertByIssuer"); + WOLFSSL_ENTER("LoadCertByIssuer"); /* sanity check */ - if (store == NULL || issuer == NULL || lookup->dirs == NULL || - lookup->type != 1 || (type != X509_LU_X509 && type != X509_LU_CRL)) { + if (store == NULL || issuer == NULL || (type != X509_LU_X509 && type != X509_LU_CRL)) { + return WOLFSSL_FAILURE; + } + lookup = &store->lookup; + if (lookup->dirs == NULL || lookup->type != 1) { return WOLFSSL_FAILURE; } @@ -10766,7 +10769,7 @@ int LoadCrlCertByIssuer(WOLFSSL_X509_STORE* store, X509_NAME* issuer, int type) (void) i; ret = WOLFSSL_NOT_IMPLEMENTED; #endif - WOLFSSL_LEAVE("LoadCrlCertByIssuer", ret); + WOLFSSL_LEAVE("LoadCertByIssuer", ret); return ret; } @@ -11305,11 +11308,11 @@ int ProcessPeerCerts(WOLFSSL* ssl, byte* input, word32* inOutIdx, if (ret == ASN_NO_SIGNER_E) { WOLFSSL_MSG("try to load certificate if hash dir is set"); if (ssl->ctx->x509_store_pt != NULL) { - ret = LoadCrlCertByIssuer(ssl->ctx->x509_store_pt, + ret = LoadCertByIssuer(ssl->ctx->x509_store_pt, (WOLFSSL_X509_NAME*)args->dCert->issuerName, X509_LU_X509); } else { - ret = LoadCrlCertByIssuer(&ssl->ctx->x509_store, + ret = LoadCertByIssuer(&ssl->ctx->x509_store, (WOLFSSL_X509_NAME*)args->dCert->issuerName, X509_LU_X509); } @@ -11523,11 +11526,11 @@ int ProcessPeerCerts(WOLFSSL* ssl, byte* input, word32* inOutIdx, if (ret == ASN_NO_SIGNER_E) { WOLFSSL_MSG("try to load certificate if hash dir is set"); if (ssl->ctx->x509_store_pt != NULL) { - ret = LoadCrlCertByIssuer(ssl->ctx->x509_store_pt, + ret = LoadCertByIssuer(ssl->ctx->x509_store_pt, (WOLFSSL_X509_NAME*)args->dCert->issuerName, X509_LU_X509); } else { - ret = LoadCrlCertByIssuer(&ssl->ctx->x509_store, + ret = LoadCertByIssuer(&ssl->ctx->x509_store, (WOLFSSL_X509_NAME*)args->dCert->issuerName, X509_LU_X509); } diff --git a/wolfcrypt/src/asn.c b/wolfcrypt/src/asn.c index c2af80e85..a19529107 100644 --- a/wolfcrypt/src/asn.c +++ b/wolfcrypt/src/asn.c @@ -13201,7 +13201,7 @@ int wc_EncodeNameCanonical(EncodedName* name, const char* nameStr, char nameType int wc_EncodeName(EncodedName* name, const char* nameStr, char nameType, byte type) { - return wc_EncodeName_ex(name, nameStr, nameType, type, 0x16); + return wc_EncodeName_ex(name, nameStr, nameType, type, ASN_IA5_STRING); } /* encode CertName into output, return total bytes written */ int SetName(byte* output, word32 outputSz, CertName* name) diff --git a/wolfcrypt/src/wc_port.c b/wolfcrypt/src/wc_port.c index 3a30d198a..9e119eb61 100644 --- a/wolfcrypt/src/wc_port.c +++ b/wolfcrypt/src/wc_port.c @@ -429,20 +429,19 @@ int wc_FileExists(const char* fname) return BAD_PATH_ERROR; } else #if defined(USE_WINDOWS_API) - if (ctx.s.st_mode & _S_IFREG) { + if (XS_ISREG(ctx.s.st_mode)) { return 0; } #elif defined(WOLFSSL_ZEPHYR) - if (ctx.s.type == FS_DIR_ENTRY_FILE) { + if (XS_ISREG(ctx.s.type)) { return 0; } - #elif defined(WOLFSSL_TELIT_M2MB) - if (ctx.s.st_mode & M2MB_S_IFREG) { + if (XS_ISREG(ctx.s.st_mode)) { return 0; } #else - if (S_ISREG(ctx.s.st_mode)) { + if (XS_ISREG(ctx.s.st_mode)) { return 0; } #endif diff --git a/wolfssl/internal.h b/wolfssl/internal.h index 14fa0dc90..e24ebdb39 100644 --- a/wolfssl/internal.h +++ b/wolfssl/internal.h @@ -4836,7 +4836,7 @@ WOLFSSL_LOCAL void FreeKey(WOLFSSL* ssl, int type, void** pKey); #if defined(OPENSSL_ALL) && defined(WOLFSSL_CERT_GEN) && \ (defined(WOLFSSL_CERT_REQ) || defined(WOLFSSL_CERT_EXT)) && \ !defined(NO_FILESYSTEM) && !defined(NO_WOLFSSL_DIR) -WOLFSSL_LOCAL int LoadCrlCertByIssuer(WOLFSSL_X509_STORE* store, +WOLFSSL_LOCAL int LoadCertByIssuer(WOLFSSL_X509_STORE* store, X509_NAME* issuer, int Type); #endif #if defined(OPENSSL_ALL) && !defined(NO_FILESYSTEM) && !defined(NO_WOLFSSL_DIR) diff --git a/wolfssl/ssl.h b/wolfssl/ssl.h index 5b6c26687..6f7c384b3 100644 --- a/wolfssl/ssl.h +++ b/wolfssl/ssl.h @@ -196,9 +196,6 @@ typedef struct WOLFSSL_ASN1_OBJECT WOLFSSL_ASN1_OBJECT; typedef struct WOLFSSL_ASN1_OTHERNAME WOLFSSL_ASN1_OTHERNAME; typedef struct WOLFSSL_X509V3_CTX WOLFSSL_X509V3_CTX; typedef struct WOLFSSL_v3_ext_method WOLFSSL_v3_ext_method; -typedef struct WOLFSSL_BY_DIR WOLFSSL_BY_DIR; -typedef struct WOLFSSL_BY_DIR_entry WOLFSSL_BY_DIR_entry; -typedef struct WOLFSSL_BY_DIR_HASH WOLFSSL_BY_DIR_HASH; typedef struct WOLFSSL_ASN1_STRING WOLFSSL_ASN1_STRING; typedef struct WOLFSSL_dynlock_value WOLFSSL_dynlock_value; diff --git a/wolfssl/wolfcrypt/wc_port.h b/wolfssl/wolfcrypt/wc_port.h index 3da8f90c8..c08ec6ca1 100644 --- a/wolfssl/wolfcrypt/wc_port.h +++ b/wolfssl/wolfcrypt/wc_port.h @@ -681,12 +681,15 @@ WOLFSSL_API int wolfCrypt_Cleanup(void); #if defined(USE_WINDOWS_API) #include #define XSTAT _stat + #define XS_ISREG(s) (s & _S_IFREG) #define SEPARATOR_CHAR ';' #elif defined(WOLFSSL_ZEPHYR) #define XSTAT fs_stat + #define XS_ISREG(s) (s == FS_DIR_ENTRY_FILE) #define SEPARATOR_CHAR ':' #elif defined(WOLFSSL_TELIT_M2MB) #define XSTAT m2mb_fs_stat + #define XS_ISREG(s) (s & M2MB_S_IFREG) #define SEPARATOR_CHAR ':' #else #include @@ -696,6 +699,7 @@ WOLFSSL_API int wolfCrypt_Cleanup(void); #define XREAD read #define XCLOSE close #define XSTAT stat + #define XS_ISREG(s) S_ISREG(s) #define SEPARATOR_CHAR ':' #endif #endif From 300cbf7a5b6a3cf2fba7fe19786d4c1147d55405 Mon Sep 17 00:00:00 2001 From: Hideki Miyazaki Date: Thu, 18 Mar 2021 16:44:38 +0900 Subject: [PATCH 14/16] fixed NO_WOLFSSL_DIR configuration case --- src/ssl.c | 3 ++- tests/api.c | 9 ++++++--- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/src/ssl.c b/src/ssl.c index b08fe0967..68adb8516 100644 --- a/src/ssl.c +++ b/src/ssl.c @@ -24985,7 +24985,8 @@ int wolfSSL_X509_LOOKUP_ctrl(WOLFSSL_X509_LOOKUP *ctx, int cmd, #if !defined(NO_WOLFSSL_DIR) lret = x509AddCertDir(ctx->dirs, argc, argl); #else - lret = WOLFSSL_NOT_IMPLEMENTED + (void)x509AddCertDir; + lret = WOLFSSL_NOT_IMPLEMENTED; #endif break; case WOLFSSL_X509_L_ADD_STORE: diff --git a/tests/api.c b/tests/api.c index 7cecf86e4..ca2444bf4 100644 --- a/tests/api.c +++ b/tests/api.c @@ -28925,7 +28925,8 @@ static void test_wolfSSL_X509_STORE(void) static void test_wolfSSL_X509_STORE_load_locations(void) { -#if (defined(OPENSSL_ALL) || defined(WOLFSSL_APACHE_HTTPD)) && !defined(NO_FILESYSTEM) +#if (defined(OPENSSL_ALL) || defined(WOLFSSL_APACHE_HTTPD)) && !defined(NO_FILESYSTEM)\ + && !defined(NO_WOLFSSL_DIR) SSL_CTX *ctx; X509_STORE *store; @@ -40867,7 +40868,7 @@ static void test_wolfSSL_X509_print(void) !defined(NO_RSA) && !defined(HAVE_FAST_RSA) && defined(XSNPRINTF) X509 *x509; BIO *bio; -#ifdef OPENSSL_ALL +#if defined(OPENSSL_ALL) && !defined(NO_WOLFSSL_DIR) const X509_ALGOR *cert_sig_alg; #endif @@ -40888,14 +40889,16 @@ static void test_wolfSSL_X509_print(void) AssertNotNull(bio = BIO_new_fd(STDOUT_FILENO, BIO_NOCLOSE)); -#ifdef OPENSSL_ALL +#if defined(OPENSSL_ALL) && !defined(NO_WOLFSSL_DIR) /* Print signature */ AssertNotNull(cert_sig_alg = X509_get0_tbs_sigalg(x509)); AssertIntEQ(X509_signature_print(bio, cert_sig_alg, NULL), SSL_SUCCESS); #endif /* print to stdout */ +#if !defined(NO_WOLFSSL_DIR) AssertIntEQ(X509_print(bio, x509), SSL_SUCCESS); +#endif /* print again */ AssertIntEQ(X509_print_fp(stdout, x509), SSL_SUCCESS); From fae36f108eef40fb99bcce894c22b08047b1ef37 Mon Sep 17 00:00:00 2001 From: Hideki Miyazaki Date: Sat, 20 Mar 2021 12:29:42 +0900 Subject: [PATCH 15/16] adressed review comments part 5 --- src/crl.c | 5 +++++ wolfssl/internal.h | 4 +++- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/src/crl.c b/src/crl.c index cb99ec1c7..148ea5796 100644 --- a/src/crl.c +++ b/src/crl.c @@ -367,6 +367,11 @@ int CheckCertCRL(WOLFSSL_CRL* crl, DecodedCert* cert) #if defined(OPENSSL_ALL) && defined(WOLFSSL_CERT_GEN) && \ (defined(WOLFSSL_CERT_REQ) || defined(WOLFSSL_CERT_EXT)) && \ !defined(NO_FILESYSTEM) && !defined(NO_WOLFSSL_DIR) + /* if not find entry in the CRL list, it looks at the folder that sets */ + /* by LOOKUP_ctrl because user would want to use hash_dir. */ + /* Loading .rN form CRL file if find at the folder, */ + /* and try again checking Cert in the CRL list. */ + /* When not set the folder or not use hash_dir, do nothing. */ if (foundEntry == 0) { if (crl->cm->x509_store_p != NULL) { ret = LoadCertByIssuer(crl->cm->x509_store_p, diff --git a/wolfssl/internal.h b/wolfssl/internal.h index e24ebdb39..1d55b3afe 100644 --- a/wolfssl/internal.h +++ b/wolfssl/internal.h @@ -2083,7 +2083,9 @@ struct WOLFSSL_CERT_MANAGER { short minEccKeySz; /* minimum allowed ECC key size */ #endif #if defined(OPENSSL_EXTRA) - WOLFSSL_X509_STORE *x509_store_p; /* pointer back to x509 store */ + WOLFSSL_X509_STORE *x509_store_p; /* a pointer back to CTX x509 store */ + /* CTX has ownership and free this */ + /* with CTX free. */ #endif wolfSSL_Mutex refMutex; /* reference count mutex */ int refCount; /* reference count */ From 526688a1a53f4e4dd34d692fd2ead027434d241b Mon Sep 17 00:00:00 2001 From: Hideki Miyazaki Date: Sat, 20 Mar 2021 12:47:35 +0900 Subject: [PATCH 16/16] adressed review comments part 5-1 --- src/ssl.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/ssl.c b/src/ssl.c index 68adb8516..dff8a4dc9 100644 --- a/src/ssl.c +++ b/src/ssl.c @@ -15821,7 +15821,8 @@ int wolfSSL_set_compression(WOLFSSL* ssl) ctx->x509_store.cache = str->cache; ctx->x509_store_pt = str; /* take ownership of store and free it with CTX free */ - ctx->cm->x509_store_p = ctx->x509_store_pt; + ctx->cm->x509_store_p = ctx->x509_store_pt;/* CTX has onwership + and free it with CTX free*/ }