cjson
.github
workflows CI.yml ci-fuzz.yml
CONTRIBUTING.md
fuzzing
inputs test1 test10 test11 test2 test3 test3.bu test3.uf test3.uu test4 test5 test6 test7 test8 test9
.gitignore CMakeLists.txt afl-prepare-linux.sh afl.c afl.sh cjson_read_fuzzer.c fuzz_main.c json.dict ossfuzz.sh
library_config cJSONConfig.cmake.in cJSONConfigVersion.cmake.in libcjson.pc.in libcjson_utils.pc.in uninstall.cmake
tests
inputs test1 test1.expected test10 test10.expected test11 test11.expected test2 test2.expected test3 test3.expected test4 test4.expected test5 test5.expected test6 test7 test7.expected test8 test8.expected test9 test9.expected
json-patch-tests .editorconfig .gitignore .npmignore README.md cjson-utils-tests.json package.json spec_tests.json tests.json
unity
auto colour_prompt.rb colour_reporter.rb generate_config.yml generate_module.rb generate_test_runner.rb parse_output.rb stylize_as_junit.rb test_file_filter.rb type_sanitizer.rb unity_test_summary.py unity_test_summary.rb unity_to_junit.py
docs ThrowTheSwitchCodingStandard.md UnityAssertionsCheatSheetSuitableforPrintingandPossiblyFraming.pdf UnityAssertionsReference.md UnityConfigurationGuide.md UnityGettingStartedGuide.md UnityHelperScriptsGuide.md license.txt
examples
example_1
src ProductionCode.c ProductionCode.h ProductionCode2.c ProductionCode2.h
makefile readme.txt
example_2
src ProductionCode.c ProductionCode.h ProductionCode2.c ProductionCode2.h
makefile readme.txt
example_3
helper UnityHelper.c UnityHelper.h
src ProductionCode.c ProductionCode.h ProductionCode2.c ProductionCode2.h
rakefile.rb rakefile_helper.rb readme.txt target_gcc_32.yml
unity_config.h
extras
eclipse error_parsers.txt
fixture
src unity_fixture.c unity_fixture.h unity_fixture_internals.h unity_fixture_malloc_overrides.h
rakefile.rb rakefile_helper.rb readme.txt
release build.info version.info
src unity.c unity.h unity_internals.h
.gitattributes .gitignore .travis.yml README.md
CMakeLists.txt cjson_add.c common.h compare_tests.c json_patch_tests.c minify_tests.c misc_tests.c misc_utils_tests.c old_utils_tests.c parse_array.c parse_examples.c parse_hex4.c parse_number.c parse_object.c parse_string.c parse_value.c parse_with_opts.c print_array.c print_number.c print_object.c print_string.c print_value.c readme_examples.c unity_setup.c
.editorconfig .gitattributes .gitignore .travis.yml CHANGELOG.md CMakeLists.txt CONTRIBUTORS.md LICENSE Makefile README.md SECURITY.md appveyor.yml cJSON.c cJSON.h cJSON_Utils.c cJSON_Utils.h test.c valgrind.supp
curl
.circleci config.yml
.github
ISSUE_TEMPLATE bug_report.yml config.yml docs.yml
scripts cleancmd.pl cmp-config.pl cmp-pkg-config.sh codespell-ignore.words codespell.sh distfiles.sh pyspelling.words pyspelling.yaml randcurl.pl requirements-docs.txt requirements-proselint.txt requirements.txt shellcheck-ci.sh shellcheck.sh spellcheck.curl trimmarkdownheader.pl typos.sh typos.toml verify-examples.pl verify-synopsis.pl yamlcheck.sh yamlcheck.yaml
workflows appveyor-status.yml checkdocs.yml checksrc.yml checkurls.yml codeql.yml configure-vs-cmake.yml curl-for-win.yml distcheck.yml fuzz.yml http3-linux.yml label.yml linux-old.yml linux.yml macos.yml non-native.yml windows.yml
CODEOWNERS CONTRIBUTING.md FUNDING.yml dependabot.yml labeler.yml lock.yml stale.yml
CMake CurlSymbolHiding.cmake CurlTests.c FindBrotli.cmake FindCares.cmake FindGSS.cmake FindGnuTLS.cmake FindLDAP.cmake FindLibbacktrace.cmake FindLibgsasl.cmake FindLibidn2.cmake FindLibpsl.cmake FindLibssh.cmake FindLibssh2.cmake FindLibuv.cmake FindMbedTLS.cmake FindNGHTTP2.cmake FindNGHTTP3.cmake FindNGTCP2.cmake FindNettle.cmake FindQuiche.cmake FindRustls.cmake FindWolfSSL.cmake FindZstd.cmake Macros.cmake OtherTests.cmake PickyWarnings.cmake Utilities.cmake cmake_uninstall.in.cmake curl-config.in.cmake unix-cache.cmake win32-cache.cmake
LICENSES BSD-4-Clause-UC.txt ISC.txt curl.txt
docs
cmdline-opts .gitignore CMakeLists.txt MANPAGE.md Makefile.am Makefile.inc _AUTHORS.md _BUGS.md _DESCRIPTION.md _ENVIRONMENT.md _EXITCODES.md _FILES.md _GLOBBING.md _NAME.md _OPTIONS.md _OUTPUT.md _PROGRESS.md _PROTOCOLS.md _PROXYPREFIX.md _SEEALSO.md _SYNOPSIS.md _URL.md _VARIABLES.md _VERSION.md _WWW.md abstract-unix-socket.md alt-svc.md anyauth.md append.md aws-sigv4.md basic.md ca-native.md cacert.md capath.md cert-status.md cert-type.md cert.md ciphers.md compressed-ssh.md compressed.md config.md connect-timeout.md connect-to.md continue-at.md cookie-jar.md cookie.md create-dirs.md create-file-mode.md crlf.md crlfile.md curves.md data-ascii.md data-binary.md data-raw.md data-urlencode.md data.md delegation.md digest.md disable-eprt.md disable-epsv.md disable.md disallow-username-in-url.md dns-interface.md dns-ipv4-addr.md dns-ipv6-addr.md dns-servers.md doh-cert-status.md doh-insecure.md doh-url.md dump-ca-embed.md dump-header.md ech.md egd-file.md engine.md etag-compare.md etag-save.md expect100-timeout.md fail-early.md fail-with-body.md fail.md false-start.md follow.md form-escape.md form-string.md form.md ftp-account.md ftp-alternative-to-user.md ftp-create-dirs.md ftp-method.md ftp-pasv.md ftp-port.md ftp-pret.md ftp-skip-pasv-ip.md ftp-ssl-ccc-mode.md ftp-ssl-ccc.md ftp-ssl-control.md get.md globoff.md happy-eyeballs-timeout-ms.md haproxy-clientip.md haproxy-protocol.md head.md header.md help.md hostpubmd5.md hostpubsha256.md hsts.md http0.9.md http1.0.md http1.1.md http2-prior-knowledge.md http2.md http3-only.md http3.md ignore-content-length.md insecure.md interface.md ip-tos.md ipfs-gateway.md ipv4.md ipv6.md json.md junk-session-cookies.md keepalive-cnt.md keepalive-time.md key-type.md key.md knownhosts.md krb.md libcurl.md limit-rate.md list-only.md local-port.md location-trusted.md location.md login-options.md mail-auth.md mail-from.md mail-rcpt-allowfails.md mail-rcpt.md mainpage.idx manual.md max-filesize.md max-redirs.md max-time.md metalink.md mptcp.md negotiate.md netrc-file.md netrc-optional.md netrc.md next.md no-alpn.md no-buffer.md no-clobber.md no-keepalive.md no-npn.md no-progress-meter.md no-sessionid.md noproxy.md ntlm-wb.md ntlm.md oauth2-bearer.md out-null.md output-dir.md output.md parallel-immediate.md parallel-max-host.md parallel-max.md parallel.md pass.md path-as-is.md pinnedpubkey.md post301.md post302.md post303.md preproxy.md progress-bar.md proto-default.md proto-redir.md proto.md proxy-anyauth.md proxy-basic.md proxy-ca-native.md proxy-cacert.md proxy-capath.md proxy-cert-type.md proxy-cert.md proxy-ciphers.md proxy-crlfile.md proxy-digest.md proxy-header.md proxy-http2.md proxy-insecure.md proxy-key-type.md proxy-key.md proxy-negotiate.md proxy-ntlm.md proxy-pass.md proxy-pinnedpubkey.md proxy-service-name.md proxy-ssl-allow-beast.md proxy-ssl-auto-client-cert.md proxy-tls13-ciphers.md proxy-tlsauthtype.md proxy-tlspassword.md proxy-tlsuser.md proxy-tlsv1.md proxy-user.md proxy.md proxy1.0.md proxytunnel.md pubkey.md quote.md random-file.md range.md rate.md raw.md referer.md remote-header-name.md remote-name-all.md remote-name.md remote-time.md remove-on-error.md request-target.md request.md resolve.md retry-all-errors.md retry-connrefused.md retry-delay.md retry-max-time.md retry.md sasl-authzid.md sasl-ir.md service-name.md show-error.md show-headers.md sigalgs.md silent.md skip-existing.md socks4.md socks4a.md socks5-basic.md socks5-gssapi-nec.md socks5-gssapi-service.md socks5-gssapi.md socks5-hostname.md socks5.md speed-limit.md speed-time.md ssl-allow-beast.md ssl-auto-client-cert.md ssl-no-revoke.md ssl-reqd.md ssl-revoke-best-effort.md ssl-sessions.md ssl.md sslv2.md sslv3.md stderr.md styled-output.md suppress-connect-headers.md tcp-fastopen.md tcp-nodelay.md telnet-option.md tftp-blksize.md tftp-no-options.md time-cond.md tls-earlydata.md tls-max.md tls13-ciphers.md tlsauthtype.md tlspassword.md tlsuser.md tlsv1.0.md tlsv1.1.md tlsv1.2.md tlsv1.3.md tlsv1.md tr-encoding.md trace-ascii.md trace-config.md trace-ids.md trace-time.md trace.md unix-socket.md upload-file.md upload-flags.md url-query.md url.md use-ascii.md user-agent.md user.md variable.md verbose.md version.md vlan-priority.md write-out.md xattr.md
examples .checksrc .gitignore 10-at-a-time.c CMakeLists.txt Makefile.am Makefile.example Makefile.inc README.md adddocsref.pl address-scope.c altsvc.c anyauthput.c block_ip.c cacertinmem.c certinfo.c chkspeed.c connect-to.c cookie_interface.c crawler.c debug.c default-scheme.c ephiperfifo.c evhiperfifo.c externalsocket.c fileupload.c ftp-delete.c ftp-wildcard.c ftpget.c ftpgetinfo.c ftpgetresp.c ftpsget.c ftpupload.c ftpuploadfrommem.c ftpuploadresume.c getinfo.c getinmemory.c getredirect.c getreferrer.c ghiper.c headerapi.c hiperfifo.c hsts-preload.c htmltidy.c htmltitle.cpp http-options.c http-post.c http2-download.c http2-pushinmemory.c http2-serverpush.c http2-upload.c http3-present.c http3.c httpcustomheader.c httpput-postfields.c httpput.c https.c imap-append.c imap-authzid.c imap-copy.c imap-create.c imap-delete.c imap-examine.c imap-fetch.c imap-list.c imap-lsub.c imap-multi.c imap-noop.c imap-search.c imap-ssl.c imap-store.c imap-tls.c interface.c ipv6.c keepalive.c localport.c log_failed_transfers.c maxconnects.c multi-app.c multi-debugcallback.c multi-double.c multi-event.c multi-formadd.c multi-legacy.c multi-post.c multi-single.c multi-uv.c netrc.c parseurl.c persistent.c pop3-authzid.c pop3-dele.c pop3-list.c pop3-multi.c pop3-noop.c pop3-retr.c pop3-ssl.c pop3-stat.c pop3-tls.c pop3-top.c pop3-uidl.c post-callback.c postinmemory.c postit2-formadd.c postit2.c progressfunc.c protofeats.c range.c resolve.c rtsp-options.c sendrecv.c sepheaders.c sessioninfo.c sftpget.c sftpuploadresume.c shared-connection-cache.c simple.c simplepost.c simplessl.c smooth-gtk-thread.c smtp-authzid.c smtp-expn.c smtp-mail.c smtp-mime.c smtp-multi.c smtp-ssl.c smtp-tls.c smtp-vrfy.c sslbackend.c synctime.c threaded.c unixsocket.c url2file.c urlapi.c usercertinmem.c version-check.pl websocket-cb.c websocket-updown.c websocket.c xmlstream.c
internals BUFQ.md BUFREF.md CHECKSRC.md CLIENT-READERS.md CLIENT-WRITERS.md CODE_STYLE.md CONNECTION-FILTERS.md CREDENTIALS.md CURLX.md DYNBUF.md HASH.md LLIST.md MID.md MQTT.md MULTI-EV.md NEW-PROTOCOL.md PEERS.md PORTING.md RATELIMITS.md README.md SCORECARD.md SPLAY.md STRPARSE.md THRDPOOL-AND-QUEUE.md TIME-KEEPING.md TLS-SESSIONS.md UINT_SETS.md WEBSOCKET.md
libcurl
opts CMakeLists.txt CURLINFO_ACTIVESOCKET.md CURLINFO_APPCONNECT_TIME.md CURLINFO_APPCONNECT_TIME_T.md CURLINFO_CAINFO.md CURLINFO_CAPATH.md CURLINFO_CERTINFO.md CURLINFO_CONDITION_UNMET.md CURLINFO_CONNECT_TIME.md CURLINFO_CONNECT_TIME_T.md CURLINFO_CONN_ID.md CURLINFO_CONTENT_LENGTH_DOWNLOAD.md CURLINFO_CONTENT_LENGTH_DOWNLOAD_T.md CURLINFO_CONTENT_LENGTH_UPLOAD.md CURLINFO_CONTENT_LENGTH_UPLOAD_T.md CURLINFO_CONTENT_TYPE.md CURLINFO_COOKIELIST.md CURLINFO_EARLYDATA_SENT_T.md CURLINFO_EFFECTIVE_METHOD.md CURLINFO_EFFECTIVE_URL.md CURLINFO_FILETIME.md CURLINFO_FILETIME_T.md CURLINFO_FTP_ENTRY_PATH.md CURLINFO_HEADER_SIZE.md CURLINFO_HTTPAUTH_AVAIL.md CURLINFO_HTTPAUTH_USED.md CURLINFO_HTTP_CONNECTCODE.md CURLINFO_HTTP_VERSION.md CURLINFO_LASTSOCKET.md CURLINFO_LOCAL_IP.md CURLINFO_LOCAL_PORT.md CURLINFO_NAMELOOKUP_TIME.md CURLINFO_NAMELOOKUP_TIME_T.md CURLINFO_NUM_CONNECTS.md CURLINFO_OS_ERRNO.md CURLINFO_POSTTRANSFER_TIME_T.md CURLINFO_PRETRANSFER_TIME.md CURLINFO_PRETRANSFER_TIME_T.md CURLINFO_PRIMARY_IP.md CURLINFO_PRIMARY_PORT.md CURLINFO_PRIVATE.md CURLINFO_PROTOCOL.md CURLINFO_PROXYAUTH_AVAIL.md CURLINFO_PROXYAUTH_USED.md CURLINFO_PROXY_ERROR.md CURLINFO_PROXY_SSL_VERIFYRESULT.md CURLINFO_QUEUE_TIME_T.md CURLINFO_REDIRECT_COUNT.md CURLINFO_REDIRECT_TIME.md CURLINFO_REDIRECT_TIME_T.md CURLINFO_REDIRECT_URL.md CURLINFO_REFERER.md CURLINFO_REQUEST_SIZE.md CURLINFO_RESPONSE_CODE.md CURLINFO_RETRY_AFTER.md CURLINFO_RTSP_CLIENT_CSEQ.md CURLINFO_RTSP_CSEQ_RECV.md CURLINFO_RTSP_SERVER_CSEQ.md CURLINFO_RTSP_SESSION_ID.md CURLINFO_SCHEME.md CURLINFO_SIZE_DELIVERED.md CURLINFO_SIZE_DOWNLOAD.md CURLINFO_SIZE_DOWNLOAD_T.md CURLINFO_SIZE_UPLOAD.md CURLINFO_SIZE_UPLOAD_T.md CURLINFO_SPEED_DOWNLOAD.md CURLINFO_SPEED_DOWNLOAD_T.md CURLINFO_SPEED_UPLOAD.md CURLINFO_SPEED_UPLOAD_T.md CURLINFO_SSL_ENGINES.md CURLINFO_SSL_VERIFYRESULT.md CURLINFO_STARTTRANSFER_TIME.md CURLINFO_STARTTRANSFER_TIME_T.md CURLINFO_TLS_SESSION.md CURLINFO_TLS_SSL_PTR.md CURLINFO_TOTAL_TIME.md CURLINFO_TOTAL_TIME_T.md CURLINFO_USED_PROXY.md CURLINFO_XFER_ID.md CURLMINFO_XFERS_ADDED.md CURLMINFO_XFERS_CURRENT.md CURLMINFO_XFERS_DONE.md CURLMINFO_XFERS_PENDING.md CURLMINFO_XFERS_RUNNING.md CURLMOPT_CHUNK_LENGTH_PENALTY_SIZE.md CURLMOPT_CONTENT_LENGTH_PENALTY_SIZE.md CURLMOPT_MAXCONNECTS.md CURLMOPT_MAX_CONCURRENT_STREAMS.md CURLMOPT_MAX_HOST_CONNECTIONS.md CURLMOPT_MAX_PIPELINE_LENGTH.md CURLMOPT_MAX_TOTAL_CONNECTIONS.md CURLMOPT_NETWORK_CHANGED.md CURLMOPT_NOTIFYDATA.md CURLMOPT_NOTIFYFUNCTION.md CURLMOPT_PIPELINING.md CURLMOPT_PIPELINING_SERVER_BL.md CURLMOPT_PIPELINING_SITE_BL.md CURLMOPT_PUSHDATA.md CURLMOPT_PUSHFUNCTION.md CURLMOPT_QUICK_EXIT.md CURLMOPT_RESOLVE_THREADS_MAX.md CURLMOPT_SOCKETDATA.md CURLMOPT_SOCKETFUNCTION.md CURLMOPT_TIMERDATA.md CURLMOPT_TIMERFUNCTION.md CURLOPT_ABSTRACT_UNIX_SOCKET.md CURLOPT_ACCEPTTIMEOUT_MS.md CURLOPT_ACCEPT_ENCODING.md CURLOPT_ADDRESS_SCOPE.md CURLOPT_ALTSVC.md CURLOPT_ALTSVC_CTRL.md CURLOPT_APPEND.md CURLOPT_AUTOREFERER.md CURLOPT_AWS_SIGV4.md CURLOPT_BUFFERSIZE.md CURLOPT_CAINFO.md CURLOPT_CAINFO_BLOB.md CURLOPT_CAPATH.md CURLOPT_CA_CACHE_TIMEOUT.md CURLOPT_CERTINFO.md CURLOPT_CHUNK_BGN_FUNCTION.md CURLOPT_CHUNK_DATA.md CURLOPT_CHUNK_END_FUNCTION.md CURLOPT_CLOSESOCKETDATA.md CURLOPT_CLOSESOCKETFUNCTION.md CURLOPT_CONNECTTIMEOUT.md CURLOPT_CONNECTTIMEOUT_MS.md CURLOPT_CONNECT_ONLY.md CURLOPT_CONNECT_TO.md CURLOPT_CONV_FROM_NETWORK_FUNCTION.md CURLOPT_CONV_FROM_UTF8_FUNCTION.md CURLOPT_CONV_TO_NETWORK_FUNCTION.md CURLOPT_COOKIE.md CURLOPT_COOKIEFILE.md CURLOPT_COOKIEJAR.md CURLOPT_COOKIELIST.md CURLOPT_COOKIESESSION.md CURLOPT_COPYPOSTFIELDS.md CURLOPT_CRLF.md CURLOPT_CRLFILE.md CURLOPT_CURLU.md CURLOPT_CUSTOMREQUEST.md CURLOPT_DEBUGDATA.md CURLOPT_DEBUGFUNCTION.md CURLOPT_DEFAULT_PROTOCOL.md CURLOPT_DIRLISTONLY.md CURLOPT_DISALLOW_USERNAME_IN_URL.md CURLOPT_DNS_CACHE_TIMEOUT.md CURLOPT_DNS_INTERFACE.md CURLOPT_DNS_LOCAL_IP4.md CURLOPT_DNS_LOCAL_IP6.md CURLOPT_DNS_SERVERS.md CURLOPT_DNS_SHUFFLE_ADDRESSES.md CURLOPT_DNS_USE_GLOBAL_CACHE.md CURLOPT_DOH_SSL_VERIFYHOST.md CURLOPT_DOH_SSL_VERIFYPEER.md CURLOPT_DOH_SSL_VERIFYSTATUS.md CURLOPT_DOH_URL.md CURLOPT_ECH.md CURLOPT_EGDSOCKET.md CURLOPT_ERRORBUFFER.md CURLOPT_EXPECT_100_TIMEOUT_MS.md CURLOPT_FAILONERROR.md CURLOPT_FILETIME.md CURLOPT_FNMATCH_DATA.md CURLOPT_FNMATCH_FUNCTION.md CURLOPT_FOLLOWLOCATION.md CURLOPT_FORBID_REUSE.md CURLOPT_FRESH_CONNECT.md CURLOPT_FTPPORT.md CURLOPT_FTPSSLAUTH.md CURLOPT_FTP_ACCOUNT.md CURLOPT_FTP_ALTERNATIVE_TO_USER.md CURLOPT_FTP_CREATE_MISSING_DIRS.md CURLOPT_FTP_FILEMETHOD.md CURLOPT_FTP_SKIP_PASV_IP.md CURLOPT_FTP_SSL_CCC.md CURLOPT_FTP_USE_EPRT.md CURLOPT_FTP_USE_EPSV.md CURLOPT_FTP_USE_PRET.md CURLOPT_GSSAPI_DELEGATION.md CURLOPT_HAPPY_EYEBALLS_TIMEOUT_MS.md CURLOPT_HAPROXYPROTOCOL.md CURLOPT_HAPROXY_CLIENT_IP.md CURLOPT_HEADER.md CURLOPT_HEADERDATA.md CURLOPT_HEADERFUNCTION.md CURLOPT_HEADEROPT.md CURLOPT_HSTS.md CURLOPT_HSTSREADDATA.md CURLOPT_HSTSREADFUNCTION.md CURLOPT_HSTSWRITEDATA.md CURLOPT_HSTSWRITEFUNCTION.md CURLOPT_HSTS_CTRL.md CURLOPT_HTTP09_ALLOWED.md CURLOPT_HTTP200ALIASES.md CURLOPT_HTTPAUTH.md CURLOPT_HTTPGET.md CURLOPT_HTTPHEADER.md CURLOPT_HTTPPOST.md CURLOPT_HTTPPROXYTUNNEL.md CURLOPT_HTTP_CONTENT_DECODING.md CURLOPT_HTTP_TRANSFER_DECODING.md CURLOPT_HTTP_VERSION.md CURLOPT_IGNORE_CONTENT_LENGTH.md CURLOPT_INFILESIZE.md CURLOPT_INFILESIZE_LARGE.md CURLOPT_INTERFACE.md CURLOPT_INTERLEAVEDATA.md CURLOPT_INTERLEAVEFUNCTION.md CURLOPT_IOCTLDATA.md CURLOPT_IOCTLFUNCTION.md CURLOPT_IPRESOLVE.md CURLOPT_ISSUERCERT.md CURLOPT_ISSUERCERT_BLOB.md CURLOPT_KEEP_SENDING_ON_ERROR.md CURLOPT_KEYPASSWD.md CURLOPT_KRBLEVEL.md CURLOPT_LOCALPORT.md CURLOPT_LOCALPORTRANGE.md CURLOPT_LOGIN_OPTIONS.md CURLOPT_LOW_SPEED_LIMIT.md CURLOPT_LOW_SPEED_TIME.md CURLOPT_MAIL_AUTH.md CURLOPT_MAIL_FROM.md CURLOPT_MAIL_RCPT.md CURLOPT_MAIL_RCPT_ALLOWFAILS.md CURLOPT_MAXAGE_CONN.md CURLOPT_MAXCONNECTS.md CURLOPT_MAXFILESIZE.md CURLOPT_MAXFILESIZE_LARGE.md CURLOPT_MAXLIFETIME_CONN.md CURLOPT_MAXREDIRS.md CURLOPT_MAX_RECV_SPEED_LARGE.md CURLOPT_MAX_SEND_SPEED_LARGE.md CURLOPT_MIMEPOST.md CURLOPT_MIME_OPTIONS.md CURLOPT_NETRC.md CURLOPT_NETRC_FILE.md CURLOPT_NEW_DIRECTORY_PERMS.md CURLOPT_NEW_FILE_PERMS.md CURLOPT_NOBODY.md CURLOPT_NOPROGRESS.md CURLOPT_NOPROXY.md CURLOPT_NOSIGNAL.md CURLOPT_OPENSOCKETDATA.md CURLOPT_OPENSOCKETFUNCTION.md CURLOPT_PASSWORD.md CURLOPT_PATH_AS_IS.md CURLOPT_PINNEDPUBLICKEY.md CURLOPT_PIPEWAIT.md CURLOPT_PORT.md CURLOPT_POST.md CURLOPT_POSTFIELDS.md CURLOPT_POSTFIELDSIZE.md CURLOPT_POSTFIELDSIZE_LARGE.md CURLOPT_POSTQUOTE.md CURLOPT_POSTREDIR.md CURLOPT_PREQUOTE.md CURLOPT_PREREQDATA.md CURLOPT_PREREQFUNCTION.md CURLOPT_PRE_PROXY.md CURLOPT_PRIVATE.md CURLOPT_PROGRESSDATA.md CURLOPT_PROGRESSFUNCTION.md CURLOPT_PROTOCOLS.md CURLOPT_PROTOCOLS_STR.md CURLOPT_PROXY.md CURLOPT_PROXYAUTH.md CURLOPT_PROXYHEADER.md CURLOPT_PROXYPASSWORD.md CURLOPT_PROXYPORT.md CURLOPT_PROXYTYPE.md CURLOPT_PROXYUSERNAME.md CURLOPT_PROXYUSERPWD.md CURLOPT_PROXY_CAINFO.md CURLOPT_PROXY_CAINFO_BLOB.md CURLOPT_PROXY_CAPATH.md CURLOPT_PROXY_CRLFILE.md CURLOPT_PROXY_ISSUERCERT.md CURLOPT_PROXY_ISSUERCERT_BLOB.md CURLOPT_PROXY_KEYPASSWD.md CURLOPT_PROXY_PINNEDPUBLICKEY.md CURLOPT_PROXY_SERVICE_NAME.md CURLOPT_PROXY_SSLCERT.md CURLOPT_PROXY_SSLCERTTYPE.md CURLOPT_PROXY_SSLCERT_BLOB.md CURLOPT_PROXY_SSLKEY.md CURLOPT_PROXY_SSLKEYTYPE.md CURLOPT_PROXY_SSLKEY_BLOB.md CURLOPT_PROXY_SSLVERSION.md CURLOPT_PROXY_SSL_CIPHER_LIST.md CURLOPT_PROXY_SSL_OPTIONS.md CURLOPT_PROXY_SSL_VERIFYHOST.md CURLOPT_PROXY_SSL_VERIFYPEER.md CURLOPT_PROXY_TLS13_CIPHERS.md CURLOPT_PROXY_TLSAUTH_PASSWORD.md CURLOPT_PROXY_TLSAUTH_TYPE.md CURLOPT_PROXY_TLSAUTH_USERNAME.md CURLOPT_PROXY_TRANSFER_MODE.md CURLOPT_PUT.md CURLOPT_QUICK_EXIT.md CURLOPT_QUOTE.md CURLOPT_RANDOM_FILE.md CURLOPT_RANGE.md CURLOPT_READDATA.md CURLOPT_READFUNCTION.md CURLOPT_REDIR_PROTOCOLS.md CURLOPT_REDIR_PROTOCOLS_STR.md CURLOPT_REFERER.md CURLOPT_REQUEST_TARGET.md CURLOPT_RESOLVE.md CURLOPT_RESOLVER_START_DATA.md CURLOPT_RESOLVER_START_FUNCTION.md CURLOPT_RESUME_FROM.md CURLOPT_RESUME_FROM_LARGE.md CURLOPT_RTSP_CLIENT_CSEQ.md CURLOPT_RTSP_REQUEST.md CURLOPT_RTSP_SERVER_CSEQ.md CURLOPT_RTSP_SESSION_ID.md CURLOPT_RTSP_STREAM_URI.md CURLOPT_RTSP_TRANSPORT.md CURLOPT_SASL_AUTHZID.md CURLOPT_SASL_IR.md CURLOPT_SEEKDATA.md CURLOPT_SEEKFUNCTION.md CURLOPT_SERVER_RESPONSE_TIMEOUT.md CURLOPT_SERVER_RESPONSE_TIMEOUT_MS.md CURLOPT_SERVICE_NAME.md CURLOPT_SHARE.md CURLOPT_SOCKOPTDATA.md CURLOPT_SOCKOPTFUNCTION.md CURLOPT_SOCKS5_AUTH.md CURLOPT_SOCKS5_GSSAPI_NEC.md CURLOPT_SOCKS5_GSSAPI_SERVICE.md CURLOPT_SSH_AUTH_TYPES.md CURLOPT_SSH_COMPRESSION.md CURLOPT_SSH_HOSTKEYDATA.md CURLOPT_SSH_HOSTKEYFUNCTION.md CURLOPT_SSH_HOST_PUBLIC_KEY_MD5.md CURLOPT_SSH_HOST_PUBLIC_KEY_SHA256.md CURLOPT_SSH_KEYDATA.md CURLOPT_SSH_KEYFUNCTION.md CURLOPT_SSH_KNOWNHOSTS.md CURLOPT_SSH_PRIVATE_KEYFILE.md CURLOPT_SSH_PUBLIC_KEYFILE.md CURLOPT_SSLCERT.md CURLOPT_SSLCERTTYPE.md CURLOPT_SSLCERT_BLOB.md CURLOPT_SSLENGINE.md CURLOPT_SSLENGINE_DEFAULT.md CURLOPT_SSLKEY.md CURLOPT_SSLKEYTYPE.md CURLOPT_SSLKEY_BLOB.md CURLOPT_SSLVERSION.md CURLOPT_SSL_CIPHER_LIST.md CURLOPT_SSL_CTX_DATA.md CURLOPT_SSL_CTX_FUNCTION.md CURLOPT_SSL_EC_CURVES.md CURLOPT_SSL_ENABLE_ALPN.md CURLOPT_SSL_ENABLE_NPN.md CURLOPT_SSL_FALSESTART.md CURLOPT_SSL_OPTIONS.md CURLOPT_SSL_SESSIONID_CACHE.md CURLOPT_SSL_SIGNATURE_ALGORITHMS.md CURLOPT_SSL_VERIFYHOST.md CURLOPT_SSL_VERIFYPEER.md CURLOPT_SSL_VERIFYSTATUS.md CURLOPT_STDERR.md CURLOPT_STREAM_DEPENDS.md CURLOPT_STREAM_DEPENDS_E.md CURLOPT_STREAM_WEIGHT.md CURLOPT_SUPPRESS_CONNECT_HEADERS.md CURLOPT_TCP_FASTOPEN.md CURLOPT_TCP_KEEPALIVE.md CURLOPT_TCP_KEEPCNT.md CURLOPT_TCP_KEEPIDLE.md CURLOPT_TCP_KEEPINTVL.md CURLOPT_TCP_NODELAY.md CURLOPT_TELNETOPTIONS.md CURLOPT_TFTP_BLKSIZE.md CURLOPT_TFTP_NO_OPTIONS.md CURLOPT_TIMECONDITION.md CURLOPT_TIMEOUT.md CURLOPT_TIMEOUT_MS.md CURLOPT_TIMEVALUE.md CURLOPT_TIMEVALUE_LARGE.md CURLOPT_TLS13_CIPHERS.md CURLOPT_TLSAUTH_PASSWORD.md CURLOPT_TLSAUTH_TYPE.md CURLOPT_TLSAUTH_USERNAME.md CURLOPT_TRAILERDATA.md CURLOPT_TRAILERFUNCTION.md CURLOPT_TRANSFERTEXT.md CURLOPT_TRANSFER_ENCODING.md CURLOPT_UNIX_SOCKET_PATH.md CURLOPT_UNRESTRICTED_AUTH.md CURLOPT_UPKEEP_INTERVAL_MS.md CURLOPT_UPLOAD.md CURLOPT_UPLOAD_BUFFERSIZE.md CURLOPT_UPLOAD_FLAGS.md CURLOPT_URL.md CURLOPT_USERAGENT.md CURLOPT_USERNAME.md CURLOPT_USERPWD.md CURLOPT_USE_SSL.md CURLOPT_VERBOSE.md CURLOPT_WILDCARDMATCH.md CURLOPT_WRITEDATA.md CURLOPT_WRITEFUNCTION.md CURLOPT_WS_OPTIONS.md CURLOPT_XFERINFODATA.md CURLOPT_XFERINFOFUNCTION.md CURLOPT_XOAUTH2_BEARER.md CURLSHOPT_LOCKFUNC.md CURLSHOPT_SHARE.md CURLSHOPT_UNLOCKFUNC.md CURLSHOPT_UNSHARE.md CURLSHOPT_USERDATA.md Makefile.am Makefile.inc
.gitignore ABI.md CMakeLists.txt Makefile.am Makefile.inc curl_easy_cleanup.md curl_easy_duphandle.md curl_easy_escape.md curl_easy_getinfo.md curl_easy_header.md curl_easy_init.md curl_easy_nextheader.md curl_easy_option_by_id.md curl_easy_option_by_name.md curl_easy_option_next.md curl_easy_pause.md curl_easy_perform.md curl_easy_recv.md curl_easy_reset.md curl_easy_send.md curl_easy_setopt.md curl_easy_ssls_export.md curl_easy_ssls_import.md curl_easy_strerror.md curl_easy_unescape.md curl_easy_upkeep.md curl_escape.md curl_formadd.md curl_formfree.md curl_formget.md curl_free.md curl_getdate.md curl_getenv.md curl_global_cleanup.md curl_global_init.md curl_global_init_mem.md curl_global_sslset.md curl_global_trace.md curl_mime_addpart.md curl_mime_data.md curl_mime_data_cb.md curl_mime_encoder.md curl_mime_filedata.md curl_mime_filename.md curl_mime_free.md curl_mime_headers.md curl_mime_init.md curl_mime_name.md curl_mime_subparts.md curl_mime_type.md curl_mprintf.md curl_multi_add_handle.md curl_multi_assign.md curl_multi_cleanup.md curl_multi_fdset.md curl_multi_get_handles.md curl_multi_get_offt.md curl_multi_info_read.md curl_multi_init.md curl_multi_notify_disable.md curl_multi_notify_enable.md curl_multi_perform.md curl_multi_poll.md curl_multi_remove_handle.md curl_multi_setopt.md curl_multi_socket.md curl_multi_socket_action.md curl_multi_socket_all.md curl_multi_strerror.md curl_multi_timeout.md curl_multi_wait.md curl_multi_waitfds.md curl_multi_wakeup.md curl_pushheader_byname.md curl_pushheader_bynum.md curl_share_cleanup.md curl_share_init.md curl_share_setopt.md curl_share_strerror.md curl_slist_append.md curl_slist_free_all.md curl_strequal.md curl_strnequal.md curl_unescape.md curl_url.md curl_url_cleanup.md curl_url_dup.md curl_url_get.md curl_url_set.md curl_url_strerror.md curl_version.md curl_version_info.md curl_ws_meta.md curl_ws_recv.md curl_ws_send.md curl_ws_start_frame.md libcurl-easy.md libcurl-env-dbg.md libcurl-env.md libcurl-errors.md libcurl-multi.md libcurl-security.md libcurl-share.md libcurl-thread.md libcurl-tutorial.md libcurl-url.md libcurl-ws.md libcurl.m4 libcurl.md mksymbolsmanpage.pl symbols-in-versions symbols.pl
tests CI.md FILEFORMAT.md HTTP.md TEST-SUITE.md
.gitignore ALTSVC.md BINDINGS.md BUG-BOUNTY.md BUGS.md CIPHERS-TLS12.md CIPHERS.md CMakeLists.txt CODE_OF_CONDUCT.md CODE_REVIEW.md CONTRIBUTE.md CURL-DISABLE.md CURLDOWN.md DEPRECATE.md DISTROS.md EARLY-RELEASE.md ECH.md EXPERIMENTAL.md FAQ.md FEATURES.md GOVERNANCE.md HELP-US.md HISTORY.md HSTS.md HTTP-COOKIES.md HTTP3.md HTTPSRR.md INFRASTRUCTURE.md INSTALL-CMAKE.md INSTALL.md INTERNALS.md IPFS.md KNOWN_BUGS.md KNOWN_RISKS.md MAIL-ETIQUETTE.md MANUAL.md Makefile.am README.md RELEASE-PROCEDURE.md ROADMAP.md RUSTLS.md SECURITY-ADVISORY.md SPONSORS.md SSL-PROBLEMS.md SSLCERTS.md THANKS THANKS-filter TODO.md TheArtOfHttpScripting.md URL-SYNTAX.md VERIFY.md VERSIONS.md VULN-DISCLOSURE-POLICY.md curl-config.md mk-ca-bundle.md options-in-versions runtests.md testcurl.md wcurl.md
include
curl Makefile.am curl.h curlver.h easy.h header.h mprintf.h multi.h options.h stdcheaders.h system.h typecheck-gcc.h urlapi.h websockets.h
Makefile.am README.md
lib
curlx base64.c base64.h basename.c basename.h dynbuf.c dynbuf.h fopen.c fopen.h inet_ntop.c inet_ntop.h inet_pton.c inet_pton.h multibyte.c multibyte.h nonblock.c nonblock.h snprintf.c snprintf.h strcopy.c strcopy.h strdup.c strdup.h strerr.c strerr.h strparse.c strparse.h timediff.c timediff.h timeval.c timeval.h version_win32.c version_win32.h wait.c wait.h warnless.c warnless.h winapi.c winapi.h
vauth cleartext.c cram.c digest.c digest.h digest_sspi.c gsasl.c krb5_gssapi.c krb5_sspi.c ntlm.c ntlm_sspi.c oauth2.c spnego_gssapi.c spnego_sspi.c vauth.c vauth.h
vquic curl_ngtcp2.c curl_ngtcp2.h curl_quiche.c curl_quiche.h vquic-tls.c vquic-tls.h vquic.c vquic.h vquic_int.h
vssh libssh.c libssh2.c ssh.h vssh.c vssh.h
vtls apple.c apple.h cipher_suite.c cipher_suite.h gtls.c gtls.h hostcheck.c hostcheck.h keylog.c keylog.h mbedtls.c mbedtls.h openssl.c openssl.h rustls.c rustls.h schannel.c schannel.h schannel_int.h schannel_verify.c vtls.c vtls.h vtls_int.h vtls_scache.c vtls_scache.h vtls_spack.c vtls_spack.h wolfssl.c wolfssl.h x509asn1.c x509asn1.h
.gitignore CMakeLists.txt Makefile.am Makefile.inc Makefile.soname altsvc.c altsvc.h amigaos.c amigaos.h arpa_telnet.h asyn-ares.c asyn-base.c asyn-thrdd.c asyn.h bufq.c bufq.h bufref.c bufref.h cf-dns.c cf-dns.h cf-h1-proxy.c cf-h1-proxy.h cf-h2-proxy.c cf-h2-proxy.h cf-haproxy.c cf-haproxy.h cf-https-connect.c cf-https-connect.h cf-ip-happy.c cf-ip-happy.h cf-socket.c cf-socket.h cfilters.c cfilters.h config-mac.h config-os400.h config-riscos.h config-win32.h conncache.c conncache.h connect.c connect.h content_encoding.c content_encoding.h cookie.c cookie.h creds.c creds.h cshutdn.c cshutdn.h curl_addrinfo.c curl_addrinfo.h curl_config-cmake.h.in curl_ctype.h curl_endian.c curl_endian.h curl_fnmatch.c curl_fnmatch.h curl_fopen.c curl_fopen.h curl_get_line.c curl_get_line.h curl_gethostname.c curl_gethostname.h curl_gssapi.c curl_gssapi.h curl_hmac.h curl_ldap.h curl_md4.h curl_md5.h curl_memrchr.c curl_memrchr.h curl_ntlm_core.c curl_ntlm_core.h curl_printf.h curl_range.c curl_range.h curl_sasl.c curl_sasl.h curl_setup.h curl_sha256.h curl_sha512_256.c curl_sha512_256.h curl_share.c curl_share.h curl_sspi.c curl_sspi.h curl_threads.c curl_threads.h curl_trc.c curl_trc.h cw-out.c cw-out.h cw-pause.c cw-pause.h dict.c dict.h dllmain.c dnscache.c dnscache.h doh.c doh.h dynhds.c dynhds.h easy.c easy_lock.h easygetopt.c easyif.h easyoptions.c easyoptions.h escape.c escape.h fake_addrinfo.c fake_addrinfo.h file.c file.h fileinfo.c fileinfo.h formdata.c formdata.h ftp-int.h ftp.c ftp.h ftplistparser.c ftplistparser.h functypes.h getenv.c getinfo.c getinfo.h gopher.c gopher.h hash.c hash.h headers.c headers.h hmac.c hostip.c hostip.h hostip4.c hostip6.c hsts.c hsts.h http.c http.h http1.c http1.h http2.c http2.h http_aws_sigv4.c http_aws_sigv4.h http_chunks.c http_chunks.h http_digest.c http_digest.h http_negotiate.c http_negotiate.h http_ntlm.c http_ntlm.h http_proxy.c http_proxy.h httpsrr.c httpsrr.h idn.c idn.h if2ip.c if2ip.h imap.c imap.h ldap.c libcurl.def libcurl.rc libcurl.vers.in llist.c llist.h macos.c macos.h md4.c md5.c memdebug.c mime.c mime.h mprintf.c mqtt.c mqtt.h multi.c multi_ev.c multi_ev.h multi_ntfy.c multi_ntfy.h multihandle.h multiif.h netrc.c netrc.h noproxy.c noproxy.h openldap.c optiontable.pl parsedate.c parsedate.h peer.c peer.h pingpong.c pingpong.h pop3.c pop3.h progress.c progress.h protocol.c protocol.h psl.c psl.h rand.c rand.h ratelimit.c ratelimit.h request.c request.h rtsp.c rtsp.h select.c select.h sendf.c sendf.h setopt.c setopt.h setup-os400.h setup-vms.h setup-win32.h sha256.c sigpipe.h slist.c slist.h smb.c smb.h smtp.c smtp.h sockaddr.h socketpair.c socketpair.h socks.c socks.h socks_gssapi.c socks_sspi.c splay.c splay.h strcase.c strcase.h strequal.c strerror.c strerror.h system_win32.c system_win32.h telnet.c telnet.h tftp.c tftp.h thrdpool.c thrdpool.h thrdqueue.c thrdqueue.h transfer.c transfer.h uint-bset.c uint-bset.h uint-hash.c uint-hash.h uint-spbset.c uint-spbset.h uint-table.c uint-table.h url.c url.h urlapi-int.h urlapi.c urldata.h version.c ws.c ws.h
m4 .gitignore curl-amissl.m4 curl-apple-sectrust.m4 curl-compilers.m4 curl-confopts.m4 curl-functions.m4 curl-gnutls.m4 curl-mbedtls.m4 curl-openssl.m4 curl-override.m4 curl-reentrant.m4 curl-rustls.m4 curl-schannel.m4 curl-sysconfig.m4 curl-wolfssl.m4 xc-am-iface.m4 xc-cc-check.m4 xc-lt-iface.m4 xc-val-flgs.m4 zz40-xc-ovr.m4 zz50-xc-ovr.m4
projects
OS400
rpg-examples HEADERAPI HTTPPOST INMEMORY SIMPLE1 SIMPLE2 SMTPSRCMBR
.checksrc README.OS400 ccsidcurl.c ccsidcurl.h config400.default curl.cmd curl.inc.in curlcl.c curlmain.c initscript.sh make-docs.sh make-include.sh make-lib.sh make-src.sh make-tests.sh makefile.sh os400sys.c os400sys.h
Windows
tmpl .gitattributes README.txt curl-all.sln curl.sln curl.vcxproj curl.vcxproj.filters libcurl.sln libcurl.vcxproj libcurl.vcxproj.filters
.gitignore README.md generate.bat
vms Makefile.am backup_gnv_curl_src.com build_curl-config_script.com build_gnv_curl.com build_gnv_curl_pcsi_desc.com build_gnv_curl_pcsi_text.com build_gnv_curl_release_notes.com build_libcurl_pc.com build_vms.com clean_gnv_curl.com compare_curl_source.com config_h.com curl_crtl_init.c curl_gnv_build_steps.txt curl_release_note_start.txt curl_startup.com curlmsg.h curlmsg.msg curlmsg.sdl curlmsg_vms.h generate_config_vms_h_curl.com generate_vax_transfer.com gnv_conftest.c_first gnv_curl_configure.sh gnv_libcurl_symbols.opt gnv_link_curl.com macro32_exactcase.patch make_gnv_curl_install.sh make_pcsi_curl_kit_name.com pcsi_gnv_curl_file_list.txt pcsi_product_gnv_curl.com readme report_openssl_version.c setup_gnv_curl_build.com stage_curl_install.com vms_eco_level.h
Makefile.am README.md
scripts .checksrc CMakeLists.txt Makefile.am badwords badwords-all badwords.txt cd2cd cd2nroff cdall checksrc-all.pl checksrc.pl cmakelint.sh completion.pl contributors.sh contrithanks.sh coverage.sh delta dmaketgz extract-unit-protos firefox-db2pem.sh installcheck.sh maketgz managen mdlinkcheck mk-ca-bundle.pl mk-unity.pl nroff2cd perlcheck.sh pythonlint.sh randdisable release-notes.pl release-tools.sh schemetable.c singleuse.pl spacecheck.pl top-complexity top-length verify-release wcurl
src
toolx tool_time.c tool_time.h
.checksrc .gitignore CMakeLists.txt Makefile.am Makefile.inc config2setopts.c config2setopts.h curl.rc curlinfo.c mk-file-embed.pl mkhelp.pl slist_wc.c slist_wc.h terminal.c terminal.h tool_cb_dbg.c tool_cb_dbg.h tool_cb_hdr.c tool_cb_hdr.h tool_cb_prg.c tool_cb_prg.h tool_cb_rea.c tool_cb_rea.h tool_cb_see.c tool_cb_see.h tool_cb_soc.c tool_cb_soc.h tool_cb_wrt.c tool_cb_wrt.h tool_cfgable.c tool_cfgable.h tool_dirhie.c tool_dirhie.h tool_doswin.c tool_doswin.h tool_easysrc.c tool_easysrc.h tool_filetime.c tool_filetime.h tool_findfile.c tool_findfile.h tool_formparse.c tool_formparse.h tool_getparam.c tool_getparam.h tool_getpass.c tool_getpass.h tool_help.c tool_help.h tool_helpers.c tool_helpers.h tool_hugehelp.h tool_ipfs.c tool_ipfs.h tool_libinfo.c tool_libinfo.h tool_listhelp.c tool_main.c tool_main.h tool_msgs.c tool_msgs.h tool_operate.c tool_operate.h tool_operhlp.c tool_operhlp.h tool_paramhlp.c tool_paramhlp.h tool_parsecfg.c tool_parsecfg.h tool_progress.c tool_progress.h tool_sdecls.h tool_setopt.c tool_setopt.h tool_setup.h tool_ssls.c tool_ssls.h tool_stderr.c tool_stderr.h tool_urlglob.c tool_urlglob.h tool_util.c tool_util.h tool_version.h tool_vms.c tool_vms.h tool_writeout.c tool_writeout.h tool_writeout_json.c tool_writeout_json.h tool_xattr.c tool_xattr.h var.c var.h
tests
certs .gitignore CMakeLists.txt Makefile.am Makefile.inc genserv.pl srp-verifier-conf srp-verifier-db test-ca.cnf test-ca.prm test-client-cert.prm test-client-eku-only.prm test-localhost-san-first.prm test-localhost-san-last.prm test-localhost.nn.prm test-localhost.prm test-localhost0h.prm
cmake CMakeLists.txt test.c test.cpp test.sh
data .gitignore DISABLED Makefile.am data-xml1 data1400.c data1401.c data1402.c data1403.c data1404.c data1405.c data1406.c data1407.c data1420.c data1461.txt data1463.txt data1465.c data1481.c data1705-1.md data1705-2.md data1705-3.md data1705-4.md data1705-stdout.1 data1706-1.md data1706-2.md data1706-3.md data1706-4.md data1706-stdout.txt data320.html test1 test10 test100 test1000 test1001 test1002 test1003 test1004 test1005 test1006 test1007 test1008 test1009 test101 test1010 test1011 test1012 test1013 test1014 test1015 test1016 test1017 test1018 test1019 test102 test1020 test1021 test1022 test1023 test1024 test1025 test1026 test1027 test1028 test1029 test103 test1030 test1031 test1032 test1033 test1034 test1035 test1036 test1037 test1038 test1039 test104 test1040 test1041 test1042 test1043 test1044 test1045 test1046 test1047 test1048 test1049 test105 test1050 test1051 test1052 test1053 test1054 test1055 test1056 test1057 test1058 test1059 test106 test1060 test1061 test1062 test1063 test1064 test1065 test1066 test1067 test1068 test1069 test107 test1070 test1071 test1072 test1073 test1074 test1075 test1076 test1077 test1078 test1079 test108 test1080 test1081 test1082 test1083 test1084 test1085 test1086 test1087 test1088 test1089 test109 test1090 test1091 test1092 test1093 test1094 test1095 test1096 test1097 test1098 test1099 test11 test110 test1100 test1101 test1102 test1103 test1104 test1105 test1106 test1107 test1108 test1109 test111 test1110 test1111 test1112 test1113 test1114 test1115 test1116 test1117 test1118 test1119 test112 test1120 test1121 test1122 test1123 test1124 test1125 test1126 test1127 test1128 test1129 test113 test1130 test1131 test1132 test1133 test1134 test1135 test1136 test1137 test1138 test1139 test114 test1140 test1141 test1142 test1143 test1144 test1145 test1146 test1147 test1148 test1149 test115 test1150 test1151 test1152 test1153 test1154 test1155 test1156 test1157 test1158 test1159 test116 test1160 test1161 test1162 test1163 test1164 test1165 test1166 test1167 test1168 test1169 test117 test1170 test1171 test1172 test1173 test1174 test1175 test1176 test1177 test1178 test1179 test118 test1180 test1181 test1182 test1183 test1184 test1185 test1186 test1187 test1188 test1189 test119 test1190 test1191 test1192 test1193 test1194 test1195 test1196 test1197 test1198 test1199 test12 test120 test1200 test1201 test1202 test1203 test1204 test1205 test1206 test1207 test1208 test1209 test121 test1210 test1211 test1212 test1213 test1214 test1215 test1216 test1217 test1218 test1219 test122 test1220 test1221 test1222 test1223 test1224 test1225 test1226 test1227 test1228 test1229 test123 test1230 test1231 test1232 test1233 test1234 test1235 test1236 test1237 test1238 test1239 test124 test1240 test1241 test1242 test1243 test1244 test1245 test1246 test1247 test1248 test1249 test125 test1250 test1251 test1252 test1253 test1254 test1255 test1256 test1257 test1258 test1259 test126 test1260 test1261 test1262 test1263 test1264 test1265 test1266 test1267 test1268 test1269 test127 test1270 test1271 test1272 test1273 test1274 test1275 test1276 test1277 test1278 test1279 test128 test1280 test1281 test1282 test1283 test1284 test1285 test1286 test1287 test1288 test1289 test129 test1290 test1291 test1292 test1293 test1294 test1295 test1296 test1297 test1298 test1299 test13 test130 test1300 test1301 test1302 test1303 test1304 test1305 test1306 test1307 test1308 test1309 test131 test1310 test1311 test1312 test1313 test1314 test1315 test1316 test1317 test1318 test1319 test132 test1320 test1321 test1322 test1323 test1324 test1325 test1326 test1327 test1328 test1329 test133 test1330 test1331 test1332 test1333 test1334 test1335 test1336 test1337 test1338 test1339 test134 test1340 test1341 test1342 test1343 test1344 test1345 test1346 test1347 test1348 test1349 test135 test1350 test1351 test1352 test1353 test1354 test1355 test1356 test1357 test1358 test1359 test136 test1360 test1361 test1362 test1363 test1364 test1365 test1366 test1367 test1368 test1369 test137 test1370 test1371 test1372 test1373 test1374 test1375 test1376 test1377 test1378 test1379 test138 test1380 test1381 test1382 test1383 test1384 test1385 test1386 test1387 test1388 test1389 test139 test1390 test1391 test1392 test1393 test1394 test1395 test1396 test1397 test1398 test1399 test14 test140 test1400 test1401 test1402 test1403 test1404 test1405 test1406 test1407 test1408 test1409 test141 test1410 test1411 test1412 test1413 test1414 test1415 test1416 test1417 test1418 test1419 test142 test1420 test1421 test1422 test1423 test1424 test1425 test1426 test1427 test1428 test1429 test143 test1430 test1431 test1432 test1433 test1434 test1435 test1436 test1437 test1438 test1439 test144 test1440 test1441 test1442 test1443 test1444 test1445 test1446 test1447 test1448 test1449 test145 test1450 test1451 test1452 test1453 test1454 test1455 test1456 test1457 test1458 test1459 test146 test1460 test1461 test1462 test1463 test1464 test1465 test1466 test1467 test1468 test1469 test147 test1470 test1471 test1472 test1473 test1474 test1475 test1476 test1477 test1478 test1479 test148 test1480 test1481 test1482 test1483 test1484 test1485 test1486 test1487 test1488 test1489 test149 test1490 test1491 test1492 test1493 test1494 test1495 test1496 test1497 test1498 test1499 test15 test150 test1500 test1501 test1502 test1503 test1504 test1505 test1506 test1507 test1508 test1509 test151 test1510 test1511 test1512 test1513 test1514 test1515 test1516 test1517 test1518 test1519 test152 test1520 test1521 test1522 test1523 test1524 test1525 test1526 test1527 test1528 test1529 test153 test1530 test1531 test1532 test1533 test1534 test1535 test1536 test1537 test1538 test1539 test154 test1540 test1541 test1542 test1543 test1544 test1545 test1546 test1547 test1548 test1549 test155 test1550 test1551 test1552 test1553 test1554 test1555 test1556 test1557 test1558 test1559 test156 test1560 test1561 test1562 test1563 test1564 test1565 test1566 test1567 test1568 test1569 test157 test1570 test1571 test1572 test1573 test1574 test1575 test1576 test1577 test1578 test1579 test158 test1580 test1581 test1582 test1583 test1584 test1585 test1586 test1587 test1588 test1589 test159 test1590 test1591 test1592 test1593 test1594 test1595 test1596 test1597 test1598 test1599 test16 test160 test1600 test1601 test1602 test1603 test1604 test1605 test1606 test1607 test1608 test1609 test161 test1610 test1611 test1612 test1613 test1614 test1615 test1616 test1617 test1618 test1619 test162 test1620 test1621 test1622 test1623 test1624 test1625 test1626 test1627 test1628 test1629 test163 test1630 test1631 test1632 test1633 test1634 test1635 test1636 test1637 test1638 test1639 test164 test1640 test1641 test1642 test1643 test1644 test1645 test165 test1650 test1651 test1652 test1653 test1654 test1655 test1656 test1657 test1658 test1659 test166 test1660 test1661 test1662 test1663 test1664 test1665 test1666 test1667 test1668 test1669 test167 test1670 test1671 test1672 test1673 test1674 test1675 test1676 test168 test1680 test1681 test1682 test1683 test1684 test1685 test169 test17 test170 test1700 test1701 test1702 test1703 test1704 test1705 test1706 test1707 test1708 test1709 test171 test1710 test1711 test1712 test1713 test1714 test1715 test172 test1720 test1721 test173 test174 test175 test176 test177 test178 test179 test18 test180 test1800 test1801 test1802 test181 test182 test183 test184 test1847 test1848 test1849 test185 test1850 test1851 test186 test187 test188 test189 test19 test190 test1900 test1901 test1902 test1903 test1904 test1905 test1906 test1907 test1908 test1909 test191 test1910 test1911 test1912 test1913 test1914 test1915 test1916 test1917 test1918 test1919 test192 test1920 test1921 test193 test1933 test1934 test1935 test1936 test1937 test1938 test1939 test194 test1940 test1941 test1942 test1943 test1944 test1945 test1946 test1947 test1948 test195 test1955 test1956 test1957 test1958 test1959 test196 test1960 test1964 test1965 test1966 test197 test1970 test1971 test1972 test1973 test1974 test1975 test1976 test1977 test1978 test1979 test198 test1980 test1981 test1982 test1983 test1984 test199 test2 test20 test200 test2000 test2001 test2002 test2003 test2004 test2005 test2006 test2007 test2008 test2009 test201 test2010 test2011 test2012 test2013 test2014 test202 test2023 test2024 test2025 test2026 test2027 test2028 test2029 test203 test2030 test2031 test2032 test2033 test2034 test2035 test2037 test2038 test2039 test204 test2040 test2041 test2042 test2043 test2044 test2045 test2046 test2047 test2048 test2049 test205 test2050 test2051 test2052 test2053 test2054 test2055 test2056 test2057 test2058 test2059 test206 test2060 test2061 test2062 test2063 test2064 test2065 test2066 test2067 test2068 test2069 test207 test2070 test2071 test2072 test2073 test2074 test2075 test2076 test2077 test2078 test2079 test208 test2080 test2081 test2082 test2083 test2084 test2085 test2086 test2087 test2088 test2089 test209 test2090 test2091 test2092 test21 test210 test2100 test2101 test2102 test2103 test2104 test211 test212 test213 test214 test215 test216 test217 test218 test219 test22 test220 test2200 test2201 test2202 test2203 test2204 test2205 test2206 test2207 test221 test222 test223 test224 test225 test226 test227 test228 test229 test23 test230 test2300 test2301 test2302 test2303 test2304 test2306 test2307 test2308 test2309 test231 test232 test233 test234 test235 test236 test237 test238 test239 test24 test240 test2400 test2401 test2402 test2403 test2404 test2405 test2406 test2407 test2408 test2409 test241 test2410 test2411 test242 test243 test244 test245 test246 test247 test248 test249 test25 test250 test2500 test2501 test2502 test2503 test2504 test2505 test2506 test251 test252 test253 test254 test255 test256 test257 test258 test259 test26 test260 test2600 test2601 test2602 test2603 test2604 test2605 test261 test262 test263 test264 test265 test266 test267 test268 test269 test27 test270 test2700 test2701 test2702 test2703 test2704 test2705 test2706 test2707 test2708 test2709 test271 test2710 test2711 test2712 test2713 test2714 test2715 test2716 test2717 test2718 test2719 test272 test2720 test2721 test2722 test2723 test273 test274 test275 test276 test277 test278 test279 test28 test280 test281 test282 test283 test284 test285 test286 test287 test288 test289 test29 test290 test291 test292 test293 test294 test295 test296 test297 test298 test299 test3 test30 test300 test3000 test3001 test3002 test3003 test3004 test3005 test3006 test3007 test3008 test3009 test301 test3010 test3011 test3012 test3013 test3014 test3015 test3016 test3017 test3018 test3019 test302 test3020 test3021 test3022 test3023 test3024 test3025 test3026 test3027 test3028 test3029 test303 test3030 test3031 test3032 test3033 test3034 test3035 test3036 test304 test305 test306 test307 test308 test309 test31 test310 test3100 test3101 test3102 test3103 test3104 test3105 test3106 test311 test312 test313 test314 test315 test316 test317 test318 test319 test32 test320 test3200 test3201 test3202 test3203 test3204 test3205 test3206 test3207 test3208 test3209 test321 test3210 test3211 test3212 test3213 test3214 test3215 test3216 test3217 test3218 test3219 test322 test3220 test323 test324 test325 test326 test327 test328 test329 test33 test330 test3300 test3301 test3302 test331 test332 test333 test334 test335 test336 test337 test338 test339 test34 test340 test341 test342 test343 test344 test345 test346 test347 test348 test349 test35 test350 test351 test352 test353 test354 test355 test356 test357 test358 test359 test36 test360 test361 test362 test363 test364 test365 test366 test367 test368 test369 test37 test370 test371 test372 test373 test374 test375 test376 test378 test379 test38 test380 test381 test383 test384 test385 test386 test387 test388 test389 test39 test390 test391 test392 test393 test394 test395 test396 test397 test398 test399 test4 test40 test400 test4000 test4001 test401 test402 test403 test404 test405 test406 test407 test408 test409 test41 test410 test411 test412 test413 test414 test415 test416 test417 test418 test419 test42 test420 test421 test422 test423 test424 test425 test426 test427 test428 test429 test43 test430 test431 test432 test433 test434 test435 test436 test437 test438 test439 test44 test440 test441 test442 test443 test444 test445 test446 test447 test448 test449 test45 test450 test451 test452 test453 test454 test455 test456 test457 test458 test459 test46 test460 test461 test462 test463 test467 test468 test469 test47 test470 test471 test472 test473 test474 test475 test476 test477 test478 test479 test48 test480 test481 test482 test483 test484 test485 test486 test487 test488 test489 test49 test490 test491 test492 test493 test494 test495 test496 test497 test498 test499 test5 test50 test500 test501 test502 test503 test504 test505 test506 test507 test508 test509 test51 test510 test511 test512 test513 test514 test515 test516 test517 test518 test519 test52 test520 test521 test522 test523 test524 test525 test526 test527 test528 test529 test53 test530 test531 test532 test533 test534 test535 test536 test537 test538 test539 test54 test540 test541 test542 test543 test544 test545 test546 test547 test548 test549 test55 test550 test551 test552 test553 test554 test555 test556 test557 test558 test559 test56 test560 test561 test562 test563 test564 test565 test566 test567 test568 test569 test57 test570 test571 test572 test573 test574 test575 test576 test577 test578 test579 test58 test580 test581 test582 test583 test584 test585 test586 test587 test588 test589 test59 test590 test591 test592 test593 test594 test595 test596 test597 test598 test599 test6 test60 test600 test601 test602 test603 test604 test605 test606 test607 test608 test609 test61 test610 test611 test612 test613 test614 test615 test616 test617 test618 test619 test62 test620 test621 test622 test623 test624 test625 test626 test627 test628 test629 test63 test630 test631 test632 test633 test634 test635 test636 test637 test638 test639 test64 test640 test641 test642 test643 test644 test645 test646 test647 test648 test649 test65 test650 test651 test652 test653 test654 test655 test656 test658 test659 test66 test660 test661 test662 test663 test664 test665 test666 test667 test668 test669 test67 test670 test671 test672 test673 test674 test675 test676 test677 test678 test679 test68 test680 test681 test682 test683 test684 test685 test686 test687 test688 test689 test69 test690 test691 test692 test693 test694 test695 test696 test697 test698 test699 test7 test70 test700 test701 test702 test703 test704 test705 test706 test707 test708 test709 test71 test710 test711 test712 test713 test714 test715 test716 test717 test718 test719 test72 test720 test721 test722 test723 test724 test725 test726 test727 test728 test729 test73 test730 test731 test732 test733 test734 test735 test736 test737 test738 test739 test74 test740 test741 test742 test743 test744 test745 test746 test747 test748 test749 test75 test750 test751 test752 test753 test754 test755 test756 test757 test758 test759 test76 test760 test761 test762 test763 test764 test765 test766 test767 test768 test769 test77 test770 test771 test772 test773 test774 test775 test776 test777 test778 test779 test78 test780 test781 test782 test783 test784 test785 test786 test787 test788 test789 test79 test790 test791 test792 test793 test794 test795 test796 test797 test798 test799 test8 test80 test800 test801 test802 test803 test804 test805 test806 test807 test808 test809 test81 test810 test811 test812 test813 test814 test815 test816 test817 test818 test819 test82 test820 test821 test822 test823 test824 test825 test826 test827 test828 test829 test83 test830 test831 test832 test833 test834 test835 test836 test837 test838 test839 test84 test840 test841 test842 test843 test844 test845 test846 test847 test848 test849 test85 test850 test851 test852 test853 test854 test855 test856 test857 test858 test859 test86 test860 test861 test862 test863 test864 test865 test866 test867 test868 test869 test87 test870 test871 test872 test873 test874 test875 test876 test877 test878 test879 test88 test880 test881 test882 test883 test884 test885 test886 test887 test888 test889 test89 test890 test891 test892 test893 test894 test895 test896 test897 test898 test899 test9 test90 test900 test901 test902 test903 test904 test905 test906 test907 test908 test909 test91 test910 test911 test912 test913 test914 test915 test916 test917 test918 test919 test92 test920 test921 test922 test923 test924 test925 test926 test927 test928 test929 test93 test930 test931 test932 test933 test934 test935 test936 test937 test938 test939 test94 test940 test941 test942 test943 test944 test945 test946 test947 test948 test949 test95 test950 test951 test952 test953 test954 test955 test956 test957 test958 test959 test96 test960 test961 test962 test963 test964 test965 test966 test967 test968 test969 test97 test970 test971 test972 test973 test974 test975 test976 test977 test978 test979 test98 test980 test981 test982 test983 test984 test985 test986 test987 test988 test989 test99 test990 test991 test992 test993 test994 test995 test996 test997 test998 test999
http
testenv
mod_curltest .gitignore mod_curltest.c
__init__.py caddy.py certs.py client.py curl.py dante.py dnsd.py env.py httpd.py nghttpx.py ports.py sshd.py vsftpd.py ws_echo_server.py
.gitignore CMakeLists.txt Makefile.am config.ini.in conftest.py requirements.txt scorecard.py test_01_basic.py test_02_download.py test_03_goaway.py test_04_stuttered.py test_05_errors.py test_06_eyeballs.py test_07_upload.py test_08_caddy.py test_09_push.py test_10_proxy.py test_11_unix.py test_12_reuse.py test_13_proxy_auth.py test_14_auth.py test_15_tracing.py test_16_info.py test_17_ssl_use.py test_18_methods.py test_19_shutdown.py test_20_websockets.py test_21_resolve.py test_22_httpsrr.py test_30_vsftpd.py test_31_vsftpds.py test_32_ftps_vsftpd.py test_40_socks.py test_50_scp.py test_51_sftp.py
libtest .gitignore CMakeLists.txt Makefile.am Makefile.inc cli_ftp_upload.c cli_h2_pausing.c cli_h2_serverpush.c cli_h2_upgrade_extreme.c cli_hx_download.c cli_hx_upload.c cli_tls_session_reuse.c cli_upload_pausing.c cli_ws_data.c cli_ws_pingpong.c first.c first.h lib1156.c lib1301.c lib1308.c lib1485.c lib1500.c lib1501.c lib1502.c lib1506.c lib1507.c lib1508.c lib1509.c lib1510.c lib1511.c lib1512.c lib1513.c lib1514.c lib1515.c lib1517.c lib1518.c lib1520.c lib1522.c lib1523.c lib1525.c lib1526.c lib1527.c lib1528.c lib1529.c lib1530.c lib1531.c lib1532.c lib1533.c lib1534.c lib1535.c lib1536.c lib1537.c lib1538.c lib1540.c lib1541.c lib1542.c lib1545.c lib1549.c lib1550.c lib1551.c lib1552.c lib1553.c lib1554.c lib1555.c lib1556.c lib1557.c lib1558.c lib1559.c lib1560.c lib1564.c lib1565.c lib1567.c lib1568.c lib1569.c lib1571.c lib1576.c lib1582.c lib1587.c lib1588.c lib1589.c lib1591.c lib1592.c lib1593.c lib1594.c lib1597.c lib1598.c lib1599.c lib1662.c lib1900.c lib1901.c lib1902.c lib1903.c lib1905.c lib1906.c lib1907.c lib1908.c lib1910.c lib1911.c lib1912.c lib1913.c lib1915.c lib1916.c lib1918.c lib1919.c lib1920.c lib1921.c lib1933.c lib1934.c lib1935.c lib1936.c lib1937.c lib1938.c lib1939.c lib1940.c lib1945.c lib1947.c lib1948.c lib1955.c lib1956.c lib1957.c lib1958.c lib1959.c lib1960.c lib1964.c lib1965.c lib1970.c lib1971.c lib1972.c lib1973.c lib1974.c lib1975.c lib1977.c lib1978.c lib2023.c lib2032.c lib2082.c lib2301.c lib2302.c lib2304.c lib2306.c lib2308.c lib2309.c lib2402.c lib2404.c lib2405.c lib2502.c lib2504.c lib2505.c lib2506.c lib2700.c lib3010.c lib3025.c lib3026.c lib3027.c lib3033.c lib3034.c lib3100.c lib3101.c lib3102.c lib3103.c lib3104.c lib3105.c lib3207.c lib3208.c lib500.c lib501.c lib502.c lib503.c lib504.c lib505.c lib506.c lib507.c lib508.c lib509.c lib510.c lib511.c lib512.c lib513.c lib514.c lib515.c lib516.c lib517.c lib518.c lib519.c lib520.c lib521.c lib523.c lib524.c lib525.c lib526.c lib530.c lib533.c lib536.c lib537.c lib539.c lib540.c lib541.c lib542.c lib543.c lib544.c lib547.c lib549.c lib552.c lib553.c lib554.c lib555.c lib556.c lib557.c lib558.c lib559.c lib560.c lib562.c lib564.c lib566.c lib567.c lib568.c lib569.c lib570.c lib571.c lib572.c lib573.c lib574.c lib575.c lib576.c lib578.c lib579.c lib582.c lib583.c lib586.c lib589.c lib590.c lib591.c lib597.c lib598.c lib599.c lib643.c lib650.c lib651.c lib652.c lib653.c lib654.c lib655.c lib658.c lib659.c lib661.c lib666.c lib667.c lib668.c lib670.c lib674.c lib676.c lib677.c lib678.c lib694.c lib695.c lib751.c lib753.c lib757.c lib758.c lib766.c memptr.c mk-lib1521.pl test1013.pl test1022.pl test307.pl test610.pl test613.pl testtrace.c testtrace.h testutil.c testutil.h unitcheck.h
server .checksrc .gitignore CMakeLists.txt Makefile.am Makefile.inc dnsd.c first.c first.h getpart.c mqttd.c resolve.c rtspd.c sockfilt.c socksd.c sws.c tftpd.c util.c
tunit .gitignore CMakeLists.txt Makefile.am Makefile.inc README.md tool1394.c tool1604.c tool1621.c tool1622.c tool1623.c tool1720.c
unit .gitignore CMakeLists.txt Makefile.am Makefile.inc README.md unit1300.c unit1302.c unit1303.c unit1304.c unit1305.c unit1307.c unit1309.c unit1323.c unit1330.c unit1395.c unit1396.c unit1397.c unit1398.c unit1399.c unit1600.c unit1601.c unit1602.c unit1603.c unit1605.c unit1606.c unit1607.c unit1608.c unit1609.c unit1610.c unit1611.c unit1612.c unit1614.c unit1615.c unit1616.c unit1620.c unit1625.c unit1626.c unit1627.c unit1636.c unit1650.c unit1651.c unit1652.c unit1653.c unit1654.c unit1655.c unit1656.c unit1657.c unit1658.c unit1660.c unit1661.c unit1663.c unit1664.c unit1666.c unit1667.c unit1668.c unit1669.c unit1674.c unit1675.c unit1676.c unit1979.c unit1980.c unit2600.c unit2601.c unit2602.c unit2603.c unit2604.c unit2605.c unit3200.c unit3205.c unit3211.c unit3212.c unit3213.c unit3214.c unit3216.c unit3219.c unit3300.c unit3301.c unit3302.c
.gitignore CMakeLists.txt Makefile.am allversions.pm appveyor.pm azure.pm config.in configurehelp.pm.in devtest.pl dictserver.py directories.pm ech_combos.py ech_tests.sh ftpserver.pl getpart.pm globalconfig.pm http-server.pl http2-server.pl http3-server.pl memanalyze.pl memanalyzer.pm negtelnetserver.py nghttpx.conf pathhelp.pm processhelp.pm requirements.txt rtspserver.pl runner.pm runtests.pl secureserver.pl serverhelp.pm servers.pm smbserver.py sshhelp.pm sshserver.pl test1119.pl test1135.pl test1139.pl test1140.pl test1165.pl test1167.pl test1173.pl test1175.pl test1177.pl test1222.pl test1275.pl test1276.pl test1477.pl test1486.pl test1488.pl test1544.pl test1707.pl test745.pl test971.pl testcurl.pl testutil.pm tftpserver.pl util.py valgrind.pm valgrind.supp
.clang-tidy.yml .dir-locals.el .editorconfig .git-blame-ignore-revs .gitattributes .gitignore .mailmap CHANGES.md CMakeLists.txt COPYING Dockerfile GIT-INFO.md Makefile.am README README.md RELEASE-NOTES REUSE.toml SECURITY.md acinclude.m4 appveyor.sh appveyor.yml configure.ac curl-config.in libcurl.pc.in renovate.json
examples .env config.ini crypto_test.lua env_test.lua fs_example.lua http_server.lua https_test.lua ini_example.lua json.lua log.lua path_fs_example.lua process_example.lua request_download.lua request_test.lua run_all.lua sqlite_example.lua sqlite_http_template.lua stash_test.lua template_test.lua timer.lua websocket.lua
iniparser
.github
ISSUE_TEMPLATE config.yml
workflows disable-pull-requests.yml trigger-gitlab-ci.yml
cmake JoinPaths.cmake config.cmake.in pc.in
example iniexample.c iniwrite.c parse.c twisted-errors.ini twisted-genhuge.py twisted-ofkey.ini twisted-ofval.ini twisted.ini
src dictionary.c dictionary.h iniparser.c iniparser.h
test
ressources
bad_ini ends_well.ini twisted-errors.ini twisted-ofkey.ini twisted-ofval.ini
good_ini empty.ini spaced.ini spaced2.ini twisted.ini
gruezi.ini old.ini quotes.ini utf8.ini
CMakeLists.txt test_dictionary.c test_iniparser.c unity-config.yml unity_config.h
.cmake-format.py .gitignore .gitlab-ci.yml .gitmessage .travis.yml AUTHORS CMakeLists.txt FAQ-en.md FAQ-zhcn.md INSTALL LICENSE README.md compile_commands.json
jinjac
example CMakeLists.txt example.c
jinjac_test_app CMakeLists.txt jinjac_test_app.c
libjinjac
include jinjac.h
src CMakeLists.txt ast.c ast.h block_statement.c block_statement.h buffer.c buffer.h buildin.c buildin.h common.h convert.c convert.h flex_decl.h jfunction.c jfunction.h jinja_expression.l jinja_expression.y jinjac_parse.c jinjac_parse.h jinjac_stream.c jinjac_stream.h jlist.c jlist.h jobject.c jobject.h parameter.c parameter.h str_obj.c str_obj.h trace.c trace.h
CMakeLists.txt
test .gitignore CMakeLists.txt autotest.rb test_01.expected test_01.jinja test_01b.expected test_01b.jinja test_01c.expected test_01c.jinja test_01d.expected test_01d.jinja test_02.expected test_02.jinja test_03.expected test_03.jinja test_04.expected test_04.jinja test_05.expected test_05.jinja test_06.expected test_06.jinja test_07.expected test_07.jinja test_08.expected test_08.jinja test_08b.expected test_08b.jinja test_09.expected test_09.jinja test_10.expected test_10.jinja test_11.expected test_11.jinja test_12.expected test_12.jinja test_13.expected test_13.jinja test_14.expected test_14.jinja test_15.expected test_15.jinja test_16.expected test_16.jinja test_17.expected test_17.jinja test_18.expected test_18.jinja test_18b.expected test_18b.jinja test_18c.expected test_18c.jinja test_19.expected test_19.jinja test_19b.expected test_19b.jinja test_19c.expected test_19c.jinja test_19d.expected test_19d.jinja test_19e.expected test_19e.jinja test_19f.expected test_19f.jinja test_20.expected test_20.jinja test_21.expected test_21.jinja test_22.expected test_22.jinja test_22a.expected test_22a.jinja test_22b.expected test_22b.jinja test_23.expected test_23.jinja test_24.expected test_24.jinja
.gitignore CMakeLists.txt LICENSE.txt README.md build_coverage.sh build_debug.sh build_release.sh cppcheck_analysis.sh
libev Changes LICENSE Makefile Makefile.am Makefile.in README Symbols.ev Symbols.event aclocal.m4 autogen.sh compile config.guess config.h config.h.in config.status config.sub configure configure.ac depcomp ev++.h ev.3 ev.c ev.h ev.pod ev_epoll.c ev_kqueue.c ev_poll.c ev_port.c ev_select.c ev_vars.h ev_win32.c ev_wrap.h event.c event.h install-sh libev.m4 libtool ltmain.sh missing mkinstalldirs stamp-h1
luajit
doc
img contact.png
bluequad-print.css bluequad.css contact.html ext_buffer.html ext_c_api.html ext_ffi.html ext_ffi_api.html ext_ffi_semantics.html ext_ffi_tutorial.html ext_jit.html ext_profiler.html extensions.html install.html luajit.html running.html
dynasm dasm_arm.h dasm_arm.lua dasm_arm64.h dasm_arm64.lua dasm_mips.h dasm_mips.lua dasm_mips64.lua dasm_ppc.h dasm_ppc.lua dasm_proto.h dasm_x64.lua dasm_x86.h dasm_x86.lua dynasm.lua
etc luajit.1 luajit.pc
src
host .gitignore README buildvm.c buildvm.h buildvm_asm.c buildvm_fold.c buildvm_lib.c buildvm_libbc.h buildvm_peobj.c genlibbc.lua genminilua.lua genversion.lua minilua.c
jit .gitignore bc.lua bcsave.lua dis_arm.lua dis_arm64.lua dis_arm64be.lua dis_mips.lua dis_mips64.lua dis_mips64el.lua dis_mips64r6.lua dis_mips64r6el.lua dis_mipsel.lua dis_ppc.lua dis_x64.lua dis_x86.lua dump.lua p.lua v.lua zone.lua
.gitignore Makefile Makefile.dep lauxlib.h lib_aux.c lib_base.c lib_bit.c lib_buffer.c lib_debug.c lib_ffi.c lib_init.c lib_io.c lib_jit.c lib_math.c lib_os.c lib_package.c lib_string.c lib_table.c lj_alloc.c lj_alloc.h lj_api.c lj_arch.h lj_asm.c lj_asm.h lj_asm_arm.h lj_asm_arm64.h lj_asm_mips.h lj_asm_ppc.h lj_asm_x86.h lj_assert.c lj_bc.c lj_bc.h lj_bcdump.h lj_bcread.c lj_bcwrite.c lj_buf.c lj_buf.h lj_carith.c lj_carith.h lj_ccall.c lj_ccall.h lj_ccallback.c lj_ccallback.h lj_cconv.c lj_cconv.h lj_cdata.c lj_cdata.h lj_char.c lj_char.h lj_clib.c lj_clib.h lj_cparse.c lj_cparse.h lj_crecord.c lj_crecord.h lj_ctype.c lj_ctype.h lj_debug.c lj_debug.h lj_def.h lj_dispatch.c lj_dispatch.h lj_emit_arm.h lj_emit_arm64.h lj_emit_mips.h lj_emit_ppc.h lj_emit_x86.h lj_err.c lj_err.h lj_errmsg.h lj_ff.h lj_ffrecord.c lj_ffrecord.h lj_frame.h lj_func.c lj_func.h lj_gc.c lj_gc.h lj_gdbjit.c lj_gdbjit.h lj_ir.c lj_ir.h lj_ircall.h lj_iropt.h lj_jit.h lj_lex.c lj_lex.h lj_lib.c lj_lib.h lj_load.c lj_mcode.c lj_mcode.h lj_meta.c lj_meta.h lj_obj.c lj_obj.h lj_opt_dce.c lj_opt_fold.c lj_opt_loop.c lj_opt_mem.c lj_opt_narrow.c lj_opt_sink.c lj_opt_split.c lj_parse.c lj_parse.h lj_prng.c lj_prng.h lj_profile.c lj_profile.h lj_record.c lj_record.h lj_serialize.c lj_serialize.h lj_snap.c lj_snap.h lj_state.c lj_state.h lj_str.c lj_str.h lj_strfmt.c lj_strfmt.h lj_strfmt_num.c lj_strscan.c lj_strscan.h lj_tab.c lj_tab.h lj_target.h lj_target_arm.h lj_target_arm64.h lj_target_mips.h lj_target_ppc.h lj_target_x86.h lj_trace.c lj_trace.h lj_traceerr.h lj_udata.c lj_udata.h lj_vm.h lj_vmevent.c lj_vmevent.h lj_vmmath.c ljamalg.c lua.h lua.hpp luaconf.h luajit.c luajit_rolling.h lualib.h msvcbuild.bat nxbuild.bat ps4build.bat ps5build.bat psvitabuild.bat vm_arm.dasc vm_arm64.dasc vm_mips.dasc vm_mips64.dasc vm_ppc.dasc vm_x64.dasc vm_x86.dasc xb1build.bat xedkbuild.bat
.gitattributes .gitignore .relver COPYRIGHT Makefile README
sqlite shell.c sqlite3.c sqlite3.h sqlite3ext.h
wolfssl
.github
ISSUE_TEMPLATE bug_report.yaml other.yaml
actions
install-apt-deps action.yml
scripts
zephyr-4.x external_libc.conf zephyr-test.sh
openssl-ech.sh tls-anvil-test.sh
workflows
disabled haproxy.yml hitch.yml hostap.yml
hostap-files
configs
07c9f183ea744ac04585fb6dd10220c75a5e2e74 hostapd.config tests wpa_supplicant.config
b607d2723e927a3446d89aed813f1aa6068186bb hostapd.config tests wpa_supplicant.config
hostap_2_10 extra.patch hostapd.config tests wpa_supplicant.config
Makefile README dbus-wpa_supplicant.conf
ada.yml arduino.yml async-examples.yml async.yml atecc608-sim.yml bind.yml cmake-autoconf.yml cmake.yml codespell.yml coverity-scan-fixes.yml cryptocb-only.yml curl.yml cyrus-sasl.yml disable-pk-algs.yml docker-Espressif.yml docker-OpenWrt.yml emnet-nonblock.yml fil-c.yml freertos-mem-track.yml gencertbuf.yml grpc.yml haproxy.yml hostap-vm.yml intelasm-c-fallback.yml ipmitool.yml jwt-cpp.yml krb5.yml libspdm.yml libssh2.yml libvncserver.yml linuxkm.yml macos-apple-native-cert-validation.yml mbedtls.sh mbedtls.yml membrowse-comment.yml membrowse-onboard.yml membrowse-report.yml memcached.sh memcached.yml mono.yml mosquitto.yml msmtp.yml msys2.yml multi-arch.yml multi-compiler.yml net-snmp.yml nginx.yml no-malloc.yml no-tls.yml nss.sh nss.yml ntp.yml ocsp.yml openldap.yml openssh.yml openssl-ech.yml opensslcoexist.yml openvpn.yml os-check.yml packaging.yml pam-ipmi.yml pq-all.yml pr-commit-check.yml psk.yml puf.yml python.yml rng-tools.yml rust-wrapper.yml se050-sim.yml smallStackSize.yml socat.yml softhsm.yml sssd.yml stm32-sim.yml stsafe-a120-sim.yml stunnel.yml symbol-prefixes.yml threadx.yml tls-anvil.yml trackmemory.yml watcomc.yml win-csharp-test.yml wolfCrypt-Wconversion.yml wolfboot-integration.yml wolfsm.yml xcode.yml zephyr-4.x.yml zephyr.yml
PULL_REQUEST_TEMPLATE.md SECURITY.md membrowse-targets.json
Docker
OpenWrt Dockerfile README.md runTests.sh
packaging
debian Dockerfile
fedora Dockerfile
wolfCLU Dockerfile README.md
yocto Dockerfile buildAndPush.sh
Dockerfile Dockerfile.cross-compiler README.md buildAndPush.sh include.am run.sh
IDE
ARDUINO
sketches
wolfssl_client README.md
wolfssl_server README.md
wolfssl_version README.md
README.md
Arduino_README_prepend.md README.md include.am keywords.txt library.properties.template wolfssl-arduino.cpp wolfssl-arduino.sh wolfssl.h
AURIX Cpu0_Main.c README.md include.am user_settings.h wolf_main.c
Android Android.bp README.md include.am user_settings.h
CRYPTOCELL README.md include.am main.c user_settings.h
CSBENCH include.am user_settings.h
ECLIPSE
DEOS
deos_wolfssl .options
README.md deos_malloc.c include.am tls_wolfssl.c tls_wolfssl.h user_settings.h
MICRIUM README.md client_wolfssl.c client_wolfssl.h include.am server_wolfssl.c server_wolfssl.h user_settings.h wolfsslRunTests.c
RTTHREAD README.md include.am user_settings.h wolfssl_test.c
SIFIVE README.md include.am
Espressif
ESP-IDF
examples
template
VisualGDB wolfssl_template_IDF_v5.1_ESP32.vgdbproj
components
wolfssl
include user_settings.h
CMakeLists.txt Kconfig README.md component.mk
main
include main.h
CMakeLists.txt Kconfig.projbuild component.mk main.c
CMakeLists.txt Makefile README.md partitions_singleapp_large.csv sdkconfig.defaults sdkconfig.defaults.esp8266
wolfssl_benchmark
VisualGDB wolfssl_benchmark_IDF_v4.4_ESP32.sln wolfssl_benchmark_IDF_v4.4_ESP32.vgdbproj wolfssl_benchmark_IDF_v5_ESP32.sln wolfssl_benchmark_IDF_v5_ESP32.vgdbproj wolfssl_benchmark_IDF_v5_ESP32C3.sln wolfssl_benchmark_IDF_v5_ESP32C3.vgdbproj wolfssl_benchmark_IDF_v5_ESP32S3.sln wolfssl_benchmark_IDF_v5_ESP32S3.vgdbproj
components
wolfssl
include user_settings.h
CMakeLists.txt Kconfig README.md component.mk
main
include main.h
CMakeLists.txt Kconfig.projbuild component.mk main.c
CMakeLists.txt Makefile README.md partitions_singleapp_large.csv sdkconfig.defaults sdkconfig.defaults.esp8266
wolfssl_client
VisualGDB README.md wolfssl_client_IDF_v5_ESP32.sln wolfssl_client_IDF_v5_ESP32.vgdbproj
components
wolfssl
include user_settings.h
CMakeLists.txt Kconfig README.md component.mk
main
include client-tls.h main.h time_helper.h wifi_connect.h
CMakeLists.txt Kconfig.projbuild client-tls.c component.mk main.c time_helper.c wifi_connect.c
CMakeLists.txt Makefile README.md README_server_sm.md partitions_singleapp_large.csv sdkconfig.defaults sdkconfig.defaults.esp32c2 sdkconfig.defaults.esp8266 wolfssl_client_ESP8266.vgdbproj
wolfssl_server
VisualGDB README.md wolfssl_server_IDF_v5_ESP32.sln wolfssl_server_IDF_v5_ESP32.vgdbproj
components
wolfssl
include user_settings.h
CMakeLists.txt Kconfig README.md component.mk
main
include main.h server-tls.h time_helper.h wifi_connect.h
CMakeLists.txt Kconfig.projbuild component.mk main.c server-tls.c time_helper.c wifi_connect.c
CMakeLists.txt Makefile README.md README_server_sm.md partitions_singleapp_large.csv sdkconfig.defaults sdkconfig.defaults.esp32c2 sdkconfig.defaults.esp8266 wolfssl_server_ESP8266.vgdbproj
wolfssl_test
VisualGDB wolfssl_test-IDF_v5_ESP32.sln wolfssl_test-IDF_v5_ESP32.vgdbproj wolfssl_test-IDF_v5_ESP32C3.sln wolfssl_test-IDF_v5_ESP32C3.vgdbproj wolfssl_test-IDF_v5_ESP32C6.sln wolfssl_test-IDF_v5_ESP32C6.vgdbproj wolfssl_test_IDF_v5_ESP32S3.sln wolfssl_test_IDF_v5_ESP32S3.vgdbproj
components
wolfssl
include user_settings.h
CMakeLists.txt Kconfig README.md component.mk
main
include main.h
CMakeLists.txt Kconfig.projbuild component.mk main.c
CMakeLists.txt Makefile README.md partitions_singleapp_large.csv sdkconfig.defaults sdkconfig.defaults.esp32 sdkconfig.defaults.esp32c3 sdkconfig.defaults.esp32c6 sdkconfig.defaults.esp32h2 sdkconfig.defaults.esp32s2 sdkconfig.defaults.esp32s3 sdkconfig.defaults.esp8266 testAll.sh testMonitor.sh wolfssl_test_ESP8266.sln wolfssl_test_ESP8266.vgdbproj
wolfssl_test_idf
VisualGDB VisualGDB_wolfssl_test_idf.sln VisualGDB_wolfssl_test_idf.vgdbproj
main CMakeLists.txt Kconfig.projbuild component.mk main.c main_wip.c.ex time_helper.c time_helper.h
CMakeLists.txt Kconfig.projbuild README.md component.mk sdkconfig.defaults
README.md
libs CMakeLists.txt README.md component.mk tigard.cfg
test CMakeLists.txt README.md component.mk test_wolfssl.c
README.md README_32se.md UPDATE.md compileAllExamples.sh dummy_config_h dummy_test_paths.h setup.sh setup_win.bat user_settings.h
README.md include.am
GCC-ARM
Header user_settings.h
Source armtarget.c benchmark_main.c test_main.c tls_client.c tls_server.c wolf_main.c
Makefile Makefile.bench Makefile.client Makefile.common Makefile.server Makefile.static Makefile.test README.md include.am linker.ld linker_fips.ld
Gaisler-BCC README.md include.am
HEXAGON
DSP Makefile wolfssl_dsp.idl
Makefile README.md build.sh ecc-verify-benchmark.c ecc-verify.c include.am user_settings.h
HEXIWEAR
wolfSSL_HW .cwGeneratedFileSetLog user_settings.h
IAR-EWARM
Projects
benchmark benchmark-main.c current_time.c wolfCrypt-benchmark.ewd wolfCrypt-benchmark.ewp
common minimum-startup.c wolfssl.icf
lib wolfSSL-Lib.ewd wolfSSL-Lib.ewp
test test-main.c wolfCrypt-test.ewd wolfCrypt-test.ewp
user_settings.h wolfssl.eww
embOS
SAMV71_XULT
embOS_SAMV71_XULT_Linker_Script samv71q21_wolfssl.icf
embOS_SAMV71_XULT_user_settings user_settings.h user_settings_simple_example.h user_settings_verbose_example.h
embOS_wolfcrypt_benchmark_SAMV71_XULT
Application runBenchmarks.c
README_wolfcrypt_benchmark wolfcrypt_benchmark.ewd wolfcrypt_benchmark.ewp
embOS_wolfcrypt_lib_SAMV71_XULT README_wolfcrypt_lib wolfcrypt_lib.ewd wolfcrypt_lib.ewp
embOS_wolfcrypt_test_SAMV71_XULT
Application runWolfcryptTests.c
README_wolfcrypt_test wolfcrypt_test.ewd wolfcrypt_test.ewp
README_SAMV71
custom_port
custom_port_Linker_Script samv71q21_wolfssl.icf
custom_port_user_settings user_settings.h
wolfcrypt_benchmark_custom_port
Application runBenchmarks.c
wolfcrypt_test_custom_port
Application runWolfcryptTests.c
README_custom_port
extract_trial_here README_extract_trial_here
README
.gitignore README
IAR-MSP430 Makefile README.md include.am main.c user_settings.h
INTIME-RTOS Makefile README.md include.am libwolfssl.c libwolfssl.vcxproj user_settings.h wolfExamples.c wolfExamples.h wolfExamples.sln wolfExamples.vcxproj wolfssl-lib.sln wolfssl-lib.vcxproj
Infineon README.md include.am user_settings.h
KDS
config user_settings.h
include.am
LINUX-SGX README.md build.sh clean.sh include.am sgx_t_static.mk
LPCXPRESSO
lib_wolfssl lpc_18xx_port.c user_settings.h
wolf_example
src lpc_18xx_startup.c wolfssl_example.c
readme.txt
README.md
M68K
benchmark Makefile main.cpp
testwolfcrypt Makefile main.cpp
Makefile README.md include.am user_settings.h
MCUEXPRESSO
RT1170 fsl_caam_c.patch fsl_caam_h.patch user_settings.h
benchmark
source run_benchmark.c
wolfssl liblinks.xml
README.md include.am user_settings.h wolfcrypt_test.c
MDK-ARM
LPC43xx time-LCP43xx.c
MDK-ARM
wolfSSL Retarget.c cert_data.c cert_data.h config-BARE-METAL.h config-FS.h config-RTX-TCP-FS.h config-WOLFLIB.h main.c shell.c time-CortexM3-4.c time-dummy.c wolfssl_MDK_ARM.c wolfssl_MDK_ARM.h
STM32F2xx_StdPeriph_Lib time-STM32F2xx.c
MDK5-ARM
Conf user_settings.h
Inc wolfssl_MDK_ARM.h
Projects
CryptBenchmark Abstract.txt CryptBenchmark.sct CryptBenchmark.uvoptx CryptBenchmark.uvprojx main.c
CryptTest Abstract.txt CryptTest.sct CryptTest.uvoptx CryptTest.uvprojx main.c
EchoClient Abstract.txt EchoClient.uvoptx EchoClient.uvprojx main.c wolfssl-link.sct
EchoServer Abstract.txt EchoServer.uvoptx EchoServer.uvprojx main.c wolfssl-link.sct
SimpleClient Abstract.txt SimpleClient.uvoptx SimpleClient.uvprojx main.c wolfssl-link.sct
SimpleServer Abstract.txt SimpleServer.uvoptx SimpleServer.uvprojx main.c wolfssl-link.sct
wolfSSL-Full Abstract.txt main.c shell.c time-CortexM3-4.c wolfsslFull.uvoptx wolfsslFull.uvprojx
wolfSSL-Lib Abstract.txt wolfSSL-Lib.uvoptx wolfSSL-Lib.uvprojx
Src ssl-dummy.c
README.md include.am
MPLABX16
wolfcrypt_test.X
nbproject
private configurations.xml private.xml
configurations.xml include.am project.xml
Makefile
wolfssl.X
nbproject configurations.xml include.am project.xml
Makefile
README.md include.am main.c user_settings.h
MQX Makefile README-jp.md README.md client-tls.c include.am server-tls.c user_config.h user_settings.h
MSVS-2019-AZSPHERE
client client.c client.h
server server.c server.h
shared util.h
wolfssl_new_azsphere
HardwareDefinitions
avnet_mt3620_sk
inc
hw template_appliance.h
template_appliance.json
mt3620_rdb
inc
hw template_appliance.h
template_appliance.json
seeed_mt3620_mdb
inc
hw template_appliance.h
template_appliance.json
.gitignore CMakeLists.txt CMakeSettings.json app_manifest.json applibs_versions.h launch.vs.json main.c
README.md include.am user_settings.h
MYSQL CMakeLists_wolfCrypt.txt CMakeLists_wolfSSL.txt do.sh
NDS README.md
NETOS Makefile.wolfcrypt.inc README.md include.am user_settings.h user_settings.h-cert2425 user_settings.h-cert3389 wolfssl_netos_custom.c
OPENSTM32 README.md
PlatformIO
examples
wolfssl_benchmark
include README main.h
lib README
src CMakeLists.txt main.c
test README
CMakeLists.txt README.md platformio.ini sdkconfig.defaults wolfssl_benchmark.code-workspace
wolfssl_test
include README main.h
lib README
src CMakeLists.txt main.c
test README
CMakeLists.txt README.md platformio.ini sdkconfig.defaults wolfssl_test.code-workspace
README.md wolfssl_platformio.code-workspace
README.md include.am
QNX
CAAM-DRIVER Makefile
example-client Makefile client-tls.c
example-cmac Makefile cmac-test.c
example-server Makefile server-tls.c
testwolfcrypt Makefile
wolfssl Makefile user_settings.h
README.md include.am
RISCV
SIFIVE-HIFIVE1 Makefile README.md include.am main.c user_settings.h
SIFIVE-UNLEASHED README.md include.am
include.am
ROWLEY-CROSSWORKS-ARM Kinetis_FlashPlacement.xml README.md arm_startup.c benchmark_main.c hw.h include.am kinetis_hw.c retarget.c test_main.c user_settings.h wolfssl.hzp wolfssl_ltc.hzp
Renesas
cs+
Projects
common strings.h unistd.h user_settings.h wolfssl_dummy.c
t4_demo README_en.txt README_jp.txt t4_demo.mtpj wolf_client.c wolf_demo.h wolf_main.c wolf_server.c
test test.mtpj test_main.c
wolfssl_lib wolfssl_lib.mtpj
README include.am
e2studio
DK-S7G2
benchmark-template
src app_entry.c
example_server-template
src app_entry.c
wolfcrypttest-template
src app_entry.c
wolfssl-template-project configuration.xml
README.md include.am user_settings.h
Projects
common strings.h unistd.h user_settings.h wolfssl_dummy.c
test
src key_data.c key_data.h test_main.c wolf_client.c wolf_server.c wolfssl_demo.h
tools generate_rsa_keypair.sh genhexbuf.pl rsa_pss_sign.sh
wolfssl
src .gitkeep
wolfcrypt
src .gitkeep
README include.am
RA6M3
benchmark-wolfcrypt
common .gitkeep
script .gitkeep
src wolfssl_thread_entry.c
client-wolfssl
common
src .gitkeep
script .gitkeep
src wolfssl_thread_entry.c
wolfssl_thread_entry.h
common
ra6m3g README.md
src freertos_tcp_port.c
user_settings.h util.h
server-wolfssl
common
src .gitkeep
script .gitkeep
src wolfssl_thread_entry.c
wolfssl_thread_entry.h
test-wolfcrypt
common .gitkeep
script .gitkeep
src wolfssl_thread_entry.c
wolfssl
src .gitkeep
wolfcrypt .gitkeep
README.md README_APRA6M_en.md README_APRA6M_jp.md include.am
RA6M3G README.md
RA6M4
common user_settings.h wolfssl_demo.h
test
key_data key_data.h key_data_sce.c
src
SEGGER_RTT myprint.c
common .gitignore
test_main.c wolf_client.c wolfssl_sce_unit_test.c
test_RA6M4Debug.launch
tools
example_keys generate_SignedCA.sh rsa_private.pem rsa_public.pem
README.md
README.md include.am
RX65N
GR-ROSE
common strings.h unistd.h user_settings.h wolfssl_dummy.c
smc smc.scfg
test
src key_data.c key_data.h test_main.c wolf_client.c wolf_server.c wolfssl_demo.h
test.rcpc test_HardwareDebug.launch
tools
example_keys generate_SignedCA.sh rsa_private.pem rsa_public.pem
README.md
wolfssl wolfssl.rcpc
README_EN.md README_JP.md include.am
RSK
resource section.esi
wolfssl wolfssl.rcpc
wolfssl_demo key_data.c key_data.h user_settings.h wolfssl_demo.c wolfssl_demo.h
InstructionManualForExample_RSK+RX65N-2MB_EN.pdf InstructionManualForExample_RSK+RX65N-2MB_JP.pdf README_EN.md README_JP.md include.am
RX72N
EnvisionKit
Simple
common sectioninfo.esi wolfssl_dummy.c
test
src
client simple_tcp_client.c simple_tls_tsip_client.c
server simple_tcp_server.c simple_tls_server.c
test_main.c wolfssl_simple_demo.h
test.rcpc test.scfg test_HardwareDebug.launch
wolfssl wolfssl.rcpc
README_EN.md README_JP.md
resource section.esi
tools
example_keys generate_SignedCA.sh rsa_private.pem rsa_public.pem
README.md
wolfssl wolfssl.rcpc
wolfssl_demo key_data.c key_data.h user_settings.h wolfssl_demo.c wolfssl_demo.h wolfssl_tsip_unit_test.c
InstructionManualForExample_RX72N_EnvisonKit_EN.pdf InstructionManualForExample_RX72N_EnvisonKit_JP.pdf README_EN.md README_JP.md include.am
RZN2L
common user_settings.h wolfssl_demo.h
test
src
serial_io app_print.c
test wolf_client.c wolf_server.c wolfssl_rsip_unit_test.c
wolfCrypt .gitignore
wolfSSL .gitignore
local_system_init.c rzn2l_tst_thread_entry.c wolfssl_dummy.c
README.md include.am
SK-S7G2
common user_settings.h
wolfssl_lib configuration.xml
.gitignore README.md include.am
STARCORE README.txt include.am starcore_test.c user_settings.h
STM32Cube README.md STM32_Benchmarks.md default_conf.ftl include.am main.c wolfssl_example.c wolfssl_example.h
SimplicityStudio README.md include.am test_wolf.c user_settings.h
TRUESTUDIO
wolfssl user_settings.h
README include.am
VS-ARM README.md include.am user_settings.h wolfssl.sln wolfssl.vcxproj
VS-AZURE-SPHERE
client app_manifest.json client.c client.h client.vcxproj
server app_manifest.json server.c server.h server.vcxproj
shared util.h
wolfcrypt_test app_manifest.json wolfcrypt_test.vcxproj
README.md include.am user_settings.h wolfssl.sln wolfssl.vcxproj
VisualDSP include.am user_settings.h wolf_tasks.c
WICED-STUDIO README include.am user_settings.h
WIN README.txt include.am test.vcxproj user_settings.h user_settings_dtls.h wolfssl-fips.sln wolfssl-fips.vcxproj
WIN-SGX ReadMe.txt include.am wolfSSL_SGX.edl wolfSSL_SGX.sln wolfSSL_SGX.vcxproj
WIN-SRTP-KDF-140-3 README.txt include.am resource.h test.vcxproj user_settings.h wolfssl-fips.rc wolfssl-fips.sln wolfssl-fips.vcxproj
WIN10 README.txt include.am resource.h test.vcxproj user_settings.h wolfssl-fips.rc wolfssl-fips.sln wolfssl-fips.vcxproj
WINCE README.md include.am user_settings.h user_settings.h.140-2-deprecated
WORKBENCH README.md include.am
XCODE
Benchmark
wolfBench
Assets.xcassets
AppIcon.appiconset Contents.json
Base.lproj LaunchScreen.storyboard Main.storyboard
AppDelegate.h AppDelegate.m Info.plist ViewController.h ViewController.m main.m
wolfBench.xcodeproj project.pbxproj
include.am
wolfssl-FIPS.xcodeproj project.pbxproj
wolfssl.xcodeproj project.pbxproj
wolfssl_testsuite.xcodeproj project.pbxproj
README.md build-for-i386.sh include.am user_settings.h
XCODE-FIPSv2
macOS-C++
Intel user_settings.h
M1 user_settings.h
include.am user_settings.h
XCODE-FIPSv5 README include.am user_settings.h
XCODE-FIPSv6 README include.am user_settings.h
XilinxSDK
2018_2 lscript.ld
2019_2
wolfCrypt_example
src lscript.ld
wolfCrypt_example_system wolfCrypt_example_system.sprj
2022_1
wolfCrypt_FreeRTOS_example wolfCrypt_FreeRTOS_example.prj
wolfCrypt_FreeRTOS_example_system wolfCrypt_FreeRTOS_example_system.sprj
wolfCrypt_example wolfCrypt_example.prj
wolfCrypt_example_system wolfCrypt_example_system.sprj
.gitignore
README.md bench.sh combine.sh eclipse_formatter_profile.xml graph.sh include.am user_settings.h wolfssl_example.c
apple-universal
wolfssl-multiplatform
wolfssl-multiplatform
Assets.xcassets
AccentColor.colorset Contents.json
AppIcon.appiconset Contents.json
Contents.json
ContentView.swift simple_client_example.c simple_client_example.h wolfssl-multiplatform-Bridging-Header.h wolfssl_multiplatform.entitlements wolfssl_multiplatformApp.swift wolfssl_test_driver.c wolfssl_test_driver.h
wolfssl-multiplatform.xcodeproj project.pbxproj
.gitignore README.md build-wolfssl-framework.sh include.am
iotsafe Makefile README.md ca-cert.c devices.c devices.h include.am main.c memory-tls.c startup.c target.ld user_settings.h
iotsafe-raspberrypi Makefile README.md client-tls13.c include.am main.c
mynewt README.md apps.wolfcrypttest.pkg.yml crypto.wolfssl.pkg.yml crypto.wolfssl.syscfg.yml include.am setup.sh
zephyr README.md include.am
include.am
RTOS
nuttx
wolfssl .gitignore Kconfig Make.defs Makefile README.md setup-wolfssl.sh user_settings.h
include.am
bsdkm Makefile README.md bsdkm_wc_port.h include.am wolfkmod.c wolfkmod_aes.c x86_vecreg.c
certs
1024 ca-cert.der ca-cert.pem ca-key.der ca-key.pem client-cert.der client-cert.pem client-key.der client-key.pem client-keyPub.der dh1024.der dh1024.pem dsa-pub-1024.pem dsa1024.der dsa1024.pem include.am rsa1024.der server-cert.der server-cert.pem server-key.der server-key.pem
3072 client-cert.der client-cert.pem client-key.der client-key.pem client-keyPub.der include.am
4096 client-cert.der client-cert.pem client-key.der client-key.pem client-keyPub.der include.am
acert
rsa_pss acert.pem acert_ietf.pem acert_ietf_pubkey.pem acert_pubkey.pem
acert.pem acert_ietf.pem acert_ietf_pubkey.pem acert_pubkey.pem include.am
aia ca-issuers-cert.pem multi-aia-cert.pem overflow-aia-cert.pem
crl
extra-crls ca-int-cert-revoked.pem claim-root.pem crl_critical_entry.pem crlnum_57oct.pem crlnum_64oct.pem general-server-crl.pem large_crlnum.pem large_crlnum2.pem
hash_der 0fdb2da4.r0
hash_pem 0fdb2da4.r0
bad_time_fmt.pem ca-int-ecc.pem ca-int.pem ca-int2-ecc.pem ca-int2.pem caEcc384Crl.pem caEccCrl.der caEccCrl.pem cliCrl.pem client-int-ecc.pem client-int.pem crl.der crl.pem crl.revoked crl2.der crl2.pem crl_reason.pem crl_rsapss.pem eccCliCRL.pem eccSrvCRL.pem gencrls.sh include.am server-goodaltCrl.pem server-goodaltwildCrl.pem server-goodcnCrl.pem server-goodcnwildCrl.pem server-int-ecc.pem server-int.pem wolfssl.cnf
dilithium bench_dilithium_level2_key.der bench_dilithium_level3_key.der bench_dilithium_level5_key.der include.am
ecc bp256r1-key.der bp256r1-key.pem ca-secp256k1-cert.pem ca-secp256k1-key.pem client-bp256r1-cert.der client-bp256r1-cert.pem client-secp256k1-cert.der client-secp256k1-cert.pem genecc.sh include.am secp256k1-key.der secp256k1-key.pem secp256k1-param.pem secp256k1-privkey.der secp256k1-privkey.pem server-bp256r1-cert.der server-bp256r1-cert.pem server-secp256k1-cert.der server-secp256k1-cert.pem server2-secp256k1-cert.der server2-secp256k1-cert.pem wolfssl.cnf wolfssl_384.cnf
ed25519 ca-ed25519-key.der ca-ed25519-key.pem ca-ed25519-priv.der ca-ed25519-priv.pem ca-ed25519.der ca-ed25519.pem client-ed25519-key.der client-ed25519-key.pem client-ed25519-priv.der client-ed25519-priv.pem client-ed25519.der client-ed25519.pem eddsa-ed25519.der eddsa-ed25519.pem gen-ed25519-certs.sh gen-ed25519-keys.sh gen-ed25519.sh include.am root-ed25519-key.der root-ed25519-key.pem root-ed25519-priv.der root-ed25519-priv.pem root-ed25519.der root-ed25519.pem server-ed25519-cert.pem server-ed25519-key.der server-ed25519-key.pem server-ed25519-priv.der server-ed25519-priv.pem server-ed25519.der server-ed25519.pem
ed448 ca-ed448-key.der ca-ed448-key.pem ca-ed448-priv.der ca-ed448-priv.pem ca-ed448.der ca-ed448.pem client-ed448-key.der client-ed448-key.pem client-ed448-priv.der client-ed448-priv.pem client-ed448.der client-ed448.pem gen-ed448-certs.sh gen-ed448-keys.sh include.am root-ed448-key.der root-ed448-key.pem root-ed448-priv.der root-ed448-priv.pem root-ed448.der root-ed448.pem server-ed448-cert.pem server-ed448-key.der server-ed448-key.pem server-ed448-priv.der server-ed448-priv.pem server-ed448.der server-ed448.pem
external DigiCertGlobalRootCA.pem README.txt ca-digicert-ev.pem ca-globalsign-root.pem ca-google-root.pem ca_collection.pem include.am
falcon bench_falcon_level1_key.der bench_falcon_level5_key.der include.am
intermediate
ca_false_intermediate gentestcert.sh int_ca.key server.key test_ca.key test_ca.pem test_int_not_cacert.pem test_sign_bynoca_srv.pem wolfssl_base.conf wolfssl_srv.conf
ca-ecc-bad-aki.der ca-ecc-bad-aki.pem ca-int-cert.der ca-int-cert.pem ca-int-ecc-cert.der ca-int-ecc-cert.pem ca-int-ecc-key.der ca-int-ecc-key.pem ca-int-key.der ca-int-key.pem ca-int2-cert.der ca-int2-cert.pem ca-int2-ecc-cert.der ca-int2-ecc-cert.pem ca-int2-ecc-key.der ca-int2-ecc-key.pem ca-int2-key.der ca-int2-key.pem client-chain-alt-ecc.pem client-chain-alt.pem client-chain-ecc.der client-chain-ecc.pem client-chain.der client-chain.pem client-int-cert.der client-int-cert.pem client-int-ecc-cert.der client-int-ecc-cert.pem genintcerts.sh include.am server-chain-alt-ecc.pem server-chain-alt.pem server-chain-ecc.der server-chain-ecc.pem server-chain-short.pem server-chain.der server-chain.pem server-int-cert.der server-int-cert.pem server-int-ecc-cert.der server-int-ecc-cert.pem
lms bc_hss_L2_H5_W8_root.der bc_hss_L3_H5_W4_root.der bc_lms_chain_ca.der bc_lms_chain_leaf.der bc_lms_native_bc_root.der bc_lms_sha256_h10_w8_root.der bc_lms_sha256_h5_w4_root.der include.am
mldsa README.txt include.am mldsa44-cert.der mldsa44-cert.pem mldsa44-key.pem mldsa44_bare-priv.der mldsa44_bare-seed.der mldsa44_oqskeypair.der mldsa44_priv-only.der mldsa44_pub-spki.der mldsa44_seed-only.der mldsa44_seed-priv.der mldsa65-cert.der mldsa65-cert.pem mldsa65-key.pem mldsa65_bare-priv.der mldsa65_bare-seed.der mldsa65_oqskeypair.der mldsa65_priv-only.der mldsa65_pub-spki.der mldsa65_seed-only.der mldsa65_seed-priv.der mldsa87-cert.der mldsa87-cert.pem mldsa87-key.pem mldsa87_bare-priv.der mldsa87_bare-seed.der mldsa87_oqskeypair.der mldsa87_priv-only.der mldsa87_pub-spki.der mldsa87_seed-only.der mldsa87_seed-priv.der
ocsp imposter-root-ca-cert.der imposter-root-ca-cert.pem imposter-root-ca-key.der imposter-root-ca-key.pem include.am index-ca-and-intermediate-cas.txt index-ca-and-intermediate-cas.txt.attr index-intermediate1-ca-issued-certs.txt index-intermediate1-ca-issued-certs.txt.attr index-intermediate2-ca-issued-certs.txt index-intermediate2-ca-issued-certs.txt.attr index-intermediate3-ca-issued-certs.txt index-intermediate3-ca-issued-certs.txt.attr intermediate1-ca-cert.der intermediate1-ca-cert.pem intermediate1-ca-key.der intermediate1-ca-key.pem intermediate2-ca-cert.der intermediate2-ca-cert.pem intermediate2-ca-key.der intermediate2-ca-key.pem intermediate3-ca-cert.der intermediate3-ca-cert.pem intermediate3-ca-key.der intermediate3-ca-key.pem ocsp-responder-cert.der ocsp-responder-cert.pem ocsp-responder-key.der ocsp-responder-key.pem openssl.cnf renewcerts-for-test.sh renewcerts.sh root-ca-cert.der root-ca-cert.pem root-ca-crl.pem root-ca-key.der root-ca-key.pem server1-cert.der server1-cert.pem server1-chain-noroot.pem server1-key.der server1-key.pem server2-cert.der server2-cert.pem server2-key.der server2-key.pem server3-cert.der server3-cert.pem server3-key.der server3-key.pem server4-cert.der server4-cert.pem server4-key.der server4-key.pem server5-cert.der server5-cert.pem server5-key.der server5-key.pem test-leaf-response.der test-multi-response.der test-response-nointern.der test-response-rsapss.der test-response.der
p521 ca-p521-key.der ca-p521-key.pem ca-p521-priv.der ca-p521-priv.pem ca-p521.der ca-p521.pem client-p521-key.der client-p521-key.pem client-p521-priv.der client-p521-priv.pem client-p521.der client-p521.pem gen-p521-certs.sh gen-p521-keys.sh include.am root-p521-key.der root-p521-key.pem root-p521-priv.der root-p521-priv.pem root-p521.der root-p521.pem server-p521-cert.pem server-p521-key.der server-p521-key.pem server-p521-priv.der server-p521-priv.pem server-p521.der server-p521.pem
renewcerts wolfssl.cnf
rpk client-cert-rpk.der client-ecc-cert-rpk.der include.am server-cert-rpk.der server-ecc-cert-rpk.der
rsapss ca-3072-rsapss-key.der ca-3072-rsapss-key.pem ca-3072-rsapss-priv.der ca-3072-rsapss-priv.pem ca-3072-rsapss.der ca-3072-rsapss.pem ca-rsapss-key.der ca-rsapss-key.pem ca-rsapss-priv.der ca-rsapss-priv.pem ca-rsapss.der ca-rsapss.pem client-3072-rsapss-key.der client-3072-rsapss-key.pem client-3072-rsapss-priv.der client-3072-rsapss-priv.pem client-3072-rsapss.der client-3072-rsapss.pem client-rsapss-key.der client-rsapss-key.pem client-rsapss-priv.der client-rsapss-priv.pem client-rsapss.der client-rsapss.pem gen-rsapss-keys.sh include.am renew-rsapss-certs.sh root-3072-rsapss-key.der root-3072-rsapss-key.pem root-3072-rsapss-priv.der root-3072-rsapss-priv.pem root-3072-rsapss.der root-3072-rsapss.pem root-rsapss-key.der root-rsapss-key.pem root-rsapss-priv.der root-rsapss-priv.pem root-rsapss.der root-rsapss.pem server-3072-rsapss-cert.pem server-3072-rsapss-key.der server-3072-rsapss-key.pem server-3072-rsapss-priv.der server-3072-rsapss-priv.pem server-3072-rsapss.der server-3072-rsapss.pem server-mix-rsapss-cert.pem server-rsapss-cert.pem server-rsapss-key.der server-rsapss-key.pem server-rsapss-priv.der server-rsapss-priv.pem server-rsapss.der server-rsapss.pem
sia timestamping-sia-cert.pem
slhdsa bench_slhdsa_sha2_128f_key.der bench_slhdsa_sha2_128s_key.der bench_slhdsa_sha2_192f_key.der bench_slhdsa_sha2_192s_key.der bench_slhdsa_sha2_256f_key.der bench_slhdsa_sha2_256s_key.der bench_slhdsa_shake128f_key.der bench_slhdsa_shake128s_key.der bench_slhdsa_shake192f_key.der bench_slhdsa_shake192s_key.der bench_slhdsa_shake256f_key.der bench_slhdsa_shake256s_key.der client-mldsa44-priv.pem client-mldsa44-sha2.der client-mldsa44-sha2.pem client-mldsa44-shake.der client-mldsa44-shake.pem gen-slhdsa-mldsa-certs.sh include.am root-slhdsa-sha2-128s-priv.der root-slhdsa-sha2-128s-priv.pem root-slhdsa-sha2-128s.der root-slhdsa-sha2-128s.pem root-slhdsa-shake-128s-priv.der root-slhdsa-shake-128s-priv.pem root-slhdsa-shake-128s.der root-slhdsa-shake-128s.pem server-mldsa44-priv.pem server-mldsa44-sha2.der server-mldsa44-sha2.pem server-mldsa44-shake.der server-mldsa44-shake.pem
sm2 ca-sm2-key.der ca-sm2-key.pem ca-sm2-priv.der ca-sm2-priv.pem ca-sm2.der ca-sm2.pem client-sm2-key.der client-sm2-key.pem client-sm2-priv.der client-sm2-priv.pem client-sm2.der client-sm2.pem fix_sm2_spki.py gen-sm2-certs.sh gen-sm2-keys.sh include.am root-sm2-key.der root-sm2-key.pem root-sm2-priv.der root-sm2-priv.pem root-sm2.der root-sm2.pem self-sm2-cert.pem self-sm2-key.pem self-sm2-priv.pem server-sm2-cert.der server-sm2-cert.pem server-sm2-key.der server-sm2-key.pem server-sm2-priv.der server-sm2-priv.pem server-sm2.der server-sm2.pem
statickeys dh-ffdhe2048-params.pem dh-ffdhe2048-pub.der dh-ffdhe2048-pub.pem dh-ffdhe2048.der dh-ffdhe2048.pem ecc-secp256r1.der ecc-secp256r1.pem gen-static.sh include.am x25519-pub.der x25519-pub.pem x25519.der x25519.pem
test
expired expired-ca.der expired-ca.pem expired-cert.der expired-cert.pem
catalog.txt cert-bad-neg-int.der cert-bad-oid.der cert-bad-utf8.der cert-ext-ia.cfg cert-ext-ia.der cert-ext-ia.pem cert-ext-joi.cfg cert-ext-joi.der cert-ext-joi.pem cert-ext-mnc.der cert-ext-multiple.cfg cert-ext-multiple.der cert-ext-multiple.pem cert-ext-nc-combined.der cert-ext-nc-combined.pem cert-ext-nc.cfg cert-ext-nc.der cert-ext-nc.pem cert-ext-ncdns.der cert-ext-ncdns.pem cert-ext-ncip.der cert-ext-ncip.pem cert-ext-ncmixed.der cert-ext-ncmulti.der cert-ext-ncmulti.pem cert-ext-ncrid.der cert-ext-ncrid.pem cert-ext-nct.cfg cert-ext-nct.der cert-ext-nct.pem cert-ext-ndir-exc.cfg cert-ext-ndir-exc.der cert-ext-ndir-exc.pem cert-ext-ndir.cfg cert-ext-ndir.der cert-ext-ndir.pem cert-ext-ns.der cert-over-max-altnames.cfg cert-over-max-altnames.der cert-over-max-altnames.pem cert-over-max-nc.cfg cert-over-max-nc.der cert-over-max-nc.pem client-ecc-cert-ski.hex cn-ip-literal.der cn-ip-wildcard.der crit-cert.pem crit-key.pem dh1024.der dh1024.pem dh512.der dh512.pem digsigku.pem encrypteddata.msg gen-badsig.sh gen-ext-certs.sh gen-testcerts.sh include.am kari-keyid-cms.msg ktri-keyid-cms.msg ossl-trusted-cert.pem server-badaltname.der server-badaltname.pem server-badaltnull.der server-badaltnull.pem server-badcn.der server-badcn.pem server-badcnnull.der server-badcnnull.pem server-cert-ecc-badsig.der server-cert-ecc-badsig.pem server-cert-rsa-badsig.der server-cert-rsa-badsig.pem server-duplicate-policy.pem server-garbage.der server-garbage.pem server-goodalt.der server-goodalt.pem server-goodaltwild.der server-goodaltwild.pem server-goodcn.der server-goodcn.pem server-goodcnwild.der server-goodcnwild.pem server-localhost.der server-localhost.pem smime-test-canon.p7s smime-test-multipart-badsig.p7s smime-test-multipart.p7s smime-test.p7s
test-pathlen assemble-chains.sh chainA-ICA1-key.pem chainA-ICA1-pathlen0.pem chainA-assembled.pem chainA-entity-key.pem chainA-entity.pem chainB-ICA1-key.pem chainB-ICA1-pathlen0.pem chainB-ICA2-key.pem chainB-ICA2-pathlen1.pem chainB-assembled.pem chainB-entity-key.pem chainB-entity.pem chainC-ICA1-key.pem chainC-ICA1-pathlen1.pem chainC-assembled.pem chainC-entity-key.pem chainC-entity.pem chainD-ICA1-key.pem chainD-ICA1-pathlen127.pem chainD-assembled.pem chainD-entity-key.pem chainD-entity.pem chainE-ICA1-key.pem chainE-ICA1-pathlen128.pem chainE-assembled.pem chainE-entity-key.pem chainE-entity.pem chainF-ICA1-key.pem chainF-ICA1-pathlen1.pem chainF-ICA2-key.pem chainF-ICA2-pathlen0.pem chainF-assembled.pem chainF-entity-key.pem chainF-entity.pem chainG-ICA1-key.pem chainG-ICA1-pathlen0.pem chainG-ICA2-key.pem chainG-ICA2-pathlen1.pem chainG-ICA3-key.pem chainG-ICA3-pathlen99.pem chainG-ICA4-key.pem chainG-ICA4-pathlen5.pem chainG-ICA5-key.pem chainG-ICA5-pathlen20.pem chainG-ICA6-key.pem chainG-ICA6-pathlen10.pem chainG-ICA7-key.pem chainG-ICA7-pathlen100.pem chainG-assembled.pem chainG-entity-key.pem chainG-entity.pem chainH-ICA1-key.pem chainH-ICA1-pathlen0.pem chainH-ICA2-key.pem chainH-ICA2-pathlen2.pem chainH-ICA3-key.pem chainH-ICA3-pathlen2.pem chainH-ICA4-key.pem chainH-ICA4-pathlen2.pem chainH-assembled.pem chainH-entity-key.pem chainH-entity.pem chainI-ICA1-key.pem chainI-ICA1-no_pathlen.pem chainI-ICA2-key.pem chainI-ICA2-no_pathlen.pem chainI-ICA3-key.pem chainI-ICA3-pathlen2.pem chainI-assembled.pem chainI-entity-key.pem chainI-entity.pem chainJ-ICA1-key.pem chainJ-ICA1-no_pathlen.pem chainJ-ICA2-key.pem chainJ-ICA2-no_pathlen.pem chainJ-ICA3-key.pem chainJ-ICA3-no_pathlen.pem chainJ-ICA4-key.pem chainJ-ICA4-pathlen2.pem chainJ-assembled.pem chainJ-entity-key.pem chainJ-entity.pem include.am refreshkeys.sh
test-serial0 ee_normal.pem ee_serial0.pem generate_certs.sh include.am intermediate_serial0.pem root_serial0.pem root_serial0_key.pem selfsigned_nonca_serial0.pem
xmss bc_xmss_chain_ca.der bc_xmss_chain_leaf.der bc_xmss_sha2_10_256_root.der bc_xmss_sha2_16_256_root.der bc_xmssmt_sha2_20_2_256_root.der bc_xmssmt_sha2_20_4_256_root.der bc_xmssmt_sha2_40_8_256_root.der include.am
ca-cert-chain.der ca-cert.der ca-cert.pem ca-ecc-cert.der ca-ecc-cert.pem ca-ecc-key.der ca-ecc-key.pem ca-ecc384-cert.der ca-ecc384-cert.pem ca-ecc384-key.der ca-ecc384-key.pem ca-key-pkcs8-attribute.der ca-key.der ca-key.pem check_dates.sh client-absolute-urn.pem client-ca-cert.der client-ca-cert.pem client-ca.pem client-cert-ext.der client-cert-ext.pem client-cert.der client-cert.pem client-crl-dist.der client-crl-dist.pem client-ecc-ca-cert.der client-ecc-ca-cert.pem client-ecc-cert.der client-ecc-cert.pem client-ecc384-cert.der client-ecc384-cert.pem client-ecc384-key.der client-ecc384-key.pem client-key.der client-key.pem client-keyEnc.pem client-keyPub.der client-keyPub.pem client-relative-uri.pem client-uri-cert.pem csr.attr.der csr.dsa.der csr.dsa.pem csr.ext.der csr.signed.der dh-priv-2048.der dh-priv-2048.pem dh-pub-2048.der dh-pub-2048.pem dh-pubkey-2048.der dh2048.der dh2048.pem dh3072.der dh3072.pem dh4096.der dh4096.pem dsa-pubkey-2048.der dsa2048.der dsa2048.pem dsa3072.der dsaparams.der dsaparams.pem ecc-client-key.der ecc-client-key.pem ecc-client-keyPub.der ecc-client-keyPub.pem ecc-key-comp.pem ecc-keyPkcs8.der ecc-keyPkcs8.pem ecc-keyPkcs8Enc.der ecc-keyPkcs8Enc.pem ecc-keyPub.der ecc-keyPub.pem ecc-params.der ecc-params.pem ecc-privOnlyCert.pem ecc-privOnlyKey.pem ecc-privkey.der ecc-privkey.pem ecc-privkeyPkcs8.der ecc-privkeyPkcs8.pem ecc-rsa-server.p12 empty-issuer-cert.pem entity-no-ca-bool-cert.pem entity-no-ca-bool-key.pem fpki-cert.der fpki-certpol-cert.der gen_revoked.sh include.am renewcerts.sh rid-cert.der rsa-pub-2048.pem rsa2048.der rsa3072.der server-cert-chain.der server-cert.der server-cert.pem server-ecc-comp.der server-ecc-comp.pem server-ecc-rsa.der server-ecc-rsa.pem server-ecc-self.der server-ecc-self.pem server-ecc.der server-ecc.pem server-ecc384-cert.der server-ecc384-cert.pem server-ecc384-key.der server-ecc384-key.pem server-key.der server-key.pem server-keyEnc.pem server-keyPkcs8.der server-keyPkcs8.pem server-keyPkcs8Enc.der server-keyPkcs8Enc.pem server-keyPkcs8Enc12.pem server-keyPkcs8Enc2.pem server-keyPub.der server-keyPub.pem server-revoked-cert.pem server-revoked-key.pem taoCert.txt test-ber-exp02-05-2022.p7b test-degenerate.p7b test-multiple-recipients.p7b test-servercert-rc2.p12 test-servercert.p12 test-stream-dec.p7b test-stream-sign.p7b wolfssl-website-ca.pem x942dh2048.der x942dh2048.pem
cmake
consumer CMakeLists.txt README.md main.c
modules FindARIA.cmake FindOQS.cmake
Config.cmake.in README.md config.in functions.cmake include.am options.h.in wolfssl-config-version.cmake.in wolfssl-targets.cmake.in
debian
source format
changelog.in control.in copyright include.am libwolfssl-dev.install libwolfssl.install rules.in
doc
dox_comments
header_files aes.h arc4.h ascon.h asn.h asn_public.h blake2.h bn.h camellia.h chacha.h chacha20_poly1305.h cmac.h coding.h compress.h cryptocb.h curve25519.h curve448.h des3.h dh.h doxygen_groups.h doxygen_pages.h dsa.h ecc.h eccsi.h ed25519.h ed448.h error-crypt.h evp.h hash.h hmac.h iotsafe.h kdf.h logging.h md2.h md4.h md5.h memory.h ocsp.h pem.h pkcs11.h pkcs7.h poly1305.h psa.h puf.h pwdbased.h quic.h random.h ripemd.h rsa.h sakke.h sha.h sha256.h sha3.h sha512.h signature.h siphash.h srp.h ssl.h tfm.h types.h wc_encrypt.h wc_port.h wc_she.h wc_slhdsa.h wolfio.h
header_files-ja aes.h arc4.h ascon.h asn.h asn_public.h blake2.h bn.h camellia.h chacha.h chacha20_poly1305.h cmac.h coding.h compress.h cryptocb.h curve25519.h curve448.h des3.h dh.h doxygen_groups.h doxygen_pages.h dsa.h ecc.h eccsi.h ed25519.h ed448.h error-crypt.h evp.h hash.h hmac.h iotsafe.h kdf.h logging.h md2.h md4.h md5.h memory.h ocsp.h pem.h pkcs11.h pkcs7.h poly1305.h psa.h pwdbased.h quic.h random.h ripemd.h rsa.h sakke.h sha.h sha256.h sha3.h sha512.h signature.h siphash.h srp.h ssl.h tfm.h types.h wc_encrypt.h wc_port.h wolfio.h
formats
html
html_changes
search search.css search.js
customdoxygen.css doxygen.css menu.js menudata.js tabs.css
Doxyfile footer.html header.html mainpage.dox
pdf Doxyfile header.tex
images wolfssl_logo.png
QUIC.md README.txt README_DOXYGEN check_api.sh generate_documentation.sh include.am
examples
asn1 asn1.c dumpasn1.cfg gen_oid_names.rb include.am oid_names.h
async Makefile README.md async_client.c async_server.c async_tls.c async_tls.h include.am user_settings.h
benchmark include.am tls_bench.c tls_bench.h
client client.c client.h client.sln client.vcproj client.vcxproj include.am
configs README.md include.am user_settings_EBSnet.h user_settings_all.h user_settings_arduino.h user_settings_baremetal.h user_settings_ca.h user_settings_curve25519nonblock.h user_settings_dtls13.h user_settings_eccnonblock.h user_settings_espressif.h user_settings_fipsv2.h user_settings_fipsv5.h user_settings_min_ecc.h user_settings_openssl_compat.h user_settings_pkcs7.h user_settings_platformio.h user_settings_pq.h user_settings_rsa_only.h user_settings_stm32.h user_settings_template.h user_settings_tls12.h user_settings_tls13.h user_settings_wolfboot_keytools.h user_settings_wolfssh.h user_settings_wolftpm.h
crypto_policies
default wolfssl.txt
future wolfssl.txt
legacy wolfssl.txt
echoclient echoclient.c echoclient.h echoclient.sln echoclient.vcproj echoclient.vcxproj include.am quit
echoserver echoserver.c echoserver.h echoserver.sln echoserver.vcproj echoserver.vcxproj include.am
ocsp_responder include.am ocsp_responder.c ocsp_responder.h
pem include.am pem.c
sctp include.am sctp-client-dtls.c sctp-client.c sctp-server-dtls.c sctp-server.c
server include.am server.c server.h server.sln server.vcproj server.vcxproj
README.md include.am
linuxkm
patches
5.10.17 WOLFSSL_LINUXKM_HAVE_GET_RANDOM_CALLBACKS-5v10v17.patch
5.10.236 WOLFSSL_LINUXKM_HAVE_GET_RANDOM_CALLBACKS-5v10v236.patch
5.14.0-570.58.1.el9_6 WOLFSSL_LINUXKM_HAVE_GET_RANDOM_CALLBACKS-5v14-570v58v1-el9_6.patch
5.15 WOLFSSL_LINUXKM_HAVE_GET_RANDOM_CALLBACKS-5v15.patch
5.17 WOLFSSL_LINUXKM_HAVE_GET_RANDOM_CALLBACKS-5v17.patch
5.17-ubuntu-jammy-tegra WOLFSSL_LINUXKM_HAVE_GET_RANDOM_CALLBACKS-5v17-ubuntu-jammy-tegra.patch
6.1.73 WOLFSSL_LINUXKM_HAVE_GET_RANDOM_CALLBACKS-6v1v73.patch
6.12 WOLFSSL_LINUXKM_HAVE_GET_RANDOM_CALLBACKS-6v12.patch
6.15 WOLFSSL_LINUXKM_HAVE_GET_RANDOM_CALLBACKS-6v15.patch
7.0 WOLFSSL_LINUXKM_HAVE_GET_RANDOM_CALLBACKS-7v0.patch
regen-patches.sh
Kbuild Makefile README.md get_thread_size.c include.am linuxkm-fips-hash-wrapper.sh linuxkm-fips-hash.c linuxkm_memory.c linuxkm_memory.h linuxkm_wc_port.h lkcapi_aes_glue.c lkcapi_dh_glue.c lkcapi_ecdh_glue.c lkcapi_ecdsa_glue.c lkcapi_glue.c lkcapi_rsa_glue.c lkcapi_sha_glue.c module_exports.c.template module_hooks.c pie_redirect_table.c wolfcrypt.lds x86_vector_register_glue.c
m4 ax_add_am_macro.m4 ax_am_jobserver.m4 ax_am_macros.m4 ax_append_compile_flags.m4 ax_append_flag.m4 ax_append_link_flags.m4 ax_append_to_file.m4 ax_atomic.m4 ax_bsdkm.m4 ax_check_compile_flag.m4 ax_check_link_flag.m4 ax_compiler_version.m4 ax_count_cpus.m4 ax_create_generic_config.m4 ax_debug.m4 ax_file_escapes.m4 ax_harden_compiler_flags.m4 ax_linuxkm.m4 ax_print_to_file.m4 ax_pthread.m4 ax_require_defined.m4 ax_tls.m4 ax_vcs_checkout.m4 hexversion.m4 lib_socket_nsl.m4 visibility.m4
mcapi
wolfcrypt_mcapi.X
nbproject configurations.xml include.am project.xml
Makefile
wolfcrypt_test.X
nbproject configurations.xml include.am project.xml
Makefile
wolfssl.X
nbproject configurations.xml include.am project.xml
Makefile
zlib.X
nbproject configurations.xml include.am project.xml
Makefile
PIC32MZ-serial.h README crypto.c crypto.h include.am mcapi_test.c user_settings.h
mplabx
wolfcrypt_benchmark.X
nbproject configurations.xml include.am project.xml
Makefile
wolfcrypt_test.X
nbproject configurations.xml include.am project.xml
Makefile
wolfssl.X
nbproject configurations.xml include.am project.xml
Makefile
PIC32MZ-serial.h README benchmark_main.c include.am test_main.c user_settings.h
mqx
util_lib
Sources include.am util.c util.h
wolfcrypt_benchmark
Debugger K70FN1M0.mem init_kinetis.tcl mass_erase_kinetis.tcl
Sources include.am main.c main.h
ReferencedRSESystems.xml wolfcrypt_benchmark_twrk70f120m_Int_Flash_DDRData_Debug_PnE_U-MultiLink.launch wolfcrypt_benchmark_twrk70f120m_Int_Flash_DDRData_Release_PnE_U-MultiLink.launch wolfcrypt_benchmark_twrk70f120m_Int_Flash_SramData_Debug_JTrace.jlink wolfcrypt_benchmark_twrk70f120m_Int_Flash_SramData_Debug_JTrace.launch wolfcrypt_benchmark_twrk70f120m_Int_Flash_SramData_Debug_PnE_U-MultiLink.launch wolfcrypt_benchmark_twrk70f120m_Int_Flash_SramData_Release_PnE_U-MultiLink.launch
wolfcrypt_test
Debugger K70FN1M0.mem init_kinetis.tcl mass_erase_kinetis.tcl
Sources include.am main.c main.h
ReferencedRSESystems.xml wolfcrypt_test_twrk70f120m_Int_Flash_DDRData_Debug_PnE_U-MultiLink.launch wolfcrypt_test_twrk70f120m_Int_Flash_DDRData_Release_PnE_U-MultiLink.launch wolfcrypt_test_twrk70f120m_Int_Flash_SramData_Debug_JTrace.jlink wolfcrypt_test_twrk70f120m_Int_Flash_SramData_Debug_JTrace.launch wolfcrypt_test_twrk70f120m_Int_Flash_SramData_Debug_PnE_U-MultiLink.launch wolfcrypt_test_twrk70f120m_Int_Flash_SramData_Release_PnE_U-MultiLink.launch
wolfssl include.am
wolfssl_client
Debugger K70FN1M0.mem init_kinetis.tcl mass_erase_kinetis.tcl
Sources include.am main.c main.h
ReferencedRSESystems.xml wolfssl_client_twrk70f120m_Int_Flash_DDRData_Debug_PnE_U-MultiLink.launch wolfssl_client_twrk70f120m_Int_Flash_DDRData_Release_PnE_U-MultiLink.launch wolfssl_client_twrk70f120m_Int_Flash_SramData_Debug_JTrace.jlink wolfssl_client_twrk70f120m_Int_Flash_SramData_Debug_JTrace.launch wolfssl_client_twrk70f120m_Int_Flash_SramData_Debug_PnE_U-MultiLink.launch wolfssl_client_twrk70f120m_Int_Flash_SramData_Release_PnE_U-MultiLink.launch
README
rpm include.am spec.in
scripts
bench bench_functions.sh
aria-cmake-build-test.sh asn1_oid_sum.pl benchmark.test benchmark_compare.sh cleanup_testfiles.sh crl-gen-openssl.test crl-revoked.test dertoc.pl dtls.test dtlscid.test external.test google.test include.am makedistsmall.sh memtest.sh ocsp-responder-openssl-interop.test ocsp-stapling-with-ca-as-responder.test ocsp-stapling-with-wolfssl-responder.test ocsp-stapling.test ocsp-stapling2.test ocsp-stapling_tls13multi.test ocsp.test openssl.test openssl_srtp.test pem.test ping.test pkcallbacks.test psk.test resume.test rsapss.test sniffer-gen.sh sniffer-ipv6.pcap sniffer-static-rsa.pcap sniffer-testsuite.test sniffer-tls12-keylog.out sniffer-tls12-keylog.pcap sniffer-tls12-keylog.sslkeylog sniffer-tls13-dh-resume.pcap sniffer-tls13-dh.pcap sniffer-tls13-ecc-resume.pcap sniffer-tls13-ecc.pcap sniffer-tls13-hrr.pcap sniffer-tls13-keylog.out sniffer-tls13-keylog.pcap sniffer-tls13-keylog.sslkeylog sniffer-tls13-x25519-resume.pcap sniffer-tls13-x25519.pcap stm32l4-v4_0_1_build.sh tls13.test trusted_peer.test unit.test.in user_settings_asm.sh
src bio.c conf.c crl.c dtls.c dtls13.c include.am internal.c keys.c ocsp.c pk.c pk_ec.c pk_rsa.c quic.c sniffer.c ssl.c ssl_api_cert.c ssl_api_crl_ocsp.c ssl_api_pk.c ssl_asn1.c ssl_bn.c ssl_certman.c ssl_crypto.c ssl_ech.c ssl_load.c ssl_misc.c ssl_p7p12.c ssl_sess.c ssl_sk.c tls.c tls13.c wolfio.c x509.c x509_str.c
sslSniffer
sslSnifferTest README_WIN.md include.am snifftest.c sslSniffTest.vcproj sslSniffTest.vcxproj
README.md sslSniffer.vcproj sslSniffer.vcxproj
support gen-debug-trace-error-codes.sh include.am wolfssl.pc.in
tests
api api.h api_decl.h create_ocsp_test_blobs.py include.am test_aes.c test_aes.h test_arc4.c test_arc4.h test_ascon.c test_ascon.h test_ascon_kats.h test_asn.c test_asn.h test_blake2.c test_blake2.h test_camellia.c test_camellia.h test_certman.c test_certman.h test_chacha.c test_chacha.h test_chacha20_poly1305.c test_chacha20_poly1305.h test_cmac.c test_cmac.h test_curve25519.c test_curve25519.h test_curve448.c test_curve448.h test_des3.c test_des3.h test_dh.c test_dh.h test_digest.h test_dsa.c test_dsa.h test_dtls.c test_dtls.h test_ecc.c test_ecc.h test_ed25519.c test_ed25519.h test_ed448.c test_ed448.h test_evp.c test_evp.h test_evp_cipher.c test_evp_cipher.h test_evp_digest.c test_evp_digest.h test_evp_pkey.c test_evp_pkey.h test_hash.c test_hash.h test_hmac.c test_hmac.h test_md2.c test_md2.h test_md4.c test_md4.h test_md5.c test_md5.h test_mldsa.c test_mldsa.h test_mlkem.c test_mlkem.h test_ocsp.c test_ocsp.h test_ocsp_test_blobs.h test_ossl_asn1.c test_ossl_asn1.h test_ossl_bio.c test_ossl_bio.h test_ossl_bn.c test_ossl_bn.h test_ossl_cipher.c test_ossl_cipher.h test_ossl_dgst.c test_ossl_dgst.h test_ossl_dh.c test_ossl_dh.h test_ossl_dsa.c test_ossl_dsa.h test_ossl_ec.c test_ossl_ec.h test_ossl_ecx.c test_ossl_ecx.h test_ossl_mac.c test_ossl_mac.h test_ossl_obj.c test_ossl_obj.h test_ossl_p7p12.c test_ossl_p7p12.h test_ossl_pem.c test_ossl_pem.h test_ossl_rand.c test_ossl_rand.h test_ossl_rsa.c test_ossl_rsa.h test_ossl_sk.c test_ossl_sk.h test_ossl_x509.c test_ossl_x509.h test_ossl_x509_acert.c test_ossl_x509_acert.h test_ossl_x509_crypto.c test_ossl_x509_crypto.h test_ossl_x509_ext.c test_ossl_x509_ext.h test_ossl_x509_info.c test_ossl_x509_info.h test_ossl_x509_io.c test_ossl_x509_io.h test_ossl_x509_lu.c test_ossl_x509_lu.h test_ossl_x509_name.c test_ossl_x509_name.h test_ossl_x509_pk.c test_ossl_x509_pk.h test_ossl_x509_str.c test_ossl_x509_str.h test_ossl_x509_vp.c test_ossl_x509_vp.h test_pkcs12.c test_pkcs12.h test_pkcs7.c test_pkcs7.h test_poly1305.c test_poly1305.h test_random.c test_random.h test_rc2.c test_rc2.h test_ripemd.c test_ripemd.h test_rsa.c test_rsa.h test_sha.c test_sha.h test_sha256.c test_sha256.h test_sha3.c test_sha3.h test_sha512.c test_sha512.h test_she.c test_she.h test_signature.c test_signature.h test_slhdsa.c test_slhdsa.h test_sm2.c test_sm2.h test_sm3.c test_sm3.h test_sm4.c test_sm4.h test_tls.c test_tls.h test_tls13.c test_tls13.h test_tls_ext.c test_tls_ext.h test_wc_encrypt.c test_wc_encrypt.h test_wolfmath.c test_wolfmath.h test_x509.c test_x509.h
emnet
IP IP.h
Makefile emnet_nonblock_test.c emnet_shim.c
freertos-mem-track-repro FreeRTOS.h repro.c run.sh semphr.h task.h user_settings.h
swdev .gitignore Makefile README.md swdev.c swdev.h swdev_loader.c swdev_loader.h user_settings.h
CONF_FILES_README.md NCONF_test.cnf README TXT_DB.txt api.c include.am quic.c srp.c suites.c test-altchains.conf test-chains.conf test-dhprime.conf test-dtls-downgrade.conf test-dtls-fails-cipher.conf test-dtls-fails.conf test-dtls-group.conf test-dtls-mtu.conf test-dtls-reneg-client.conf test-dtls-reneg-server.conf test-dtls-resume.conf test-dtls-sha2.conf test-dtls-srtp-fails.conf test-dtls-srtp.conf test-dtls.conf test-dtls13-cid.conf test-dtls13-downgrade-fails.conf test-dtls13-downgrade.conf test-dtls13-pq-hybrid-extra-frag.conf test-dtls13-pq-hybrid-extra.conf test-dtls13-pq-hybrid-frag.conf test-dtls13-pq-standalone-frag.conf test-dtls13-pq-standalone.conf test-dtls13-psk.conf test-dtls13.conf test-ecc-cust-curves.conf test-ed25519.conf test-ed448.conf test-enckeys.conf test-fails.conf test-maxfrag-dtls.conf test-maxfrag.conf test-p521.conf test-psk-no-id-sha2.conf test-psk-no-id.conf test-psk.conf test-rsapss.conf test-sctp-sha2.conf test-sctp.conf test-sha2.conf test-sig.conf test-sm2.conf test-tls-downgrade.conf test-tls13-down.conf test-tls13-ecc.conf test-tls13-pq-hybrid-extra.conf test-tls13-pq-hybrid.conf test-tls13-pq-standalone.conf test-tls13-psk-certs.conf test-tls13-psk.conf test-tls13-slhdsa-fail.conf test-tls13-slhdsa-sha2.conf test-tls13-slhdsa-shake.conf test-tls13.conf test-trustpeer.conf test.conf unit.c unit.h utils.c utils.h w64wrapper.c
testsuite include.am testsuite.c testsuite.sln testsuite.vcproj testsuite.vcxproj utils.c utils.h
tirtos
packages
ti
net
wolfssl
tests
EK_TM4C1294XL
wolfcrypt
benchmark TM4C1294NC.icf benchmark.cfg main.c package.bld.hide package.xdc
test TM4C1294NC.icf main.c package.bld.hide package.xdc test.cfg
package.bld package.xdc package.xs
.gitignore README include.am products.mak wolfssl.bld wolfssl.mak
wolfcrypt
benchmark README.md benchmark-VS2022.sln benchmark-VS2022.vcxproj benchmark-VS2022.vcxproj.user benchmark.c benchmark.h benchmark.sln benchmark.vcproj benchmark.vcxproj include.am
src
port
Espressif
esp_crt_bundle README.md cacrt_all.pem cacrt_deprecated.pem cacrt_local.pem esp_crt_bundle.c gen_crt_bundle.py pio_install_cryptography.py
README.md esp32_aes.c esp32_mp.c esp32_sha.c esp32_util.c esp_sdk_mem_lib.c esp_sdk_time_lib.c esp_sdk_wifi_lib.c
Renesas README.md renesas_common.c renesas_fspsm_aes.c renesas_fspsm_rsa.c renesas_fspsm_sha.c renesas_fspsm_util.c renesas_rx64_hw_sha.c renesas_rx64_hw_util.c renesas_tsip_aes.c renesas_tsip_rsa.c renesas_tsip_sha.c renesas_tsip_util.c
af_alg afalg_aes.c afalg_hash.c wc_afalg.c
aria aria-crypt.c aria-cryptocb.c
arm armv8-32-aes-asm.S armv8-32-aes-asm_c.c armv8-32-chacha-asm.S armv8-32-chacha-asm_c.c armv8-32-curve25519.S armv8-32-curve25519_c.c armv8-32-mlkem-asm.S armv8-32-mlkem-asm_c.c armv8-32-poly1305-asm.S armv8-32-poly1305-asm_c.c armv8-32-sha256-asm.S armv8-32-sha256-asm_c.c armv8-32-sha3-asm.S armv8-32-sha3-asm_c.c armv8-32-sha512-asm.S armv8-32-sha512-asm_c.c armv8-aes-asm.S armv8-aes-asm_c.c armv8-aes.c armv8-chacha-asm.S armv8-chacha-asm_c.c armv8-curve25519.S armv8-curve25519_c.c armv8-mlkem-asm.S armv8-mlkem-asm_c.c armv8-poly1305-asm.S armv8-poly1305-asm_c.c armv8-sha256-asm.S armv8-sha256-asm_c.c armv8-sha256.c armv8-sha3-asm.S armv8-sha3-asm_c.c armv8-sha512-asm.S armv8-sha512-asm_c.c armv8-sha512.c cryptoCell.c cryptoCellHash.c thumb2-aes-asm.S thumb2-aes-asm_c.c thumb2-chacha-asm.S thumb2-chacha-asm_c.c thumb2-curve25519.S thumb2-curve25519_c.c thumb2-mlkem-asm.S thumb2-mlkem-asm_c.c thumb2-poly1305-asm.S thumb2-poly1305-asm_c.c thumb2-sha256-asm.S thumb2-sha256-asm_c.c thumb2-sha3-asm.S thumb2-sha3-asm_c.c thumb2-sha512-asm.S thumb2-sha512-asm_c.c
atmel README.md atmel.c
autosar README.md cryif.c crypto.c csm.c include.am test.c
caam README.md caam_aes.c caam_doc.pdf caam_driver.c caam_error.c caam_integrity.c caam_qnx.c caam_sha.c wolfcaam_aes.c wolfcaam_cmac.c wolfcaam_ecdsa.c wolfcaam_fsl_nxp.c wolfcaam_hash.c wolfcaam_hmac.c wolfcaam_init.c wolfcaam_qnx.c wolfcaam_rsa.c wolfcaam_seco.c wolfcaam_x25519.c
cavium README.md README_Octeon.md cavium_nitrox.c cavium_octeon_sync.c
cuda README.md aes-cuda.cu
cypress README.md psoc6_crypto.c
devcrypto README.md devcrypto_aes.c devcrypto_ecdsa.c devcrypto_hash.c devcrypto_hmac.c devcrypto_rsa.c devcrypto_x25519.c wc_devcrypto.c
intel README.md quickassist.c quickassist_mem.c quickassist_sync.c
iotsafe iotsafe.c
kcapi README.md kcapi_aes.c kcapi_dh.c kcapi_ecc.c kcapi_hash.c kcapi_hmac.c kcapi_rsa.c
liboqs liboqs.c
maxim README.md max3266x.c maxq10xx.c
mynewt mynewt_port.c
nxp README.md README_SE050.md casper_port.c dcp_port.c hashcrypt_port.c ksdk_port.c se050_port.c
pic32 pic32mz-crypt.c
ppc32 ppc32-sha256-asm.S ppc32-sha256-asm_c.c ppc32-sha256-asm_cr.c
psa README.md psa.c psa_aes.c psa_hash.c psa_pkcbs.c
riscv riscv-64-aes.c riscv-64-chacha.c riscv-64-poly1305.c riscv-64-sha256.c riscv-64-sha3.c riscv-64-sha512.c
rpi_pico README.md pico.c
silabs README.md silabs_aes.c silabs_ecc.c silabs_hash.c silabs_random.c
st README.md STM32MP13.md STM32MP25.md stm32.c stsafe.c
ti ti-aes.c ti-ccm.c ti-des3.c ti-hash.c
tropicsquare README.md tropic01.c
xilinx xil-aesgcm.c xil-sha3.c xil-versal-glue.c xil-versal-trng.c
nrf51.c
ASN_TEMPLATE.md aes.c aes_asm.S aes_asm.asm aes_gcm_asm.S aes_gcm_asm.asm aes_gcm_x86_asm.S aes_xts_asm.S aes_xts_asm.asm arc4.c ascon.c asm.c asn.c asn_orig.c async.c blake2b.c blake2s.c camellia.c chacha.c chacha20_poly1305.c chacha_asm.S chacha_asm.asm cmac.c coding.c compress.c cpuid.c cryptocb.c curve25519.c curve448.c des3.c dh.c dilithium.c dsa.c ecc.c ecc_fp.c eccsi.c ed25519.c ed448.c error.c evp.c evp_pk.c falcon.c fe_448.c fe_low_mem.c fe_operations.c fe_x25519_128.h fe_x25519_asm.S fp_mont_small.i fp_mul_comba_12.i fp_mul_comba_17.i fp_mul_comba_20.i fp_mul_comba_24.i fp_mul_comba_28.i fp_mul_comba_3.i fp_mul_comba_32.i fp_mul_comba_4.i fp_mul_comba_48.i fp_mul_comba_6.i fp_mul_comba_64.i fp_mul_comba_7.i fp_mul_comba_8.i fp_mul_comba_9.i fp_mul_comba_small_set.i fp_sqr_comba_12.i fp_sqr_comba_17.i fp_sqr_comba_20.i fp_sqr_comba_24.i fp_sqr_comba_28.i fp_sqr_comba_3.i fp_sqr_comba_32.i fp_sqr_comba_4.i fp_sqr_comba_48.i fp_sqr_comba_6.i fp_sqr_comba_64.i fp_sqr_comba_7.i fp_sqr_comba_8.i fp_sqr_comba_9.i fp_sqr_comba_small_set.i ge_448.c ge_low_mem.c ge_operations.c hash.c hmac.c hpke.c include.am integer.c kdf.c logging.c md2.c md4.c md5.c memory.c misc.c pkcs12.c pkcs7.c poly1305.c poly1305_asm.S poly1305_asm.asm puf.c pwdbased.c random.c rc2.c ripemd.c rng_bank.c rsa.c sakke.c sha.c sha256.c sha256_asm.S sha3.c sha3_asm.S sha512.c sha512_asm.S signature.c siphash.c sm2.c sm3.c sm3_asm.S sm4.c sp_arm32.c sp_arm64.c sp_armthumb.c sp_c32.c sp_c64.c sp_cortexm.c sp_dsp32.c sp_int.c sp_sm2_arm32.c sp_sm2_arm64.c sp_sm2_armthumb.c sp_sm2_c32.c sp_sm2_c64.c sp_sm2_cortexm.c sp_sm2_x86_64.c sp_sm2_x86_64_asm.S sp_x86_64.c sp_x86_64_asm.S sp_x86_64_asm.asm srp.c tfm.c wc_dsp.c wc_encrypt.c wc_lms.c wc_lms_impl.c wc_mldsa_asm.S wc_mlkem.c wc_mlkem_asm.S wc_mlkem_poly.c wc_pkcs11.c wc_port.c wc_she.c wc_slhdsa.c wc_xmss.c wc_xmss_impl.c wolfentropy.c wolfevent.c wolfmath.c
test README.md include.am test-VS2022.sln test-VS2022.vcxproj test-VS2022.vcxproj.user test.c test.h test.sln test.vcproj test_paths.h.in
wolfssl
openssl aes.h asn1.h asn1t.h bio.h bn.h buffer.h camellia.h cmac.h cms.h compat_types.h conf.h crypto.h des.h dh.h dsa.h ec.h ec25519.h ec448.h ecdh.h ecdsa.h ed25519.h ed448.h engine.h err.h evp.h fips_rand.h hmac.h include.am kdf.h lhash.h md4.h md5.h modes.h obj_mac.h objects.h ocsp.h opensslconf.h opensslv.h ossl_typ.h pem.h pkcs12.h pkcs7.h rand.h rc4.h ripemd.h rsa.h safestack.h sha.h sha3.h srp.h ssl.h ssl23.h stack.h tls1.h txt_db.h ui.h x509.h x509_vfy.h x509v3.h
wolfcrypt
port
Espressif esp-sdk-lib.h esp32-crypt.h esp_crt_bundle.h
Renesas renesas-fspsm-crypt.h renesas-fspsm-types.h renesas-rx64-hw-crypt.h renesas-tsip-crypt.h renesas_cmn.h renesas_fspsm_internal.h renesas_sync.h renesas_tsip_internal.h renesas_tsip_types.h
af_alg afalg_hash.h wc_afalg.h
aria aria-crypt.h aria-cryptocb.h
arm cryptoCell.h
atmel atmel.h
autosar CryIf.h Crypto.h Csm.h StandardTypes.h
caam caam_driver.h caam_error.h caam_qnx.h wolfcaam.h wolfcaam_aes.h wolfcaam_cmac.h wolfcaam_ecdsa.h wolfcaam_fsl_nxp.h wolfcaam_hash.h wolfcaam_qnx.h wolfcaam_rsa.h wolfcaam_seco.h wolfcaam_sha.h wolfcaam_x25519.h
cavium cavium_nitrox.h cavium_octeon_sync.h
cypress psoc6_crypto.h
devcrypto wc_devcrypto.h
intel quickassist.h quickassist_mem.h quickassist_sync.h
iotsafe iotsafe.h
kcapi kcapi_dh.h kcapi_ecc.h kcapi_hash.h kcapi_hmac.h kcapi_rsa.h wc_kcapi.h
liboqs liboqs.h
maxim max3266x-cryptocb.h max3266x.h maxq10xx.h
nxp casper_port.h dcp_port.h hashcrypt_port.h ksdk_port.h se050_port.h
pic32 pic32mz-crypt.h
psa psa.h
riscv riscv-64-asm.h
rpi_pico pico.h
silabs silabs_aes.h silabs_ecc.h silabs_hash.h silabs_random.h
st stm32.h stsafe.h
ti ti-ccm.h ti-hash.h
tropicsquare tropic01.h
xilinx xil-sha3.h xil-versal-glue.h xil-versal-trng.h
nrf51.h
aes.h arc4.h ascon.h asn.h asn_public.h async.h blake2-impl.h blake2-int.h blake2.h camellia.h chacha.h chacha20_poly1305.h cmac.h coding.h compress.h cpuid.h cryptocb.h curve25519.h curve448.h des3.h dh.h dilithium.h dsa.h ecc.h eccsi.h ed25519.h ed448.h error-crypt.h falcon.h fe_448.h fe_operations.h fips_test.h ge_448.h ge_operations.h hash.h hmac.h hpke.h include.am integer.h kdf.h libwolfssl_sources.h libwolfssl_sources_asm.h logging.h md2.h md4.h md5.h mem_track.h memory.h misc.h mpi_class.h mpi_superclass.h oid_sum.h pkcs11.h pkcs12.h pkcs7.h poly1305.h puf.h pwdbased.h random.h rc2.h ripemd.h rng_bank.h rsa.h sakke.h selftest.h settings.h sha.h sha256.h sha3.h sha512.h signature.h siphash.h sm2.h sm3.h sm4.h sp.h sp_int.h srp.h tfm.h types.h visibility.h wc_encrypt.h wc_lms.h wc_mlkem.h wc_pkcs11.h wc_port.h wc_she.h wc_slhdsa.h wc_xmss.h wolfentropy.h wolfevent.h wolfmath.h
callbacks.h certs_test.h certs_test_sm.h crl.h error-ssl.h include.am internal.h ocsp.h options.h.in quic.h sniffer.h sniffer_error.h sniffer_error.rc ssl.h test.h version.h version.h.in wolfio.h
wrapper
Ada
examples
src aes_verify_main.adb rsa_verify_main.adb sha256_main.adb spark_sockets.adb spark_sockets.ads spark_terminal.adb spark_terminal.ads tls_client.adb tls_client.ads tls_client_main.adb tls_server.adb tls_server.ads tls_server_main.adb
.gitignore alire.toml examples.gpr
tests
src
support test_support.adb test_support.ads tests_root_suite.adb tests_root_suite.ads
aes_bindings_tests.adb aes_bindings_tests.ads rsa_verify_bindings_tests.adb rsa_verify_bindings_tests.ads sha256_bindings_tests.adb sha256_bindings_tests.ads tests.adb
.gitignore README.md alire.toml tests.gpr valgrind.supp
.gitignore README.md ada_binding.c alire.toml default.gpr include.am restricted.adc user_settings.h wolfssl-full_runtime.adb wolfssl-full_runtime.ads wolfssl.adb wolfssl.ads wolfssl.gpr
CSharp
wolfCrypt-Test
Properties AssemblyInfo.cs
App.config wolfCrypt-Test.cs wolfCrypt-Test.csproj
wolfSSL-DTLS-PSK-Server
Properties AssemblyInfo.cs
App.config wolfSSL-DTLS-PSK-Server.cs wolfSSL-DTLS-PSK-Server.csproj
wolfSSL-DTLS-Server
Properties AssemblyInfo.cs
App.config wolfSSL-DTLS-Server.cs wolfSSL-DTLS-Server.csproj
wolfSSL-Example-IOCallbacks
Properties AssemblyInfo.cs
App.config wolfSSL-Example-IOCallbacks.cs wolfSSL-Example-IOCallbacks.csproj
wolfSSL-TLS-Client
Properties AssemblyInfo.cs
App.config wolfSSL-TLS-Client.cs wolfSSL-TLS-Client.csproj
wolfSSL-TLS-PSK-Client
Properties AssemblyInfo.cs
App.config wolfSSL-TLS-PSK-Client.cs wolfSSL-TLS-PSK-Client.csproj
wolfSSL-TLS-PSK-Server
Properties AssemblyInfo.cs
App.config wolfSSL-TLS-PSK-Server.cs wolfSSL-TLS-PSK-Server.csproj
wolfSSL-TLS-Server
Properties AssemblyInfo.cs
App.config wolfSSL-TLS-Server.cs wolfSSL-TLS-Server.csproj
wolfSSL-TLS-ServerThreaded
Properties AssemblyInfo.cs
App.config wolfSSL-TLS-ServerThreaded.cs wolfSSL-TLS-ServerThreaded.csproj
wolfSSL_CSharp
Properties AssemblyInfo.cs Resources.Designer.cs Resources.resx
X509.cs wolfCrypt.cs wolfSSL.cs wolfSSL_CSharp.csproj
README.md include.am user_settings.h wolfSSL_CSharp.sln wolfssl.vcxproj
python README.md
rust
wolfssl-wolfcrypt
src aes.rs blake2.rs chacha20_poly1305.rs cmac.rs cmac_mac.rs curve25519.rs dh.rs dilithium.rs ecc.rs ecdsa.rs ed25519.rs ed448.rs fips.rs hkdf.rs hmac.rs hmac_mac.rs kdf.rs lib.rs lms.rs mlkem.rs mlkem_kem.rs pbkdf2_password_hash.rs prf.rs random.rs rsa.rs rsa_pkcs1v15.rs sha.rs sha_digest.rs sys.rs
tests
common mod.rs
test_aes.rs test_blake2.rs test_chacha20_poly1305.rs test_cmac.rs test_cmac_mac.rs test_curve25519.rs test_dh.rs test_dilithium.rs test_ecc.rs test_ecdsa.rs test_ed25519.rs test_ed448.rs test_hkdf.rs test_hmac.rs test_hmac_mac.rs test_kdf.rs test_lms.rs test_mlkem.rs test_mlkem_kem.rs test_pbkdf2_password_hash.rs test_prf.rs test_random.rs test_rsa.rs test_rsa_pkcs1v15.rs test_sha.rs test_sha_digest.rs test_wolfcrypt.rs
CHANGELOG.md Cargo.lock Cargo.toml Makefile README.md build.rs headers.h
Makefile README.md include.am
include.am
zephyr
samples
wolfssl_benchmark
boards native_sim.conf nrf5340dk_nrf5340_cpuapp.conf nrf5340dk_nrf5340_cpuapp_ns.conf
CMakeLists.txt README install_test.sh prj.conf sample.yaml zephyr_legacy.conf zephyr_v4.1.conf
wolfssl_test
boards native_sim.conf nrf5340dk_nrf5340_cpuapp.conf nrf5340dk_nrf5340_cpuapp_ns.conf
CMakeLists.txt README install_test.sh prj-no-malloc.conf prj.conf sample.yaml zephyr_legacy.conf zephyr_v4.1.conf
wolfssl_tls_sock
boards native_sim.conf
src tls_sock.c
CMakeLists.txt README install_sample.sh prj-no-malloc.conf prj.conf sample.yaml zephyr_legacy.conf zephyr_v4.1.conf
wolfssl_tls_thread
boards native_sim.conf nrf5340dk_nrf5340_cpuapp.conf nrf5340dk_nrf5340_cpuapp_ns.conf
src tls_threaded.c
CMakeLists.txt README install_sample.sh prj.conf sample.yaml zephyr_legacy.conf zephyr_v4.1.conf
wolfssl options.h
CMakeLists.txt Kconfig Kconfig.tls-generic README.md include.am module.yml user_settings-no-malloc.h user_settings.h zephyr_init.c
.codespellexcludelines .cyignore .editorconfig .gitignore .wolfssl_known_macro_extras AUTHORS CMakeLists.txt CMakePresets.json CMakeSettings.json COPYING ChangeLog.md INSTALL LICENSING LPCExpresso.cproject LPCExpresso.project Makefile.am README README-async.md README.md SCRIPTS-LIST SECURITY-POLICY.md SECURITY-REPORT-TEMPLATE.md Vagrantfile autogen.sh commit-tests.sh configure.ac fips-check.sh fips-hash.sh gencertbuf.pl input pull_to_vagrant.sh quit resource.h stamp-h.in valgrind-bash.supp valgrind-error.sh wnr-example.conf wolfssl-VS2022.vcxproj wolfssl.rc wolfssl.vcproj wolfssl.vcxproj wolfssl64.sln
.clangd .gitignore DOCS.md Makefile README.md assert.c core.c crypto.c env.c fs.c http.c ini.c json.c log.c luna.h main.c makext.mk path.c process.c request.c sqlite.c stash.c template.c util.c
wolfssl/src/ssl.c raw
    1/* ssl.c
    2 *
    3 * Copyright (C) 2006-2026 wolfSSL Inc.
    4 *
    5 * This file is part of wolfSSL.
    6 *
    7 * wolfSSL is free software; you can redistribute it and/or modify
    8 * it under the terms of the GNU General Public License as published by
    9 * the Free Software Foundation; either version 3 of the License, or
   10 * (at your option) any later version.
   11 *
   12 * wolfSSL is distributed in the hope that it will be useful,
   13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
   14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   15 * GNU General Public License for more details.
   16 *
   17 * You should have received a copy of the GNU General Public License
   18 * along with this program; if not, write to the Free Software
   19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA
   20 */
   21
   22#include <wolfssl/wolfcrypt/libwolfssl_sources.h>
   23
   24#if defined(OPENSSL_EXTRA) && !defined(_WIN32) && !defined(_GNU_SOURCE)
   25    /* turn on GNU extensions for XISASCII */
   26    #define _GNU_SOURCE 1
   27#endif
   28
   29#if !defined(WOLFCRYPT_ONLY) || defined(OPENSSL_EXTRA) || \
   30    defined(OPENSSL_EXTRA_X509_SMALL)
   31
   32#include <wolfssl/internal.h>
   33#include <wolfssl/error-ssl.h>
   34#include <wolfssl/wolfcrypt/error-crypt.h>
   35#include <wolfssl/wolfcrypt/coding.h>
   36#include <wolfssl/wolfcrypt/kdf.h>
   37#ifdef NO_INLINE
   38    #include <wolfssl/wolfcrypt/misc.h>
   39#else
   40    #define WOLFSSL_MISC_INCLUDED
   41    #include <wolfcrypt/src/misc.c>
   42#endif
   43
   44#ifdef HAVE_ERRNO_H
   45    #include <errno.h>
   46#endif
   47
   48
   49#if !defined(WOLFSSL_ALLOW_NO_SUITES) && !defined(WOLFCRYPT_ONLY)
   50    #if defined(NO_DH) && !defined(HAVE_ECC) && !defined(WOLFSSL_STATIC_RSA) \
   51                && !defined(WOLFSSL_STATIC_DH) && !defined(WOLFSSL_STATIC_PSK) \
   52                && !defined(HAVE_CURVE25519) && !defined(HAVE_CURVE448)
   53        #error "No cipher suites defined because DH disabled, ECC disabled, " \
   54               "and no static suites defined. Please see top of README"
   55    #endif
   56    #ifdef WOLFSSL_CERT_GEN
   57        /* need access to Cert struct for creating certificate */
   58        #include <wolfssl/wolfcrypt/asn_public.h>
   59    #endif
   60#endif
   61
   62#if !defined(WOLFCRYPT_ONLY) && (defined(OPENSSL_EXTRA)     \
   63    || defined(OPENSSL_EXTRA_X509_SMALL)                    \
   64    || defined(HAVE_WEBSERVER) || defined(WOLFSSL_KEY_GEN))
   65    #include <wolfssl/openssl/evp.h>
   66    /* openssl headers end, wolfssl internal headers next */
   67#endif
   68
   69#include <wolfssl/wolfcrypt/wc_encrypt.h>
   70
   71#ifndef NO_RSA
   72    #include <wolfssl/wolfcrypt/rsa.h>
   73#endif
   74
   75#ifdef OPENSSL_EXTRA
   76    /* openssl headers begin */
   77    #include <wolfssl/openssl/ssl.h>
   78    #include <wolfssl/openssl/aes.h>
   79#ifndef WOLFCRYPT_ONLY
   80    #include <wolfssl/openssl/hmac.h>
   81    #include <wolfssl/openssl/cmac.h>
   82#endif
   83    #include <wolfssl/openssl/crypto.h>
   84    #include <wolfssl/openssl/des.h>
   85    #include <wolfssl/openssl/bn.h>
   86    #include <wolfssl/openssl/buffer.h>
   87    #include <wolfssl/openssl/dh.h>
   88    #include <wolfssl/openssl/rsa.h>
   89    #include <wolfssl/openssl/fips_rand.h>
   90    #include <wolfssl/openssl/pem.h>
   91    #include <wolfssl/openssl/ec.h>
   92    #include <wolfssl/openssl/ec25519.h>
   93    #include <wolfssl/openssl/ed25519.h>
   94    #include <wolfssl/openssl/ec448.h>
   95    #include <wolfssl/openssl/ed448.h>
   96    #include <wolfssl/openssl/ecdsa.h>
   97    #include <wolfssl/openssl/ecdh.h>
   98    #include <wolfssl/openssl/err.h>
   99    #include <wolfssl/openssl/modes.h>
  100    #include <wolfssl/openssl/opensslv.h>
  101    #include <wolfssl/openssl/rc4.h>
  102    #include <wolfssl/openssl/stack.h>
  103    #include <wolfssl/openssl/x509_vfy.h>
  104    /* openssl headers end, wolfssl internal headers next */
  105    #include <wolfssl/wolfcrypt/hmac.h>
  106    #include <wolfssl/wolfcrypt/random.h>
  107    #include <wolfssl/wolfcrypt/des3.h>
  108    #include <wolfssl/wolfcrypt/ecc.h>
  109    #include <wolfssl/wolfcrypt/md4.h>
  110    #include <wolfssl/wolfcrypt/md5.h>
  111    #include <wolfssl/wolfcrypt/arc4.h>
  112    #include <wolfssl/wolfcrypt/curve25519.h>
  113    #include <wolfssl/wolfcrypt/ed25519.h>
  114    #include <wolfssl/wolfcrypt/curve448.h>
  115    #if defined(HAVE_FALCON)
  116        #include <wolfssl/wolfcrypt/falcon.h>
  117    #endif /* HAVE_FALCON */
  118    #if defined(HAVE_DILITHIUM)
  119        #include <wolfssl/wolfcrypt/dilithium.h>
  120    #endif /* HAVE_DILITHIUM */
  121    #if defined(OPENSSL_ALL) || defined(HAVE_STUNNEL)
  122        #ifdef HAVE_OCSP
  123            #include <wolfssl/openssl/ocsp.h>
  124        #endif
  125        #include <wolfssl/openssl/lhash.h>
  126        #include <wolfssl/openssl/txt_db.h>
  127    #endif /* WITH_STUNNEL */
  128    #if defined(WOLFSSL_SHA512) || defined(WOLFSSL_SHA384)
  129        #include <wolfssl/wolfcrypt/sha512.h>
  130    #endif
  131    #if defined(WOLFCRYPT_HAVE_SRP) && !defined(NO_SHA256) \
  132        && !defined(WC_NO_RNG)
  133        #include <wolfssl/wolfcrypt/srp.h>
  134    #endif
  135#endif
  136
  137#if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)
  138    #include <wolfssl/openssl/x509v3.h>
  139    int wolfssl_bn_get_value(WOLFSSL_BIGNUM* bn, mp_int* mpi);
  140    int wolfssl_bn_set_value(WOLFSSL_BIGNUM** bn, mp_int* mpi);
  141#endif
  142
  143#if defined(WOLFSSL_QT)
  144    #include <wolfssl/wolfcrypt/sha.h>
  145#endif
  146
  147#ifdef NO_ASN
  148    #include <wolfssl/wolfcrypt/dh.h>
  149#endif
  150#endif /* !WOLFCRYPT_ONLY || OPENSSL_EXTRA */
  151
  152/*
  153 * ssl.c Build Options:
  154 *
  155 * See also: tls.c for TLS extension/protocol options, tls13.c for TLS 1.3,
  156 *           internal.c for handshake internals, wc_port.c for platform/memory.
  157 *
  158 * OpenSSL Compatibility:
  159 * OPENSSL_EXTRA:              Enable OpenSSL compatibility API        default: off
  160 * OPENSSL_ALL:                Enable all OpenSSL compat APIs          default: off
  161 * OPENSSL_EXTRA_X509_SMALL:   Minimal OpenSSL X509 compat APIs       default: off
  162 * OPENSSL_EXTRA_NO_ASN1:      OpenSSL extra without ASN1 objects      default: off
  163 * OPENSSL_COMPATIBLE_DEFAULTS:
  164 *                  Default behavior compatible with OpenSSL           default: off
  165 * NO_WOLFSSL_STUB:            Disable stubs for unimplemented funcs   default: off
  166 * WOLFSSL_DEBUG_OPENSSL:      Debug logging for OpenSSL compat layer  default: off
  167 * WOLFSSL_HAVE_ERROR_QUEUE:   OpenSSL-compatible error queue          default: off
  168 * WOLFSSL_ERROR_CODE_OPENSSL: Use OpenSSL-compatible error codes      default: off
  169 * WOLFSSL_CIPHER_INTERNALNAME:
  170 *                  Use wolfSSL internal cipher suite names             default: off
  171 * NO_CIPHER_SUITE_ALIASES:    Disable cipher suite name aliases       default: off
  172 * WOLFSSL_SET_CIPHER_BYTES:   Set cipher suites by raw byte values    default: off
  173 * WOLFSSL_OLD_SET_CURVES_LIST:
  174 *                  Old-style curve list parsing for compat             default: off
  175 * WOLFSSL_NO_OPENSSL_RAND_CB: Disable OpenSSL RAND callback compat   default: off
  176 * NO_ERROR_STRINGS:           Disable human-readable error strings    default: off
  177 * WOLFSSL_PUBLIC_ASN:         Make ASN parsing functions public        default: off
  178 *
  179 * Extra Data / BIO:
  180 * HAVE_EX_DATA:               Enable ex_data on SSL/CTX/X509 objects  default: off
  181 * HAVE_EX_DATA_CLEANUP_HOOKS: Cleanup callbacks for ex_data           default: off
  182 * HAVE_EX_DATA_CRYPTO:        ex_data support for wolfCrypt objects   default: off
  183 * MAX_EX_DATA:                Max ex_data entries per object           default: 5
  184 * NO_BIO:                     Disable BIO abstraction layer           default: off
  185 *
  186 * Session & Cache:
  187 * NO_SESSION_CACHE:           Disable server session cache            default: off
  188 * NO_SESSION_CACHE_REF:       wolfSSL_get_session returns ssl->session
  189 *                             reference instead of ClientCache ref    default: off
  190 * SESSION_CACHE_DYNAMIC_MEM:  Dynamically allocate session cache      default: off
  191 * NO_CLIENT_CACHE:            Disable client-side session cache       default: off
  192 * SESSION_CERTS:              Store full cert chain in session         default: off
  193 * WOLFSSL_SESSION_ID_CTX:     Session ID context for cache sharing    default: off
  194 *
  195 * I/O & Transport:
  196 * USE_WOLFSSL_IO:             Use built-in I/O callbacks              default: on
  197 * WOLFSSL_USER_IO:            Application provides custom I/O         default: off
  198 * WOLFSSL_NO_SOCK:            Build without socket support            default: off
  199 * NO_WRITEV:                  Disable writev() scatter/gather I/O     default: off
  200 * WOLFSSL_DTLS_MTU:           Enable DTLS MTU management APIs         default: off
  201 * WOLFSSL_DTLS_DROP_STATS:    Track DTLS packet drop statistics       default: off
  202 * WOLFSSL_MULTICAST:          Enable DTLS multicast support           default: off
  203 *
  204 * Callbacks & Features:
  205 * WOLFSSL_CHECK_ALERT_ON_ERR: Check alerts on handshake error         default: off
  206 * ATOMIC_USER:                User-defined record layer callbacks      default: off
  207 * HAVE_WRITE_DUP:             Separate threads for SSL read/write     default: off
  208 * WOLFSSL_CALLBACKS:          Handshake monitoring callbacks           default: off
  209 * NO_HANDSHAKE_DONE_CB:       Disable handshake completion callback   default: off
  210 * WOLFSSL_SHUTDOWNONCE:       Send close_notify only once             default: off
  211 * WOLFSSL_COPY_CERT:          Copy certificate buffer (own copy)      default: off
  212 * WOLFSSL_COPY_KEY:           Copy private key buffer (own copy)      default: off
  213 * WOLF_PRIVATE_KEY_ID:        Reference private keys by ID            default: off
  214 * WOLFSSL_REFCNT_ERROR_RETURN:
  215 *                  Return errors on ref counting failures             default: off
  216 * WOLFSSL_ALLOW_MAX_FRAGMENT_ADJUST:
  217 *                  Allow runtime max fragment size adjustment          default: off
  218 * WOLFSSL_ALLOW_NO_SUITES:    Allow SSL objects with no cipher suites default: off
  219 *
  220 * Certificates & Keys:
  221 * KEEP_PEER_CERT:             Keep peer cert after handshake          default: off
  222 * KEEP_OUR_CERT:              Keep our cert after handshake           default: off
  223 * WOLFSSL_STATIC_RSA:         Enable static RSA key exchange          default: off
  224 * WOLFSSL_HAVE_CERT_SERVICE:  Certificate service callbacks           default: off
  225 * WOLFSSL_SYS_CA_CERTS:       Load system CA certs from OS            default: off
  226 *
  227 * Application Compatibility:
  228 * HAVE_CURL:                  APIs for libcurl compatibility          default: off
  229 * HAVE_LIGHTY:                APIs for lighttpd compatibility         default: off
  230 * HAVE_MEMCACHED:             APIs for memcached compatibility        default: off
  231 * WOLFSSL_APACHE_HTTPD:       APIs for Apache httpd compatibility     default: off
  232 * WOLFSSL_NGINX:              APIs for nginx compatibility            default: off
  233 * WOLFSSL_HAPROXY:            APIs for HAProxy compatibility          default: off
  234 * WOLFSSL_ASIO:               APIs for Boost.Asio compatibility       default: off
  235 * WOLFSSL_PYTHON:             APIs for Python module compatibility    default: off
  236 * WOLFSSL_QT:                 APIs for Qt framework compatibility     default: off
  237 * WOLFSSL_JNI:                APIs for Java JNI/JSSE compatibility    default: off
  238 *
  239 * Protocol Features:
  240 * WOLFSSL_HAVE_WOLFSCEP:      Enable wolfSCEP protocol support        default: off
  241 * WOLFCRYPT_HAVE_SRP:         Enable SRP protocol support             default: off
  242 * HAVE_LIBZ:                  Enable zlib TLS compression             default: off
  243 * WOLFSSL_EXTRA:              Extra SSL session info APIs              default: off
  244 * WOLFSSL_WPAS_SMALL:         Minimal wpa_supplicant/hostapd APIs     default: off
  245 * HAVE_FUZZER:                Fuzzing callback support                 default: off
  246 *
  247 * Memory & Threading:
  248 * WOLFSSL_STATIC_MEMORY_LEAN: Lean static memory allocation           default: off
  249 * WOLFSSL_THREADED_CRYPT:     Multi-threaded crypto operations         default: off
  250 * WOLFSSL_CLEANUP_THREADSAFE_BY_ATOMIC_OPS:
  251 *                  Thread-safe cleanup via atomics                     default: off
  252 * WOLFSSL_ATOMIC_INITIALIZER: Static init for atomic variables        default: off
  253 * WOLFSSL_DEBUG_MEMORY:       Log malloc/free with file/line info     default: off
  254 * WOLFSSL_NO_REALLOC:         Disable realloc, use malloc+copy+free   default: off
  255 * WOLFSSL_HEAP_TEST:          Heap-related testing utilities           default: off
  256 *
  257 * Debugging & Build:
  258 * SHOW_SIZES:                 Display struct sizes at init             default: off
  259 * WOLFSSL_DEBUG_TRACE_ERROR_CODES:
  260 *                  Trace error code origins for debugging              default: off
  261 * HAVE_ATEXIT:                Register wolfSSL_Cleanup via atexit     default: off
  262 * WOLFSSL_SYS_CRYPTO_POLICY:  Honor system crypto policy settings     default: off
  263 *
  264 * Hardware TLS:
  265 * WOLFSSL_RENESAS_TSIP_TLS:   Renesas TSIP hardware crypto for TLS   default: off
  266 * WOLFSSL_RENESAS_FSPSM_TLS:  Renesas FSP Security Module for TLS    default: off
  267 * WOLFSSL_EGD_NBLOCK:         Non-blocking EGD entropy support        default: off
  268 */
  269
  270#define WOLFSSL_SSL_MISC_INCLUDED
  271#include "src/ssl_misc.c"
  272
  273#define WOLFSSL_EVP_INCLUDED
  274#include "wolfcrypt/src/evp.c"
  275
  276/* Crypto code uses EVP APIs. */
  277#define WOLFSSL_SSL_CRYPTO_INCLUDED
  278#include "src/ssl_crypto.c"
  279
  280#ifndef WOLFCRYPT_ONLY
  281#define WOLFSSL_SSL_CERTMAN_INCLUDED
  282#include "src/ssl_certman.c"
  283
  284#define WOLFSSL_SSL_SESS_INCLUDED
  285#include "src/ssl_sess.c"
  286
  287#define WOLFSSL_SSL_API_CERT_INCLUDED
  288#include "src/ssl_api_cert.c"
  289
  290#define WOLFSSL_SSL_API_PK_INCLUDED
  291#include "src/ssl_api_pk.c"
  292#endif
  293
  294#if (defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)) && \
  295    !defined(WOLFCRYPT_ONLY)
  296/* Convert shortname to NID.
  297 *
  298 * For OpenSSL compatibility.
  299 *
  300 * @param [in] sn  Short name of OID.
  301 * @return  NID corresponding to shortname on success.
  302 * @return  WC_NID_undef when not recognized.
  303 */
  304int wc_OBJ_sn2nid(const char *sn)
  305{
  306    const WOLFSSL_ObjectInfo *obj_info = wolfssl_object_info;
  307    size_t i;
  308    WOLFSSL_ENTER("wc_OBJ_sn2nid");
  309    for (i = 0; i < wolfssl_object_info_sz; i++, obj_info++) {
  310        if (XSTRCMP(sn, obj_info->sName) == 0)
  311            return obj_info->nid;
  312    }
  313    WOLFSSL_MSG("short name not found in table");
  314    return WC_NID_undef;
  315}
  316#endif /* OPENSSL_EXTRA || OPENSSL_EXTRA_X509_SMALL */
  317
  318#ifndef WOLFCRYPT_ONLY
  319
  320
  321#if defined(WOLFSSL_SYS_CRYPTO_POLICY)
  322/* The system wide crypto-policy. Configured by wolfSSL_crypto_policy_enable.
  323 * */
  324static struct SystemCryptoPolicy crypto_policy;
  325#endif /* WOLFSSL_SYS_CRYPTO_POLICY */
  326
  327#if !defined(NO_RSA) || !defined(NO_DH) || defined(HAVE_ECC) || \
  328    (defined(OPENSSL_EXTRA) && defined(WOLFSSL_KEY_GEN) && !defined(NO_DSA))
  329
  330#define HAVE_GLOBAL_RNG /* consolidate flags for using globalRNG */
  331static WC_RNG globalRNG;
  332static volatile int initGlobalRNG = 0;
  333
  334#if defined(OPENSSL_EXTRA) || !defined(WOLFSSL_MUTEX_INITIALIZER)
  335static WC_MAYBE_UNUSED wolfSSL_Mutex globalRNGMutex
  336    WOLFSSL_MUTEX_INITIALIZER_CLAUSE(globalRNGMutex);
  337#endif
  338#ifndef WOLFSSL_MUTEX_INITIALIZER
  339static int globalRNGMutex_valid = 0;
  340#endif
  341
  342#if defined(OPENSSL_EXTRA) && defined(HAVE_HASHDRBG)
  343static WOLFSSL_DRBG_CTX* gDrbgDefCtx = NULL;
  344#endif
  345
  346WC_RNG* wolfssl_get_global_rng(void)
  347{
  348    WC_RNG* ret = NULL;
  349
  350    if (initGlobalRNG == 0)
  351        WOLFSSL_MSG("Global RNG no Init");
  352    else
  353        ret = &globalRNG;
  354
  355    return ret;
  356}
  357
  358/* Make a global RNG and return.
  359 *
  360 * @return  Global RNG on success.
  361 * @return  NULL on error.
  362 */
  363WC_RNG* wolfssl_make_global_rng(void)
  364{
  365    WC_RNG* ret;
  366
  367#ifdef HAVE_GLOBAL_RNG
  368    /* Get the global random number generator instead. */
  369    ret = wolfssl_get_global_rng();
  370#ifdef OPENSSL_EXTRA
  371    if (ret == NULL) {
  372        /* Create a global random if possible. */
  373        (void)wolfSSL_RAND_Init();
  374        ret = wolfssl_get_global_rng();
  375    }
  376#endif
  377#else
  378    WOLFSSL_ERROR_MSG("Bad RNG Init");
  379    ret = NULL;
  380#endif
  381
  382    return ret;
  383}
  384
  385/* Too many defines to check explicitly - prototype it and always include
  386 * for RSA, DH, ECC and DSA for BN. */
  387WC_RNG* wolfssl_make_rng(WC_RNG* rng, int* local);
  388
  389/* Make a random number generator or get global if possible.
  390 *
  391 * Global may not be available and NULL will be returned.
  392 *
  393 * @param [in, out] rng    Local random number generator.
  394 * @param [out]     local  Local random number generator returned.
  395 * @return  NULL on failure.
  396 * @return  A random number generator object.
  397 */
  398WC_RNG* wolfssl_make_rng(WC_RNG* rng, int* local)
  399{
  400    WC_RNG* ret = NULL;
  401#ifdef WOLFSSL_SMALL_STACK
  402    int freeRng = 0;
  403
  404    /* Allocate RNG object . */
  405    if (rng == NULL) {
  406        rng = (WC_RNG*)XMALLOC(sizeof(WC_RNG), NULL, DYNAMIC_TYPE_RNG);
  407        freeRng = 1;
  408    }
  409#endif
  410
  411    if (rng != NULL) {
  412        if (wc_InitRng(rng) == 0) {
  413            ret = rng;
  414            *local = 1;
  415        }
  416        else {
  417            WOLFSSL_MSG("Bad RNG Init");
  418#ifdef WOLFSSL_SMALL_STACK
  419            if (freeRng) {
  420                XFREE(rng, NULL, DYNAMIC_TYPE_RNG);
  421                rng = NULL;
  422            }
  423#endif
  424        }
  425    }
  426    if (ret == NULL) {
  427#ifdef HAVE_GLOBAL_RNG
  428        WOLFSSL_MSG("trying global RNG");
  429#endif
  430        ret = wolfssl_make_global_rng();
  431    }
  432
  433    return ret;
  434}
  435#endif
  436
  437#ifdef OPENSSL_EXTRA
  438    /* WOLFSSL_NO_OPENSSL_RAND_CB: Allows way to reduce code size for
  439     *                OPENSSL_EXTRA where RAND callbacks are not used */
  440    #ifndef WOLFSSL_NO_OPENSSL_RAND_CB
  441        static const WOLFSSL_RAND_METHOD* gRandMethods = NULL;
  442        static wolfSSL_Mutex gRandMethodMutex
  443            WOLFSSL_MUTEX_INITIALIZER_CLAUSE(gRandMethodMutex);
  444        #ifndef WOLFSSL_MUTEX_INITIALIZER
  445        static int gRandMethodsInit = 0;
  446        #endif
  447    #endif /* !WOLFSSL_NO_OPENSSL_RAND_CB */
  448#endif /* OPENSSL_EXTRA */
  449
  450#define WOLFSSL_SSL_BN_INCLUDED
  451#include "src/ssl_bn.c"
  452
  453#ifndef OPENSSL_EXTRA_NO_ASN1
  454#define WOLFSSL_SSL_ASN1_INCLUDED
  455#include "src/ssl_asn1.c"
  456#endif /* OPENSSL_EXTRA_NO_ASN1 */
  457
  458#define WOLFSSL_PK_INCLUDED
  459#include "src/pk.c"
  460
  461#define WOLFSSL_EVP_PK_INCLUDED
  462#include "wolfcrypt/src/evp_pk.c"
  463
  464#if defined(OPENSSL_EXTRA) || defined(WOLFSSL_WPAS_SMALL)
  465/* copies over data of "in" to "out" */
  466static void wolfSSL_CIPHER_copy(WOLFSSL_CIPHER* in, WOLFSSL_CIPHER* out)
  467{
  468    if (in == NULL || out == NULL)
  469        return;
  470
  471    *out = *in;
  472}
  473
  474
  475#if defined(OPENSSL_ALL)
  476static WOLFSSL_X509_OBJECT* wolfSSL_X509_OBJECT_dup(WOLFSSL_X509_OBJECT* obj)
  477{
  478    WOLFSSL_X509_OBJECT* ret = NULL;
  479    if (obj) {
  480        ret = wolfSSL_X509_OBJECT_new();
  481        if (ret) {
  482            ret->type = obj->type;
  483            switch (ret->type) {
  484                case WOLFSSL_X509_LU_NONE:
  485                    break;
  486                case WOLFSSL_X509_LU_X509:
  487                    ret->data.x509 = wolfSSL_X509_dup(obj->data.x509);
  488                    break;
  489                case WOLFSSL_X509_LU_CRL:
  490            #if defined(HAVE_CRL)
  491                    ret->data.crl = wolfSSL_X509_CRL_dup(obj->data.crl);
  492            #endif
  493                    break;
  494            }
  495        }
  496    }
  497    return ret;
  498}
  499#endif /* OPENSSL_ALL */
  500
  501#endif /* OPENSSL_EXTRA || WOLFSSL_WPAS_SMALL */
  502
  503#define WOLFSSL_SSL_SK_INCLUDED
  504#include "src/ssl_sk.c"
  505
  506
  507#include <wolfssl/wolfcrypt/hpke.h>
  508
  509#define WOLFSSL_SSL_ECH_INCLUDED
  510#include "src/ssl_ech.c"
  511
  512#ifdef OPENSSL_EXTRA
  513static int wolfSSL_parse_cipher_list(WOLFSSL_CTX* ctx, WOLFSSL* ssl,
  514        Suites* suites, const char* list);
  515#endif
  516
  517#if defined(WOLFSSL_RENESAS_TSIP_TLS) || defined(WOLFSSL_RENESAS_FSPSM_TLS)
  518#include <wolfssl/wolfcrypt/port/Renesas/renesas_cmn.h>
  519#endif
  520
  521/* prevent multiple mutex initializations */
  522
  523/* note, initRefCount is not used for thread synchronization, only for
  524 * bookkeeping while inits_count_mutex is held.
  525 */
  526static volatile WC_THREADSHARED int initRefCount = 0;
  527
  528/* init ref count mutex */
  529static WC_THREADSHARED wolfSSL_Mutex inits_count_mutex
  530    WOLFSSL_MUTEX_INITIALIZER_CLAUSE(inits_count_mutex);
  531#ifndef WOLFSSL_MUTEX_INITIALIZER
  532static WC_THREADSHARED volatile int inits_count_mutex_valid = 0;
  533#endif
  534
  535#ifdef NO_TLS
  536static const WOLFSSL_METHOD gNoTlsMethod;
  537#endif
  538
  539/* Create a new WOLFSSL_CTX struct and return the pointer to created struct.
  540   WOLFSSL_METHOD pointer passed in is given to ctx to manage.
  541   This function frees the passed in WOLFSSL_METHOD struct on failure and on
  542   success is freed when ctx is freed.
  543 */
  544WOLFSSL_CTX* wolfSSL_CTX_new_ex(WOLFSSL_METHOD* method, void* heap)
  545{
  546    WOLFSSL_CTX* ctx = NULL;
  547
  548    WOLFSSL_ENTER("wolfSSL_CTX_new_ex");
  549
  550    if (initRefCount == 0) {
  551        /* user no longer forced to call Init themselves */
  552        int ret = wolfSSL_Init();
  553        if (ret != WOLFSSL_SUCCESS) {
  554            WOLFSSL_MSG("wolfSSL_Init failed");
  555            WOLFSSL_LEAVE("wolfSSL_CTX_new_ex", 0);
  556            XFREE(method, heap, DYNAMIC_TYPE_METHOD);
  557            return NULL;
  558        }
  559    }
  560
  561#ifndef NO_TLS
  562    if (method == NULL)
  563        return ctx;
  564#else
  565    /* a blank TLS method */
  566    method = (WOLFSSL_METHOD*)&gNoTlsMethod;
  567#endif
  568
  569    ctx = (WOLFSSL_CTX*)XMALLOC(sizeof(WOLFSSL_CTX), heap, DYNAMIC_TYPE_CTX);
  570    if (ctx) {
  571        int ret;
  572
  573        ret = InitSSL_Ctx(ctx, method, heap);
  574    #ifdef WOLFSSL_STATIC_MEMORY
  575        if (heap != NULL) {
  576            ctx->onHeapHint = 1; /* free the memory back to heap when done */
  577        }
  578    #endif
  579        if (ret < 0) {
  580            WOLFSSL_MSG("Init CTX failed");
  581            wolfSSL_CTX_free(ctx);
  582            ctx = NULL;
  583        }
  584#if defined(OPENSSL_EXTRA) && defined(WOLFCRYPT_HAVE_SRP) \
  585                           && !defined(NO_SHA256) && !defined(WC_NO_RNG)
  586        else {
  587            ctx->srp = (Srp*)XMALLOC(sizeof(Srp), heap, DYNAMIC_TYPE_SRP);
  588            if (ctx->srp == NULL){
  589                WOLFSSL_MSG("Init CTX failed");
  590                wolfSSL_CTX_free(ctx);
  591                return NULL;
  592            }
  593            XMEMSET(ctx->srp, 0, sizeof(Srp));
  594        }
  595#endif
  596    }
  597    else {
  598        WOLFSSL_MSG("Alloc CTX failed, method freed");
  599        XFREE(method, heap, DYNAMIC_TYPE_METHOD);
  600    }
  601
  602#ifdef OPENSSL_COMPATIBLE_DEFAULTS
  603    if (ctx) {
  604        wolfSSL_CTX_set_verify(ctx, WOLFSSL_VERIFY_NONE, NULL);
  605        wolfSSL_CTX_set_mode(ctx, WOLFSSL_MODE_AUTO_RETRY);
  606        if (wolfSSL_CTX_set_min_proto_version(ctx,
  607                (method->version.major == DTLS_MAJOR) ?
  608                DTLS1_VERSION : SSL3_VERSION) != WOLFSSL_SUCCESS ||
  609#ifdef HAVE_ANON
  610                wolfSSL_CTX_allow_anon_cipher(ctx) != WOLFSSL_SUCCESS ||
  611#endif
  612                wolfSSL_CTX_set_group_messages(ctx) != WOLFSSL_SUCCESS) {
  613            WOLFSSL_MSG("Setting OpenSSL CTX defaults failed");
  614            wolfSSL_CTX_free(ctx);
  615            ctx = NULL;
  616        }
  617    }
  618#endif
  619
  620#if defined(WOLFSSL_SYS_CRYPTO_POLICY)
  621    /* Load the crypto-policy ciphers if configured. */
  622    if (ctx && wolfSSL_crypto_policy_is_enabled()) {
  623        const char * list = wolfSSL_crypto_policy_get_ciphers();
  624        int          ret = 0;
  625
  626        if (list != NULL && *list != '\0') {
  627            if (AllocateCtxSuites(ctx) != 0) {
  628                WOLFSSL_MSG("allocate ctx suites failed");
  629                wolfSSL_CTX_free(ctx);
  630                ctx = NULL;
  631            }
  632            else {
  633                ret = wolfSSL_parse_cipher_list(ctx, NULL, ctx->suites, list);
  634                if (ret != WOLFSSL_SUCCESS) {
  635                    WOLFSSL_MSG("parse cipher list failed");
  636                    wolfSSL_CTX_free(ctx);
  637                    ctx = NULL;
  638                }
  639            }
  640        }
  641    }
  642#endif /* WOLFSSL_SYS_CRYPTO_POLICY */
  643
  644    WOLFSSL_LEAVE("wolfSSL_CTX_new_ex", 0);
  645    return ctx;
  646}
  647
  648
  649WOLFSSL_ABI
  650WOLFSSL_CTX* wolfSSL_CTX_new(WOLFSSL_METHOD* method)
  651{
  652#ifdef WOLFSSL_HEAP_TEST
  653    /* if testing the heap hint then set top level CTX to have test value */
  654    return wolfSSL_CTX_new_ex(method, (void*)WOLFSSL_HEAP_TEST);
  655#else
  656    return wolfSSL_CTX_new_ex(method, NULL);
  657#endif
  658}
  659
  660/* increases CTX reference count to track proper time to "free" */
  661int wolfSSL_CTX_up_ref(WOLFSSL_CTX* ctx)
  662{
  663    int ret;
  664    wolfSSL_RefWithMutexInc(&ctx->ref, &ret);
  665#ifdef WOLFSSL_REFCNT_ERROR_RETURN
  666    return ((ret == 0) ? WOLFSSL_SUCCESS : WOLFSSL_FAILURE);
  667#else
  668    (void)ret;
  669    return WOLFSSL_SUCCESS;
  670#endif
  671}
  672
  673WOLFSSL_ABI
  674void wolfSSL_CTX_free(WOLFSSL_CTX* ctx)
  675{
  676    WOLFSSL_ENTER("wolfSSL_CTX_free");
  677    if (ctx) {
  678        FreeSSL_Ctx(ctx);
  679    }
  680
  681    WOLFSSL_LEAVE("wolfSSL_CTX_free", 0);
  682}
  683
  684
  685#ifdef HAVE_ENCRYPT_THEN_MAC
  686/**
  687 * Sets whether Encrypt-Then-MAC extension can be negotiated against context.
  688 * The default value: enabled.
  689 *
  690 * ctx  SSL/TLS context.
  691 * set  Whether to allow or not: 1 is allow and 0 is disallow.
  692 * returns WOLFSSL_SUCCESS
  693 */
  694int wolfSSL_CTX_AllowEncryptThenMac(WOLFSSL_CTX *ctx, int set)
  695{
  696    ctx->disallowEncThenMac = !set;
  697    return WOLFSSL_SUCCESS;
  698}
  699
  700/**
  701 * Sets whether Encrypt-Then-MAC extension can be negotiated against context.
  702 * The default value comes from context.
  703 *
  704 * ctx  SSL/TLS context.
  705 * set  Whether to allow or not: 1 is allow and 0 is disallow.
  706 * returns WOLFSSL_SUCCESS
  707 */
  708int wolfSSL_AllowEncryptThenMac(WOLFSSL *ssl, int set)
  709{
  710    ssl->options.disallowEncThenMac = !set;
  711    return WOLFSSL_SUCCESS;
  712}
  713#endif
  714
  715#ifdef SINGLE_THREADED
  716/* no locking in single threaded mode, allow a CTX level rng to be shared with
  717 * WOLFSSL objects, WOLFSSL_SUCCESS on ok */
  718int wolfSSL_CTX_new_rng(WOLFSSL_CTX* ctx)
  719{
  720    WC_RNG* rng;
  721    int     ret;
  722
  723    if (ctx == NULL) {
  724        return BAD_FUNC_ARG;
  725    }
  726
  727    rng = (WC_RNG*)XMALLOC(sizeof(WC_RNG), ctx->heap, DYNAMIC_TYPE_RNG);
  728    if (rng == NULL) {
  729        return MEMORY_E;
  730    }
  731
  732#ifndef HAVE_FIPS
  733    ret = wc_InitRng_ex(rng, ctx->heap, ctx->devId);
  734#else
  735    ret = wc_InitRng(rng);
  736#endif
  737    if (ret != 0) {
  738        XFREE(rng, ctx->heap, DYNAMIC_TYPE_RNG);
  739        return ret;
  740    }
  741
  742    ctx->rng = rng;
  743    return WOLFSSL_SUCCESS;
  744}
  745#endif
  746
  747
  748WOLFSSL_ABI
  749WOLFSSL* wolfSSL_new(WOLFSSL_CTX* ctx)
  750{
  751    WOLFSSL* ssl = NULL;
  752    int ret = 0;
  753
  754    WOLFSSL_ENTER("wolfSSL_new");
  755
  756    if (ctx == NULL) {
  757        WOLFSSL_MSG("wolfSSL_new ctx is null");
  758        return NULL;
  759    }
  760
  761    ssl = (WOLFSSL*) XMALLOC(sizeof(WOLFSSL), ctx->heap, DYNAMIC_TYPE_SSL);
  762
  763    if (ssl == NULL) {
  764        WOLFSSL_MSG_EX("ssl xmalloc failed to allocate %d bytes",
  765                        (int)sizeof(WOLFSSL));
  766    }
  767    else {
  768        ret = InitSSL(ssl, ctx, 0);
  769        if (ret < 0) {
  770            WOLFSSL_MSG_EX("wolfSSL_new failed during InitSSL. err = %d", ret);
  771            FreeSSL(ssl, ctx->heap);
  772            ssl = NULL;
  773        }
  774        else if (ret == 0) {
  775            WOLFSSL_MSG("wolfSSL_new InitSSL success");
  776        }
  777        else {
  778            /* Only success (0) or negative values should ever be seen. */
  779            WOLFSSL_MSG_EX("WARNING: wolfSSL_new unexpected InitSSL return"
  780                           " value = %d", ret);
  781        } /* InitSSL check */
  782    } /* ssl XMALLOC success */
  783
  784    WOLFSSL_LEAVE("wolfSSL_new InitSSL =", ret);
  785    (void)ret;
  786
  787    return ssl;
  788}
  789
  790
  791WOLFSSL_ABI
  792void wolfSSL_free(WOLFSSL* ssl)
  793{
  794    WOLFSSL_ENTER("wolfSSL_free");
  795
  796    if (ssl) {
  797        WOLFSSL_MSG_EX("Free SSL: %p", (wc_ptr_t)ssl);
  798        FreeSSL(ssl, ssl->ctx->heap);
  799    }
  800    else {
  801        WOLFSSL_MSG("Free SSL: wolfSSL_free already null");
  802    }
  803    WOLFSSL_LEAVE("wolfSSL_free", 0);
  804}
  805
  806
  807int wolfSSL_is_server(WOLFSSL* ssl)
  808{
  809    if (ssl == NULL)
  810        return BAD_FUNC_ARG;
  811    return ssl->options.side == WOLFSSL_SERVER_END;
  812}
  813
  814#ifdef HAVE_WRITE_DUP
  815
  816/*
  817 * Release resources around WriteDup object
  818 *
  819 * ssl WOLFSSL object
  820 *
  821 * no return, destruction so make best attempt
  822*/
  823void FreeWriteDup(WOLFSSL* ssl)
  824{
  825    int doFree = 0;
  826
  827    WOLFSSL_ENTER("FreeWriteDup");
  828
  829    if (ssl->dupWrite) {
  830        if (wc_LockMutex(&ssl->dupWrite->dupMutex) == 0) {
  831            ssl->dupWrite->dupCount--;
  832            if (ssl->dupWrite->dupCount == 0) {
  833                doFree = 1;
  834            } else {
  835                WOLFSSL_MSG("WriteDup count not zero, no full free");
  836            }
  837            wc_UnLockMutex(&ssl->dupWrite->dupMutex);
  838        }
  839    }
  840
  841    if (doFree) {
  842#ifdef WOLFSSL_DTLS13
  843        struct Dtls13RecordNumber* rn = ssl->dupWrite->sendAckList;
  844        while (rn != NULL) {
  845            struct Dtls13RecordNumber* next = rn->next;
  846            XFREE(rn, ssl->heap, DYNAMIC_TYPE_DTLS_MSG);
  847            rn = next;
  848        }
  849#endif
  850#if defined(WOLFSSL_TLS13) && defined(WOLFSSL_POST_HANDSHAKE_AUTH)
  851        Free_HS_Hashes(ssl->dupWrite->postHandshakeHashState, ssl->heap);
  852        {
  853            CertReqCtx* ctx = ssl->dupWrite->postHandshakeCertReqCtx;
  854            while (ctx != NULL) {
  855                CertReqCtx* nxt = ctx->next;
  856                XFREE(ctx, ssl->heap, DYNAMIC_TYPE_TMP_BUFFER);
  857                ctx = nxt;
  858            }
  859        }
  860#endif /* WOLFSSL_TLS13 && WOLFSSL_POST_HANDSHAKE_AUTH */
  861        wc_FreeMutex(&ssl->dupWrite->dupMutex);
  862        XFREE(ssl->dupWrite, ssl->heap, DYNAMIC_TYPE_WRITEDUP);
  863        ssl->dupWrite = NULL;
  864        WOLFSSL_MSG("Did WriteDup full free, count to zero");
  865    }
  866}
  867
  868
  869/*
  870 * duplicate existing ssl members into dup needed for writing
  871 *
  872 * dup write only WOLFSSL
  873 * ssl existing WOLFSSL
  874 *
  875 * 0 on success
  876*/
  877static int DupSSL(WOLFSSL* dup, WOLFSSL* ssl)
  878{
  879    word16 tmp_weOwnRng;
  880#ifdef HAVE_ONE_TIME_AUTH
  881#ifdef HAVE_POLY1305
  882    Poly1305* tmp_poly1305 = NULL;
  883#endif
  884#endif
  885
  886    /* shared dupWrite setup */
  887    ssl->dupWrite = (WriteDup*)XMALLOC(sizeof(WriteDup), ssl->heap,
  888                                       DYNAMIC_TYPE_WRITEDUP);
  889    if (ssl->dupWrite == NULL) {
  890        return MEMORY_E;
  891    }
  892    XMEMSET(ssl->dupWrite, 0, sizeof(WriteDup));
  893
  894    if (wc_InitMutex(&ssl->dupWrite->dupMutex) != 0) {
  895        XFREE(ssl->dupWrite, ssl->heap, DYNAMIC_TYPE_WRITEDUP);
  896        ssl->dupWrite = NULL;
  897        return BAD_MUTEX_E;
  898    }
  899
  900    /* Pre-allocate any objects that can fail BEFORE performing destructive
  901     * state mutations on ssl, so an allocation failure cannot leave ssl
  902     * with a zeroed encrypt context and a poisoned dupWrite.
  903     * dup->heap == ssl->heap here because dup was initialised with ssl->ctx;
  904     * use ssl->heap consistently for cleanup symmetry. */
  905#ifdef HAVE_ONE_TIME_AUTH
  906#ifdef HAVE_POLY1305
  907    if (ssl->auth.setup && ssl->auth.poly1305 != NULL) {
  908        tmp_poly1305 = (Poly1305*)XMALLOC(sizeof(Poly1305), ssl->heap,
  909            DYNAMIC_TYPE_CIPHER);
  910        if (tmp_poly1305 == NULL) {
  911            wc_FreeMutex(&ssl->dupWrite->dupMutex);
  912            XFREE(ssl->dupWrite, ssl->heap, DYNAMIC_TYPE_WRITEDUP);
  913            ssl->dupWrite = NULL;
  914            return MEMORY_E;
  915        }
  916    }
  917#endif
  918#endif
  919
  920    ssl->dupWrite->dupCount = 2;    /* both sides have a count to start */
  921    dup->dupWrite = ssl->dupWrite; /* each side uses */
  922
  923    tmp_weOwnRng = dup->options.weOwnRng;
  924
  925    /* copy write parts over to dup writer */
  926    XMEMCPY(&dup->specs,   &ssl->specs,   sizeof(CipherSpecs));
  927    XMEMCPY(&dup->options, &ssl->options, sizeof(Options));
  928    XMEMCPY(&dup->keys,    &ssl->keys,    sizeof(Keys));
  929    XMEMCPY(&dup->encrypt, &ssl->encrypt, sizeof(Ciphers));
  930    XMEMCPY(&dup->version, &ssl->version, sizeof(ProtocolVersion));
  931    XMEMCPY(&dup->chVersion, &ssl->chVersion, sizeof(ProtocolVersion));
  932
  933    /* dup side now owns encrypt/write ciphers */
  934    XMEMSET(&ssl->encrypt, 0, sizeof(Ciphers));
  935
  936#ifdef HAVE_ONE_TIME_AUTH
  937#ifdef HAVE_POLY1305
  938    if (tmp_poly1305 != NULL) {
  939        dup->auth.poly1305 = tmp_poly1305;
  940        dup->auth.setup = 1;
  941    }
  942#endif
  943#endif
  944
  945#ifdef WOLFSSL_TLS13
  946    if (IsAtLeastTLSv1_3(ssl->version)) {
  947        /* Copy TLS 1.3 application traffic secrets so the write side can
  948         * derive updated keys when wolfSSL_update_keys() is called. */
  949        XMEMCPY(dup->clientSecret, ssl->clientSecret, SECRET_LEN);
  950        XMEMCPY(dup->serverSecret, ssl->serverSecret, SECRET_LEN);
  951
  952#ifdef WOLFSSL_DTLS13
  953        if (ssl->options.dtls) {
  954            /* Copy epoch array (contains only value types -- safe to memcpy). */
  955            XMEMCPY(dup->dtls13Epochs, ssl->dtls13Epochs,
  956                    sizeof(ssl->dtls13Epochs));
  957
  958            /* Re-point dtls13EncryptEpoch into dup's own epoch array. */
  959            if (ssl->dtls13EncryptEpoch != NULL) {
  960                dup->dtls13EncryptEpoch =
  961                    &dup->dtls13Epochs[ssl->dtls13EncryptEpoch -
  962                                       ssl->dtls13Epochs];
  963            }
  964
  965            /* Copy current write epoch number. */
  966            dup->dtls13Epoch = ssl->dtls13Epoch;
  967
  968            /* Transfer record-number encryption cipher ownership to dup. */
  969            XMEMCPY(&dup->dtlsRecordNumberEncrypt,
  970                    &ssl->dtlsRecordNumberEncrypt, sizeof(RecordNumberCiphers));
  971            XMEMSET(&ssl->dtlsRecordNumberEncrypt,
  972                    0, sizeof(RecordNumberCiphers));
  973        }
  974#endif /* WOLFSSL_DTLS13 */
  975    }
  976#endif /* WOLFSSL_TLS13 */
  977
  978
  979    dup->IOCB_WriteCtx = ssl->IOCB_WriteCtx;
  980    dup->CBIOSend = ssl->CBIOSend;
  981#ifdef OPENSSL_EXTRA
  982    dup->cbioFlag = ssl->cbioFlag;
  983#endif
  984    dup->wfd    = ssl->wfd;
  985    dup->wflags = ssl->wflags;
  986#ifndef WOLFSSL_AEAD_ONLY
  987    dup->hmac   = ssl->hmac;
  988#endif
  989#ifdef HAVE_TRUNCATED_HMAC
  990    dup->truncated_hmac = ssl->truncated_hmac;
  991#endif
  992
  993    /* Restore rng option */
  994    dup->options.weOwnRng = tmp_weOwnRng;
  995
  996    /* unique side dup setup */
  997    dup->dupSide = WRITE_DUP_SIDE;
  998    ssl->dupSide = READ_DUP_SIDE;
  999
 1000    return 0;
 1001}
 1002
 1003
 1004/*
 1005 * duplicate a WOLFSSL object post handshake for writing only
 1006 * turn existing object into read only.  Allows concurrent access from two
 1007 * different threads.
 1008 *
 1009 * ssl existing WOLFSSL object
 1010 *
 1011 * return dup'd WOLFSSL object on success
 1012*/
 1013WOLFSSL* wolfSSL_write_dup(WOLFSSL* ssl)
 1014{
 1015    WOLFSSL* dup = NULL;
 1016    int ret = 0;
 1017
 1018    (void)ret;
 1019    WOLFSSL_ENTER("wolfSSL_write_dup");
 1020
 1021    if (ssl == NULL) {
 1022        return ssl;
 1023    }
 1024
 1025    if (ssl->options.handShakeDone == 0) {
 1026        WOLFSSL_MSG("wolfSSL_write_dup called before handshake complete");
 1027        return NULL;
 1028    }
 1029
 1030    if (ssl->dupWrite) {
 1031        WOLFSSL_MSG("wolfSSL_write_dup already called once");
 1032        return NULL;
 1033    }
 1034
 1035    dup = (WOLFSSL*) XMALLOC(sizeof(WOLFSSL), ssl->ctx->heap, DYNAMIC_TYPE_SSL);
 1036    if (dup) {
 1037        if ( (ret = InitSSL(dup, ssl->ctx, 1)) < 0) {
 1038            FreeSSL(dup, ssl->ctx->heap);
 1039            dup = NULL;
 1040        } else if ( (ret = DupSSL(dup, ssl)) < 0) {
 1041            FreeSSL(dup, ssl->ctx->heap);
 1042            dup = NULL;
 1043        }
 1044    }
 1045
 1046    WOLFSSL_LEAVE("wolfSSL_write_dup", ret);
 1047
 1048    return dup;
 1049}
 1050
 1051
 1052/*
 1053 * Notify write dup side of fatal error or close notify
 1054 *
 1055 * ssl WOLFSSL object
 1056 * err Notify err
 1057 *
 1058 * 0 on success
 1059*/
 1060int NotifyWriteSide(WOLFSSL* ssl, int err)
 1061{
 1062    int ret;
 1063
 1064    WOLFSSL_ENTER("NotifyWriteSide");
 1065
 1066    ret = wc_LockMutex(&ssl->dupWrite->dupMutex);
 1067    if (ret == 0) {
 1068        ssl->dupWrite->dupErr = err;
 1069        ret = wc_UnLockMutex(&ssl->dupWrite->dupMutex);
 1070    }
 1071
 1072    return ret;
 1073}
 1074
 1075
 1076#endif /* HAVE_WRITE_DUP */
 1077
 1078
 1079#ifdef HAVE_POLY1305
 1080/* set if to use old poly 1 for yes 0 to use new poly */
 1081int wolfSSL_use_old_poly(WOLFSSL* ssl, int value)
 1082{
 1083    (void)ssl;
 1084    (void)value;
 1085
 1086#ifndef WOLFSSL_NO_TLS12
 1087    WOLFSSL_ENTER("wolfSSL_use_old_poly");
 1088    WOLFSSL_MSG("Warning SSL connection auto detects old/new and this function"
 1089            "is depreciated");
 1090    ssl->options.oldPoly = (word16)value;
 1091    WOLFSSL_LEAVE("wolfSSL_use_old_poly", 0);
 1092#endif
 1093    return 0;
 1094}
 1095#endif
 1096
 1097
 1098WOLFSSL_ABI
 1099int wolfSSL_set_fd(WOLFSSL* ssl, int fd)
 1100{
 1101    int ret;
 1102
 1103    WOLFSSL_ENTER("wolfSSL_set_fd");
 1104
 1105    if (ssl == NULL) {
 1106        return BAD_FUNC_ARG;
 1107    }
 1108
 1109    ret = wolfSSL_set_read_fd(ssl, fd);
 1110    if (ret == WOLFSSL_SUCCESS) {
 1111        ret = wolfSSL_set_write_fd(ssl, fd);
 1112    }
 1113
 1114    return ret;
 1115}
 1116
 1117#ifdef WOLFSSL_DTLS
 1118int wolfSSL_set_dtls_fd_connected(WOLFSSL* ssl, int fd)
 1119{
 1120    int ret;
 1121
 1122    WOLFSSL_ENTER("wolfSSL_set_dtls_fd_connected");
 1123
 1124    if (ssl == NULL) {
 1125        return BAD_FUNC_ARG;
 1126    }
 1127
 1128    ret = wolfSSL_set_fd(ssl, fd);
 1129    if (ret == WOLFSSL_SUCCESS)
 1130        ssl->buffers.dtlsCtx.connected = 1;
 1131
 1132    return ret;
 1133}
 1134#endif
 1135
 1136
 1137int wolfSSL_set_read_fd(WOLFSSL* ssl, int fd)
 1138{
 1139    WOLFSSL_ENTER("wolfSSL_set_read_fd");
 1140
 1141    if (ssl == NULL) {
 1142        return BAD_FUNC_ARG;
 1143    }
 1144
 1145    ssl->rfd = fd;      /* not used directly to allow IO callbacks */
 1146    ssl->IOCB_ReadCtx  = &ssl->rfd;
 1147
 1148    #ifdef WOLFSSL_DTLS
 1149        ssl->buffers.dtlsCtx.connected = 0;
 1150        if (ssl->options.dtls) {
 1151            ssl->IOCB_ReadCtx = &ssl->buffers.dtlsCtx;
 1152            ssl->buffers.dtlsCtx.rfd = fd;
 1153        }
 1154    #endif
 1155
 1156    WOLFSSL_LEAVE("wolfSSL_set_read_fd", WOLFSSL_SUCCESS);
 1157    return WOLFSSL_SUCCESS;
 1158}
 1159
 1160
 1161int wolfSSL_set_write_fd(WOLFSSL* ssl, int fd)
 1162{
 1163    WOLFSSL_ENTER("wolfSSL_set_write_fd");
 1164
 1165    if (ssl == NULL) {
 1166        return BAD_FUNC_ARG;
 1167    }
 1168
 1169    ssl->wfd = fd;      /* not used directly to allow IO callbacks */
 1170    ssl->IOCB_WriteCtx  = &ssl->wfd;
 1171
 1172    #ifdef WOLFSSL_DTLS
 1173        ssl->buffers.dtlsCtx.connected = 0;
 1174        if (ssl->options.dtls) {
 1175            ssl->IOCB_WriteCtx = &ssl->buffers.dtlsCtx;
 1176            ssl->buffers.dtlsCtx.wfd = fd;
 1177        }
 1178    #endif
 1179
 1180    WOLFSSL_LEAVE("wolfSSL_set_write_fd", WOLFSSL_SUCCESS);
 1181    return WOLFSSL_SUCCESS;
 1182}
 1183
 1184
 1185/**
 1186  * Get the name of cipher at priority level passed in.
 1187  */
 1188char* wolfSSL_get_cipher_list(int priority)
 1189{
 1190    const CipherSuiteInfo* ciphers = GetCipherNames();
 1191
 1192    if (priority >= GetCipherNamesSize() || priority < 0) {
 1193        return 0;
 1194    }
 1195
 1196    return (char*)ciphers[priority].name;
 1197}
 1198
 1199
 1200/**
 1201  * Get the name of cipher at priority level passed in.
 1202  */
 1203char* wolfSSL_get_cipher_list_ex(WOLFSSL* ssl, int priority)
 1204{
 1205
 1206    if (ssl == NULL) {
 1207        return NULL;
 1208    }
 1209    else {
 1210        const char* cipher;
 1211
 1212        if ((cipher = wolfSSL_get_cipher_name_internal(ssl)) != NULL) {
 1213            if (priority == 0) {
 1214                return (char*)cipher;
 1215            }
 1216            else {
 1217                return NULL;
 1218            }
 1219        }
 1220        else {
 1221            return wolfSSL_get_cipher_list(priority);
 1222        }
 1223    }
 1224}
 1225
 1226
 1227int wolfSSL_get_ciphers(char* buf, int len)
 1228{
 1229    const CipherSuiteInfo* ciphers = GetCipherNames();
 1230    int ciphersSz = GetCipherNamesSize();
 1231    int i;
 1232
 1233    if (buf == NULL || len <= 0)
 1234        return BAD_FUNC_ARG;
 1235
 1236    /* Add each member to the buffer delimited by a : */
 1237    for (i = 0; i < ciphersSz; i++) {
 1238        int cipherNameSz = (int)XSTRLEN(ciphers[i].name);
 1239        if (cipherNameSz + 1 < len) {
 1240            XSTRNCPY(buf, ciphers[i].name, (size_t)len);
 1241            buf += cipherNameSz;
 1242
 1243            if (i < ciphersSz - 1)
 1244                *buf++ = ':';
 1245            *buf = 0;
 1246
 1247            len -= cipherNameSz + 1;
 1248        }
 1249        else
 1250            return BUFFER_E;
 1251    }
 1252    return WOLFSSL_SUCCESS;
 1253}
 1254
 1255
 1256#ifndef NO_ERROR_STRINGS
 1257/* places a list of all supported cipher suites in TLS_* format into "buf"
 1258 * return WOLFSSL_SUCCESS on success */
 1259int wolfSSL_get_ciphers_iana(char* buf, int len)
 1260{
 1261    const CipherSuiteInfo* ciphers = GetCipherNames();
 1262    int ciphersSz = GetCipherNamesSize();
 1263    int i;
 1264    int cipherNameSz;
 1265
 1266    if (buf == NULL || len <= 0)
 1267        return BAD_FUNC_ARG;
 1268
 1269    /* Add each member to the buffer delimited by a : */
 1270    for (i = 0; i < ciphersSz; i++) {
 1271#ifndef NO_CIPHER_SUITE_ALIASES
 1272        if (ciphers[i].flags & WOLFSSL_CIPHER_SUITE_FLAG_NAMEALIAS)
 1273            continue;
 1274#endif
 1275        cipherNameSz = (int)XSTRLEN(ciphers[i].name_iana);
 1276        if (cipherNameSz + 1 < len) {
 1277            XSTRNCPY(buf, ciphers[i].name_iana, (size_t)len);
 1278            buf += cipherNameSz;
 1279
 1280            if (i < ciphersSz - 1)
 1281                *buf++ = ':';
 1282            *buf = 0;
 1283
 1284            len -= cipherNameSz + 1;
 1285        }
 1286        else
 1287            return BUFFER_E;
 1288    }
 1289    return WOLFSSL_SUCCESS;
 1290}
 1291#endif /* NO_ERROR_STRINGS */
 1292
 1293
 1294const char* wolfSSL_get_shared_ciphers(WOLFSSL* ssl, char* buf, int len)
 1295{
 1296    const char* cipher;
 1297
 1298    if (ssl == NULL || len <= 0)
 1299        return NULL;
 1300
 1301    cipher = wolfSSL_get_cipher_name_iana(ssl);
 1302    len = (int)min((word32)len, (word32)(XSTRLEN(cipher) + 1));
 1303    XMEMCPY(buf, cipher, (size_t)len);
 1304    return buf;
 1305}
 1306
 1307int wolfSSL_get_fd(const WOLFSSL* ssl)
 1308{
 1309    int fd = -1;
 1310    WOLFSSL_ENTER("wolfSSL_get_fd");
 1311    if (ssl) {
 1312        fd = ssl->rfd;
 1313    }
 1314    WOLFSSL_LEAVE("wolfSSL_get_fd", fd);
 1315    return fd;
 1316}
 1317
 1318int wolfSSL_get_wfd(const WOLFSSL* ssl)
 1319{
 1320    int fd = -1;
 1321    WOLFSSL_ENTER("wolfSSL_get_fd");
 1322    if (ssl) {
 1323        fd = ssl->wfd;
 1324    }
 1325    WOLFSSL_LEAVE("wolfSSL_get_fd", fd);
 1326    return fd;
 1327}
 1328
 1329
 1330int wolfSSL_dtls(WOLFSSL* ssl)
 1331{
 1332    int dtlsOpt = 0;
 1333    if (ssl)
 1334        dtlsOpt = ssl->options.dtls;
 1335    return dtlsOpt;
 1336}
 1337
 1338#ifdef WOLFSSL_WOLFSENTRY_HOOKS
 1339
 1340int wolfSSL_CTX_set_AcceptFilter(
 1341    WOLFSSL_CTX *ctx,
 1342    NetworkFilterCallback_t AcceptFilter,
 1343    void *AcceptFilter_arg)
 1344{
 1345    if (ctx == NULL)
 1346        return BAD_FUNC_ARG;
 1347    ctx->AcceptFilter = AcceptFilter;
 1348    ctx->AcceptFilter_arg = AcceptFilter_arg;
 1349    return 0;
 1350}
 1351
 1352int wolfSSL_set_AcceptFilter(
 1353    WOLFSSL *ssl,
 1354    NetworkFilterCallback_t AcceptFilter,
 1355    void *AcceptFilter_arg)
 1356{
 1357    if (ssl == NULL)
 1358        return BAD_FUNC_ARG;
 1359    ssl->AcceptFilter = AcceptFilter;
 1360    ssl->AcceptFilter_arg = AcceptFilter_arg;
 1361    return 0;
 1362}
 1363
 1364int wolfSSL_CTX_set_ConnectFilter(
 1365    WOLFSSL_CTX *ctx,
 1366    NetworkFilterCallback_t ConnectFilter,
 1367    void *ConnectFilter_arg)
 1368{
 1369    if (ctx == NULL)
 1370        return BAD_FUNC_ARG;
 1371    ctx->ConnectFilter = ConnectFilter;
 1372    ctx->ConnectFilter_arg = ConnectFilter_arg;
 1373    return 0;
 1374}
 1375
 1376int wolfSSL_set_ConnectFilter(
 1377    WOLFSSL *ssl,
 1378    NetworkFilterCallback_t ConnectFilter,
 1379    void *ConnectFilter_arg)
 1380{
 1381    if (ssl == NULL)
 1382        return BAD_FUNC_ARG;
 1383    ssl->ConnectFilter = ConnectFilter;
 1384    ssl->ConnectFilter_arg = ConnectFilter_arg;
 1385    return 0;
 1386}
 1387
 1388#endif /* WOLFSSL_WOLFSENTRY_HOOKS */
 1389
 1390#ifndef WOLFSSL_LEANPSK
 1391#if defined(WOLFSSL_DTLS) && defined(XINET_PTON) && \
 1392    !defined(WOLFSSL_NO_SOCK) && defined(HAVE_SOCKADDR)
 1393void* wolfSSL_dtls_create_peer(int port, char* ip)
 1394{
 1395    SOCKADDR_IN *addr;
 1396    addr = (SOCKADDR_IN*)XMALLOC(sizeof(*addr), NULL,
 1397            DYNAMIC_TYPE_SOCKADDR);
 1398    if (addr == NULL) {
 1399        return NULL;
 1400    }
 1401
 1402    addr->sin_family = AF_INET;
 1403    addr->sin_port = XHTONS((word16)port);
 1404    if (XINET_PTON(AF_INET, ip, &addr->sin_addr) < 1) {
 1405        XFREE(addr, NULL, DYNAMIC_TYPE_SOCKADDR);
 1406        return NULL;
 1407    }
 1408
 1409    return addr;
 1410}
 1411
 1412int wolfSSL_dtls_free_peer(void* addr)
 1413{
 1414    XFREE(addr, NULL, DYNAMIC_TYPE_SOCKADDR);
 1415    return WOLFSSL_SUCCESS;
 1416}
 1417#endif
 1418
 1419#ifdef WOLFSSL_DTLS
 1420static int SockAddrSet(WOLFSSL_SOCKADDR* sockAddr, void* peer,
 1421                       unsigned int peerSz, void* heap)
 1422{
 1423    if (peer == NULL || peerSz == 0) {
 1424        if (sockAddr->sa != NULL)
 1425            XFREE(sockAddr->sa, heap, DYNAMIC_TYPE_SOCKADDR);
 1426        sockAddr->sa = NULL;
 1427        sockAddr->sz = 0;
 1428        sockAddr->bufSz = 0;
 1429        return WOLFSSL_SUCCESS;
 1430    }
 1431
 1432    if (peerSz > sockAddr->bufSz) {
 1433        if (sockAddr->sa != NULL)
 1434            XFREE(sockAddr->sa, heap, DYNAMIC_TYPE_SOCKADDR);
 1435        sockAddr->sa =
 1436                (void*)XMALLOC(peerSz, heap, DYNAMIC_TYPE_SOCKADDR);
 1437        if (sockAddr->sa == NULL) {
 1438            sockAddr->sz = 0;
 1439            sockAddr->bufSz = 0;
 1440            return WOLFSSL_FAILURE;
 1441        }
 1442        sockAddr->bufSz = peerSz;
 1443    }
 1444    XMEMCPY(sockAddr->sa, peer, peerSz);
 1445    sockAddr->sz = peerSz;
 1446    return WOLFSSL_SUCCESS;
 1447}
 1448#endif
 1449
 1450int wolfSSL_dtls_set_peer(WOLFSSL* ssl, void* peer, unsigned int peerSz)
 1451{
 1452#ifdef WOLFSSL_DTLS
 1453    int ret;
 1454
 1455    if (ssl == NULL)
 1456        return WOLFSSL_FAILURE;
 1457#ifdef WOLFSSL_RW_THREADED
 1458    if (wc_LockRwLock_Wr(&ssl->buffers.dtlsCtx.peerLock) != 0)
 1459        return WOLFSSL_FAILURE;
 1460#endif
 1461    ret = SockAddrSet(&ssl->buffers.dtlsCtx.peer, peer, peerSz, ssl->heap);
 1462    if (ret == WOLFSSL_SUCCESS && !(peer == NULL || peerSz == 0))
 1463        ssl->buffers.dtlsCtx.userSet = 1;
 1464    else
 1465        ssl->buffers.dtlsCtx.userSet = 0;
 1466#ifdef WOLFSSL_RW_THREADED
 1467    if (wc_UnLockRwLock(&ssl->buffers.dtlsCtx.peerLock) != 0)
 1468        ret = WOLFSSL_FAILURE;
 1469#endif
 1470    return ret;
 1471#else
 1472    (void)ssl;
 1473    (void)peer;
 1474    (void)peerSz;
 1475    return WOLFSSL_NOT_IMPLEMENTED;
 1476#endif
 1477}
 1478
 1479#if defined(WOLFSSL_DTLS_CID) && !defined(WOLFSSL_NO_SOCK)
 1480int wolfSSL_dtls_set_pending_peer(WOLFSSL* ssl, void* peer, unsigned int peerSz)
 1481{
 1482#ifdef WOLFSSL_DTLS
 1483    int ret = WC_NO_ERR_TRACE(WOLFSSL_FAILURE);
 1484
 1485    if (ssl == NULL)
 1486        return WOLFSSL_FAILURE;
 1487#ifdef WOLFSSL_RW_THREADED
 1488    if (wc_LockRwLock_Rd(&ssl->buffers.dtlsCtx.peerLock) != 0)
 1489        return WOLFSSL_FAILURE;
 1490#endif
 1491    if (ssl->buffers.dtlsCtx.peer.sa != NULL &&
 1492            ssl->buffers.dtlsCtx.peer.sz == peerSz &&
 1493            sockAddrEqual((SOCKADDR_S*)ssl->buffers.dtlsCtx.peer.sa,
 1494                    (XSOCKLENT)ssl->buffers.dtlsCtx.peer.sz, (SOCKADDR_S*)peer,
 1495                    (XSOCKLENT)peerSz)) {
 1496        /* Already the current peer. */
 1497        if (ssl->buffers.dtlsCtx.pendingPeer.sa != NULL) {
 1498            /* Clear any other pendingPeer */
 1499            XFREE(ssl->buffers.dtlsCtx.pendingPeer.sa, ssl->heap,
 1500                  DYNAMIC_TYPE_SOCKADDR);
 1501            ssl->buffers.dtlsCtx.pendingPeer.sa = NULL;
 1502            ssl->buffers.dtlsCtx.pendingPeer.sz = 0;
 1503            ssl->buffers.dtlsCtx.pendingPeer.bufSz = 0;
 1504        }
 1505        ret = WOLFSSL_SUCCESS;
 1506    }
 1507    else {
 1508        ret = SockAddrSet(&ssl->buffers.dtlsCtx.pendingPeer, peer, peerSz,
 1509                ssl->heap);
 1510    }
 1511    if (ret == WOLFSSL_SUCCESS)
 1512        ssl->buffers.dtlsCtx.processingPendingRecord = 0;
 1513#ifdef WOLFSSL_RW_THREADED
 1514    if (wc_UnLockRwLock(&ssl->buffers.dtlsCtx.peerLock) != 0)
 1515        ret = WOLFSSL_FAILURE;
 1516#endif
 1517    return ret;
 1518#else
 1519    (void)ssl;
 1520    (void)peer;
 1521    (void)peerSz;
 1522    return WOLFSSL_NOT_IMPLEMENTED;
 1523#endif
 1524}
 1525#endif /* WOLFSSL_DTLS_CID && !WOLFSSL_NO_SOCK */
 1526
 1527int wolfSSL_dtls_get_peer(WOLFSSL* ssl, void* peer, unsigned int* peerSz)
 1528{
 1529#ifdef WOLFSSL_DTLS
 1530    int ret = WC_NO_ERR_TRACE(WOLFSSL_FAILURE);
 1531    if (ssl == NULL)
 1532        return WOLFSSL_FAILURE;
 1533#ifdef WOLFSSL_RW_THREADED
 1534    if (wc_LockRwLock_Rd(&ssl->buffers.dtlsCtx.peerLock) != 0)
 1535        return WOLFSSL_FAILURE;
 1536#endif
 1537    if (peer != NULL && peerSz != NULL
 1538            && *peerSz >= ssl->buffers.dtlsCtx.peer.sz
 1539            && ssl->buffers.dtlsCtx.peer.sa != NULL) {
 1540        *peerSz = ssl->buffers.dtlsCtx.peer.sz;
 1541        XMEMCPY(peer, ssl->buffers.dtlsCtx.peer.sa, *peerSz);
 1542        ret = WOLFSSL_SUCCESS;
 1543    }
 1544#ifdef WOLFSSL_RW_THREADED
 1545    if (wc_UnLockRwLock(&ssl->buffers.dtlsCtx.peerLock) != 0)
 1546        ret = WOLFSSL_FAILURE;
 1547#endif
 1548    return ret;
 1549#else
 1550    (void)ssl;
 1551    (void)peer;
 1552    (void)peerSz;
 1553    return WOLFSSL_NOT_IMPLEMENTED;
 1554#endif
 1555}
 1556
 1557int wolfSSL_dtls_get0_peer(WOLFSSL* ssl, const void** peer,
 1558                           unsigned int* peerSz)
 1559{
 1560#if defined(WOLFSSL_DTLS) && !defined(WOLFSSL_RW_THREADED)
 1561    if (ssl == NULL)
 1562        return WOLFSSL_FAILURE;
 1563
 1564    if (peer == NULL || peerSz == NULL)
 1565        return WOLFSSL_FAILURE;
 1566
 1567    *peer = ssl->buffers.dtlsCtx.peer.sa;
 1568    *peerSz = ssl->buffers.dtlsCtx.peer.sz;
 1569    return WOLFSSL_SUCCESS;
 1570#else
 1571    (void)ssl;
 1572    (void)peer;
 1573    (void)peerSz;
 1574    return WOLFSSL_NOT_IMPLEMENTED;
 1575#endif
 1576}
 1577
 1578
 1579#if defined(WOLFSSL_SCTP) && defined(WOLFSSL_DTLS)
 1580
 1581int wolfSSL_CTX_dtls_set_sctp(WOLFSSL_CTX* ctx)
 1582{
 1583    WOLFSSL_ENTER("wolfSSL_CTX_dtls_set_sctp");
 1584
 1585    if (ctx == NULL)
 1586        return BAD_FUNC_ARG;
 1587
 1588    ctx->dtlsSctp = 1;
 1589    return WOLFSSL_SUCCESS;
 1590}
 1591
 1592
 1593int wolfSSL_dtls_set_sctp(WOLFSSL* ssl)
 1594{
 1595    WOLFSSL_ENTER("wolfSSL_dtls_set_sctp");
 1596
 1597    if (ssl == NULL)
 1598        return BAD_FUNC_ARG;
 1599
 1600    ssl->options.dtlsSctp = 1;
 1601    return WOLFSSL_SUCCESS;
 1602}
 1603
 1604#endif /* WOLFSSL_DTLS && WOLFSSL_SCTP */
 1605
 1606#if (defined(WOLFSSL_SCTP) || defined(WOLFSSL_DTLS_MTU)) && \
 1607                                                           defined(WOLFSSL_DTLS)
 1608
 1609int wolfSSL_CTX_dtls_set_mtu(WOLFSSL_CTX* ctx, word16 newMtu)
 1610{
 1611    if (ctx == NULL || newMtu > MAX_RECORD_SIZE)
 1612        return BAD_FUNC_ARG;
 1613
 1614    ctx->dtlsMtuSz = newMtu;
 1615    return WOLFSSL_SUCCESS;
 1616}
 1617
 1618
 1619int wolfSSL_dtls_set_mtu(WOLFSSL* ssl, word16 newMtu)
 1620{
 1621    if (ssl == NULL)
 1622        return BAD_FUNC_ARG;
 1623
 1624    if (newMtu > MAX_RECORD_SIZE) {
 1625        ssl->error = BAD_FUNC_ARG;
 1626        return WOLFSSL_FAILURE;
 1627    }
 1628
 1629    ssl->dtlsMtuSz = newMtu;
 1630    return WOLFSSL_SUCCESS;
 1631}
 1632
 1633#ifdef OPENSSL_EXTRA
 1634/* Maps to compatibility API SSL_set_mtu and is same as wolfSSL_dtls_set_mtu,
 1635 * but expects only success or failure returns. */
 1636int wolfSSL_set_mtu_compat(WOLFSSL* ssl, unsigned short mtu)
 1637{
 1638    if (wolfSSL_dtls_set_mtu(ssl, mtu) == WOLFSSL_SUCCESS)
 1639        return WOLFSSL_SUCCESS;
 1640    else
 1641        return WOLFSSL_FAILURE;
 1642}
 1643#endif /* OPENSSL_EXTRA */
 1644
 1645#endif /* WOLFSSL_DTLS && (WOLFSSL_SCTP || WOLFSSL_DTLS_MTU) */
 1646
 1647#ifdef WOLFSSL_SRTP
 1648
 1649static const WOLFSSL_SRTP_PROTECTION_PROFILE gSrtpProfiles[] = {
 1650    /* AES CCM 128, Salt:112-bits, Auth HMAC-SHA1 Tag: 80-bits
 1651     * (master_key:128bits + master_salt:112bits) * 2 = 480 bits (60) */
 1652    {"SRTP_AES128_CM_SHA1_80", SRTP_AES128_CM_SHA1_80,
 1653     (((128 + 112) * 2) / 8) },
 1654    /* AES CCM 128, Salt:112-bits, Auth HMAC-SHA1 Tag: 32-bits
 1655     * (master_key:128bits + master_salt:112bits) * 2 = 480 bits (60) */
 1656    {"SRTP_AES128_CM_SHA1_32", SRTP_AES128_CM_SHA1_32,
 1657     (((128 + 112) * 2) / 8) },
 1658    /* NULL Cipher, Salt:112-bits, Auth HMAC-SHA1 Tag 80-bits */
 1659    {"SRTP_NULL_SHA1_80", SRTP_NULL_SHA1_80, ((112 * 2) / 8)},
 1660    /* NULL Cipher, Salt:112-bits, Auth HMAC-SHA1 Tag 32-bits */
 1661    {"SRTP_NULL_SHA1_32", SRTP_NULL_SHA1_32, ((112 * 2) / 8)},
 1662    /* AES GCM 128, Salt: 96-bits, Auth GCM Tag 128-bits
 1663     * (master_key:128bits + master_salt:96bits) * 2 = 448 bits (56) */
 1664    {"SRTP_AEAD_AES_128_GCM", SRTP_AEAD_AES_128_GCM, (((128 + 96) * 2) / 8) },
 1665    /* AES GCM 256, Salt: 96-bits, Auth GCM Tag 128-bits
 1666     * (master_key:256bits + master_salt:96bits) * 2 = 704 bits (88) */
 1667    {"SRTP_AEAD_AES_256_GCM", SRTP_AEAD_AES_256_GCM, (((256 + 96) * 2) / 8) },
 1668};
 1669
 1670static const WOLFSSL_SRTP_PROTECTION_PROFILE* DtlsSrtpFindProfile(
 1671    const char* profile_str, word32 profile_str_len, unsigned long id)
 1672{
 1673    int i;
 1674    const WOLFSSL_SRTP_PROTECTION_PROFILE* profile = NULL;
 1675    for (i=0;
 1676         i<(int)(sizeof(gSrtpProfiles)/sizeof(WOLFSSL_SRTP_PROTECTION_PROFILE));
 1677         i++) {
 1678        if (profile_str != NULL) {
 1679            word32 srtp_profile_len = (word32)XSTRLEN(gSrtpProfiles[i].name);
 1680            if (srtp_profile_len == profile_str_len &&
 1681                XMEMCMP(gSrtpProfiles[i].name, profile_str, profile_str_len)
 1682                                                                         == 0) {
 1683                profile = &gSrtpProfiles[i];
 1684                break;
 1685            }
 1686        }
 1687        else if (id != 0 && gSrtpProfiles[i].id == id) {
 1688            profile = &gSrtpProfiles[i];
 1689            break;
 1690        }
 1691    }
 1692    return profile;
 1693}
 1694
 1695/* profile_str: accepts ":" colon separated list of SRTP profiles */
 1696static int DtlsSrtpSelProfiles(word16* id, const char* profile_str)
 1697{
 1698    const WOLFSSL_SRTP_PROTECTION_PROFILE* profile;
 1699    const char *current, *next = NULL;
 1700    word32 length = 0, current_length;
 1701
 1702    *id = 0; /* reset destination ID's */
 1703
 1704    if (profile_str == NULL) {
 1705        return WOLFSSL_FAILURE;
 1706    }
 1707
 1708    /* loop on end of line or colon ":" */
 1709    next = profile_str;
 1710    length = (word32)XSTRLEN(profile_str);
 1711    do {
 1712        current = next;
 1713        next = XSTRSTR(current, ":");
 1714        if (next) {
 1715            current_length = (word32)(next - current);
 1716            ++next; /* ++ needed to skip ':' */
 1717        } else {
 1718            current_length = (word32)XSTRLEN(current);
 1719        }
 1720        if (current_length < length)
 1721            length = current_length;
 1722        profile = DtlsSrtpFindProfile(current, current_length, 0);
 1723        if (profile != NULL) {
 1724            *id |= (1 << profile->id); /* selected bit based on ID */
 1725        }
 1726    } while (next != NULL);
 1727    return WOLFSSL_SUCCESS;
 1728}
 1729
 1730/**
 1731 * @brief Set the SRTP protection profiles for DTLS.
 1732 *
 1733 * @param ctx Pointer to the WOLFSSL_CTX structure representing the SSL/TLS
 1734 *            context.
 1735 * @param profile_str A colon-separated string of SRTP profile names.
 1736 * @return 0 on success to match OpenSSL
 1737 * @return 1 on error to match OpenSSL
 1738 */
 1739int wolfSSL_CTX_set_tlsext_use_srtp(WOLFSSL_CTX* ctx, const char* profile_str)
 1740{
 1741    int ret = WC_NO_ERR_TRACE(WOLFSSL_FAILURE);
 1742    if (ctx != NULL) {
 1743        ret = DtlsSrtpSelProfiles(&ctx->dtlsSrtpProfiles, profile_str);
 1744    }
 1745
 1746    if (ret == WC_NO_ERR_TRACE(WOLFSSL_FAILURE)) {
 1747        ret = 1;
 1748    } else {
 1749        ret = 0;
 1750    }
 1751
 1752    return ret;
 1753}
 1754
 1755/**
 1756 * @brief Set the SRTP protection profiles for DTLS.
 1757 *
 1758 * @param ssl Pointer to the WOLFSSL structure representing the SSL/TLS
 1759 *            session.
 1760 * @param profile_str A colon-separated string of SRTP profile names.
 1761 * @return 0 on success to match OpenSSL
 1762 * @return 1 on error to match OpenSSL
 1763 */
 1764int wolfSSL_set_tlsext_use_srtp(WOLFSSL* ssl, const char* profile_str)
 1765{
 1766    int ret = WC_NO_ERR_TRACE(WOLFSSL_FAILURE);
 1767    if (ssl != NULL) {
 1768        ret = DtlsSrtpSelProfiles(&ssl->dtlsSrtpProfiles, profile_str);
 1769    }
 1770
 1771    if (ret == WC_NO_ERR_TRACE(WOLFSSL_FAILURE)) {
 1772        ret = 1;
 1773    } else {
 1774        ret = 0;
 1775    }
 1776
 1777    return ret;
 1778}
 1779
 1780const WOLFSSL_SRTP_PROTECTION_PROFILE* wolfSSL_get_selected_srtp_profile(
 1781    WOLFSSL* ssl)
 1782{
 1783    const WOLFSSL_SRTP_PROTECTION_PROFILE* profile = NULL;
 1784    if (ssl) {
 1785        profile = DtlsSrtpFindProfile(NULL, 0, ssl->dtlsSrtpId);
 1786    }
 1787    return profile;
 1788}
 1789#ifndef NO_WOLFSSL_STUB
 1790WOLF_STACK_OF(WOLFSSL_SRTP_PROTECTION_PROFILE)* wolfSSL_get_srtp_profiles(
 1791    WOLFSSL* ssl)
 1792{
 1793    /* Not yet implemented - should return list of available SRTP profiles
 1794     * ssl->dtlsSrtpProfiles */
 1795    (void)ssl;
 1796    return NULL;
 1797}
 1798#endif
 1799
 1800#define DTLS_SRTP_KEYING_MATERIAL_LABEL "EXTRACTOR-dtls_srtp"
 1801
 1802int wolfSSL_export_dtls_srtp_keying_material(WOLFSSL* ssl,
 1803    unsigned char* out, size_t* olen)
 1804{
 1805    const WOLFSSL_SRTP_PROTECTION_PROFILE* profile = NULL;
 1806
 1807    if (ssl == NULL || olen == NULL) {
 1808        return BAD_FUNC_ARG;
 1809    }
 1810
 1811    profile = DtlsSrtpFindProfile(NULL, 0, ssl->dtlsSrtpId);
 1812    if (profile == NULL) {
 1813        WOLFSSL_MSG("Not using DTLS SRTP");
 1814        return EXT_MISSING;
 1815    }
 1816    if (out == NULL) {
 1817        *olen = (size_t)profile->kdfBits;
 1818        return WC_NO_ERR_TRACE(LENGTH_ONLY_E);
 1819    }
 1820
 1821    if (*olen < (size_t)profile->kdfBits) {
 1822        return BUFFER_E;
 1823    }
 1824
 1825    return wolfSSL_export_keying_material(ssl, out, (size_t)profile->kdfBits,
 1826            DTLS_SRTP_KEYING_MATERIAL_LABEL,
 1827            XSTR_SIZEOF(DTLS_SRTP_KEYING_MATERIAL_LABEL), NULL, 0, 0);
 1828}
 1829
 1830#endif /* WOLFSSL_SRTP */
 1831
 1832
 1833#ifdef WOLFSSL_DTLS_DROP_STATS
 1834
 1835int wolfSSL_dtls_get_drop_stats(WOLFSSL* ssl,
 1836                                word32* macDropCount, word32* replayDropCount)
 1837{
 1838    int ret;
 1839
 1840    WOLFSSL_ENTER("wolfSSL_dtls_get_drop_stats");
 1841
 1842    if (ssl == NULL)
 1843        ret = BAD_FUNC_ARG;
 1844    else {
 1845        ret = WOLFSSL_SUCCESS;
 1846        if (macDropCount != NULL)
 1847            *macDropCount = ssl->macDropCount;
 1848        if (replayDropCount != NULL)
 1849            *replayDropCount = ssl->replayDropCount;
 1850    }
 1851
 1852    WOLFSSL_LEAVE("wolfSSL_dtls_get_drop_stats", ret);
 1853    return ret;
 1854}
 1855
 1856#endif /* WOLFSSL_DTLS_DROP_STATS */
 1857
 1858
 1859#if defined(WOLFSSL_MULTICAST)
 1860
 1861int wolfSSL_CTX_mcast_set_member_id(WOLFSSL_CTX* ctx, word16 id)
 1862{
 1863    int ret = 0;
 1864
 1865    WOLFSSL_ENTER("wolfSSL_CTX_mcast_set_member_id");
 1866
 1867    if (ctx == NULL || id > WOLFSSL_MAX_8BIT)
 1868        ret = BAD_FUNC_ARG;
 1869
 1870    if (ret == 0) {
 1871        ctx->haveEMS = 0;
 1872        ctx->haveMcast = 1;
 1873        ctx->mcastID = (byte)id;
 1874#ifndef WOLFSSL_USER_IO
 1875        ctx->CBIORecv = EmbedReceiveFromMcast;
 1876#endif /* WOLFSSL_USER_IO */
 1877
 1878        ret = WOLFSSL_SUCCESS;
 1879    }
 1880    WOLFSSL_LEAVE("wolfSSL_CTX_mcast_set_member_id", ret);
 1881    return ret;
 1882}
 1883
 1884int wolfSSL_mcast_get_max_peers(void)
 1885{
 1886    return WOLFSSL_MULTICAST_PEERS;
 1887}
 1888
 1889#ifdef WOLFSSL_DTLS
 1890static WC_INLINE word32 UpdateHighwaterMark(word32 cur, word32 first,
 1891                                         word32 second, word32 high)
 1892{
 1893    word32 newCur = 0;
 1894
 1895    if (cur < first)
 1896        newCur = first;
 1897    else if (cur < second)
 1898        newCur = second;
 1899    else if (cur < high)
 1900        newCur = high;
 1901
 1902    return newCur;
 1903}
 1904#endif /* WOLFSSL_DTLS */
 1905
 1906
 1907int wolfSSL_set_secret(WOLFSSL* ssl, word16 epoch,
 1908                       const byte* preMasterSecret, word32 preMasterSz,
 1909                       const byte* clientRandom, const byte* serverRandom,
 1910                       const byte* suite)
 1911{
 1912    int ret = 0;
 1913
 1914    WOLFSSL_ENTER("wolfSSL_set_secret");
 1915
 1916    if (ssl == NULL || preMasterSecret == NULL ||
 1917        preMasterSz == 0 || preMasterSz > ENCRYPT_LEN ||
 1918        clientRandom == NULL || serverRandom == NULL || suite == NULL) {
 1919
 1920        ret = BAD_FUNC_ARG;
 1921    }
 1922
 1923    if (ret == 0 && ssl->arrays->preMasterSecret == NULL) {
 1924        ssl->arrays->preMasterSz = ENCRYPT_LEN;
 1925        ssl->arrays->preMasterSecret = (byte*)XMALLOC(ENCRYPT_LEN, ssl->heap,
 1926            DYNAMIC_TYPE_SECRET);
 1927        if (ssl->arrays->preMasterSecret == NULL) {
 1928            ret = MEMORY_E;
 1929        }
 1930    }
 1931
 1932    if (ret == 0) {
 1933        XMEMCPY(ssl->arrays->preMasterSecret, preMasterSecret, preMasterSz);
 1934        XMEMSET(ssl->arrays->preMasterSecret + preMasterSz, 0,
 1935            ENCRYPT_LEN - preMasterSz);
 1936        ssl->arrays->preMasterSz = preMasterSz;
 1937        XMEMCPY(ssl->arrays->clientRandom, clientRandom, RAN_LEN);
 1938        XMEMCPY(ssl->arrays->serverRandom, serverRandom, RAN_LEN);
 1939        ssl->options.cipherSuite0 = suite[0];
 1940        ssl->options.cipherSuite = suite[1];
 1941
 1942        ret = SetCipherSpecs(ssl);
 1943    }
 1944
 1945    if (ret == 0)
 1946        ret = MakeTlsMasterSecret(ssl);
 1947
 1948    if (ret == 0) {
 1949        ssl->keys.encryptionOn = 1;
 1950        ret = SetKeysSide(ssl, ENCRYPT_AND_DECRYPT_SIDE);
 1951    }
 1952
 1953    if (ret == 0) {
 1954        if (ssl->options.dtls) {
 1955        #ifdef WOLFSSL_DTLS
 1956            WOLFSSL_DTLS_PEERSEQ* peerSeq;
 1957            int i;
 1958
 1959            ssl->keys.dtls_epoch = epoch;
 1960            for (i = 0, peerSeq = ssl->keys.peerSeq;
 1961                 i < WOLFSSL_DTLS_PEERSEQ_SZ;
 1962                 i++, peerSeq++) {
 1963
 1964                peerSeq->nextEpoch = epoch;
 1965                peerSeq->prevSeq_lo = peerSeq->nextSeq_lo;
 1966                peerSeq->prevSeq_hi = peerSeq->nextSeq_hi;
 1967                peerSeq->nextSeq_lo = 0;
 1968                peerSeq->nextSeq_hi = 0;
 1969                XMEMCPY(peerSeq->prevWindow, peerSeq->window, DTLS_SEQ_SZ);
 1970                XMEMSET(peerSeq->window, 0, DTLS_SEQ_SZ);
 1971                peerSeq->highwaterMark = UpdateHighwaterMark(0,
 1972                        ssl->ctx->mcastFirstSeq,
 1973                        ssl->ctx->mcastSecondSeq,
 1974                        ssl->ctx->mcastMaxSeq);
 1975            }
 1976        #else
 1977            (void)epoch;
 1978        #endif
 1979        }
 1980        FreeHandshakeResources(ssl);
 1981        ret = WOLFSSL_SUCCESS;
 1982    }
 1983    else {
 1984        if (ssl)
 1985            ssl->error = ret;
 1986        ret = WOLFSSL_FATAL_ERROR;
 1987    }
 1988    WOLFSSL_LEAVE("wolfSSL_set_secret", ret);
 1989    return ret;
 1990}
 1991
 1992
 1993#ifdef WOLFSSL_DTLS
 1994
 1995int wolfSSL_mcast_peer_add(WOLFSSL* ssl, word16 peerId, int sub)
 1996{
 1997    WOLFSSL_DTLS_PEERSEQ* p = NULL;
 1998    int ret = WOLFSSL_SUCCESS;
 1999    int i;
 2000
 2001    WOLFSSL_ENTER("wolfSSL_mcast_peer_add");
 2002    if (ssl == NULL || peerId > WOLFSSL_MAX_8BIT)
 2003        return BAD_FUNC_ARG;
 2004
 2005    if (!sub) {
 2006        /* Make sure it isn't already present, while keeping the first
 2007         * open spot. */
 2008        for (i = 0; i < WOLFSSL_DTLS_PEERSEQ_SZ; i++) {
 2009            if (ssl->keys.peerSeq[i].peerId == INVALID_PEER_ID)
 2010                p = &ssl->keys.peerSeq[i];
 2011            if (ssl->keys.peerSeq[i].peerId == peerId) {
 2012                WOLFSSL_MSG("Peer ID already in multicast peer list.");
 2013                p = NULL;
 2014            }
 2015        }
 2016
 2017        if (p != NULL) {
 2018            XMEMSET(p, 0, sizeof(WOLFSSL_DTLS_PEERSEQ));
 2019            p->peerId = peerId;
 2020            p->highwaterMark = UpdateHighwaterMark(0,
 2021                ssl->ctx->mcastFirstSeq,
 2022                ssl->ctx->mcastSecondSeq,
 2023                ssl->ctx->mcastMaxSeq);
 2024        }
 2025        else {
 2026            WOLFSSL_MSG("No room in peer list.");
 2027            ret = WOLFSSL_FATAL_ERROR;
 2028        }
 2029    }
 2030    else {
 2031        for (i = 0; i < WOLFSSL_DTLS_PEERSEQ_SZ; i++) {
 2032            if (ssl->keys.peerSeq[i].peerId == peerId)
 2033                p = &ssl->keys.peerSeq[i];
 2034        }
 2035
 2036        if (p != NULL) {
 2037            p->peerId = INVALID_PEER_ID;
 2038        }
 2039        else {
 2040            WOLFSSL_MSG("Peer not found in list.");
 2041        }
 2042    }
 2043
 2044    WOLFSSL_LEAVE("wolfSSL_mcast_peer_add", ret);
 2045    return ret;
 2046}
 2047
 2048
 2049/* If peerId is in the list of peers and its last sequence number is non-zero,
 2050 * return 1, otherwise return 0. */
 2051int wolfSSL_mcast_peer_known(WOLFSSL* ssl, unsigned short peerId)
 2052{
 2053    int known = 0;
 2054    int i;
 2055
 2056    WOLFSSL_ENTER("wolfSSL_mcast_peer_known");
 2057
 2058    if (ssl == NULL || peerId > WOLFSSL_MAX_8BIT) {
 2059        return BAD_FUNC_ARG;
 2060    }
 2061
 2062    for (i = 0; i < WOLFSSL_DTLS_PEERSEQ_SZ; i++) {
 2063        if (ssl->keys.peerSeq[i].peerId == peerId) {
 2064            if (ssl->keys.peerSeq[i].nextSeq_hi ||
 2065                ssl->keys.peerSeq[i].nextSeq_lo) {
 2066
 2067                known = 1;
 2068            }
 2069            break;
 2070        }
 2071    }
 2072
 2073    WOLFSSL_LEAVE("wolfSSL_mcast_peer_known", known);
 2074    return known;
 2075}
 2076
 2077
 2078int wolfSSL_CTX_mcast_set_highwater_cb(WOLFSSL_CTX* ctx, word32 maxSeq,
 2079                                       word32 first, word32 second,
 2080                                       CallbackMcastHighwater cb)
 2081{
 2082    if (ctx == NULL || (second && first > second) ||
 2083        first > maxSeq || second > maxSeq || cb == NULL) {
 2084
 2085        return BAD_FUNC_ARG;
 2086    }
 2087
 2088    ctx->mcastHwCb = cb;
 2089    ctx->mcastFirstSeq = first;
 2090    ctx->mcastSecondSeq = second;
 2091    ctx->mcastMaxSeq = maxSeq;
 2092
 2093    return WOLFSSL_SUCCESS;
 2094}
 2095
 2096
 2097int wolfSSL_mcast_set_highwater_ctx(WOLFSSL* ssl, void* ctx)
 2098{
 2099    if (ssl == NULL || ctx == NULL)
 2100        return BAD_FUNC_ARG;
 2101
 2102    ssl->mcastHwCbCtx = ctx;
 2103
 2104    return WOLFSSL_SUCCESS;
 2105}
 2106
 2107#endif /* WOLFSSL_DTLS */
 2108
 2109#endif /* WOLFSSL_MULTICAST */
 2110
 2111
 2112#endif /* WOLFSSL_LEANPSK */
 2113
 2114#ifndef NO_TLS
 2115/* return underlying connect or accept, WOLFSSL_SUCCESS on ok */
 2116int wolfSSL_negotiate(WOLFSSL* ssl)
 2117{
 2118    int err = WC_NO_ERR_TRACE(WOLFSSL_FATAL_ERROR);
 2119
 2120    WOLFSSL_ENTER("wolfSSL_negotiate");
 2121
 2122    if (ssl == NULL)
 2123        return WOLFSSL_FATAL_ERROR;
 2124
 2125#ifndef NO_WOLFSSL_SERVER
 2126    if (ssl->options.side == WOLFSSL_SERVER_END) {
 2127#ifdef WOLFSSL_TLS13
 2128        if (IsAtLeastTLSv1_3(ssl->version))
 2129            err = wolfSSL_accept_TLSv13(ssl);
 2130        else
 2131#endif
 2132            err = wolfSSL_accept(ssl);
 2133    }
 2134#endif
 2135
 2136#ifndef NO_WOLFSSL_CLIENT
 2137    if (ssl->options.side == WOLFSSL_CLIENT_END) {
 2138#ifdef WOLFSSL_TLS13
 2139        if (IsAtLeastTLSv1_3(ssl->version))
 2140            err = wolfSSL_connect_TLSv13(ssl);
 2141        else
 2142#endif
 2143            err = wolfSSL_connect(ssl);
 2144    }
 2145#endif
 2146
 2147    (void)ssl;
 2148
 2149    WOLFSSL_LEAVE("wolfSSL_negotiate", err);
 2150
 2151    return err;
 2152}
 2153#endif /* !NO_TLS */
 2154
 2155WOLFSSL_ABI
 2156WC_RNG* wolfSSL_GetRNG(WOLFSSL* ssl)
 2157{
 2158    if (ssl) {
 2159        return ssl->rng;
 2160    }
 2161
 2162    return NULL;
 2163}
 2164
 2165
 2166#ifndef WOLFSSL_LEANPSK
 2167/* object size based on build */
 2168int wolfSSL_GetObjectSize(void)
 2169{
 2170#ifdef SHOW_SIZES
 2171    printf("sizeof suites           = %lu\n", (unsigned long)sizeof(Suites));
 2172    printf("sizeof ciphers(2)       = %lu\n", (unsigned long)sizeof(Ciphers));
 2173#ifndef NO_RC4
 2174    printf("\tsizeof arc4         = %lu\n", (unsigned long)sizeof(Arc4));
 2175#endif
 2176    printf("\tsizeof aes          = %lu\n", (unsigned long)sizeof(Aes));
 2177#ifndef NO_DES3
 2178    printf("\tsizeof des3         = %lu\n", (unsigned long)sizeof(Des3));
 2179#endif
 2180#ifdef HAVE_CHACHA
 2181    printf("\tsizeof chacha       = %lu\n", (unsigned long)sizeof(ChaCha));
 2182#endif
 2183#ifdef WOLFSSL_SM4
 2184    printf("\tsizeof sm4          = %lu\n", (unsigned long)sizeof(Sm4));
 2185#endif
 2186    printf("sizeof cipher specs     = %lu\n", (unsigned long)
 2187        sizeof(CipherSpecs));
 2188    printf("sizeof keys             = %lu\n", (unsigned long)sizeof(Keys));
 2189    printf("sizeof Hashes(2)        = %lu\n", (unsigned long)sizeof(Hashes));
 2190#ifndef NO_MD5
 2191    printf("\tsizeof MD5          = %lu\n", (unsigned long)sizeof(wc_Md5));
 2192#endif
 2193#ifndef NO_SHA
 2194    printf("\tsizeof SHA          = %lu\n", (unsigned long)sizeof(wc_Sha));
 2195#endif
 2196#ifdef WOLFSSL_SHA224
 2197    printf("\tsizeof SHA224       = %lu\n", (unsigned long)sizeof(wc_Sha224));
 2198#endif
 2199#ifndef NO_SHA256
 2200    printf("\tsizeof SHA256       = %lu\n", (unsigned long)sizeof(wc_Sha256));
 2201#endif
 2202#ifdef WOLFSSL_SHA384
 2203    printf("\tsizeof SHA384       = %lu\n", (unsigned long)sizeof(wc_Sha384));
 2204#endif
 2205#ifdef WOLFSSL_SHA384
 2206    printf("\tsizeof SHA512       = %lu\n", (unsigned long)sizeof(wc_Sha512));
 2207#endif
 2208#ifdef WOLFSSL_SM3
 2209    printf("\tsizeof sm3          = %lu\n", (unsigned long)sizeof(Sm3));
 2210#endif
 2211    printf("sizeof Buffers          = %lu\n", (unsigned long)sizeof(Buffers));
 2212    printf("sizeof Options          = %lu\n", (unsigned long)sizeof(Options));
 2213    printf("sizeof Arrays           = %lu\n", (unsigned long)sizeof(Arrays));
 2214#ifndef NO_RSA
 2215    printf("sizeof RsaKey           = %lu\n", (unsigned long)sizeof(RsaKey));
 2216#endif
 2217#ifdef HAVE_ECC
 2218    printf("sizeof ecc_key          = %lu\n", (unsigned long)sizeof(ecc_key));
 2219#endif
 2220    printf("sizeof WOLFSSL_CIPHER    = %lu\n", (unsigned long)
 2221        sizeof(WOLFSSL_CIPHER));
 2222    printf("sizeof WOLFSSL_SESSION   = %lu\n", (unsigned long)
 2223        sizeof(WOLFSSL_SESSION));
 2224    printf("sizeof WOLFSSL           = %lu\n", (unsigned long)sizeof(WOLFSSL));
 2225    printf("sizeof WOLFSSL_CTX       = %lu\n", (unsigned long)
 2226        sizeof(WOLFSSL_CTX));
 2227#endif
 2228
 2229    return sizeof(WOLFSSL);
 2230}
 2231
 2232int wolfSSL_CTX_GetObjectSize(void)
 2233{
 2234    return sizeof(WOLFSSL_CTX);
 2235}
 2236
 2237int wolfSSL_METHOD_GetObjectSize(void)
 2238{
 2239    return sizeof(WOLFSSL_METHOD);
 2240}
 2241#endif
 2242
 2243
 2244#ifdef WOLFSSL_STATIC_MEMORY
 2245
 2246int wolfSSL_CTX_load_static_memory(WOLFSSL_CTX** ctx,
 2247    wolfSSL_method_func method, unsigned char* buf, unsigned int sz, int flag,
 2248    int maxSz)
 2249{
 2250    WOLFSSL_HEAP_HINT* hint = NULL;
 2251
 2252    if (ctx == NULL || buf == NULL) {
 2253        return BAD_FUNC_ARG;
 2254    }
 2255
 2256    if (*ctx == NULL && method == NULL) {
 2257        return BAD_FUNC_ARG;
 2258    }
 2259
 2260    /* If there is a heap already, capture it in hint. */
 2261    if (*ctx && (*ctx)->heap != NULL) {
 2262        hint = (*ctx)->heap;
 2263    }
 2264
 2265    if (wc_LoadStaticMemory(&hint, buf, sz, flag, maxSz)) {
 2266        WOLFSSL_MSG("Error loading static memory");
 2267        return WOLFSSL_FAILURE;
 2268    }
 2269
 2270    if (*ctx) {
 2271        if ((*ctx)->heap == NULL) {
 2272            (*ctx)->heap = (void*)hint;
 2273        }
 2274    }
 2275    else {
 2276        /* create ctx if needed */
 2277        *ctx = wolfSSL_CTX_new_ex(method(hint), hint);
 2278        if (*ctx == NULL) {
 2279            WOLFSSL_MSG("Error creating ctx");
 2280            return WOLFSSL_FAILURE;
 2281        }
 2282    }
 2283
 2284    return WOLFSSL_SUCCESS;
 2285}
 2286
 2287
 2288int wolfSSL_is_static_memory(WOLFSSL* ssl, WOLFSSL_MEM_CONN_STATS* mem_stats)
 2289{
 2290    if (ssl == NULL) {
 2291        return BAD_FUNC_ARG;
 2292    }
 2293    WOLFSSL_ENTER("wolfSSL_is_static_memory");
 2294
 2295#ifndef WOLFSSL_STATIC_MEMORY_LEAN
 2296    /* fill out statistics if wanted and WOLFMEM_TRACK_STATS flag */
 2297    if (mem_stats != NULL && ssl->heap != NULL) {
 2298        WOLFSSL_HEAP_HINT* hint = ((WOLFSSL_HEAP_HINT*)(ssl->heap));
 2299        WOLFSSL_HEAP* heap      = hint->memory;
 2300        if (heap->flag & WOLFMEM_TRACK_STATS && hint->stats != NULL) {
 2301            XMEMCPY(mem_stats, hint->stats, sizeof(WOLFSSL_MEM_CONN_STATS));
 2302        }
 2303    }
 2304#endif
 2305
 2306    (void)mem_stats;
 2307    return (ssl->heap) ? 1 : 0;
 2308}
 2309
 2310
 2311int wolfSSL_CTX_is_static_memory(WOLFSSL_CTX* ctx, WOLFSSL_MEM_STATS* mem_stats)
 2312{
 2313    if (ctx == NULL) {
 2314        return BAD_FUNC_ARG;
 2315    }
 2316    WOLFSSL_ENTER("wolfSSL_CTX_is_static_memory");
 2317
 2318#ifndef WOLFSSL_STATIC_MEMORY_LEAN
 2319    /* fill out statistics if wanted */
 2320    if (mem_stats != NULL && ctx->heap != NULL) {
 2321        WOLFSSL_HEAP* heap = ((WOLFSSL_HEAP_HINT*)(ctx->heap))->memory;
 2322        if (wolfSSL_GetMemStats(heap, mem_stats) != 1) {
 2323            return MEMORY_E;
 2324        }
 2325    }
 2326#endif
 2327
 2328    (void)mem_stats;
 2329    return (ctx->heap) ? 1 : 0;
 2330}
 2331
 2332#endif /* WOLFSSL_STATIC_MEMORY */
 2333
 2334#ifndef NO_TLS
 2335/* return max record layer size plaintext input size */
 2336int wolfSSL_GetMaxOutputSize(WOLFSSL* ssl)
 2337{
 2338    WOLFSSL_ENTER("wolfSSL_GetMaxOutputSize");
 2339
 2340    if (ssl == NULL)
 2341        return BAD_FUNC_ARG;
 2342
 2343    if (ssl->options.handShakeState != HANDSHAKE_DONE) {
 2344        WOLFSSL_MSG("Handshake not complete yet");
 2345        return BAD_FUNC_ARG;
 2346    }
 2347
 2348    return min(OUTPUT_RECORD_SIZE, wolfssl_local_GetMaxPlaintextSize(ssl));
 2349}
 2350
 2351
 2352/* return record layer size of plaintext input size */
 2353int wolfSSL_GetOutputSize(WOLFSSL* ssl, int inSz)
 2354{
 2355    int maxSize;
 2356
 2357    WOLFSSL_ENTER("wolfSSL_GetOutputSize");
 2358
 2359    if (inSz < 0)
 2360        return BAD_FUNC_ARG;
 2361
 2362    maxSize = wolfSSL_GetMaxOutputSize(ssl);
 2363    if (maxSize < 0)
 2364        return maxSize;   /* error */
 2365    if (inSz > maxSize)
 2366        return INPUT_SIZE_E;
 2367
 2368    return wolfssl_local_GetRecordSize(ssl, inSz, 1);
 2369}
 2370
 2371
 2372#ifdef HAVE_ECC
 2373int wolfSSL_CTX_SetMinEccKey_Sz(WOLFSSL_CTX* ctx, short keySz)
 2374{
 2375    short keySzBytes;
 2376
 2377    WOLFSSL_ENTER("wolfSSL_CTX_SetMinEccKey_Sz");
 2378    if (ctx == NULL || keySz < 0) {
 2379        WOLFSSL_MSG("Key size must be positive value or ctx was null");
 2380        return BAD_FUNC_ARG;
 2381    }
 2382
 2383    if (keySz % 8 == 0) {
 2384        keySzBytes = keySz / 8;
 2385    }
 2386    else {
 2387        keySzBytes = (keySz / 8) + 1;
 2388    }
 2389
 2390#if defined(WOLFSSL_SYS_CRYPTO_POLICY)
 2391    if (crypto_policy.enabled) {
 2392        if (ctx->minEccKeySz > (keySzBytes)) {
 2393            return CRYPTO_POLICY_FORBIDDEN;
 2394        }
 2395    }
 2396#endif /* WOLFSSL_SYS_CRYPTO_POLICY */
 2397
 2398    ctx->minEccKeySz     = keySzBytes;
 2399#ifndef NO_CERTS
 2400    ctx->cm->minEccKeySz = keySzBytes;
 2401#endif
 2402    return WOLFSSL_SUCCESS;
 2403}
 2404
 2405
 2406int wolfSSL_SetMinEccKey_Sz(WOLFSSL* ssl, short keySz)
 2407{
 2408    short keySzBytes;
 2409
 2410    WOLFSSL_ENTER("wolfSSL_SetMinEccKey_Sz");
 2411    if (ssl == NULL || keySz < 0) {
 2412        WOLFSSL_MSG("Key size must be positive value or ctx was null");
 2413        return BAD_FUNC_ARG;
 2414    }
 2415
 2416    if (keySz % 8 == 0) {
 2417        keySzBytes = keySz / 8;
 2418    }
 2419    else {
 2420        keySzBytes = (keySz / 8) + 1;
 2421    }
 2422
 2423#if defined(WOLFSSL_SYS_CRYPTO_POLICY)
 2424    if (crypto_policy.enabled) {
 2425        if (ssl->options.minEccKeySz > (keySzBytes)) {
 2426            return CRYPTO_POLICY_FORBIDDEN;
 2427        }
 2428    }
 2429#endif /* WOLFSSL_SYS_CRYPTO_POLICY */
 2430
 2431    ssl->options.minEccKeySz = keySzBytes;
 2432    return WOLFSSL_SUCCESS;
 2433}
 2434
 2435#endif /* HAVE_ECC */
 2436
 2437#ifndef NO_RSA
 2438int wolfSSL_CTX_SetMinRsaKey_Sz(WOLFSSL_CTX* ctx, short keySz)
 2439{
 2440    if (ctx == NULL || keySz < 0 || keySz % 8 != 0) {
 2441        WOLFSSL_MSG("Key size must be divisible by 8 or ctx was null");
 2442        return BAD_FUNC_ARG;
 2443    }
 2444
 2445#if defined(WOLFSSL_SYS_CRYPTO_POLICY)
 2446    if (crypto_policy.enabled) {
 2447        if (ctx->minRsaKeySz > (keySz / 8)) {
 2448            return CRYPTO_POLICY_FORBIDDEN;
 2449        }
 2450    }
 2451#endif /* WOLFSSL_SYS_CRYPTO_POLICY */
 2452
 2453    ctx->minRsaKeySz     = keySz / 8;
 2454    ctx->cm->minRsaKeySz = keySz / 8;
 2455    return WOLFSSL_SUCCESS;
 2456}
 2457
 2458
 2459int wolfSSL_SetMinRsaKey_Sz(WOLFSSL* ssl, short keySz)
 2460{
 2461    if (ssl == NULL || keySz < 0 || keySz % 8 != 0) {
 2462        WOLFSSL_MSG("Key size must be divisible by 8 or ssl was null");
 2463        return BAD_FUNC_ARG;
 2464    }
 2465
 2466#if defined(WOLFSSL_SYS_CRYPTO_POLICY)
 2467    if (crypto_policy.enabled) {
 2468        if (ssl->options.minRsaKeySz > (keySz / 8)) {
 2469            return CRYPTO_POLICY_FORBIDDEN;
 2470        }
 2471    }
 2472#endif /* WOLFSSL_SYS_CRYPTO_POLICY */
 2473
 2474    ssl->options.minRsaKeySz = keySz / 8;
 2475    return WOLFSSL_SUCCESS;
 2476}
 2477#endif /* !NO_RSA */
 2478
 2479#ifndef NO_DH
 2480
 2481#if !defined(WOLFSSL_OLD_PRIME_CHECK) && !defined(HAVE_FIPS) && \
 2482    !defined(HAVE_SELFTEST)
 2483/* Enables or disables the session's DH key prime test. */
 2484int wolfSSL_SetEnableDhKeyTest(WOLFSSL* ssl, int enable)
 2485{
 2486    WOLFSSL_ENTER("wolfSSL_SetEnableDhKeyTest");
 2487
 2488    if (ssl == NULL)
 2489        return BAD_FUNC_ARG;
 2490
 2491    if (!enable)
 2492        ssl->options.dhDoKeyTest = 0;
 2493    else
 2494        ssl->options.dhDoKeyTest = 1;
 2495
 2496    WOLFSSL_LEAVE("wolfSSL_SetEnableDhKeyTest", WOLFSSL_SUCCESS);
 2497    return WOLFSSL_SUCCESS;
 2498}
 2499#endif
 2500
 2501int wolfSSL_CTX_SetMinDhKey_Sz(WOLFSSL_CTX* ctx, word16 keySz_bits)
 2502{
 2503    if (ctx == NULL || keySz_bits > 16000 || keySz_bits % 8 != 0)
 2504        return BAD_FUNC_ARG;
 2505
 2506#if defined(WOLFSSL_SYS_CRYPTO_POLICY)
 2507    if (crypto_policy.enabled) {
 2508        if (ctx->minDhKeySz > (keySz_bits / 8)) {
 2509            return CRYPTO_POLICY_FORBIDDEN;
 2510        }
 2511    }
 2512#endif /* WOLFSSL_SYS_CRYPTO_POLICY */
 2513
 2514    ctx->minDhKeySz = keySz_bits / 8;
 2515    return WOLFSSL_SUCCESS;
 2516}
 2517
 2518
 2519int wolfSSL_SetMinDhKey_Sz(WOLFSSL* ssl, word16 keySz_bits)
 2520{
 2521    if (ssl == NULL || keySz_bits > 16000 || keySz_bits % 8 != 0)
 2522        return BAD_FUNC_ARG;
 2523
 2524#if defined(WOLFSSL_SYS_CRYPTO_POLICY)
 2525    if (crypto_policy.enabled) {
 2526        if (ssl->options.minDhKeySz > (keySz_bits / 8)) {
 2527            return CRYPTO_POLICY_FORBIDDEN;
 2528        }
 2529    }
 2530#endif /* WOLFSSL_SYS_CRYPTO_POLICY */
 2531
 2532    ssl->options.minDhKeySz = keySz_bits / 8;
 2533    return WOLFSSL_SUCCESS;
 2534}
 2535
 2536
 2537int wolfSSL_CTX_SetMaxDhKey_Sz(WOLFSSL_CTX* ctx, word16 keySz_bits)
 2538{
 2539    if (ctx == NULL || keySz_bits > 16000 || keySz_bits % 8 != 0)
 2540        return BAD_FUNC_ARG;
 2541
 2542#if defined(WOLFSSL_SYS_CRYPTO_POLICY)
 2543    if (crypto_policy.enabled) {
 2544        if (ctx->minDhKeySz > (keySz_bits / 8)) {
 2545            return CRYPTO_POLICY_FORBIDDEN;
 2546        }
 2547    }
 2548#endif /* WOLFSSL_SYS_CRYPTO_POLICY */
 2549
 2550    ctx->maxDhKeySz = keySz_bits / 8;
 2551    return WOLFSSL_SUCCESS;
 2552}
 2553
 2554
 2555int wolfSSL_SetMaxDhKey_Sz(WOLFSSL* ssl, word16 keySz_bits)
 2556{
 2557    if (ssl == NULL || keySz_bits > 16000 || keySz_bits % 8 != 0)
 2558        return BAD_FUNC_ARG;
 2559
 2560#if defined(WOLFSSL_SYS_CRYPTO_POLICY)
 2561    if (crypto_policy.enabled) {
 2562        if (ssl->options.minDhKeySz > (keySz_bits / 8)) {
 2563            return CRYPTO_POLICY_FORBIDDEN;
 2564        }
 2565    }
 2566#endif /* WOLFSSL_SYS_CRYPTO_POLICY */
 2567
 2568    ssl->options.maxDhKeySz = keySz_bits / 8;
 2569    return WOLFSSL_SUCCESS;
 2570}
 2571
 2572
 2573int wolfSSL_GetDhKey_Sz(WOLFSSL* ssl)
 2574{
 2575    if (ssl == NULL)
 2576        return BAD_FUNC_ARG;
 2577
 2578    return (ssl->options.dhKeySz * 8);
 2579}
 2580
 2581#endif /* !NO_DH */
 2582
 2583
 2584static int wolfSSL_write_internal(WOLFSSL* ssl, const void* data, size_t sz)
 2585{
 2586    int ret = 0;
 2587
 2588    WOLFSSL_ENTER("wolfSSL_write");
 2589
 2590    if (ssl == NULL || data == NULL)
 2591        return BAD_FUNC_ARG;
 2592
 2593#ifdef WOLFSSL_QUIC
 2594    if (WOLFSSL_IS_QUIC(ssl)) {
 2595        WOLFSSL_MSG("SSL_write() on QUIC not allowed");
 2596        return BAD_FUNC_ARG;
 2597    }
 2598#endif
 2599
 2600#ifdef HAVE_WRITE_DUP
 2601    if (ssl->dupSide == READ_DUP_SIDE) {
 2602        WOLFSSL_MSG("Read dup side cannot write");
 2603        return WRITE_DUP_WRITE_E;
 2604    }
 2605    /* Only enter special dupWrite logic when error is cleared. This will help
 2606     * with handling async data and other edge case errors. */
 2607    if (ssl->dupWrite != NULL && ssl->error == 0) {
 2608        int dupErr = 0;   /* local copy */
 2609        /* Lock ssl->dupWrite to gather what needs to be done. */
 2610        if (wc_LockMutex(&ssl->dupWrite->dupMutex) != 0)
 2611            return BAD_MUTEX_E;
 2612        dupErr = ssl->dupWrite->dupErr;
 2613#ifdef WOLFSSL_TLS13
 2614        if (IsAtLeastTLSv1_3(ssl->version)) {
 2615            /* TLS 1.3: if the read side received a KeyUpdate(update_requested)
 2616             * it cannot respond; send the response from here. */
 2617            ssl->keys.keyUpdateRespond |= ssl->dupWrite->keyUpdateRespond;
 2618            ssl->dupWrite->keyUpdateRespond = 0;
 2619#ifdef WOLFSSL_POST_HANDSHAKE_AUTH
 2620            ssl->postHandshakeAuthPending |=
 2621                    ssl->dupWrite->postHandshakeAuthPending;
 2622            ssl->dupWrite->postHandshakeAuthPending = 0;
 2623            if (ssl->postHandshakeAuthPending) {
 2624                /* Take ownership of the delegated auth state. */
 2625                CertReqCtx** tail = &ssl->dupWrite->postHandshakeCertReqCtx;
 2626                while (*tail != NULL)
 2627                    tail = &(*tail)->next;
 2628                *tail = ssl->certReqCtx;
 2629                ssl->certReqCtx = ssl->dupWrite->postHandshakeCertReqCtx;
 2630                ssl->dupWrite->postHandshakeCertReqCtx = NULL;
 2631                FreeHandshakeHashes(ssl);
 2632                ssl->hsHashes = ssl->dupWrite->postHandshakeHashState;
 2633                ssl->dupWrite->postHandshakeHashState = NULL;
 2634                ssl->options.sendVerify = ssl->dupWrite->postHandshakeSendVerify;
 2635                ssl->options.sigAlgo = ssl->dupWrite->postHandshakeSigAlgo;
 2636                ssl->options.hashAlgo = ssl->dupWrite->postHandshakeHashAlgo;
 2637            }
 2638#endif /* WOLFSSL_POST_HANDSHAKE_AUTH */
 2639#ifdef WOLFSSL_DTLS13
 2640            if (ssl->options.dtls) {
 2641                /* Schedule key update to be sent. */
 2642                if (ssl->keys.keyUpdateRespond)
 2643                    ssl->dtls13DoKeyUpdate = 1;
 2644
 2645                /* Copy over ACKs */
 2646                ssl->dtls13Rtx.sendAcks |= ssl->dupWrite->sendAcks;
 2647                if (ssl->dupWrite->sendAcks) {
 2648                    /* Insert each record number so the
 2649                     * ACK message is properly ordered. */
 2650                    struct Dtls13RecordNumber* rn;
 2651                    for (rn = ssl->dupWrite->sendAckList; rn != NULL;
 2652                         rn = rn->next) {
 2653                        ret = Dtls13RtxAddAck(ssl, rn->epoch, rn->seq);
 2654                        if (ret != 0)
 2655                            break;
 2656                    }
 2657                    /* Clear only on success so no ACKs get dropped */
 2658                    if (ret == 0) {
 2659                        rn = ssl->dupWrite->sendAckList;
 2660                        ssl->dupWrite->sendAckList = NULL;
 2661                        ssl->dupWrite->sendAcks = 0;
 2662                        while (rn != NULL) {
 2663                            struct Dtls13RecordNumber* next = rn->next;
 2664                            XFREE(rn, ssl->heap, DYNAMIC_TYPE_DTLS_MSG);
 2665                            rn = next;
 2666                        }
 2667                    }
 2668                }
 2669
 2670                /* Remove KeyUpdate record from RTX list. */
 2671                if (ssl->dupWrite->keyUpdateAcked) {
 2672                    Dtls13RtxRemoveRecord(ssl, ssl->dupWrite->keyUpdateEpoch,
 2673                            ssl->dupWrite->keyUpdateSeq);
 2674                }
 2675                /* Store if KeyUpdate was ACKed. */
 2676                ssl->dtls13KeyUpdateAcked |= ssl->dupWrite->keyUpdateAcked;
 2677                ssl->dupWrite->keyUpdateAcked = 0;
 2678            }
 2679#endif /* WOLFSSL_DTLS13 */
 2680        }
 2681#endif /* WOLFSSL_TLS13 */
 2682        wc_UnLockMutex(&ssl->dupWrite->dupMutex);
 2683
 2684        if (dupErr != 0) {
 2685            WOLFSSL_MSG("Write dup error from other side");
 2686            ssl->error = dupErr;
 2687            return WOLFSSL_FATAL_ERROR;
 2688        }
 2689        if (ret != 0) {
 2690            ssl->error = ret;
 2691            return WOLFSSL_FATAL_ERROR;
 2692        }
 2693
 2694
 2695#ifdef WOLFSSL_TLS13
 2696        if (IsAtLeastTLSv1_3(ssl->version)) {
 2697#ifdef WOLFSSL_POST_HANDSHAKE_AUTH
 2698            /* Read side received a CertificateRequest but couldn't write;
 2699             * send Certificate+CertificateVerify+Finished from the write side. */
 2700            if (ssl->postHandshakeAuthPending) {
 2701                /* reset handshake states */
 2702                ssl->postHandshakeAuthPending = 0;
 2703                ssl->options.clientState = CLIENT_HELLO_COMPLETE;
 2704                ssl->options.connectState = FIRST_REPLY_DONE;
 2705                ssl->options.handShakeState = CLIENT_HELLO_COMPLETE;
 2706                ssl->options.processReply = 0; /* doProcessInit */
 2707                if (wolfSSL_connect_TLSv13(ssl) != WOLFSSL_SUCCESS) {
 2708                    if (ssl->error != WC_NO_ERR_TRACE(WANT_WRITE) &&
 2709                            ssl->error != WC_NO_ERR_TRACE(WC_PENDING_E)) {
 2710                        WOLFSSL_MSG("Post-handshake auth send failed");
 2711                        ssl->error = POST_HAND_AUTH_ERROR;
 2712                    }
 2713                    return WOLFSSL_FATAL_ERROR;
 2714                }
 2715            }
 2716#endif /* WOLFSSL_POST_HANDSHAKE_AUTH */
 2717#ifdef WOLFSSL_DTLS13
 2718            if (ssl->options.dtls) {
 2719                if (ssl->dtls13KeyUpdateAcked)
 2720                    ret = DoDtls13KeyUpdateAck(ssl);
 2721                ssl->dtls13KeyUpdateAcked = 0;
 2722                if (ret == 0)
 2723                    ret = Dtls13DoScheduledWork(ssl);
 2724            }
 2725            else
 2726#endif /* WOLFSSL_DTLS13 */
 2727            if (ssl->keys.keyUpdateRespond) /* cleared in SendTls13KeyUpdate */
 2728                ret = Tls13UpdateKeys(ssl);
 2729            if (ret != 0) {
 2730                ssl->error = ret;
 2731                return WOLFSSL_FATAL_ERROR;
 2732            }
 2733            /* WANT_WRITE is safe to clear. Data is buffered in output buffer
 2734             * or in DTLS RTX queue */
 2735            ret = 0;
 2736        }
 2737#endif /* WOLFSSL_TLS13 */
 2738    }
 2739#endif
 2740
 2741#ifdef HAVE_ERRNO_H
 2742    errno = 0;
 2743#endif
 2744
 2745    #ifdef OPENSSL_EXTRA
 2746    if (ssl->CBIS != NULL) {
 2747        ssl->CBIS(ssl, WOLFSSL_CB_WRITE, WOLFSSL_SUCCESS);
 2748        ssl->cbmode = WOLFSSL_CB_WRITE;
 2749    }
 2750    #endif
 2751    ret = SendData(ssl, data, sz);
 2752
 2753    WOLFSSL_LEAVE("wolfSSL_write", ret);
 2754
 2755    if (ret < 0)
 2756        return WOLFSSL_FATAL_ERROR;
 2757    else
 2758        return ret;
 2759}
 2760
 2761WOLFSSL_ABI
 2762int wolfSSL_write(WOLFSSL* ssl, const void* data, int sz)
 2763{
 2764    WOLFSSL_ENTER("wolfSSL_write");
 2765
 2766    if (sz < 0)
 2767        return BAD_FUNC_ARG;
 2768
 2769    return wolfSSL_write_internal(ssl, data, (size_t)sz);
 2770}
 2771
 2772int wolfSSL_inject(WOLFSSL* ssl, const void* data, int sz)
 2773{
 2774    int maxLength;
 2775    int usedLength;
 2776
 2777    WOLFSSL_ENTER("wolfSSL_inject");
 2778
 2779    if (ssl == NULL || data == NULL || sz <= 0)
 2780        return BAD_FUNC_ARG;
 2781
 2782    usedLength = (int)(ssl->buffers.inputBuffer.length -
 2783                       ssl->buffers.inputBuffer.idx);
 2784    maxLength  = (int)(ssl->buffers.inputBuffer.bufferSize -
 2785                       (word32)usedLength);
 2786
 2787    if (sz > maxLength) {
 2788        /* Need to make space */
 2789        int ret;
 2790        if (ssl->buffers.clearOutputBuffer.length > 0) {
 2791            /* clearOutputBuffer points into so reallocating inputBuffer will
 2792             * invalidate clearOutputBuffer and lose app data */
 2793            WOLFSSL_MSG("Can't inject while there is application data to read");
 2794            return APP_DATA_READY;
 2795        }
 2796        ret = GrowInputBuffer(ssl, sz, usedLength);
 2797        if (ret < 0)
 2798            return ret;
 2799    }
 2800
 2801    XMEMCPY(ssl->buffers.inputBuffer.buffer + ssl->buffers.inputBuffer.idx,
 2802            data, sz);
 2803    ssl->buffers.inputBuffer.length += sz;
 2804
 2805    return WOLFSSL_SUCCESS;
 2806}
 2807
 2808
 2809int wolfSSL_write_ex(WOLFSSL* ssl, const void* data, size_t sz, size_t* wr)
 2810{
 2811    int ret;
 2812
 2813    if (wr != NULL) {
 2814        *wr = 0;
 2815    }
 2816
 2817    ret = wolfSSL_write_internal(ssl, data, sz);
 2818    if (ret >= 0) {
 2819        if (wr != NULL) {
 2820            *wr = (size_t)ret;
 2821        }
 2822
 2823        /* handle partial write cases, if not set then a partial write is
 2824         * considered a failure case, or if set and ret is 0 then is a fail */
 2825        if (ret == 0 && ssl->options.partialWrite) {
 2826            ret = 0;
 2827        }
 2828        else if ((size_t)ret < sz && !ssl->options.partialWrite) {
 2829            ret = 0;
 2830        }
 2831        else {
 2832            /* wrote out all application data, or wrote out 1 byte or more with
 2833             * partial write flag set */
 2834            ret = 1;
 2835        }
 2836    }
 2837    else {
 2838        ret = 0;
 2839    }
 2840
 2841    return ret;
 2842}
 2843
 2844
 2845static int wolfSSL_read_internal(WOLFSSL* ssl, void* data, size_t sz, int peek)
 2846{
 2847    int ret;
 2848
 2849    WOLFSSL_ENTER("wolfSSL_read_internal");
 2850
 2851    if (ssl == NULL || data == NULL)
 2852        return BAD_FUNC_ARG;
 2853
 2854#ifdef WOLFSSL_QUIC
 2855    if (WOLFSSL_IS_QUIC(ssl)) {
 2856        WOLFSSL_MSG("SSL_read() on QUIC not allowed");
 2857        return BAD_FUNC_ARG;
 2858    }
 2859#endif
 2860#if defined(WOLFSSL_ERROR_CODE_OPENSSL) && defined(OPENSSL_EXTRA)
 2861    /* This additional logic is meant to simulate following openSSL behavior:
 2862     * After bidirectional SSL_shutdown complete, SSL_read returns 0 and
 2863     * SSL_get_error_code returns SSL_ERROR_ZERO_RETURN.
 2864     * This behavior is used to know the disconnect of the underlying
 2865     * transport layer.
 2866     *
 2867     * In this logic, CBIORecv is called with a read size of 0 to check the
 2868     * transport layer status. It also returns WOLFSSL_FAILURE so that
 2869     * SSL_read does not return a positive number on failure.
 2870     */
 2871
 2872    /* make sure bidirectional TLS shutdown completes */
 2873    if (ssl->error == WOLFSSL_ERROR_SYSCALL || ssl->options.shutdownDone) {
 2874        /* ask the underlying transport the connection is closed */
 2875        if (ssl->CBIORecv(ssl, (char*)data, 0, ssl->IOCB_ReadCtx)
 2876            == WC_NO_ERR_TRACE(WOLFSSL_CBIO_ERR_CONN_CLOSE))
 2877        {
 2878            ssl->options.isClosed = 1;
 2879            ssl->error = WOLFSSL_ERROR_ZERO_RETURN;
 2880        }
 2881        return WOLFSSL_FAILURE;
 2882    }
 2883#endif
 2884
 2885#ifdef HAVE_WRITE_DUP
 2886    if (ssl->dupWrite && ssl->dupSide == WRITE_DUP_SIDE) {
 2887        WOLFSSL_MSG("Write dup side cannot read");
 2888        return WRITE_DUP_READ_E;
 2889    }
 2890#endif
 2891
 2892#ifdef HAVE_ERRNO_H
 2893        errno = 0;
 2894#endif
 2895
 2896    ret = ReceiveData(ssl, (byte*)data, sz, peek);
 2897
 2898#ifdef HAVE_WRITE_DUP
 2899    if (ssl->dupWrite) {
 2900        if (ssl->error != 0 && ssl->error != WC_NO_ERR_TRACE(WANT_READ)
 2901        #ifdef WOLFSSL_ASYNC_CRYPT
 2902            && ssl->error != WC_NO_ERR_TRACE(WC_PENDING_E)
 2903        #endif
 2904        ) {
 2905            int notifyErr;
 2906
 2907            WOLFSSL_MSG("Notifying write side of fatal read error");
 2908            notifyErr  = NotifyWriteSide(ssl, ssl->error);
 2909            if (notifyErr < 0) {
 2910                ret = ssl->error = notifyErr;
 2911            }
 2912        }
 2913    }
 2914#endif
 2915
 2916    WOLFSSL_LEAVE("wolfSSL_read_internal", ret);
 2917
 2918    if (ret < 0)
 2919        return WOLFSSL_FATAL_ERROR;
 2920    else
 2921        return ret;
 2922}
 2923
 2924
 2925int wolfSSL_peek(WOLFSSL* ssl, void* data, int sz)
 2926{
 2927    WOLFSSL_ENTER("wolfSSL_peek");
 2928
 2929    if (sz < 0)
 2930        return BAD_FUNC_ARG;
 2931
 2932    return wolfSSL_read_internal(ssl, data, (size_t)sz, TRUE);
 2933}
 2934
 2935
 2936WOLFSSL_ABI
 2937int wolfSSL_read(WOLFSSL* ssl, void* data, int sz)
 2938{
 2939    WOLFSSL_ENTER("wolfSSL_read");
 2940
 2941    if (sz < 0)
 2942        return BAD_FUNC_ARG;
 2943
 2944    #ifdef OPENSSL_EXTRA
 2945    if (ssl == NULL) {
 2946        return BAD_FUNC_ARG;
 2947    }
 2948    if (ssl->CBIS != NULL) {
 2949        ssl->CBIS(ssl, WOLFSSL_CB_READ, WOLFSSL_SUCCESS);
 2950        ssl->cbmode = WOLFSSL_CB_READ;
 2951    }
 2952    #endif
 2953    return wolfSSL_read_internal(ssl, data, (size_t)sz, FALSE);
 2954}
 2955
 2956
 2957/* returns 0 on failure and 1 on read */
 2958int wolfSSL_read_ex(WOLFSSL* ssl, void* data, size_t sz, size_t* rd)
 2959{
 2960    int ret;
 2961
 2962    #ifdef OPENSSL_EXTRA
 2963    if (ssl == NULL) {
 2964        return BAD_FUNC_ARG;
 2965    }
 2966    if (ssl->CBIS != NULL) {
 2967        ssl->CBIS(ssl, WOLFSSL_CB_READ, WOLFSSL_SUCCESS);
 2968        ssl->cbmode = WOLFSSL_CB_READ;
 2969    }
 2970    #endif
 2971    ret = wolfSSL_read_internal(ssl, data, sz, FALSE);
 2972
 2973    if (ret > 0 && rd != NULL) {
 2974        *rd = (size_t)ret;
 2975    }
 2976
 2977    return ret > 0 ? 1 : 0;
 2978}
 2979
 2980#ifdef WOLFSSL_MULTICAST
 2981
 2982int wolfSSL_mcast_read(WOLFSSL* ssl, word16* id, void* data, int sz)
 2983{
 2984    int ret = 0;
 2985
 2986    WOLFSSL_ENTER("wolfSSL_mcast_read");
 2987
 2988    if ((ssl == NULL) || (sz < 0))
 2989        return BAD_FUNC_ARG;
 2990
 2991    ret = wolfSSL_read_internal(ssl, data, (size_t)sz, FALSE);
 2992    if (ssl->options.dtls && ssl->options.haveMcast && id != NULL)
 2993        *id = ssl->keys.curPeerId;
 2994    return ret;
 2995}
 2996
 2997#endif /* WOLFSSL_MULTICAST */
 2998#endif /* !NO_TLS */
 2999
 3000/* helpers to set the device id, WOLFSSL_SUCCESS on ok */
 3001WOLFSSL_ABI
 3002int wolfSSL_SetDevId(WOLFSSL* ssl, int devId)
 3003{
 3004    if (ssl == NULL)
 3005        return BAD_FUNC_ARG;
 3006
 3007    ssl->devId = devId;
 3008
 3009    return WOLFSSL_SUCCESS;
 3010}
 3011
 3012WOLFSSL_ABI
 3013int wolfSSL_CTX_SetDevId(WOLFSSL_CTX* ctx, int devId)
 3014{
 3015    if (ctx == NULL)
 3016        return BAD_FUNC_ARG;
 3017
 3018    ctx->devId = devId;
 3019
 3020    return WOLFSSL_SUCCESS;
 3021}
 3022
 3023/* helpers to get device id and heap */
 3024WOLFSSL_ABI
 3025int wolfSSL_CTX_GetDevId(WOLFSSL_CTX* ctx, WOLFSSL* ssl)
 3026{
 3027    int devId = INVALID_DEVID;
 3028    if (ssl != NULL)
 3029        devId = ssl->devId;
 3030    if (ctx != NULL && devId == INVALID_DEVID)
 3031        devId = ctx->devId;
 3032    return devId;
 3033}
 3034void* wolfSSL_CTX_GetHeap(WOLFSSL_CTX* ctx, WOLFSSL* ssl)
 3035{
 3036    void* heap = NULL;
 3037    if (ctx != NULL)
 3038        heap = ctx->heap;
 3039    else if (ssl != NULL)
 3040        heap = ssl->heap;
 3041    return heap;
 3042}
 3043
 3044
 3045#ifndef NO_TLS
 3046#ifdef HAVE_SNI
 3047
 3048WOLFSSL_ABI
 3049int wolfSSL_UseSNI(WOLFSSL* ssl, byte type, const void* data, word16 size)
 3050{
 3051    if (ssl == NULL)
 3052        return BAD_FUNC_ARG;
 3053
 3054    return TLSX_UseSNI(&ssl->extensions, type, data, size, ssl->heap);
 3055}
 3056
 3057
 3058WOLFSSL_ABI
 3059int wolfSSL_CTX_UseSNI(WOLFSSL_CTX* ctx, byte type, const void* data,
 3060                                                                    word16 size)
 3061{
 3062    if (ctx == NULL)
 3063        return BAD_FUNC_ARG;
 3064
 3065    return TLSX_UseSNI(&ctx->extensions, type, data, size, ctx->heap);
 3066}
 3067
 3068#ifndef NO_WOLFSSL_SERVER
 3069
 3070void wolfSSL_SNI_SetOptions(WOLFSSL* ssl, byte type, byte options)
 3071{
 3072    if (ssl && ssl->extensions)
 3073        TLSX_SNI_SetOptions(ssl->extensions, type, options);
 3074}
 3075
 3076
 3077void wolfSSL_CTX_SNI_SetOptions(WOLFSSL_CTX* ctx, byte type, byte options)
 3078{
 3079    if (ctx && ctx->extensions)
 3080        TLSX_SNI_SetOptions(ctx->extensions, type, options);
 3081}
 3082
 3083
 3084byte wolfSSL_SNI_Status(WOLFSSL* ssl, byte type)
 3085{
 3086    return TLSX_SNI_Status(ssl ? ssl->extensions : NULL, type);
 3087}
 3088
 3089
 3090word16 wolfSSL_SNI_GetRequest(WOLFSSL* ssl, byte type, void** data)
 3091{
 3092    if (data)
 3093        *data = NULL;
 3094
 3095    if (ssl && ssl->extensions)
 3096        return TLSX_SNI_GetRequest(ssl->extensions, type, data, 0);
 3097
 3098    return 0;
 3099}
 3100
 3101
 3102int wolfSSL_SNI_GetFromBuffer(const byte* clientHello, word32 helloSz,
 3103                              byte type, byte* sni, word32* inOutSz)
 3104{
 3105    if (clientHello && helloSz > 0 && sni && inOutSz && *inOutSz > 0)
 3106        return TLSX_SNI_GetFromBuffer(clientHello, helloSz, type, sni, inOutSz);
 3107
 3108    return BAD_FUNC_ARG;
 3109}
 3110
 3111#endif /* !NO_WOLFSSL_SERVER */
 3112
 3113#endif /* HAVE_SNI */
 3114
 3115
 3116#ifdef HAVE_TRUSTED_CA
 3117
 3118int wolfSSL_UseTrustedCA(WOLFSSL* ssl, byte type,
 3119    const byte* certId, word32 certIdSz)
 3120{
 3121    if (ssl == NULL)
 3122        return BAD_FUNC_ARG;
 3123
 3124    if (type == WOLFSSL_TRUSTED_CA_PRE_AGREED) {
 3125        if (certId != NULL || certIdSz != 0)
 3126            return BAD_FUNC_ARG;
 3127    }
 3128    else if (type == WOLFSSL_TRUSTED_CA_X509_NAME) {
 3129        if (certId == NULL || certIdSz == 0)
 3130            return BAD_FUNC_ARG;
 3131    }
 3132    #ifndef NO_SHA
 3133    else if (type == WOLFSSL_TRUSTED_CA_KEY_SHA1 ||
 3134            type == WOLFSSL_TRUSTED_CA_CERT_SHA1) {
 3135        if (certId == NULL || certIdSz != WC_SHA_DIGEST_SIZE)
 3136            return BAD_FUNC_ARG;
 3137    }
 3138    #endif
 3139    else
 3140        return BAD_FUNC_ARG;
 3141
 3142    return TLSX_UseTrustedCA(&ssl->extensions,
 3143            type, certId, certIdSz, ssl->heap);
 3144}
 3145
 3146#endif /* HAVE_TRUSTED_CA */
 3147
 3148
 3149#ifdef HAVE_MAX_FRAGMENT
 3150#ifndef NO_WOLFSSL_CLIENT
 3151
 3152int wolfSSL_UseMaxFragment(WOLFSSL* ssl, byte mfl)
 3153{
 3154    if (ssl == NULL)
 3155        return BAD_FUNC_ARG;
 3156
 3157#ifdef WOLFSSL_ALLOW_MAX_FRAGMENT_ADJUST
 3158    /* The following is a non-standard way to reconfigure the max packet size
 3159        post-handshake for wolfSSL_write/wolfSSL_read */
 3160    if (ssl->options.handShakeState == HANDSHAKE_DONE) {
 3161        switch (mfl) {
 3162            case WOLFSSL_MFL_2_8 : ssl->max_fragment =  256; break;
 3163            case WOLFSSL_MFL_2_9 : ssl->max_fragment =  512; break;
 3164            case WOLFSSL_MFL_2_10: ssl->max_fragment = 1024; break;
 3165            case WOLFSSL_MFL_2_11: ssl->max_fragment = 2048; break;
 3166            case WOLFSSL_MFL_2_12: ssl->max_fragment = 4096; break;
 3167            case WOLFSSL_MFL_2_13: ssl->max_fragment = 8192; break;
 3168            default: ssl->max_fragment = MAX_RECORD_SIZE; break;
 3169        }
 3170        return WOLFSSL_SUCCESS;
 3171    }
 3172#endif /* WOLFSSL_MAX_FRAGMENT_ADJUST */
 3173
 3174    /* This call sets the max fragment TLS extension, which gets sent to server.
 3175        The server_hello response is what sets the `ssl->max_fragment` in
 3176        TLSX_MFL_Parse */
 3177    return TLSX_UseMaxFragment(&ssl->extensions, mfl, ssl->heap);
 3178}
 3179
 3180
 3181int wolfSSL_CTX_UseMaxFragment(WOLFSSL_CTX* ctx, byte mfl)
 3182{
 3183    if (ctx == NULL)
 3184        return BAD_FUNC_ARG;
 3185
 3186    return TLSX_UseMaxFragment(&ctx->extensions, mfl, ctx->heap);
 3187}
 3188
 3189#endif /* NO_WOLFSSL_CLIENT */
 3190#endif /* HAVE_MAX_FRAGMENT */
 3191
 3192#ifdef HAVE_TRUNCATED_HMAC
 3193#ifndef NO_WOLFSSL_CLIENT
 3194
 3195int wolfSSL_UseTruncatedHMAC(WOLFSSL* ssl)
 3196{
 3197    if (ssl == NULL)
 3198        return BAD_FUNC_ARG;
 3199
 3200    return TLSX_UseTruncatedHMAC(&ssl->extensions, ssl->heap);
 3201}
 3202
 3203
 3204int wolfSSL_CTX_UseTruncatedHMAC(WOLFSSL_CTX* ctx)
 3205{
 3206    if (ctx == NULL)
 3207        return BAD_FUNC_ARG;
 3208
 3209    return TLSX_UseTruncatedHMAC(&ctx->extensions, ctx->heap);
 3210}
 3211
 3212#endif /* NO_WOLFSSL_CLIENT */
 3213#endif /* HAVE_TRUNCATED_HMAC */
 3214
 3215/* Elliptic Curves */
 3216#if defined(HAVE_SUPPORTED_CURVES)
 3217
 3218static int isValidCurveGroup(word16 name)
 3219{
 3220    switch (name) {
 3221        case WOLFSSL_ECC_SECP160K1:
 3222        case WOLFSSL_ECC_SECP160R1:
 3223        case WOLFSSL_ECC_SECP160R2:
 3224        case WOLFSSL_ECC_SECP192K1:
 3225        case WOLFSSL_ECC_SECP192R1:
 3226        case WOLFSSL_ECC_SECP224K1:
 3227        case WOLFSSL_ECC_SECP224R1:
 3228        case WOLFSSL_ECC_SECP256K1:
 3229        case WOLFSSL_ECC_SECP256R1:
 3230        case WOLFSSL_ECC_SECP384R1:
 3231        case WOLFSSL_ECC_SECP521R1:
 3232        case WOLFSSL_ECC_BRAINPOOLP256R1:
 3233        case WOLFSSL_ECC_BRAINPOOLP384R1:
 3234        case WOLFSSL_ECC_BRAINPOOLP512R1:
 3235        case WOLFSSL_ECC_SM2P256V1:
 3236        case WOLFSSL_ECC_X25519:
 3237        case WOLFSSL_ECC_X448:
 3238        case WOLFSSL_ECC_BRAINPOOLP256R1TLS13:
 3239        case WOLFSSL_ECC_BRAINPOOLP384R1TLS13:
 3240        case WOLFSSL_ECC_BRAINPOOLP512R1TLS13:
 3241
 3242        case WOLFSSL_FFDHE_2048:
 3243        case WOLFSSL_FFDHE_3072:
 3244        case WOLFSSL_FFDHE_4096:
 3245        case WOLFSSL_FFDHE_6144:
 3246        case WOLFSSL_FFDHE_8192:
 3247
 3248#ifdef WOLFSSL_HAVE_MLKEM
 3249#ifndef WOLFSSL_NO_ML_KEM
 3250    #ifndef WOLFSSL_TLS_NO_MLKEM_STANDALONE
 3251        case WOLFSSL_ML_KEM_512:
 3252        case WOLFSSL_ML_KEM_768:
 3253        case WOLFSSL_ML_KEM_1024:
 3254    #endif /* !WOLFSSL_TLS_NO_MLKEM_STANDALONE */
 3255    #ifdef WOLFSSL_PQC_HYBRIDS
 3256        case WOLFSSL_SECP384R1MLKEM1024:
 3257        case WOLFSSL_X25519MLKEM768:
 3258        case WOLFSSL_SECP256R1MLKEM768:
 3259    #endif /* WOLFSSL_PQC_HYBRIDS */
 3260    #ifdef WOLFSSL_EXTRA_PQC_HYBRIDS
 3261        case WOLFSSL_SECP256R1MLKEM512:
 3262        case WOLFSSL_SECP384R1MLKEM768:
 3263        case WOLFSSL_SECP521R1MLKEM1024:
 3264        case WOLFSSL_X25519MLKEM512:
 3265        case WOLFSSL_X448MLKEM768:
 3266    #endif /* WOLFSSL_EXTRA_PQC_HYBRIDS */
 3267#endif /* !WOLFSSL_NO_ML_KEM */
 3268#ifdef WOLFSSL_MLKEM_KYBER
 3269        case WOLFSSL_KYBER_LEVEL1:
 3270        case WOLFSSL_KYBER_LEVEL3:
 3271        case WOLFSSL_KYBER_LEVEL5:
 3272        case WOLFSSL_P256_KYBER_LEVEL1:
 3273        case WOLFSSL_P384_KYBER_LEVEL3:
 3274        case WOLFSSL_P521_KYBER_LEVEL5:
 3275        case WOLFSSL_X25519_KYBER_LEVEL1:
 3276        case WOLFSSL_X448_KYBER_LEVEL3:
 3277        case WOLFSSL_X25519_KYBER_LEVEL3:
 3278        case WOLFSSL_P256_KYBER_LEVEL3:
 3279#endif /* WOLFSSL_MLKEM_KYBER */
 3280#endif
 3281            return 1;
 3282
 3283        default:
 3284            return 0;
 3285    }
 3286}
 3287
 3288int wolfSSL_UseSupportedCurve(WOLFSSL* ssl, word16 name)
 3289{
 3290    if (ssl == NULL || !isValidCurveGroup(name))
 3291        return BAD_FUNC_ARG;
 3292
 3293    ssl->options.userCurves = 1;
 3294#if defined(NO_TLS)
 3295    return WOLFSSL_FAILURE;
 3296#else
 3297    return TLSX_UseSupportedCurve(&ssl->extensions, name, ssl->heap);
 3298#endif /* NO_TLS */
 3299}
 3300
 3301
 3302int wolfSSL_CTX_UseSupportedCurve(WOLFSSL_CTX* ctx, word16 name)
 3303{
 3304    if (ctx == NULL || !isValidCurveGroup(name))
 3305        return BAD_FUNC_ARG;
 3306
 3307    ctx->userCurves = 1;
 3308#if defined(NO_TLS)
 3309    return WOLFSSL_FAILURE;
 3310#else
 3311    return TLSX_UseSupportedCurve(&ctx->extensions, name, ctx->heap);
 3312#endif /* NO_TLS */
 3313}
 3314
 3315#if defined(OPENSSL_EXTRA)
 3316int  wolfSSL_CTX_set1_groups(WOLFSSL_CTX* ctx, int* groups,
 3317                                        int count)
 3318{
 3319    int i;
 3320    int _groups[WOLFSSL_MAX_GROUP_COUNT];
 3321    WOLFSSL_ENTER("wolfSSL_CTX_set1_groups");
 3322    if (count == 0) {
 3323        WOLFSSL_MSG("Group count is zero");
 3324        return WOLFSSL_FAILURE;
 3325    }
 3326    if (count > WOLFSSL_MAX_GROUP_COUNT) {
 3327        WOLFSSL_MSG("Group count exceeds maximum");
 3328        return WOLFSSL_FAILURE;
 3329    }
 3330    for (i = 0; i < count; i++) {
 3331        if (isValidCurveGroup((word16)groups[i])) {
 3332            _groups[i] = groups[i];
 3333        }
 3334#ifdef HAVE_ECC
 3335        else {
 3336            /* groups may be populated with curve NIDs */
 3337            int oid = (int)nid2oid(groups[i], oidCurveType);
 3338            int name = (int)GetCurveByOID(oid);
 3339            if (name == 0) {
 3340                WOLFSSL_MSG("Invalid group name");
 3341                return WOLFSSL_FAILURE;
 3342            }
 3343            _groups[i] = name;
 3344        }
 3345#else
 3346        else {
 3347            WOLFSSL_MSG("Invalid group name");
 3348            return WOLFSSL_FAILURE;
 3349        }
 3350#endif
 3351    }
 3352    return wolfSSL_CTX_set_groups(ctx, _groups, count) == WOLFSSL_SUCCESS ?
 3353            WOLFSSL_SUCCESS : WOLFSSL_FAILURE;
 3354}
 3355
 3356int  wolfSSL_set1_groups(WOLFSSL* ssl, int* groups, int count)
 3357{
 3358    int i;
 3359    int _groups[WOLFSSL_MAX_GROUP_COUNT];
 3360    WOLFSSL_ENTER("wolfSSL_CTX_set1_groups");
 3361    if (count == 0) {
 3362        WOLFSSL_MSG("Group count is zero");
 3363        return WOLFSSL_FAILURE;
 3364    }
 3365    if (count > WOLFSSL_MAX_GROUP_COUNT) {
 3366        WOLFSSL_MSG("Group count exceeds maximum");
 3367        return WOLFSSL_FAILURE;
 3368    }
 3369    for (i = 0; i < count; i++) {
 3370        if (isValidCurveGroup((word16)groups[i])) {
 3371            _groups[i] = groups[i];
 3372        }
 3373#ifdef HAVE_ECC
 3374        else {
 3375            /* groups may be populated with curve NIDs */
 3376            int oid = (int)nid2oid(groups[i], oidCurveType);
 3377            int name = (int)GetCurveByOID(oid);
 3378            if (name == 0) {
 3379                WOLFSSL_MSG("Invalid group name");
 3380                return WOLFSSL_FAILURE;
 3381            }
 3382            _groups[i] = name;
 3383        }
 3384#else
 3385        else {
 3386            WOLFSSL_MSG("Invalid group name");
 3387            return WOLFSSL_FAILURE;
 3388        }
 3389#endif
 3390    }
 3391    return wolfSSL_set_groups(ssl, _groups, count) == WOLFSSL_SUCCESS ?
 3392            WOLFSSL_SUCCESS : WOLFSSL_FAILURE;
 3393}
 3394#endif /* OPENSSL_EXTRA */
 3395#endif /* HAVE_SUPPORTED_CURVES */
 3396
 3397/* Application-Layer Protocol Negotiation */
 3398#ifdef HAVE_ALPN
 3399
 3400WOLFSSL_ABI
 3401int wolfSSL_UseALPN(WOLFSSL* ssl, char *protocol_name_list,
 3402                    word32 protocol_name_listSz, byte options)
 3403{
 3404    char    *list, *ptr = NULL, **token;
 3405    word16  len;
 3406    int     idx = 0;
 3407    int     ret = WC_NO_ERR_TRACE(WOLFSSL_FAILURE);
 3408
 3409    WOLFSSL_ENTER("wolfSSL_UseALPN");
 3410
 3411    if (ssl == NULL || protocol_name_list == NULL)
 3412        return BAD_FUNC_ARG;
 3413
 3414    if (protocol_name_listSz > (WOLFSSL_MAX_ALPN_NUMBER *
 3415                                WOLFSSL_MAX_ALPN_PROTO_NAME_LEN +
 3416                                WOLFSSL_MAX_ALPN_NUMBER)) {
 3417        WOLFSSL_MSG("Invalid arguments, protocol name list too long");
 3418        return BAD_FUNC_ARG;
 3419    }
 3420
 3421    if (!(options & WOLFSSL_ALPN_CONTINUE_ON_MISMATCH) &&
 3422        !(options & WOLFSSL_ALPN_FAILED_ON_MISMATCH)) {
 3423            WOLFSSL_MSG("Invalid arguments, options not supported");
 3424            return BAD_FUNC_ARG;
 3425        }
 3426
 3427
 3428    list = (char *)XMALLOC(protocol_name_listSz+1, ssl->heap,
 3429                           DYNAMIC_TYPE_ALPN);
 3430    if (list == NULL) {
 3431        WOLFSSL_MSG("Memory failure");
 3432        return MEMORY_ERROR;
 3433    }
 3434
 3435    token = (char **)XMALLOC(sizeof(char *) * (WOLFSSL_MAX_ALPN_NUMBER+1),
 3436        ssl->heap, DYNAMIC_TYPE_ALPN);
 3437    if (token == NULL) {
 3438        XFREE(list, ssl->heap, DYNAMIC_TYPE_ALPN);
 3439        WOLFSSL_MSG("Memory failure");
 3440        return MEMORY_ERROR;
 3441    }
 3442    XMEMSET(token, 0, sizeof(char *) * (WOLFSSL_MAX_ALPN_NUMBER+1));
 3443
 3444    XSTRNCPY(list, protocol_name_list, protocol_name_listSz);
 3445    list[protocol_name_listSz] = '\0';
 3446
 3447    /* read all protocol name from the list */
 3448    token[idx] = XSTRTOK(list, ",", &ptr);
 3449    while (idx < WOLFSSL_MAX_ALPN_NUMBER && token[idx] != NULL)
 3450        token[++idx] = XSTRTOK(NULL, ",", &ptr);
 3451
 3452    /* add protocol name list in the TLS extension in reverse order */
 3453    while ((idx--) > 0) {
 3454        len = (word16)XSTRLEN(token[idx]);
 3455
 3456        ret = TLSX_UseALPN(&ssl->extensions, token[idx], len, options,
 3457                                                                     ssl->heap);
 3458        if (ret != WOLFSSL_SUCCESS) {
 3459            WOLFSSL_MSG("TLSX_UseALPN failure");
 3460            break;
 3461        }
 3462    }
 3463
 3464    XFREE(token, ssl->heap, DYNAMIC_TYPE_ALPN);
 3465    XFREE(list, ssl->heap, DYNAMIC_TYPE_ALPN);
 3466
 3467    return ret;
 3468}
 3469
 3470int wolfSSL_ALPN_GetProtocol(WOLFSSL* ssl, char **protocol_name, word16 *size)
 3471{
 3472    return TLSX_ALPN_GetRequest(ssl ? ssl->extensions : NULL,
 3473                               (void **)protocol_name, size);
 3474}
 3475
 3476int wolfSSL_ALPN_GetPeerProtocol(WOLFSSL* ssl, char **list, word16 *listSz)
 3477{
 3478    int i, len;
 3479    char *p;
 3480    byte *s;
 3481
 3482    if (ssl == NULL || list == NULL || listSz == NULL)
 3483        return BAD_FUNC_ARG;
 3484
 3485    if (ssl->alpn_peer_requested == NULL
 3486        || ssl->alpn_peer_requested_length == 0)
 3487        return BUFFER_ERROR;
 3488
 3489    /* ssl->alpn_peer_requested are the original bytes sent in a ClientHello,
 3490     * formatted as (len-byte chars+)+. To turn n protocols into a
 3491     * comma-separated C string, one needs (n-1) commas and a final 0 byte
 3492     * which has the same length as the original.
 3493     * The returned length is the strlen() of the C string, so -1 of that. */
 3494    *listSz = ssl->alpn_peer_requested_length-1;
 3495    *list = p = (char *)XMALLOC(ssl->alpn_peer_requested_length, ssl->heap,
 3496                                DYNAMIC_TYPE_TLSX);
 3497    if (p == NULL)
 3498        return MEMORY_ERROR;
 3499
 3500    for (i = 0, s = ssl->alpn_peer_requested;
 3501         i < ssl->alpn_peer_requested_length;
 3502         p += len, i += len)
 3503    {
 3504        if (i)
 3505            *p++ = ',';
 3506        len = s[i++];
 3507        /* guard against bad length bytes. */
 3508        if (i + len > ssl->alpn_peer_requested_length) {
 3509            XFREE(*list, ssl->heap, DYNAMIC_TYPE_TLSX);
 3510            *list = NULL;
 3511            return WOLFSSL_FAILURE;
 3512        }
 3513        XMEMCPY(p, s + i, (size_t)len);
 3514    }
 3515    *p = 0;
 3516
 3517    return WOLFSSL_SUCCESS;
 3518}
 3519
 3520
 3521/* used to free memory allocated by wolfSSL_ALPN_GetPeerProtocol */
 3522int wolfSSL_ALPN_FreePeerProtocol(WOLFSSL* ssl, char **list)
 3523{
 3524    if (ssl == NULL) {
 3525        return BAD_FUNC_ARG;
 3526    }
 3527
 3528    XFREE(*list, ssl->heap, DYNAMIC_TYPE_TLSX);
 3529    *list = NULL;
 3530
 3531    return WOLFSSL_SUCCESS;
 3532}
 3533
 3534#endif /* HAVE_ALPN */
 3535
 3536/* Secure Renegotiation */
 3537#ifdef HAVE_SERVER_RENEGOTIATION_INFO
 3538
 3539/* user is forcing ability to use secure renegotiation, we discourage it */
 3540int wolfSSL_UseSecureRenegotiation(WOLFSSL* ssl)
 3541{
 3542    int ret = WC_NO_ERR_TRACE(BAD_FUNC_ARG);
 3543#if defined(NO_TLS)
 3544    (void)ssl;
 3545#else
 3546    if (ssl)
 3547        ret = TLSX_UseSecureRenegotiation(&ssl->extensions, ssl->heap);
 3548    else
 3549        ret = BAD_FUNC_ARG;
 3550
 3551    if (ret == WOLFSSL_SUCCESS) {
 3552        TLSX* extension = TLSX_Find(ssl->extensions, TLSX_RENEGOTIATION_INFO);
 3553
 3554        if (extension)
 3555            ssl->secure_renegotiation = (SecureRenegotiation*)extension->data;
 3556    }
 3557#endif /* !NO_TLS */
 3558    return ret;
 3559}
 3560
 3561int wolfSSL_CTX_UseSecureRenegotiation(WOLFSSL_CTX* ctx)
 3562{
 3563    if (ctx == NULL)
 3564        return BAD_FUNC_ARG;
 3565
 3566    ctx->useSecureReneg = 1;
 3567    return WOLFSSL_SUCCESS;
 3568}
 3569
 3570#ifdef HAVE_SECURE_RENEGOTIATION
 3571/* do a secure renegotiation handshake, user forced, we discourage */
 3572static int _Rehandshake(WOLFSSL* ssl)
 3573{
 3574    int ret;
 3575
 3576    if (ssl == NULL)
 3577        return BAD_FUNC_ARG;
 3578
 3579    if (IsAtLeastTLSv1_3(ssl->version)) {
 3580        WOLFSSL_MSG("Secure Renegotiation not supported in TLS 1.3");
 3581        return SECURE_RENEGOTIATION_E;
 3582    }
 3583
 3584    if (ssl->secure_renegotiation == NULL) {
 3585        WOLFSSL_MSG("Secure Renegotiation not forced on by user");
 3586        return SECURE_RENEGOTIATION_E;
 3587    }
 3588
 3589    if (ssl->secure_renegotiation->enabled == 0) {
 3590        WOLFSSL_MSG("Secure Renegotiation not enabled at extension level");
 3591        return SECURE_RENEGOTIATION_E;
 3592    }
 3593
 3594#ifdef WOLFSSL_DTLS
 3595    if (ssl->options.dtls && ssl->keys.dtls_epoch == 0xFFFF) {
 3596        WOLFSSL_MSG("Secure Renegotiation not allowed. Epoch would wrap");
 3597        return SECURE_RENEGOTIATION_E;
 3598    }
 3599#endif
 3600
 3601    /* If the client started the renegotiation, the server will already
 3602     * have processed the client's hello. */
 3603    if (ssl->options.side != WOLFSSL_SERVER_END ||
 3604        ssl->options.acceptState != ACCEPT_FIRST_REPLY_DONE) {
 3605
 3606        if (ssl->options.handShakeState != HANDSHAKE_DONE) {
 3607            if (!ssl->options.handShakeDone) {
 3608                WOLFSSL_MSG("Can't renegotiate until initial "
 3609                            "handshake complete");
 3610                return SECURE_RENEGOTIATION_E;
 3611            }
 3612            else {
 3613                WOLFSSL_MSG("Renegotiation already started. "
 3614                            "Moving it forward.");
 3615                ret = wolfSSL_negotiate(ssl);
 3616                if (ret == WOLFSSL_SUCCESS)
 3617                    ssl->secure_rene_count++;
 3618                return ret;
 3619            }
 3620        }
 3621
 3622        /* reset handshake states */
 3623        ssl->options.sendVerify = 0;
 3624        ssl->options.serverState = NULL_STATE;
 3625        ssl->options.clientState = NULL_STATE;
 3626        ssl->options.connectState  = CONNECT_BEGIN;
 3627        ssl->options.acceptState   = ACCEPT_BEGIN_RENEG;
 3628        ssl->options.handShakeState = NULL_STATE;
 3629        ssl->options.processReply  = 0;  /* TODO, move states in internal.h */
 3630
 3631        XMEMSET(&ssl->msgsReceived, 0, sizeof(ssl->msgsReceived));
 3632
 3633        ssl->secure_renegotiation->cache_status = SCR_CACHE_NEEDED;
 3634
 3635#if !defined(NO_WOLFSSL_SERVER) && !defined(WOLFSSL_NO_TLS12)
 3636        if (ssl->options.side == WOLFSSL_SERVER_END) {
 3637            ret = SendHelloRequest(ssl);
 3638            if (ret != 0) {
 3639                ssl->error = ret;
 3640                return WOLFSSL_FATAL_ERROR;
 3641            }
 3642        }
 3643#endif /* !NO_WOLFSSL_SERVER && !WOLFSSL_NO_TLS12 */
 3644
 3645        ret = InitHandshakeHashes(ssl);
 3646        if (ret != 0) {
 3647            ssl->error = ret;
 3648            return WOLFSSL_FATAL_ERROR;
 3649        }
 3650    }
 3651    ret = wolfSSL_negotiate(ssl);
 3652    if (ret == WOLFSSL_SUCCESS)
 3653        ssl->secure_rene_count++;
 3654    return ret;
 3655}
 3656
 3657
 3658/* do a secure renegotiation handshake, user forced, we discourage */
 3659int wolfSSL_Rehandshake(WOLFSSL* ssl)
 3660{
 3661    int ret;
 3662    WOLFSSL_ENTER("wolfSSL_Rehandshake");
 3663
 3664    if (ssl == NULL)
 3665        return WOLFSSL_FAILURE;
 3666
 3667#ifdef HAVE_SESSION_TICKET
 3668    ret = WOLFSSL_SUCCESS;
 3669#endif
 3670
 3671    if (ssl->options.side == WOLFSSL_SERVER_END) {
 3672        /* Reset option to send certificate verify. */
 3673        ssl->options.sendVerify = 0;
 3674        /* Reset resuming flag to do full secure handshake. */
 3675        ssl->options.resuming = 0;
 3676    }
 3677    else {
 3678        /* Reset resuming flag to do full secure handshake. */
 3679        ssl->options.resuming = 0;
 3680        #if defined(HAVE_SESSION_TICKET) && !defined(NO_WOLFSSL_CLIENT)
 3681            /* Clearing the ticket. */
 3682            ret = wolfSSL_UseSessionTicket(ssl);
 3683        #endif
 3684    }
 3685    /* CLIENT/SERVER: Reset peer authentication for full secure handshake. */
 3686    ssl->options.peerAuthGood = 0;
 3687
 3688#ifdef HAVE_SESSION_TICKET
 3689    if (ret == WOLFSSL_SUCCESS)
 3690#endif
 3691        ret = _Rehandshake(ssl);
 3692
 3693    return ret;
 3694}
 3695
 3696
 3697#ifndef NO_WOLFSSL_CLIENT
 3698
 3699/* do a secure resumption handshake, user forced, we discourage */
 3700int wolfSSL_SecureResume(WOLFSSL* ssl)
 3701{
 3702    WOLFSSL_ENTER("wolfSSL_SecureResume");
 3703
 3704    if (ssl == NULL)
 3705        return BAD_FUNC_ARG;
 3706
 3707    if (ssl->options.side == WOLFSSL_SERVER_END) {
 3708        ssl->error = SIDE_ERROR;
 3709        return WOLFSSL_FATAL_ERROR;
 3710    }
 3711
 3712    return _Rehandshake(ssl);
 3713}
 3714
 3715#endif /* NO_WOLFSSL_CLIENT */
 3716
 3717#endif /* HAVE_SECURE_RENEGOTIATION */
 3718
 3719long wolfSSL_SSL_get_secure_renegotiation_support(WOLFSSL* ssl)
 3720{
 3721    WOLFSSL_ENTER("wolfSSL_SSL_get_secure_renegotiation_support");
 3722
 3723    if (!ssl || !ssl->secure_renegotiation)
 3724        return WOLFSSL_FAILURE;
 3725    return ssl->secure_renegotiation->enabled;
 3726}
 3727
 3728#endif /* HAVE_SECURE_RENEGOTIATION_INFO */
 3729
 3730#if !defined(NO_WOLFSSL_CLIENT) && !defined(WOLFSSL_NO_TLS12) && \
 3731    defined(WOLFSSL_HARDEN_TLS) && !defined(WOLFSSL_HARDEN_TLS_NO_SCR_CHECK)
 3732WOLFSSL_API int wolfSSL_get_scr_check_enabled(const WOLFSSL* ssl)
 3733{
 3734    WOLFSSL_ENTER("wolfSSL_get_scr_check_enabled");
 3735
 3736    if (ssl == NULL)
 3737        return BAD_FUNC_ARG;
 3738
 3739    return ssl->scr_check_enabled;
 3740}
 3741
 3742WOLFSSL_API int wolfSSL_set_scr_check_enabled(WOLFSSL* ssl, byte enabled)
 3743{
 3744    WOLFSSL_ENTER("wolfSSL_set_scr_check_enabled");
 3745
 3746    if (ssl == NULL)
 3747        return BAD_FUNC_ARG;
 3748
 3749    ssl->scr_check_enabled = !!enabled;
 3750    return WOLFSSL_SUCCESS;
 3751}
 3752#endif
 3753
 3754#if defined(HAVE_SESSION_TICKET)
 3755/* Session Ticket */
 3756
 3757#if !defined(NO_WOLFSSL_SERVER)
 3758int wolfSSL_CTX_NoTicketTLSv12(WOLFSSL_CTX* ctx)
 3759{
 3760    if (ctx == NULL)
 3761        return BAD_FUNC_ARG;
 3762
 3763    ctx->noTicketTls12 = 1;
 3764
 3765    return WOLFSSL_SUCCESS;
 3766}
 3767
 3768int wolfSSL_NoTicketTLSv12(WOLFSSL* ssl)
 3769{
 3770    if (ssl == NULL)
 3771        return BAD_FUNC_ARG;
 3772
 3773    ssl->options.noTicketTls12 = 1;
 3774
 3775    return WOLFSSL_SUCCESS;
 3776}
 3777
 3778/* WOLFSSL_SUCCESS on ok */
 3779int wolfSSL_CTX_set_TicketEncCb(WOLFSSL_CTX* ctx, SessionTicketEncCb cb)
 3780{
 3781    if (ctx == NULL)
 3782        return BAD_FUNC_ARG;
 3783
 3784    ctx->ticketEncCb = cb;
 3785
 3786    return WOLFSSL_SUCCESS;
 3787}
 3788
 3789/* set hint interval, WOLFSSL_SUCCESS on ok */
 3790int wolfSSL_CTX_set_TicketHint(WOLFSSL_CTX* ctx, int hint)
 3791{
 3792    if (ctx == NULL)
 3793        return BAD_FUNC_ARG;
 3794
 3795    /* RFC8446 Section 4.6.1: Servers MUST NOT use any value greater than
 3796     * 604800 seconds (7 days). */
 3797    if (hint < 0 || hint > 604800)
 3798        return BAD_FUNC_ARG;
 3799
 3800    ctx->ticketHint = hint;
 3801
 3802    return WOLFSSL_SUCCESS;
 3803}
 3804
 3805/* set user context, WOLFSSL_SUCCESS on ok */
 3806int wolfSSL_CTX_set_TicketEncCtx(WOLFSSL_CTX* ctx, void* userCtx)
 3807{
 3808    if (ctx == NULL)
 3809        return BAD_FUNC_ARG;
 3810
 3811    ctx->ticketEncCtx = userCtx;
 3812
 3813    return WOLFSSL_SUCCESS;
 3814}
 3815
 3816/* get user context - returns userCtx on success, NULL on failure */
 3817void* wolfSSL_CTX_get_TicketEncCtx(WOLFSSL_CTX* ctx)
 3818{
 3819    if (ctx == NULL)
 3820        return NULL;
 3821
 3822    return ctx->ticketEncCtx;
 3823}
 3824
 3825#ifdef WOLFSSL_TLS13
 3826/* set the maximum number of tickets to send
 3827 * return WOLFSSL_SUCCESS on success and WOLFSSL_FAILURE on fail
 3828 */
 3829int wolfSSL_CTX_set_num_tickets(WOLFSSL_CTX* ctx, size_t mxTickets)
 3830{
 3831    if (ctx == NULL)
 3832        return WOLFSSL_FAILURE;
 3833
 3834    ctx->maxTicketTls13 = (unsigned int)mxTickets;
 3835    return WOLFSSL_SUCCESS;
 3836}
 3837
 3838/* get the maximum number of tickets to send
 3839 * return number of tickets set to be sent
 3840 */
 3841size_t wolfSSL_CTX_get_num_tickets(WOLFSSL_CTX* ctx)
 3842{
 3843    if (ctx == NULL)
 3844        return 0;
 3845
 3846    return (size_t)ctx->maxTicketTls13;
 3847}
 3848#endif /* WOLFSSL_TLS13 */
 3849#endif /* !NO_WOLFSSL_SERVER */
 3850
 3851#if !defined(NO_WOLFSSL_CLIENT)
 3852int wolfSSL_UseSessionTicket(WOLFSSL* ssl)
 3853{
 3854    if (ssl == NULL)
 3855        return BAD_FUNC_ARG;
 3856
 3857    return TLSX_UseSessionTicket(&ssl->extensions, NULL, ssl->heap);
 3858}
 3859
 3860int wolfSSL_CTX_UseSessionTicket(WOLFSSL_CTX* ctx)
 3861{
 3862    if (ctx == NULL)
 3863        return BAD_FUNC_ARG;
 3864
 3865    return TLSX_UseSessionTicket(&ctx->extensions, NULL, ctx->heap);
 3866}
 3867
 3868int wolfSSL_get_SessionTicket(WOLFSSL* ssl, byte* buf, word32* bufSz)
 3869{
 3870    if (ssl == NULL || bufSz == NULL)
 3871        return BAD_FUNC_ARG;
 3872
 3873    if (*bufSz == 0 && buf == NULL) {
 3874        *bufSz = ssl->session->ticketLen;
 3875        return LENGTH_ONLY_E;
 3876    }
 3877
 3878    if (buf == NULL)
 3879        return BAD_FUNC_ARG;
 3880
 3881    if (ssl->session->ticketLen <= *bufSz) {
 3882        XMEMCPY(buf, ssl->session->ticket, ssl->session->ticketLen);
 3883        *bufSz = ssl->session->ticketLen;
 3884    }
 3885    else
 3886        *bufSz = 0;
 3887
 3888    return WOLFSSL_SUCCESS;
 3889}
 3890
 3891int wolfSSL_set_SessionTicket(WOLFSSL* ssl, const byte* buf,
 3892                                          word32 bufSz)
 3893{
 3894    if (ssl == NULL || (buf == NULL && bufSz > 0))
 3895        return BAD_FUNC_ARG;
 3896
 3897    if (bufSz > 0) {
 3898        /* Ticket will fit into static ticket */
 3899        if (bufSz <= SESSION_TICKET_LEN) {
 3900            if (ssl->session->ticketLenAlloc > 0) {
 3901                XFREE(ssl->session->ticket, ssl->session->heap,
 3902                      DYNAMIC_TYPE_SESSION_TICK);
 3903                ssl->session->ticketLenAlloc = 0;
 3904                ssl->session->ticket = ssl->session->staticTicket;
 3905            }
 3906        }
 3907        else { /* Ticket requires dynamic ticket storage */
 3908            /* is dyn buffer big enough */
 3909            if (ssl->session->ticketLen < bufSz) {
 3910                if (ssl->session->ticketLenAlloc > 0) {
 3911                    XFREE(ssl->session->ticket, ssl->session->heap,
 3912                          DYNAMIC_TYPE_SESSION_TICK);
 3913                }
 3914                ssl->session->ticket = (byte*)XMALLOC(bufSz, ssl->session->heap,
 3915                        DYNAMIC_TYPE_SESSION_TICK);
 3916                if(ssl->session->ticket == NULL) {
 3917                    ssl->session->ticket = ssl->session->staticTicket;
 3918                    ssl->session->ticketLenAlloc = 0;
 3919                    return MEMORY_ERROR;
 3920                }
 3921                ssl->session->ticketLenAlloc = (word16)bufSz;
 3922            }
 3923        }
 3924        XMEMCPY(ssl->session->ticket, buf, bufSz);
 3925    }
 3926    ssl->session->ticketLen = (word16)bufSz;
 3927
 3928    return WOLFSSL_SUCCESS;
 3929}
 3930
 3931
 3932int wolfSSL_set_SessionTicket_cb(WOLFSSL* ssl,
 3933                                 CallbackSessionTicket cb, void* ctx)
 3934{
 3935    if (ssl == NULL)
 3936        return BAD_FUNC_ARG;
 3937
 3938    ssl->session_ticket_cb = cb;
 3939    ssl->session_ticket_ctx = ctx;
 3940
 3941    return WOLFSSL_SUCCESS;
 3942}
 3943#endif /* !NO_WOLFSSL_CLIENT */
 3944
 3945#endif /* HAVE_SESSION_TICKET */
 3946
 3947
 3948#ifdef HAVE_EXTENDED_MASTER
 3949#ifndef NO_WOLFSSL_CLIENT
 3950
 3951int wolfSSL_CTX_DisableExtendedMasterSecret(WOLFSSL_CTX* ctx)
 3952{
 3953    if (ctx == NULL)
 3954        return BAD_FUNC_ARG;
 3955
 3956    ctx->haveEMS = 0;
 3957
 3958    return WOLFSSL_SUCCESS;
 3959}
 3960
 3961
 3962int wolfSSL_DisableExtendedMasterSecret(WOLFSSL* ssl)
 3963{
 3964    if (ssl == NULL)
 3965        return BAD_FUNC_ARG;
 3966
 3967    ssl->options.haveEMS = 0;
 3968
 3969    return WOLFSSL_SUCCESS;
 3970}
 3971
 3972#endif
 3973#endif
 3974
 3975
 3976#ifndef WOLFSSL_LEANPSK
 3977
 3978int wolfSSL_send(WOLFSSL* ssl, const void* data, int sz, int flags)
 3979{
 3980    int ret;
 3981    int oldFlags;
 3982
 3983    WOLFSSL_ENTER("wolfSSL_send");
 3984
 3985    if (ssl == NULL || data == NULL || sz < 0)
 3986        return BAD_FUNC_ARG;
 3987
 3988    oldFlags = ssl->wflags;
 3989
 3990    ssl->wflags = flags;
 3991    ret = wolfSSL_write(ssl, data, sz);
 3992    ssl->wflags = oldFlags;
 3993
 3994    WOLFSSL_LEAVE("wolfSSL_send", ret);
 3995
 3996    return ret;
 3997}
 3998
 3999
 4000int wolfSSL_recv(WOLFSSL* ssl, void* data, int sz, int flags)
 4001{
 4002    int ret;
 4003    int oldFlags;
 4004
 4005    WOLFSSL_ENTER("wolfSSL_recv");
 4006
 4007    if (ssl == NULL || data == NULL || sz < 0)
 4008        return BAD_FUNC_ARG;
 4009
 4010    oldFlags = ssl->rflags;
 4011
 4012    ssl->rflags = flags;
 4013    ret = wolfSSL_read(ssl, data, sz);
 4014    ssl->rflags = oldFlags;
 4015
 4016    WOLFSSL_LEAVE("wolfSSL_recv", ret);
 4017
 4018    return ret;
 4019}
 4020#endif
 4021
 4022int wolfSSL_SendUserCanceled(WOLFSSL* ssl)
 4023{
 4024    int ret = WC_NO_ERR_TRACE(WOLFSSL_FAILURE);
 4025    WOLFSSL_ENTER("wolfSSL_recv");
 4026
 4027    if (ssl != NULL) {
 4028        ssl->error = SendAlert(ssl, alert_warning, user_canceled);
 4029        if (ssl->error < 0) {
 4030            WOLFSSL_ERROR(ssl->error);
 4031        }
 4032        else {
 4033            ret = wolfSSL_shutdown(ssl);
 4034        }
 4035    }
 4036
 4037    WOLFSSL_LEAVE("wolfSSL_SendUserCanceled", ret);
 4038
 4039    return ret;
 4040}
 4041
 4042/* WOLFSSL_SUCCESS on ok */
 4043WOLFSSL_ABI
 4044int wolfSSL_shutdown(WOLFSSL* ssl)
 4045{
 4046    int ret = WC_NO_ERR_TRACE(WOLFSSL_FATAL_ERROR);
 4047    WOLFSSL_ENTER("wolfSSL_shutdown");
 4048
 4049    if (ssl == NULL)
 4050        return WOLFSSL_FATAL_ERROR;
 4051
 4052    if (ssl->options.quietShutdown) {
 4053        WOLFSSL_MSG("quiet shutdown, no close notify sent");
 4054        ret = WOLFSSL_SUCCESS;
 4055    }
 4056    else {
 4057
 4058        /* Try to flush the buffer first, it might contain the alert */
 4059        if (ssl->error == WC_NO_ERR_TRACE(WANT_WRITE) &&
 4060            ssl->buffers.outputBuffer.length > 0) {
 4061            ret = SendBuffered(ssl);
 4062            if (ret != 0) {
 4063                ssl->error = ret;
 4064                /* for error tracing */
 4065                if (ret != WC_NO_ERR_TRACE(WANT_WRITE))
 4066                    WOLFSSL_ERROR(ret);
 4067                ret = WOLFSSL_FATAL_ERROR;
 4068                WOLFSSL_LEAVE("wolfSSL_shutdown", ret);
 4069                return ret;
 4070            }
 4071
 4072            ssl->error = WOLFSSL_ERROR_NONE;
 4073            /* we succeeded in sending the alert now */
 4074            if (ssl->options.sentNotify)  {
 4075                /* just after we send the alert, if we didn't receive the alert
 4076                 * from the other peer yet, return WOLFSSL_STHUDOWN_NOT_DONE */
 4077                if (!ssl->options.closeNotify) {
 4078                    ret = WOLFSSL_SHUTDOWN_NOT_DONE;
 4079                    WOLFSSL_LEAVE("wolfSSL_shutdown", ret);
 4080                    return ret;
 4081                }
 4082                else {
 4083                    ssl->options.shutdownDone = 1;
 4084                    ret = WOLFSSL_SUCCESS;
 4085                }
 4086            }
 4087        }
 4088
 4089        /* try to send close notify, not an error if can't */
 4090        if (!ssl->options.isClosed && !ssl->options.connReset &&
 4091                                      !ssl->options.sentNotify) {
 4092            ssl->error = SendAlert(ssl, alert_warning, close_notify);
 4093
 4094            /* the alert is now sent or sitting in the buffer,
 4095             * where will be sent eventually */
 4096            if (ssl->error == 0 || ssl->error == WC_NO_ERR_TRACE(WANT_WRITE))
 4097                ssl->options.sentNotify = 1;
 4098
 4099            if (ssl->error < 0) {
 4100                WOLFSSL_ERROR(ssl->error);
 4101                return WOLFSSL_FATAL_ERROR;
 4102            }
 4103
 4104            if (ssl->options.closeNotify) {
 4105                ret = WOLFSSL_SUCCESS;
 4106                ssl->options.shutdownDone = 1;
 4107            }
 4108            else {
 4109                ret = WOLFSSL_SHUTDOWN_NOT_DONE;
 4110                WOLFSSL_LEAVE("wolfSSL_shutdown", ret);
 4111                return ret;
 4112            }
 4113        }
 4114
 4115#ifdef WOLFSSL_SHUTDOWNONCE
 4116        if (ssl->options.isClosed || ssl->options.connReset) {
 4117            /* Shutdown has already occurred.
 4118             * Caller is free to ignore this error. */
 4119            return SSL_SHUTDOWN_ALREADY_DONE_E;
 4120        }
 4121#endif
 4122
 4123        /* wolfSSL_shutdown called again for bidirectional shutdown */
 4124        if (ssl->options.sentNotify && !ssl->options.closeNotify) {
 4125            ret = ProcessReply(ssl);
 4126            if ((ret == WC_NO_ERR_TRACE(ZERO_RETURN)) ||
 4127                (ret == WC_NO_ERR_TRACE(SOCKET_ERROR_E))) {
 4128                /* simulate OpenSSL behavior */
 4129                ssl->options.shutdownDone = 1;
 4130                /* Clear error */
 4131                ssl->error = WOLFSSL_ERROR_NONE;
 4132                ret = WOLFSSL_SUCCESS;
 4133            }
 4134            else if (ret == WC_NO_ERR_TRACE(MEMORY_E)) {
 4135                ret = WOLFSSL_FATAL_ERROR;
 4136            }
 4137            else if (ret == WC_NO_ERR_TRACE(WANT_READ)) {
 4138                ssl->error = ret;
 4139                ret = WOLFSSL_FATAL_ERROR;
 4140            }
 4141            else if (ssl->error == WOLFSSL_ERROR_NONE) {
 4142                ret = WOLFSSL_SHUTDOWN_NOT_DONE;
 4143            }
 4144            else {
 4145                WOLFSSL_ERROR(ssl->error);
 4146                ret = WOLFSSL_FATAL_ERROR;
 4147            }
 4148        }
 4149    }
 4150
 4151#if defined(OPENSSL_EXTRA) || defined(WOLFSSL_WPAS_SMALL)
 4152    /* reset WOLFSSL structure state for possible reuse */
 4153    if (ret == WOLFSSL_SUCCESS) {
 4154        if (wolfSSL_clear(ssl) != WOLFSSL_SUCCESS) {
 4155            WOLFSSL_MSG("could not clear WOLFSSL");
 4156            ret = WOLFSSL_FATAL_ERROR;
 4157        }
 4158    }
 4159#endif
 4160
 4161    WOLFSSL_LEAVE("wolfSSL_shutdown", ret);
 4162
 4163    return ret;
 4164}
 4165#endif /* !NO_TLS */
 4166
 4167/* get current error state value */
 4168int wolfSSL_state(WOLFSSL* ssl)
 4169{
 4170    if (ssl == NULL) {
 4171        return BAD_FUNC_ARG;
 4172    }
 4173
 4174    return ssl->error;
 4175}
 4176
 4177
 4178WOLFSSL_ABI
 4179int wolfSSL_get_error(WOLFSSL* ssl, int ret)
 4180{
 4181    WOLFSSL_ENTER("wolfSSL_get_error");
 4182
 4183    if (ret > 0)
 4184        return WOLFSSL_ERROR_NONE;
 4185    if (ssl == NULL)
 4186        return BAD_FUNC_ARG;
 4187
 4188    WOLFSSL_LEAVE("wolfSSL_get_error", ssl->error);
 4189
 4190    /* make sure converted types are handled in SetErrorString() too */
 4191    if (ssl->error == WC_NO_ERR_TRACE(WANT_READ))
 4192        return WOLFSSL_ERROR_WANT_READ;         /* convert to OpenSSL type */
 4193    else if (ssl->error == WC_NO_ERR_TRACE(WANT_WRITE))
 4194        return WOLFSSL_ERROR_WANT_WRITE;        /* convert to OpenSSL type */
 4195    else if (ssl->error == WC_NO_ERR_TRACE(ZERO_RETURN) ||
 4196             ssl->options.shutdownDone)
 4197        return WOLFSSL_ERROR_ZERO_RETURN;       /* convert to OpenSSL type */
 4198#ifdef OPENSSL_EXTRA
 4199    else if (ssl->error == WC_NO_ERR_TRACE(MATCH_SUITE_ERROR))
 4200        return WOLFSSL_ERROR_SYSCALL;           /* convert to OpenSSL type */
 4201    else if (ssl->error == WC_NO_ERR_TRACE(SOCKET_PEER_CLOSED_E))
 4202        return WOLFSSL_ERROR_SYSCALL;           /* convert to OpenSSL type */
 4203#endif
 4204#ifdef WOLFSSL_ASYNC_CRYPT
 4205    else if (ssl->error == WC_NO_ERR_TRACE(MP_WOULDBLOCK))
 4206        return WC_PENDING_E;                    /* map non-blocking crypto */
 4207#endif
 4208    return ssl->error;
 4209}
 4210
 4211
 4212/* retrieve alert history, WOLFSSL_SUCCESS on ok */
 4213int wolfSSL_get_alert_history(WOLFSSL* ssl, WOLFSSL_ALERT_HISTORY *h)
 4214{
 4215    if (ssl && h) {
 4216        *h = ssl->alert_history;
 4217    }
 4218    return WOLFSSL_SUCCESS;
 4219}
 4220
 4221#ifdef OPENSSL_EXTRA
 4222/* returns SSL_WRITING, SSL_READING or SSL_NOTHING */
 4223int wolfSSL_want(WOLFSSL* ssl)
 4224{
 4225    int rw_state = WOLFSSL_NOTHING;
 4226    if (ssl) {
 4227        if (ssl->error == WC_NO_ERR_TRACE(WANT_READ))
 4228            rw_state = WOLFSSL_READING;
 4229        else if (ssl->error == WC_NO_ERR_TRACE(WANT_WRITE))
 4230            rw_state = WOLFSSL_WRITING;
 4231    }
 4232    return rw_state;
 4233}
 4234#endif
 4235
 4236/* return TRUE if current error is want read */
 4237int wolfSSL_want_read(WOLFSSL* ssl)
 4238{
 4239    WOLFSSL_ENTER("wolfSSL_want_read");
 4240    if (ssl->error == WC_NO_ERR_TRACE(WANT_READ))
 4241        return 1;
 4242
 4243    return 0;
 4244}
 4245
 4246/* return TRUE if current error is want write */
 4247int wolfSSL_want_write(WOLFSSL* ssl)
 4248{
 4249    WOLFSSL_ENTER("wolfSSL_want_write");
 4250    if (ssl->error == WC_NO_ERR_TRACE(WANT_WRITE))
 4251        return 1;
 4252
 4253    return 0;
 4254}
 4255
 4256char* wolfSSL_ERR_error_string(unsigned long errNumber, char* data)
 4257{
 4258    WOLFSSL_ENTER("wolfSSL_ERR_error_string");
 4259    if (data) {
 4260        SetErrorString((int)errNumber, data);
 4261        return data;
 4262    }
 4263    else {
 4264        static char tmp[WOLFSSL_MAX_ERROR_SZ] = {0};
 4265        SetErrorString((int)errNumber, tmp);
 4266        return tmp;
 4267    }
 4268}
 4269
 4270
 4271void wolfSSL_ERR_error_string_n(unsigned long e, char* buf, unsigned long len)
 4272{
 4273    WOLFSSL_ENTER("wolfSSL_ERR_error_string_n");
 4274    if (len >= WOLFSSL_MAX_ERROR_SZ)
 4275        wolfSSL_ERR_error_string(e, buf);
 4276    else {
 4277        WOLFSSL_MSG("Error buffer too short, truncating");
 4278        if (len) {
 4279            char tmp[WOLFSSL_MAX_ERROR_SZ];
 4280            wolfSSL_ERR_error_string(e, tmp);
 4281            XMEMCPY(buf, tmp, len-1);
 4282            buf[len-1] = '\0';
 4283        }
 4284    }
 4285}
 4286
 4287
 4288/* don't free temporary arrays at end of handshake */
 4289void wolfSSL_KeepArrays(WOLFSSL* ssl)
 4290{
 4291    if (ssl)
 4292        ssl->options.saveArrays = 1;
 4293}
 4294
 4295
 4296/* user doesn't need temporary arrays anymore, Free */
 4297void wolfSSL_FreeArrays(WOLFSSL* ssl)
 4298{
 4299    if (ssl && ssl->options.handShakeState == HANDSHAKE_DONE) {
 4300        ssl->options.saveArrays = 0;
 4301        FreeArrays(ssl, 1);
 4302    }
 4303}
 4304
 4305/* Set option to indicate that the resources are not to be freed after
 4306 * handshake.
 4307 *
 4308 * ssl  The SSL/TLS object.
 4309 * returns BAD_FUNC_ARG when ssl is NULL and 0 on success.
 4310 */
 4311int wolfSSL_KeepHandshakeResources(WOLFSSL* ssl)
 4312{
 4313    if (ssl == NULL)
 4314        return BAD_FUNC_ARG;
 4315
 4316    ssl->options.keepResources = 1;
 4317
 4318    return 0;
 4319}
 4320
 4321/* Free the handshake resources after handshake.
 4322 *
 4323 * ssl  The SSL/TLS object.
 4324 * returns BAD_FUNC_ARG when ssl is NULL and 0 on success.
 4325 */
 4326int wolfSSL_FreeHandshakeResources(WOLFSSL* ssl)
 4327{
 4328    if (ssl == NULL)
 4329        return BAD_FUNC_ARG;
 4330
 4331    FreeHandshakeResources(ssl);
 4332
 4333    return 0;
 4334}
 4335
 4336/* Use the client's order of preference when matching cipher suites.
 4337 *
 4338 * ssl  The SSL/TLS context object.
 4339 * returns BAD_FUNC_ARG when ssl is NULL and 0 on success.
 4340 */
 4341int wolfSSL_CTX_UseClientSuites(WOLFSSL_CTX* ctx)
 4342{
 4343    if (ctx == NULL)
 4344        return BAD_FUNC_ARG;
 4345
 4346    ctx->useClientOrder = 1;
 4347
 4348    return 0;
 4349}
 4350
 4351/* Use the client's order of preference when matching cipher suites.
 4352 *
 4353 * ssl  The SSL/TLS object.
 4354 * returns BAD_FUNC_ARG when ssl is NULL and 0 on success.
 4355 */
 4356int wolfSSL_UseClientSuites(WOLFSSL* ssl)
 4357{
 4358    if (ssl == NULL)
 4359        return BAD_FUNC_ARG;
 4360
 4361    ssl->options.useClientOrder = 1;
 4362
 4363    return 0;
 4364}
 4365
 4366#ifdef WOLFSSL_DTLS
 4367const byte* wolfSSL_GetDtlsMacSecret(WOLFSSL* ssl, int verify, int epochOrder)
 4368{
 4369#ifndef WOLFSSL_AEAD_ONLY
 4370    Keys* keys = NULL;
 4371
 4372    (void)epochOrder;
 4373
 4374    if (ssl == NULL)
 4375        return NULL;
 4376
 4377#ifdef HAVE_SECURE_RENEGOTIATION
 4378    switch (epochOrder) {
 4379    case PEER_ORDER:
 4380        if (IsDtlsMsgSCRKeys(ssl))
 4381            keys = &ssl->secure_renegotiation->tmp_keys;
 4382        else
 4383            keys = &ssl->keys;
 4384        break;
 4385    case PREV_ORDER:
 4386        keys = &ssl->keys;
 4387        break;
 4388    case CUR_ORDER:
 4389        if (DtlsUseSCRKeys(ssl))
 4390            keys = &ssl->secure_renegotiation->tmp_keys;
 4391        else
 4392            keys = &ssl->keys;
 4393        break;
 4394    default:
 4395        WOLFSSL_MSG("Unknown epoch order");
 4396        return NULL;
 4397    }
 4398#else
 4399    keys = &ssl->keys;
 4400#endif
 4401
 4402    if ( (ssl->options.side == WOLFSSL_CLIENT_END && !verify) ||
 4403         (ssl->options.side == WOLFSSL_SERVER_END &&  verify) )
 4404        return keys->client_write_MAC_secret;
 4405    else
 4406        return keys->server_write_MAC_secret;
 4407#else
 4408    (void)ssl;
 4409    (void)verify;
 4410    (void)epochOrder;
 4411
 4412    return NULL;
 4413#endif
 4414}
 4415#endif /* WOLFSSL_DTLS */
 4416
 4417const byte* wolfSSL_GetMacSecret(WOLFSSL* ssl, int verify)
 4418{
 4419#ifndef WOLFSSL_AEAD_ONLY
 4420    if (ssl == NULL)
 4421        return NULL;
 4422
 4423    if ( (ssl->options.side == WOLFSSL_CLIENT_END && !verify) ||
 4424         (ssl->options.side == WOLFSSL_SERVER_END &&  verify) )
 4425        return ssl->keys.client_write_MAC_secret;
 4426    else
 4427        return ssl->keys.server_write_MAC_secret;
 4428#else
 4429    (void)ssl;
 4430    (void)verify;
 4431
 4432    return NULL;
 4433#endif
 4434}
 4435
 4436int wolfSSL_GetSide(WOLFSSL* ssl)
 4437{
 4438    if (ssl)
 4439        return ssl->options.side;
 4440
 4441    return BAD_FUNC_ARG;
 4442}
 4443
 4444#ifdef ATOMIC_USER
 4445
 4446void  wolfSSL_CTX_SetMacEncryptCb(WOLFSSL_CTX* ctx, CallbackMacEncrypt cb)
 4447{
 4448    if (ctx)
 4449        ctx->MacEncryptCb = cb;
 4450}
 4451
 4452
 4453void  wolfSSL_SetMacEncryptCtx(WOLFSSL* ssl, void *ctx)
 4454{
 4455    if (ssl)
 4456        ssl->MacEncryptCtx = ctx;
 4457}
 4458
 4459
 4460void* wolfSSL_GetMacEncryptCtx(WOLFSSL* ssl)
 4461{
 4462    if (ssl)
 4463        return ssl->MacEncryptCtx;
 4464
 4465    return NULL;
 4466}
 4467
 4468
 4469void  wolfSSL_CTX_SetDecryptVerifyCb(WOLFSSL_CTX* ctx, CallbackDecryptVerify cb)
 4470{
 4471    if (ctx)
 4472        ctx->DecryptVerifyCb = cb;
 4473}
 4474
 4475
 4476void  wolfSSL_SetDecryptVerifyCtx(WOLFSSL* ssl, void *ctx)
 4477{
 4478    if (ssl)
 4479        ssl->DecryptVerifyCtx = ctx;
 4480}
 4481
 4482
 4483void* wolfSSL_GetDecryptVerifyCtx(WOLFSSL* ssl)
 4484{
 4485    if (ssl)
 4486        return ssl->DecryptVerifyCtx;
 4487
 4488    return NULL;
 4489}
 4490
 4491#if defined(HAVE_ENCRYPT_THEN_MAC) && !defined(WOLFSSL_AEAD_ONLY)
 4492/**
 4493 * Set the callback, against the context, that encrypts then MACs.
 4494 *
 4495 * ctx  SSL/TLS context.
 4496 * cb   Callback function to use with Encrypt-Then-MAC.
 4497 */
 4498void  wolfSSL_CTX_SetEncryptMacCb(WOLFSSL_CTX* ctx, CallbackEncryptMac cb)
 4499{
 4500    if (ctx)
 4501        ctx->EncryptMacCb = cb;
 4502}
 4503
 4504/**
 4505 * Set the context to use with callback that encrypts then MACs.
 4506 *
 4507 * ssl  SSL/TLS object.
 4508 * ctx  Callback function's context.
 4509 */
 4510void  wolfSSL_SetEncryptMacCtx(WOLFSSL* ssl, void *ctx)
 4511{
 4512    if (ssl)
 4513        ssl->EncryptMacCtx = ctx;
 4514}
 4515
 4516/**
 4517 * Get the context being used with callback that encrypts then MACs.
 4518 *
 4519 * ssl  SSL/TLS object.
 4520 * returns callback function's context or NULL if SSL/TLS object is NULL.
 4521 */
 4522void* wolfSSL_GetEncryptMacCtx(WOLFSSL* ssl)
 4523{
 4524    if (ssl)
 4525        return ssl->EncryptMacCtx;
 4526
 4527    return NULL;
 4528}
 4529
 4530
 4531/**
 4532 * Set the callback, against the context, that MAC verifies then decrypts.
 4533 *
 4534 * ctx  SSL/TLS context.
 4535 * cb   Callback function to use with Encrypt-Then-MAC.
 4536 */
 4537void  wolfSSL_CTX_SetVerifyDecryptCb(WOLFSSL_CTX* ctx, CallbackVerifyDecrypt cb)
 4538{
 4539    if (ctx)
 4540        ctx->VerifyDecryptCb = cb;
 4541}
 4542
 4543/**
 4544 * Set the context to use with callback that MAC verifies then decrypts.
 4545 *
 4546 * ssl  SSL/TLS object.
 4547 * ctx  Callback function's context.
 4548 */
 4549void  wolfSSL_SetVerifyDecryptCtx(WOLFSSL* ssl, void *ctx)
 4550{
 4551    if (ssl)
 4552        ssl->VerifyDecryptCtx = ctx;
 4553}
 4554
 4555/**
 4556 * Get the context being used with callback that MAC verifies then decrypts.
 4557 *
 4558 * ssl  SSL/TLS object.
 4559 * returns callback function's context or NULL if SSL/TLS object is NULL.
 4560 */
 4561void* wolfSSL_GetVerifyDecryptCtx(WOLFSSL* ssl)
 4562{
 4563    if (ssl)
 4564        return ssl->VerifyDecryptCtx;
 4565
 4566    return NULL;
 4567}
 4568#endif /* HAVE_ENCRYPT_THEN_MAC !WOLFSSL_AEAD_ONLY */
 4569
 4570
 4571
 4572const byte* wolfSSL_GetClientWriteKey(WOLFSSL* ssl)
 4573{
 4574    if (ssl)
 4575        return ssl->keys.client_write_key;
 4576
 4577    return NULL;
 4578}
 4579
 4580
 4581const byte* wolfSSL_GetClientWriteIV(WOLFSSL* ssl)
 4582{
 4583    if (ssl)
 4584        return ssl->keys.client_write_IV;
 4585
 4586    return NULL;
 4587}
 4588
 4589
 4590const byte* wolfSSL_GetServerWriteKey(WOLFSSL* ssl)
 4591{
 4592    if (ssl)
 4593        return ssl->keys.server_write_key;
 4594
 4595    return NULL;
 4596}
 4597
 4598
 4599const byte* wolfSSL_GetServerWriteIV(WOLFSSL* ssl)
 4600{
 4601    if (ssl)
 4602        return ssl->keys.server_write_IV;
 4603
 4604    return NULL;
 4605}
 4606
 4607int wolfSSL_GetKeySize(WOLFSSL* ssl)
 4608{
 4609    if (ssl)
 4610        return ssl->specs.key_size;
 4611
 4612    return BAD_FUNC_ARG;
 4613}
 4614
 4615
 4616int wolfSSL_GetIVSize(WOLFSSL* ssl)
 4617{
 4618    if (ssl)
 4619        return ssl->specs.iv_size;
 4620
 4621    return BAD_FUNC_ARG;
 4622}
 4623
 4624
 4625int wolfSSL_GetBulkCipher(WOLFSSL* ssl)
 4626{
 4627    if (ssl)
 4628        return ssl->specs.bulk_cipher_algorithm;
 4629
 4630    return BAD_FUNC_ARG;
 4631}
 4632
 4633
 4634int wolfSSL_GetCipherType(WOLFSSL* ssl)
 4635{
 4636    if (ssl == NULL)
 4637        return BAD_FUNC_ARG;
 4638
 4639#ifndef WOLFSSL_AEAD_ONLY
 4640    if (ssl->specs.cipher_type == block)
 4641        return WOLFSSL_BLOCK_TYPE;
 4642    if (ssl->specs.cipher_type == stream)
 4643        return WOLFSSL_STREAM_TYPE;
 4644#endif
 4645    if (ssl->specs.cipher_type == aead)
 4646        return WOLFSSL_AEAD_TYPE;
 4647
 4648    return WOLFSSL_FATAL_ERROR;
 4649}
 4650
 4651
 4652int wolfSSL_GetCipherBlockSize(WOLFSSL* ssl)
 4653{
 4654    if (ssl == NULL)
 4655        return BAD_FUNC_ARG;
 4656
 4657    return ssl->specs.block_size;
 4658}
 4659
 4660
 4661int wolfSSL_GetAeadMacSize(WOLFSSL* ssl)
 4662{
 4663    if (ssl == NULL)
 4664        return BAD_FUNC_ARG;
 4665
 4666    return ssl->specs.aead_mac_size;
 4667}
 4668
 4669
 4670int wolfSSL_IsTLSv1_1(WOLFSSL* ssl)
 4671{
 4672    if (ssl == NULL)
 4673        return BAD_FUNC_ARG;
 4674
 4675    if (ssl->options.tls1_1)
 4676        return 1;
 4677
 4678    return 0;
 4679}
 4680
 4681
 4682
 4683int wolfSSL_GetHmacSize(WOLFSSL* ssl)
 4684{
 4685    /* AEAD ciphers don't have HMAC keys */
 4686    if (ssl)
 4687        return (ssl->specs.cipher_type != aead) ? ssl->specs.hash_size : 0;
 4688
 4689    return BAD_FUNC_ARG;
 4690}
 4691
 4692#ifdef WORD64_AVAILABLE
 4693int wolfSSL_GetPeerSequenceNumber(WOLFSSL* ssl, word64 *seq)
 4694{
 4695    if ((ssl == NULL) || (seq == NULL))
 4696        return BAD_FUNC_ARG;
 4697
 4698    *seq = ((word64)ssl->keys.peer_sequence_number_hi << 32) |
 4699                    ssl->keys.peer_sequence_number_lo;
 4700    return !(*seq);
 4701}
 4702
 4703int wolfSSL_GetSequenceNumber(WOLFSSL* ssl, word64 *seq)
 4704{
 4705    if ((ssl == NULL) || (seq == NULL))
 4706        return BAD_FUNC_ARG;
 4707
 4708    *seq = ((word64)ssl->keys.sequence_number_hi << 32) |
 4709                    ssl->keys.sequence_number_lo;
 4710    return !(*seq);
 4711}
 4712#endif
 4713
 4714#endif /* ATOMIC_USER */
 4715
 4716#if !defined(NO_FILESYSTEM) && !defined(NO_STDIO_FILESYSTEM) \
 4717    && defined(XFPRINTF)
 4718
 4719void wolfSSL_ERR_print_errors_fp(XFILE fp, int err)
 4720{
 4721    char data[WOLFSSL_MAX_ERROR_SZ + 1];
 4722
 4723    WOLFSSL_ENTER("wolfSSL_ERR_print_errors_fp");
 4724    SetErrorString(err, data);
 4725    if (XFPRINTF(fp, "%s", data) < 0)
 4726        WOLFSSL_MSG("fprintf failed in wolfSSL_ERR_print_errors_fp");
 4727}
 4728
 4729#if defined(OPENSSL_EXTRA) || defined(DEBUG_WOLFSSL_VERBOSE)
 4730void wolfSSL_ERR_dump_errors_fp(XFILE fp)
 4731{
 4732    wc_ERR_print_errors_fp(fp);
 4733}
 4734
 4735void wolfSSL_ERR_print_errors_cb (int (*cb)(const char *str, size_t len,
 4736                                            void *u), void *u)
 4737{
 4738    wc_ERR_print_errors_cb(cb, u);
 4739}
 4740#endif
 4741#endif /* !NO_FILESYSTEM && !NO_STDIO_FILESYSTEM && XFPRINTF */
 4742
 4743/*
 4744 * TODO This ssl parameter needs to be changed to const once our ABI checker
 4745 *      stops flagging qualifier additions as ABI breaking.
 4746 */
 4747WOLFSSL_ABI
 4748int wolfSSL_pending(WOLFSSL* ssl)
 4749{
 4750    WOLFSSL_ENTER("wolfSSL_pending");
 4751    if (ssl == NULL)
 4752        return WOLFSSL_FAILURE;
 4753
 4754    return (int)ssl->buffers.clearOutputBuffer.length;
 4755}
 4756
 4757int wolfSSL_has_pending(const WOLFSSL* ssl)
 4758{
 4759    WOLFSSL_ENTER("wolfSSL_has_pending");
 4760    if (ssl == NULL)
 4761        return WOLFSSL_FAILURE;
 4762
 4763    return ssl->buffers.clearOutputBuffer.length > 0;
 4764}
 4765
 4766#ifndef WOLFSSL_LEANPSK
 4767/* turn on handshake group messages for context */
 4768int wolfSSL_CTX_set_group_messages(WOLFSSL_CTX* ctx)
 4769{
 4770    if (ctx == NULL)
 4771       return BAD_FUNC_ARG;
 4772
 4773    ctx->groupMessages = 1;
 4774
 4775    return WOLFSSL_SUCCESS;
 4776}
 4777
 4778int wolfSSL_CTX_clear_group_messages(WOLFSSL_CTX* ctx)
 4779{
 4780    if (ctx == NULL)
 4781       return BAD_FUNC_ARG;
 4782
 4783    ctx->groupMessages = 0;
 4784
 4785    return WOLFSSL_SUCCESS;
 4786}
 4787#endif
 4788
 4789
 4790#if !defined(NO_WOLFSSL_CLIENT) && !defined(NO_TLS)
 4791/* connect enough to get peer cert chain */
 4792int wolfSSL_connect_cert(WOLFSSL* ssl)
 4793{
 4794    int  ret;
 4795
 4796    if (ssl == NULL)
 4797        return WOLFSSL_FAILURE;
 4798
 4799    ssl->options.certOnly = 1;
 4800    ret = wolfSSL_connect(ssl);
 4801    ssl->options.certOnly   = 0;
 4802
 4803    return ret;
 4804}
 4805#endif
 4806
 4807
 4808#ifndef WOLFSSL_LEANPSK
 4809/* turn on handshake group messages for ssl object */
 4810int wolfSSL_set_group_messages(WOLFSSL* ssl)
 4811{
 4812    if (ssl == NULL)
 4813       return BAD_FUNC_ARG;
 4814
 4815    ssl->options.groupMessages = 1;
 4816
 4817    return WOLFSSL_SUCCESS;
 4818}
 4819
 4820int wolfSSL_clear_group_messages(WOLFSSL* ssl)
 4821{
 4822    if (ssl == NULL)
 4823       return BAD_FUNC_ARG;
 4824
 4825    ssl->options.groupMessages = 0;
 4826
 4827    return WOLFSSL_SUCCESS;
 4828}
 4829
 4830/* make minVersion the internal equivalent SSL version */
 4831static int SetMinVersionHelper(byte* minVersion, int version)
 4832{
 4833    (void)minVersion;
 4834
 4835    switch (version) {
 4836#if defined(WOLFSSL_ALLOW_SSLV3) && !defined(NO_OLD_TLS)
 4837        case WOLFSSL_SSLV3:
 4838            *minVersion = SSLv3_MINOR;
 4839            break;
 4840#endif
 4841
 4842#ifndef NO_TLS
 4843    #ifndef NO_OLD_TLS
 4844        #ifdef WOLFSSL_ALLOW_TLSV10
 4845        case WOLFSSL_TLSV1:
 4846            *minVersion = TLSv1_MINOR;
 4847            break;
 4848        #endif
 4849
 4850        case WOLFSSL_TLSV1_1:
 4851            *minVersion = TLSv1_1_MINOR;
 4852            break;
 4853    #endif
 4854    #ifndef WOLFSSL_NO_TLS12
 4855        case WOLFSSL_TLSV1_2:
 4856            *minVersion = TLSv1_2_MINOR;
 4857            break;
 4858    #endif
 4859#endif
 4860    #ifdef WOLFSSL_TLS13
 4861        case WOLFSSL_TLSV1_3:
 4862            *minVersion = TLSv1_3_MINOR;
 4863            break;
 4864    #endif
 4865
 4866#ifdef WOLFSSL_DTLS
 4867        case WOLFSSL_DTLSV1:
 4868            *minVersion = DTLS_MINOR;
 4869            break;
 4870        case WOLFSSL_DTLSV1_2:
 4871            *minVersion = DTLSv1_2_MINOR;
 4872            break;
 4873#ifdef WOLFSSL_DTLS13
 4874        case WOLFSSL_DTLSV1_3:
 4875            *minVersion = DTLSv1_3_MINOR;
 4876            break;
 4877#endif /* WOLFSSL_DTLS13 */
 4878#endif /* WOLFSSL_DTLS */
 4879
 4880        default:
 4881            WOLFSSL_MSG("Bad function argument");
 4882            return BAD_FUNC_ARG;
 4883    }
 4884
 4885    return WOLFSSL_SUCCESS;
 4886}
 4887
 4888
 4889/* Set minimum downgrade version allowed, WOLFSSL_SUCCESS on ok */
 4890WOLFSSL_ABI
 4891int wolfSSL_CTX_SetMinVersion(WOLFSSL_CTX* ctx, int version)
 4892{
 4893    WOLFSSL_ENTER("wolfSSL_CTX_SetMinVersion");
 4894
 4895    if (ctx == NULL) {
 4896        WOLFSSL_MSG("Bad function argument");
 4897        return BAD_FUNC_ARG;
 4898    }
 4899
 4900#if defined(WOLFSSL_SYS_CRYPTO_POLICY)
 4901    if (crypto_policy.enabled) {
 4902        return CRYPTO_POLICY_FORBIDDEN;
 4903    }
 4904#endif /* WOLFSSL_SYS_CRYPTO_POLICY */
 4905
 4906    return SetMinVersionHelper(&ctx->minDowngrade, version);
 4907}
 4908
 4909
 4910/* Set minimum downgrade version allowed, WOLFSSL_SUCCESS on ok */
 4911int wolfSSL_SetMinVersion(WOLFSSL* ssl, int version)
 4912{
 4913    WOLFSSL_ENTER("wolfSSL_SetMinVersion");
 4914
 4915    if (ssl == NULL) {
 4916        WOLFSSL_MSG("Bad function argument");
 4917        return BAD_FUNC_ARG;
 4918    }
 4919
 4920#if defined(WOLFSSL_SYS_CRYPTO_POLICY)
 4921    if (crypto_policy.enabled) {
 4922        return CRYPTO_POLICY_FORBIDDEN;
 4923    }
 4924#endif /* WOLFSSL_SYS_CRYPTO_POLICY */
 4925
 4926    return SetMinVersionHelper(&ssl->options.minDowngrade, version);
 4927}
 4928
 4929
 4930/* Function to get version as WOLFSSL_ enum value for wolfSSL_SetVersion */
 4931int wolfSSL_GetVersion(const WOLFSSL* ssl)
 4932{
 4933    if (ssl == NULL)
 4934        return BAD_FUNC_ARG;
 4935
 4936    if (ssl->version.major == SSLv3_MAJOR) {
 4937        switch (ssl->version.minor) {
 4938            case SSLv3_MINOR :
 4939                return WOLFSSL_SSLV3;
 4940            case TLSv1_MINOR :
 4941                return WOLFSSL_TLSV1;
 4942            case TLSv1_1_MINOR :
 4943                return WOLFSSL_TLSV1_1;
 4944            case TLSv1_2_MINOR :
 4945                return WOLFSSL_TLSV1_2;
 4946            case TLSv1_3_MINOR :
 4947                return WOLFSSL_TLSV1_3;
 4948            default:
 4949                break;
 4950        }
 4951    }
 4952#ifdef WOLFSSL_DTLS
 4953    if (ssl->version.major == DTLS_MAJOR) {
 4954        switch (ssl->version.minor) {
 4955            case DTLS_MINOR :
 4956                return WOLFSSL_DTLSV1;
 4957            case DTLSv1_2_MINOR :
 4958                return WOLFSSL_DTLSV1_2;
 4959            case DTLSv1_3_MINOR :
 4960                return WOLFSSL_DTLSV1_3;
 4961            default:
 4962                break;
 4963        }
 4964    }
 4965#endif /* WOLFSSL_DTLS */
 4966
 4967    return VERSION_ERROR;
 4968}
 4969
 4970int wolfSSL_SetVersion(WOLFSSL* ssl, int version)
 4971{
 4972    word16 haveRSA = 1;
 4973    word16 havePSK = 0;
 4974    int    keySz   = 0;
 4975
 4976    WOLFSSL_ENTER("wolfSSL_SetVersion");
 4977
 4978    if (ssl == NULL) {
 4979        WOLFSSL_MSG("Bad function argument");
 4980        return BAD_FUNC_ARG;
 4981    }
 4982
 4983    switch (version) {
 4984#if defined(WOLFSSL_ALLOW_SSLV3) && !defined(NO_OLD_TLS)
 4985        case WOLFSSL_SSLV3:
 4986            ssl->version = MakeSSLv3();
 4987            break;
 4988#endif
 4989
 4990#ifndef NO_TLS
 4991    #ifndef NO_OLD_TLS
 4992        #ifdef WOLFSSL_ALLOW_TLSV10
 4993        case WOLFSSL_TLSV1:
 4994            ssl->version = MakeTLSv1();
 4995            break;
 4996        #endif
 4997
 4998        case WOLFSSL_TLSV1_1:
 4999            ssl->version = MakeTLSv1_1();
 5000            break;
 5001    #endif
 5002    #ifndef WOLFSSL_NO_TLS12
 5003        case WOLFSSL_TLSV1_2:
 5004            ssl->version = MakeTLSv1_2();
 5005            break;
 5006    #endif
 5007
 5008    #ifdef WOLFSSL_TLS13
 5009        case WOLFSSL_TLSV1_3:
 5010            ssl->version = MakeTLSv1_3();
 5011            break;
 5012    #endif /* WOLFSSL_TLS13 */
 5013#endif
 5014
 5015        default:
 5016            WOLFSSL_MSG("Bad function argument");
 5017            return BAD_FUNC_ARG;
 5018    }
 5019
 5020    ssl->options.downgrade = 0;
 5021
 5022    #ifdef NO_RSA
 5023        haveRSA = 0;
 5024    #endif
 5025    #ifndef NO_PSK
 5026        havePSK = ssl->options.havePSK;
 5027    #endif
 5028    #ifndef NO_CERTS
 5029        keySz = ssl->buffers.keySz;
 5030    #endif
 5031
 5032    if (AllocateSuites(ssl) != 0)
 5033        return WOLFSSL_FAILURE;
 5034    InitSuites(ssl->suites, ssl->version, keySz, haveRSA, havePSK,
 5035               ssl->options.haveDH, ssl->options.haveECDSAsig,
 5036               ssl->options.haveECC, TRUE, ssl->options.haveStaticECC,
 5037               ssl->options.useAnon, TRUE, TRUE, TRUE, TRUE, ssl->options.side);
 5038    return WOLFSSL_SUCCESS;
 5039}
 5040#endif /* !leanpsk */
 5041
 5042#if defined(OPENSSL_EXTRA) && !defined(WOLFSSL_NO_OPENSSL_RAND_CB)
 5043static int wolfSSL_RAND_InitMutex(void);
 5044#endif
 5045
 5046/* If we don't have static mutex initializers, but we do have static atomic
 5047 * initializers, activate WOLFSSL_CLEANUP_THREADSAFE_BY_ATOMIC_OPS to leverage
 5048 * the latter.
 5049 *
 5050 * See further explanation below in wolfSSL_Init().
 5051 */
 5052#ifndef WOLFSSL_CLEANUP_THREADSAFE_BY_ATOMIC_OPS
 5053    #if !defined(WOLFSSL_MUTEX_INITIALIZER) && !defined(SINGLE_THREADED) && \
 5054            defined(WOLFSSL_ATOMIC_OPS) && defined(WOLFSSL_ATOMIC_INITIALIZER)
 5055        #define WOLFSSL_CLEANUP_THREADSAFE_BY_ATOMIC_OPS 1
 5056    #else
 5057        #define WOLFSSL_CLEANUP_THREADSAFE_BY_ATOMIC_OPS 0
 5058    #endif
 5059#elif defined(WOLFSSL_MUTEX_INITIALIZER) || defined(SINGLE_THREADED)
 5060    #undef WOLFSSL_CLEANUP_THREADSAFE_BY_ATOMIC_OPS
 5061    #define WOLFSSL_CLEANUP_THREADSAFE_BY_ATOMIC_OPS 0
 5062#endif
 5063
 5064#if WOLFSSL_CLEANUP_THREADSAFE_BY_ATOMIC_OPS
 5065    #ifndef WOLFSSL_ATOMIC_OPS
 5066        #error WOLFSSL_CLEANUP_THREADSAFE_BY_ATOMIC_OPS requires WOLFSSL_ATOMIC_OPS
 5067    #endif
 5068    #ifndef WOLFSSL_ATOMIC_INITIALIZER
 5069        #error WOLFSSL_CLEANUP_THREADSAFE_BY_ATOMIC_OPS requires WOLFSSL_ATOMIC_INITIALIZER
 5070    #endif
 5071    static wolfSSL_Atomic_Int inits_count_mutex_atomic_initing_flag =
 5072        WOLFSSL_ATOMIC_INITIALIZER(0);
 5073#endif /* WOLFSSL_CLEANUP_THREADSAFE_BY_ATOMIC_OPS && !WOLFSSL_MUTEX_INITIALIZER */
 5074
 5075#if defined(OPENSSL_EXTRA) && defined(HAVE_ATEXIT)
 5076static void AtExitCleanup(void)
 5077{
 5078    if (initRefCount > 0) {
 5079        initRefCount = 1;
 5080        (void)wolfSSL_Cleanup();
 5081#if WOLFSSL_CLEANUP_THREADSAFE_BY_ATOMIC_OPS
 5082        if (inits_count_mutex_valid == 1) {
 5083            (void)wc_FreeMutex(&inits_count_mutex);
 5084            inits_count_mutex_valid = 0;
 5085            inits_count_mutex_atomic_initing_flag = 0;
 5086        }
 5087#endif
 5088    }
 5089}
 5090#endif
 5091
 5092WOLFSSL_ABI
 5093int wolfSSL_Init(void)
 5094{
 5095    int ret = WOLFSSL_SUCCESS;
 5096#if !defined(NO_SESSION_CACHE) && defined(ENABLE_SESSION_CACHE_ROW_LOCK)
 5097    int i;
 5098#endif
 5099
 5100    WOLFSSL_ENTER("wolfSSL_Init");
 5101
 5102#if defined(LIBWOLFSSL_CMAKE_OUTPUT)
 5103    WOLFSSL_MSG(LIBWOLFSSL_CMAKE_OUTPUT);
 5104#else
 5105    WOLFSSL_MSG("No extra wolfSSL cmake messages found");
 5106#endif
 5107
 5108#ifndef WOLFSSL_MUTEX_INITIALIZER
 5109    if (inits_count_mutex_valid == 0) {
 5110    #if WOLFSSL_CLEANUP_THREADSAFE_BY_ATOMIC_OPS
 5111
 5112        /* Without this mitigation, if two threads enter wolfSSL_Init() at the
 5113         * same time, and both see zero inits_count_mutex_valid, then both will
 5114         * run wc_InitMutex(&inits_count_mutex), leading to process corruption
 5115         * or (best case) a resource leak.
 5116         *
 5117         * When WOLFSSL_ATOMIC_INITIALIZER() is available, we can mitigate this
 5118         * by use an atomic counting int as a mutex.
 5119         */
 5120
 5121        if (wolfSSL_Atomic_Int_FetchAdd(&inits_count_mutex_atomic_initing_flag,
 5122                                        1) != 0)
 5123        {
 5124            (void)wolfSSL_Atomic_Int_FetchSub(
 5125                &inits_count_mutex_atomic_initing_flag, 1);
 5126            return DEADLOCK_AVERTED_E;
 5127        }
 5128    #endif /* WOLFSSL_CLEANUP_THREADSAFE_BY_ATOMIC_OPS */
 5129        if (wc_InitMutex(&inits_count_mutex) != 0) {
 5130            WOLFSSL_MSG("Bad Init Mutex count");
 5131    #if WOLFSSL_CLEANUP_THREADSAFE_BY_ATOMIC_OPS
 5132            (void)wolfSSL_Atomic_Int_FetchSub(
 5133                &inits_count_mutex_atomic_initing_flag, 1);
 5134    #endif
 5135            return BAD_MUTEX_E;
 5136        }
 5137        else {
 5138            inits_count_mutex_valid = 1;
 5139        }
 5140    }
 5141#endif /* !WOLFSSL_MUTEX_INITIALIZER */
 5142
 5143    if (wc_LockMutex(&inits_count_mutex) != 0) {
 5144        WOLFSSL_MSG("Bad Lock Mutex count");
 5145        return BAD_MUTEX_E;
 5146    }
 5147
 5148#if FIPS_VERSION_GE(5,1)
 5149    if ((ret == WOLFSSL_SUCCESS) && (initRefCount == 0)) {
 5150        ret = wolfCrypt_SetPrivateKeyReadEnable_fips(1, WC_KEYTYPE_ALL);
 5151        if (ret == 0)
 5152            ret = WOLFSSL_SUCCESS;
 5153    }
 5154#endif
 5155
 5156    if ((ret == WOLFSSL_SUCCESS) && (initRefCount == 0)) {
 5157        /* Initialize crypto for use with TLS connection */
 5158
 5159        if (wolfCrypt_Init() != 0) {
 5160            WOLFSSL_MSG("Bad wolfCrypt Init");
 5161            ret = WC_INIT_E;
 5162        }
 5163
 5164#if defined(HAVE_GLOBAL_RNG) && !defined(WOLFSSL_MUTEX_INITIALIZER)
 5165        if (ret == WOLFSSL_SUCCESS) {
 5166            if (wc_InitMutex(&globalRNGMutex) != 0) {
 5167                WOLFSSL_MSG("Bad Init Mutex rng");
 5168                ret = BAD_MUTEX_E;
 5169            }
 5170            else {
 5171                globalRNGMutex_valid = 1;
 5172            }
 5173        }
 5174#endif
 5175
 5176    #ifdef WC_RNG_SEED_CB
 5177        wc_SetSeed_Cb(WC_GENERATE_SEED_DEFAULT);
 5178    #endif
 5179
 5180#ifdef OPENSSL_EXTRA
 5181    #ifndef WOLFSSL_NO_OPENSSL_RAND_CB
 5182        if ((ret == WOLFSSL_SUCCESS) && (wolfSSL_RAND_InitMutex() != 0)) {
 5183            ret = BAD_MUTEX_E;
 5184        }
 5185    #endif
 5186        if ((ret == WOLFSSL_SUCCESS) &&
 5187            (wolfSSL_RAND_seed(NULL, 0) != WOLFSSL_SUCCESS)) {
 5188            WOLFSSL_MSG("wolfSSL_RAND_seed failed");
 5189            ret = WC_INIT_E;
 5190        }
 5191#endif
 5192
 5193#ifndef NO_SESSION_CACHE
 5194    #ifdef ENABLE_SESSION_CACHE_ROW_LOCK
 5195        for (i = 0; i < SESSION_ROWS; ++i) {
 5196            SessionCache[i].lock_valid = 0;
 5197        }
 5198        for (i = 0; (ret == WOLFSSL_SUCCESS) && (i < SESSION_ROWS); ++i) {
 5199            if (wc_InitRwLock(&SessionCache[i].row_lock) != 0) {
 5200                WOLFSSL_MSG("Bad Init Mutex session");
 5201                ret = BAD_MUTEX_E;
 5202            }
 5203            else {
 5204                SessionCache[i].lock_valid = 1;
 5205            }
 5206        }
 5207    #else
 5208        if (ret == WOLFSSL_SUCCESS) {
 5209            if (wc_InitRwLock(&session_lock) != 0) {
 5210                WOLFSSL_MSG("Bad Init Mutex session");
 5211                ret = BAD_MUTEX_E;
 5212            }
 5213            else {
 5214                session_lock_valid = 1;
 5215            }
 5216        }
 5217    #endif
 5218    #ifndef NO_CLIENT_CACHE
 5219        #ifndef WOLFSSL_MUTEX_INITIALIZER
 5220        if (ret == WOLFSSL_SUCCESS) {
 5221            if (wc_InitMutex(&clisession_mutex) != 0) {
 5222                WOLFSSL_MSG("Bad Init Mutex session");
 5223                ret = BAD_MUTEX_E;
 5224            }
 5225            else {
 5226                clisession_mutex_valid = 1;
 5227            }
 5228        }
 5229        #endif
 5230    #endif
 5231#endif
 5232#if defined(OPENSSL_EXTRA) && defined(HAVE_ATEXIT)
 5233        /* OpenSSL registers cleanup using atexit */
 5234        if ((ret == WOLFSSL_SUCCESS) && (atexit(AtExitCleanup) != 0)) {
 5235            WOLFSSL_MSG("Bad atexit registration");
 5236            ret = WC_INIT_E;
 5237        }
 5238#endif
 5239    }
 5240
 5241#if defined(WOLFSSL_SYS_CRYPTO_POLICY)
 5242    /* System wide crypto policy disabled by default. */
 5243    XMEMSET(&crypto_policy, 0, sizeof(crypto_policy));
 5244#endif /* WOLFSSL_SYS_CRYPTO_POLICY */
 5245
 5246    if (ret == WOLFSSL_SUCCESS) {
 5247        initRefCount = initRefCount + 1;
 5248    }
 5249    else {
 5250        initRefCount = 1; /* Force cleanup */
 5251    }
 5252
 5253    wc_UnLockMutex(&inits_count_mutex);
 5254
 5255    if (ret != WOLFSSL_SUCCESS) {
 5256        (void)wolfSSL_Cleanup(); /* Ignore any error from cleanup */
 5257    }
 5258
 5259    return ret;
 5260}
 5261
 5262#if defined(WOLFSSL_SYS_CRYPTO_POLICY)
 5263/* Helper function for wolfSSL_crypto_policy_enable and
 5264 * wolfSSL_crypto_policy_enable_buffer.
 5265 *
 5266 * Parses the crypto policy string, verifies values,
 5267 * and sets in global crypto policy struct. Not thread
 5268 * safe. String length has already been verified.
 5269 *
 5270 * Returns WOLFSSL_SUCCESS on success.
 5271 * Returns CRYPTO_POLICY_FORBIDDEN if already enabled.
 5272 * Returns < 0 on misc error.
 5273 * */
 5274static int crypto_policy_parse(void)
 5275{
 5276    const char * hdr = WOLFSSL_SECLEVEL_STR;
 5277    int          sec_level = 0;
 5278    size_t       i = 0;
 5279
 5280    /* All policies should begin with "@SECLEVEL=<N>" (N={0..5}) followed
 5281     * by bulk cipher list. */
 5282    if (XMEMCMP(crypto_policy.str, hdr, strlen(hdr)) != 0) {
 5283        WOLFSSL_MSG("error: crypto policy: invalid header");
 5284        return WOLFSSL_BAD_FILE;
 5285    }
 5286
 5287    {
 5288        /* Extract the security level. */
 5289        char *       policy_mem = crypto_policy.str;
 5290        policy_mem += strlen(hdr);
 5291        sec_level = (int) (*policy_mem - '0');
 5292    }
 5293
 5294    if (sec_level < MIN_WOLFSSL_SEC_LEVEL ||
 5295        sec_level > MAX_WOLFSSL_SEC_LEVEL) {
 5296        WOLFSSL_MSG_EX("error: invalid SECLEVEL: %d", sec_level);
 5297        return WOLFSSL_BAD_FILE;
 5298    }
 5299
 5300    /* Remove trailing '\r' or '\n'. */
 5301    for (i = 0; i < MAX_WOLFSSL_CRYPTO_POLICY_SIZE; ++i) {
 5302        if (crypto_policy.str[i] == '\0') {
 5303            break;
 5304        }
 5305
 5306        if (crypto_policy.str[i] == '\r' || crypto_policy.str[i] == '\n') {
 5307            crypto_policy.str[i] = '\0';
 5308            break;
 5309        }
 5310    }
 5311
 5312    #if defined(DEBUG_WOLFSSL_VERBOSE)
 5313    WOLFSSL_MSG_EX("info: SECLEVEL=%d", sec_level);
 5314    WOLFSSL_MSG_EX("info: using crypto-policy file: %s, %ld", policy_file, sz);
 5315    #endif /* DEBUG_WOLFSSL_VERBOSE */
 5316
 5317    crypto_policy.secLevel = sec_level;
 5318    crypto_policy.enabled = 1;
 5319
 5320    return WOLFSSL_SUCCESS;
 5321}
 5322
 5323#ifndef NO_FILESYSTEM
 5324/* Enables wolfSSL system wide crypto-policy, using the given policy
 5325 * file arg. If NULL is passed, then the default system crypto-policy
 5326 * file that was set at configure time will be used instead.
 5327 *
 5328 * While enabled:
 5329 *   - TLS methods, min key sizes, and cipher lists are all configured
 5330 *     automatically by the policy.
 5331 *   - Attempting to use lesser strength parameters will fail with
 5332 *     error CRYPTO_POLICY_FORBIDDEN.
 5333 *
 5334 * Disable with wolfSSL_crypto_policy_disable.
 5335 *
 5336 * Note: the wolfSSL_crypto_policy_X API are not thread safe, and should
 5337 * only be called at program init time.
 5338 *
 5339 * Returns WOLFSSL_SUCCESS on success.
 5340 * Returns CRYPTO_POLICY_FORBIDDEN if already enabled.
 5341 * Returns < 0 on misc error.
 5342 * */
 5343int wolfSSL_crypto_policy_enable(const char * policy_file)
 5344{
 5345    XFILE   file;
 5346    long    sz = 0;
 5347    size_t  n_read = 0;
 5348
 5349    WOLFSSL_ENTER("wolfSSL_crypto_policy_enable");
 5350
 5351    if (wolfSSL_crypto_policy_is_enabled()) {
 5352        WOLFSSL_MSG_EX("error: crypto policy already enabled: %s",
 5353                       policy_file);
 5354        return CRYPTO_POLICY_FORBIDDEN;
 5355    }
 5356
 5357    if (policy_file == NULL) {
 5358        /* Use the configure-time default if NULL passed. */
 5359        policy_file = WC_STRINGIFY(WOLFSSL_CRYPTO_POLICY_FILE);
 5360    }
 5361
 5362    if (policy_file == NULL || *policy_file == '\0') {
 5363        WOLFSSL_MSG("error: crypto policy empty file");
 5364        return BAD_FUNC_ARG;
 5365    }
 5366
 5367    XMEMSET(&crypto_policy, 0, sizeof(crypto_policy));
 5368
 5369    file = XFOPEN(policy_file, "rb");
 5370
 5371    if (file == XBADFILE) {
 5372        WOLFSSL_MSG_EX("error: crypto policy file open failed: %s",
 5373                       policy_file);
 5374        return WOLFSSL_BAD_FILE;
 5375    }
 5376
 5377    if (XFSEEK(file, 0, XSEEK_END) != 0) {
 5378        WOLFSSL_MSG_EX("error: crypto policy file seek end failed: %s",
 5379                       policy_file);
 5380        XFCLOSE(file);
 5381        return WOLFSSL_BAD_FILE;
 5382    }
 5383
 5384    sz = XFTELL(file);
 5385
 5386    if (XFSEEK(file, 0, XSEEK_SET) != 0) {
 5387        WOLFSSL_MSG_EX("error: crypto policy file seek failed: %s",
 5388                       policy_file);
 5389        XFCLOSE(file);
 5390        return WOLFSSL_BAD_FILE;
 5391    }
 5392
 5393    if (sz <= 0 || sz > MAX_WOLFSSL_CRYPTO_POLICY_SIZE) {
 5394        WOLFSSL_MSG_EX("error: crypto policy file %s, invalid size: %ld",
 5395                       policy_file, sz);
 5396        XFCLOSE(file);
 5397        return WOLFSSL_BAD_FILE;
 5398    }
 5399
 5400    n_read = XFREAD(crypto_policy.str, 1, sz, file);
 5401    XFCLOSE(file);
 5402
 5403    if (n_read != (size_t) sz) {
 5404        WOLFSSL_MSG_EX("error: crypto policy file %s: read %zu, "
 5405                       "expected %ld", policy_file, n_read, sz);
 5406        return WOLFSSL_BAD_FILE;
 5407    }
 5408
 5409    crypto_policy.str[n_read] = '\0';
 5410
 5411    return crypto_policy_parse();
 5412}
 5413#endif /* ! NO_FILESYSTEM */
 5414
 5415/* Same behavior as wolfSSL_crypto_policy_enable, but loads
 5416 * via memory buf instead of file.
 5417 *
 5418 * Returns WOLFSSL_SUCCESS on success.
 5419 * Returns CRYPTO_POLICY_FORBIDDEN if already enabled.
 5420 * Returns < 0 on misc error.
 5421 * */
 5422int wolfSSL_crypto_policy_enable_buffer(const char * buf)
 5423{
 5424    size_t sz = 0;
 5425
 5426    WOLFSSL_ENTER("wolfSSL_crypto_policy_enable_buffer");
 5427
 5428    if (wolfSSL_crypto_policy_is_enabled()) {
 5429        WOLFSSL_MSG_EX("error: crypto policy already enabled");
 5430        return CRYPTO_POLICY_FORBIDDEN;
 5431    }
 5432
 5433    if (buf == NULL || *buf == '\0') {
 5434        return BAD_FUNC_ARG;
 5435    }
 5436
 5437    sz = XSTRLEN(buf);
 5438
 5439    if (sz == 0 || sz > MAX_WOLFSSL_CRYPTO_POLICY_SIZE) {
 5440        return BAD_FUNC_ARG;
 5441    }
 5442
 5443    XMEMSET(&crypto_policy, 0, sizeof(crypto_policy));
 5444    XMEMCPY(crypto_policy.str, buf, sz);
 5445
 5446    return crypto_policy_parse();
 5447}
 5448
 5449/* Returns whether the system wide crypto-policy is enabled.
 5450 *
 5451 * Returns 1 if enabled.
 5452 *         0 if disabled.
 5453 * */
 5454int wolfSSL_crypto_policy_is_enabled(void)
 5455{
 5456    WOLFSSL_ENTER("wolfSSL_crypto_policy_is_enabled");
 5457
 5458    return crypto_policy.enabled == 1;
 5459}
 5460
 5461/* Disables the system wide crypto-policy.
 5462 * note: SSL and CTX structures already instantiated will
 5463 * keep their security policy parameters. This will only
 5464 * affect new instantiations.
 5465 * */
 5466void wolfSSL_crypto_policy_disable(void)
 5467{
 5468    WOLFSSL_ENTER("wolfSSL_crypto_policy_disable");
 5469    crypto_policy.enabled = 0;
 5470    XMEMSET(&crypto_policy, 0, sizeof(crypto_policy));
 5471    return;
 5472}
 5473
 5474/* Get the crypto-policy bulk cipher list string.
 5475 * String is not owned by caller, should not be freed.
 5476 *
 5477 * Returns pointer to bulk cipher list string.
 5478 * Returns NULL if NOT enabled, or on error.
 5479 * */
 5480const char * wolfSSL_crypto_policy_get_ciphers(void)
 5481{
 5482    WOLFSSL_ENTER("wolfSSL_crypto_policy_get_ciphers");
 5483
 5484    if (crypto_policy.enabled == 1) {
 5485        /* The crypto policy config will have
 5486         * this form:
 5487         *   "@SECLEVEL=2:kEECDH:kRSA..." */
 5488        return crypto_policy.str;
 5489    }
 5490
 5491    return NULL;
 5492}
 5493
 5494/* Get the configured crypto-policy security level.
 5495 * A security level of 0 does not impose any additional
 5496 * restrictions.
 5497 *
 5498 * Returns 1 - 5 if enabled.
 5499 * Returns 0 if NOT enabled.
 5500 * */
 5501int wolfSSL_crypto_policy_get_level(void)
 5502{
 5503    if (crypto_policy.enabled == 1) {
 5504        return crypto_policy.secLevel;
 5505    }
 5506
 5507    return 0;
 5508}
 5509
 5510/* Get security level from ssl structure.
 5511 * @param ssl  a pointer to WOLFSSL structure
 5512 */
 5513int wolfSSL_get_security_level(const WOLFSSL * ssl)
 5514{
 5515    if (ssl == NULL) {
 5516        return BAD_FUNC_ARG;
 5517    }
 5518
 5519    return ssl->secLevel;
 5520}
 5521
 5522#ifndef NO_WOLFSSL_STUB
 5523/*
 5524 * Set security level (wolfSSL doesn't support setting the security level).
 5525 *
 5526 * The security level can only be set through a system wide crypto-policy
 5527 * with wolfSSL_crypto_policy_enable().
 5528 *
 5529 * @param ssl  a pointer to WOLFSSL structure
 5530 * @param level security level
 5531 */
 5532void wolfSSL_set_security_level(WOLFSSL * ssl, int level)
 5533{
 5534    WOLFSSL_ENTER("wolfSSL_set_security_level");
 5535    (void)ssl;
 5536    (void)level;
 5537}
 5538#endif /* !NO_WOLFSSL_STUB */
 5539
 5540#endif /* WOLFSSL_SYS_CRYPTO_POLICY */
 5541
 5542
 5543#define WOLFSSL_SSL_LOAD_INCLUDED
 5544#include <src/ssl_load.c>
 5545
 5546#define WOLFSSL_SSL_API_CRL_OCSP_INCLUDED
 5547#include "src/ssl_api_crl_ocsp.c"
 5548
 5549
 5550void wolfSSL_load_error_strings(void)
 5551{
 5552    /* compatibility only */
 5553}
 5554
 5555
 5556int wolfSSL_library_init(void)
 5557{
 5558    WOLFSSL_ENTER("wolfSSL_library_init");
 5559    if (wolfSSL_Init() == WOLFSSL_SUCCESS)
 5560        return WOLFSSL_SUCCESS;
 5561    else
 5562        return WOLFSSL_FATAL_ERROR;
 5563}
 5564
 5565
 5566#ifdef HAVE_SECRET_CALLBACK
 5567
 5568int wolfSSL_set_session_secret_cb(WOLFSSL* ssl, SessionSecretCb cb, void* ctx)
 5569{
 5570    WOLFSSL_ENTER("wolfSSL_set_session_secret_cb");
 5571    if (ssl == NULL)
 5572        return WOLFSSL_FAILURE;
 5573
 5574    ssl->sessionSecretCb = cb;
 5575    ssl->sessionSecretCtx = ctx;
 5576    if (cb != NULL) {
 5577        /* If using a pre-set key, assume session resumption. */
 5578        ssl->session->sessionIDSz = 0;
 5579        ssl->options.resuming = 1;
 5580    }
 5581
 5582    return WOLFSSL_SUCCESS;
 5583}
 5584
 5585int wolfSSL_set_session_ticket_ext_cb(WOLFSSL* ssl, TicketParseCb cb,
 5586        void *ctx)
 5587{
 5588    WOLFSSL_ENTER("wolfSSL_set_session_ticket_ext_cb");
 5589    if (ssl == NULL)
 5590        return WOLFSSL_FAILURE;
 5591
 5592    ssl->ticketParseCb = cb;
 5593    ssl->ticketParseCtx = ctx;
 5594
 5595    return WOLFSSL_SUCCESS;
 5596}
 5597
 5598int wolfSSL_set_secret_cb(WOLFSSL* ssl, TlsSecretCb cb, void* ctx)
 5599{
 5600    WOLFSSL_ENTER("wolfSSL_set_secret_cb");
 5601    if (ssl == NULL)
 5602        return WOLFSSL_FATAL_ERROR;
 5603
 5604    ssl->tlsSecretCb = cb;
 5605    ssl->tlsSecretCtx = ctx;
 5606
 5607    return WOLFSSL_SUCCESS;
 5608}
 5609
 5610#ifdef SHOW_SECRETS
 5611int tlsShowSecrets(WOLFSSL* ssl, void* secret, int secretSz,
 5612        void* ctx)
 5613{
 5614    /* Wireshark Pre-Master-Secret Format:
 5615     *  CLIENT_RANDOM <clientrandom> <mastersecret>
 5616     */
 5617    const char* CLIENT_RANDOM_LABEL = "CLIENT_RANDOM";
 5618    int i, pmsPos = 0;
 5619    char pmsBuf[13 + 1 + 64 + 1 + 96 + 1 + 1];
 5620    byte clientRandom[RAN_LEN];
 5621    int clientRandomSz;
 5622
 5623    (void)ctx;
 5624
 5625    clientRandomSz = (int)wolfSSL_get_client_random(ssl, clientRandom,
 5626        sizeof(clientRandom));
 5627
 5628    if (clientRandomSz <= 0) {
 5629        printf("Error getting server random %d\n", clientRandomSz);
 5630        return BAD_FUNC_ARG;
 5631    }
 5632
 5633    XSNPRINTF(&pmsBuf[pmsPos], sizeof(pmsBuf) - pmsPos, "%s ",
 5634        CLIENT_RANDOM_LABEL);
 5635    pmsPos += XSTRLEN(CLIENT_RANDOM_LABEL) + 1;
 5636    for (i = 0; i < clientRandomSz; i++) {
 5637        XSNPRINTF(&pmsBuf[pmsPos], sizeof(pmsBuf) - pmsPos, "%02x",
 5638            clientRandom[i]);
 5639        pmsPos += 2;
 5640    }
 5641    XSNPRINTF(&pmsBuf[pmsPos], sizeof(pmsBuf) - pmsPos, " ");
 5642    pmsPos += 1;
 5643    for (i = 0; i < secretSz; i++) {
 5644        XSNPRINTF(&pmsBuf[pmsPos], sizeof(pmsBuf) - pmsPos, "%02x",
 5645            ((byte*)secret)[i]);
 5646        pmsPos += 2;
 5647    }
 5648    XSNPRINTF(&pmsBuf[pmsPos], sizeof(pmsBuf) - pmsPos, "\n");
 5649    pmsPos += 1;
 5650
 5651    /* print master secret */
 5652    puts(pmsBuf);
 5653
 5654    #if !defined(NO_FILESYSTEM) && defined(WOLFSSL_SSLKEYLOGFILE)
 5655    {
 5656        FILE* f = XFOPEN(WOLFSSL_SSLKEYLOGFILE_OUTPUT, "a");
 5657        if (f != XBADFILE) {
 5658            XFWRITE(pmsBuf, 1, pmsPos, f);
 5659            XFCLOSE(f);
 5660        }
 5661    }
 5662    #endif
 5663    return 0;
 5664}
 5665#endif /* SHOW_SECRETS */
 5666
 5667#endif
 5668
 5669
 5670#ifdef OPENSSL_EXTRA
 5671
 5672/*
 5673 * check if the list has TLS13 and pre-TLS13 suites
 5674 * @param list cipher suite list that user want to set
 5675 *         (caller required to check for NULL)
 5676 * @return mixed: 0, only pre-TLS13: 1, only TLS13: 2
 5677 */
 5678static int CheckcipherList(const char* list)
 5679{
 5680    int ret;
 5681    int findTLSv13Suites = 0;
 5682    int findbeforeSuites = 0;
 5683    byte cipherSuite0;
 5684    byte cipherSuite1;
 5685    int flags;
 5686    char* next = (char*)list;
 5687
 5688    do {
 5689        char*  current = next;
 5690        char   name[MAX_SUITE_NAME + 1];
 5691        word32 length = MAX_SUITE_NAME;
 5692        word32 current_length;
 5693        byte major = INVALID_BYTE;
 5694        byte minor = INVALID_BYTE;
 5695
 5696        next   = XSTRSTR(next, ":");
 5697
 5698        if (next) {
 5699            current_length = (word32)(next - current);
 5700            ++next; /* increment to skip ':' */
 5701        }
 5702        else {
 5703            current_length = (word32)XSTRLEN(current);
 5704        }
 5705
 5706        if (current_length == 0) {
 5707            break;
 5708        }
 5709
 5710        if (current_length < length) {
 5711            length = current_length;
 5712        }
 5713        XMEMCPY(name, current, length);
 5714        name[length] = 0;
 5715
 5716        if (XSTRCMP(name, "ALL") == 0 ||
 5717            XSTRCMP(name, "DEFAULT") == 0 ||
 5718            XSTRCMP(name, "HIGH") == 0)
 5719        {
 5720            findTLSv13Suites = 1;
 5721            findbeforeSuites = 1;
 5722            break;
 5723        }
 5724
 5725        ret = GetCipherSuiteFromName(name, &cipherSuite0,
 5726                &cipherSuite1, &major, &minor, &flags);
 5727        if (ret == 0) {
 5728            if (cipherSuite0 == TLS13_BYTE || minor == TLSv1_3_MINOR) {
 5729                /* TLSv13 suite */
 5730                findTLSv13Suites = 1;
 5731            }
 5732            else {
 5733                findbeforeSuites = 1;
 5734            }
 5735        }
 5736
 5737    #if defined(OPENSSL_EXTRA) || defined(OPENSSL_ALL)
 5738        /* check if mixed due to names like RSA:ECDHE+AESGCM etc. */
 5739        if (ret != 0) {
 5740            char* subStr = name;
 5741            char* subStrNext;
 5742
 5743            do {
 5744                subStrNext = XSTRSTR(subStr, "+");
 5745
 5746                if ((XSTRCMP(subStr, "ECDHE") == 0) ||
 5747                    (XSTRCMP(subStr, "RSA") == 0)) {
 5748                    return 0;
 5749                }
 5750
 5751                if (subStrNext && (XSTRLEN(subStrNext) > 0)) {
 5752                    subStr = subStrNext + 1; /* +1 to skip past '+' */
 5753                }
 5754            } while (subStrNext != NULL);
 5755        }
 5756    #endif
 5757
 5758        if (findTLSv13Suites == 1 && findbeforeSuites == 1) {
 5759            /* list has mixed suites */
 5760            return 0;
 5761        }
 5762    } while (next);
 5763
 5764    if (findTLSv13Suites == 0 && findbeforeSuites == 1) {
 5765        ret = 1;/* only before TLSv13 suites */
 5766    }
 5767    else if (findTLSv13Suites == 1 && findbeforeSuites == 0) {
 5768        ret = 2;/* only TLSv13 suties */
 5769    }
 5770    else {
 5771        ret = 0;/* handle as mixed */
 5772    }
 5773    return ret;
 5774}
 5775
 5776/* parse some bulk lists like !eNULL / !aNULL
 5777 *
 5778 * returns WOLFSSL_SUCCESS on success and sets the cipher suite list
 5779 */
 5780static int wolfSSL_parse_cipher_list(WOLFSSL_CTX* ctx, WOLFSSL* ssl,
 5781        Suites* suites, const char* list)
 5782{
 5783    int     ret = 0;
 5784    int     listattribute = 0;
 5785    int     tls13Only = 0;
 5786    WC_DECLARE_VAR(suitesCpy, byte, WOLFSSL_MAX_SUITE_SZ, 0);
 5787    word16  suitesCpySz = 0;
 5788    word16  i = 0;
 5789    word16  j = 0;
 5790
 5791    if (suites == NULL || list == NULL) {
 5792        WOLFSSL_MSG("NULL argument");
 5793        return WOLFSSL_FAILURE;
 5794    }
 5795
 5796    listattribute = CheckcipherList(list);
 5797
 5798    if (listattribute == 0) {
 5799       /* list has mixed(pre-TLSv13 and TLSv13) suites
 5800        * update cipher suites the same as before
 5801        */
 5802        return (SetCipherList_ex(ctx, ssl, suites, list)) ? WOLFSSL_SUCCESS :
 5803        WOLFSSL_FAILURE;
 5804    }
 5805    else if (listattribute == 1) {
 5806       /* list has only pre-TLSv13 suites.
 5807        * Only update before TLSv13 suites.
 5808        */
 5809        tls13Only = 0;
 5810    }
 5811    else if (listattribute == 2) {
 5812       /* list has only TLSv13 suites. Only update TLv13 suites
 5813        * simulate set_ciphersuites() compatibility layer API
 5814        */
 5815        tls13Only = 1;
 5816        if ((ctx != NULL && !IsAtLeastTLSv1_3(ctx->method->version)) ||
 5817                (ssl != NULL && !IsAtLeastTLSv1_3(ssl->version))) {
 5818            /* Silently ignore TLS 1.3 ciphers if we don't support it. */
 5819            return WOLFSSL_SUCCESS;
 5820        }
 5821    }
 5822
 5823    /* list contains ciphers either only for TLS 1.3 or <= TLS 1.2 */
 5824#ifdef WOLFSSL_SMALL_STACK
 5825    if (suites->suiteSz > 0) {
 5826        suitesCpy = (byte*)XMALLOC(suites->suiteSz, NULL,
 5827                DYNAMIC_TYPE_TMP_BUFFER);
 5828        if (suitesCpy == NULL) {
 5829            return WOLFSSL_FAILURE;
 5830        }
 5831
 5832        XMEMSET(suitesCpy, 0, suites->suiteSz);
 5833    }
 5834#else
 5835        XMEMSET(suitesCpy, 0, sizeof(suitesCpy));
 5836#endif
 5837
 5838    if (suites->suiteSz > 0)
 5839        XMEMCPY(suitesCpy, suites->suites, suites->suiteSz);
 5840    suitesCpySz = suites->suiteSz;
 5841
 5842    ret = SetCipherList_ex(ctx, ssl, suites, list);
 5843    if (ret != 1) {
 5844        WC_FREE_VAR_EX(suitesCpy, NULL, DYNAMIC_TYPE_TMP_BUFFER);
 5845        return WOLFSSL_FAILURE;
 5846    }
 5847
 5848    /* The idea in this section is that OpenSSL has two API to set ciphersuites.
 5849     *   - SSL_CTX_set_cipher_list for setting TLS <= 1.2 suites
 5850     *   - SSL_CTX_set_ciphersuites for setting TLS 1.3 suites
 5851     * Since we direct both API here we attempt to provide API compatibility. If
 5852     * we only get suites from <= 1.2 or == 1.3 then we will only update those
 5853     * suites and keep the suites from the other group.
 5854     * If downgrade is disabled, skip preserving the other group's suites. */
 5855    if ((ssl != NULL && !ssl->options.downgrade) ||
 5856        (ctx != NULL && !ctx->method->downgrade)) {
 5857        /* Downgrade disabled - don't preserve other group's suites */
 5858        WC_FREE_VAR_EX(suitesCpy, NULL, DYNAMIC_TYPE_TMP_BUFFER);
 5859        return ret;
 5860    }
 5861
 5862    for (i = 0; i < suitesCpySz &&
 5863                suites->suiteSz <= (WOLFSSL_MAX_SUITE_SZ - SUITE_LEN); i += 2) {
 5864        /* Check for duplicates */
 5865        int duplicate = 0;
 5866        for (j = 0; j < suites->suiteSz; j += 2) {
 5867            if (suitesCpy[i] == suites->suites[j] &&
 5868                    suitesCpy[i+1] == suites->suites[j+1]) {
 5869                duplicate = 1;
 5870                break;
 5871            }
 5872        }
 5873        if (!duplicate) {
 5874            if (tls13Only) {
 5875                /* Updating TLS 1.3 ciphers */
 5876                if (suitesCpy[i] != TLS13_BYTE) {
 5877                    /* Only copy over <= TLS 1.2 ciphers */
 5878                    /* TLS 1.3 ciphers take precedence */
 5879                    suites->suites[suites->suiteSz++] = suitesCpy[i];
 5880                    suites->suites[suites->suiteSz++] = suitesCpy[i+1];
 5881                }
 5882            }
 5883            else {
 5884                /* Updating <= TLS 1.2 ciphers */
 5885                if (suitesCpy[i] == TLS13_BYTE) {
 5886                    /* Only copy over TLS 1.3 ciphers */
 5887                    /* TLS 1.3 ciphers take precedence */
 5888                    XMEMMOVE(suites->suites + SUITE_LEN, suites->suites,
 5889                             suites->suiteSz);
 5890                    suites->suites[0] = suitesCpy[i];
 5891                    suites->suites[1] = suitesCpy[i+1];
 5892                    suites->suiteSz += 2;
 5893                }
 5894            }
 5895        }
 5896    }
 5897
 5898    WC_FREE_VAR_EX(suitesCpy, NULL, DYNAMIC_TYPE_TMP_BUFFER);
 5899    return ret;
 5900}
 5901
 5902#endif
 5903
 5904
 5905int wolfSSL_CTX_set_cipher_list(WOLFSSL_CTX* ctx, const char* list)
 5906{
 5907    WOLFSSL_ENTER("wolfSSL_CTX_set_cipher_list");
 5908
 5909    if (ctx == NULL)
 5910        return WOLFSSL_FAILURE;
 5911
 5912    if (AllocateCtxSuites(ctx) != 0)
 5913        return WOLFSSL_FAILURE;
 5914
 5915#ifdef OPENSSL_EXTRA
 5916    return wolfSSL_parse_cipher_list(ctx, NULL, ctx->suites, list);
 5917#else
 5918    return (SetCipherList(ctx, ctx->suites, list)) ?
 5919        WOLFSSL_SUCCESS : WOLFSSL_FAILURE;
 5920#endif
 5921}
 5922
 5923#if defined(OPENSSL_EXTRA) || defined(WOLFSSL_SET_CIPHER_BYTES)
 5924int wolfSSL_CTX_set_cipher_list_bytes(WOLFSSL_CTX* ctx, const byte* list,
 5925                                      const int listSz)
 5926{
 5927    WOLFSSL_ENTER("wolfSSL_CTX_set_cipher_list_bytes");
 5928
 5929    if (ctx == NULL)
 5930        return WOLFSSL_FAILURE;
 5931
 5932    if (AllocateCtxSuites(ctx) != 0)
 5933        return WOLFSSL_FAILURE;
 5934
 5935    return (SetCipherListFromBytes(ctx, ctx->suites, list, listSz)) ?
 5936        WOLFSSL_SUCCESS : WOLFSSL_FAILURE;
 5937}
 5938#endif /* OPENSSL_EXTRA || WOLFSSL_SET_CIPHER_BYTES */
 5939
 5940int wolfSSL_set_cipher_list(WOLFSSL* ssl, const char* list)
 5941{
 5942    WOLFSSL_ENTER("wolfSSL_set_cipher_list");
 5943
 5944    if (ssl == NULL || ssl->ctx == NULL) {
 5945        return WOLFSSL_FAILURE;
 5946    }
 5947
 5948    if (AllocateSuites(ssl) != 0)
 5949        return WOLFSSL_FAILURE;
 5950
 5951#ifdef OPENSSL_EXTRA
 5952    return wolfSSL_parse_cipher_list(NULL, ssl, ssl->suites, list);
 5953#else
 5954    return (SetCipherList_ex(NULL, ssl, ssl->suites, list)) ?
 5955        WOLFSSL_SUCCESS :
 5956        WOLFSSL_FAILURE;
 5957#endif
 5958}
 5959
 5960#if defined(OPENSSL_EXTRA) || defined(WOLFSSL_SET_CIPHER_BYTES)
 5961int wolfSSL_set_cipher_list_bytes(WOLFSSL* ssl, const byte* list,
 5962                                  const int listSz)
 5963{
 5964    WOLFSSL_ENTER("wolfSSL_set_cipher_list_bytes");
 5965
 5966    if (ssl == NULL || ssl->ctx == NULL) {
 5967        return WOLFSSL_FAILURE;
 5968    }
 5969
 5970    if (AllocateSuites(ssl) != 0)
 5971        return WOLFSSL_FAILURE;
 5972
 5973    return (SetCipherListFromBytes(ssl->ctx, ssl->suites, list, listSz))
 5974           ? WOLFSSL_SUCCESS
 5975           : WOLFSSL_FAILURE;
 5976}
 5977#endif /* OPENSSL_EXTRA || WOLFSSL_SET_CIPHER_BYTES */
 5978
 5979
 5980#ifdef HAVE_KEYING_MATERIAL
 5981
 5982#define TLS_PRF_LABEL_CLIENT_FINISHED     "client finished"
 5983#define TLS_PRF_LABEL_SERVER_FINISHED     "server finished"
 5984#define TLS_PRF_LABEL_MASTER_SECRET       "master secret"
 5985#define TLS_PRF_LABEL_EXT_MASTER_SECRET   "extended master secret"
 5986#define TLS_PRF_LABEL_KEY_EXPANSION       "key expansion"
 5987
 5988static const struct ForbiddenLabels {
 5989    const char* label;
 5990    size_t labelLen;
 5991} forbiddenLabels[] = {
 5992    {TLS_PRF_LABEL_CLIENT_FINISHED, XSTR_SIZEOF(TLS_PRF_LABEL_CLIENT_FINISHED)},
 5993    {TLS_PRF_LABEL_SERVER_FINISHED, XSTR_SIZEOF(TLS_PRF_LABEL_SERVER_FINISHED)},
 5994    {TLS_PRF_LABEL_MASTER_SECRET, XSTR_SIZEOF(TLS_PRF_LABEL_MASTER_SECRET)},
 5995    {TLS_PRF_LABEL_EXT_MASTER_SECRET,
 5996     XSTR_SIZEOF(TLS_PRF_LABEL_EXT_MASTER_SECRET)},
 5997    {TLS_PRF_LABEL_KEY_EXPANSION, XSTR_SIZEOF(TLS_PRF_LABEL_KEY_EXPANSION)},
 5998    {NULL, 0},
 5999};
 6000
 6001/**
 6002 * Implement RFC 5705
 6003 * TLS 1.3 uses a different exporter definition (section 7.5 of RFC 8446)
 6004 * @return WOLFSSL_SUCCESS on success and WOLFSSL_FAILURE on error
 6005 */
 6006int wolfSSL_export_keying_material(WOLFSSL *ssl,
 6007        unsigned char *out, size_t outLen,
 6008        const char *label, size_t labelLen,
 6009        const unsigned char *context, size_t contextLen,
 6010        int use_context)
 6011{
 6012    byte*  seed = NULL;
 6013    word32 seedLen;
 6014    const struct ForbiddenLabels* fl;
 6015
 6016    WOLFSSL_ENTER("wolfSSL_export_keying_material");
 6017
 6018    if (ssl == NULL || out == NULL || label == NULL ||
 6019            (use_context && contextLen && context == NULL)) {
 6020        WOLFSSL_MSG("Bad argument");
 6021        return WOLFSSL_FAILURE;
 6022    }
 6023
 6024    /* Sanity check contextLen to prevent integer overflow when cast to word32
 6025     * and to ensure it fits in the 2-byte length encoding (max 65535). */
 6026    if (use_context && contextLen > WOLFSSL_MAX_16BIT) {
 6027        WOLFSSL_MSG("contextLen too large");
 6028        return WOLFSSL_FAILURE;
 6029    }
 6030
 6031    /* clientRandom + serverRandom
 6032     * OR
 6033     * clientRandom + serverRandom + ctx len encoding + ctx */
 6034    seedLen = !use_context ? (word32)SEED_LEN :
 6035                             (word32)SEED_LEN + 2 + (word32)contextLen;
 6036
 6037    if (ssl->options.saveArrays == 0 || ssl->arrays == NULL) {
 6038        WOLFSSL_MSG("To export keying material wolfSSL needs to keep handshake "
 6039                    "data. Call wolfSSL_KeepArrays before attempting to "
 6040                    "export keyid material.");
 6041        return WOLFSSL_FAILURE;
 6042    }
 6043
 6044    /* check forbidden labels */
 6045    for (fl = &forbiddenLabels[0]; fl->label != NULL; fl++) {
 6046        if (labelLen >= fl->labelLen &&
 6047                XMEMCMP(label, fl->label, fl->labelLen) == 0) {
 6048            WOLFSSL_MSG("Forbidden label");
 6049            return WOLFSSL_FAILURE;
 6050        }
 6051    }
 6052
 6053#ifdef WOLFSSL_TLS13
 6054    if (IsAtLeastTLSv1_3(ssl->version)) {
 6055        /* Path for TLS 1.3 */
 6056        if (!use_context) {
 6057            contextLen = 0;
 6058            context = (byte*)""; /* Give valid pointer for 0 length memcpy */
 6059        }
 6060
 6061        if (Tls13_Exporter(ssl, out, (word32)outLen, label, labelLen,
 6062                context, contextLen) != 0) {
 6063            WOLFSSL_MSG("Tls13_Exporter error");
 6064            return WOLFSSL_FAILURE;
 6065        }
 6066        return WOLFSSL_SUCCESS;
 6067    }
 6068#endif
 6069
 6070    /* Path for <=TLS 1.2 */
 6071    seed = (byte*)XMALLOC(seedLen, NULL, DYNAMIC_TYPE_TMP_BUFFER);
 6072    if (seed == NULL) {
 6073        WOLFSSL_MSG("malloc error");
 6074        return WOLFSSL_FAILURE;
 6075    }
 6076
 6077    XMEMCPY(seed,           ssl->arrays->clientRandom, RAN_LEN);
 6078    XMEMCPY(seed + RAN_LEN, ssl->arrays->serverRandom, RAN_LEN);
 6079
 6080    if (use_context) {
 6081        /* Encode len in big endian */
 6082        seed[SEED_LEN    ] = (contextLen >> 8) & 0xFF;
 6083        seed[SEED_LEN + 1] = (contextLen) & 0xFF;
 6084        if (contextLen) {
 6085            /* 0 length context is allowed */
 6086            XMEMCPY(seed + SEED_LEN + 2, context, contextLen);
 6087        }
 6088    }
 6089
 6090    PRIVATE_KEY_UNLOCK();
 6091    if (wc_PRF_TLS(out, (word32)outLen, ssl->arrays->masterSecret, SECRET_LEN,
 6092            (byte*)label, (word32)labelLen, seed, seedLen,
 6093            IsAtLeastTLSv1_2(ssl), ssl->specs.mac_algorithm, ssl->heap,
 6094            ssl->devId) != 0) {
 6095        WOLFSSL_MSG("wc_PRF_TLS error");
 6096        PRIVATE_KEY_LOCK();
 6097        XFREE(seed, NULL, DYNAMIC_TYPE_TMP_BUFFER);
 6098        return WOLFSSL_FAILURE;
 6099    }
 6100    PRIVATE_KEY_LOCK();
 6101
 6102    XFREE(seed, NULL, DYNAMIC_TYPE_TMP_BUFFER);
 6103    return WOLFSSL_SUCCESS;
 6104}
 6105#endif /* HAVE_KEYING_MATERIAL */
 6106
 6107int wolfSSL_dtls_get_using_nonblock(WOLFSSL* ssl)
 6108{
 6109    int useNb = 0;
 6110
 6111    if (ssl == NULL)
 6112        return WOLFSSL_FAILURE;
 6113
 6114    WOLFSSL_ENTER("wolfSSL_dtls_get_using_nonblock");
 6115    if (ssl->options.dtls) {
 6116#ifdef WOLFSSL_DTLS
 6117        useNb = ssl->options.dtlsUseNonblock;
 6118#endif
 6119    }
 6120    else {
 6121        WOLFSSL_MSG("wolfSSL_dtls_get_using_nonblock() is "
 6122                    "DEPRECATED for non-DTLS use.");
 6123    }
 6124    return useNb;
 6125}
 6126
 6127
 6128#ifndef WOLFSSL_LEANPSK
 6129
 6130void wolfSSL_dtls_set_using_nonblock(WOLFSSL* ssl, int nonblock)
 6131{
 6132    (void)nonblock;
 6133
 6134    WOLFSSL_ENTER("wolfSSL_dtls_set_using_nonblock");
 6135
 6136    if (ssl == NULL)
 6137        return;
 6138
 6139    if (ssl->options.dtls) {
 6140#ifdef WOLFSSL_DTLS
 6141        ssl->options.dtlsUseNonblock = (nonblock != 0);
 6142#endif
 6143    }
 6144    else {
 6145        WOLFSSL_MSG("wolfSSL_dtls_set_using_nonblock() is "
 6146                    "DEPRECATED for non-DTLS use.");
 6147    }
 6148}
 6149
 6150
 6151#ifdef WOLFSSL_DTLS
 6152
 6153int wolfSSL_dtls_get_current_timeout(WOLFSSL* ssl)
 6154{
 6155    int timeout = 0;
 6156    if (ssl)
 6157        timeout = ssl->dtls_timeout;
 6158
 6159    WOLFSSL_LEAVE("wolfSSL_dtls_get_current_timeout", timeout);
 6160    return timeout;
 6161}
 6162
 6163#ifdef WOLFSSL_DTLS13
 6164
 6165/*
 6166 * This API returns 1 when the user should set a short timeout for receiving
 6167 * data. It is recommended that it is at most 1/4 the value returned by
 6168 * wolfSSL_dtls_get_current_timeout().
 6169 */
 6170int wolfSSL_dtls13_use_quick_timeout(WOLFSSL* ssl)
 6171{
 6172    return ssl != NULL && ssl->dtls13FastTimeout;
 6173}
 6174
 6175/*
 6176 * When this is set, a DTLS 1.3 connection will send acks immediately when a
 6177 * disruption is detected to shortcut timeouts. This results in potentially
 6178 * more traffic but may make the handshake quicker.
 6179 */
 6180void wolfSSL_dtls13_set_send_more_acks(WOLFSSL* ssl, int value)
 6181{
 6182    if (ssl != NULL)
 6183        ssl->options.dtls13SendMoreAcks = !!value;
 6184}
 6185#endif /* WOLFSSL_DTLS13 */
 6186
 6187int wolfSSL_DTLSv1_get_timeout(WOLFSSL* ssl, WOLFSSL_TIMEVAL* timeleft)
 6188{
 6189    if (ssl && timeleft) {
 6190        XMEMSET(timeleft, 0, sizeof(WOLFSSL_TIMEVAL));
 6191        timeleft->tv_sec = ssl->dtls_timeout;
 6192    }
 6193    return 0;
 6194}
 6195
 6196#ifndef NO_WOLFSSL_STUB
 6197int wolfSSL_DTLSv1_handle_timeout(WOLFSSL* ssl)
 6198{
 6199    WOLFSSL_STUB("SSL_DTLSv1_handle_timeout");
 6200    (void)ssl;
 6201    return 0;
 6202}
 6203#endif
 6204
 6205#ifndef NO_WOLFSSL_STUB
 6206void wolfSSL_DTLSv1_set_initial_timeout_duration(WOLFSSL* ssl,
 6207    word32 duration_ms)
 6208{
 6209    WOLFSSL_STUB("SSL_DTLSv1_set_initial_timeout_duration");
 6210    (void)ssl;
 6211    (void)duration_ms;
 6212}
 6213#endif
 6214
 6215/* user may need to alter init dtls recv timeout, WOLFSSL_SUCCESS on ok */
 6216int wolfSSL_dtls_set_timeout_init(WOLFSSL* ssl, int timeout)
 6217{
 6218    if (ssl == NULL || timeout < 0)
 6219        return BAD_FUNC_ARG;
 6220
 6221    if (timeout > ssl->dtls_timeout_max) {
 6222        WOLFSSL_MSG("Can't set dtls timeout init greater than dtls timeout "
 6223                    "max");
 6224        return BAD_FUNC_ARG;
 6225    }
 6226
 6227    ssl->dtls_timeout_init = timeout;
 6228    ssl->dtls_timeout = timeout;
 6229
 6230    return WOLFSSL_SUCCESS;
 6231}
 6232
 6233
 6234/* user may need to alter max dtls recv timeout, WOLFSSL_SUCCESS on ok */
 6235int wolfSSL_dtls_set_timeout_max(WOLFSSL* ssl, int timeout)
 6236{
 6237    if (ssl == NULL || timeout < 0)
 6238        return BAD_FUNC_ARG;
 6239
 6240    if (timeout < ssl->dtls_timeout_init) {
 6241        WOLFSSL_MSG("Can't set dtls timeout max less than dtls timeout init");
 6242        return BAD_FUNC_ARG;
 6243    }
 6244
 6245    ssl->dtls_timeout_max = timeout;
 6246
 6247    return WOLFSSL_SUCCESS;
 6248}
 6249
 6250
 6251int wolfSSL_dtls_got_timeout(WOLFSSL* ssl)
 6252{
 6253    int result = WOLFSSL_SUCCESS;
 6254    WOLFSSL_ENTER("wolfSSL_dtls_got_timeout");
 6255
 6256    if (ssl == NULL || !ssl->options.dtls)
 6257        return WOLFSSL_FATAL_ERROR;
 6258
 6259#ifdef WOLFSSL_DTLS13
 6260    if (IsAtLeastTLSv1_3(ssl->version)) {
 6261        result = Dtls13RtxTimeout(ssl);
 6262        if (result < 0) {
 6263            if (result == WC_NO_ERR_TRACE(WANT_WRITE))
 6264                ssl->dtls13SendingAckOrRtx = 1;
 6265            ssl->error = result;
 6266            WOLFSSL_ERROR(result);
 6267            return WOLFSSL_FATAL_ERROR;
 6268        }
 6269
 6270        return WOLFSSL_SUCCESS;
 6271    }
 6272#endif /* WOLFSSL_DTLS13 */
 6273
 6274    /* Do we have any 1.2 messages stored? */
 6275    if (ssl->dtls_tx_msg_list != NULL || ssl->dtls_tx_msg != NULL) {
 6276        if (DtlsMsgPoolTimeout(ssl) < 0){
 6277            ssl->error = SOCKET_ERROR_E;
 6278            WOLFSSL_ERROR(ssl->error);
 6279            result = WOLFSSL_FATAL_ERROR;
 6280        }
 6281        else if ((result = DtlsMsgPoolSend(ssl, 0)) < 0)  {
 6282            ssl->error = result;
 6283            WOLFSSL_ERROR(result);
 6284            result = WOLFSSL_FATAL_ERROR;
 6285        }
 6286        else {
 6287            /* Reset return value to success */
 6288            result = WOLFSSL_SUCCESS;
 6289        }
 6290    }
 6291
 6292    WOLFSSL_LEAVE("wolfSSL_dtls_got_timeout", result);
 6293    return result;
 6294}
 6295
 6296
 6297/* retransmit all the saves messages, WOLFSSL_SUCCESS on ok */
 6298int wolfSSL_dtls_retransmit(WOLFSSL* ssl)
 6299{
 6300    WOLFSSL_ENTER("wolfSSL_dtls_retransmit");
 6301
 6302    if (ssl == NULL)
 6303        return WOLFSSL_FATAL_ERROR;
 6304
 6305    if (!ssl->options.handShakeDone) {
 6306        int result;
 6307#ifdef WOLFSSL_DTLS13
 6308        if (IsAtLeastTLSv1_3(ssl->version))
 6309            result = Dtls13DoScheduledWork(ssl);
 6310        else
 6311#endif
 6312            result = DtlsMsgPoolSend(ssl, 0);
 6313        if (result < 0) {
 6314            ssl->error = result;
 6315            WOLFSSL_ERROR(result);
 6316            return WOLFSSL_FATAL_ERROR;
 6317        }
 6318    }
 6319
 6320    return WOLFSSL_SUCCESS;
 6321}
 6322
 6323#endif /* DTLS */
 6324#endif /* LEANPSK */
 6325
 6326
 6327#if defined(WOLFSSL_DTLS) && !defined(NO_WOLFSSL_SERVER)
 6328
 6329/* Not an SSL function, return 0 for success, error code otherwise */
 6330/* Prereq: ssl's RNG needs to be initialized. */
 6331int wolfSSL_DTLS_SetCookieSecret(WOLFSSL* ssl,
 6332                                 const byte* secret, word32 secretSz)
 6333{
 6334    int ret = 0;
 6335
 6336    WOLFSSL_ENTER("wolfSSL_DTLS_SetCookieSecret");
 6337
 6338    if (ssl == NULL) {
 6339        WOLFSSL_MSG("need a SSL object");
 6340        return BAD_FUNC_ARG;
 6341    }
 6342
 6343    if (secret != NULL && secretSz == 0) {
 6344        WOLFSSL_MSG("can't have a new secret without a size");
 6345        return BAD_FUNC_ARG;
 6346    }
 6347
 6348    /* If secretSz is 0, use the default size. */
 6349    if (secretSz == 0)
 6350        secretSz = COOKIE_SECRET_SZ;
 6351
 6352    if (secretSz != ssl->buffers.dtlsCookieSecret.length) {
 6353        byte* newSecret;
 6354
 6355        if (ssl->buffers.dtlsCookieSecret.buffer != NULL) {
 6356            ForceZero(ssl->buffers.dtlsCookieSecret.buffer,
 6357                      ssl->buffers.dtlsCookieSecret.length);
 6358            XFREE(ssl->buffers.dtlsCookieSecret.buffer,
 6359                  ssl->heap, DYNAMIC_TYPE_COOKIE_PWD);
 6360        }
 6361
 6362        newSecret = (byte*)XMALLOC(secretSz, ssl->heap,DYNAMIC_TYPE_COOKIE_PWD);
 6363        if (newSecret == NULL) {
 6364            ssl->buffers.dtlsCookieSecret.buffer = NULL;
 6365            ssl->buffers.dtlsCookieSecret.length = 0;
 6366            WOLFSSL_MSG("couldn't allocate new cookie secret");
 6367            return MEMORY_ERROR;
 6368        }
 6369        ssl->buffers.dtlsCookieSecret.buffer = newSecret;
 6370        ssl->buffers.dtlsCookieSecret.length = secretSz;
 6371    #ifdef WOLFSSL_CHECK_MEM_ZERO
 6372        wc_MemZero_Add("wolfSSL_DTLS_SetCookieSecret secret",
 6373            ssl->buffers.dtlsCookieSecret.buffer,
 6374            ssl->buffers.dtlsCookieSecret.length);
 6375    #endif
 6376    }
 6377
 6378    /* If the supplied secret is NULL, randomly generate a new secret. */
 6379    if (secret == NULL) {
 6380        ret = wc_RNG_GenerateBlock(ssl->rng,
 6381                             ssl->buffers.dtlsCookieSecret.buffer, secretSz);
 6382    }
 6383    else
 6384        XMEMCPY(ssl->buffers.dtlsCookieSecret.buffer, secret, secretSz);
 6385
 6386    WOLFSSL_LEAVE("wolfSSL_DTLS_SetCookieSecret", 0);
 6387    return ret;
 6388}
 6389
 6390#endif /* WOLFSSL_DTLS && !NO_WOLFSSL_SERVER */
 6391
 6392
 6393/* EITHER SIDE METHODS */
 6394#if !defined(NO_TLS) && (defined(OPENSSL_EXTRA) || defined(WOLFSSL_EITHER_SIDE))
 6395    WOLFSSL_METHOD* wolfSSLv23_method(void)
 6396    {
 6397        return wolfSSLv23_method_ex(NULL);
 6398    }
 6399    WOLFSSL_METHOD* wolfSSLv23_method_ex(void* heap)
 6400    {
 6401        WOLFSSL_METHOD* m = NULL;
 6402        WOLFSSL_ENTER("wolfSSLv23_method");
 6403    #if !defined(NO_WOLFSSL_CLIENT)
 6404        m = wolfSSLv23_client_method_ex(heap);
 6405    #elif !defined(NO_WOLFSSL_SERVER)
 6406        m = wolfSSLv23_server_method_ex(heap);
 6407    #else
 6408        (void)heap;
 6409    #endif
 6410        if (m != NULL) {
 6411            m->side = WOLFSSL_NEITHER_END;
 6412        }
 6413
 6414        return m;
 6415    }
 6416
 6417    #ifndef NO_OLD_TLS
 6418    #ifdef WOLFSSL_ALLOW_SSLV3
 6419    WOLFSSL_METHOD* wolfSSLv3_method(void)
 6420    {
 6421        return wolfSSLv3_method_ex(NULL);
 6422    }
 6423    WOLFSSL_METHOD* wolfSSLv3_method_ex(void* heap)
 6424    {
 6425        WOLFSSL_METHOD* m = NULL;
 6426        WOLFSSL_ENTER("wolfSSLv3_method_ex");
 6427    #if !defined(NO_WOLFSSL_CLIENT)
 6428        m = wolfSSLv3_client_method_ex(heap);
 6429    #elif !defined(NO_WOLFSSL_SERVER)
 6430        m = wolfSSLv3_server_method_ex(heap);
 6431    #endif
 6432        if (m != NULL) {
 6433            m->side = WOLFSSL_NEITHER_END;
 6434        }
 6435
 6436        return m;
 6437    }
 6438    #endif
 6439    #endif
 6440#endif /* !NO_TLS && (OPENSSL_EXTRA || WOLFSSL_EITHER_SIDE) */
 6441
 6442/* client only parts */
 6443#if !defined(NO_WOLFSSL_CLIENT) && !defined(NO_TLS)
 6444
 6445    #if defined(OPENSSL_EXTRA) && !defined(NO_OLD_TLS)
 6446    WOLFSSL_METHOD* wolfSSLv2_client_method(void)
 6447    {
 6448        WOLFSSL_STUB("wolfSSLv2_client_method");
 6449        return NULL;
 6450    }
 6451    #endif
 6452
 6453    #if defined(WOLFSSL_ALLOW_SSLV3) && !defined(NO_OLD_TLS)
 6454    WOLFSSL_METHOD* wolfSSLv3_client_method(void)
 6455    {
 6456        return wolfSSLv3_client_method_ex(NULL);
 6457    }
 6458    WOLFSSL_METHOD* wolfSSLv3_client_method_ex(void* heap)
 6459    {
 6460        WOLFSSL_METHOD* method =
 6461                              (WOLFSSL_METHOD*) XMALLOC(sizeof(WOLFSSL_METHOD),
 6462                                                     heap, DYNAMIC_TYPE_METHOD);
 6463        (void)heap;
 6464        WOLFSSL_ENTER("wolfSSLv3_client_method_ex");
 6465        if (method)
 6466            InitSSL_Method(method, MakeSSLv3());
 6467        return method;
 6468    }
 6469    #endif /* WOLFSSL_ALLOW_SSLV3 && !NO_OLD_TLS */
 6470
 6471
 6472    WOLFSSL_METHOD* wolfSSLv23_client_method(void)
 6473    {
 6474        return wolfSSLv23_client_method_ex(NULL);
 6475    }
 6476    WOLFSSL_METHOD* wolfSSLv23_client_method_ex(void* heap)
 6477    {
 6478        WOLFSSL_METHOD* method =
 6479                              (WOLFSSL_METHOD*) XMALLOC(sizeof(WOLFSSL_METHOD),
 6480                                                     heap, DYNAMIC_TYPE_METHOD);
 6481        (void)heap;
 6482        WOLFSSL_ENTER("wolfSSLv23_client_method_ex");
 6483        if (method) {
 6484    #if !defined(NO_SHA256) || defined(WOLFSSL_SHA384) || \
 6485        defined(WOLFSSL_SHA512)
 6486        #if defined(WOLFSSL_TLS13)
 6487            InitSSL_Method(method, MakeTLSv1_3());
 6488        #elif !defined(WOLFSSL_NO_TLS12)
 6489            InitSSL_Method(method, MakeTLSv1_2());
 6490        #elif !defined(NO_OLD_TLS)
 6491            InitSSL_Method(method, MakeTLSv1_1());
 6492        #endif
 6493    #else
 6494        #ifndef NO_OLD_TLS
 6495            InitSSL_Method(method, MakeTLSv1_1());
 6496        #endif
 6497    #endif
 6498    #if !defined(NO_OLD_TLS) || defined(WOLFSSL_TLS13)
 6499            method->downgrade = 1;
 6500    #endif
 6501        }
 6502        return method;
 6503    }
 6504
 6505    /* please see note at top of README if you get an error from connect */
 6506    WOLFSSL_ABI
 6507    int wolfSSL_connect(WOLFSSL* ssl)
 6508    {
 6509    #if !(defined(WOLFSSL_NO_TLS12) && defined(NO_OLD_TLS) && \
 6510          defined(WOLFSSL_TLS13))
 6511        int neededState;
 6512        byte advanceState;
 6513    #endif
 6514        int ret = 0;
 6515
 6516        (void)ret;
 6517
 6518        #ifdef HAVE_ERRNO_H
 6519            errno = 0;
 6520        #endif
 6521
 6522        if (ssl == NULL)
 6523            return BAD_FUNC_ARG;
 6524
 6525    #if defined(OPENSSL_EXTRA) || defined(WOLFSSL_EITHER_SIDE)
 6526        if (ssl->options.side == WOLFSSL_NEITHER_END) {
 6527            ssl->error = InitSSL_Side(ssl, WOLFSSL_CLIENT_END);
 6528            if (ssl->error != WOLFSSL_SUCCESS) {
 6529                WOLFSSL_ERROR(ssl->error);
 6530                return WOLFSSL_FATAL_ERROR;
 6531            }
 6532            ssl->error = 0; /* expected to be zero here */
 6533        }
 6534
 6535    #ifdef OPENSSL_EXTRA
 6536        if (ssl->CBIS != NULL) {
 6537            ssl->CBIS(ssl, WOLFSSL_ST_CONNECT, WOLFSSL_SUCCESS);
 6538            ssl->cbmode = WOLFSSL_CB_WRITE;
 6539        }
 6540    #endif
 6541    #endif /* OPENSSL_EXTRA || WOLFSSL_EITHER_SIDE */
 6542
 6543    #if defined(WOLFSSL_NO_TLS12) && defined(NO_OLD_TLS) && \
 6544        defined(WOLFSSL_TLS13)
 6545        return wolfSSL_connect_TLSv13(ssl);
 6546    #else
 6547        #ifdef WOLFSSL_TLS13
 6548        if (ssl->options.tls1_3) {
 6549            WOLFSSL_MSG("TLS 1.3");
 6550            return wolfSSL_connect_TLSv13(ssl);
 6551        }
 6552        #endif
 6553
 6554        WOLFSSL_MSG("TLS 1.2 or lower");
 6555        WOLFSSL_ENTER("wolfSSL_connect");
 6556
 6557        /* make sure this wolfSSL object has arrays and rng setup. Protects
 6558         * case where the WOLFSSL object is reused via wolfSSL_clear() */
 6559        if ((ret = ReinitSSL(ssl, ssl->ctx, 0)) != 0) {
 6560            return ret;
 6561        }
 6562
 6563#ifdef WOLFSSL_WOLFSENTRY_HOOKS
 6564        if ((ssl->ConnectFilter != NULL) &&
 6565            (ssl->options.connectState == CONNECT_BEGIN)) {
 6566            wolfSSL_netfilter_decision_t res;
 6567            if ((ssl->ConnectFilter(ssl, ssl->ConnectFilter_arg, &res) ==
 6568                 WOLFSSL_SUCCESS) &&
 6569                (res == WOLFSSL_NETFILTER_REJECT)) {
 6570                ssl->error = SOCKET_FILTERED_E;
 6571                WOLFSSL_ERROR(ssl->error);
 6572                return WOLFSSL_FATAL_ERROR;
 6573            }
 6574        }
 6575#endif /* WOLFSSL_WOLFSENTRY_HOOKS */
 6576
 6577        if (ssl->options.side != WOLFSSL_CLIENT_END) {
 6578            ssl->error = SIDE_ERROR;
 6579            WOLFSSL_ERROR(ssl->error);
 6580            return WOLFSSL_FATAL_ERROR;
 6581        }
 6582
 6583        #ifdef WOLFSSL_DTLS
 6584        if (ssl->version.major == DTLS_MAJOR) {
 6585            ssl->options.dtls   = 1;
 6586            ssl->options.tls    = 1;
 6587            ssl->options.tls1_1 = 1;
 6588            ssl->options.dtlsStateful = 1;
 6589        }
 6590        #endif
 6591
 6592        /* fragOffset is non-zero when sending fragments. On the last
 6593         * fragment, fragOffset is zero again, and the state can be
 6594         * advanced. */
 6595        advanceState = ssl->fragOffset == 0 &&
 6596            (ssl->options.connectState == CONNECT_BEGIN ||
 6597             ssl->options.connectState == HELLO_AGAIN ||
 6598             (ssl->options.connectState >= FIRST_REPLY_DONE &&
 6599              ssl->options.connectState <= FIRST_REPLY_FOURTH));
 6600
 6601#ifdef WOLFSSL_DTLS13
 6602        if (ssl->options.dtls && IsAtLeastTLSv1_3(ssl->version))
 6603            advanceState = advanceState && !ssl->dtls13SendingAckOrRtx;
 6604#endif /* WOLFSSL_DTLS13 */
 6605
 6606        if (ssl->buffers.outputBuffer.length > 0
 6607        #ifdef WOLFSSL_ASYNC_CRYPT
 6608            /* do not send buffered or advance state if last error was an
 6609                async pending operation */
 6610            && ssl->error != WC_NO_ERR_TRACE(WC_PENDING_E)
 6611        #endif
 6612        ) {
 6613            ret = SendBuffered(ssl);
 6614            if (ret == 0) {
 6615                if (ssl->fragOffset == 0 && !ssl->options.buildingMsg) {
 6616                    if (advanceState) {
 6617                        ssl->options.connectState++;
 6618                        WOLFSSL_MSG("connect state: Advanced from last "
 6619                                    "buffered fragment send");
 6620                    #ifdef WOLFSSL_ASYNC_IO
 6621                        /* Cleanup async */
 6622                        FreeAsyncCtx(ssl, 0);
 6623                    #endif
 6624                    }
 6625                }
 6626                else {
 6627                    WOLFSSL_MSG("connect state: "
 6628                                "Not advanced, more fragments to send");
 6629                }
 6630            }
 6631            else {
 6632                ssl->error = ret;
 6633                WOLFSSL_ERROR(ssl->error);
 6634                return WOLFSSL_FATAL_ERROR;
 6635            }
 6636#ifdef WOLFSSL_DTLS13
 6637            if (ssl->options.dtls)
 6638                ssl->dtls13SendingAckOrRtx = 0;
 6639#endif /* WOLFSSL_DTLS13 */
 6640        }
 6641
 6642        ret = RetrySendAlert(ssl);
 6643        if (ret != 0) {
 6644            ssl->error = ret;
 6645            WOLFSSL_ERROR(ssl->error);
 6646            return WOLFSSL_FATAL_ERROR;
 6647        }
 6648
 6649        switch (ssl->options.connectState) {
 6650
 6651        case CONNECT_BEGIN :
 6652            /* always send client hello first */
 6653            if ( (ssl->error = SendClientHello(ssl)) != 0) {
 6654                WOLFSSL_ERROR(ssl->error);
 6655                return WOLFSSL_FATAL_ERROR;
 6656            }
 6657            ssl->options.connectState = CLIENT_HELLO_SENT;
 6658            WOLFSSL_MSG("connect state: CLIENT_HELLO_SENT");
 6659            FALL_THROUGH;
 6660
 6661        case CLIENT_HELLO_SENT :
 6662            neededState = ssl->options.resuming ? SERVER_FINISHED_COMPLETE :
 6663                                          SERVER_HELLODONE_COMPLETE;
 6664            #ifdef WOLFSSL_DTLS
 6665                /* In DTLS, when resuming, we can go straight to FINISHED,
 6666                 * or do a cookie exchange and then skip to FINISHED, assume
 6667                 * we need the cookie exchange first. */
 6668                if (IsDtlsNotSctpMode(ssl))
 6669                    neededState = SERVER_HELLOVERIFYREQUEST_COMPLETE;
 6670            #endif
 6671            /* get response */
 6672            WOLFSSL_MSG("Server state up to needed state.");
 6673            while (ssl->options.serverState < neededState) {
 6674                WOLFSSL_MSG("Progressing server state...");
 6675                #ifdef WOLFSSL_TLS13
 6676                    if (ssl->options.tls1_3)
 6677                        return wolfSSL_connect_TLSv13(ssl);
 6678                #endif
 6679                WOLFSSL_MSG("ProcessReply...");
 6680                if ( (ssl->error = ProcessReply(ssl)) < 0) {
 6681                    WOLFSSL_ERROR(ssl->error);
 6682                    return WOLFSSL_FATAL_ERROR;
 6683                }
 6684                /* if resumption failed, reset needed state */
 6685                else if (neededState == SERVER_FINISHED_COMPLETE) {
 6686                    if (!ssl->options.resuming) {
 6687                    #ifdef WOLFSSL_DTLS
 6688                        if (IsDtlsNotSctpMode(ssl))
 6689                            neededState = SERVER_HELLOVERIFYREQUEST_COMPLETE;
 6690                        else
 6691                    #endif
 6692                            neededState = SERVER_HELLODONE_COMPLETE;
 6693                    }
 6694                }
 6695                WOLFSSL_MSG("ProcessReply done.");
 6696
 6697#ifdef WOLFSSL_DTLS13
 6698                if (ssl->options.dtls && IsAtLeastTLSv1_3(ssl->version)
 6699                    && ssl->dtls13Rtx.sendAcks == 1
 6700                    && ssl->options.seenUnifiedHdr) {
 6701                    /* we aren't negotiated the version yet, so we aren't sure
 6702                     * the other end can speak v1.3. On the other side we have
 6703                     * received a unified records, assuming that the
 6704                     * ServerHello got lost, we will send an empty ACK. In case
 6705                     * the server is a DTLS with version less than 1.3, it
 6706                     * should just ignore the message */
 6707                    ssl->dtls13Rtx.sendAcks = 0;
 6708                    if ((ssl->error = SendDtls13Ack(ssl)) < 0) {
 6709                        if (ssl->error == WC_NO_ERR_TRACE(WANT_WRITE))
 6710                            ssl->dtls13SendingAckOrRtx = 1;
 6711                        WOLFSSL_ERROR(ssl->error);
 6712                        return WOLFSSL_FATAL_ERROR;
 6713                    }
 6714                }
 6715#endif /* WOLFSSL_DTLS13 */
 6716            }
 6717
 6718            ssl->options.connectState = HELLO_AGAIN;
 6719            WOLFSSL_MSG("connect state: HELLO_AGAIN");
 6720            FALL_THROUGH;
 6721
 6722        case HELLO_AGAIN :
 6723
 6724        #ifdef WOLFSSL_TLS13
 6725            if (ssl->options.tls1_3)
 6726                return wolfSSL_connect_TLSv13(ssl);
 6727        #endif
 6728
 6729            #ifdef WOLFSSL_DTLS
 6730            if (ssl->options.serverState ==
 6731                    SERVER_HELLOVERIFYREQUEST_COMPLETE) {
 6732                if (IsDtlsNotSctpMode(ssl)) {
 6733                    /* re-init hashes, exclude first hello and verify request */
 6734                    if ((ssl->error = InitHandshakeHashes(ssl)) != 0) {
 6735                        WOLFSSL_ERROR(ssl->error);
 6736                        return WOLFSSL_FATAL_ERROR;
 6737                    }
 6738                    if ( (ssl->error = SendClientHello(ssl)) != 0) {
 6739                        WOLFSSL_ERROR(ssl->error);
 6740                        return WOLFSSL_FATAL_ERROR;
 6741                    }
 6742                }
 6743            }
 6744            #endif
 6745
 6746            ssl->options.connectState = HELLO_AGAIN_REPLY;
 6747            WOLFSSL_MSG("connect state: HELLO_AGAIN_REPLY");
 6748            FALL_THROUGH;
 6749
 6750        case HELLO_AGAIN_REPLY :
 6751            #ifdef WOLFSSL_DTLS
 6752                if (IsDtlsNotSctpMode(ssl)) {
 6753                    neededState = ssl->options.resuming ?
 6754                           SERVER_FINISHED_COMPLETE : SERVER_HELLODONE_COMPLETE;
 6755
 6756                    /* get response */
 6757                    while (ssl->options.serverState < neededState) {
 6758                        if ( (ssl->error = ProcessReply(ssl)) < 0) {
 6759                            WOLFSSL_ERROR(ssl->error);
 6760                            return WOLFSSL_FATAL_ERROR;
 6761                        }
 6762                        /* if resumption failed, reset needed state */
 6763                        if (neededState == SERVER_FINISHED_COMPLETE) {
 6764                            if (!ssl->options.resuming)
 6765                                neededState = SERVER_HELLODONE_COMPLETE;
 6766                        }
 6767                    }
 6768                }
 6769            #endif
 6770
 6771            ssl->options.connectState = FIRST_REPLY_DONE;
 6772            WOLFSSL_MSG("connect state: FIRST_REPLY_DONE");
 6773            FALL_THROUGH;
 6774
 6775        case FIRST_REPLY_DONE :
 6776            if (ssl->options.certOnly)
 6777                return WOLFSSL_SUCCESS;
 6778            #if !defined(NO_CERTS) && !defined(WOLFSSL_NO_CLIENT_AUTH)
 6779                #ifdef WOLFSSL_TLS13
 6780                    if (ssl->options.tls1_3)
 6781                        return wolfSSL_connect_TLSv13(ssl);
 6782                #endif
 6783                if (ssl->options.sendVerify) {
 6784                    if ( (ssl->error = SendCertificate(ssl)) != 0) {
 6785                        wolfssl_local_MaybeCheckAlertOnErr(ssl, ssl->error);
 6786                        WOLFSSL_ERROR(ssl->error);
 6787                        return WOLFSSL_FATAL_ERROR;
 6788                    }
 6789                    WOLFSSL_MSG("sent: certificate");
 6790                }
 6791
 6792            #endif
 6793            ssl->options.connectState = FIRST_REPLY_FIRST;
 6794            WOLFSSL_MSG("connect state: FIRST_REPLY_FIRST");
 6795            FALL_THROUGH;
 6796
 6797        case FIRST_REPLY_FIRST :
 6798        #ifdef WOLFSSL_TLS13
 6799            if (ssl->options.tls1_3)
 6800                return wolfSSL_connect_TLSv13(ssl);
 6801        #endif
 6802            if (!ssl->options.resuming) {
 6803                if ( (ssl->error = SendClientKeyExchange(ssl)) != 0) {
 6804                    wolfssl_local_MaybeCheckAlertOnErr(ssl, ssl->error);
 6805#ifdef WOLFSSL_EXTRA_ALERTS
 6806                    if (ssl->error == WC_NO_ERR_TRACE(NO_PEER_KEY) ||
 6807                        ssl->error == WC_NO_ERR_TRACE(PSK_KEY_ERROR)) {
 6808                        SendAlert(ssl, alert_fatal, handshake_failure);
 6809                    }
 6810#endif
 6811                    WOLFSSL_ERROR(ssl->error);
 6812                    return WOLFSSL_FATAL_ERROR;
 6813                }
 6814                WOLFSSL_MSG("sent: client key exchange");
 6815            }
 6816
 6817            ssl->options.connectState = FIRST_REPLY_SECOND;
 6818            WOLFSSL_MSG("connect state: FIRST_REPLY_SECOND");
 6819            FALL_THROUGH;
 6820
 6821    #if !defined(WOLFSSL_NO_TLS12) || !defined(NO_OLD_TLS)
 6822        case FIRST_REPLY_SECOND :
 6823            /* CLIENT: Fail-safe for Server Authentication. */
 6824            if (!ssl->options.peerAuthGood) {
 6825                WOLFSSL_MSG("Server authentication did not happen");
 6826                ssl->error = NO_PEER_VERIFY;
 6827                return WOLFSSL_FATAL_ERROR;
 6828            }
 6829
 6830            #if !defined(NO_CERTS) && !defined(WOLFSSL_NO_CLIENT_AUTH)
 6831                if (ssl->options.sendVerify) {
 6832                    if ( (ssl->error = SendCertificateVerify(ssl)) != 0) {
 6833                        wolfssl_local_MaybeCheckAlertOnErr(ssl, ssl->error);
 6834                        WOLFSSL_ERROR(ssl->error);
 6835                        return WOLFSSL_FATAL_ERROR;
 6836                    }
 6837                    WOLFSSL_MSG("sent: certificate verify");
 6838                }
 6839            #endif /* !NO_CERTS && !WOLFSSL_NO_CLIENT_AUTH */
 6840            ssl->options.connectState = FIRST_REPLY_THIRD;
 6841            WOLFSSL_MSG("connect state: FIRST_REPLY_THIRD");
 6842            FALL_THROUGH;
 6843
 6844        case FIRST_REPLY_THIRD :
 6845            if ( (ssl->error = SendChangeCipher(ssl)) != 0) {
 6846                wolfssl_local_MaybeCheckAlertOnErr(ssl, ssl->error);
 6847                WOLFSSL_ERROR(ssl->error);
 6848                return WOLFSSL_FATAL_ERROR;
 6849            }
 6850            WOLFSSL_MSG("sent: change cipher spec");
 6851            ssl->options.connectState = FIRST_REPLY_FOURTH;
 6852            WOLFSSL_MSG("connect state: FIRST_REPLY_FOURTH");
 6853            FALL_THROUGH;
 6854
 6855        case FIRST_REPLY_FOURTH :
 6856            if ( (ssl->error = SendFinished(ssl)) != 0) {
 6857                wolfssl_local_MaybeCheckAlertOnErr(ssl, ssl->error);
 6858                WOLFSSL_ERROR(ssl->error);
 6859                return WOLFSSL_FATAL_ERROR;
 6860            }
 6861            WOLFSSL_MSG("sent: finished");
 6862            ssl->options.connectState = FINISHED_DONE;
 6863            WOLFSSL_MSG("connect state: FINISHED_DONE");
 6864            FALL_THROUGH;
 6865
 6866#ifdef WOLFSSL_DTLS13
 6867        case WAIT_FINISHED_ACK:
 6868            ssl->options.connectState = FINISHED_DONE;
 6869            FALL_THROUGH;
 6870#endif /* WOLFSSL_DTLS13 */
 6871
 6872        case FINISHED_DONE :
 6873            /* get response */
 6874            while (ssl->options.serverState < SERVER_FINISHED_COMPLETE)
 6875                if ( (ssl->error = ProcessReply(ssl)) < 0) {
 6876                    WOLFSSL_ERROR(ssl->error);
 6877                    return WOLFSSL_FATAL_ERROR;
 6878                }
 6879
 6880            ssl->options.connectState = SECOND_REPLY_DONE;
 6881            WOLFSSL_MSG("connect state: SECOND_REPLY_DONE");
 6882            FALL_THROUGH;
 6883
 6884        case SECOND_REPLY_DONE:
 6885        #ifndef NO_HANDSHAKE_DONE_CB
 6886            if (ssl->hsDoneCb) {
 6887                int cbret = ssl->hsDoneCb(ssl, ssl->hsDoneCtx);
 6888                if (cbret < 0) {
 6889                    ssl->error = cbret;
 6890                    WOLFSSL_MSG("HandShake Done Cb don't continue error");
 6891                    return WOLFSSL_FATAL_ERROR;
 6892                }
 6893            }
 6894        #endif /* NO_HANDSHAKE_DONE_CB */
 6895
 6896            if (!ssl->options.dtls) {
 6897                if (!ssl->options.keepResources) {
 6898                    FreeHandshakeResources(ssl);
 6899                }
 6900            }
 6901        #ifdef WOLFSSL_DTLS
 6902            else {
 6903                ssl->options.dtlsHsRetain = 1;
 6904            }
 6905        #endif /* WOLFSSL_DTLS */
 6906
 6907        #if defined(WOLFSSL_ASYNC_CRYPT) && defined(HAVE_SECURE_RENEGOTIATION)
 6908            /* This may be necessary in async so that we don't try to
 6909             * renegotiate again */
 6910            if (ssl->secure_renegotiation &&
 6911                    ssl->secure_renegotiation->startScr) {
 6912                ssl->secure_renegotiation->startScr = 0;
 6913            }
 6914        #endif /* WOLFSSL_ASYNC_CRYPT && HAVE_SECURE_RENEGOTIATION */
 6915        #if defined(WOLFSSL_ASYNC_IO) && !defined(WOLFSSL_ASYNC_CRYPT)
 6916            /* Free the remaining async context if not using it for crypto */
 6917            FreeAsyncCtx(ssl, 1);
 6918        #endif
 6919
 6920            ssl->error = 0; /* clear the error */
 6921
 6922            WOLFSSL_LEAVE("wolfSSL_connect", WOLFSSL_SUCCESS);
 6923            return WOLFSSL_SUCCESS;
 6924    #endif /* !WOLFSSL_NO_TLS12 || !NO_OLD_TLS */
 6925
 6926        default:
 6927            WOLFSSL_MSG("Unknown connect state ERROR");
 6928            return WOLFSSL_FATAL_ERROR; /* unknown connect state */
 6929        }
 6930    #endif /* !WOLFSSL_NO_TLS12 || !NO_OLD_TLS || !WOLFSSL_TLS13 */
 6931    }
 6932
 6933#endif /* !NO_WOLFSSL_CLIENT && !NO_TLS */
 6934/* end client only parts */
 6935
 6936/* server only parts */
 6937#if !defined(NO_WOLFSSL_SERVER) && !defined(NO_TLS)
 6938
 6939    #if defined(OPENSSL_EXTRA) && !defined(NO_OLD_TLS)
 6940    WOLFSSL_METHOD* wolfSSLv2_server_method(void)
 6941    {
 6942        WOLFSSL_STUB("wolfSSLv2_server_method");
 6943        return 0;
 6944    }
 6945    #endif
 6946
 6947    #if defined(WOLFSSL_ALLOW_SSLV3) && !defined(NO_OLD_TLS)
 6948    WOLFSSL_METHOD* wolfSSLv3_server_method(void)
 6949    {
 6950        return wolfSSLv3_server_method_ex(NULL);
 6951    }
 6952    WOLFSSL_METHOD* wolfSSLv3_server_method_ex(void* heap)
 6953    {
 6954        WOLFSSL_METHOD* method =
 6955                              (WOLFSSL_METHOD*) XMALLOC(sizeof(WOLFSSL_METHOD),
 6956                                                     heap, DYNAMIC_TYPE_METHOD);
 6957        (void)heap;
 6958        WOLFSSL_ENTER("wolfSSLv3_server_method_ex");
 6959        if (method) {
 6960            InitSSL_Method(method, MakeSSLv3());
 6961            method->side = WOLFSSL_SERVER_END;
 6962        }
 6963        return method;
 6964    }
 6965    #endif /* WOLFSSL_ALLOW_SSLV3 && !NO_OLD_TLS */
 6966
 6967    WOLFSSL_METHOD* wolfSSLv23_server_method(void)
 6968    {
 6969        return wolfSSLv23_server_method_ex(NULL);
 6970    }
 6971
 6972    WOLFSSL_METHOD* wolfSSLv23_server_method_ex(void* heap)
 6973    {
 6974        WOLFSSL_METHOD* method =
 6975                              (WOLFSSL_METHOD*) XMALLOC(sizeof(WOLFSSL_METHOD),
 6976                                                     heap, DYNAMIC_TYPE_METHOD);
 6977        (void)heap;
 6978        WOLFSSL_ENTER("wolfSSLv23_server_method_ex");
 6979        if (method) {
 6980    #if !defined(NO_SHA256) || defined(WOLFSSL_SHA384) || \
 6981        defined(WOLFSSL_SHA512)
 6982        #ifdef WOLFSSL_TLS13
 6983            InitSSL_Method(method, MakeTLSv1_3());
 6984        #elif !defined(WOLFSSL_NO_TLS12)
 6985            InitSSL_Method(method, MakeTLSv1_2());
 6986        #elif !defined(NO_OLD_TLS)
 6987            InitSSL_Method(method, MakeTLSv1_1());
 6988        #endif
 6989    #else
 6990        #ifndef NO_OLD_TLS
 6991            InitSSL_Method(method, MakeTLSv1_1());
 6992        #else
 6993            #error Must have SHA256, SHA384 or SHA512 enabled for TLS 1.2
 6994        #endif
 6995    #endif
 6996    #if !defined(NO_OLD_TLS) || defined(WOLFSSL_TLS13)
 6997            method->downgrade = 1;
 6998    #endif
 6999            method->side      = WOLFSSL_SERVER_END;
 7000        }
 7001        return method;
 7002    }
 7003
 7004
 7005    WOLFSSL_ABI
 7006    int wolfSSL_accept(WOLFSSL* ssl)
 7007    {
 7008#if !(defined(WOLFSSL_NO_TLS12) && defined(NO_OLD_TLS) && \
 7009    defined(WOLFSSL_TLS13))
 7010        word16 havePSK = 0;
 7011        word16 haveAnon = 0;
 7012        word16 haveMcast = 0;
 7013#endif
 7014        int ret = 0;
 7015
 7016        (void)ret;
 7017
 7018        if (ssl == NULL)
 7019            return WOLFSSL_FATAL_ERROR;
 7020
 7021    #if defined(OPENSSL_EXTRA) || defined(WOLFSSL_EITHER_SIDE)
 7022        if (ssl->options.side == WOLFSSL_NEITHER_END) {
 7023            WOLFSSL_MSG("Setting WOLFSSL_SSL to be server side");
 7024            ssl->error = InitSSL_Side(ssl, WOLFSSL_SERVER_END);
 7025            if (ssl->error != WOLFSSL_SUCCESS) {
 7026                WOLFSSL_ERROR(ssl->error);
 7027                return WOLFSSL_FATAL_ERROR;
 7028            }
 7029            ssl->error = 0; /* expected to be zero here */
 7030        }
 7031    #endif /* OPENSSL_EXTRA || WOLFSSL_EITHER_SIDE */
 7032
 7033#if defined(WOLFSSL_NO_TLS12) && defined(NO_OLD_TLS) && defined(WOLFSSL_TLS13)
 7034        return wolfSSL_accept_TLSv13(ssl);
 7035#else
 7036    #ifdef WOLFSSL_TLS13
 7037        if (ssl->options.tls1_3)
 7038            return wolfSSL_accept_TLSv13(ssl);
 7039    #endif
 7040        WOLFSSL_ENTER("wolfSSL_accept");
 7041
 7042        /* make sure this wolfSSL object has arrays and rng setup. Protects
 7043         * case where the WOLFSSL object is reused via wolfSSL_clear() */
 7044        if ((ret = ReinitSSL(ssl, ssl->ctx, 0)) != 0) {
 7045            return ret;
 7046        }
 7047
 7048#ifdef WOLFSSL_WOLFSENTRY_HOOKS
 7049        if ((ssl->AcceptFilter != NULL) &&
 7050            ((ssl->options.acceptState == ACCEPT_BEGIN)
 7051#ifdef HAVE_SECURE_RENEGOTIATION
 7052             || (ssl->options.acceptState == ACCEPT_BEGIN_RENEG)
 7053#endif
 7054                ))
 7055        {
 7056            wolfSSL_netfilter_decision_t res;
 7057            if ((ssl->AcceptFilter(ssl, ssl->AcceptFilter_arg, &res) ==
 7058                 WOLFSSL_SUCCESS) &&
 7059                (res == WOLFSSL_NETFILTER_REJECT)) {
 7060                ssl->error = SOCKET_FILTERED_E;
 7061                WOLFSSL_ERROR(ssl->error);
 7062                return WOLFSSL_FATAL_ERROR;
 7063            }
 7064        }
 7065#endif /* WOLFSSL_WOLFSENTRY_HOOKS */
 7066
 7067        #ifdef HAVE_ERRNO_H
 7068            errno = 0;
 7069        #endif
 7070
 7071        #ifndef NO_PSK
 7072            havePSK = ssl->options.havePSK;
 7073        #endif
 7074        (void)havePSK;
 7075
 7076        #ifdef HAVE_ANON
 7077            haveAnon = ssl->options.useAnon;
 7078        #endif
 7079        (void)haveAnon;
 7080
 7081        #ifdef WOLFSSL_MULTICAST
 7082            haveMcast = ssl->options.haveMcast;
 7083        #endif
 7084        (void)haveMcast;
 7085
 7086        if (ssl->options.side != WOLFSSL_SERVER_END) {
 7087            ssl->error = SIDE_ERROR;
 7088            WOLFSSL_ERROR(ssl->error);
 7089            return WOLFSSL_FATAL_ERROR;
 7090        }
 7091
 7092    #ifndef NO_CERTS
 7093        /* in case used set_accept_state after init */
 7094        if (!havePSK && !haveAnon && !haveMcast) {
 7095        #ifdef WOLFSSL_CERT_SETUP_CB
 7096            if (ssl->ctx->certSetupCb != NULL) {
 7097                WOLFSSL_MSG("CertSetupCb set. server cert and "
 7098                            "key not checked");
 7099            }
 7100            else
 7101        #endif
 7102            {
 7103                if (!ssl->buffers.certificate ||
 7104                    !ssl->buffers.certificate->buffer) {
 7105
 7106                    WOLFSSL_MSG("accept error: server cert required");
 7107                    ssl->error = NO_PRIVATE_KEY;
 7108                    WOLFSSL_ERROR(ssl->error);
 7109                    return WOLFSSL_FATAL_ERROR;
 7110                }
 7111
 7112                if (!ssl->buffers.key || !ssl->buffers.key->buffer) {
 7113                    /* allow no private key if using existing key */
 7114                #ifdef WOLF_PRIVATE_KEY_ID
 7115                    if (ssl->devId != INVALID_DEVID
 7116                    #ifdef HAVE_PK_CALLBACKS
 7117                        || wolfSSL_CTX_IsPrivatePkSet(ssl->ctx)
 7118                    #endif
 7119                    ) {
 7120                        WOLFSSL_MSG("Allowing no server private key "
 7121                                    "(external)");
 7122                    }
 7123                    else
 7124                #endif
 7125                    {
 7126                        WOLFSSL_MSG("accept error: server key required");
 7127                        ssl->error = NO_PRIVATE_KEY;
 7128                        WOLFSSL_ERROR(ssl->error);
 7129                        return WOLFSSL_FATAL_ERROR;
 7130                    }
 7131                }
 7132            }
 7133        }
 7134    #endif
 7135
 7136    #ifdef WOLFSSL_DTLS
 7137        if (ssl->version.major == DTLS_MAJOR) {
 7138            ssl->options.dtls   = 1;
 7139            ssl->options.tls    = 1;
 7140            ssl->options.tls1_1 = 1;
 7141            if (!IsDtlsNotSctpMode(ssl) || IsSCR(ssl))
 7142                ssl->options.dtlsStateful = 1;
 7143        }
 7144    #endif
 7145
 7146        if (ssl->buffers.outputBuffer.length > 0
 7147        #ifdef WOLFSSL_ASYNC_CRYPT
 7148            /* do not send buffered or advance state if last error was an
 7149                async pending operation */
 7150            && ssl->error != WC_NO_ERR_TRACE(WC_PENDING_E)
 7151        #endif
 7152        ) {
 7153            ret = SendBuffered(ssl);
 7154            if (ret == 0) {
 7155                /* fragOffset is non-zero when sending fragments. On the last
 7156                 * fragment, fragOffset is zero again, and the state can be
 7157                 * advanced. */
 7158                if (ssl->fragOffset == 0 && !ssl->options.buildingMsg) {
 7159                    if (ssl->options.acceptState == ACCEPT_FIRST_REPLY_DONE ||
 7160                        ssl->options.acceptState == SERVER_HELLO_SENT ||
 7161                        ssl->options.acceptState == CERT_SENT ||
 7162                        ssl->options.acceptState == CERT_STATUS_SENT ||
 7163                        ssl->options.acceptState == KEY_EXCHANGE_SENT ||
 7164                        ssl->options.acceptState == CERT_REQ_SENT ||
 7165                        ssl->options.acceptState == ACCEPT_SECOND_REPLY_DONE ||
 7166                        ssl->options.acceptState == TICKET_SENT ||
 7167                        ssl->options.acceptState == CHANGE_CIPHER_SENT) {
 7168                        ssl->options.acceptState++;
 7169                        WOLFSSL_MSG("accept state: Advanced from last "
 7170                                    "buffered fragment send");
 7171                    #ifdef WOLFSSL_ASYNC_IO
 7172                        /* Cleanup async */
 7173                        FreeAsyncCtx(ssl, 0);
 7174                    #endif
 7175                    }
 7176                }
 7177                else {
 7178                    WOLFSSL_MSG("accept state: "
 7179                                "Not advanced, more fragments to send");
 7180                }
 7181            }
 7182            else {
 7183                ssl->error = ret;
 7184                WOLFSSL_ERROR(ssl->error);
 7185                return WOLFSSL_FATAL_ERROR;
 7186            }
 7187#ifdef WOLFSSL_DTLS13
 7188            if (ssl->options.dtls)
 7189                ssl->dtls13SendingAckOrRtx = 0;
 7190#endif /* WOLFSSL_DTLS13 */
 7191        }
 7192
 7193        ret = RetrySendAlert(ssl);
 7194        if (ret != 0) {
 7195            ssl->error = ret;
 7196            WOLFSSL_ERROR(ssl->error);
 7197            return WOLFSSL_FATAL_ERROR;
 7198        }
 7199
 7200        switch (ssl->options.acceptState) {
 7201
 7202        case ACCEPT_BEGIN :
 7203#ifdef HAVE_SECURE_RENEGOTIATION
 7204        case ACCEPT_BEGIN_RENEG:
 7205#endif
 7206            /* get response */
 7207            while (ssl->options.clientState < CLIENT_HELLO_COMPLETE)
 7208                if ( (ssl->error = ProcessReply(ssl)) < 0) {
 7209                    WOLFSSL_ERROR(ssl->error);
 7210                    return WOLFSSL_FATAL_ERROR;
 7211                }
 7212#ifdef WOLFSSL_TLS13
 7213            ssl->options.acceptState = ACCEPT_CLIENT_HELLO_DONE;
 7214            WOLFSSL_MSG("accept state ACCEPT_CLIENT_HELLO_DONE");
 7215            FALL_THROUGH;
 7216
 7217        case ACCEPT_CLIENT_HELLO_DONE :
 7218            if (ssl->options.tls1_3) {
 7219                return wolfSSL_accept_TLSv13(ssl);
 7220            }
 7221#endif
 7222
 7223            ssl->options.acceptState = ACCEPT_FIRST_REPLY_DONE;
 7224            WOLFSSL_MSG("accept state ACCEPT_FIRST_REPLY_DONE");
 7225            FALL_THROUGH;
 7226
 7227        case ACCEPT_FIRST_REPLY_DONE :
 7228            if (ssl->options.returnOnGoodCh) {
 7229                /* Higher level in stack wants us to return. Simulate a
 7230                 * WANT_WRITE to accomplish this. */
 7231                ssl->error = WANT_WRITE;
 7232                return WOLFSSL_FATAL_ERROR;
 7233            }
 7234            if ( (ssl->error = SendServerHello(ssl)) != 0) {
 7235                wolfssl_local_MaybeCheckAlertOnErr(ssl, ssl->error);
 7236                WOLFSSL_ERROR(ssl->error);
 7237                return WOLFSSL_FATAL_ERROR;
 7238            }
 7239            ssl->options.acceptState = SERVER_HELLO_SENT;
 7240            WOLFSSL_MSG("accept state SERVER_HELLO_SENT");
 7241            FALL_THROUGH;
 7242
 7243        case SERVER_HELLO_SENT :
 7244        #ifdef WOLFSSL_TLS13
 7245            if (ssl->options.tls1_3) {
 7246                return wolfSSL_accept_TLSv13(ssl);
 7247            }
 7248        #endif
 7249            #ifndef NO_CERTS
 7250                if (!ssl->options.resuming)
 7251                    if ( (ssl->error = SendCertificate(ssl)) != 0) {
 7252                        wolfssl_local_MaybeCheckAlertOnErr(ssl, ssl->error);
 7253                        WOLFSSL_ERROR(ssl->error);
 7254                        return WOLFSSL_FATAL_ERROR;
 7255                    }
 7256            #endif
 7257            ssl->options.acceptState = CERT_SENT;
 7258            WOLFSSL_MSG("accept state CERT_SENT");
 7259            FALL_THROUGH;
 7260
 7261        case CERT_SENT :
 7262            #ifndef NO_CERTS
 7263            if (!ssl->options.resuming)
 7264                if ( (ssl->error = SendCertificateStatus(ssl)) != 0) {
 7265                    wolfssl_local_MaybeCheckAlertOnErr(ssl, ssl->error);
 7266                    WOLFSSL_ERROR(ssl->error);
 7267                    return WOLFSSL_FATAL_ERROR;
 7268                }
 7269            #endif
 7270            ssl->options.acceptState = CERT_STATUS_SENT;
 7271            WOLFSSL_MSG("accept state CERT_STATUS_SENT");
 7272            FALL_THROUGH;
 7273
 7274        case CERT_STATUS_SENT :
 7275        #ifdef WOLFSSL_TLS13
 7276            if (ssl->options.tls1_3) {
 7277                return wolfSSL_accept_TLSv13(ssl);
 7278            }
 7279        #endif
 7280            if (!ssl->options.resuming)
 7281                if ( (ssl->error = SendServerKeyExchange(ssl)) != 0) {
 7282                    wolfssl_local_MaybeCheckAlertOnErr(ssl, ssl->error);
 7283                    WOLFSSL_ERROR(ssl->error);
 7284                    return WOLFSSL_FATAL_ERROR;
 7285                }
 7286            ssl->options.acceptState = KEY_EXCHANGE_SENT;
 7287            WOLFSSL_MSG("accept state KEY_EXCHANGE_SENT");
 7288            FALL_THROUGH;
 7289
 7290        case KEY_EXCHANGE_SENT :
 7291            #ifndef NO_CERTS
 7292                if (!ssl->options.resuming) {
 7293                    if (ssl->options.verifyPeer) {
 7294                        if ( (ssl->error = SendCertificateRequest(ssl)) != 0) {
 7295                            wolfssl_local_MaybeCheckAlertOnErr(ssl, ssl->error);
 7296                            WOLFSSL_ERROR(ssl->error);
 7297                            return WOLFSSL_FATAL_ERROR;
 7298                        }
 7299                    }
 7300                    else {
 7301                        /* SERVER: Peer auth good if not verifying client. */
 7302                        ssl->options.peerAuthGood = 1;
 7303                    }
 7304                }
 7305            #endif
 7306            ssl->options.acceptState = CERT_REQ_SENT;
 7307            WOLFSSL_MSG("accept state CERT_REQ_SENT");
 7308            FALL_THROUGH;
 7309
 7310        case CERT_REQ_SENT :
 7311            if (!ssl->options.resuming)
 7312                if ( (ssl->error = SendServerHelloDone(ssl)) != 0) {
 7313                    wolfssl_local_MaybeCheckAlertOnErr(ssl, ssl->error);
 7314                    WOLFSSL_ERROR(ssl->error);
 7315                    return WOLFSSL_FATAL_ERROR;
 7316                }
 7317            ssl->options.acceptState = SERVER_HELLO_DONE;
 7318            WOLFSSL_MSG("accept state SERVER_HELLO_DONE");
 7319            FALL_THROUGH;
 7320
 7321        case SERVER_HELLO_DONE :
 7322            if (!ssl->options.resuming) {
 7323                while (ssl->options.clientState < CLIENT_FINISHED_COMPLETE)
 7324                    if ( (ssl->error = ProcessReply(ssl)) < 0) {
 7325                        WOLFSSL_ERROR(ssl->error);
 7326                        return WOLFSSL_FATAL_ERROR;
 7327                    }
 7328            }
 7329            ssl->options.acceptState = ACCEPT_SECOND_REPLY_DONE;
 7330            WOLFSSL_MSG("accept state  ACCEPT_SECOND_REPLY_DONE");
 7331            FALL_THROUGH;
 7332
 7333        case ACCEPT_SECOND_REPLY_DONE :
 7334        #ifndef NO_CERTS
 7335            /* SERVER: When not resuming and verifying peer but no certificate
 7336             * received and not failing when not received then peer auth good.
 7337             */
 7338            if (!ssl->options.resuming && ssl->options.verifyPeer &&
 7339                !ssl->options.havePeerCert && !ssl->options.failNoCert) {
 7340                ssl->options.peerAuthGood = 1;
 7341            }
 7342        #endif /* !NO_CERTS  */
 7343        #ifdef WOLFSSL_NO_CLIENT_AUTH
 7344            if (!ssl->options.resuming) {
 7345                ssl->options.peerAuthGood = 1;
 7346            }
 7347        #endif
 7348
 7349#ifdef HAVE_SESSION_TICKET
 7350            if (ssl->options.createTicket && !ssl->options.noTicketTls12) {
 7351                if ( (ssl->error = SendTicket(ssl)) != 0) {
 7352                    wolfssl_local_MaybeCheckAlertOnErr(ssl, ssl->error);
 7353                    WOLFSSL_MSG("Thought we need ticket but failed");
 7354                    WOLFSSL_ERROR(ssl->error);
 7355                    return WOLFSSL_FATAL_ERROR;
 7356                }
 7357            }
 7358#endif /* HAVE_SESSION_TICKET */
 7359            ssl->options.acceptState = TICKET_SENT;
 7360            WOLFSSL_MSG("accept state  TICKET_SENT");
 7361            FALL_THROUGH;
 7362
 7363        case TICKET_SENT:
 7364            /* SERVER: Fail-safe for CLient Authentication. */
 7365            if (!ssl->options.peerAuthGood) {
 7366                WOLFSSL_MSG("Client authentication did not happen");
 7367                return WOLFSSL_FATAL_ERROR;
 7368            }
 7369
 7370            if ( (ssl->error = SendChangeCipher(ssl)) != 0) {
 7371                wolfssl_local_MaybeCheckAlertOnErr(ssl, ssl->error);
 7372                WOLFSSL_ERROR(ssl->error);
 7373                return WOLFSSL_FATAL_ERROR;
 7374            }
 7375            ssl->options.acceptState = CHANGE_CIPHER_SENT;
 7376            WOLFSSL_MSG("accept state  CHANGE_CIPHER_SENT");
 7377            FALL_THROUGH;
 7378
 7379        case CHANGE_CIPHER_SENT :
 7380            if ( (ssl->error = SendFinished(ssl)) != 0) {
 7381                wolfssl_local_MaybeCheckAlertOnErr(ssl, ssl->error);
 7382                WOLFSSL_ERROR(ssl->error);
 7383                return WOLFSSL_FATAL_ERROR;
 7384            }
 7385
 7386            ssl->options.acceptState = ACCEPT_FINISHED_DONE;
 7387            WOLFSSL_MSG("accept state ACCEPT_FINISHED_DONE");
 7388            FALL_THROUGH;
 7389
 7390        case ACCEPT_FINISHED_DONE :
 7391            if (ssl->options.resuming) {
 7392                while (ssl->options.clientState < CLIENT_FINISHED_COMPLETE) {
 7393                    if ( (ssl->error = ProcessReply(ssl)) < 0) {
 7394                        WOLFSSL_ERROR(ssl->error);
 7395                        return WOLFSSL_FATAL_ERROR;
 7396                    }
 7397                }
 7398            }
 7399            ssl->options.acceptState = ACCEPT_THIRD_REPLY_DONE;
 7400            WOLFSSL_MSG("accept state ACCEPT_THIRD_REPLY_DONE");
 7401            FALL_THROUGH;
 7402
 7403        case ACCEPT_THIRD_REPLY_DONE :
 7404#ifndef NO_HANDSHAKE_DONE_CB
 7405            if (ssl->hsDoneCb) {
 7406                int cbret = ssl->hsDoneCb(ssl, ssl->hsDoneCtx);
 7407                if (cbret < 0) {
 7408                    ssl->error = cbret;
 7409                    WOLFSSL_MSG("HandShake Done Cb don't continue error");
 7410                    return WOLFSSL_FATAL_ERROR;
 7411                }
 7412            }
 7413#endif /* NO_HANDSHAKE_DONE_CB */
 7414
 7415            if (!ssl->options.dtls) {
 7416                if (!ssl->options.keepResources) {
 7417                    FreeHandshakeResources(ssl);
 7418                }
 7419            }
 7420#ifdef WOLFSSL_DTLS
 7421            else {
 7422                ssl->options.dtlsHsRetain = 1;
 7423            }
 7424#endif /* WOLFSSL_DTLS */
 7425
 7426#if defined(WOLFSSL_ASYNC_CRYPT) && defined(HAVE_SECURE_RENEGOTIATION)
 7427            /* This may be necessary in async so that we don't try to
 7428             * renegotiate again */
 7429            if (ssl->secure_renegotiation &&
 7430                    ssl->secure_renegotiation->startScr) {
 7431                ssl->secure_renegotiation->startScr = 0;
 7432            }
 7433#endif /* WOLFSSL_ASYNC_CRYPT && HAVE_SECURE_RENEGOTIATION */
 7434#if defined(WOLFSSL_ASYNC_IO) && !defined(WOLFSSL_ASYNC_CRYPT)
 7435            /* Free the remaining async context if not using it for crypto */
 7436            FreeAsyncCtx(ssl, 1);
 7437#endif
 7438
 7439#if defined(WOLFSSL_SESSION_EXPORT) && defined(WOLFSSL_DTLS)
 7440            if (ssl->dtls_export) {
 7441                if ((ssl->error = wolfSSL_send_session(ssl)) != 0) {
 7442                    WOLFSSL_MSG("Export DTLS session error");
 7443                    WOLFSSL_ERROR(ssl->error);
 7444                    return WOLFSSL_FATAL_ERROR;
 7445                }
 7446            }
 7447#endif
 7448            ssl->error = 0; /* clear the error */
 7449
 7450            WOLFSSL_LEAVE("wolfSSL_accept", WOLFSSL_SUCCESS);
 7451            return WOLFSSL_SUCCESS;
 7452
 7453        default:
 7454            WOLFSSL_MSG("Unknown accept state ERROR");
 7455            return WOLFSSL_FATAL_ERROR;
 7456        }
 7457#endif /* !WOLFSSL_NO_TLS12 */
 7458    }
 7459
 7460#endif /* !NO_WOLFSSL_SERVER && !NO_TLS */
 7461/* end server only parts */
 7462
 7463
 7464#if defined(WOLFSSL_DTLS) && !defined(NO_WOLFSSL_SERVER)
 7465struct chGoodDisableReadCbCtx {
 7466    ClientHelloGoodCb userCb;
 7467    void*             userCtx;
 7468};
 7469
 7470static int chGoodDisableReadCB(WOLFSSL* ssl, void* ctx)
 7471{
 7472    struct chGoodDisableReadCbCtx* cb = (struct chGoodDisableReadCbCtx*)ctx;
 7473    int ret = 0;
 7474    if (cb->userCb != NULL)
 7475        ret = cb->userCb(ssl, cb->userCtx);
 7476    if (ret >= 0)
 7477        wolfSSL_SSLDisableRead(ssl);
 7478    return ret;
 7479}
 7480
 7481/**
 7482 * Statelessly listen for a connection
 7483 * @param ssl The ssl object to use for listening to connections
 7484 * @return WOLFSSL_SUCCESS - ClientHello containing a valid cookie was received
 7485 *                           The connection can be continued with wolfSSL_accept
 7486 *         WOLFSSL_FAILURE - The I/O layer returned WANT_READ. This is either
 7487 *                           because there is no data to read and we are using
 7488 *                           non-blocking sockets or we sent a cookie request
 7489 *                           and we are waiting for a reply. The user should
 7490 *                           call wolfDTLS_accept_stateless again after data
 7491 *                           becomes available in the I/O layer.
 7492 *         WOLFSSL_FATAL_ERROR - A fatal error occurred. The ssl object should
 7493 *                           be free'd and allocated again to continue.
 7494 */
 7495int wolfDTLS_accept_stateless(WOLFSSL* ssl)
 7496{
 7497    byte disableRead;
 7498    int ret = WC_NO_ERR_TRACE(WOLFSSL_FATAL_ERROR);
 7499    struct chGoodDisableReadCbCtx cb;
 7500
 7501    WOLFSSL_ENTER("wolfDTLS_SetChGoodCb");
 7502
 7503    if (ssl == NULL)
 7504        return WOLFSSL_FATAL_ERROR;
 7505
 7506    /* Save this to restore it later */
 7507    disableRead = (byte)ssl->options.disableRead;
 7508    cb.userCb = ssl->chGoodCb;
 7509    cb.userCtx = ssl->chGoodCtx;
 7510
 7511    /* Register our own callback so that we can disable reading */
 7512    if (wolfDTLS_SetChGoodCb(ssl, chGoodDisableReadCB, &cb) != WOLFSSL_SUCCESS)
 7513        return WOLFSSL_FATAL_ERROR;
 7514
 7515    ssl->options.returnOnGoodCh = 1;
 7516    ret = wolfSSL_accept(ssl);
 7517    ssl->options.returnOnGoodCh = 0;
 7518    /* restore user options */
 7519    ssl->options.disableRead = disableRead;
 7520    (void)wolfDTLS_SetChGoodCb(ssl, cb.userCb, cb.userCtx);
 7521    if (ret == WOLFSSL_SUCCESS) {
 7522        WOLFSSL_MSG("should not happen. maybe the user called "
 7523                    "wolfDTLS_accept_stateless instead of wolfSSL_accept");
 7524    }
 7525    else if (ssl->error == WC_NO_ERR_TRACE(WANT_READ) ||
 7526             ssl->error == WC_NO_ERR_TRACE(WANT_WRITE)) {
 7527        ssl->error = 0;
 7528        if (ssl->options.dtlsStateful)
 7529            ret = WOLFSSL_SUCCESS;
 7530        else
 7531            ret = WOLFSSL_FAILURE;
 7532    }
 7533    else {
 7534        ret = WOLFSSL_FATAL_ERROR;
 7535    }
 7536    return ret;
 7537}
 7538
 7539int wolfDTLS_SetChGoodCb(WOLFSSL* ssl, ClientHelloGoodCb cb, void* user_ctx)
 7540{
 7541    WOLFSSL_ENTER("wolfDTLS_SetChGoodCb");
 7542
 7543    if (ssl == NULL)
 7544        return BAD_FUNC_ARG;
 7545
 7546    ssl->chGoodCb  = cb;
 7547    ssl->chGoodCtx = user_ctx;
 7548
 7549    return WOLFSSL_SUCCESS;
 7550}
 7551#endif
 7552
 7553#ifndef NO_HANDSHAKE_DONE_CB
 7554
 7555int wolfSSL_SetHsDoneCb(WOLFSSL* ssl, HandShakeDoneCb cb, void* user_ctx)
 7556{
 7557    WOLFSSL_ENTER("wolfSSL_SetHsDoneCb");
 7558
 7559    if (ssl == NULL)
 7560        return BAD_FUNC_ARG;
 7561
 7562    ssl->hsDoneCb  = cb;
 7563    ssl->hsDoneCtx = user_ctx;
 7564
 7565    return WOLFSSL_SUCCESS;
 7566}
 7567
 7568#endif /* NO_HANDSHAKE_DONE_CB */
 7569
 7570WOLFSSL_ABI
 7571int wolfSSL_Cleanup(void)
 7572{
 7573    int ret = WOLFSSL_SUCCESS; /* Only the first error will be returned */
 7574    int release = 0;
 7575#if !defined(NO_SESSION_CACHE)
 7576    int i;
 7577    int j;
 7578#endif
 7579
 7580    WOLFSSL_ENTER("wolfSSL_Cleanup");
 7581
 7582#ifndef WOLFSSL_MUTEX_INITIALIZER
 7583    if (inits_count_mutex_valid == 1) {
 7584#endif
 7585        if (wc_LockMutex(&inits_count_mutex) != 0) {
 7586            WOLFSSL_MSG("Bad Lock Mutex count");
 7587            return BAD_MUTEX_E;
 7588        }
 7589#ifndef WOLFSSL_MUTEX_INITIALIZER
 7590    }
 7591#endif
 7592
 7593    if (initRefCount > 0) {
 7594        initRefCount = initRefCount - 1;
 7595        if (initRefCount == 0)
 7596            release = 1;
 7597    }
 7598
 7599#ifndef WOLFSSL_MUTEX_INITIALIZER
 7600    if (inits_count_mutex_valid == 1) {
 7601#endif
 7602        wc_UnLockMutex(&inits_count_mutex);
 7603#ifndef WOLFSSL_MUTEX_INITIALIZER
 7604    }
 7605#endif
 7606
 7607    if (!release)
 7608        return ret;
 7609
 7610#if defined(WOLFSSL_SYS_CRYPTO_POLICY)
 7611    wolfSSL_crypto_policy_disable();
 7612#endif /* WOLFSSL_SYS_CRYPTO_POLICY */
 7613
 7614#ifdef OPENSSL_EXTRA
 7615    wolfSSL_BN_free_one();
 7616#endif
 7617
 7618#ifndef NO_SESSION_CACHE
 7619    #ifdef ENABLE_SESSION_CACHE_ROW_LOCK
 7620    for (i = 0; i < SESSION_ROWS; ++i) {
 7621        if ((SessionCache[i].lock_valid == 1) &&
 7622            (wc_FreeRwLock(&SessionCache[i].row_lock) != 0)) {
 7623            if (ret == WOLFSSL_SUCCESS)
 7624                ret = BAD_MUTEX_E;
 7625        }
 7626        SessionCache[i].lock_valid = 0;
 7627    }
 7628    #else
 7629    if ((session_lock_valid == 1) && (wc_FreeRwLock(&session_lock) != 0)) {
 7630        if (ret == WOLFSSL_SUCCESS)
 7631            ret = BAD_MUTEX_E;
 7632    }
 7633    session_lock_valid = 0;
 7634    #endif
 7635    for (i = 0; i < SESSION_ROWS; i++) {
 7636        for (j = 0; j < SESSIONS_PER_ROW; j++) {
 7637    #ifdef SESSION_CACHE_DYNAMIC_MEM
 7638            if (SessionCache[i].Sessions[j]) {
 7639                EvictSessionFromCache(SessionCache[i].Sessions[j]);
 7640                XFREE(SessionCache[i].Sessions[j], SessionCache[i].heap,
 7641                      DYNAMIC_TYPE_SESSION);
 7642                SessionCache[i].Sessions[j] = NULL;
 7643            }
 7644    #else
 7645            EvictSessionFromCache(&SessionCache[i].Sessions[j]);
 7646    #endif
 7647        }
 7648    }
 7649    #ifndef NO_CLIENT_CACHE
 7650    #ifndef WOLFSSL_MUTEX_INITIALIZER
 7651    if ((clisession_mutex_valid == 1) &&
 7652        (wc_FreeMutex(&clisession_mutex) != 0)) {
 7653        if (ret == WOLFSSL_SUCCESS)
 7654            ret = BAD_MUTEX_E;
 7655    }
 7656    clisession_mutex_valid = 0;
 7657    #endif
 7658    #endif
 7659#endif /* !NO_SESSION_CACHE */
 7660
 7661#if !defined(WOLFSSL_MUTEX_INITIALIZER) && \
 7662      !WOLFSSL_CLEANUP_THREADSAFE_BY_ATOMIC_OPS
 7663    if ((inits_count_mutex_valid == 1) &&
 7664            (wc_FreeMutex(&inits_count_mutex) != 0)) {
 7665        if (ret == WOLFSSL_SUCCESS)
 7666            ret = BAD_MUTEX_E;
 7667    }
 7668    inits_count_mutex_valid = 0;
 7669#endif
 7670
 7671#ifdef OPENSSL_EXTRA
 7672    wolfSSL_RAND_Cleanup();
 7673#endif
 7674
 7675    if (wolfCrypt_Cleanup() != 0) {
 7676        WOLFSSL_MSG("Error with wolfCrypt_Cleanup call");
 7677        if (ret == WOLFSSL_SUCCESS)
 7678            ret = WC_CLEANUP_E;
 7679    }
 7680
 7681#if FIPS_VERSION_GE(5,1)
 7682    if (wolfCrypt_SetPrivateKeyReadEnable_fips(0, WC_KEYTYPE_ALL) < 0) {
 7683        if (ret == WOLFSSL_SUCCESS)
 7684            ret = WC_CLEANUP_E;
 7685    }
 7686#endif
 7687
 7688#ifdef HAVE_GLOBAL_RNG
 7689#ifndef WOLFSSL_MUTEX_INITIALIZER
 7690    if ((globalRNGMutex_valid == 1) && (wc_FreeMutex(&globalRNGMutex) != 0)) {
 7691        if (ret == WOLFSSL_SUCCESS)
 7692            ret = BAD_MUTEX_E;
 7693    }
 7694    globalRNGMutex_valid = 0;
 7695#endif /* !WOLFSSL_MUTEX_INITIALIZER */
 7696
 7697    #if defined(OPENSSL_EXTRA) && defined(HAVE_HASHDRBG)
 7698    wolfSSL_FIPS_drbg_free(gDrbgDefCtx);
 7699    gDrbgDefCtx = NULL;
 7700    #endif
 7701#endif
 7702
 7703#ifdef HAVE_EX_DATA_CRYPTO
 7704    crypto_ex_cb_free(crypto_ex_cb_ctx_session);
 7705    crypto_ex_cb_ctx_session = NULL;
 7706#endif
 7707
 7708#ifdef WOLFSSL_MEM_FAIL_COUNT
 7709    wc_MemFailCount_Free();
 7710#endif
 7711
 7712    return ret;
 7713}
 7714
 7715/* Returns 1 if name is a syntactically valid DNS FQDN per RFC 952/1123.
 7716 *
 7717 * Rules enforced:
 7718 *   - Total effective length (excluding optional trailing dot) in [1, 253]
 7719 *   - Each label is 1-63 octets of [a-zA-Z0-9-], with _ allowed in all but
 7720 *     the last label.
 7721 *   - No label starts or ends with '-'
 7722 *   - At least two labels (single-label names are not "fully qualified")
 7723 *   - Final label (TLD) contains at least one letter (rejects all-numeric
 7724 *     strings that could be confused with IPv4 literals, and matches the
 7725 *     ICANN constraint that TLDs are alphabetic)
 7726 *   - Optional trailing dot is accepted (absolute FQDN form)
 7727 *   - Internationalized names are valid in their ACE/punycode (xn--) form
 7728 */
 7729int wolfssl_local_IsValidFQDN(const char* name, word32 nameSz)
 7730{
 7731    word32 i;
 7732    int labelLen = 0;
 7733    int labelCount = 0;
 7734    int curLabelHasAlpha = 0;
 7735    int curLabelHasUnderscore = 0;
 7736
 7737    if (name == NULL || nameSz == 0)
 7738        return 0;
 7739
 7740    /* Strip a single optional trailing dot before measuring.  "example.com."
 7741     * is the absolute form of the same FQDN.
 7742     */
 7743    if (name[nameSz - 1] == '.')
 7744        --nameSz;
 7745
 7746    if (nameSz < 1 || nameSz > 253)
 7747        return 0;
 7748
 7749    for (i = 0; i < nameSz; i++) {
 7750        byte c = (byte)name[i];
 7751
 7752        if (c == '.') {
 7753            if (labelLen == 0 || name[i - 1] == '-')
 7754                return 0;
 7755            ++labelCount;
 7756            labelLen = 0;
 7757            curLabelHasAlpha = 0;
 7758            curLabelHasUnderscore = 0;
 7759            continue;
 7760        }
 7761
 7762        if (++labelLen > 63)
 7763            return 0;
 7764
 7765        if (c == '-') {
 7766            if (labelLen == 1)
 7767                return 0;
 7768        }
 7769        else if (((c | 0x20) >= 'a') && ((c | 0x20) <= 'z')) {
 7770            curLabelHasAlpha = 1;
 7771        }
 7772        else if (c == '_') {
 7773            curLabelHasUnderscore = 1;
 7774        }
 7775        else if ((c < '0') || (c > '9')) {
 7776            return 0;
 7777        }
 7778    }
 7779
 7780    /* Final label (no trailing dot in the effective range to close it) */
 7781    if ((labelLen == 0) || (name[nameSz - 1] == '-') || curLabelHasUnderscore)
 7782        return 0;
 7783    ++labelCount;
 7784
 7785    return ((labelCount > 1) && curLabelHasAlpha);
 7786}
 7787
 7788/* call before SSL_connect, if verifying will add name check to
 7789   date check and signature check */
 7790WOLFSSL_ABI
 7791int wolfSSL_check_domain_name(WOLFSSL* ssl, const char* dn)
 7792{
 7793    size_t dn_len;
 7794
 7795    WOLFSSL_ENTER("wolfSSL_check_domain_name");
 7796
 7797    if (ssl == NULL || dn == NULL) {
 7798        WOLFSSL_MSG("Bad function argument: NULL");
 7799        return WOLFSSL_FAILURE;
 7800    }
 7801
 7802    dn_len = XSTRLEN(dn);
 7803
 7804    if ((! wolfssl_local_IsValidFQDN(dn, (word32)dn_len)) &&
 7805        (XSTRCMP(dn, "localhost") != 0))
 7806    {
 7807        WOLFSSL_MSG("Bad function argument: fails wolfssl_local_IsValidFQDN");
 7808        return WOLFSSL_FAILURE;
 7809    }
 7810
 7811    if (ssl->buffers.domainName.buffer)
 7812        XFREE(ssl->buffers.domainName.buffer, ssl->heap, DYNAMIC_TYPE_DOMAIN);
 7813
 7814    ssl->buffers.domainName.length = (word32)XSTRLEN(dn);
 7815    ssl->buffers.domainName.buffer = (byte*)XMALLOC(
 7816            ssl->buffers.domainName.length + 1, ssl->heap, DYNAMIC_TYPE_DOMAIN);
 7817
 7818    if (ssl->buffers.domainName.buffer) {
 7819        unsigned char* domainName = ssl->buffers.domainName.buffer;
 7820        XMEMCPY(domainName, dn, ssl->buffers.domainName.length);
 7821        domainName[ssl->buffers.domainName.length] = '\0';
 7822        return WOLFSSL_SUCCESS;
 7823    }
 7824    else {
 7825        ssl->error = MEMORY_ERROR;
 7826        return WOLFSSL_FAILURE;
 7827    }
 7828}
 7829
 7830/* call before SSL_connect, if verifying will add IP SAN check to
 7831   date check and signature check */
 7832WOLFSSL_ABI
 7833int wolfSSL_check_ip_address(WOLFSSL* ssl, const char* ipaddr)
 7834{
 7835    WOLFSSL_ENTER("wolfSSL_check_ip_address");
 7836
 7837    if (ssl == NULL || ipaddr == NULL) {
 7838        WOLFSSL_MSG("Bad function argument: NULL");
 7839        return WOLFSSL_FAILURE;
 7840    }
 7841
 7842    if (ssl->buffers.ipasc.buffer != NULL) {
 7843        XFREE(ssl->buffers.ipasc.buffer, ssl->heap, DYNAMIC_TYPE_DOMAIN);
 7844        ssl->buffers.ipasc.buffer = NULL;
 7845        ssl->buffers.ipasc.length = 0;
 7846    }
 7847
 7848    ssl->buffers.ipasc.length = (word32)XSTRLEN(ipaddr);
 7849    ssl->buffers.ipasc.buffer = (byte*)XMALLOC(ssl->buffers.ipasc.length + 1,
 7850                                               ssl->heap, DYNAMIC_TYPE_DOMAIN);
 7851    if (ssl->buffers.ipasc.buffer == NULL) {
 7852        ssl->error = MEMORY_ERROR;
 7853        return WOLFSSL_FAILURE;
 7854    }
 7855
 7856    XMEMCPY(ssl->buffers.ipasc.buffer, ipaddr, ssl->buffers.ipasc.length);
 7857    ssl->buffers.ipasc.buffer[ssl->buffers.ipasc.length] = '\0';
 7858
 7859#ifdef OPENSSL_EXTRA
 7860    if (ssl->param == NULL) {
 7861        return WOLFSSL_FAILURE;
 7862    }
 7863    if (wolfSSL_X509_VERIFY_PARAM_set1_ip_asc(ssl->param, ipaddr) !=
 7864            WOLFSSL_SUCCESS) {
 7865        return WOLFSSL_FAILURE;
 7866    }
 7867#endif
 7868
 7869    return WOLFSSL_SUCCESS;
 7870}
 7871
 7872#if defined(SESSION_CERTS) && defined(OPENSSL_EXTRA)
 7873const char *wolfSSL_get0_peername(WOLFSSL *ssl) {
 7874    if (ssl == NULL) {
 7875        return NULL;
 7876    }
 7877
 7878    if (ssl->buffers.domainName.buffer)
 7879        return (const char *)ssl->buffers.domainName.buffer;
 7880    else if (ssl->session && ssl->session->peer)
 7881        return ssl->session->peer->subjectCN;
 7882#ifdef KEEP_PEER_CERT
 7883    else if (ssl->peerCert.subjectCN[0])
 7884        return ssl->peerCert.subjectCN;
 7885#endif
 7886    else {
 7887        ssl->error = NO_PEER_CERT;
 7888        return NULL;
 7889    }
 7890}
 7891
 7892#endif /* SESSION_CERTS && OPENSSL_EXTRA */
 7893
 7894/* turn on wolfSSL zlib compression
 7895   returns WOLFSSL_SUCCESS for success, else error (not built in)
 7896*/
 7897int wolfSSL_set_compression(WOLFSSL* ssl)
 7898{
 7899    WOLFSSL_ENTER("wolfSSL_set_compression");
 7900    (void)ssl;
 7901#ifdef HAVE_LIBZ
 7902    ssl->options.usingCompression = 1;
 7903    return WOLFSSL_SUCCESS;
 7904#else
 7905    return NOT_COMPILED_IN;
 7906#endif
 7907}
 7908
 7909
 7910#ifndef USE_WINDOWS_API
 7911    #if !defined(NO_WRITEV) && !defined(NO_TLS)
 7912
 7913        /* simulate writev semantics, doesn't actually do block at a time though
 7914           because of SSL_write behavior and because front adds may be small */
 7915        int wolfSSL_writev(WOLFSSL* ssl, const struct iovec* iov, int iovcnt)
 7916        {
 7917        #ifdef WOLFSSL_SMALL_STACK
 7918            byte   staticBuffer[1]; /* force heap usage */
 7919        #else
 7920            byte   staticBuffer[FILE_BUFFER_SIZE];
 7921        #endif
 7922            byte* myBuffer  = staticBuffer;
 7923            int   dynamic   = 0;
 7924            size_t sending   = 0;
 7925            size_t idx       = 0;
 7926            int   i;
 7927            int   ret;
 7928
 7929            WOLFSSL_ENTER("wolfSSL_writev");
 7930
 7931            for (i = 0; i < iovcnt; i++)
 7932                if (! WC_SAFE_SUM_UNSIGNED(size_t, sending, iov[i].iov_len,
 7933                                           sending))
 7934                    return BUFFER_E;
 7935
 7936            if (sending > sizeof(staticBuffer)) {
 7937                myBuffer = (byte*)XMALLOC(sending, ssl->heap,
 7938                                          DYNAMIC_TYPE_WRITEV);
 7939                if (!myBuffer)
 7940                    return MEMORY_ERROR;
 7941
 7942                dynamic = 1;
 7943            }
 7944
 7945            for (i = 0; i < iovcnt; i++) {
 7946                XMEMCPY(&myBuffer[idx], iov[i].iov_base, iov[i].iov_len);
 7947                idx += (int)iov[i].iov_len;
 7948            }
 7949
 7950           /* myBuffer may not be initialized fully, but the span up to the
 7951            * sending length will be.
 7952            */
 7953            PRAGMA_GCC_DIAG_PUSH
 7954            PRAGMA_GCC("GCC diagnostic ignored \"-Wmaybe-uninitialized\"")
 7955            ret = wolfSSL_write_internal(ssl, myBuffer, sending);
 7956            PRAGMA_GCC_DIAG_POP
 7957
 7958            if (dynamic)
 7959                XFREE(myBuffer, ssl->heap, DYNAMIC_TYPE_WRITEV);
 7960
 7961            return ret;
 7962        }
 7963    #endif
 7964#endif
 7965
 7966
 7967#ifdef WOLFSSL_CALLBACKS
 7968
 7969    typedef struct itimerval Itimerval;
 7970
 7971    /* don't keep calling simple functions while setting up timer and signals
 7972       if no inlining these are the next best */
 7973
 7974    #define AddTimes(a, b, c)                       \
 7975        do {                                        \
 7976            (c).tv_sec  = (a).tv_sec + (b).tv_sec;  \
 7977            (c).tv_usec = (a).tv_usec + (b).tv_usec;\
 7978            if ((c).tv_usec >=  1000000) {          \
 7979                (c).tv_sec++;                       \
 7980                (c).tv_usec -= 1000000;             \
 7981            }                                       \
 7982        } while (0)
 7983
 7984
 7985    #define SubtractTimes(a, b, c)                  \
 7986        do {                                        \
 7987            (c).tv_sec  = (a).tv_sec - (b).tv_sec;  \
 7988            (c).tv_usec = (a).tv_usec - (b).tv_usec;\
 7989            if ((c).tv_usec < 0) {                  \
 7990                (c).tv_sec--;                       \
 7991                (c).tv_usec += 1000000;             \
 7992            }                                       \
 7993        } while (0)
 7994
 7995    #define CmpTimes(a, b, cmp)                     \
 7996        (((a).tv_sec  ==  (b).tv_sec) ?             \
 7997            ((a).tv_usec cmp (b).tv_usec) :         \
 7998            ((a).tv_sec  cmp (b).tv_sec))           \
 7999
 8000
 8001    /* do nothing handler */
 8002    static void myHandler(int signo)
 8003    {
 8004        (void)signo;
 8005        return;
 8006    }
 8007
 8008
 8009    static int wolfSSL_ex_wrapper(WOLFSSL* ssl, HandShakeCallBack hsCb,
 8010                                 TimeoutCallBack toCb, WOLFSSL_TIMEVAL timeout)
 8011    {
 8012        int       ret        = WC_NO_ERR_TRACE(WOLFSSL_FATAL_ERROR);
 8013        int       oldTimerOn = 0;   /* was timer already on */
 8014        WOLFSSL_TIMEVAL startTime;
 8015        WOLFSSL_TIMEVAL endTime;
 8016        WOLFSSL_TIMEVAL totalTime;
 8017        Itimerval myTimeout;
 8018        Itimerval oldTimeout; /* if old timer adjust from total time to reset */
 8019        struct sigaction act, oact;
 8020
 8021        #define ERR_OUT(x) { ssl->hsInfoOn = 0; ssl->toInfoOn = 0; return x; }
 8022
 8023        if (hsCb) {
 8024            ssl->hsInfoOn = 1;
 8025            InitHandShakeInfo(&ssl->handShakeInfo, ssl);
 8026        }
 8027        if (toCb) {
 8028            ssl->toInfoOn = 1;
 8029            InitTimeoutInfo(&ssl->timeoutInfo);
 8030
 8031            if (gettimeofday(&startTime, 0) < 0)
 8032                ERR_OUT(GETTIME_ERROR);
 8033
 8034            /* use setitimer to simulate getitimer, init 0 myTimeout */
 8035            myTimeout.it_interval.tv_sec  = 0;
 8036            myTimeout.it_interval.tv_usec = 0;
 8037            myTimeout.it_value.tv_sec     = 0;
 8038            myTimeout.it_value.tv_usec    = 0;
 8039            if (setitimer(ITIMER_REAL, &myTimeout, &oldTimeout) < 0)
 8040                ERR_OUT(SETITIMER_ERROR);
 8041
 8042            if (oldTimeout.it_value.tv_sec || oldTimeout.it_value.tv_usec) {
 8043                oldTimerOn = 1;
 8044
 8045                /* is old timer going to expire before ours */
 8046                if (CmpTimes(oldTimeout.it_value, timeout, <)) {
 8047                    timeout.tv_sec  = oldTimeout.it_value.tv_sec;
 8048                    timeout.tv_usec = oldTimeout.it_value.tv_usec;
 8049                }
 8050            }
 8051            myTimeout.it_value.tv_sec  = timeout.tv_sec;
 8052            myTimeout.it_value.tv_usec = timeout.tv_usec;
 8053
 8054            /* set up signal handler, don't restart socket send/recv */
 8055            act.sa_handler = myHandler;
 8056            sigemptyset(&act.sa_mask);
 8057            act.sa_flags = 0;
 8058#ifdef SA_INTERRUPT
 8059            act.sa_flags |= SA_INTERRUPT;
 8060#endif
 8061            if (sigaction(SIGALRM, &act, &oact) < 0)
 8062                ERR_OUT(SIGACT_ERROR);
 8063
 8064            if (setitimer(ITIMER_REAL, &myTimeout, 0) < 0)
 8065                ERR_OUT(SETITIMER_ERROR);
 8066        }
 8067
 8068        /* do main work */
 8069#ifndef NO_WOLFSSL_CLIENT
 8070        if (ssl->options.side == WOLFSSL_CLIENT_END)
 8071            ret = wolfSSL_connect(ssl);
 8072#endif
 8073#ifndef NO_WOLFSSL_SERVER
 8074        if (ssl->options.side == WOLFSSL_SERVER_END)
 8075            ret = wolfSSL_accept(ssl);
 8076#endif
 8077
 8078        /* do callbacks */
 8079        if (toCb) {
 8080            if (oldTimerOn) {
 8081                if (gettimeofday(&endTime, 0) < 0)
 8082                    ERR_OUT(SYSLIB_FAILED_E);
 8083                SubtractTimes(endTime, startTime, totalTime);
 8084                /* adjust old timer for elapsed time */
 8085                if (CmpTimes(totalTime, oldTimeout.it_value, <))
 8086                    SubtractTimes(oldTimeout.it_value, totalTime,
 8087                                  oldTimeout.it_value);
 8088                else {
 8089                    /* reset value to interval, may be off */
 8090                    oldTimeout.it_value.tv_sec = oldTimeout.it_interval.tv_sec;
 8091                    oldTimeout.it_value.tv_usec =oldTimeout.it_interval.tv_usec;
 8092                }
 8093                /* keep iter the same whether there or not */
 8094            }
 8095            /* restore old handler */
 8096            if (sigaction(SIGALRM, &oact, 0) < 0)
 8097                ret = SIGACT_ERROR;    /* more pressing error, stomp */
 8098            else
 8099                /* use old settings which may turn off (expired or not there) */
 8100                if (setitimer(ITIMER_REAL, &oldTimeout, 0) < 0)
 8101                    ret = SETITIMER_ERROR;
 8102
 8103            /* if we had a timeout call callback */
 8104            if (ssl->timeoutInfo.timeoutName[0]) {
 8105                ssl->timeoutInfo.timeoutValue.tv_sec  = timeout.tv_sec;
 8106                ssl->timeoutInfo.timeoutValue.tv_usec = timeout.tv_usec;
 8107                (toCb)(&ssl->timeoutInfo);
 8108            }
 8109            ssl->toInfoOn = 0;
 8110        }
 8111
 8112        /* clean up buffers allocated by AddPacketInfo */
 8113        FreeTimeoutInfo(&ssl->timeoutInfo, ssl->heap);
 8114
 8115        if (hsCb) {
 8116            FinishHandShakeInfo(&ssl->handShakeInfo);
 8117            (hsCb)(&ssl->handShakeInfo);
 8118            ssl->hsInfoOn = 0;
 8119        }
 8120        return ret;
 8121    }
 8122
 8123
 8124#ifndef NO_WOLFSSL_CLIENT
 8125
 8126    int wolfSSL_connect_ex(WOLFSSL* ssl, HandShakeCallBack hsCb,
 8127                          TimeoutCallBack toCb, WOLFSSL_TIMEVAL timeout)
 8128    {
 8129        WOLFSSL_ENTER("wolfSSL_connect_ex");
 8130        return wolfSSL_ex_wrapper(ssl, hsCb, toCb, timeout);
 8131    }
 8132
 8133#endif
 8134
 8135
 8136#ifndef NO_WOLFSSL_SERVER
 8137
 8138    int wolfSSL_accept_ex(WOLFSSL* ssl, HandShakeCallBack hsCb,
 8139                         TimeoutCallBack toCb, WOLFSSL_TIMEVAL timeout)
 8140    {
 8141        WOLFSSL_ENTER("wolfSSL_accept_ex");
 8142        return wolfSSL_ex_wrapper(ssl, hsCb, toCb, timeout);
 8143    }
 8144
 8145#endif
 8146
 8147#endif /* WOLFSSL_CALLBACKS */
 8148
 8149
 8150#ifndef NO_PSK
 8151
 8152    void wolfSSL_CTX_set_psk_client_callback(WOLFSSL_CTX* ctx,
 8153                                         wc_psk_client_callback cb)
 8154    {
 8155        WOLFSSL_ENTER("wolfSSL_CTX_set_psk_client_callback");
 8156
 8157        if (ctx == NULL)
 8158            return;
 8159
 8160        ctx->havePSK = 1;
 8161        ctx->client_psk_cb = cb;
 8162    }
 8163
 8164    void wolfSSL_set_psk_client_callback(WOLFSSL* ssl,wc_psk_client_callback cb)
 8165    {
 8166        byte haveRSA = 1;
 8167        int  keySz   = 0;
 8168
 8169        WOLFSSL_ENTER("wolfSSL_set_psk_client_callback");
 8170
 8171        if (ssl == NULL)
 8172            return;
 8173
 8174        ssl->options.havePSK = 1;
 8175        ssl->options.client_psk_cb = cb;
 8176
 8177        #ifdef NO_RSA
 8178            haveRSA = 0;
 8179        #endif
 8180        #ifndef NO_CERTS
 8181            keySz = ssl->buffers.keySz;
 8182        #endif
 8183        if (AllocateSuites(ssl) != 0)
 8184            return;
 8185        InitSuites(ssl->suites, ssl->version, keySz, haveRSA, TRUE,
 8186                   ssl->options.haveDH, ssl->options.haveECDSAsig,
 8187                   ssl->options.haveECC, TRUE, ssl->options.haveStaticECC,
 8188                   ssl->options.useAnon, TRUE, TRUE, TRUE, TRUE, ssl->options.side);
 8189    }
 8190
 8191#if defined(WOLFSSL_TLS13) && defined(WOLFSSL_CERT_WITH_EXTERN_PSK)
 8192    int wolfSSL_CTX_set_cert_with_extern_psk(WOLFSSL_CTX* ctx, int state)
 8193    {
 8194        WOLFSSL_ENTER("wolfSSL_CTX_set_cert_with_extern_psk");
 8195        if (ctx == NULL)
 8196            return WOLFSSL_FAILURE;
 8197        ctx->certWithExternPsk = (byte)(state != 0);
 8198        return WOLFSSL_SUCCESS;
 8199    }
 8200
 8201    int wolfSSL_set_cert_with_extern_psk(WOLFSSL* ssl, int state)
 8202    {
 8203        WOLFSSL_ENTER("wolfSSL_set_cert_with_extern_psk");
 8204        if (ssl == NULL)
 8205            return WOLFSSL_FAILURE;
 8206        ssl->options.certWithExternPsk = (word16)(state != 0);
 8207        return WOLFSSL_SUCCESS;
 8208    }
 8209#endif
 8210
 8211    #ifdef OPENSSL_EXTRA
 8212    /**
 8213     * set call back function for psk session use
 8214     * @param ssl  a pointer to WOLFSSL structure
 8215     * @param cb   a function pointer to wc_psk_use_session_cb
 8216     * @return none
 8217     */
 8218    void wolfSSL_set_psk_use_session_callback(WOLFSSL* ssl,
 8219                                                wc_psk_use_session_cb_func cb)
 8220    {
 8221        WOLFSSL_ENTER("wolfSSL_set_psk_use_session_callback");
 8222
 8223        if (ssl != NULL) {
 8224            ssl->options.havePSK = 1;
 8225            ssl->options.session_psk_cb = cb;
 8226        }
 8227
 8228        WOLFSSL_LEAVE("wolfSSL_set_psk_use_session_callback", WOLFSSL_SUCCESS);
 8229    }
 8230    #endif
 8231
 8232    void wolfSSL_CTX_set_psk_server_callback(WOLFSSL_CTX* ctx,
 8233                                         wc_psk_server_callback cb)
 8234    {
 8235        WOLFSSL_ENTER("wolfSSL_CTX_set_psk_server_callback");
 8236        if (ctx == NULL)
 8237            return;
 8238        ctx->havePSK = 1;
 8239        ctx->server_psk_cb = cb;
 8240    }
 8241
 8242    void wolfSSL_set_psk_server_callback(WOLFSSL* ssl,wc_psk_server_callback cb)
 8243    {
 8244        byte haveRSA = 1;
 8245        int  keySz   = 0;
 8246
 8247        WOLFSSL_ENTER("wolfSSL_set_psk_server_callback");
 8248        if (ssl == NULL)
 8249            return;
 8250
 8251        ssl->options.havePSK = 1;
 8252        ssl->options.server_psk_cb = cb;
 8253
 8254        #ifdef NO_RSA
 8255            haveRSA = 0;
 8256        #endif
 8257        #ifndef NO_CERTS
 8258            keySz = ssl->buffers.keySz;
 8259        #endif
 8260        if (AllocateSuites(ssl) != 0)
 8261            return;
 8262        InitSuites(ssl->suites, ssl->version, keySz, haveRSA, TRUE,
 8263                   ssl->options.haveDH, ssl->options.haveECDSAsig,
 8264                   ssl->options.haveECC, TRUE, ssl->options.haveStaticECC,
 8265                   ssl->options.useAnon, TRUE, TRUE, TRUE, TRUE, ssl->options.side);
 8266    }
 8267
 8268    const char* wolfSSL_get_psk_identity_hint(const WOLFSSL* ssl)
 8269    {
 8270        WOLFSSL_ENTER("wolfSSL_get_psk_identity_hint");
 8271
 8272        if (ssl == NULL || ssl->arrays == NULL)
 8273            return NULL;
 8274
 8275        return ssl->arrays->server_hint;
 8276    }
 8277
 8278
 8279    const char* wolfSSL_get_psk_identity(const WOLFSSL* ssl)
 8280    {
 8281        WOLFSSL_ENTER("wolfSSL_get_psk_identity");
 8282
 8283        if (ssl == NULL || ssl->arrays == NULL)
 8284            return NULL;
 8285
 8286        return ssl->arrays->client_identity;
 8287    }
 8288
 8289    int wolfSSL_CTX_use_psk_identity_hint(WOLFSSL_CTX* ctx, const char* hint)
 8290    {
 8291        WOLFSSL_ENTER("wolfSSL_CTX_use_psk_identity_hint");
 8292        if (hint == 0)
 8293            ctx->server_hint[0] = '\0';
 8294        else {
 8295            /* Qt does not call CTX_set_*_psk_callbacks where havePSK is set */
 8296            #ifdef WOLFSSL_QT
 8297            ctx->havePSK=1;
 8298            #endif
 8299            XSTRNCPY(ctx->server_hint, hint, MAX_PSK_ID_LEN);
 8300            ctx->server_hint[MAX_PSK_ID_LEN] = '\0'; /* null term */
 8301        }
 8302        return WOLFSSL_SUCCESS;
 8303    }
 8304
 8305    int wolfSSL_use_psk_identity_hint(WOLFSSL* ssl, const char* hint)
 8306    {
 8307        WOLFSSL_ENTER("wolfSSL_use_psk_identity_hint");
 8308
 8309        if (ssl == NULL || ssl->arrays == NULL)
 8310            return WOLFSSL_FAILURE;
 8311
 8312        if (hint == 0)
 8313            ssl->arrays->server_hint[0] = 0;
 8314        else {
 8315            XSTRNCPY(ssl->arrays->server_hint, hint,
 8316                                            sizeof(ssl->arrays->server_hint)-1);
 8317            ssl->arrays->server_hint[sizeof(ssl->arrays->server_hint)-1] = '\0';
 8318        }
 8319        return WOLFSSL_SUCCESS;
 8320    }
 8321
 8322    void* wolfSSL_get_psk_callback_ctx(WOLFSSL* ssl)
 8323    {
 8324        return ssl ? ssl->options.psk_ctx : NULL;
 8325    }
 8326    void* wolfSSL_CTX_get_psk_callback_ctx(WOLFSSL_CTX* ctx)
 8327    {
 8328        return ctx ? ctx->psk_ctx : NULL;
 8329    }
 8330    int wolfSSL_set_psk_callback_ctx(WOLFSSL* ssl, void* psk_ctx)
 8331    {
 8332        if (ssl == NULL)
 8333            return WOLFSSL_FAILURE;
 8334        ssl->options.psk_ctx = psk_ctx;
 8335        return WOLFSSL_SUCCESS;
 8336    }
 8337    int wolfSSL_CTX_set_psk_callback_ctx(WOLFSSL_CTX* ctx, void* psk_ctx)
 8338    {
 8339        if (ctx == NULL)
 8340            return WOLFSSL_FAILURE;
 8341        ctx->psk_ctx = psk_ctx;
 8342        return WOLFSSL_SUCCESS;
 8343    }
 8344#endif /* NO_PSK */
 8345
 8346
 8347#ifdef HAVE_ANON
 8348
 8349    int wolfSSL_CTX_allow_anon_cipher(WOLFSSL_CTX* ctx)
 8350    {
 8351        WOLFSSL_ENTER("wolfSSL_CTX_allow_anon_cipher");
 8352
 8353        if (ctx == NULL)
 8354            return WOLFSSL_FAILURE;
 8355
 8356        ctx->useAnon = 1;
 8357
 8358        return WOLFSSL_SUCCESS;
 8359    }
 8360
 8361#endif /* HAVE_ANON */
 8362
 8363#ifdef OPENSSL_EXTRA
 8364
 8365    int wolfSSL_add_all_algorithms(void)
 8366    {
 8367        WOLFSSL_ENTER("wolfSSL_add_all_algorithms");
 8368        if (initRefCount != 0 || wolfSSL_Init() == WOLFSSL_SUCCESS)
 8369            return WOLFSSL_SUCCESS;
 8370        else
 8371            return WOLFSSL_FATAL_ERROR;
 8372    }
 8373
 8374    int wolfSSL_OpenSSL_add_all_algorithms_noconf(void)
 8375    {
 8376        WOLFSSL_ENTER("wolfSSL_OpenSSL_add_all_algorithms_noconf");
 8377
 8378        if  (wolfSSL_add_all_algorithms() ==
 8379             WC_NO_ERR_TRACE(WOLFSSL_FATAL_ERROR))
 8380        {
 8381            return WOLFSSL_FATAL_ERROR;
 8382        }
 8383
 8384        return  WOLFSSL_SUCCESS;
 8385    }
 8386
 8387    int wolfSSL_OpenSSL_add_all_algorithms_conf(void)
 8388    {
 8389        WOLFSSL_ENTER("wolfSSL_OpenSSL_add_all_algorithms_conf");
 8390        /* This function is currently the same as
 8391        wolfSSL_OpenSSL_add_all_algorithms_noconf since we do not employ
 8392        the use of a wolfssl.cnf type configuration file and is only used for
 8393        OpenSSL compatibility. */
 8394
 8395        if (wolfSSL_add_all_algorithms() ==
 8396            WC_NO_ERR_TRACE(WOLFSSL_FATAL_ERROR))
 8397        {
 8398            return WOLFSSL_FATAL_ERROR;
 8399        }
 8400        return WOLFSSL_SUCCESS;
 8401    }
 8402
 8403#endif
 8404
 8405#if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL) || \
 8406    defined(WOLFSSL_EXTRA) || defined(WOLFSSL_WPAS_SMALL)
 8407    void wolfSSL_CTX_set_quiet_shutdown(WOLFSSL_CTX* ctx, int mode)
 8408    {
 8409        WOLFSSL_ENTER("wolfSSL_CTX_set_quiet_shutdown");
 8410        if (mode)
 8411            ctx->quietShutdown = 1;
 8412    }
 8413
 8414
 8415    void wolfSSL_set_quiet_shutdown(WOLFSSL* ssl, int mode)
 8416    {
 8417        WOLFSSL_ENTER("wolfSSL_set_quiet_shutdown");
 8418        if (mode)
 8419            ssl->options.quietShutdown = 1;
 8420    }
 8421#endif /* OPENSSL_EXTRA || OPENSSL_EXTRA_X509_SMALL ||
 8422          WOLFSSL_EXTRA || WOLFSSL_WPAS_SMALL */
 8423
 8424#ifdef OPENSSL_EXTRA
 8425#ifndef NO_BIO
 8426    static void ssl_set_bio(WOLFSSL* ssl, WOLFSSL_BIO* rd, WOLFSSL_BIO* wr, int flags)
 8427    {
 8428        WOLFSSL_ENTER("wolfSSL_set_bio");
 8429
 8430        if (ssl == NULL) {
 8431            WOLFSSL_MSG("Bad argument, ssl was NULL");
 8432            return;
 8433        }
 8434
 8435        /* free any existing WOLFSSL_BIOs in use but don't free those in
 8436         * a chain */
 8437        if ((flags & WOLFSSL_BIO_FLAG_READ) && (ssl->biord != NULL)) {
 8438            if ((flags & WOLFSSL_BIO_FLAG_WRITE) && (ssl->biord != ssl->biowr)) {
 8439                if (ssl->biowr != NULL && ssl->biowr->prev != NULL)
 8440                    wolfSSL_BIO_free(ssl->biowr);
 8441                ssl->biowr = NULL;
 8442            }
 8443            if (ssl->biord->prev != NULL)
 8444                wolfSSL_BIO_free(ssl->biord);
 8445            ssl->biord = NULL;
 8446        }
 8447        else if ((flags & WOLFSSL_BIO_FLAG_WRITE) && (ssl->biowr != NULL)) {
 8448            if (ssl->biowr->prev != NULL)
 8449                wolfSSL_BIO_free(ssl->biowr);
 8450            ssl->biowr = NULL;
 8451        }
 8452
 8453        /* set flag obviously */
 8454        if (rd && !(rd->flags & WOLFSSL_BIO_FLAG_READ))
 8455            rd->flags |= WOLFSSL_BIO_FLAG_READ;
 8456        if (wr && !(wr->flags & WOLFSSL_BIO_FLAG_WRITE))
 8457            wr->flags |= WOLFSSL_BIO_FLAG_WRITE;
 8458
 8459        if (flags & WOLFSSL_BIO_FLAG_READ)
 8460            ssl->biord = rd;
 8461        if (flags & WOLFSSL_BIO_FLAG_WRITE)
 8462            ssl->biowr = wr;
 8463
 8464        /* set SSL to use BIO callbacks instead */
 8465        if ((flags & WOLFSSL_BIO_FLAG_READ) &&
 8466            (((ssl->cbioFlag & WOLFSSL_CBIO_RECV) == 0)))
 8467        {
 8468            ssl->CBIORecv = SslBioReceive;
 8469        }
 8470        if ((flags & WOLFSSL_BIO_FLAG_WRITE) &&
 8471            (((ssl->cbioFlag & WOLFSSL_CBIO_SEND) == 0)))
 8472        {
 8473            ssl->CBIOSend = SslBioSend;
 8474        }
 8475
 8476        /* User programs should always retry reading from these BIOs */
 8477        if (rd) {
 8478            /* User writes to rd */
 8479            wolfSSL_BIO_set_retry_write(rd);
 8480        }
 8481        if (wr) {
 8482            /* User reads from wr */
 8483            wolfSSL_BIO_set_retry_read(wr);
 8484        }
 8485    }
 8486
 8487    void wolfSSL_set_bio(WOLFSSL* ssl, WOLFSSL_BIO* rd, WOLFSSL_BIO* wr)
 8488    {
 8489        ssl_set_bio(ssl, rd, wr, WOLFSSL_BIO_FLAG_READ | WOLFSSL_BIO_FLAG_WRITE);
 8490    }
 8491
 8492    void wolfSSL_set_rbio(WOLFSSL* ssl, WOLFSSL_BIO* rd)
 8493    {
 8494        ssl_set_bio(ssl, rd, NULL, WOLFSSL_BIO_FLAG_READ);
 8495    }
 8496
 8497    void wolfSSL_set_wbio(WOLFSSL* ssl, WOLFSSL_BIO* wr)
 8498    {
 8499        ssl_set_bio(ssl, NULL, wr, WOLFSSL_BIO_FLAG_WRITE);
 8500    }
 8501
 8502#endif /* !NO_BIO */
 8503#endif /* OPENSSL_EXTRA */
 8504
 8505#ifdef WOLFSSL_CERT_SETUP_CB
 8506#if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)
 8507    /* registers client cert callback, called during handshake if server
 8508       requests client auth but user has not loaded client cert/key */
 8509    void wolfSSL_CTX_set_client_cert_cb(WOLFSSL_CTX *ctx, client_cert_cb cb)
 8510    {
 8511        WOLFSSL_ENTER("wolfSSL_CTX_set_client_cert_cb");
 8512
 8513        if (ctx != NULL) {
 8514            ctx->CBClientCert = cb;
 8515        }
 8516    }
 8517#endif
 8518
 8519    void wolfSSL_CTX_set_cert_cb(WOLFSSL_CTX* ctx,
 8520        CertSetupCallback cb, void *arg)
 8521    {
 8522        WOLFSSL_ENTER("wolfSSL_CTX_set_cert_cb");
 8523        if (ctx == NULL)
 8524            return;
 8525
 8526        ctx->certSetupCb = cb;
 8527        ctx->certSetupCbArg = arg;
 8528    }
 8529
 8530    int wolfSSL_get_client_suites_sigalgs(const WOLFSSL* ssl,
 8531            const byte** suites, word16* suiteSz,
 8532            const byte** hashSigAlgo, word16* hashSigAlgoSz)
 8533    {
 8534        WOLFSSL_ENTER("wolfSSL_get_client_suites_sigalgs");
 8535
 8536        if (suites != NULL)
 8537            *suites = NULL;
 8538        if (suiteSz != NULL)
 8539            *suiteSz = 0;
 8540        if (hashSigAlgo != NULL)
 8541            *hashSigAlgo = NULL;
 8542        if (hashSigAlgoSz != NULL)
 8543            *hashSigAlgoSz = 0;
 8544
 8545        if (ssl != NULL && ssl->clSuites != NULL) {
 8546            if (suites != NULL && suiteSz != NULL) {
 8547                *suites = ssl->clSuites->suites;
 8548                *suiteSz = ssl->clSuites->suiteSz;
 8549            }
 8550            if (hashSigAlgo != NULL && hashSigAlgoSz != NULL) {
 8551                *hashSigAlgo = ssl->clSuites->hashSigAlgo;
 8552                *hashSigAlgoSz = ssl->clSuites->hashSigAlgoSz;
 8553            }
 8554            return WOLFSSL_SUCCESS;
 8555        }
 8556        return WOLFSSL_FAILURE;
 8557    }
 8558
 8559#ifndef NO_TLS
 8560    WOLFSSL_CIPHERSUITE_INFO wolfSSL_get_ciphersuite_info(byte first,
 8561            byte second)
 8562    {
 8563        WOLFSSL_CIPHERSUITE_INFO info;
 8564        info.rsaAuth = (byte)(CipherRequires(first, second, REQUIRES_RSA) ||
 8565                CipherRequires(first, second, REQUIRES_RSA_SIG));
 8566        info.eccAuth = (byte)(CipherRequires(first, second, REQUIRES_ECC) ||
 8567                /* Static ECC ciphers may require RSA for authentication */
 8568                (CipherRequires(first, second, REQUIRES_ECC_STATIC) &&
 8569                        !CipherRequires(first, second, REQUIRES_RSA_SIG)));
 8570        info.eccStatic =
 8571                (byte)CipherRequires(first, second, REQUIRES_ECC_STATIC);
 8572        info.psk = (byte)CipherRequires(first, second, REQUIRES_PSK);
 8573        return info;
 8574    }
 8575#endif
 8576
 8577    /**
 8578     * @param first First byte of the hash and signature algorithm
 8579     * @param second Second byte of the hash and signature algorithm
 8580     * @param hashAlgo The enum wc_HashType of the MAC algorithm
 8581     * @param sigAlgo The enum Key_Sum of the authentication algorithm
 8582     */
 8583    int wolfSSL_get_sigalg_info(byte first, byte second,
 8584            int* hashAlgo, int* sigAlgo)
 8585    {
 8586        byte input[2];
 8587        byte hashType;
 8588        byte sigType;
 8589
 8590        if (hashAlgo == NULL || sigAlgo == NULL)
 8591            return BAD_FUNC_ARG;
 8592
 8593        input[0] = first;
 8594        input[1] = second;
 8595        DecodeSigAlg(input, &hashType, &sigType);
 8596
 8597        /* cast so that compiler reminds us of unimplemented values */
 8598        switch ((enum SignatureAlgorithm)sigType) {
 8599        case anonymous_sa_algo:
 8600            *sigAlgo = ANONk;
 8601            break;
 8602        case rsa_sa_algo:
 8603            *sigAlgo = RSAk;
 8604            break;
 8605        case dsa_sa_algo:
 8606            *sigAlgo = DSAk;
 8607            break;
 8608        case ecc_dsa_sa_algo:
 8609        case ecc_brainpool_sa_algo:
 8610            *sigAlgo = ECDSAk;
 8611            break;
 8612        case rsa_pss_sa_algo:
 8613            *sigAlgo = RSAPSSk;
 8614            break;
 8615        case ed25519_sa_algo:
 8616            *sigAlgo = ED25519k;
 8617            break;
 8618        case rsa_pss_pss_algo:
 8619            *sigAlgo = RSAPSSk;
 8620            break;
 8621        case ed448_sa_algo:
 8622            *sigAlgo = ED448k;
 8623            break;
 8624        case falcon_level1_sa_algo:
 8625            *sigAlgo = FALCON_LEVEL1k;
 8626            break;
 8627        case falcon_level5_sa_algo:
 8628            *sigAlgo = FALCON_LEVEL5k;
 8629            break;
 8630        case dilithium_level2_sa_algo:
 8631            *sigAlgo = ML_DSA_LEVEL2k;
 8632            break;
 8633        case dilithium_level3_sa_algo:
 8634            *sigAlgo = ML_DSA_LEVEL3k;
 8635            break;
 8636        case dilithium_level5_sa_algo:
 8637            *sigAlgo = ML_DSA_LEVEL5k;
 8638            break;
 8639        case sm2_sa_algo:
 8640            *sigAlgo = SM2k;
 8641            break;
 8642        case invalid_sa_algo:
 8643        case any_sa_algo:
 8644        default:
 8645            *hashAlgo = WC_HASH_TYPE_NONE;
 8646            *sigAlgo = 0;
 8647            return BAD_FUNC_ARG;
 8648        }
 8649
 8650        /* cast so that compiler reminds us of unimplemented values */
 8651        switch((enum wc_MACAlgorithm)hashType) {
 8652        case no_mac:
 8653        case rmd_mac: /* Don't have a RIPEMD type in wc_HashType */
 8654            *hashAlgo = WC_HASH_TYPE_NONE;
 8655            break;
 8656        case md5_mac:
 8657            *hashAlgo = WC_HASH_TYPE_MD5;
 8658            break;
 8659        case sha_mac:
 8660            *hashAlgo = WC_HASH_TYPE_SHA;
 8661            break;
 8662        case sha224_mac:
 8663            *hashAlgo = WC_HASH_TYPE_SHA224;
 8664            break;
 8665        case sha256_mac:
 8666            *hashAlgo = WC_HASH_TYPE_SHA256;
 8667            break;
 8668        case sha384_mac:
 8669            *hashAlgo = WC_HASH_TYPE_SHA384;
 8670            break;
 8671        case sha512_mac:
 8672            *hashAlgo = WC_HASH_TYPE_SHA512;
 8673            break;
 8674        case blake2b_mac:
 8675            *hashAlgo = WC_HASH_TYPE_BLAKE2B;
 8676            break;
 8677        case sm3_mac:
 8678#ifdef WOLFSSL_SM3
 8679            *hashAlgo = WC_HASH_TYPE_SM3;
 8680#else
 8681            *hashAlgo = WC_HASH_TYPE_NONE;
 8682#endif
 8683            break;
 8684        default:
 8685            *hashAlgo = WC_HASH_TYPE_NONE;
 8686            *sigAlgo = 0;
 8687            return BAD_FUNC_ARG;
 8688        }
 8689        return 0;
 8690    }
 8691
 8692    /**
 8693     * Internal wrapper for calling certSetupCb
 8694     * @param ssl The SSL/TLS Object
 8695     * @return 0 on success
 8696     */
 8697    int CertSetupCbWrapper(WOLFSSL* ssl)
 8698    {
 8699        int ret = 0;
 8700        if (ssl->ctx->certSetupCb != NULL) {
 8701            WOLFSSL_MSG("Calling user cert setup callback");
 8702            ret = ssl->ctx->certSetupCb(ssl, ssl->ctx->certSetupCbArg);
 8703            if (ret == 1) {
 8704                WOLFSSL_MSG("User cert callback returned success");
 8705                ret = 0;
 8706            }
 8707            else if (ret == 0) {
 8708                SendAlert(ssl, alert_fatal, internal_error);
 8709                ret = CLIENT_CERT_CB_ERROR;
 8710            }
 8711            else if (ret < 0) {
 8712                ret = WOLFSSL_ERROR_WANT_X509_LOOKUP;
 8713            }
 8714            else {
 8715                WOLFSSL_MSG("Unexpected user callback return");
 8716                ret = CLIENT_CERT_CB_ERROR;
 8717            }
 8718        }
 8719        return ret;
 8720    }
 8721#endif /* WOLFSSL_CERT_SETUP_CB */
 8722
 8723#ifdef OPENSSL_EXTRA
 8724
 8725    #if defined(WOLFCRYPT_HAVE_SRP) && !defined(NO_SHA256) \
 8726        && !defined(WC_NO_RNG)
 8727    static const byte srp_N[] = {
 8728        0xEE, 0xAF, 0x0A, 0xB9, 0xAD, 0xB3, 0x8D, 0xD6, 0x9C, 0x33, 0xF8,
 8729        0x0A, 0xFA, 0x8F, 0xC5, 0xE8, 0x60, 0x72, 0x61, 0x87, 0x75, 0xFF,
 8730        0x3C, 0x0B, 0x9E, 0xA2, 0x31, 0x4C, 0x9C, 0x25, 0x65, 0x76, 0xD6,
 8731        0x74, 0xDF, 0x74, 0x96, 0xEA, 0x81, 0xD3, 0x38, 0x3B, 0x48, 0x13,
 8732        0xD6, 0x92, 0xC6, 0xE0, 0xE0, 0xD5, 0xD8, 0xE2, 0x50, 0xB9, 0x8B,
 8733        0xE4, 0x8E, 0x49, 0x5C, 0x1D, 0x60, 0x89, 0xDA, 0xD1, 0x5D, 0xC7,
 8734        0xD7, 0xB4, 0x61, 0x54, 0xD6, 0xB6, 0xCE, 0x8E, 0xF4, 0xAD, 0x69,
 8735        0xB1, 0x5D, 0x49, 0x82, 0x55, 0x9B, 0x29, 0x7B, 0xCF, 0x18, 0x85,
 8736        0xC5, 0x29, 0xF5, 0x66, 0x66, 0x0E, 0x57, 0xEC, 0x68, 0xED, 0xBC,
 8737        0x3C, 0x05, 0x72, 0x6C, 0xC0, 0x2F, 0xD4, 0xCB, 0xF4, 0x97, 0x6E,
 8738        0xAA, 0x9A, 0xFD, 0x51, 0x38, 0xFE, 0x83, 0x76, 0x43, 0x5B, 0x9F,
 8739        0xC6, 0x1D, 0x2F, 0xC0, 0xEB, 0x06, 0xE3
 8740    };
 8741    static const byte srp_g[] = {
 8742        0x02
 8743    };
 8744
 8745    int wolfSSL_CTX_set_srp_username(WOLFSSL_CTX* ctx, char* username)
 8746    {
 8747        int r = 0;
 8748        SrpSide srp_side = SRP_CLIENT_SIDE;
 8749
 8750        WOLFSSL_ENTER("wolfSSL_CTX_set_srp_username");
 8751        if (ctx == NULL || ctx->srp == NULL || username==NULL)
 8752            return WOLFSSL_FAILURE;
 8753
 8754        if (ctx->method->side == WOLFSSL_SERVER_END){
 8755            srp_side = SRP_SERVER_SIDE;
 8756        } else if (ctx->method->side == WOLFSSL_CLIENT_END){
 8757            srp_side = SRP_CLIENT_SIDE;
 8758        } else {
 8759            WOLFSSL_MSG("Init CTX failed");
 8760            return WOLFSSL_FAILURE;
 8761        }
 8762
 8763        if (wc_SrpInit(ctx->srp, SRP_TYPE_SHA256, srp_side) < 0) {
 8764            WOLFSSL_MSG("Init SRP CTX failed");
 8765            XFREE(ctx->srp, ctx->heap, DYNAMIC_TYPE_SRP);
 8766            ctx->srp = NULL;
 8767            return WOLFSSL_FAILURE;
 8768        }
 8769        r = wc_SrpSetUsername(ctx->srp, (const byte*)username,
 8770                              (word32)XSTRLEN(username));
 8771        if (r < 0) {
 8772            WOLFSSL_MSG("fail to set srp username.");
 8773            return WOLFSSL_FAILURE;
 8774        }
 8775
 8776        /* if wolfSSL_CTX_set_srp_password has already been called, */
 8777        /* use saved password here */
 8778        if (ctx->srp_password != NULL) {
 8779            if (ctx->srp->user == NULL)
 8780                return WOLFSSL_FAILURE;
 8781            return wolfSSL_CTX_set_srp_password(ctx, (char*)ctx->srp_password);
 8782        }
 8783
 8784        return WOLFSSL_SUCCESS;
 8785    }
 8786
 8787    int wolfSSL_CTX_set_srp_password(WOLFSSL_CTX* ctx, char* password)
 8788    {
 8789        int r;
 8790        byte salt[SRP_SALT_SIZE];
 8791
 8792        WOLFSSL_ENTER("wolfSSL_CTX_set_srp_password");
 8793        if (ctx == NULL || ctx->srp == NULL || password == NULL)
 8794            return WOLFSSL_FAILURE;
 8795
 8796        if (ctx->srp->user != NULL) {
 8797            WC_RNG rng;
 8798            if (wc_InitRng(&rng) < 0) {
 8799                WOLFSSL_MSG("wc_InitRng failed");
 8800                return WOLFSSL_FAILURE;
 8801            }
 8802            XMEMSET(salt, 0, sizeof(salt)/sizeof(salt[0]));
 8803            r = wc_RNG_GenerateBlock(&rng, salt, sizeof(salt)/sizeof(salt[0]));
 8804            wc_FreeRng(&rng);
 8805            if (r <  0) {
 8806                WOLFSSL_MSG("wc_RNG_GenerateBlock failed");
 8807                return WOLFSSL_FAILURE;
 8808            }
 8809            if (wc_SrpSetParams(ctx->srp, srp_N, sizeof(srp_N)/sizeof(srp_N[0]),
 8810                                srp_g, sizeof(srp_g)/sizeof(srp_g[0]),
 8811                                salt, sizeof(salt)/sizeof(salt[0])) < 0){
 8812                WOLFSSL_MSG("wc_SrpSetParam failed");
 8813                return WOLFSSL_FAILURE;
 8814            }
 8815            r = wc_SrpSetPassword(ctx->srp, (const byte*)password,
 8816                                  (word32)XSTRLEN(password));
 8817            if (r < 0) {
 8818                WOLFSSL_MSG("wc_SrpSetPassword failed.");
 8819                return WOLFSSL_FAILURE;
 8820            }
 8821            XFREE(ctx->srp_password, NULL, DYNAMIC_TYPE_SRP);
 8822            ctx->srp_password = NULL;
 8823        } else {
 8824            /* save password for wolfSSL_set_srp_username */
 8825            XFREE(ctx->srp_password, ctx->heap, DYNAMIC_TYPE_SRP);
 8826
 8827            ctx->srp_password = (byte*)XMALLOC(XSTRLEN(password) + 1, ctx->heap,
 8828                                               DYNAMIC_TYPE_SRP);
 8829            if (ctx->srp_password == NULL){
 8830                WOLFSSL_MSG("memory allocation error");
 8831                return WOLFSSL_FAILURE;
 8832            }
 8833            XMEMCPY(ctx->srp_password, password, XSTRLEN(password) + 1);
 8834        }
 8835        return WOLFSSL_SUCCESS;
 8836    }
 8837
 8838    /**
 8839     * The modulus passed to wc_SrpSetParams in ssl.c is constant so check
 8840     * that the requested strength is less than or equal to the size of the
 8841     * static modulus size.
 8842     * @param ctx Not used
 8843     * @param strength Minimum number of bits for the modulus
 8844     * @return 1 if strength is less than or equal to static modulus
 8845     *         0 if strength is greater than static modulus
 8846     */
 8847    int  wolfSSL_CTX_set_srp_strength(WOLFSSL_CTX *ctx, int strength)
 8848    {
 8849        (void)ctx;
 8850        WOLFSSL_ENTER("wolfSSL_CTX_set_srp_strength");
 8851        if (strength > (int)(sizeof(srp_N)*8)) {
 8852            WOLFSSL_MSG("Bad Parameter");
 8853            return WOLFSSL_FAILURE;
 8854        }
 8855        return WOLFSSL_SUCCESS;
 8856    }
 8857
 8858    char* wolfSSL_get_srp_username(WOLFSSL *ssl)
 8859    {
 8860        if (ssl && ssl->ctx && ssl->ctx->srp) {
 8861            return (char*) ssl->ctx->srp->user;
 8862        }
 8863        return NULL;
 8864    }
 8865    #endif /* WOLFCRYPT_HAVE_SRP && !NO_SHA256 && !WC_NO_RNG */
 8866
 8867    /* keyblock size in bytes or -1 */
 8868    int wolfSSL_get_keyblock_size(WOLFSSL* ssl)
 8869    {
 8870        if (ssl == NULL)
 8871            return WOLFSSL_FATAL_ERROR;
 8872
 8873        return 2 * (ssl->specs.key_size + ssl->specs.iv_size +
 8874                    ssl->specs.hash_size);
 8875    }
 8876
 8877#endif /* OPENSSL_EXTRA */
 8878
 8879#if defined(OPENSSL_EXTRA) || defined(WOLFSSL_EXTRA) || \
 8880    defined(WOLFSSL_WPAS_SMALL)
 8881
 8882    /* store keys returns WOLFSSL_SUCCESS or -1 on error */
 8883    int wolfSSL_get_keys(WOLFSSL* ssl, unsigned char** ms, unsigned int* msLen,
 8884                                     unsigned char** sr, unsigned int* srLen,
 8885                                     unsigned char** cr, unsigned int* crLen)
 8886    {
 8887        if (ssl == NULL || ssl->arrays == NULL)
 8888            return WOLFSSL_FATAL_ERROR;
 8889
 8890        *ms = ssl->arrays->masterSecret;
 8891        *sr = ssl->arrays->serverRandom;
 8892        *cr = ssl->arrays->clientRandom;
 8893
 8894        *msLen = SECRET_LEN;
 8895        *srLen = RAN_LEN;
 8896        *crLen = RAN_LEN;
 8897
 8898        return WOLFSSL_SUCCESS;
 8899    }
 8900
 8901    void wolfSSL_set_accept_state(WOLFSSL* ssl)
 8902    {
 8903        WOLFSSL_ENTER("wolfSSL_set_accept_state");
 8904
 8905        if (ssl == NULL)
 8906            return;
 8907
 8908        if (ssl->options.side == WOLFSSL_CLIENT_END) {
 8909    #ifdef HAVE_ECC
 8910            WC_DECLARE_VAR(key, ecc_key, 1, 0);
 8911            word32 idx = 0;
 8912
 8913        #ifdef WOLFSSL_SMALL_STACK
 8914            key = (ecc_key*)XMALLOC(sizeof(ecc_key), ssl->heap,
 8915                                    DYNAMIC_TYPE_ECC);
 8916            if (key == NULL) {
 8917                WOLFSSL_MSG("Error allocating memory for ecc_key");
 8918            }
 8919        #endif
 8920            if (ssl->options.haveStaticECC && ssl->buffers.key != NULL) {
 8921                if (wc_ecc_init(key) >= 0) {
 8922                    if (wc_EccPrivateKeyDecode(ssl->buffers.key->buffer, &idx,
 8923                            key, ssl->buffers.key->length) != 0) {
 8924                        ssl->options.haveECDSAsig = 0;
 8925                        ssl->options.haveECC = 0;
 8926                        ssl->options.haveStaticECC = 0;
 8927                    }
 8928                    wc_ecc_free(key);
 8929                }
 8930            }
 8931            WC_FREE_VAR_EX(key, ssl->heap, DYNAMIC_TYPE_ECC);
 8932    #endif
 8933
 8934    #ifndef NO_DH
 8935            if (!ssl->options.haveDH && ssl->ctx->haveDH) {
 8936                ssl->buffers.serverDH_P = ssl->ctx->serverDH_P;
 8937                ssl->buffers.serverDH_G = ssl->ctx->serverDH_G;
 8938                ssl->options.haveDH = 1;
 8939            }
 8940    #endif
 8941        }
 8942
 8943        if (InitSSL_Side(ssl, WOLFSSL_SERVER_END) != WOLFSSL_SUCCESS) {
 8944            WOLFSSL_MSG("Error initializing server side");
 8945        }
 8946    }
 8947
 8948#endif /* OPENSSL_EXTRA || WOLFSSL_EXTRA || WOLFSSL_WPAS_SMALL */
 8949
 8950    /* return true if connection established */
 8951    /* this works for TLS and DTLS */
 8952    int wolfSSL_is_init_finished(const WOLFSSL* ssl)
 8953    {
 8954        if (ssl == NULL)
 8955            return 0;
 8956
 8957#if defined(WOLFSSL_DTLS13) && !defined(NO_WOLFSSL_CLIENT)
 8958        if (ssl->options.side == WOLFSSL_CLIENT_END && ssl->options.dtls
 8959                && IsAtLeastTLSv1_3(ssl->version)) {
 8960            return ssl->options.serverState == SERVER_FINISHED_ACKED;
 8961        }
 8962#endif /* WOLFSSL_DTLS13 && !NO_WOLFSSL_CLIENT */
 8963
 8964        /* Can't use ssl->options.connectState and ssl->options.acceptState
 8965         * because they differ in meaning for TLS <=1.2 and 1.3 */
 8966        if (ssl->options.handShakeState == HANDSHAKE_DONE)
 8967            return 1;
 8968
 8969        return 0;
 8970    }
 8971
 8972#ifdef OPENSSL_EXTRA
 8973    void wolfSSL_CTX_set_tmp_rsa_callback(WOLFSSL_CTX* ctx,
 8974                                      WOLFSSL_RSA*(*f)(WOLFSSL*, int, int))
 8975    {
 8976        /* wolfSSL verifies all these internally */
 8977        (void)ctx;
 8978        (void)f;
 8979    }
 8980
 8981
 8982    void wolfSSL_set_shutdown(WOLFSSL* ssl, int opt)
 8983    {
 8984        WOLFSSL_ENTER("wolfSSL_set_shutdown");
 8985        if(ssl==NULL) {
 8986            WOLFSSL_MSG("Shutdown not set. ssl is null");
 8987            return;
 8988        }
 8989
 8990        ssl->options.sentNotify =  (opt&WOLFSSL_SENT_SHUTDOWN) > 0;
 8991        ssl->options.closeNotify = (opt&WOLFSSL_RECEIVED_SHUTDOWN) > 0;
 8992    }
 8993#endif
 8994
 8995    long wolfSSL_CTX_get_options(WOLFSSL_CTX* ctx)
 8996    {
 8997        WOLFSSL_ENTER("wolfSSL_CTX_get_options");
 8998        WOLFSSL_MSG("wolfSSL options are set through API calls and macros");
 8999        if(ctx == NULL)
 9000            return BAD_FUNC_ARG;
 9001        return (long)ctx->mask;
 9002    }
 9003
 9004    /* forward declaration */
 9005    static long wolf_set_options(long old_op, long op);
 9006
 9007    long wolfSSL_CTX_set_options(WOLFSSL_CTX* ctx, long opt)
 9008    {
 9009        WOLFSSL_ENTER("wolfSSL_CTX_set_options");
 9010
 9011        if (ctx == NULL)
 9012            return BAD_FUNC_ARG;
 9013
 9014        ctx->mask = (unsigned long)wolf_set_options((long)ctx->mask, opt);
 9015#if defined(HAVE_SESSION_TICKET) && (defined(OPENSSL_EXTRA) \
 9016        || defined(HAVE_WEBSERVER) || defined(WOLFSSL_WPAS_SMALL))
 9017        if ((ctx->mask & WOLFSSL_OP_NO_TICKET) == WOLFSSL_OP_NO_TICKET) {
 9018          ctx->noTicketTls12 = 1;
 9019        }
 9020        /* This code is here for documentation purpose. You must not turn off
 9021         * session tickets with the WOLFSSL_OP_NO_TICKET option for TLSv1.3.
 9022         * Because we need to support both stateful and stateless tickets.
 9023        #ifdef WOLFSSL_TLS13
 9024            if ((ctx->mask & WOLFSSL_OP_NO_TICKET) == WOLFSSL_OP_NO_TICKET) {
 9025                ctx->noTicketTls13 = 1;
 9026            }
 9027        #endif
 9028        */
 9029#endif
 9030        return (long)ctx->mask;
 9031    }
 9032
 9033    long wolfSSL_CTX_clear_options(WOLFSSL_CTX* ctx, long opt)
 9034    {
 9035        WOLFSSL_ENTER("wolfSSL_CTX_clear_options");
 9036        if(ctx == NULL)
 9037            return BAD_FUNC_ARG;
 9038        ctx->mask &= (unsigned long)~opt;
 9039        return (long)ctx->mask;
 9040    }
 9041
 9042#ifdef OPENSSL_EXTRA
 9043
 9044    int wolfSSL_set_rfd(WOLFSSL* ssl, int rfd)
 9045    {
 9046        WOLFSSL_ENTER("wolfSSL_set_rfd");
 9047        ssl->rfd = rfd;      /* not used directly to allow IO callbacks */
 9048
 9049        ssl->IOCB_ReadCtx  = &ssl->rfd;
 9050
 9051    #ifdef WOLFSSL_DTLS
 9052        if (ssl->options.dtls) {
 9053            ssl->IOCB_ReadCtx = &ssl->buffers.dtlsCtx;
 9054            ssl->buffers.dtlsCtx.rfd = rfd;
 9055        }
 9056    #endif
 9057
 9058        return WOLFSSL_SUCCESS;
 9059    }
 9060
 9061
 9062    int wolfSSL_set_wfd(WOLFSSL* ssl, int wfd)
 9063    {
 9064        WOLFSSL_ENTER("wolfSSL_set_wfd");
 9065        ssl->wfd = wfd;      /* not used directly to allow IO callbacks */
 9066
 9067        ssl->IOCB_WriteCtx  = &ssl->wfd;
 9068
 9069        return WOLFSSL_SUCCESS;
 9070    }
 9071#endif /* OPENSSL_EXTRA */
 9072
 9073#ifdef WOLFSSL_ENCRYPTED_KEYS
 9074
 9075    void wolfSSL_CTX_set_default_passwd_cb_userdata(WOLFSSL_CTX* ctx,
 9076                                                   void* userdata)
 9077    {
 9078        WOLFSSL_ENTER("wolfSSL_CTX_set_default_passwd_cb_userdata");
 9079        if (ctx)
 9080            ctx->passwd_userdata = userdata;
 9081    }
 9082
 9083
 9084    void wolfSSL_CTX_set_default_passwd_cb(WOLFSSL_CTX* ctx, wc_pem_password_cb*
 9085                                           cb)
 9086    {
 9087        WOLFSSL_ENTER("wolfSSL_CTX_set_default_passwd_cb");
 9088        if (ctx)
 9089            ctx->passwd_cb = cb;
 9090    }
 9091
 9092    wc_pem_password_cb* wolfSSL_CTX_get_default_passwd_cb(WOLFSSL_CTX *ctx)
 9093    {
 9094        if (ctx == NULL || ctx->passwd_cb == NULL) {
 9095            return NULL;
 9096        }
 9097
 9098        return ctx->passwd_cb;
 9099    }
 9100
 9101
 9102    void* wolfSSL_CTX_get_default_passwd_cb_userdata(WOLFSSL_CTX *ctx)
 9103    {
 9104        if (ctx == NULL) {
 9105            return NULL;
 9106        }
 9107
 9108        return ctx->passwd_userdata;
 9109    }
 9110
 9111#endif /* WOLFSSL_ENCRYPTED_KEYS */
 9112
 9113
 9114#if defined(OPENSSL_EXTRA) || defined(HAVE_WEBSERVER) || defined(HAVE_MEMCACHED)
 9115    unsigned long wolfSSL_ERR_get_error(void)
 9116    {
 9117        WOLFSSL_ENTER("wolfSSL_ERR_get_error");
 9118#ifdef WOLFSSL_HAVE_ERROR_QUEUE
 9119        return (unsigned long)wc_GetErrorNodeErr();
 9120#else
 9121        return (unsigned long)(0 - NOT_COMPILED_IN);
 9122#endif
 9123    }
 9124#endif
 9125
 9126#if defined(OPENSSL_EXTRA) || defined(HAVE_WEBSERVER)
 9127
 9128    int wolfSSL_num_locks(void)
 9129    {
 9130        return 0;
 9131    }
 9132
 9133    void wolfSSL_set_locking_callback(mutex_cb* f)
 9134    {
 9135        WOLFSSL_ENTER("wolfSSL_set_locking_callback");
 9136
 9137        if (wc_SetMutexCb(f) != 0) {
 9138            WOLFSSL_MSG("Error when setting mutex call back");
 9139        }
 9140    }
 9141
 9142    mutex_cb* wolfSSL_get_locking_callback(void)
 9143    {
 9144        WOLFSSL_ENTER("wolfSSL_get_locking_callback");
 9145
 9146        return wc_GetMutexCb();
 9147    }
 9148
 9149
 9150    typedef unsigned long (idCb)(void);
 9151    static idCb* inner_idCb = NULL;
 9152
 9153    unsigned long wolfSSL_thread_id(void)
 9154    {
 9155        if (inner_idCb != NULL) {
 9156            return inner_idCb();
 9157        }
 9158        else {
 9159            return 0;
 9160        }
 9161    }
 9162
 9163
 9164    void wolfSSL_set_id_callback(unsigned long (*f)(void))
 9165    {
 9166        inner_idCb = f;
 9167    }
 9168
 9169#ifdef WOLFSSL_HAVE_ERROR_QUEUE
 9170#ifndef NO_BIO
 9171    /* print out and clear all errors */
 9172    void wolfSSL_ERR_print_errors(WOLFSSL_BIO* bio)
 9173    {
 9174        const char* file = NULL;
 9175        const char* reason = NULL;
 9176        int ret;
 9177        int line = 0;
 9178        char buf[WOLFSSL_MAX_ERROR_SZ * 2];
 9179
 9180        WOLFSSL_ENTER("wolfSSL_ERR_print_errors");
 9181
 9182        if (bio == NULL) {
 9183            WOLFSSL_MSG("BIO passed in was null");
 9184            return;
 9185        }
 9186
 9187        do {
 9188        ret = wc_PeekErrorNode(0, &file, &reason, &line);
 9189        if (ret >= 0) {
 9190            const char* r = wolfSSL_ERR_reason_error_string(
 9191                (unsigned long)(0 - ret));
 9192            if (XSNPRINTF(buf, sizeof(buf),
 9193                          "error:%d:wolfSSL library:%s:%s:%d\n",
 9194                          ret, r, file, line)
 9195                >= (int)sizeof(buf))
 9196            {
 9197                WOLFSSL_MSG("Buffer overrun formatting error message");
 9198            }
 9199            wolfSSL_BIO_write(bio, buf, (int)XSTRLEN(buf));
 9200            wc_RemoveErrorNode(0);
 9201        }
 9202        } while (ret >= 0);
 9203        if (wolfSSL_BIO_write(bio, "", 1) != 1) {
 9204            WOLFSSL_MSG("Issue writing final string terminator");
 9205        }
 9206    }
 9207#endif /* !NO_BIO */
 9208#endif /* WOLFSSL_HAVE_ERROR_QUEUE */
 9209
 9210#endif /* OPENSSL_EXTRA || HAVE_WEBSERVER */
 9211
 9212#if defined(OPENSSL_EXTRA) || defined(WOLFSSL_WPAS_SMALL) || \
 9213    defined(HAVE_SECRET_CALLBACK)
 9214#if !defined(NO_WOLFSSL_SERVER)
 9215/* Return the amount of random bytes copied over or error case.
 9216 * ssl : ssl struct after handshake
 9217 * out : buffer to hold random bytes
 9218 * outSz : either 0 (return max buffer sz) or size of out buffer
 9219 */
 9220size_t wolfSSL_get_server_random(const WOLFSSL *ssl, unsigned char *out,
 9221                                                                   size_t outSz)
 9222{
 9223    size_t size;
 9224
 9225    /* return max size of buffer */
 9226    if (outSz == 0) {
 9227        return RAN_LEN;
 9228    }
 9229
 9230    if (ssl == NULL || out == NULL) {
 9231        return 0;
 9232    }
 9233
 9234    if (ssl->arrays == NULL) {
 9235        WOLFSSL_MSG("Arrays struct not saved after handshake");
 9236        return 0;
 9237    }
 9238
 9239    if (outSz > RAN_LEN) {
 9240        size = RAN_LEN;
 9241    }
 9242    else {
 9243        size = outSz;
 9244    }
 9245
 9246    XMEMCPY(out, ssl->arrays->serverRandom, size);
 9247    return size;
 9248}
 9249#endif /* !NO_WOLFSSL_SERVER */
 9250#endif /* OPENSSL_EXTRA || WOLFSSL_WPAS_SMALL || HAVE_SECRET_CALLBACK */
 9251
 9252#ifdef OPENSSL_EXTRA
 9253#if !defined(NO_WOLFSSL_SERVER)
 9254/* Used to get the peer ephemeral public key sent during the connection
 9255 * NOTE: currently wolfSSL_KeepHandshakeResources(WOLFSSL* ssl) must be called
 9256 *       before the ephemeral key is stored.
 9257 * return WOLFSSL_SUCCESS on success */
 9258int wolfSSL_get_peer_tmp_key(const WOLFSSL* ssl, WOLFSSL_EVP_PKEY** pkey)
 9259{
 9260    WOLFSSL_EVP_PKEY* ret = NULL;
 9261
 9262    WOLFSSL_ENTER("wolfSSL_get_server_tmp_key");
 9263
 9264    if (ssl == NULL || pkey == NULL) {
 9265        WOLFSSL_MSG("Bad argument passed in");
 9266        return WOLFSSL_FAILURE;
 9267    }
 9268
 9269#ifdef HAVE_ECC
 9270    if (ssl->peerEccKey != NULL) {
 9271        unsigned char* der;
 9272        const unsigned char* pt;
 9273        unsigned int   derSz = 0;
 9274        int sz;
 9275
 9276        PRIVATE_KEY_UNLOCK();
 9277        if (wc_ecc_export_x963(ssl->peerEccKey, NULL, &derSz)
 9278              != WC_NO_ERR_TRACE(LENGTH_ONLY_E))
 9279        {
 9280            WOLFSSL_MSG("get ecc der size failed");
 9281            PRIVATE_KEY_LOCK();
 9282            return WOLFSSL_FAILURE;
 9283        }
 9284        PRIVATE_KEY_LOCK();
 9285
 9286        derSz += MAX_SEQ_SZ + (2 * MAX_ALGO_SZ) + MAX_SEQ_SZ + TRAILING_ZERO;
 9287        der = (unsigned char*)XMALLOC(derSz, ssl->heap, DYNAMIC_TYPE_KEY);
 9288        if (der == NULL) {
 9289            WOLFSSL_MSG("Memory error");
 9290            return WOLFSSL_FAILURE;
 9291        }
 9292
 9293        if ((sz = wc_EccPublicKeyToDer(ssl->peerEccKey, der, derSz, 1)) <= 0) {
 9294            WOLFSSL_MSG("get ecc der failed");
 9295            XFREE(der, ssl->heap, DYNAMIC_TYPE_KEY);
 9296            return WOLFSSL_FAILURE;
 9297        }
 9298        pt = der; /* in case pointer gets advanced */
 9299        ret = wolfSSL_d2i_PUBKEY(NULL, &pt, sz);
 9300        XFREE(der, ssl->heap, DYNAMIC_TYPE_KEY);
 9301    }
 9302#endif
 9303
 9304    *pkey = ret;
 9305#ifdef HAVE_ECC
 9306    if (ret != NULL)
 9307        return WOLFSSL_SUCCESS;
 9308    else
 9309#endif
 9310        return WOLFSSL_FAILURE;
 9311}
 9312
 9313#endif /* !NO_WOLFSSL_SERVER */
 9314
 9315/**
 9316 * This function checks if any compiled in protocol versions are
 9317 * left enabled after calls to set_min or set_max API.
 9318 * @param major The SSL/TLS major version
 9319 * @return WOLFSSL_SUCCESS on valid settings and WOLFSSL_FAILURE when no
 9320 *         protocol versions are left enabled.
 9321 */
 9322static int CheckSslMethodVersion(byte major, unsigned long options)
 9323{
 9324    int sanityConfirmed = 0;
 9325
 9326    (void)options;
 9327
 9328    switch (major) {
 9329    #ifndef NO_TLS
 9330        case SSLv3_MAJOR:
 9331            #ifdef WOLFSSL_ALLOW_SSLV3
 9332                if (!(options & WOLFSSL_OP_NO_SSLv3)) {
 9333                    sanityConfirmed = 1;
 9334                }
 9335            #endif
 9336            #ifndef NO_OLD_TLS
 9337                if (!(options & WOLFSSL_OP_NO_TLSv1))
 9338                    sanityConfirmed = 1;
 9339                if (!(options & WOLFSSL_OP_NO_TLSv1_1))
 9340                    sanityConfirmed = 1;
 9341            #endif
 9342            #ifndef WOLFSSL_NO_TLS12
 9343                if (!(options & WOLFSSL_OP_NO_TLSv1_2))
 9344                    sanityConfirmed = 1;
 9345            #endif
 9346            #ifdef WOLFSSL_TLS13
 9347                if (!(options & WOLFSSL_OP_NO_TLSv1_3))
 9348                    sanityConfirmed = 1;
 9349            #endif
 9350            break;
 9351    #endif
 9352    #ifdef WOLFSSL_DTLS
 9353        case DTLS_MAJOR:
 9354            sanityConfirmed = 1;
 9355            break;
 9356    #endif
 9357        default:
 9358            WOLFSSL_MSG("Invalid major version");
 9359            return WOLFSSL_FAILURE;
 9360    }
 9361    if (!sanityConfirmed) {
 9362        WOLFSSL_MSG("All compiled in TLS versions disabled");
 9363        return WOLFSSL_FAILURE;
 9364    }
 9365    return WOLFSSL_SUCCESS;
 9366}
 9367
 9368/**
 9369 * protoVerTbl holds (D)TLS version numbers in ascending order.
 9370 * Except DTLS versions, the newer version is located in the latter part of
 9371 * the table. This table is referred by wolfSSL_CTX_set_min_proto_version and
 9372 * wolfSSL_CTX_set_max_proto_version.
 9373 */
 9374static const int protoVerTbl[] = {
 9375    SSL3_VERSION,
 9376    TLS1_VERSION,
 9377    TLS1_1_VERSION,
 9378    TLS1_2_VERSION,
 9379    TLS1_3_VERSION,
 9380    DTLS1_VERSION,
 9381    DTLS1_2_VERSION
 9382};
 9383/* number of protocol versions listed in protoVerTbl */
 9384#define NUMBER_OF_PROTOCOLS (sizeof(protoVerTbl)/sizeof(int))
 9385
 9386/**
 9387 * wolfSSL_CTX_set_min_proto_version attempts to set the minimum protocol
 9388 * version to use by SSL objects created from this WOLFSSL_CTX.
 9389 * This API guarantees that a version of SSL/TLS lower than specified
 9390 * here will not be allowed. If the version specified is not compiled in
 9391 * then this API sets the lowest compiled in protocol version.
 9392 * This API also accept 0 as version, to set the minimum version automatically.
 9393 * CheckSslMethodVersion() is called to check if any remaining protocol versions
 9394 * are enabled.
 9395 * @param ctx The wolfSSL CONTEXT factory for spawning SSL/TLS objects
 9396 * @param version Any of the following
 9397 *          * 0
 9398 *          * SSL3_VERSION
 9399 *          * TLS1_VERSION
 9400 *          * TLS1_1_VERSION
 9401 *          * TLS1_2_VERSION
 9402 *          * TLS1_3_VERSION
 9403 *          * DTLS1_VERSION
 9404 *          * DTLS1_2_VERSION
 9405 * @return WOLFSSL_SUCCESS on valid settings and WOLFSSL_FAILURE when no
 9406 *         protocol versions are left enabled.
 9407 */
 9408static int Set_CTX_min_proto_version(WOLFSSL_CTX* ctx, int version)
 9409{
 9410    WOLFSSL_ENTER("wolfSSL_CTX_set_min_proto_version_ex");
 9411
 9412    if (ctx == NULL) {
 9413        return WOLFSSL_FAILURE;
 9414    }
 9415
 9416    switch (version) {
 9417#ifndef NO_TLS
 9418        case SSL3_VERSION:
 9419#if defined(WOLFSSL_ALLOW_SSLV3) && !defined(NO_OLD_TLS)
 9420            ctx->minDowngrade = SSLv3_MINOR;
 9421            break;
 9422#endif
 9423        case TLS1_VERSION:
 9424        #ifdef WOLFSSL_ALLOW_TLSV10
 9425            ctx->minDowngrade = TLSv1_MINOR;
 9426            break;
 9427        #endif
 9428        case TLS1_1_VERSION:
 9429        #ifndef NO_OLD_TLS
 9430            ctx->minDowngrade = TLSv1_1_MINOR;
 9431            break;
 9432        #endif
 9433        case TLS1_2_VERSION:
 9434        #ifndef WOLFSSL_NO_TLS12
 9435            ctx->minDowngrade = TLSv1_2_MINOR;
 9436            break;
 9437        #endif
 9438        case TLS1_3_VERSION:
 9439        #ifdef WOLFSSL_TLS13
 9440            ctx->minDowngrade = TLSv1_3_MINOR;
 9441            break;
 9442        #endif
 9443#endif
 9444#ifdef WOLFSSL_DTLS
 9445        case DTLS1_VERSION:
 9446    #ifndef NO_OLD_TLS
 9447            ctx->minDowngrade = DTLS_MINOR;
 9448            break;
 9449    #endif
 9450        case DTLS1_2_VERSION:
 9451            ctx->minDowngrade = DTLSv1_2_MINOR;
 9452            break;
 9453#endif
 9454        default:
 9455            WOLFSSL_MSG("Unrecognized protocol version or not compiled in");
 9456            return WOLFSSL_FAILURE;
 9457    }
 9458
 9459    switch (version) {
 9460#ifndef NO_TLS
 9461    case TLS1_3_VERSION:
 9462        wolfSSL_CTX_set_options(ctx, WOLFSSL_OP_NO_TLSv1_2);
 9463        FALL_THROUGH;
 9464    case TLS1_2_VERSION:
 9465        wolfSSL_CTX_set_options(ctx, WOLFSSL_OP_NO_TLSv1_1);
 9466        FALL_THROUGH;
 9467    case TLS1_1_VERSION:
 9468        wolfSSL_CTX_set_options(ctx, WOLFSSL_OP_NO_TLSv1);
 9469        FALL_THROUGH;
 9470    case TLS1_VERSION:
 9471        wolfSSL_CTX_set_options(ctx, WOLFSSL_OP_NO_SSLv3);
 9472        break;
 9473    case SSL3_VERSION:
 9474    case SSL2_VERSION:
 9475        /* Nothing to do here */
 9476        break;
 9477#endif
 9478#ifdef WOLFSSL_DTLS
 9479    case DTLS1_VERSION:
 9480    case DTLS1_2_VERSION:
 9481        break;
 9482#endif
 9483    default:
 9484        WOLFSSL_MSG("Unrecognized protocol version or not compiled in");
 9485        return WOLFSSL_FAILURE;
 9486    }
 9487
 9488    return CheckSslMethodVersion(ctx->method->version.major, ctx->mask);
 9489}
 9490
 9491/* Sets the min protocol version allowed with WOLFSSL_CTX
 9492 * returns WOLFSSL_SUCCESS on success */
 9493int wolfSSL_CTX_set_min_proto_version(WOLFSSL_CTX* ctx, int version)
 9494{
 9495    int ret;
 9496    int proto    = 0;
 9497    int maxProto = 0;
 9498    int i;
 9499    int idx = 0;
 9500
 9501    WOLFSSL_ENTER("wolfSSL_CTX_set_min_proto_version");
 9502
 9503    if (ctx == NULL) {
 9504        return WOLFSSL_FAILURE;
 9505    }
 9506
 9507    if (version != 0) {
 9508        proto = version;
 9509        ctx->minProto = 0; /* turn min proto flag off */
 9510        for (i = 0; (unsigned)i < NUMBER_OF_PROTOCOLS; i++) {
 9511            if (protoVerTbl[i] == version) {
 9512                break;
 9513            }
 9514        }
 9515    }
 9516    else {
 9517        /* when 0 is specified as version, try to find out the min version */
 9518        for (i = 0; (unsigned)i < NUMBER_OF_PROTOCOLS; i++) {
 9519            ret = Set_CTX_min_proto_version(ctx, protoVerTbl[i]);
 9520            if (ret == WOLFSSL_SUCCESS) {
 9521                proto = protoVerTbl[i];
 9522                ctx->minProto = 1; /* turn min proto flag on */
 9523                break;
 9524            }
 9525        }
 9526    }
 9527
 9528    /* check case where max > min , if so then clear the NO_* options
 9529     * i is the index into the table for proto version used, see if the max
 9530     * proto version index found is smaller */
 9531    maxProto = wolfSSL_CTX_get_max_proto_version(ctx);
 9532    for (idx = 0; (unsigned)idx < NUMBER_OF_PROTOCOLS; idx++) {
 9533        if (protoVerTbl[idx] == maxProto) {
 9534            break;
 9535        }
 9536    }
 9537    if (idx < i) {
 9538        wolfSSL_CTX_clear_options(ctx, WOLFSSL_OP_NO_TLSv1 |
 9539                WOLFSSL_OP_NO_TLSv1_1 | WOLFSSL_OP_NO_TLSv1_2 |
 9540                WOLFSSL_OP_NO_TLSv1_3);
 9541    }
 9542
 9543    ret = Set_CTX_min_proto_version(ctx, proto);
 9544    return ret;
 9545}
 9546
 9547/**
 9548 * wolfSSL_CTX_set_max_proto_version attempts to set the maximum protocol
 9549 * version to use by SSL objects created from this WOLFSSL_CTX.
 9550 * This API guarantees that a version of SSL/TLS higher than specified
 9551 * here will not be allowed. If the version specified is not compiled in
 9552 * then this API sets the highest compiled in protocol version.
 9553 * This API also accept 0 as version, to set the maximum version automatically.
 9554 * CheckSslMethodVersion() is called to check if any remaining protocol versions
 9555 * are enabled.
 9556 * @param ctx The wolfSSL CONTEXT factory for spawning SSL/TLS objects
 9557 * @param ver Any of the following
 9558 *          * 0
 9559 *          * SSL3_VERSION
 9560 *          * TLS1_VERSION
 9561 *          * TLS1_1_VERSION
 9562 *          * TLS1_2_VERSION
 9563 *          * TLS1_3_VERSION
 9564 *          * DTLS1_VERSION
 9565 *          * DTLS1_2_VERSION
 9566 * @return WOLFSSL_SUCCESS on valid settings and WOLFSSL_FAILURE when no
 9567 *         protocol versions are left enabled.
 9568 */
 9569static int Set_CTX_max_proto_version(WOLFSSL_CTX* ctx, int ver)
 9570{
 9571    int ret;
 9572    WOLFSSL_ENTER("Set_CTX_max_proto_version");
 9573
 9574    if (!ctx || !ctx->method) {
 9575        WOLFSSL_MSG("Bad parameter");
 9576        return WOLFSSL_FAILURE;
 9577    }
 9578
 9579    switch (ver) {
 9580#ifndef NO_TLS
 9581#ifndef NO_OLD_TLS
 9582    case SSL2_VERSION:
 9583        WOLFSSL_MSG("wolfSSL does not support SSLv2");
 9584        return WOLFSSL_FAILURE;
 9585#endif
 9586    case SSL3_VERSION:
 9587        wolfSSL_CTX_set_options(ctx, WOLFSSL_OP_NO_TLSv1);
 9588        FALL_THROUGH;
 9589    case TLS1_VERSION:
 9590        wolfSSL_CTX_set_options(ctx, WOLFSSL_OP_NO_TLSv1_1);
 9591        FALL_THROUGH;
 9592    case TLS1_1_VERSION:
 9593        wolfSSL_CTX_set_options(ctx, WOLFSSL_OP_NO_TLSv1_2);
 9594        FALL_THROUGH;
 9595    case TLS1_2_VERSION:
 9596        wolfSSL_CTX_set_options(ctx, WOLFSSL_OP_NO_TLSv1_3);
 9597        FALL_THROUGH;
 9598    case TLS1_3_VERSION:
 9599        /* Nothing to do here */
 9600        break;
 9601#endif
 9602#ifdef WOLFSSL_DTLS
 9603    case DTLS1_VERSION:
 9604    case DTLS1_2_VERSION:
 9605        break;
 9606#endif
 9607    default:
 9608        WOLFSSL_MSG("Unrecognized protocol version or not compiled in");
 9609        return WOLFSSL_FAILURE;
 9610    }
 9611
 9612    ret = CheckSslMethodVersion(ctx->method->version.major, ctx->mask);
 9613    if (ret == WOLFSSL_SUCCESS) {
 9614        /* Check the major */
 9615        switch (ver) {
 9616    #ifndef NO_TLS
 9617        case SSL3_VERSION:
 9618        case TLS1_VERSION:
 9619        case TLS1_1_VERSION:
 9620        case TLS1_2_VERSION:
 9621        case TLS1_3_VERSION:
 9622            if (ctx->method->version.major != SSLv3_MAJOR) {
 9623                WOLFSSL_MSG("Mismatched protocol version");
 9624                return WOLFSSL_FAILURE;
 9625            }
 9626            break;
 9627    #endif
 9628    #ifdef WOLFSSL_DTLS
 9629        case DTLS1_VERSION:
 9630        case DTLS1_2_VERSION:
 9631            if (ctx->method->version.major != DTLS_MAJOR) {
 9632                WOLFSSL_MSG("Mismatched protocol version");
 9633                return WOLFSSL_FAILURE;
 9634            }
 9635            break;
 9636    #endif
 9637        }
 9638        /* Update the method */
 9639        switch (ver) {
 9640    #ifndef NO_TLS
 9641        case SSL3_VERSION:
 9642            ctx->method->version.minor = SSLv3_MINOR;
 9643            break;
 9644        case TLS1_VERSION:
 9645            ctx->method->version.minor = TLSv1_MINOR;
 9646            break;
 9647        case TLS1_1_VERSION:
 9648            ctx->method->version.minor = TLSv1_1_MINOR;
 9649            break;
 9650        case TLS1_2_VERSION:
 9651            ctx->method->version.minor = TLSv1_2_MINOR;
 9652            break;
 9653        case TLS1_3_VERSION:
 9654            ctx->method->version.minor = TLSv1_3_MINOR;
 9655            break;
 9656    #endif
 9657    #ifdef WOLFSSL_DTLS
 9658        case DTLS1_VERSION:
 9659            ctx->method->version.minor = DTLS_MINOR;
 9660            break;
 9661        case DTLS1_2_VERSION:
 9662            ctx->method->version.minor = DTLSv1_2_MINOR;
 9663            break;
 9664    #endif
 9665        default:
 9666            WOLFSSL_MSG("Unrecognized protocol version or not compiled in");
 9667            return WOLFSSL_FAILURE;
 9668        }
 9669    }
 9670    return ret;
 9671}
 9672
 9673
 9674/* Sets the max protocol version allowed with WOLFSSL_CTX
 9675 * returns WOLFSSL_SUCCESS on success */
 9676int wolfSSL_CTX_set_max_proto_version(WOLFSSL_CTX* ctx, int version)
 9677{
 9678    int i;
 9679    int ret = WC_NO_ERR_TRACE(WOLFSSL_FAILURE);
 9680    int minProto;
 9681
 9682    WOLFSSL_ENTER("wolfSSL_CTX_set_max_proto_version");
 9683
 9684    if (ctx == NULL) {
 9685        return ret;
 9686    }
 9687
 9688    /* clear out flags and reset min protocol version */
 9689    minProto = wolfSSL_CTX_get_min_proto_version(ctx);
 9690    wolfSSL_CTX_clear_options(ctx,
 9691            WOLFSSL_OP_NO_TLSv1 | WOLFSSL_OP_NO_TLSv1_1 |
 9692            WOLFSSL_OP_NO_TLSv1_2 | WOLFSSL_OP_NO_TLSv1_3);
 9693    wolfSSL_CTX_set_min_proto_version(ctx, minProto);
 9694    if (version != 0) {
 9695        ctx->maxProto = 0; /* turn max proto flag off */
 9696        return Set_CTX_max_proto_version(ctx, version);
 9697    }
 9698
 9699    /* when 0 is specified as version, try to find out the min version from
 9700     * the bottom to top of the protoverTbl.
 9701     */
 9702    for (i = NUMBER_OF_PROTOCOLS -1; i >= 0; i--) {
 9703        ret = Set_CTX_max_proto_version(ctx, protoVerTbl[i]);
 9704        if (ret == WOLFSSL_SUCCESS) {
 9705            ctx->maxProto = 1; /* turn max proto flag on */
 9706            break;
 9707        }
 9708    }
 9709
 9710    return ret;
 9711}
 9712
 9713
 9714static int Set_SSL_min_proto_version(WOLFSSL* ssl, int ver)
 9715{
 9716    WOLFSSL_ENTER("Set_SSL_min_proto_version");
 9717
 9718    if (ssl == NULL) {
 9719        return WOLFSSL_FAILURE;
 9720    }
 9721
 9722    switch (ver) {
 9723#ifndef NO_TLS
 9724        case SSL3_VERSION:
 9725#if defined(WOLFSSL_ALLOW_SSLV3) && !defined(NO_OLD_TLS)
 9726            ssl->options.minDowngrade = SSLv3_MINOR;
 9727            break;
 9728#endif
 9729        case TLS1_VERSION:
 9730        #ifdef WOLFSSL_ALLOW_TLSV10
 9731            ssl->options.minDowngrade = TLSv1_MINOR;
 9732            break;
 9733        #endif
 9734        case TLS1_1_VERSION:
 9735        #ifndef NO_OLD_TLS
 9736            ssl->options.minDowngrade = TLSv1_1_MINOR;
 9737            break;
 9738        #endif
 9739        case TLS1_2_VERSION:
 9740        #ifndef WOLFSSL_NO_TLS12
 9741            ssl->options.minDowngrade = TLSv1_2_MINOR;
 9742            break;
 9743        #endif
 9744        case TLS1_3_VERSION:
 9745        #ifdef WOLFSSL_TLS13
 9746            ssl->options.minDowngrade = TLSv1_3_MINOR;
 9747            break;
 9748        #endif
 9749#endif
 9750#ifdef WOLFSSL_DTLS
 9751        case DTLS1_VERSION:
 9752    #ifndef NO_OLD_TLS
 9753            ssl->options.minDowngrade = DTLS_MINOR;
 9754            break;
 9755    #endif
 9756        case DTLS1_2_VERSION:
 9757            ssl->options.minDowngrade = DTLSv1_2_MINOR;
 9758            break;
 9759#endif
 9760        default:
 9761            WOLFSSL_MSG("Unrecognized protocol version or not compiled in");
 9762            return WOLFSSL_FAILURE;
 9763    }
 9764
 9765    switch (ver) {
 9766#ifndef NO_TLS
 9767    case TLS1_3_VERSION:
 9768        ssl->options.mask |= WOLFSSL_OP_NO_TLSv1_2;
 9769        FALL_THROUGH;
 9770    case TLS1_2_VERSION:
 9771        ssl->options.mask |= WOLFSSL_OP_NO_TLSv1_1;
 9772        FALL_THROUGH;
 9773    case TLS1_1_VERSION:
 9774        ssl->options.mask |= WOLFSSL_OP_NO_TLSv1;
 9775        FALL_THROUGH;
 9776    case TLS1_VERSION:
 9777        ssl->options.mask |= WOLFSSL_OP_NO_SSLv3;
 9778        break;
 9779    case SSL3_VERSION:
 9780    case SSL2_VERSION:
 9781        /* Nothing to do here */
 9782        break;
 9783#endif
 9784#ifdef WOLFSSL_DTLS
 9785    case DTLS1_VERSION:
 9786    case DTLS1_2_VERSION:
 9787        break;
 9788#endif
 9789    default:
 9790        WOLFSSL_MSG("Unrecognized protocol version or not compiled in");
 9791        return WOLFSSL_FAILURE;
 9792    }
 9793
 9794    return CheckSslMethodVersion(ssl->version.major, ssl->options.mask);
 9795}
 9796
 9797int wolfSSL_set_min_proto_version(WOLFSSL* ssl, int version)
 9798{
 9799    int i;
 9800    int ret = WC_NO_ERR_TRACE(WOLFSSL_FAILURE);;
 9801
 9802    WOLFSSL_ENTER("wolfSSL_set_min_proto_version");
 9803
 9804    if (ssl == NULL) {
 9805        return WOLFSSL_FAILURE;
 9806    }
 9807    if (version != 0) {
 9808        return Set_SSL_min_proto_version(ssl, version);
 9809    }
 9810
 9811    /* when 0 is specified as version, try to find out the min version */
 9812    for (i= 0; (unsigned)i < NUMBER_OF_PROTOCOLS; i++) {
 9813        ret = Set_SSL_min_proto_version(ssl, protoVerTbl[i]);
 9814        if (ret == WOLFSSL_SUCCESS)
 9815            break;
 9816    }
 9817
 9818    return ret;
 9819}
 9820
 9821static int Set_SSL_max_proto_version(WOLFSSL* ssl, int ver)
 9822{
 9823
 9824    WOLFSSL_ENTER("Set_SSL_max_proto_version");
 9825
 9826    if (!ssl) {
 9827        WOLFSSL_MSG("Bad parameter");
 9828        return WOLFSSL_FAILURE;
 9829    }
 9830
 9831    switch (ver) {
 9832    case SSL2_VERSION:
 9833        WOLFSSL_MSG("wolfSSL does not support SSLv2");
 9834        return WOLFSSL_FAILURE;
 9835#ifndef NO_TLS
 9836    case SSL3_VERSION:
 9837        ssl->options.mask |= WOLFSSL_OP_NO_TLSv1;
 9838        FALL_THROUGH;
 9839    case TLS1_VERSION:
 9840        ssl->options.mask |= WOLFSSL_OP_NO_TLSv1_1;
 9841        FALL_THROUGH;
 9842    case TLS1_1_VERSION:
 9843        ssl->options.mask |= WOLFSSL_OP_NO_TLSv1_2;
 9844        FALL_THROUGH;
 9845    case TLS1_2_VERSION:
 9846        ssl->options.mask |= WOLFSSL_OP_NO_TLSv1_3;
 9847        FALL_THROUGH;
 9848    case TLS1_3_VERSION:
 9849        /* Nothing to do here */
 9850        break;
 9851#endif
 9852#ifdef WOLFSSL_DTLS
 9853    case DTLS1_VERSION:
 9854    case DTLS1_2_VERSION:
 9855        break;
 9856#endif
 9857    default:
 9858        WOLFSSL_MSG("Unrecognized protocol version or not compiled in");
 9859        return WOLFSSL_FAILURE;
 9860    }
 9861
 9862    return CheckSslMethodVersion(ssl->version.major, ssl->options.mask);
 9863}
 9864
 9865int wolfSSL_set_max_proto_version(WOLFSSL* ssl, int version)
 9866{
 9867    int i;
 9868    int ret = WC_NO_ERR_TRACE(WOLFSSL_FAILURE);;
 9869
 9870    WOLFSSL_ENTER("wolfSSL_set_max_proto_version");
 9871
 9872    if (ssl == NULL) {
 9873        return WOLFSSL_FAILURE;
 9874    }
 9875    if (version != 0) {
 9876        return Set_SSL_max_proto_version(ssl, version);
 9877    }
 9878
 9879    /* when 0 is specified as version, try to find out the min version from
 9880     * the bottom to top of the protoverTbl.
 9881     */
 9882    for (i = NUMBER_OF_PROTOCOLS -1; i >= 0; i--) {
 9883        ret = Set_SSL_max_proto_version(ssl, protoVerTbl[i]);
 9884        if (ret == WOLFSSL_SUCCESS)
 9885            break;
 9886    }
 9887
 9888    return ret;
 9889}
 9890
 9891static int GetMinProtoVersion(int minDowngrade)
 9892{
 9893    int ret;
 9894
 9895    switch (minDowngrade) {
 9896#ifndef NO_OLD_TLS
 9897    #ifdef WOLFSSL_ALLOW_SSLV3
 9898        case SSLv3_MINOR:
 9899            ret = SSL3_VERSION;
 9900            break;
 9901    #endif
 9902    #ifdef WOLFSSL_ALLOW_TLSV10
 9903        case TLSv1_MINOR:
 9904            ret = TLS1_VERSION;
 9905            break;
 9906    #endif
 9907        case TLSv1_1_MINOR:
 9908            ret = TLS1_1_VERSION;
 9909            break;
 9910#endif
 9911#ifndef WOLFSSL_NO_TLS12
 9912        case TLSv1_2_MINOR:
 9913            ret = TLS1_2_VERSION;
 9914            break;
 9915#endif
 9916#ifdef WOLFSSL_TLS13
 9917        case TLSv1_3_MINOR:
 9918            ret = TLS1_3_VERSION;
 9919            break;
 9920#endif
 9921        default:
 9922            ret = 0;
 9923            break;
 9924    }
 9925
 9926    return ret;
 9927}
 9928
 9929int wolfSSL_CTX_get_min_proto_version(WOLFSSL_CTX* ctx)
 9930{
 9931    int ret = 0;
 9932
 9933    WOLFSSL_ENTER("wolfSSL_CTX_get_min_proto_version");
 9934
 9935    if (ctx != NULL) {
 9936        if (ctx->minProto) {
 9937            ret = 0;
 9938        }
 9939        else {
 9940            ret = GetMinProtoVersion(ctx->minDowngrade);
 9941        }
 9942    }
 9943    else {
 9944        ret = GetMinProtoVersion(WOLFSSL_MIN_DOWNGRADE);
 9945    }
 9946
 9947    WOLFSSL_LEAVE("wolfSSL_CTX_get_min_proto_version", ret);
 9948
 9949    return ret;
 9950}
 9951
 9952
 9953/* returns the maximum allowed protocol version given the 'options' used
 9954 * returns WOLFSSL_FATAL_ERROR on no match */
 9955static int GetMaxProtoVersion(long options)
 9956{
 9957#ifndef NO_TLS
 9958#ifdef WOLFSSL_TLS13
 9959    if (!(options & WOLFSSL_OP_NO_TLSv1_3))
 9960        return TLS1_3_VERSION;
 9961#endif
 9962#ifndef WOLFSSL_NO_TLS12
 9963    if (!(options & WOLFSSL_OP_NO_TLSv1_2))
 9964        return TLS1_2_VERSION;
 9965#endif
 9966#ifndef NO_OLD_TLS
 9967    if (!(options & WOLFSSL_OP_NO_TLSv1_1))
 9968        return TLS1_1_VERSION;
 9969    #ifdef WOLFSSL_ALLOW_TLSV10
 9970    if (!(options & WOLFSSL_OP_NO_TLSv1))
 9971        return TLS1_VERSION;
 9972    #endif
 9973    #ifdef WOLFSSL_ALLOW_SSLV3
 9974    if (!(options & WOLFSSL_OP_NO_SSLv3))
 9975        return SSL3_VERSION;
 9976    #endif
 9977#endif
 9978#else
 9979    (void)options;
 9980#endif /* NO_TLS */
 9981    return WOLFSSL_FATAL_ERROR;
 9982}
 9983
 9984
 9985/* returns the maximum protocol version for 'ctx' */
 9986int wolfSSL_CTX_get_max_proto_version(WOLFSSL_CTX* ctx)
 9987{
 9988    int ret = 0;
 9989    long options = 0; /* default to nothing set */
 9990
 9991    WOLFSSL_ENTER("wolfSSL_CTX_get_max_proto_version");
 9992
 9993    if (ctx != NULL) {
 9994        options = wolfSSL_CTX_get_options(ctx);
 9995    }
 9996
 9997    if ((ctx != NULL) && ctx->maxProto) {
 9998        ret = 0;
 9999    }
10000    else {
10001        ret = GetMaxProtoVersion(options);
10002    }
10003
10004    WOLFSSL_LEAVE("wolfSSL_CTX_get_max_proto_version", ret);
10005
10006    if (ret == WC_NO_ERR_TRACE(WOLFSSL_FATAL_ERROR)) {
10007        WOLFSSL_MSG("Error getting max proto version");
10008        ret = 0; /* setting ret to 0 to match compat return */
10009    }
10010    return ret;
10011}
10012#endif /* OPENSSL_EXTRA */
10013
10014#if defined(OPENSSL_EXTRA) || defined(WOLFSSL_WPAS_SMALL) || \
10015    defined(HAVE_SECRET_CALLBACK)
10016#if !defined(NO_WOLFSSL_CLIENT)
10017/* Return the amount of random bytes copied over or error case.
10018 * ssl : ssl struct after handshake
10019 * out : buffer to hold random bytes
10020 * outSz : either 0 (return max buffer sz) or size of out buffer
10021 */
10022size_t wolfSSL_get_client_random(const WOLFSSL* ssl, unsigned char* out,
10023                                                                   size_t outSz)
10024{
10025    size_t size;
10026
10027    /* return max size of buffer */
10028    if (outSz == 0) {
10029        return RAN_LEN;
10030    }
10031
10032    if (ssl == NULL || out == NULL) {
10033        return 0;
10034    }
10035
10036    if (ssl->arrays == NULL) {
10037        WOLFSSL_MSG("Arrays struct not saved after handshake");
10038        return 0;
10039    }
10040
10041    if (outSz > RAN_LEN) {
10042        size = RAN_LEN;
10043    }
10044    else {
10045        size = outSz;
10046    }
10047
10048    XMEMCPY(out, ssl->arrays->clientRandom, size);
10049    return size;
10050}
10051#endif /* !NO_WOLFSSL_CLIENT */
10052#endif /* OPENSSL_EXTRA || WOLFSSL_WPAS_SMALL || HAVE_SECRET_CALLBACK */
10053
10054#ifdef OPENSSL_EXTRA
10055
10056    unsigned long wolfSSLeay(void)
10057    {
10058#ifdef SSLEAY_VERSION_NUMBER
10059        return SSLEAY_VERSION_NUMBER;
10060#else
10061        return OPENSSL_VERSION_NUMBER;
10062#endif
10063    }
10064
10065    unsigned long wolfSSL_OpenSSL_version_num(void)
10066    {
10067        return OPENSSL_VERSION_NUMBER;
10068    }
10069
10070    const char* wolfSSLeay_version(int type)
10071    {
10072        (void)type;
10073#if defined(OPENSSL_VERSION_NUMBER) && OPENSSL_VERSION_NUMBER >= 0x10100000L
10074        return wolfSSL_OpenSSL_version(type);
10075#else
10076        return wolfSSL_OpenSSL_version();
10077#endif
10078    }
10079#endif /* OPENSSL_EXTRA */
10080
10081#ifdef OPENSSL_EXTRA
10082    void wolfSSL_ERR_free_strings(void)
10083    {
10084        /* handled internally */
10085    }
10086
10087    void wolfSSL_cleanup_all_ex_data(void)
10088    {
10089        /* nothing to do here */
10090    }
10091
10092#endif /* OPENSSL_EXTRA */
10093
10094#if defined(OPENSSL_EXTRA) || defined(DEBUG_WOLFSSL_VERBOSE) || \
10095    defined(HAVE_CURL)
10096    void wolfSSL_ERR_clear_error(void)
10097    {
10098        WOLFSSL_ENTER("wolfSSL_ERR_clear_error");
10099    #if defined(OPENSSL_EXTRA) || defined(DEBUG_WOLFSSL_VERBOSE)
10100        wc_ClearErrorNodes();
10101    #endif
10102    }
10103#endif
10104
10105#if defined(OPENSSL_EXTRA) || defined(WOLFSSL_WPAS_SMALL)
10106    int wolfSSL_clear(WOLFSSL* ssl)
10107    {
10108        WOLFSSL_ENTER("wolfSSL_clear");
10109
10110        if (ssl == NULL) {
10111            return WOLFSSL_FAILURE;
10112        }
10113
10114        if (!ssl->options.handShakeDone) {
10115            /* Only reset the session if we didn't complete a handshake */
10116            wolfSSL_FreeSession(ssl->ctx, ssl->session);
10117            ssl->session = wolfSSL_NewSession(ssl->heap);
10118            if (ssl->session == NULL) {
10119                return WOLFSSL_FAILURE;
10120            }
10121        }
10122
10123        /* reset error */
10124        ssl->error = 0;
10125
10126        /* reset option bits */
10127        ssl->options.isClosed = 0;
10128        ssl->options.connReset = 0;
10129        ssl->options.sentNotify = 0;
10130        ssl->options.closeNotify = 0;
10131        ssl->options.sendVerify = 0;
10132        ssl->options.serverState = NULL_STATE;
10133        ssl->options.clientState = NULL_STATE;
10134        ssl->options.connectState = CONNECT_BEGIN;
10135        ssl->options.acceptState  = ACCEPT_BEGIN;
10136        ssl->options.handShakeState  = NULL_STATE;
10137        ssl->options.handShakeDone = 0;
10138        ssl->options.processReply = 0; /* doProcessInit */
10139        ssl->options.havePeerVerify = 0;
10140        ssl->options.havePeerCert = 0;
10141        ssl->options.peerAuthGood = 0;
10142        ssl->options.tls1_3 = 0;
10143        ssl->options.haveSessionId = 0;
10144        ssl->options.tls = 0;
10145        ssl->options.tls1_1 = 0;
10146    #ifdef WOLFSSL_TLS13
10147    #ifdef WOLFSSL_SEND_HRR_COOKIE
10148        ssl->options.hrrSentCookie = 0;
10149    #endif
10150        ssl->options.hrrSentKeyShare = 0;
10151    #endif
10152    #ifdef WOLFSSL_DTLS
10153        ssl->options.dtlsStateful = 0;
10154    #endif
10155    #ifdef WOLFSSL_TLS13
10156    #if defined(HAVE_SESSION_TICKET) || !defined(NO_PSK)
10157        if (ssl->ctx != NULL) {
10158            ssl->options.noPskDheKe = ssl->ctx->noPskDheKe;
10159          #ifdef HAVE_SUPPORTED_CURVES
10160            ssl->options.onlyPskDheKe = ssl->ctx->onlyPskDheKe;
10161          #endif
10162        }
10163        else {
10164            ssl->options.noPskDheKe = 0;
10165          #ifdef HAVE_SUPPORTED_CURVES
10166            ssl->options.onlyPskDheKe = 0;
10167          #endif
10168        }
10169    #endif
10170    #endif
10171    #ifdef HAVE_SESSION_TICKET
10172        #ifdef WOLFSSL_TLS13
10173        ssl->options.ticketsSent = 0;
10174        #endif
10175        ssl->options.rejectTicket = 0;
10176    #endif
10177    #ifdef WOLFSSL_EARLY_DATA
10178        ssl->earlyData = no_early_data;
10179        ssl->earlyDataSz = 0;
10180    #endif
10181
10182    #if defined(HAVE_TLS_EXTENSIONS) && !defined(NO_TLS)
10183        TLSX_FreeAll(ssl->extensions, ssl->heap);
10184        ssl->extensions = NULL;
10185      #if defined(HAVE_SECURE_RENEGOTIATION) \
10186       || defined(HAVE_SERVER_RENEGOTIATION_INFO)
10187        ssl->secure_renegotiation = NULL;
10188      #endif
10189    #endif
10190
10191        if (ssl->keys.encryptionOn) {
10192            ForceZero(ssl->buffers.inputBuffer.buffer -
10193                ssl->buffers.inputBuffer.offset,
10194                ssl->buffers.inputBuffer.bufferSize);
10195        #ifdef WOLFSSL_CHECK_MEM_ZERO
10196            wc_MemZero_Check(ssl->buffers.inputBuffer.buffer -
10197                ssl->buffers.inputBuffer.offset,
10198                ssl->buffers.inputBuffer.bufferSize);
10199        #endif
10200        }
10201        ssl->keys.encryptionOn = 0;
10202        XMEMSET(&ssl->msgsReceived, 0, sizeof(ssl->msgsReceived));
10203
10204        FreeCiphers(ssl);
10205        InitCiphers(ssl);
10206        InitCipherSpecs(&ssl->specs);
10207
10208        if (InitSSL_Suites(ssl) != WOLFSSL_SUCCESS)
10209            return WOLFSSL_FAILURE;
10210
10211        if (InitHandshakeHashes(ssl) != 0)
10212            return WOLFSSL_FAILURE;
10213
10214#ifdef KEEP_PEER_CERT
10215        FreeX509(&ssl->peerCert);
10216        InitX509(&ssl->peerCert, 0, ssl->heap);
10217#endif
10218
10219#ifdef WOLFSSL_QUIC
10220        wolfSSL_quic_clear(ssl);
10221#endif
10222#ifdef HAVE_OCSP
10223#if defined(WOLFSSL_TLS13) && defined(HAVE_CERTIFICATE_STATUS_REQUEST)
10224        ssl->response_idx = 0;
10225#endif
10226#endif
10227        return WOLFSSL_SUCCESS;
10228    }
10229
10230#endif /* OPENSSL_EXTRA || WOLFSSL_WPAS_SMALL */
10231
10232#if defined(OPENSSL_EXTRA) || defined(HAVE_WEBSERVER) || defined(HAVE_MEMCACHED)
10233    long wolfSSL_CTX_set_mode(WOLFSSL_CTX* ctx, long mode)
10234    {
10235        /* WOLFSSL_MODE_ACCEPT_MOVING_WRITE_BUFFER is wolfSSL default mode */
10236
10237        WOLFSSL_ENTER("wolfSSL_CTX_set_mode");
10238        switch(mode) {
10239            case WOLFSSL_MODE_ENABLE_PARTIAL_WRITE:
10240                ctx->partialWrite = 1;
10241                break;
10242            #if defined(OPENSSL_ALL) || defined(WOLFSSL_QT)
10243            case SSL_MODE_RELEASE_BUFFERS:
10244                WOLFSSL_MSG("SSL_MODE_RELEASE_BUFFERS not implemented.");
10245                break;
10246            #endif
10247            case WOLFSSL_MODE_AUTO_RETRY:
10248                ctx->autoRetry = 1;
10249                break;
10250            default:
10251                WOLFSSL_MSG("Mode Not Implemented");
10252        }
10253
10254        /* WOLFSSL_MODE_AUTO_RETRY
10255         * Should not return WOLFSSL_FATAL_ERROR with renegotiation on read/write */
10256
10257        return mode;
10258    }
10259
10260    long wolfSSL_CTX_clear_mode(WOLFSSL_CTX* ctx, long mode)
10261    {
10262        /* WOLFSSL_MODE_ACCEPT_MOVING_WRITE_BUFFER is wolfSSL default mode */
10263
10264        WOLFSSL_ENTER("wolfSSL_CTX_clear_mode");
10265        switch(mode) {
10266            case WOLFSSL_MODE_ENABLE_PARTIAL_WRITE:
10267                ctx->partialWrite = 0;
10268                break;
10269            #if defined(OPENSSL_ALL) || defined(WOLFSSL_QT)
10270            case SSL_MODE_RELEASE_BUFFERS:
10271                WOLFSSL_MSG("SSL_MODE_RELEASE_BUFFERS not implemented.");
10272                break;
10273            #endif
10274            case WOLFSSL_MODE_AUTO_RETRY:
10275                ctx->autoRetry = 0;
10276                break;
10277            default:
10278                WOLFSSL_MSG("Mode Not Implemented");
10279        }
10280
10281        /* WOLFSSL_MODE_AUTO_RETRY
10282         * Should not return WOLFSSL_FATAL_ERROR with renegotiation on read/write */
10283
10284        return 0;
10285    }
10286#endif
10287
10288#ifdef OPENSSL_EXTRA
10289
10290    #ifndef NO_WOLFSSL_STUB
10291    long wolfSSL_SSL_get_mode(WOLFSSL* ssl)
10292    {
10293        /* TODO: */
10294        (void)ssl;
10295        WOLFSSL_STUB("SSL_get_mode");
10296        return 0;
10297    }
10298    #endif
10299
10300    #ifndef NO_WOLFSSL_STUB
10301    long wolfSSL_CTX_get_mode(WOLFSSL_CTX* ctx)
10302    {
10303        /* TODO: */
10304        (void)ctx;
10305        WOLFSSL_STUB("SSL_CTX_get_mode");
10306        return 0;
10307    }
10308    #endif
10309
10310    #ifndef NO_WOLFSSL_STUB
10311    void wolfSSL_CTX_set_default_read_ahead(WOLFSSL_CTX* ctx, int m)
10312    {
10313        /* TODO: maybe? */
10314        (void)ctx;
10315        (void)m;
10316        WOLFSSL_STUB("SSL_CTX_set_default_read_ahead");
10317    }
10318    #endif
10319
10320
10321    /* returns the unsigned error value and increments the pointer into the
10322     * error queue.
10323     *
10324     * file  pointer to file name
10325     * line  gets set to line number of error when not NULL
10326     */
10327    unsigned long wolfSSL_ERR_get_error_line(const char** file, int* line)
10328    {
10329    #ifdef WOLFSSL_HAVE_ERROR_QUEUE
10330        int ret = wc_PullErrorNode(file, NULL, line);
10331        if (ret < 0) {
10332            if (ret == WC_NO_ERR_TRACE(BAD_STATE_E))
10333                return 0; /* no errors in queue */
10334            WOLFSSL_MSG("Issue getting error node");
10335            WOLFSSL_LEAVE("wolfSSL_ERR_get_error_line", ret);
10336            ret = 0 - ret; /* return absolute value of error */
10337
10338            /* panic and try to clear out nodes */
10339            wc_ClearErrorNodes();
10340        }
10341        return (unsigned long)ret;
10342    #else
10343        (void)file;
10344        (void)line;
10345
10346        return 0;
10347    #endif
10348    }
10349
10350
10351#if (defined(DEBUG_WOLFSSL) || defined(OPENSSL_EXTRA)) && \
10352    (!defined(_WIN32) && !defined(NO_ERROR_QUEUE))
10353    static const char WOLFSSL_SYS_ACCEPT_T[]  = "accept";
10354    static const char WOLFSSL_SYS_BIND_T[]    = "bind";
10355    static const char WOLFSSL_SYS_CONNECT_T[] = "connect";
10356    static const char WOLFSSL_SYS_FOPEN_T[]   = "fopen";
10357    static const char WOLFSSL_SYS_FREAD_T[]   = "fread";
10358    static const char WOLFSSL_SYS_GETADDRINFO_T[] = "getaddrinfo";
10359    static const char WOLFSSL_SYS_GETSOCKOPT_T[]  = "getsockopt";
10360    static const char WOLFSSL_SYS_GETSOCKNAME_T[] = "getsockname";
10361    static const char WOLFSSL_SYS_GETHOSTBYNAME_T[] = "gethostbyname";
10362    static const char WOLFSSL_SYS_GETNAMEINFO_T[]   = "getnameinfo";
10363    static const char WOLFSSL_SYS_GETSERVBYNAME_T[] = "getservbyname";
10364    static const char WOLFSSL_SYS_IOCTLSOCKET_T[]   = "ioctlsocket";
10365    static const char WOLFSSL_SYS_LISTEN_T[]        = "listen";
10366    static const char WOLFSSL_SYS_OPENDIR_T[]       = "opendir";
10367    static const char WOLFSSL_SYS_SETSOCKOPT_T[]    = "setsockopt";
10368    static const char WOLFSSL_SYS_SOCKET_T[]        = "socket";
10369
10370    /* switch with int mapped to function name for compatibility */
10371    static const char* wolfSSL_ERR_sys_func(int fun)
10372    {
10373        switch (fun) {
10374            case WOLFSSL_SYS_ACCEPT:      return WOLFSSL_SYS_ACCEPT_T;
10375            case WOLFSSL_SYS_BIND:        return WOLFSSL_SYS_BIND_T;
10376            case WOLFSSL_SYS_CONNECT:     return WOLFSSL_SYS_CONNECT_T;
10377            case WOLFSSL_SYS_FOPEN:       return WOLFSSL_SYS_FOPEN_T;
10378            case WOLFSSL_SYS_FREAD:       return WOLFSSL_SYS_FREAD_T;
10379            case WOLFSSL_SYS_GETADDRINFO: return WOLFSSL_SYS_GETADDRINFO_T;
10380            case WOLFSSL_SYS_GETSOCKOPT:  return WOLFSSL_SYS_GETSOCKOPT_T;
10381            case WOLFSSL_SYS_GETSOCKNAME: return WOLFSSL_SYS_GETSOCKNAME_T;
10382            case WOLFSSL_SYS_GETHOSTBYNAME: return WOLFSSL_SYS_GETHOSTBYNAME_T;
10383            case WOLFSSL_SYS_GETNAMEINFO: return WOLFSSL_SYS_GETNAMEINFO_T;
10384            case WOLFSSL_SYS_GETSERVBYNAME: return WOLFSSL_SYS_GETSERVBYNAME_T;
10385            case WOLFSSL_SYS_IOCTLSOCKET: return WOLFSSL_SYS_IOCTLSOCKET_T;
10386            case WOLFSSL_SYS_LISTEN:      return WOLFSSL_SYS_LISTEN_T;
10387            case WOLFSSL_SYS_OPENDIR:     return WOLFSSL_SYS_OPENDIR_T;
10388            case WOLFSSL_SYS_SETSOCKOPT:  return WOLFSSL_SYS_SETSOCKOPT_T;
10389            case WOLFSSL_SYS_SOCKET:      return WOLFSSL_SYS_SOCKET_T;
10390            default:
10391                return "NULL";
10392        }
10393    }
10394#endif /* DEBUG_WOLFSSL */
10395
10396
10397    void wolfSSL_ERR_put_error(int lib, int fun, int err, const char* file,
10398            int line)
10399    {
10400        WOLFSSL_ENTER("wolfSSL_ERR_put_error");
10401
10402        #if !defined(DEBUG_WOLFSSL) && !defined(OPENSSL_EXTRA)
10403        (void)fun;
10404        (void)err;
10405        (void)file;
10406        (void)line;
10407        WOLFSSL_MSG("Not compiled in debug mode");
10408        #elif defined(OPENSSL_EXTRA) && \
10409                (defined(_WIN32) || defined(NO_ERROR_QUEUE))
10410        (void)fun;
10411        (void)file;
10412        (void)line;
10413        WOLFSSL_ERROR(err);
10414        #else
10415        WOLFSSL_ERROR_LINE(err, wolfSSL_ERR_sys_func(fun), (unsigned int)line,
10416            file, NULL);
10417        #endif
10418        (void)lib;
10419    }
10420
10421
10422    /* Similar to wolfSSL_ERR_get_error_line but takes in a flags argument for
10423     * more flexibility.
10424     *
10425     * file  output pointer to file where error happened
10426     * line  output to line number of error
10427     * data  output data. Is a string if WOLFSSL_ERR_TXT_STRING flag is used
10428     * flags output format of output
10429     *
10430     * Returns the error value or 0 if no errors are in the queue
10431     */
10432    unsigned long wolfSSL_ERR_get_error_line_data(const char** file, int* line,
10433                                                  const char** data, int *flags)
10434    {
10435#ifdef WOLFSSL_HAVE_ERROR_QUEUE
10436        int ret;
10437
10438        WOLFSSL_ENTER("wolfSSL_ERR_get_error_line_data");
10439
10440        if (flags != NULL)
10441            *flags = WOLFSSL_ERR_TXT_STRING; /* Clear the flags */
10442
10443        ret = wc_PullErrorNode(file, data, line);
10444        if (ret < 0) {
10445            if (ret == WC_NO_ERR_TRACE(BAD_STATE_E))
10446                return 0; /* no errors in queue */
10447            WOLFSSL_MSG("Error with pulling error node!");
10448            WOLFSSL_LEAVE("wolfSSL_ERR_get_error_line_data", ret);
10449            ret = 0 - ret; /* return absolute value of error */
10450
10451            /* panic and try to clear out nodes */
10452            wc_ClearErrorNodes();
10453        }
10454
10455        return (unsigned long)ret;
10456#else
10457        WOLFSSL_ENTER("wolfSSL_ERR_get_error_line_data");
10458        WOLFSSL_MSG("Error queue turned off, can not get error line");
10459        (void)file;
10460        (void)line;
10461        (void)data;
10462        (void)flags;
10463        return 0;
10464#endif
10465    }
10466
10467#endif /* OPENSSL_EXTRA */
10468
10469
10470#if (defined(KEEP_PEER_CERT) && defined(SESSION_CERTS)) || \
10471    (defined(OPENSSL_EXTRA) && defined(SESSION_CERTS))
10472    /* Decode the X509 DER encoded certificate into a WOLFSSL_X509 object.
10473     *
10474     * x509  WOLFSSL_X509 object to decode into.
10475     * in    X509 DER data.
10476     * len   Length of the X509 DER data.
10477     * returns the new certificate on success, otherwise NULL.
10478     */
10479    static int DecodeToX509(WOLFSSL_X509* x509, const byte* in, int len)
10480    {
10481        int          ret;
10482        WC_DECLARE_VAR(cert, DecodedCert, 1, 0);
10483        if (x509 == NULL || in == NULL || len <= 0)
10484            return BAD_FUNC_ARG;
10485
10486        WC_ALLOC_VAR_EX(cert, DecodedCert, 1, NULL, DYNAMIC_TYPE_DCERT,
10487            return MEMORY_E);
10488
10489        /* Create a DecodedCert object and copy fields into WOLFSSL_X509 object.
10490         */
10491        InitDecodedCert(cert, (byte*)in, (word32)len, NULL);
10492        if ((ret = ParseCertRelative(cert, CERT_TYPE, 0, NULL, NULL)) == 0) {
10493        /* Check if x509 was not previously initialized by wolfSSL_X509_new() */
10494            if (x509->dynamicMemory != TRUE)
10495                InitX509(x509, 0, NULL);
10496            ret = CopyDecodedToX509(x509, cert);
10497        }
10498        FreeDecodedCert(cert);
10499        WC_FREE_VAR_EX(cert, NULL, DYNAMIC_TYPE_DCERT);
10500
10501        return ret;
10502    }
10503#endif /* (KEEP_PEER_CERT & SESSION_CERTS) || (OPENSSL_EXTRA & SESSION_CERTS) */
10504
10505
10506#ifdef KEEP_PEER_CERT
10507    WOLFSSL_ABI
10508    WOLFSSL_X509* wolfSSL_get_peer_certificate(WOLFSSL* ssl)
10509    {
10510        WOLFSSL_X509* ret = NULL;
10511        WOLFSSL_ENTER("wolfSSL_get_peer_certificate");
10512        if (ssl != NULL) {
10513            if (ssl->peerCert.issuer.sz)
10514                ret = wolfSSL_X509_dup(&ssl->peerCert);
10515#ifdef SESSION_CERTS
10516            else if (ssl->session->chain.count > 0) {
10517                if (DecodeToX509(&ssl->peerCert,
10518                        ssl->session->chain.certs[0].buffer,
10519                        ssl->session->chain.certs[0].length) == 0) {
10520                    ret = wolfSSL_X509_dup(&ssl->peerCert);
10521                }
10522            }
10523#endif
10524        }
10525        WOLFSSL_LEAVE("wolfSSL_get_peer_certificate", ret != NULL);
10526        return ret;
10527    }
10528
10529#endif /* KEEP_PEER_CERT */
10530
10531#if defined(SESSION_CERTS) && defined(OPENSSL_EXTRA)
10532/* Return stack of peer certs.
10533 * Caller does not need to free return. The stack is Free'd when WOLFSSL* ssl
10534 * is.
10535 */
10536WOLF_STACK_OF(WOLFSSL_X509)* wolfSSL_get_peer_cert_chain(const WOLFSSL* ssl)
10537{
10538    WOLFSSL_ENTER("wolfSSL_get_peer_cert_chain");
10539
10540    if (ssl == NULL)
10541        return NULL;
10542
10543    /* Try to populate if NULL or empty */
10544    if (ssl->peerCertChain == NULL ||
10545            wolfSSL_sk_X509_num(ssl->peerCertChain) == 0) {
10546        wolfSSL_set_peer_cert_chain((WOLFSSL*) ssl);
10547    }
10548    return ssl->peerCertChain;
10549}
10550
10551
10552static int x509GetIssuerFromCM(WOLFSSL_X509 **issuer, WOLFSSL_CERT_MANAGER* cm,
10553        WOLFSSL_X509 *x);
10554/**
10555 * Recursively push the issuer CA chain onto the stack
10556 * @param cm The cert manager that is queried for the issuer
10557 * @param x  This cert's issuer will be queried in cm
10558 * @param sk The issuer is pushed onto this stack
10559 * @return 0 on success or no issuer found
10560 *         WOLFSSL_FATAL_ERROR on a fatal error
10561 */
10562static int PushCAx509Chain(WOLFSSL_CERT_MANAGER* cm,
10563        WOLFSSL_X509 *x, WOLFSSL_STACK* sk)
10564{
10565    int i;
10566    for (i = 0; i < MAX_CHAIN_DEPTH; i++) {
10567        WOLFSSL_X509* issuer = NULL;
10568        if (x509GetIssuerFromCM(&issuer, cm, x) != WOLFSSL_SUCCESS)
10569            break;
10570        if (wolfSSL_sk_X509_push(sk, issuer) <= 0) {
10571            wolfSSL_X509_free(issuer);
10572            issuer = NULL;
10573            return WOLFSSL_FATAL_ERROR;
10574        }
10575        x = issuer;
10576    }
10577    return 0;
10578}
10579
10580
10581/* Builds up and creates a stack of peer certificates for ssl->peerCertChain
10582    or ssl->verifiedChain based off of the ssl session chain. Attempts to place
10583    CA certificates at the bottom of the stack for a verified chain. Returns
10584    stack of WOLFSSL_X509 certs or NULL on failure */
10585static WOLF_STACK_OF(WOLFSSL_X509)* CreatePeerCertChain(const WOLFSSL* ssl,
10586    int verifiedFlag)
10587{
10588    WOLFSSL_STACK* sk;
10589    WOLFSSL_X509* x509;
10590    int i = 0;
10591    int err;
10592
10593    WOLFSSL_ENTER("wolfSSL_set_peer_cert_chain");
10594    if ((ssl == NULL) || (ssl->session->chain.count == 0))
10595        return NULL;
10596
10597    sk = wolfSSL_sk_X509_new_null();
10598    for (i = 0; i < ssl->session->chain.count; i++) {
10599        x509 = wolfSSL_X509_new_ex(ssl->heap);
10600        if (x509 == NULL) {
10601            WOLFSSL_MSG("Error Creating X509");
10602            wolfSSL_sk_X509_pop_free(sk, NULL);
10603            return NULL;
10604        }
10605        err = DecodeToX509(x509, ssl->session->chain.certs[i].buffer,
10606                             ssl->session->chain.certs[i].length);
10607        if (err == 0 && wolfSSL_sk_X509_push(sk, x509) <= 0)
10608            err = WOLFSSL_FATAL_ERROR;
10609        if (err == 0 && i == ssl->session->chain.count-1 && verifiedFlag) {
10610            /* On the last element in the verified chain try to add the CA chain
10611             * if we have one for this cert */
10612            SSL_CM_WARNING(ssl);
10613            err = PushCAx509Chain(SSL_CM(ssl), x509, sk);
10614        }
10615        if (err != 0) {
10616            WOLFSSL_MSG("Error decoding cert");
10617            wolfSSL_X509_free(x509);
10618            x509 = NULL;
10619            wolfSSL_sk_X509_pop_free(sk, NULL);
10620            return NULL;
10621        }
10622    }
10623
10624    if (sk == NULL) {
10625        WOLFSSL_MSG("Null session chain");
10626    }
10627    return sk;
10628}
10629
10630
10631/* Builds up and creates a stack of peer certificates for ssl->peerCertChain
10632    returns the stack on success and NULL on failure */
10633WOLF_STACK_OF(WOLFSSL_X509)* wolfSSL_set_peer_cert_chain(WOLFSSL* ssl)
10634{
10635    WOLFSSL_STACK* sk;
10636
10637    WOLFSSL_ENTER("wolfSSL_set_peer_cert_chain");
10638    if ((ssl == NULL) || (ssl->session->chain.count == 0))
10639        return NULL;
10640
10641    sk = CreatePeerCertChain(ssl, 0);
10642
10643    if (sk != NULL) {
10644        if (ssl->options.side == WOLFSSL_SERVER_END) {
10645            if (ssl->session->peer)
10646                wolfSSL_X509_free(ssl->session->peer);
10647
10648            ssl->session->peer = wolfSSL_sk_X509_shift(sk);
10649            ssl->session->peerVerifyRet = ssl->peerVerifyRet;
10650        }
10651        if (ssl->peerCertChain != NULL)
10652            wolfSSL_sk_X509_pop_free(ssl->peerCertChain, NULL);
10653        /* This is Free'd when ssl is Free'd */
10654        ssl->peerCertChain = sk;
10655    }
10656    return sk;
10657}
10658
10659#ifdef KEEP_PEER_CERT
10660/**
10661 * Implemented in a similar way that ngx_ssl_ocsp_validate does it when
10662 * SSL_get0_verified_chain is not available.
10663 * @param ssl WOLFSSL object to extract certs from
10664 * @return Stack of verified certs
10665 */
10666WOLF_STACK_OF(WOLFSSL_X509) *wolfSSL_get0_verified_chain(const WOLFSSL *ssl)
10667{
10668    WOLF_STACK_OF(WOLFSSL_X509)* chain = NULL;
10669    WOLFSSL_X509_STORE_CTX* storeCtx = NULL;
10670    WOLFSSL_X509* peerCert = NULL;
10671
10672    WOLFSSL_ENTER("wolfSSL_get0_verified_chain");
10673
10674    if (ssl == NULL || ssl->ctx == NULL) {
10675        WOLFSSL_MSG("Bad parameter");
10676        return NULL;
10677    }
10678
10679    peerCert = wolfSSL_get_peer_certificate((WOLFSSL*)ssl);
10680    if (peerCert == NULL) {
10681        WOLFSSL_MSG("wolfSSL_get_peer_certificate error");
10682        return NULL;
10683    }
10684    /* wolfSSL_get_peer_certificate returns a copy. We want the internal
10685     * member so that we don't have to worry about free'ing it. We call
10686     * wolfSSL_get_peer_certificate so that we don't have to worry about
10687     * setting up the internal pointer. */
10688    wolfSSL_X509_free(peerCert);
10689    peerCert = (WOLFSSL_X509*)&ssl->peerCert;
10690    chain = CreatePeerCertChain((WOLFSSL*)ssl, 1);
10691    if (chain == NULL) {
10692        WOLFSSL_MSG("wolfSSL_get_peer_cert_chain error");
10693        return NULL;
10694    }
10695
10696    if (ssl->verifiedChain != NULL) {
10697        wolfSSL_sk_X509_pop_free(ssl->verifiedChain, NULL);
10698    }
10699    ((WOLFSSL*)ssl)->verifiedChain = chain;
10700
10701    storeCtx = wolfSSL_X509_STORE_CTX_new();
10702    if (storeCtx == NULL) {
10703        WOLFSSL_MSG("wolfSSL_X509_STORE_CTX_new error");
10704        return NULL;
10705    }
10706    if (wolfSSL_X509_STORE_CTX_init(storeCtx, SSL_STORE(ssl),
10707            peerCert, chain) != WOLFSSL_SUCCESS) {
10708        WOLFSSL_MSG("wolfSSL_X509_STORE_CTX_init error");
10709        wolfSSL_X509_STORE_CTX_free(storeCtx);
10710        return NULL;
10711    }
10712    if (wolfSSL_X509_verify_cert(storeCtx) <= 0) {
10713        WOLFSSL_MSG("wolfSSL_X509_verify_cert error");
10714        wolfSSL_X509_STORE_CTX_free(storeCtx);
10715        return NULL;
10716    }
10717    wolfSSL_X509_STORE_CTX_free(storeCtx);
10718    return chain;
10719}
10720#endif /* KEEP_PEER_CERT */
10721#endif /* SESSION_CERTS && OPENSSL_EXTRA */
10722
10723#if defined(OPENSSL_EXTRA) || defined(WOLFSSL_WPAS_SMALL)
10724void wolfSSL_set_connect_state(WOLFSSL* ssl)
10725{
10726    WOLFSSL_ENTER("wolfSSL_set_connect_state");
10727    if (ssl == NULL) {
10728        WOLFSSL_MSG("WOLFSSL struct pointer passed in was null");
10729        return;
10730    }
10731
10732    #ifndef NO_DH
10733    /* client creates its own DH parameters on handshake */
10734    if (ssl->buffers.serverDH_P.buffer && ssl->buffers.weOwnDH) {
10735        XFREE(ssl->buffers.serverDH_P.buffer, ssl->heap,
10736            DYNAMIC_TYPE_PUBLIC_KEY);
10737    }
10738    ssl->buffers.serverDH_P.buffer = NULL;
10739    if (ssl->buffers.serverDH_G.buffer && ssl->buffers.weOwnDH) {
10740        XFREE(ssl->buffers.serverDH_G.buffer, ssl->heap,
10741            DYNAMIC_TYPE_PUBLIC_KEY);
10742    }
10743    ssl->buffers.serverDH_G.buffer = NULL;
10744    #endif
10745
10746    if (InitSSL_Side(ssl, WOLFSSL_CLIENT_END) != WOLFSSL_SUCCESS) {
10747        WOLFSSL_MSG("Error initializing client side");
10748    }
10749}
10750#endif /* OPENSSL_EXTRA || WOLFSSL_WPAS_SMALL */
10751
10752
10753int wolfSSL_get_shutdown(const WOLFSSL* ssl)
10754{
10755    int isShutdown = 0;
10756
10757    WOLFSSL_ENTER("wolfSSL_get_shutdown");
10758
10759    if (ssl) {
10760#if defined(OPENSSL_EXTRA) || defined(WOLFSSL_WPAS_SMALL)
10761        if (ssl->options.shutdownDone) {
10762            /* The SSL object was possibly cleared with wolfSSL_clear after
10763             * a successful shutdown. Simulate a response for a full
10764             * bidirectional shutdown. */
10765            isShutdown = WOLFSSL_SENT_SHUTDOWN | WOLFSSL_RECEIVED_SHUTDOWN;
10766        }
10767        else
10768#endif
10769        {
10770            /* in OpenSSL, WOLFSSL_SENT_SHUTDOWN = 1, when closeNotifySent   *
10771             * WOLFSSL_RECEIVED_SHUTDOWN = 2, from close notify or fatal err */
10772            if (ssl->options.sentNotify)
10773                isShutdown |= WOLFSSL_SENT_SHUTDOWN;
10774            if (ssl->options.closeNotify||ssl->options.connReset)
10775                isShutdown |= WOLFSSL_RECEIVED_SHUTDOWN;
10776        }
10777
10778    }
10779
10780    WOLFSSL_LEAVE("wolfSSL_get_shutdown", isShutdown);
10781    return isShutdown;
10782}
10783
10784
10785int wolfSSL_session_reused(WOLFSSL* ssl)
10786{
10787    int resuming = 0;
10788    WOLFSSL_ENTER("wolfSSL_session_reused");
10789    if (ssl) {
10790#ifndef HAVE_SECURE_RENEGOTIATION
10791        resuming = ssl->options.resuming;
10792#else
10793        resuming = ssl->options.resuming || ssl->options.resumed;
10794#endif
10795    }
10796    WOLFSSL_LEAVE("wolfSSL_session_reused", resuming);
10797    return resuming;
10798}
10799
10800/* helper function that takes in a protocol version struct and returns string */
10801static const char* wolfSSL_internal_get_version(const ProtocolVersion* version)
10802{
10803    WOLFSSL_ENTER("wolfSSL_get_version");
10804
10805    if (version == NULL) {
10806        return "Bad arg";
10807    }
10808
10809    if (version->major == SSLv3_MAJOR) {
10810        switch (version->minor) {
10811            case SSLv3_MINOR :
10812                return "SSLv3";
10813            case TLSv1_MINOR :
10814                return "TLSv1";
10815            case TLSv1_1_MINOR :
10816                return "TLSv1.1";
10817            case TLSv1_2_MINOR :
10818                return "TLSv1.2";
10819            case TLSv1_3_MINOR :
10820                return "TLSv1.3";
10821            default:
10822                return "unknown";
10823        }
10824    }
10825#ifdef WOLFSSL_DTLS
10826    else if (version->major == DTLS_MAJOR) {
10827        switch (version->minor) {
10828            case DTLS_MINOR :
10829                return "DTLS";
10830            case DTLSv1_2_MINOR :
10831                return "DTLSv1.2";
10832            case DTLSv1_3_MINOR :
10833                return "DTLSv1.3";
10834            default:
10835                return "unknown";
10836        }
10837    }
10838#endif /* WOLFSSL_DTLS */
10839    return "unknown";
10840}
10841
10842
10843const char* wolfSSL_get_version(const WOLFSSL* ssl)
10844{
10845    if (ssl == NULL) {
10846        WOLFSSL_MSG("Bad argument");
10847        return "unknown";
10848    }
10849
10850    return wolfSSL_internal_get_version(&ssl->version);
10851}
10852
10853
10854/* current library version */
10855const char* wolfSSL_lib_version(void)
10856{
10857    return LIBWOLFSSL_VERSION_STRING;
10858}
10859
10860#ifdef OPENSSL_EXTRA
10861#if defined(OPENSSL_VERSION_NUMBER) && OPENSSL_VERSION_NUMBER >= 0x10100000L
10862const char* wolfSSL_OpenSSL_version(int a)
10863{
10864    (void)a;
10865    return "wolfSSL " LIBWOLFSSL_VERSION_STRING;
10866}
10867#else
10868const char* wolfSSL_OpenSSL_version(void)
10869{
10870    return "wolfSSL " LIBWOLFSSL_VERSION_STRING;
10871}
10872#endif /* WOLFSSL_QT */
10873#endif
10874
10875
10876/* current library version in hex */
10877word32 wolfSSL_lib_version_hex(void)
10878{
10879    return LIBWOLFSSL_VERSION_HEX;
10880}
10881
10882
10883int wolfSSL_get_current_cipher_suite(WOLFSSL* ssl)
10884{
10885    WOLFSSL_ENTER("wolfSSL_get_current_cipher_suite");
10886    if (ssl)
10887        return (ssl->options.cipherSuite0 << 8) | ssl->options.cipherSuite;
10888    return 0;
10889}
10890
10891WOLFSSL_CIPHER* wolfSSL_get_current_cipher(WOLFSSL* ssl)
10892{
10893    WOLFSSL_ENTER("wolfSSL_get_current_cipher");
10894    if (ssl) {
10895        ssl->cipher.cipherSuite0 = ssl->options.cipherSuite0;
10896        ssl->cipher.cipherSuite  = ssl->options.cipherSuite;
10897#if defined(OPENSSL_ALL) || defined(WOLFSSL_QT)
10898        ssl->cipher.bits = ssl->specs.key_size * 8;
10899#endif
10900        return &ssl->cipher;
10901    }
10902    else
10903        return NULL;
10904}
10905
10906
10907const char* wolfSSL_CIPHER_get_name(const WOLFSSL_CIPHER* cipher)
10908{
10909    WOLFSSL_ENTER("wolfSSL_CIPHER_get_name");
10910
10911    if (cipher == NULL) {
10912        return NULL;
10913    }
10914
10915    #if !defined(WOLFSSL_CIPHER_INTERNALNAME) && !defined(NO_ERROR_STRINGS) && \
10916        !defined(WOLFSSL_QT)
10917        return GetCipherNameIana(cipher->cipherSuite0, cipher->cipherSuite);
10918    #else
10919        return wolfSSL_get_cipher_name_from_suite(cipher->cipherSuite0,
10920                cipher->cipherSuite);
10921    #endif
10922}
10923
10924const char*  wolfSSL_CIPHER_get_version(const WOLFSSL_CIPHER* cipher)
10925{
10926    WOLFSSL_ENTER("wolfSSL_CIPHER_get_version");
10927
10928    if (cipher == NULL || cipher->ssl == NULL) {
10929        return NULL;
10930    }
10931
10932    return wolfSSL_get_version(cipher->ssl);
10933}
10934
10935const char* wolfSSL_get_cipher(WOLFSSL* ssl)
10936{
10937    WOLFSSL_ENTER("wolfSSL_get_cipher");
10938    return wolfSSL_CIPHER_get_name(wolfSSL_get_current_cipher(ssl));
10939}
10940
10941/* gets cipher name in the format DHE-RSA-... rather then TLS_DHE... */
10942const char* wolfSSL_get_cipher_name(WOLFSSL* ssl)
10943{
10944    /* get access to cipher_name_idx in internal.c */
10945    return wolfSSL_get_cipher_name_internal(ssl);
10946}
10947
10948const char* wolfSSL_get_cipher_name_from_suite(byte cipherSuite0,
10949    byte cipherSuite)
10950{
10951    return GetCipherNameInternal(cipherSuite0, cipherSuite);
10952}
10953
10954const char* wolfSSL_get_cipher_name_iana_from_suite(byte cipherSuite0,
10955        byte cipherSuite)
10956{
10957    return GetCipherNameIana(cipherSuite0, cipherSuite);
10958}
10959
10960int wolfSSL_get_cipher_suite_from_name(const char* name, byte* cipherSuite0,
10961                                       byte* cipherSuite, int *flags) {
10962    if ((name == NULL) ||
10963        (cipherSuite0 == NULL) ||
10964        (cipherSuite == NULL) ||
10965        (flags == NULL))
10966        return BAD_FUNC_ARG;
10967    return GetCipherSuiteFromName(name, cipherSuite0, cipherSuite, NULL, NULL,
10968                                  flags);
10969}
10970
10971
10972word32 wolfSSL_CIPHER_get_id(const WOLFSSL_CIPHER* cipher)
10973{
10974    word16 cipher_id = 0;
10975
10976    WOLFSSL_ENTER("wolfSSL_CIPHER_get_id");
10977
10978    if (cipher && cipher->ssl) {
10979        cipher_id = (word16)(cipher->ssl->options.cipherSuite0 << 8) |
10980                     cipher->ssl->options.cipherSuite;
10981    }
10982
10983    return cipher_id;
10984}
10985
10986const WOLFSSL_CIPHER* wolfSSL_get_cipher_by_value(word16 value)
10987{
10988    const WOLFSSL_CIPHER* cipher = NULL;
10989    byte cipherSuite0, cipherSuite;
10990    WOLFSSL_ENTER("wolfSSL_get_cipher_by_value");
10991
10992    /* extract cipher id information */
10993    cipherSuite =   (value       & 0xFF);
10994    cipherSuite0 = ((value >> 8) & 0xFF);
10995
10996    /* TODO: lookup by cipherSuite0 / cipherSuite */
10997    (void)cipherSuite0;
10998    (void)cipherSuite;
10999
11000    return cipher;
11001}
11002
11003
11004#if defined(HAVE_ECC) || defined(HAVE_CURVE25519) || defined(HAVE_CURVE448) || \
11005    !defined(NO_DH) || (defined(WOLFSSL_TLS13) && defined(WOLFSSL_HAVE_MLKEM))
11006#ifdef HAVE_FFDHE
11007static const char* wolfssl_ffdhe_name(word16 group)
11008{
11009    const char* str = NULL;
11010    switch (group) {
11011        case WOLFSSL_FFDHE_2048:
11012            str = "FFDHE_2048";
11013            break;
11014        case WOLFSSL_FFDHE_3072:
11015            str = "FFDHE_3072";
11016            break;
11017        case WOLFSSL_FFDHE_4096:
11018            str = "FFDHE_4096";
11019            break;
11020        case WOLFSSL_FFDHE_6144:
11021            str = "FFDHE_6144";
11022            break;
11023        case WOLFSSL_FFDHE_8192:
11024            str = "FFDHE_8192";
11025            break;
11026        default:
11027            break;
11028    }
11029    return str;
11030}
11031#endif
11032/* Return the name of the curve used for key exchange as a printable string.
11033 *
11034 * ssl  The SSL/TLS object.
11035 * returns NULL if ECDH was not used, otherwise the name as a string.
11036 */
11037const char* wolfSSL_get_curve_name(WOLFSSL* ssl)
11038{
11039    const char* cName = NULL;
11040
11041    WOLFSSL_ENTER("wolfSSL_get_curve_name");
11042
11043    if (ssl == NULL)
11044        return NULL;
11045
11046#if defined(WOLFSSL_TLS13) && defined(WOLFSSL_HAVE_MLKEM)
11047    /* Check for post-quantum groups. Return now because we do not want the ECC
11048     * check to override this result in the case of a hybrid. */
11049    if (IsAtLeastTLSv1_3(ssl->version)) {
11050        switch (ssl->namedGroup) {
11051#ifndef WOLFSSL_NO_ML_KEM
11052    #ifndef WOLFSSL_NO_ML_KEM_512
11053        case WOLFSSL_ML_KEM_512:
11054            return "ML_KEM_512";
11055        #ifdef WOLFSSL_EXTRA_PQC_HYBRIDS
11056        #ifdef WOLFSSL_ML_KEM_USE_OLD_IDS
11057        case WOLFSSL_P256_ML_KEM_512_OLD:
11058            return "P256_ML_KEM_512_OLD";
11059        #endif /* WOLFSSL_ML_KEM_USE_OLD_IDS */
11060        case WOLFSSL_SECP256R1MLKEM512:
11061            return "SecP256r1MLKEM512";
11062        #ifdef HAVE_CURVE25519
11063        case WOLFSSL_X25519MLKEM512:
11064            return "X25519MLKEM512";
11065        #endif /* HAVE_CURVE25519 */
11066        #endif /* WOLFSSL_EXTRA_PQC_HYBRIDS */
11067    #endif /* WOLFSSL_NO_ML_KEM_512 */
11068    #ifndef WOLFSSL_NO_ML_KEM_768
11069        case WOLFSSL_ML_KEM_768:
11070            return "ML_KEM_768";
11071        #ifdef WOLFSSL_PQC_HYBRIDS
11072        case WOLFSSL_SECP256R1MLKEM768:
11073            return "SecP256r1MLKEM768";
11074        #ifdef HAVE_CURVE25519
11075        case WOLFSSL_X25519MLKEM768:
11076            return "X25519MLKEM768";
11077        #endif
11078        #endif /* WOLFSSL_PQC_HYBRIDS */
11079        #ifdef WOLFSSL_EXTRA_PQC_HYBRIDS
11080        #ifdef WOLFSSL_ML_KEM_USE_OLD_IDS
11081        case WOLFSSL_P384_ML_KEM_768_OLD:
11082            return "P384_ML_KEM_768_OLD";
11083        #endif /* WOLFSSL_ML_KEM_USE_OLD_IDS */
11084        case WOLFSSL_SECP384R1MLKEM768:
11085            return "SecP384r1MLKEM768";
11086        #ifdef HAVE_CURVE448
11087        case WOLFSSL_X448MLKEM768:
11088            return "X448MLKEM768";
11089        #endif /* HAVE_CURVE448 */
11090        #endif /* WOLFSSL_EXTRA_PQC_HYBRIDS */
11091    #endif /* WOLFSSL_NO_ML_KEM_768 */
11092    #ifndef WOLFSSL_NO_ML_KEM_1024
11093        case WOLFSSL_ML_KEM_1024:
11094            return "ML_KEM_1024";
11095        #ifdef WOLFSSL_PQC_HYBRIDS
11096        case WOLFSSL_SECP384R1MLKEM1024:
11097            return "SecP384r1MLKEM1024";
11098        #endif /* WOLFSSL_PQC_HYBRIDS */
11099        #ifdef WOLFSSL_EXTRA_PQC_HYBRIDS
11100        #ifdef WOLFSSL_ML_KEM_USE_OLD_IDS
11101        case WOLFSSL_P521_ML_KEM_1024_OLD:
11102            return "P521_ML_KEM_1024_OLD";
11103        #endif /* WOLFSSL_ML_KEM_USE_OLD_IDS */
11104        case WOLFSSL_SECP521R1MLKEM1024:
11105            return "SecP521r1MLKEM1024";
11106        #endif /* WOLFSSL_EXTRA_PQC_HYBRIDS */
11107    #endif /* WOLFSSL_NO_ML_KEM_1024 */
11108#endif /* WOLFSSL_NO_ML_KEM */
11109#ifdef WOLFSSL_MLKEM_KYBER
11110    #ifndef WOLFSSL_NO_KYBER512
11111        case WOLFSSL_KYBER_LEVEL1:
11112            return "KYBER_LEVEL1";
11113        case WOLFSSL_P256_KYBER_LEVEL1:
11114            return "P256_KYBER_LEVEL1";
11115        #ifdef HAVE_CURVE25519
11116        case WOLFSSL_X25519_KYBER_LEVEL1:
11117            return "X25519_KYBER_LEVEL1";
11118        #endif
11119    #endif
11120    #ifndef WOLFSSL_NO_KYBER768
11121        case WOLFSSL_KYBER_LEVEL3:
11122            return "KYBER_LEVEL3";
11123        case WOLFSSL_P384_KYBER_LEVEL3:
11124            return "P384_KYBER_LEVEL3";
11125        case WOLFSSL_P256_KYBER_LEVEL3:
11126            return "P256_KYBER_LEVEL3";
11127        #ifdef HAVE_CURVE25519
11128        case WOLFSSL_X25519_KYBER_LEVEL3:
11129            return "X25519_KYBER_LEVEL3";
11130        #endif
11131        #ifdef HAVE_CURVE448
11132        case WOLFSSL_X448_KYBER_LEVEL3:
11133            return "X448_KYBER_LEVEL3";
11134        #endif
11135    #endif
11136    #ifndef WOLFSSL_NO_KYBER1024
11137        case WOLFSSL_KYBER_LEVEL5:
11138            return "KYBER_LEVEL5";
11139        case WOLFSSL_P521_KYBER_LEVEL5:
11140            return "P521_KYBER_LEVEL5";
11141    #endif
11142#endif /* WOLFSSL_MLKEM_KYBER */
11143        }
11144    }
11145#endif /* WOLFSSL_TLS13 && WOLFSSL_HAVE_MLKEM */
11146
11147#ifdef HAVE_FFDHE
11148    if (ssl->namedGroup != 0) {
11149        cName = wolfssl_ffdhe_name(ssl->namedGroup);
11150    }
11151#endif
11152
11153#ifdef HAVE_CURVE25519
11154    if (ssl->ecdhCurveOID == ECC_X25519_OID && cName == NULL) {
11155        cName = "X25519";
11156    }
11157#endif
11158
11159#ifdef HAVE_CURVE448
11160    if (ssl->ecdhCurveOID == ECC_X448_OID && cName == NULL) {
11161        cName = "X448";
11162    }
11163#endif
11164
11165#ifdef HAVE_ECC
11166    if (ssl->ecdhCurveOID != 0 && cName == NULL) {
11167        cName = wc_ecc_get_name(wc_ecc_get_oid(ssl->ecdhCurveOID, NULL,
11168                                NULL));
11169    }
11170#endif
11171
11172    return cName;
11173}
11174#endif
11175
11176#ifdef OPENSSL_EXTRA
11177#if defined(OPENSSL_ALL) || defined(WOLFSSL_QT)
11178/* return authentication NID corresponding to cipher suite
11179 * @param cipher a pointer to WOLFSSL_CIPHER
11180 * return NID if found, WC_NID_undef if not found
11181 */
11182int wolfSSL_CIPHER_get_auth_nid(const WOLFSSL_CIPHER* cipher)
11183{
11184    static const struct authnid {
11185        const char* alg_name;
11186        const int  nid;
11187    } authnid_tbl[] = {
11188        {"RSA",     WC_NID_auth_rsa},
11189        {"PSK",     WC_NID_auth_psk},
11190        {"SRP",     WC_NID_auth_srp},
11191        {"ECDSA",   WC_NID_auth_ecdsa},
11192        {"None",    WC_NID_auth_null},
11193        {NULL,      WC_NID_undef}
11194    };
11195
11196    const char* authStr;
11197    char n[MAX_SEGMENTS][MAX_SEGMENT_SZ] = {{0}};
11198
11199    if (GetCipherSegment(cipher, n) == NULL) {
11200        WOLFSSL_MSG("no suitable cipher name found");
11201        return WC_NID_undef;
11202    }
11203
11204    authStr = GetCipherAuthStr(n);
11205
11206    if (authStr != NULL) {
11207        const struct authnid* sa;
11208        for(sa = authnid_tbl; sa->alg_name != NULL; sa++) {
11209            if (XSTRCMP(sa->alg_name, authStr) == 0) {
11210                return sa->nid;
11211            }
11212        }
11213    }
11214
11215    return WC_NID_undef;
11216}
11217/* return cipher NID corresponding to cipher suite
11218 * @param cipher a pointer to WOLFSSL_CIPHER
11219 * return NID if found, WC_NID_undef if not found
11220 */
11221int wolfSSL_CIPHER_get_cipher_nid(const WOLFSSL_CIPHER* cipher)
11222{
11223    static const struct ciphernid {
11224        const char* alg_name;
11225        const int  nid;
11226    } ciphernid_tbl[] = {
11227        {"AESGCM(256)",             WC_NID_aes_256_gcm},
11228        {"AESGCM(128)",             WC_NID_aes_128_gcm},
11229        {"AESCCM(128)",             WC_NID_aes_128_ccm},
11230        {"AES(128)",                WC_NID_aes_128_cbc},
11231        {"AES(256)",                WC_NID_aes_256_cbc},
11232        {"CAMELLIA(256)",           WC_NID_camellia_256_cbc},
11233        {"CAMELLIA(128)",           WC_NID_camellia_128_cbc},
11234        {"RC4",                     WC_NID_rc4},
11235        {"3DES",                    WC_NID_des_ede3_cbc},
11236        {"CHACHA20/POLY1305(256)",  WC_NID_chacha20_poly1305},
11237        {"None",                    WC_NID_undef},
11238        {NULL,                      WC_NID_undef}
11239    };
11240
11241    const char* encStr;
11242    char n[MAX_SEGMENTS][MAX_SEGMENT_SZ] = {{0}};
11243
11244    WOLFSSL_ENTER("wolfSSL_CIPHER_get_cipher_nid");
11245
11246    if (GetCipherSegment(cipher, n) == NULL) {
11247        WOLFSSL_MSG("no suitable cipher name found");
11248        return WC_NID_undef;
11249    }
11250
11251    encStr = GetCipherEncStr(n);
11252
11253    if (encStr != NULL) {
11254        const struct ciphernid* c;
11255        for(c = ciphernid_tbl; c->alg_name != NULL; c++) {
11256            if (XSTRCMP(c->alg_name, encStr) == 0) {
11257                return c->nid;
11258            }
11259        }
11260    }
11261
11262    return WC_NID_undef;
11263}
11264/* return digest NID corresponding to cipher suite
11265 * @param cipher a pointer to WOLFSSL_CIPHER
11266 * return NID if found, WC_NID_undef if not found
11267 */
11268int wolfSSL_CIPHER_get_digest_nid(const WOLFSSL_CIPHER* cipher)
11269{
11270    static const struct macnid {
11271        const char* alg_name;
11272        const int  nid;
11273    } macnid_tbl[] = {
11274        {"SHA1",    WC_NID_sha1},
11275        {"SHA256",  WC_NID_sha256},
11276        {"SHA384",  WC_NID_sha384},
11277        {NULL,      WC_NID_undef}
11278    };
11279
11280    const char* name;
11281    const char* macStr;
11282    char n[MAX_SEGMENTS][MAX_SEGMENT_SZ] = {{0}};
11283    (void)name;
11284
11285    WOLFSSL_ENTER("wolfSSL_CIPHER_get_digest_nid");
11286
11287    if ((name = GetCipherSegment(cipher, n)) == NULL) {
11288        WOLFSSL_MSG("no suitable cipher name found");
11289        return WC_NID_undef;
11290    }
11291
11292    /* in MD5 case, NID will be WC_NID_md5 */
11293    if (XSTRSTR(name, "MD5") != NULL) {
11294        return WC_NID_md5;
11295    }
11296
11297    macStr = GetCipherMacStr(n);
11298
11299    if (macStr != NULL) {
11300        const struct macnid* mc;
11301        for(mc = macnid_tbl; mc->alg_name != NULL; mc++) {
11302            if (XSTRCMP(mc->alg_name, macStr) == 0) {
11303                return mc->nid;
11304            }
11305        }
11306    }
11307
11308    return WC_NID_undef;
11309}
11310/* return key exchange NID corresponding to cipher suite
11311 * @param cipher a pointer to WOLFSSL_CIPHER
11312 * return NID if found, WC_NID_undef if not found
11313 */
11314int wolfSSL_CIPHER_get_kx_nid(const WOLFSSL_CIPHER* cipher)
11315{
11316    static const struct kxnid {
11317        const char* name;
11318        const int  nid;
11319    } kxnid_table[] = {
11320        {"ECDHEPSK",  WC_NID_kx_ecdhe_psk},
11321        {"ECDH",      WC_NID_kx_ecdhe},
11322        {"DHEPSK",    WC_NID_kx_dhe_psk},
11323        {"DH",        WC_NID_kx_dhe},
11324        {"RSAPSK",    WC_NID_kx_rsa_psk},
11325        {"SRP",       WC_NID_kx_srp},
11326        {"EDH",       WC_NID_kx_dhe},
11327        {"RSA",       WC_NID_kx_rsa},
11328        {NULL,        WC_NID_undef}
11329    };
11330
11331    const char* keaStr;
11332    char n[MAX_SEGMENTS][MAX_SEGMENT_SZ] = {{0}};
11333
11334    WOLFSSL_ENTER("wolfSSL_CIPHER_get_kx_nid");
11335
11336    if (GetCipherSegment(cipher, n) == NULL) {
11337        WOLFSSL_MSG("no suitable cipher name found");
11338        return WC_NID_undef;
11339    }
11340
11341    /* in TLS 1.3 case, NID will be WC_NID_kx_any */
11342    if (XSTRCMP(n[0], "TLS13") == 0) {
11343        return WC_NID_kx_any;
11344    }
11345
11346    keaStr = GetCipherKeaStr(n);
11347
11348    if (keaStr != NULL) {
11349        const struct kxnid* k;
11350        for(k = kxnid_table; k->name != NULL; k++) {
11351            if (XSTRCMP(k->name, keaStr) == 0) {
11352                return k->nid;
11353            }
11354        }
11355    }
11356
11357    return WC_NID_undef;
11358}
11359/* check if cipher suite is AEAD
11360 * @param cipher a pointer to WOLFSSL_CIPHER
11361 * return 1 if cipher is AEAD, 0 otherwise
11362 */
11363int wolfSSL_CIPHER_is_aead(const WOLFSSL_CIPHER* cipher)
11364{
11365    char n[MAX_SEGMENTS][MAX_SEGMENT_SZ] = {{0}};
11366
11367    WOLFSSL_ENTER("wolfSSL_CIPHER_is_aead");
11368
11369    if (GetCipherSegment(cipher, n) == NULL) {
11370        WOLFSSL_MSG("no suitable cipher name found");
11371        return WC_NID_undef;
11372    }
11373
11374    return IsCipherAEAD(n);
11375}
11376/* Creates cipher->description based on cipher->offset
11377 * cipher->offset is set in wolfSSL_get_ciphers_compat when it is added
11378 * to a stack of ciphers.
11379 * @param [in] cipher: A cipher from a stack of ciphers.
11380 * return WOLFSSL_SUCCESS if cipher->description is set, else WOLFSSL_FAILURE
11381 */
11382int wolfSSL_sk_CIPHER_description(WOLFSSL_CIPHER* cipher)
11383{
11384    int strLen;
11385    unsigned long offset;
11386    char* dp;
11387    const char* name;
11388    const char *keaStr, *authStr, *encStr, *macStr, *protocol;
11389    char n[MAX_SEGMENTS][MAX_SEGMENT_SZ] = {{0}};
11390    int len = MAX_DESCRIPTION_SZ-1;
11391    const CipherSuiteInfo* cipher_names;
11392    ProtocolVersion pv;
11393    WOLFSSL_ENTER("wolfSSL_sk_CIPHER_description");
11394
11395    if (cipher == NULL)
11396        return WOLFSSL_FAILURE;
11397
11398    dp = cipher->description;
11399    if (dp == NULL)
11400        return WOLFSSL_FAILURE;
11401
11402    cipher_names = GetCipherNames();
11403
11404    offset = cipher->offset;
11405    if (offset >= (unsigned long)GetCipherNamesSize())
11406        return WOLFSSL_FAILURE;
11407    pv.major = cipher_names[offset].major;
11408    pv.minor = cipher_names[offset].minor;
11409    protocol = wolfSSL_internal_get_version(&pv);
11410
11411    if ((name = GetCipherSegment(cipher, n)) == NULL) {
11412        WOLFSSL_MSG("no suitable cipher name found");
11413        return WOLFSSL_FAILURE;
11414    }
11415
11416    /* keaStr */
11417    keaStr = GetCipherKeaStr(n);
11418    /* authStr */
11419    authStr = GetCipherAuthStr(n);
11420    /* encStr */
11421    encStr = GetCipherEncStr(n);
11422    if ((cipher->bits = SetCipherBits(encStr)) ==
11423        WC_NO_ERR_TRACE(WOLFSSL_FAILURE))
11424    {
11425       WOLFSSL_MSG("Cipher Bits Not Set.");
11426    }
11427    /* macStr */
11428    macStr = GetCipherMacStr(n);
11429
11430
11431    /* Build up the string by copying onto the end. */
11432    XSTRNCPY(dp, name, (size_t)len);
11433    dp[len-1] = '\0'; strLen = (int)XSTRLEN(dp);
11434    len -= strLen; dp += strLen;
11435
11436    XSTRNCPY(dp, " ", (size_t)len);
11437    dp[len-1] = '\0'; strLen = (int)XSTRLEN(dp);
11438    len -= strLen; dp += strLen;
11439    XSTRNCPY(dp, protocol, (size_t)len);
11440    dp[len-1] = '\0'; strLen = (int)XSTRLEN(dp);
11441    len -= strLen; dp += strLen;
11442
11443    XSTRNCPY(dp, " Kx=", (size_t)len);
11444    dp[len-1] = '\0'; strLen = (int)XSTRLEN(dp);
11445    len -= strLen; dp += strLen;
11446    XSTRNCPY(dp, keaStr, (size_t)len);
11447    dp[len-1] = '\0'; strLen = (int)XSTRLEN(dp);
11448    len -= strLen; dp += strLen;
11449
11450    XSTRNCPY(dp, " Au=", (size_t)len);
11451    dp[len-1] = '\0'; strLen = (int)XSTRLEN(dp);
11452    len -= strLen; dp += strLen;
11453    XSTRNCPY(dp, authStr, (size_t)len);
11454    dp[len-1] = '\0'; strLen = (int)XSTRLEN(dp);
11455    len -= strLen; dp += strLen;
11456
11457    XSTRNCPY(dp, " Enc=", (size_t)len);
11458    dp[len-1] = '\0'; strLen = (int)XSTRLEN(dp);
11459    len -= strLen; dp += strLen;
11460    XSTRNCPY(dp, encStr, (size_t)len);
11461    dp[len-1] = '\0'; strLen = (int)XSTRLEN(dp);
11462    len -= strLen; dp += strLen;
11463
11464    XSTRNCPY(dp, " Mac=", (size_t)len);
11465    dp[len-1] = '\0'; strLen = (int)XSTRLEN(dp);
11466    len -= strLen; dp += (size_t)strLen;
11467    XSTRNCPY(dp, macStr, (size_t)len);
11468    dp[len-1] = '\0';
11469
11470    return WOLFSSL_SUCCESS;
11471}
11472#endif /* OPENSSL_ALL || WOLFSSL_QT */
11473
11474static WC_INLINE const char* wolfssl_kea_to_string(int kea)
11475{
11476    const char* keaStr;
11477
11478    switch (kea) {
11479        case no_kea:
11480            keaStr = "None";
11481            break;
11482#ifndef NO_RSA
11483        case rsa_kea:
11484            keaStr = "RSA";
11485            break;
11486#endif
11487#ifndef NO_DH
11488        case diffie_hellman_kea:
11489            keaStr = "DHE";
11490            break;
11491#endif
11492        case fortezza_kea:
11493            keaStr = "FZ";
11494            break;
11495#ifndef NO_PSK
11496        case psk_kea:
11497            keaStr = "PSK";
11498            break;
11499    #ifndef NO_DH
11500        case dhe_psk_kea:
11501            keaStr = "DHEPSK";
11502            break;
11503    #endif
11504    #ifdef HAVE_ECC
11505        case ecdhe_psk_kea:
11506            keaStr = "ECDHEPSK";
11507            break;
11508    #endif
11509#endif
11510#ifdef HAVE_ECC
11511        case ecc_diffie_hellman_kea:
11512            keaStr = "ECDHE";
11513            break;
11514        case ecc_static_diffie_hellman_kea:
11515            keaStr = "ECDH";
11516            break;
11517#endif
11518        case any_kea:
11519            keaStr = "any";
11520            break;
11521        default:
11522            keaStr = "unknown";
11523            break;
11524    }
11525
11526    return keaStr;
11527}
11528
11529static WC_INLINE const char* wolfssl_sigalg_to_string(int sig_algo)
11530{
11531    const char* authStr;
11532
11533    switch (sig_algo) {
11534        case anonymous_sa_algo:
11535            authStr = "None";
11536            break;
11537#ifndef NO_RSA
11538        case rsa_sa_algo:
11539            authStr = "RSA";
11540            break;
11541    #ifdef WC_RSA_PSS
11542        case rsa_pss_sa_algo:
11543            authStr = "RSA-PSS";
11544            break;
11545    #endif
11546#endif
11547#ifndef NO_DSA
11548        case dsa_sa_algo:
11549            authStr = "DSA";
11550            break;
11551#endif
11552#ifdef HAVE_ECC
11553        case ecc_dsa_sa_algo:
11554            authStr = "ECDSA";
11555            break;
11556#endif
11557#ifdef WOLFSSL_SM2
11558        case sm2_sa_algo:
11559            authStr = "SM2";
11560            break;
11561#endif
11562#ifdef HAVE_ED25519
11563        case ed25519_sa_algo:
11564            authStr = "Ed25519";
11565            break;
11566#endif
11567#ifdef HAVE_ED448
11568        case ed448_sa_algo:
11569            authStr = "Ed448";
11570            break;
11571#endif
11572        case any_sa_algo:
11573            authStr = "any";
11574            break;
11575        default:
11576            authStr = "unknown";
11577            break;
11578    }
11579
11580    return authStr;
11581}
11582
11583static WC_INLINE const char* wolfssl_cipher_to_string(int cipher, int key_size)
11584{
11585    const char* encStr;
11586
11587    (void)key_size;
11588
11589    switch (cipher) {
11590        case wolfssl_cipher_null:
11591            encStr = "None";
11592            break;
11593#ifndef NO_RC4
11594        case wolfssl_rc4:
11595            encStr = "RC4(128)";
11596            break;
11597#endif
11598#ifndef NO_DES3
11599        case wolfssl_triple_des:
11600            encStr = "3DES(168)";
11601            break;
11602#endif
11603#ifndef NO_AES
11604        case wolfssl_aes:
11605            if (key_size == AES_128_KEY_SIZE)
11606                encStr = "AES(128)";
11607            else if (key_size == AES_256_KEY_SIZE)
11608                encStr = "AES(256)";
11609            else
11610                encStr = "AES(?)";
11611            break;
11612    #ifdef HAVE_AESGCM
11613        case wolfssl_aes_gcm:
11614            if (key_size == AES_128_KEY_SIZE)
11615                encStr = "AESGCM(128)";
11616            else if (key_size == AES_256_KEY_SIZE)
11617                encStr = "AESGCM(256)";
11618            else
11619                encStr = "AESGCM(?)";
11620            break;
11621    #endif
11622    #ifdef HAVE_AESCCM
11623        case wolfssl_aes_ccm:
11624            if (key_size == AES_128_KEY_SIZE)
11625                encStr = "AESCCM(128)";
11626            else if (key_size == AES_256_KEY_SIZE)
11627                encStr = "AESCCM(256)";
11628            else
11629                encStr = "AESCCM(?)";
11630            break;
11631    #endif
11632#endif
11633#ifdef HAVE_CHACHA
11634        case wolfssl_chacha:
11635            encStr = "CHACHA20/POLY1305(256)";
11636            break;
11637#endif
11638#ifdef HAVE_ARIA
11639        case wolfssl_aria_gcm:
11640            if (key_size == ARIA_128_KEY_SIZE)
11641                encStr = "Aria(128)";
11642            else if (key_size == ARIA_192_KEY_SIZE)
11643                encStr = "Aria(192)";
11644            else if (key_size == ARIA_256_KEY_SIZE)
11645                encStr = "Aria(256)";
11646            else
11647                encStr = "Aria(?)";
11648            break;
11649#endif
11650#ifdef HAVE_CAMELLIA
11651        case wolfssl_camellia:
11652            if (key_size == CAMELLIA_128_KEY_SIZE)
11653                encStr = "Camellia(128)";
11654            else if (key_size == CAMELLIA_256_KEY_SIZE)
11655                encStr = "Camellia(256)";
11656            else
11657                encStr = "Camellia(?)";
11658            break;
11659#endif
11660        default:
11661            encStr = "unknown";
11662            break;
11663    }
11664
11665    return encStr;
11666}
11667
11668static WC_INLINE const char* wolfssl_mac_to_string(int mac)
11669{
11670    const char* macStr;
11671
11672    switch (mac) {
11673        case no_mac:
11674            macStr = "None";
11675            break;
11676#ifndef NO_MD5
11677        case md5_mac:
11678            macStr = "MD5";
11679            break;
11680#endif
11681#ifndef NO_SHA
11682        case sha_mac:
11683            macStr = "SHA1";
11684            break;
11685#endif
11686#ifdef WOLFSSL_SHA224
11687        case sha224_mac:
11688            macStr = "SHA224";
11689            break;
11690#endif
11691#ifndef NO_SHA256
11692        case sha256_mac:
11693            macStr = "SHA256";
11694            break;
11695#endif
11696#ifdef WOLFSSL_SHA384
11697        case sha384_mac:
11698            macStr = "SHA384";
11699            break;
11700#endif
11701#ifdef WOLFSSL_SHA512
11702        case sha512_mac:
11703            macStr = "SHA512";
11704            break;
11705#endif
11706        default:
11707            macStr = "unknown";
11708            break;
11709    }
11710
11711    return macStr;
11712}
11713
11714char* wolfSSL_CIPHER_description(const WOLFSSL_CIPHER* cipher, char* in,
11715                                 int len)
11716{
11717    char *ret = in;
11718    const char *keaStr, *authStr, *encStr, *macStr;
11719    size_t strLen;
11720    WOLFSSL_ENTER("wolfSSL_CIPHER_description");
11721
11722    if (cipher == NULL || in == NULL)
11723        return NULL;
11724
11725#if defined(WOLFSSL_QT) || defined(OPENSSL_ALL)
11726    /* if cipher is in the stack from wolfSSL_get_ciphers_compat then
11727     * Return the description based on cipher_names[cipher->offset]
11728     */
11729    if (cipher->in_stack == TRUE) {
11730        wolfSSL_sk_CIPHER_description((WOLFSSL_CIPHER*)cipher);
11731        XSTRNCPY(in,cipher->description,(size_t)len);
11732        return ret;
11733    }
11734#endif
11735
11736    /* Get the cipher description based on the SSL session cipher */
11737    keaStr = wolfssl_kea_to_string(cipher->ssl->specs.kea);
11738    authStr = wolfssl_sigalg_to_string(cipher->ssl->specs.sig_algo);
11739    encStr = wolfssl_cipher_to_string(cipher->ssl->specs.bulk_cipher_algorithm,
11740                                      cipher->ssl->specs.key_size);
11741    if (cipher->ssl->specs.cipher_type == aead)
11742        macStr = "AEAD";
11743    else
11744        macStr = wolfssl_mac_to_string(cipher->ssl->specs.mac_algorithm);
11745
11746    /* Build up the string by copying onto the end. */
11747    XSTRNCPY(in, wolfSSL_CIPHER_get_name(cipher), (size_t)len);
11748    in[len-1] = '\0'; strLen = XSTRLEN(in); len -= (int)strLen; in += strLen;
11749
11750    XSTRNCPY(in, " ", (size_t)len);
11751    in[len-1] = '\0'; strLen = XSTRLEN(in); len -= (int)strLen; in += strLen;
11752    XSTRNCPY(in, wolfSSL_get_version(cipher->ssl), (size_t)len);
11753    in[len-1] = '\0'; strLen = XSTRLEN(in); len -= (int)strLen; in += strLen;
11754
11755    XSTRNCPY(in, " Kx=", (size_t)len);
11756    in[len-1] = '\0'; strLen = XSTRLEN(in); len -= (int)strLen; in += strLen;
11757    XSTRNCPY(in, keaStr, (size_t)len);
11758    in[len-1] = '\0'; strLen = XSTRLEN(in); len -= (int)strLen; in += strLen;
11759
11760    XSTRNCPY(in, " Au=", (size_t)len);
11761    in[len-1] = '\0'; strLen = XSTRLEN(in); len -= (int)strLen; in += strLen;
11762    XSTRNCPY(in, authStr, (size_t)len);
11763    in[len-1] = '\0'; strLen = XSTRLEN(in); len -= (int)strLen; in += strLen;
11764
11765    XSTRNCPY(in, " Enc=", (size_t)len);
11766    in[len-1] = '\0'; strLen = XSTRLEN(in); len -= (int)strLen; in += strLen;
11767    XSTRNCPY(in, encStr, (size_t)len);
11768    in[len-1] = '\0'; strLen = XSTRLEN(in); len -= (int)strLen; in += strLen;
11769
11770    XSTRNCPY(in, " Mac=", (size_t)len);
11771    in[len-1] = '\0'; strLen = XSTRLEN(in); len -= (int)strLen; in += strLen;
11772    XSTRNCPY(in, macStr, (size_t)len);
11773    in[len-1] = '\0';
11774
11775    return ret;
11776}
11777
11778int wolfSSL_OCSP_parse_url(const char* url, char** host, char** port,
11779        char** path, int* ssl)
11780{
11781    const char* u;
11782    const char* upath; /* path in u */
11783    const char* uport; /* port in u */
11784    const char* hostEnd;
11785
11786    WOLFSSL_ENTER("OCSP_parse_url");
11787
11788    if (url == NULL || host == NULL || port == NULL || path == NULL ||
11789            ssl == NULL) {
11790        return WOLFSSL_FAILURE;
11791    }
11792
11793    u = url;
11794    *host = NULL;
11795    *port = NULL;
11796    *path = NULL;
11797    *ssl = 0;
11798
11799    if (*(u++) != 'h') goto err;
11800    if (*(u++) != 't') goto err;
11801    if (*(u++) != 't') goto err;
11802    if (*(u++) != 'p') goto err;
11803    if (*u == 's') {
11804        *ssl = 1;
11805        u++;
11806        *port = CopyString("443", -1, NULL, DYNAMIC_TYPE_OPENSSL);
11807    }
11808    else if (*u == ':') {
11809        *ssl = 0;
11810        *port = CopyString("80", -1, NULL, DYNAMIC_TYPE_OPENSSL);
11811    }
11812    else
11813        goto err;
11814    if (*port == NULL)
11815        goto err;
11816    if (*(u++) != ':') goto err;
11817    if (*(u++) != '/') goto err;
11818    if (*(u++) != '/') goto err;
11819
11820    /* Look for path */
11821    upath = XSTRSTR(u, "/");
11822    *path = CopyString(upath == NULL ? "/" : upath, -1, NULL,
11823                       DYNAMIC_TYPE_OPENSSL);
11824
11825    /* Look for port */
11826    uport = XSTRSTR(u, ":");
11827    if (uport != NULL) {
11828        if (*(++uport) == '\0')
11829            goto err;
11830        /* port must be before path */
11831        if (upath != NULL && uport >= upath)
11832            goto err;
11833        XFREE(*port, NULL, DYNAMIC_TYPE_OPENSSL);
11834        if (upath)
11835            *port = CopyString(uport, (int)(upath - uport), NULL,
11836                               DYNAMIC_TYPE_OPENSSL);
11837        else
11838            *port = CopyString(uport, -1, NULL, DYNAMIC_TYPE_OPENSSL);
11839        if (*port == NULL)
11840            goto err;
11841        hostEnd = uport - 1;
11842    }
11843    else
11844        hostEnd = upath;
11845
11846    if (hostEnd)
11847        *host = CopyString(u, (int)(hostEnd - u), NULL, DYNAMIC_TYPE_OPENSSL);
11848    else
11849        *host = CopyString(u, -1, NULL, DYNAMIC_TYPE_OPENSSL);
11850
11851    if (*host == NULL)
11852        goto err;
11853
11854    return WOLFSSL_SUCCESS;
11855err:
11856    XFREE(*host, NULL, DYNAMIC_TYPE_OPENSSL);
11857    *host = NULL;
11858    XFREE(*port, NULL, DYNAMIC_TYPE_OPENSSL);
11859    *port = NULL;
11860    XFREE(*path, NULL, DYNAMIC_TYPE_OPENSSL);
11861    *path = NULL;
11862    return WOLFSSL_FAILURE;
11863}
11864
11865#ifndef NO_WOLFSSL_STUB
11866WOLFSSL_COMP_METHOD* wolfSSL_COMP_zlib(void)
11867{
11868    WOLFSSL_STUB("COMP_zlib");
11869    return 0;
11870}
11871
11872WOLFSSL_COMP_METHOD* wolfSSL_COMP_rle(void)
11873{
11874    WOLFSSL_STUB("COMP_rle");
11875    return 0;
11876}
11877
11878int wolfSSL_COMP_add_compression_method(int method, void* data)
11879{
11880    (void)method;
11881    (void)data;
11882    WOLFSSL_STUB("COMP_add_compression_method");
11883    return 0;
11884}
11885
11886const WOLFSSL_COMP_METHOD* wolfSSL_get_current_compression(const WOLFSSL *ssl) {
11887    (void)ssl;
11888    return NULL;
11889}
11890
11891const WOLFSSL_COMP_METHOD* wolfSSL_get_current_expansion(const WOLFSSL *ssl) {
11892    (void)ssl;
11893    return NULL;
11894}
11895
11896const char* wolfSSL_COMP_get_name(const WOLFSSL_COMP_METHOD *comp)
11897{
11898    static const char ret[] = "not supported";
11899
11900    (void)comp;
11901    WOLFSSL_STUB("wolfSSL_COMP_get_name");
11902    return ret;
11903}
11904#endif
11905
11906/*  wolfSSL_set_dynlock_create_callback
11907 *  CRYPTO_set_dynlock_create_callback has been deprecated since openSSL 1.0.1.
11908 *  This function exists for compatibility purposes because wolfSSL satisfies
11909 *  thread safety without relying on the callback.
11910 */
11911void wolfSSL_set_dynlock_create_callback(WOLFSSL_dynlock_value* (*f)(
11912                                                          const char*, int))
11913{
11914    WOLFSSL_STUB("CRYPTO_set_dynlock_create_callback");
11915    (void)f;
11916}
11917/*  wolfSSL_set_dynlock_lock_callback
11918 *  CRYPTO_set_dynlock_lock_callback has been deprecated since openSSL 1.0.1.
11919 *  This function exists for compatibility purposes because wolfSSL satisfies
11920 *  thread safety without relying on the callback.
11921 */
11922void wolfSSL_set_dynlock_lock_callback(
11923             void (*f)(int, WOLFSSL_dynlock_value*, const char*, int))
11924{
11925    WOLFSSL_STUB("CRYPTO_set_set_dynlock_lock_callback");
11926    (void)f;
11927}
11928/*  wolfSSL_set_dynlock_destroy_callback
11929 *  CRYPTO_set_dynlock_destroy_callback has been deprecated since openSSL 1.0.1.
11930 *  This function exists for compatibility purposes because wolfSSL satisfies
11931 *  thread safety without relying on the callback.
11932 */
11933void wolfSSL_set_dynlock_destroy_callback(
11934                  void (*f)(WOLFSSL_dynlock_value*, const char*, int))
11935{
11936    WOLFSSL_STUB("CRYPTO_set_set_dynlock_destroy_callback");
11937    (void)f;
11938}
11939
11940/* Sets the DNS hostname to name.
11941 * Hostname is cleared if name is NULL or empty. */
11942int wolfSSL_set1_host(WOLFSSL * ssl, const char* name)
11943{
11944    if (ssl == NULL) {
11945        return WOLFSSL_FAILURE;
11946    }
11947
11948    return wolfSSL_X509_VERIFY_PARAM_set1_host(ssl->param, name, 0);
11949}
11950
11951/******************************************************************************
11952* wolfSSL_CTX_set1_param - set a pointer to the SSL verification parameters
11953*
11954* RETURNS:
11955*   WOLFSSL_SUCCESS on success, otherwise returns WOLFSSL_FAILURE
11956*   Note: Returns WOLFSSL_SUCCESS, in case either parameter is NULL,
11957*   same as openssl.
11958*/
11959int wolfSSL_CTX_set1_param(WOLFSSL_CTX* ctx, WOLFSSL_X509_VERIFY_PARAM *vpm)
11960{
11961    if (ctx == NULL || vpm == NULL)
11962        return WOLFSSL_SUCCESS;
11963
11964    return wolfSSL_X509_VERIFY_PARAM_set1(ctx->param, vpm);
11965}
11966
11967/******************************************************************************
11968* wolfSSL_CTX/_get0_param - return a pointer to the SSL verification parameters
11969*
11970* RETURNS:
11971* returns pointer to the SSL verification parameters on success,
11972* otherwise returns NULL
11973*/
11974WOLFSSL_X509_VERIFY_PARAM* wolfSSL_CTX_get0_param(WOLFSSL_CTX* ctx)
11975{
11976    if (ctx == NULL) {
11977        return NULL;
11978    }
11979
11980    return ctx->param;
11981}
11982
11983WOLFSSL_X509_VERIFY_PARAM* wolfSSL_get0_param(WOLFSSL* ssl)
11984{
11985    if (ssl == NULL) {
11986        return NULL;
11987    }
11988    return ssl->param;
11989}
11990
11991#endif /* OPENSSL_EXTRA */
11992
11993#if defined(OPENSSL_EXTRA) || defined(WOLFSSL_WPAS_SMALL)
11994/* Gets an index to store SSL structure at.
11995 *
11996 * Returns positive index on success and negative values on failure
11997 */
11998int wolfSSL_get_ex_data_X509_STORE_CTX_idx(void)
11999{
12000    WOLFSSL_ENTER("wolfSSL_get_ex_data_X509_STORE_CTX_idx");
12001
12002    /* store SSL at index 0 */
12003    return 0;
12004}
12005#endif /* OPENSSL_EXTRA || WOLFSSL_WPAS_SMALL */
12006
12007#ifdef OPENSSL_EXTRA
12008/* Sets a function callback that will send information about the state of all
12009 * WOLFSSL objects that have been created by the WOLFSSL_CTX structure passed
12010 * in.
12011 *
12012 * ctx WOLFSSL_CTX structure to set callback function in
12013 * f   callback function to use
12014 */
12015void wolfSSL_CTX_set_info_callback(WOLFSSL_CTX* ctx,
12016       void (*f)(const WOLFSSL* ssl, int type, int val))
12017{
12018    WOLFSSL_ENTER("wolfSSL_CTX_set_info_callback");
12019    if (ctx == NULL) {
12020        WOLFSSL_MSG("Bad function argument");
12021    }
12022    else {
12023        ctx->CBIS = f;
12024    }
12025}
12026
12027void wolfSSL_set_info_callback(WOLFSSL* ssl,
12028       void (*f)(const WOLFSSL* ssl, int type, int val))
12029{
12030    WOLFSSL_ENTER("wolfSSL_set_info_callback");
12031    if (ssl == NULL) {
12032        WOLFSSL_MSG("Bad function argument");
12033    }
12034    else {
12035        ssl->CBIS = f;
12036    }
12037}
12038
12039
12040unsigned long wolfSSL_ERR_peek_error(void)
12041{
12042    WOLFSSL_ENTER("wolfSSL_ERR_peek_error");
12043
12044    return wolfSSL_ERR_peek_error_line_data(NULL, NULL, NULL, NULL);
12045}
12046
12047#ifdef WOLFSSL_DEBUG_TRACE_ERROR_CODES_H
12048#include <wolfssl/debug-untrace-error-codes.h>
12049#endif
12050
12051int wolfSSL_ERR_GET_LIB(unsigned long err)
12052{
12053    unsigned long value;
12054
12055    value = (err & 0xFFFFFFL);
12056    switch (value) {
12057    case -PARSE_ERROR:
12058        return WOLFSSL_ERR_LIB_SSL;
12059    case -ASN_NO_PEM_HEADER:
12060    case -WOLFSSL_PEM_R_NO_START_LINE_E:
12061    case -WOLFSSL_PEM_R_PROBLEMS_GETTING_PASSWORD_E:
12062    case -WOLFSSL_PEM_R_BAD_PASSWORD_READ_E:
12063    case -WOLFSSL_PEM_R_BAD_DECRYPT_E:
12064        return WOLFSSL_ERR_LIB_PEM;
12065    case -WOLFSSL_EVP_R_BAD_DECRYPT_E:
12066    case -WOLFSSL_EVP_R_BN_DECODE_ERROR:
12067    case -WOLFSSL_EVP_R_DECODE_ERROR:
12068    case -WOLFSSL_EVP_R_PRIVATE_KEY_DECODE_ERROR:
12069        return WOLFSSL_ERR_LIB_EVP;
12070    case -WOLFSSL_ASN1_R_HEADER_TOO_LONG_E:
12071        return WOLFSSL_ERR_LIB_ASN1;
12072    default:
12073        return 0;
12074    }
12075}
12076
12077#ifdef WOLFSSL_DEBUG_TRACE_ERROR_CODES
12078#include <wolfssl/debug-trace-error-codes.h>
12079#endif
12080
12081/* This function is to find global error values that are the same through out
12082 * all library version. With wolfSSL having only one set of error codes the
12083 * return value is pretty straight forward. The only thing needed is all wolfSSL
12084 * error values are typically negative.
12085 *
12086 * Returns the error reason
12087 */
12088int wolfSSL_ERR_GET_REASON(unsigned long err)
12089{
12090    int ret = (int)err;
12091
12092    WOLFSSL_ENTER("wolfSSL_ERR_GET_REASON");
12093
12094#if defined(OPENSSL_ALL) || defined(WOLFSSL_NGINX) || defined(WOLFSSL_HAPROXY)
12095    /* Nginx looks for this error to know to stop parsing certificates.
12096     * Same for HAProxy. */
12097    if ((err == (unsigned long)((ERR_LIB_PEM << 24) | PEM_R_NO_START_LINE)) ||
12098        ((err & 0xFFFFFFL) == (unsigned long)(-WC_NO_ERR_TRACE(ASN_NO_PEM_HEADER))) ||
12099        ((err & 0xFFFL) == (unsigned long)PEM_R_NO_START_LINE))
12100        return PEM_R_NO_START_LINE;
12101    if (err == (unsigned long)((ERR_LIB_SSL << 24) | -SSL_R_HTTP_REQUEST))
12102        return SSL_R_HTTP_REQUEST;
12103#endif
12104#if defined(OPENSSL_ALL) && defined(WOLFSSL_PYTHON)
12105    if (err == (unsigned long)((ERR_LIB_ASN1 << 24) | ASN1_R_HEADER_TOO_LONG))
12106        return ASN1_R_HEADER_TOO_LONG;
12107#endif
12108
12109    /* check if error value is in range of wolfCrypt or wolfSSL errors */
12110    ret = 0 - ret; /* setting as negative value */
12111
12112    if ((ret <= WC_SPAN1_FIRST_E && ret >= WC_SPAN1_LAST_E) ||
12113        (ret <= WC_SPAN2_FIRST_E && ret >= WC_SPAN2_LAST_E) ||
12114        (ret <= WOLFSSL_FIRST_E && ret >= WOLFSSL_LAST_E))
12115    {
12116        return ret;
12117    }
12118    else {
12119        WOLFSSL_MSG("Not in range of typical error values");
12120        ret = (int)err;
12121    }
12122
12123    return ret;
12124}
12125
12126#ifndef NO_TLS
12127/* returns a string that describes the alert
12128 *
12129 * alertID the alert value to look up
12130 */
12131const char* wolfSSL_alert_type_string_long(int alertID)
12132{
12133    WOLFSSL_ENTER("wolfSSL_alert_type_string_long");
12134
12135    return AlertTypeToString(alertID);
12136}
12137
12138const char* wolfSSL_alert_desc_string_long(int alertID)
12139{
12140    WOLFSSL_ENTER("wolfSSL_alert_desc_string_long");
12141
12142    return AlertTypeToString(alertID);
12143}
12144#endif /* !NO_TLS */
12145
12146#define STATE_STRINGS_PROTO(s) \
12147    {                          \
12148        {"SSLv3 " s,           \
12149         "SSLv3 " s,           \
12150         "SSLv3 " s},          \
12151        {"TLSv1 " s,           \
12152         "TLSv1 " s,           \
12153         "TLSv1 " s},          \
12154        {"TLSv1_1 " s,         \
12155         "TLSv1_1 " s,         \
12156         "TLSv1_1 " s},        \
12157        {"TLSv1_2 " s,         \
12158         "TLSv1_2 " s,         \
12159         "TLSv1_2 " s},        \
12160        {"TLSv1_3 " s,         \
12161         "TLSv1_3 " s,         \
12162         "TLSv1_3 " s},        \
12163        {"DTLSv1 " s,          \
12164         "DTLSv1 " s,          \
12165         "DTLSv1 " s},         \
12166        {"DTLSv1_2 " s,        \
12167         "DTLSv1_2 " s,        \
12168         "DTLSv1_2 " s},       \
12169        {"DTLSv1_3 " s,        \
12170         "DTLSv1_3 " s,        \
12171         "DTLSv1_3 " s},       \
12172    }
12173
12174#define STATE_STRINGS_PROTO_RW(s) \
12175    {                             \
12176        {"SSLv3 read " s,         \
12177         "SSLv3 write " s,        \
12178         "SSLv3 " s},             \
12179        {"TLSv1 read " s,         \
12180         "TLSv1 write " s,        \
12181         "TLSv1 " s},             \
12182        {"TLSv1_1 read " s,       \
12183         "TLSv1_1 write " s,      \
12184         "TLSv1_1 " s},           \
12185        {"TLSv1_2 read " s,       \
12186         "TLSv1_2 write " s,      \
12187         "TLSv1_2 " s},           \
12188        {"TLSv1_3 read " s,       \
12189         "TLSv1_3 write " s,      \
12190         "TLSv1_3 " s},           \
12191        {"DTLSv1 read " s,        \
12192         "DTLSv1 write " s,       \
12193         "DTLSv1 " s},            \
12194        {"DTLSv1_2 read " s,      \
12195         "DTLSv1_2 write " s,     \
12196         "DTLSv1_2 " s},          \
12197        {"DTLSv1_3 read " s,      \
12198         "DTLSv1_3 write " s,     \
12199         "DTLSv1_3 " s},          \
12200    }
12201
12202/* Gets the current state of the WOLFSSL structure
12203 *
12204 * ssl WOLFSSL structure to get state of
12205 *
12206 * Returns a human readable string of the WOLFSSL structure state
12207 */
12208const char* wolfSSL_state_string_long(const WOLFSSL* ssl)
12209{
12210
12211    static const char* OUTPUT_STR[24][8][3] = {
12212        STATE_STRINGS_PROTO("Initialization"),
12213        STATE_STRINGS_PROTO_RW("Server Hello Request"),
12214        STATE_STRINGS_PROTO_RW("Server Hello Verify Request"),
12215        STATE_STRINGS_PROTO_RW("Server Hello Retry Request"),
12216        STATE_STRINGS_PROTO_RW("Server Hello"),
12217        STATE_STRINGS_PROTO_RW("Server Certificate Status"),
12218        STATE_STRINGS_PROTO_RW("Server Encrypted Extensions"),
12219        STATE_STRINGS_PROTO_RW("Server Session Ticket"),
12220        STATE_STRINGS_PROTO_RW("Server Certificate Request"),
12221        STATE_STRINGS_PROTO_RW("Server Cert"),
12222        STATE_STRINGS_PROTO_RW("Server Key Exchange"),
12223        STATE_STRINGS_PROTO_RW("Server Hello Done"),
12224        STATE_STRINGS_PROTO_RW("Server Change CipherSpec"),
12225        STATE_STRINGS_PROTO_RW("Server Finished"),
12226        STATE_STRINGS_PROTO_RW("server Key Update"),
12227        STATE_STRINGS_PROTO_RW("Client Hello"),
12228        STATE_STRINGS_PROTO_RW("Client Key Exchange"),
12229        STATE_STRINGS_PROTO_RW("Client Cert"),
12230        STATE_STRINGS_PROTO_RW("Client Change CipherSpec"),
12231        STATE_STRINGS_PROTO_RW("Client Certificate Verify"),
12232        STATE_STRINGS_PROTO_RW("Client End Of Early Data"),
12233        STATE_STRINGS_PROTO_RW("Client Finished"),
12234        STATE_STRINGS_PROTO_RW("Client Key Update"),
12235        STATE_STRINGS_PROTO("Handshake Done"),
12236    };
12237    enum ProtocolVer {
12238        SSL_V3 = 0,
12239        TLS_V1,
12240        TLS_V1_1,
12241        TLS_V1_2,
12242        TLS_V1_3,
12243        DTLS_V1,
12244        DTLS_V1_2,
12245        DTLS_V1_3,
12246        UNKNOWN = 100
12247    };
12248
12249    enum IOMode {
12250        SS_READ = 0,
12251        SS_WRITE,
12252        SS_NEITHER
12253    };
12254
12255    enum SslState {
12256        ss_null_state = 0,
12257        ss_server_hellorequest,
12258        ss_server_helloverify,
12259        ss_server_helloretryrequest,
12260        ss_server_hello,
12261        ss_server_certificatestatus,
12262        ss_server_encryptedextensions,
12263        ss_server_sessionticket,
12264        ss_server_certrequest,
12265        ss_server_cert,
12266        ss_server_keyexchange,
12267        ss_server_hellodone,
12268        ss_server_changecipherspec,
12269        ss_server_finished,
12270        ss_server_keyupdate,
12271        ss_client_hello,
12272        ss_client_keyexchange,
12273        ss_client_cert,
12274        ss_client_changecipherspec,
12275        ss_client_certverify,
12276        ss_client_endofearlydata,
12277        ss_client_finished,
12278        ss_client_keyupdate,
12279        ss_handshake_done
12280    };
12281
12282    int protocol = 0;
12283    int cbmode = 0;
12284    int state = 0;
12285
12286    WOLFSSL_ENTER("wolfSSL_state_string_long");
12287    if (ssl == NULL) {
12288        WOLFSSL_MSG("Null argument passed in");
12289        return NULL;
12290    }
12291
12292    /* Get state of callback */
12293    if (ssl->cbmode == WOLFSSL_CB_MODE_WRITE) {
12294        cbmode =  SS_WRITE;
12295    }
12296    else if (ssl->cbmode == WOLFSSL_CB_MODE_READ) {
12297        cbmode =  SS_READ;
12298    }
12299    else {
12300        cbmode =  SS_NEITHER;
12301    }
12302
12303    /* Get protocol version */
12304    switch (ssl->version.major) {
12305        case SSLv3_MAJOR:
12306            switch (ssl->version.minor) {
12307                case SSLv3_MINOR:
12308                    protocol = SSL_V3;
12309                    break;
12310                case TLSv1_MINOR:
12311                    protocol = TLS_V1;
12312                    break;
12313                case TLSv1_1_MINOR:
12314                    protocol = TLS_V1_1;
12315                    break;
12316                case TLSv1_2_MINOR:
12317                    protocol = TLS_V1_2;
12318                    break;
12319                case TLSv1_3_MINOR:
12320                    protocol = TLS_V1_3;
12321                    break;
12322                default:
12323                    protocol = UNKNOWN;
12324            }
12325            break;
12326        case DTLS_MAJOR:
12327            switch (ssl->version.minor) {
12328                case DTLS_MINOR:
12329                    protocol = DTLS_V1;
12330                    break;
12331                case DTLSv1_2_MINOR:
12332                    protocol = DTLS_V1_2;
12333                    break;
12334                case DTLSv1_3_MINOR:
12335                    protocol = DTLS_V1_3;
12336                    break;
12337                default:
12338                    protocol = UNKNOWN;
12339            }
12340            break;
12341    default:
12342        protocol = UNKNOWN;
12343    }
12344
12345    /* accept process */
12346    if (ssl->cbmode == WOLFSSL_CB_MODE_READ) {
12347        state = ssl->cbtype;
12348        switch (state) {
12349            case hello_request:
12350                state = ss_server_hellorequest;
12351                break;
12352            case client_hello:
12353                state = ss_client_hello;
12354                break;
12355            case server_hello:
12356                state = ss_server_hello;
12357                break;
12358            case hello_verify_request:
12359                state = ss_server_helloverify;
12360                break;
12361            case session_ticket:
12362                state = ss_server_sessionticket;
12363                break;
12364            case end_of_early_data:
12365                state = ss_client_endofearlydata;
12366                break;
12367            case hello_retry_request:
12368                state = ss_server_helloretryrequest;
12369                break;
12370            case encrypted_extensions:
12371                state = ss_server_encryptedextensions;
12372                break;
12373            case certificate:
12374                if (ssl->options.side == WOLFSSL_SERVER_END)
12375                    state = ss_client_cert;
12376                else if (ssl->options.side == WOLFSSL_CLIENT_END)
12377                    state = ss_server_cert;
12378                else {
12379                    WOLFSSL_MSG("Unknown State");
12380                    state = ss_null_state;
12381                }
12382                break;
12383            case server_key_exchange:
12384                state = ss_server_keyexchange;
12385                break;
12386            case certificate_request:
12387                state = ss_server_certrequest;
12388                break;
12389            case server_hello_done:
12390                state = ss_server_hellodone;
12391                break;
12392            case certificate_verify:
12393                state = ss_client_certverify;
12394                break;
12395            case client_key_exchange:
12396                state = ss_client_keyexchange;
12397                break;
12398            case finished:
12399                if (ssl->options.side == WOLFSSL_SERVER_END)
12400                    state = ss_client_finished;
12401                else if (ssl->options.side == WOLFSSL_CLIENT_END)
12402                    state = ss_server_finished;
12403                else {
12404                    WOLFSSL_MSG("Unknown State");
12405                    state = ss_null_state;
12406                }
12407                break;
12408            case certificate_status:
12409                state = ss_server_certificatestatus;
12410                break;
12411            case key_update:
12412                if (ssl->options.side == WOLFSSL_SERVER_END)
12413                    state = ss_client_keyupdate;
12414                else if (ssl->options.side == WOLFSSL_CLIENT_END)
12415                    state = ss_server_keyupdate;
12416                else {
12417                    WOLFSSL_MSG("Unknown State");
12418                    state = ss_null_state;
12419                }
12420                break;
12421            case change_cipher_hs:
12422                if (ssl->options.side == WOLFSSL_SERVER_END)
12423                    state = ss_client_changecipherspec;
12424                else if (ssl->options.side == WOLFSSL_CLIENT_END)
12425                    state = ss_server_changecipherspec;
12426                else {
12427                    WOLFSSL_MSG("Unknown State");
12428                    state = ss_null_state;
12429                }
12430                break;
12431            default:
12432                WOLFSSL_MSG("Unknown State");
12433                state = ss_null_state;
12434        }
12435    }
12436    else {
12437        /* Send process */
12438        if (ssl->options.side == WOLFSSL_SERVER_END)
12439            state = ssl->options.serverState;
12440        else
12441            state = ssl->options.clientState;
12442
12443        switch (state) {
12444            case SERVER_HELLOVERIFYREQUEST_COMPLETE:
12445                state = ss_server_helloverify;
12446                break;
12447            case SERVER_HELLO_RETRY_REQUEST_COMPLETE:
12448                state = ss_server_helloretryrequest;
12449                break;
12450            case SERVER_HELLO_COMPLETE:
12451                state = ss_server_hello;
12452                break;
12453            case SERVER_ENCRYPTED_EXTENSIONS_COMPLETE:
12454                state = ss_server_encryptedextensions;
12455                break;
12456            case SERVER_CERT_COMPLETE:
12457                state = ss_server_cert;
12458                break;
12459            case SERVER_KEYEXCHANGE_COMPLETE:
12460                state = ss_server_keyexchange;
12461                break;
12462            case SERVER_HELLODONE_COMPLETE:
12463                state = ss_server_hellodone;
12464                break;
12465            case SERVER_CHANGECIPHERSPEC_COMPLETE:
12466                state = ss_server_changecipherspec;
12467                break;
12468            case SERVER_FINISHED_COMPLETE:
12469                state = ss_server_finished;
12470                break;
12471            case CLIENT_HELLO_RETRY:
12472            case CLIENT_HELLO_COMPLETE:
12473                state = ss_client_hello;
12474                break;
12475            case CLIENT_KEYEXCHANGE_COMPLETE:
12476                state = ss_client_keyexchange;
12477                break;
12478            case CLIENT_CHANGECIPHERSPEC_COMPLETE:
12479                state = ss_client_changecipherspec;
12480                break;
12481            case CLIENT_FINISHED_COMPLETE:
12482                state = ss_client_finished;
12483                break;
12484            case HANDSHAKE_DONE:
12485                state = ss_handshake_done;
12486                break;
12487            default:
12488                WOLFSSL_MSG("Unknown State");
12489                state = ss_null_state;
12490        }
12491    }
12492
12493    if (protocol == UNKNOWN) {
12494        WOLFSSL_MSG("Unknown protocol");
12495        return "";
12496    }
12497    else {
12498        return OUTPUT_STR[state][protocol][cbmode];
12499    }
12500}
12501
12502#endif /* OPENSSL_EXTRA */
12503
12504static long wolf_set_options(long old_op, long op)
12505{
12506    /* if SSL_OP_ALL then turn all bug workarounds on */
12507    if ((op & WOLFSSL_OP_ALL) == WOLFSSL_OP_ALL) {
12508        WOLFSSL_MSG("\tSSL_OP_ALL");
12509    }
12510
12511    /* by default cookie exchange is on with DTLS */
12512    if ((op & WOLFSSL_OP_COOKIE_EXCHANGE) == WOLFSSL_OP_COOKIE_EXCHANGE) {
12513        WOLFSSL_MSG("\tSSL_OP_COOKIE_EXCHANGE : on by default");
12514    }
12515
12516    if ((op & WOLFSSL_OP_NO_SSLv2) == WOLFSSL_OP_NO_SSLv2) {
12517        WOLFSSL_MSG("\tWOLFSSL_OP_NO_SSLv2 : wolfSSL does not support SSLv2");
12518    }
12519
12520#ifdef SSL_OP_NO_TLSv1_3
12521    if ((op & WOLFSSL_OP_NO_TLSv1_3) == WOLFSSL_OP_NO_TLSv1_3) {
12522        WOLFSSL_MSG("\tSSL_OP_NO_TLSv1_3");
12523    }
12524#endif
12525
12526    if ((op & WOLFSSL_OP_NO_TLSv1_2) == WOLFSSL_OP_NO_TLSv1_2) {
12527        WOLFSSL_MSG("\tSSL_OP_NO_TLSv1_2");
12528    }
12529
12530    if ((op & WOLFSSL_OP_NO_TLSv1_1) == WOLFSSL_OP_NO_TLSv1_1) {
12531        WOLFSSL_MSG("\tSSL_OP_NO_TLSv1_1");
12532    }
12533
12534    if ((op & WOLFSSL_OP_NO_TLSv1) == WOLFSSL_OP_NO_TLSv1) {
12535        WOLFSSL_MSG("\tSSL_OP_NO_TLSv1");
12536    }
12537
12538    if ((op & WOLFSSL_OP_NO_SSLv3) == WOLFSSL_OP_NO_SSLv3) {
12539        WOLFSSL_MSG("\tSSL_OP_NO_SSLv3");
12540    }
12541
12542    if ((op & WOLFSSL_OP_CIPHER_SERVER_PREFERENCE) ==
12543            WOLFSSL_OP_CIPHER_SERVER_PREFERENCE) {
12544        WOLFSSL_MSG("\tWOLFSSL_OP_CIPHER_SERVER_PREFERENCE");
12545    }
12546
12547    if ((op & WOLFSSL_OP_NO_COMPRESSION) == WOLFSSL_OP_NO_COMPRESSION) {
12548    #ifdef HAVE_LIBZ
12549        WOLFSSL_MSG("SSL_OP_NO_COMPRESSION");
12550    #else
12551        WOLFSSL_MSG("SSL_OP_NO_COMPRESSION: compression not compiled in");
12552    #endif
12553    }
12554
12555    return old_op | op;
12556}
12557
12558static int FindHashSig(const Suites* suites, byte first, byte second)
12559{
12560    word16 i;
12561
12562    if (suites == NULL || suites->hashSigAlgoSz == 0) {
12563        WOLFSSL_MSG("Suites pointer error or suiteSz 0");
12564        return SUITES_ERROR;
12565    }
12566
12567    for (i = 0; i < suites->hashSigAlgoSz-1; i += 2) {
12568        if (suites->hashSigAlgo[i]   == first &&
12569            suites->hashSigAlgo[i+1] == second )
12570            return i;
12571    }
12572
12573    return MATCH_SUITE_ERROR;
12574}
12575
12576long wolfSSL_set_options(WOLFSSL* ssl, long op)
12577{
12578    word16 haveRSA = 1;
12579    word16 havePSK = 0;
12580    int    keySz   = 0;
12581
12582    WOLFSSL_ENTER("wolfSSL_set_options");
12583
12584    if (ssl == NULL) {
12585        return 0;
12586    }
12587
12588    ssl->options.mask = (unsigned long)wolf_set_options((long)ssl->options.mask, op);
12589
12590    if ((ssl->options.mask & WOLFSSL_OP_NO_TLSv1_3) == WOLFSSL_OP_NO_TLSv1_3) {
12591        WOLFSSL_MSG("Disabling TLS 1.3");
12592        if (ssl->version.minor == TLSv1_3_MINOR)
12593            ssl->version.minor = TLSv1_2_MINOR;
12594    }
12595
12596    if ((ssl->options.mask & WOLFSSL_OP_NO_TLSv1_2) == WOLFSSL_OP_NO_TLSv1_2) {
12597        WOLFSSL_MSG("Disabling TLS 1.2");
12598        if (ssl->version.minor == TLSv1_2_MINOR)
12599            ssl->version.minor = TLSv1_1_MINOR;
12600    }
12601
12602    if ((ssl->options.mask & WOLFSSL_OP_NO_TLSv1_1) == WOLFSSL_OP_NO_TLSv1_1) {
12603        WOLFSSL_MSG("Disabling TLS 1.1");
12604        if (ssl->version.minor == TLSv1_1_MINOR)
12605            ssl->version.minor = TLSv1_MINOR;
12606    }
12607
12608    if ((ssl->options.mask & WOLFSSL_OP_NO_TLSv1) == WOLFSSL_OP_NO_TLSv1) {
12609        WOLFSSL_MSG("Disabling TLS 1.0");
12610        if (ssl->version.minor == TLSv1_MINOR)
12611            ssl->version.minor = SSLv3_MINOR;
12612    }
12613
12614    if ((ssl->options.mask & WOLFSSL_OP_NO_COMPRESSION)
12615        == WOLFSSL_OP_NO_COMPRESSION) {
12616    #ifdef HAVE_LIBZ
12617        ssl->options.usingCompression = 0;
12618    #endif
12619    }
12620
12621#if defined(HAVE_SESSION_TICKET) && (defined(OPENSSL_EXTRA) \
12622        || defined(HAVE_WEBSERVER) || defined(WOLFSSL_WPAS_SMALL))
12623    if ((ssl->options.mask & WOLFSSL_OP_NO_TICKET) == WOLFSSL_OP_NO_TICKET) {
12624      ssl->options.noTicketTls12 = 1;
12625    }
12626#endif
12627
12628
12629    /* in the case of a version change the cipher suites should be reset */
12630#ifndef NO_PSK
12631    havePSK = ssl->options.havePSK;
12632#endif
12633#ifdef NO_RSA
12634    haveRSA = 0;
12635#endif
12636#ifndef NO_CERTS
12637    keySz = ssl->buffers.keySz;
12638#endif
12639
12640    if (ssl->options.side != WOLFSSL_NEITHER_END) {
12641        if (AllocateSuites(ssl) != 0)
12642            return 0;
12643        if (!ssl->suites->setSuites) {
12644            /* Client side won't set DH params, so it needs haveDH set to TRUE. */
12645            if (ssl->options.side == WOLFSSL_CLIENT_END)
12646                InitSuites(ssl->suites, ssl->version, keySz, haveRSA,
12647                       havePSK, TRUE, ssl->options.haveECDSAsig,
12648                       ssl->options.haveECC, TRUE, ssl->options.haveStaticECC,
12649                       ssl->options.useAnon,
12650                       TRUE, TRUE, TRUE, TRUE, ssl->options.side);
12651            else
12652                InitSuites(ssl->suites, ssl->version, keySz, haveRSA,
12653                       havePSK, ssl->options.haveDH, ssl->options.haveECDSAsig,
12654                       ssl->options.haveECC, TRUE, ssl->options.haveStaticECC,
12655                       ssl->options.useAnon,
12656                       TRUE, TRUE, TRUE, TRUE, ssl->options.side);
12657        }
12658        else {
12659            /* Only preserve overlapping suites */
12660            Suites tmpSuites;
12661            word16 in, out;
12662            word16 haveECDSAsig, haveStaticECC;
12663#ifdef NO_RSA
12664            haveECDSAsig = 1;
12665            haveStaticECC = 1;
12666#else
12667            haveECDSAsig = 0;
12668            haveStaticECC = ssl->options.haveStaticECC;
12669#endif
12670            XMEMSET(&tmpSuites, 0, sizeof(Suites));
12671            /* Get all possible ciphers and sigalgs for the version. Following
12672             * options limit the allowed ciphers so let's try to get as many as
12673             * possible.
12674             * - haveStaticECC turns off haveRSA
12675             * - haveECDSAsig turns off haveRSAsig */
12676            InitSuites(&tmpSuites, ssl->version, 0, 1, 1, 1, haveECDSAsig, 1, 1,
12677                    haveStaticECC, 1, 1, 1, 1, 1, ssl->options.side);
12678            for (in = 0, out = 0; in < ssl->suites->suiteSz; in += SUITE_LEN) {
12679                if (FindSuite(&tmpSuites, ssl->suites->suites[in],
12680                        ssl->suites->suites[in+1]) >= 0) {
12681                    ssl->suites->suites[out] = ssl->suites->suites[in];
12682                    ssl->suites->suites[out+1] = ssl->suites->suites[in+1];
12683                    out += SUITE_LEN;
12684                }
12685            }
12686            ssl->suites->suiteSz = out;
12687            for (in = 0, out = 0; in < ssl->suites->hashSigAlgoSz; in += 2) {
12688                if (FindHashSig(&tmpSuites, ssl->suites->hashSigAlgo[in],
12689                    ssl->suites->hashSigAlgo[in+1]) >= 0) {
12690                    ssl->suites->hashSigAlgo[out] =
12691                            ssl->suites->hashSigAlgo[in];
12692                    ssl->suites->hashSigAlgo[out+1] =
12693                            ssl->suites->hashSigAlgo[in+1];
12694                    out += 2;
12695                }
12696            }
12697            ssl->suites->hashSigAlgoSz = out;
12698        }
12699    }
12700
12701    return (long)ssl->options.mask;
12702}
12703
12704
12705long wolfSSL_get_options(const WOLFSSL* ssl)
12706{
12707    WOLFSSL_ENTER("wolfSSL_get_options");
12708    if(ssl == NULL)
12709        return WOLFSSL_FAILURE;
12710    return (long)ssl->options.mask;
12711}
12712
12713#if defined(HAVE_SECURE_RENEGOTIATION) \
12714        || defined(HAVE_SERVER_RENEGOTIATION_INFO)
12715/* clears the counter for number of renegotiations done
12716 * returns the current count before it is cleared */
12717long wolfSSL_clear_num_renegotiations(WOLFSSL *s)
12718{
12719    long total;
12720
12721    WOLFSSL_ENTER("wolfSSL_clear_num_renegotiations");
12722    if (s == NULL)
12723        return 0;
12724
12725    total = s->secure_rene_count;
12726    s->secure_rene_count = 0;
12727    return total;
12728}
12729
12730
12731/* return the number of renegotiations since wolfSSL_new */
12732long wolfSSL_total_renegotiations(WOLFSSL *s)
12733{
12734    WOLFSSL_ENTER("wolfSSL_total_renegotiations");
12735    return wolfSSL_num_renegotiations(s);
12736}
12737
12738
12739/* return the number of renegotiations since wolfSSL_new */
12740long wolfSSL_num_renegotiations(WOLFSSL* s)
12741{
12742    if (s == NULL) {
12743        return 0;
12744    }
12745
12746    return s->secure_rene_count;
12747}
12748
12749
12750/* Is there a renegotiation currently in progress? */
12751int  wolfSSL_SSL_renegotiate_pending(WOLFSSL *s)
12752{
12753    return s && s->options.handShakeDone &&
12754            s->options.handShakeState != HANDSHAKE_DONE ? 1 : 0;
12755}
12756#endif /* HAVE_SECURE_RENEGOTIATION || HAVE_SERVER_RENEGOTIATION_INFO */
12757
12758#ifdef OPENSSL_EXTRA
12759
12760long wolfSSL_clear_options(WOLFSSL* ssl, long opt)
12761{
12762    WOLFSSL_ENTER("wolfSSL_clear_options");
12763    if(ssl == NULL)
12764        return WOLFSSL_FAILURE;
12765    ssl->options.mask &= (unsigned long)~opt;
12766    return (long)ssl->options.mask;
12767}
12768
12769#ifdef HAVE_PK_CALLBACKS
12770long wolfSSL_set_tlsext_debug_arg(WOLFSSL* ssl, void *arg)
12771{
12772    if (ssl == NULL) {
12773        return WOLFSSL_FAILURE;
12774    }
12775
12776    ssl->loggingCtx = arg;
12777    return WOLFSSL_SUCCESS;
12778}
12779#endif /* HAVE_PK_CALLBACKS */
12780
12781#ifndef NO_WOLFSSL_STUB
12782long wolfSSL_get_tlsext_status_exts(WOLFSSL *s, void *arg)
12783{
12784    (void)s;
12785    (void)arg;
12786    WOLFSSL_STUB("wolfSSL_get_tlsext_status_exts");
12787    return WOLFSSL_FAILURE;
12788}
12789#endif
12790
12791/*** TBD ***/
12792#ifndef NO_WOLFSSL_STUB
12793long wolfSSL_set_tlsext_status_exts(WOLFSSL *s, void *arg)
12794{
12795    (void)s;
12796    (void)arg;
12797    WOLFSSL_STUB("wolfSSL_set_tlsext_status_exts");
12798    return WOLFSSL_FAILURE;
12799}
12800#endif
12801
12802/*** TBD ***/
12803#ifndef NO_WOLFSSL_STUB
12804long wolfSSL_get_tlsext_status_ids(WOLFSSL *s, void *arg)
12805{
12806    (void)s;
12807    (void)arg;
12808    WOLFSSL_STUB("wolfSSL_get_tlsext_status_ids");
12809    return WOLFSSL_FAILURE;
12810}
12811#endif
12812
12813/*** TBD ***/
12814#ifndef NO_WOLFSSL_STUB
12815long wolfSSL_set_tlsext_status_ids(WOLFSSL *s, void *arg)
12816{
12817    (void)s;
12818    (void)arg;
12819    WOLFSSL_STUB("wolfSSL_set_tlsext_status_ids");
12820    return WOLFSSL_FAILURE;
12821}
12822#endif
12823
12824#ifndef NO_WOLFSSL_STUB
12825/*** TBD ***/
12826WOLFSSL_EVP_PKEY *wolfSSL_get_privatekey(const WOLFSSL *ssl)
12827{
12828    (void)ssl;
12829    WOLFSSL_STUB("SSL_get_privatekey");
12830    return NULL;
12831}
12832#endif
12833
12834#ifndef NO_WOLFSSL_STUB
12835/*** TBD ***/
12836void WOLFSSL_CTX_set_tmp_dh_callback(WOLFSSL_CTX *ctx,
12837    WOLFSSL_DH *(*dh) (WOLFSSL *ssl, int is_export, int keylength))
12838{
12839    (void)ctx;
12840    (void)dh;
12841    WOLFSSL_STUB("WOLFSSL_CTX_set_tmp_dh_callback");
12842}
12843#endif
12844
12845#ifndef NO_WOLFSSL_STUB
12846/*** TBD ***/
12847WOLF_STACK_OF(WOLFSSL_COMP) *WOLFSSL_COMP_get_compression_methods(void)
12848{
12849    WOLFSSL_STUB("WOLFSSL_COMP_get_compression_methods");
12850    return NULL;
12851}
12852#endif
12853
12854
12855#if !defined(NETOS)
12856void wolfSSL_ERR_load_SSL_strings(void)
12857{
12858
12859}
12860#endif
12861
12862#ifdef HAVE_MAX_FRAGMENT
12863#if !defined(NO_WOLFSSL_CLIENT) && !defined(NO_TLS)
12864/**
12865 * Set max fragment tls extension
12866 * @param c a pointer to WOLFSSL_CTX object
12867 * @param mode maximum fragment length mode
12868 * @return 1 on success, otherwise 0 or negative error code
12869 */
12870int wolfSSL_CTX_set_tlsext_max_fragment_length(WOLFSSL_CTX *c,
12871                                               unsigned char mode)
12872{
12873    if (c == NULL || (mode < WOLFSSL_MFL_2_9 || mode > WOLFSSL_MFL_2_12 ))
12874        return BAD_FUNC_ARG;
12875
12876    return wolfSSL_CTX_UseMaxFragment(c, mode);
12877}
12878/**
12879 * Set max fragment tls extension
12880 * @param c a pointer to WOLFSSL object
12881 * @param mode maximum fragment length mode
12882 * @return 1 on success, otherwise 0 or negative error code
12883 */
12884int wolfSSL_set_tlsext_max_fragment_length(WOLFSSL *s, unsigned char mode)
12885{
12886    if (s == NULL || (mode < WOLFSSL_MFL_2_9 || mode > WOLFSSL_MFL_2_12 ))
12887        return BAD_FUNC_ARG;
12888
12889    return wolfSSL_UseMaxFragment(s, mode);
12890}
12891#endif /* !NO_WOLFSSL_CLIENT && !NO_TLS */
12892#endif /* HAVE_MAX_FRAGMENT */
12893
12894#endif /* OPENSSL_EXTRA */
12895
12896#ifdef WOLFSSL_HAVE_TLS_UNIQUE
12897size_t wolfSSL_get_finished(const WOLFSSL *ssl, void *buf, size_t count)
12898{
12899    byte len = 0;
12900
12901    WOLFSSL_ENTER("wolfSSL_get_finished");
12902
12903    if (!ssl || !buf || count < TLS_FINISHED_SZ) {
12904        WOLFSSL_MSG("Bad parameter");
12905        return WOLFSSL_FAILURE;
12906    }
12907
12908    if (ssl->options.side == WOLFSSL_SERVER_END) {
12909        len = ssl->serverFinished_len;
12910        XMEMCPY(buf, ssl->serverFinished, len);
12911    }
12912    else {
12913        len = ssl->clientFinished_len;
12914        XMEMCPY(buf, ssl->clientFinished, len);
12915    }
12916    return len;
12917}
12918
12919size_t wolfSSL_get_peer_finished(const WOLFSSL *ssl, void *buf, size_t count)
12920{
12921    byte len = 0;
12922    WOLFSSL_ENTER("wolfSSL_get_peer_finished");
12923
12924    if (!ssl || !buf || count < TLS_FINISHED_SZ) {
12925        WOLFSSL_MSG("Bad parameter");
12926        return WOLFSSL_FAILURE;
12927    }
12928
12929    if (ssl->options.side == WOLFSSL_CLIENT_END) {
12930        len = ssl->serverFinished_len;
12931        XMEMCPY(buf, ssl->serverFinished, len);
12932    }
12933    else {
12934        len = ssl->clientFinished_len;
12935        XMEMCPY(buf, ssl->clientFinished, len);
12936    }
12937
12938    return len;
12939}
12940#endif /* WOLFSSL_HAVE_TLS_UNIQUE */
12941
12942#if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL) || \
12943    defined(OPENSSL_ALL)
12944long wolfSSL_get_verify_result(const WOLFSSL *ssl)
12945{
12946    if (ssl == NULL) {
12947        return WOLFSSL_FAILURE;
12948    }
12949
12950    return (long)ssl->peerVerifyRet;
12951}
12952#endif
12953
12954#ifdef OPENSSL_EXTRA
12955
12956#ifndef NO_WOLFSSL_STUB
12957/* shows the number of accepts attempted by CTX in it's lifetime */
12958long wolfSSL_CTX_sess_accept(WOLFSSL_CTX* ctx)
12959{
12960    WOLFSSL_STUB("wolfSSL_CTX_sess_accept");
12961    (void)ctx;
12962    return 0;
12963}
12964#endif
12965
12966#ifndef NO_WOLFSSL_STUB
12967/* shows the number of connects attempted CTX in it's lifetime */
12968long wolfSSL_CTX_sess_connect(WOLFSSL_CTX* ctx)
12969{
12970    WOLFSSL_STUB("wolfSSL_CTX_sess_connect");
12971    (void)ctx;
12972    return 0;
12973}
12974#endif
12975
12976
12977#ifndef NO_WOLFSSL_STUB
12978/* shows the number of accepts completed by CTX in it's lifetime */
12979long wolfSSL_CTX_sess_accept_good(WOLFSSL_CTX* ctx)
12980{
12981    WOLFSSL_STUB("wolfSSL_CTX_sess_accept_good");
12982    (void)ctx;
12983    return 0;
12984}
12985#endif
12986
12987
12988#ifndef NO_WOLFSSL_STUB
12989/* shows the number of connects completed by CTX in it's lifetime */
12990long wolfSSL_CTX_sess_connect_good(WOLFSSL_CTX* ctx)
12991{
12992    WOLFSSL_STUB("wolfSSL_CTX_sess_connect_good");
12993    (void)ctx;
12994    return 0;
12995}
12996#endif
12997
12998
12999#ifndef NO_WOLFSSL_STUB
13000/* shows the number of renegotiation accepts attempted by CTX */
13001long wolfSSL_CTX_sess_accept_renegotiate(WOLFSSL_CTX* ctx)
13002{
13003    WOLFSSL_STUB("wolfSSL_CTX_sess_accept_renegotiate");
13004    (void)ctx;
13005    return 0;
13006}
13007#endif
13008
13009
13010#ifndef NO_WOLFSSL_STUB
13011/* shows the number of renegotiation accepts attempted by CTX */
13012long wolfSSL_CTX_sess_connect_renegotiate(WOLFSSL_CTX* ctx)
13013{
13014    WOLFSSL_STUB("wolfSSL_CTX_sess_connect_renegotiate");
13015    (void)ctx;
13016    return 0;
13017}
13018#endif
13019
13020
13021#ifndef NO_WOLFSSL_STUB
13022long wolfSSL_CTX_sess_hits(WOLFSSL_CTX* ctx)
13023{
13024    WOLFSSL_STUB("wolfSSL_CTX_sess_hits");
13025    (void)ctx;
13026    return 0;
13027}
13028#endif
13029
13030
13031#ifndef NO_WOLFSSL_STUB
13032long wolfSSL_CTX_sess_cb_hits(WOLFSSL_CTX* ctx)
13033{
13034    WOLFSSL_STUB("wolfSSL_CTX_sess_cb_hits");
13035    (void)ctx;
13036    return 0;
13037}
13038#endif
13039
13040
13041#ifndef NO_WOLFSSL_STUB
13042long wolfSSL_CTX_sess_cache_full(WOLFSSL_CTX* ctx)
13043{
13044    WOLFSSL_STUB("wolfSSL_CTX_sess_cache_full");
13045    (void)ctx;
13046    return 0;
13047}
13048#endif
13049
13050
13051#ifndef NO_WOLFSSL_STUB
13052long wolfSSL_CTX_sess_misses(WOLFSSL_CTX* ctx)
13053{
13054    WOLFSSL_STUB("wolfSSL_CTX_sess_misses");
13055    (void)ctx;
13056    return 0;
13057}
13058#endif
13059
13060
13061#ifndef NO_WOLFSSL_STUB
13062long wolfSSL_CTX_sess_timeouts(WOLFSSL_CTX* ctx)
13063{
13064    WOLFSSL_STUB("wolfSSL_CTX_sess_timeouts");
13065    (void)ctx;
13066    return 0;
13067}
13068#endif
13069
13070int wolfSSL_get_read_ahead(const WOLFSSL* ssl)
13071{
13072    if (ssl == NULL) {
13073        return WOLFSSL_FAILURE;
13074    }
13075
13076    return ssl->readAhead;
13077}
13078
13079
13080int wolfSSL_set_read_ahead(WOLFSSL* ssl, int v)
13081{
13082    if (ssl == NULL) {
13083        return WOLFSSL_FAILURE;
13084    }
13085
13086    ssl->readAhead = (byte)v;
13087
13088    return WOLFSSL_SUCCESS;
13089}
13090
13091
13092int wolfSSL_CTX_get_read_ahead(WOLFSSL_CTX* ctx)
13093{
13094    if (ctx == NULL) {
13095        return WOLFSSL_FAILURE;
13096    }
13097
13098    return ctx->readAhead;
13099}
13100
13101
13102int wolfSSL_CTX_set_read_ahead(WOLFSSL_CTX* ctx, int v)
13103{
13104    if (ctx == NULL) {
13105        return WOLFSSL_FAILURE;
13106    }
13107
13108    ctx->readAhead = (byte)v;
13109
13110    return WOLFSSL_SUCCESS;
13111}
13112
13113
13114long wolfSSL_CTX_set_tlsext_opaque_prf_input_callback_arg(WOLFSSL_CTX* ctx,
13115        void* arg)
13116{
13117    if (ctx == NULL) {
13118        return WOLFSSL_FAILURE;
13119    }
13120
13121    ctx->userPRFArg = arg;
13122    return WOLFSSL_SUCCESS;
13123}
13124
13125#endif /* OPENSSL_EXTRA */
13126
13127#if defined(OPENSSL_EXTRA) && defined(KEEP_PEER_CERT) && \
13128    defined(HAVE_EX_DATA) && !defined(NO_FILESYSTEM)
13129int wolfSSL_cmp_peer_cert_to_file(WOLFSSL* ssl, const char *fname)
13130{
13131    int ret = WC_NO_ERR_TRACE(WOLFSSL_FATAL_ERROR);
13132
13133    WOLFSSL_ENTER("wolfSSL_cmp_peer_cert_to_file");
13134    if (ssl != NULL && fname != NULL)
13135    {
13136    #ifdef WOLFSSL_SMALL_STACK
13137        byte           staticBuffer[1]; /* force heap usage */
13138    #else
13139        byte           staticBuffer[FILE_BUFFER_SIZE];
13140    #endif
13141        byte*          myBuffer  = staticBuffer;
13142        int            dynamic   = 0;
13143        XFILE          file;
13144        long           sz        = 0;
13145        WOLFSSL_CTX*   ctx       = ssl->ctx;
13146        WOLFSSL_X509*  peer_cert = &ssl->peerCert;
13147        DerBuffer*     fileDer = NULL;
13148
13149        file = XFOPEN(fname, "rb");
13150        if (file == XBADFILE)
13151            return WOLFSSL_BAD_FILE;
13152
13153        if (XFSEEK(file, 0, XSEEK_END) != 0) {
13154            XFCLOSE(file);
13155            return WOLFSSL_BAD_FILE;
13156        }
13157        sz = XFTELL(file);
13158        if (XFSEEK(file, 0, XSEEK_SET) != 0) {
13159            XFCLOSE(file);
13160            return WOLFSSL_BAD_FILE;
13161        }
13162
13163        if (sz > MAX_WOLFSSL_FILE_SIZE || sz < 0) {
13164            WOLFSSL_MSG("cmp_peer_cert_to_file size error");
13165            XFCLOSE(file);
13166            return WOLFSSL_BAD_FILE;
13167        }
13168
13169        if (sz > (long)sizeof(staticBuffer)) {
13170            WOLFSSL_MSG("Getting dynamic buffer");
13171            myBuffer = (byte*)XMALLOC((size_t)sz, ctx->heap, DYNAMIC_TYPE_FILE);
13172            dynamic = 1;
13173        }
13174
13175        if ((myBuffer != NULL) &&
13176            (sz > 0) &&
13177            (XFREAD(myBuffer, 1, (size_t)sz, file) == (size_t)sz) &&
13178            (PemToDer(myBuffer, (long)sz, CERT_TYPE,
13179                      &fileDer, ctx->heap, NULL, NULL) == 0) &&
13180            (fileDer->length != 0) &&
13181            (fileDer->length == peer_cert->derCert->length) &&
13182            (XMEMCMP(peer_cert->derCert->buffer, fileDer->buffer,
13183                                                fileDer->length) == 0))
13184        {
13185            ret = 0;
13186        }
13187
13188        FreeDer(&fileDer);
13189
13190        if (dynamic)
13191            XFREE(myBuffer, ctx->heap, DYNAMIC_TYPE_FILE);
13192
13193        XFCLOSE(file);
13194    }
13195
13196    return ret;
13197}
13198#endif
13199
13200#if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)
13201const WOLFSSL_ObjectInfo wolfssl_object_info[] = {
13202#ifndef NO_CERTS
13203    /* oidCertExtType */
13204    { WC_NID_basic_constraints, BASIC_CA_OID, oidCertExtType,
13205      "basicConstraints", "X509v3 Basic Constraints"},
13206    { WC_NID_subject_alt_name, ALT_NAMES_OID, oidCertExtType, "subjectAltName",
13207      "X509v3 Subject Alternative Name"},
13208    { WC_NID_crl_distribution_points, CRL_DIST_OID, oidCertExtType,
13209      "crlDistributionPoints", "X509v3 CRL Distribution Points"},
13210    { WC_NID_info_access, AUTH_INFO_OID, oidCertExtType, "authorityInfoAccess",
13211      "Authority Information Access"},
13212    { WC_NID_authority_key_identifier, AUTH_KEY_OID, oidCertExtType,
13213      "authorityKeyIdentifier", "X509v3 Authority Key Identifier"},
13214    { WC_NID_subject_key_identifier, SUBJ_KEY_OID, oidCertExtType,
13215      "subjectKeyIdentifier", "X509v3 Subject Key Identifier"},
13216    { WC_NID_key_usage, KEY_USAGE_OID, oidCertExtType, "keyUsage",
13217      "X509v3 Key Usage"},
13218    { WC_NID_inhibit_any_policy, INHIBIT_ANY_OID, oidCertExtType,
13219      "inhibitAnyPolicy", "X509v3 Inhibit Any Policy"},
13220    { WC_NID_ext_key_usage, EXT_KEY_USAGE_OID, oidCertExtType,
13221      "extendedKeyUsage", "X509v3 Extended Key Usage"},
13222    { WC_NID_name_constraints, NAME_CONS_OID, oidCertExtType,
13223      "nameConstraints", "X509v3 Name Constraints"},
13224    { WC_NID_certificate_policies, CERT_POLICY_OID, oidCertExtType,
13225      "certificatePolicies", "X509v3 Certificate Policies"},
13226
13227    /* oidCertAuthInfoType */
13228    { WC_NID_ad_OCSP, AIA_OCSP_OID, oidCertAuthInfoType, "OCSP",
13229      "OCSP"},
13230    { WC_NID_ad_ca_issuers, AIA_CA_ISSUER_OID, oidCertAuthInfoType,
13231      "caIssuers", "CA Issuers"},
13232
13233    /* oidCertPolicyType */
13234    { WC_NID_any_policy, CP_ANY_OID, oidCertPolicyType, "anyPolicy",
13235      "X509v3 Any Policy"},
13236
13237    /* oidCertAltNameType */
13238    { WC_NID_hw_name_oid, HW_NAME_OID, oidCertAltNameType, "Hardware name",""},
13239
13240    /* oidCertKeyUseType */
13241    { WC_NID_anyExtendedKeyUsage, EKU_ANY_OID, oidCertKeyUseType,
13242      "anyExtendedKeyUsage", "Any Extended Key Usage"},
13243    { EKU_SERVER_AUTH_OID, EKU_SERVER_AUTH_OID, oidCertKeyUseType,
13244      "serverAuth", "TLS Web Server Authentication"},
13245    { EKU_CLIENT_AUTH_OID, EKU_CLIENT_AUTH_OID, oidCertKeyUseType,
13246      "clientAuth", "TLS Web Client Authentication"},
13247    { EKU_OCSP_SIGN_OID, EKU_OCSP_SIGN_OID, oidCertKeyUseType,
13248      "OCSPSigning", "OCSP Signing"},
13249
13250    /* oidCertNameType */
13251    { WC_NID_commonName, WC_NAME_COMMON_NAME_OID, oidCertNameType,
13252      "CN", "commonName"},
13253#if !defined(WOLFSSL_CERT_REQ)
13254    { WC_NID_surname, WC_NAME_SURNAME_OID, oidCertNameType, "SN", "surname"},
13255#endif
13256    { WC_NID_serialNumber, WC_NAME_SERIAL_NUMBER_OID, oidCertNameType,
13257      "serialNumber", "serialNumber"},
13258    { WC_NID_userId, WC_NID_userId, oidCertNameType, "UID", "userid"},
13259    { WC_NID_countryName, WC_NAME_COUNTRY_NAME_OID, oidCertNameType,
13260      "C", "countryName"},
13261    { WC_NID_localityName, WC_NAME_LOCALITY_NAME_OID, oidCertNameType,
13262      "L", "localityName"},
13263    { WC_NID_stateOrProvinceName, WC_NAME_STATE_NAME_OID, oidCertNameType,
13264      "ST", "stateOrProvinceName"},
13265    { WC_NID_streetAddress, WC_NAME_STREET_ADDRESS_OID, oidCertNameType,
13266      "street", "streetAddress"},
13267    { WC_NID_organizationName, WC_NAME_ORGANIZATION_NAME_OID, oidCertNameType,
13268      "O", "organizationName"},
13269    { WC_NID_organizationalUnitName, WC_NAME_ORGANIZATION_UNIT_NAME_OID,
13270      oidCertNameType, "OU", "organizationalUnitName"},
13271    { WC_NID_title, WC_NAME_TITLE_OID, oidCertNameType, "title", "title"},
13272    { WC_NID_description, WC_NAME_DESCRIPTION_OID, oidCertNameType,
13273      "description", "description"},
13274    { WC_NID_emailAddress, WC_NAME_EMAIL_ADDRESS_OID, oidCertNameType,
13275      "emailAddress", "emailAddress"},
13276    { WC_NID_domainComponent, WC_NAME_DOMAIN_COMPONENT_OID, oidCertNameType,
13277      "DC", "domainComponent"},
13278    { WC_NID_rfc822Mailbox, WC_NAME_RFC822_MAILBOX_OID, oidCertNameType,
13279      "rfc822Mailbox", "rfc822Mailbox"},
13280    { WC_NID_favouriteDrink, WC_NAME_FAVOURITE_DRINK_OID, oidCertNameType,
13281      "favouriteDrink", "favouriteDrink"},
13282    { WC_NID_businessCategory, WC_NAME_BUSINESS_CATEGORY_OID, oidCertNameType,
13283      "businessCategory", "businessCategory"},
13284    { WC_NID_jurisdictionCountryName, WC_NAME_JURIS_COUNTRY_OID,
13285      oidCertNameType, "jurisdictionC", "jurisdictionCountryName"},
13286    { WC_NID_jurisdictionStateOrProvinceName, WC_NAME_JURIS_STATE_PROV_OID,
13287      oidCertNameType, "jurisdictionST", "jurisdictionStateOrProvinceName"},
13288    { WC_NID_postalCode, WC_NAME_POSTAL_CODE_OID, oidCertNameType, "postalCode",
13289      "postalCode"},
13290    { WC_NID_userId, WC_NAME_USER_ID_OID, oidCertNameType, "UID", "userId"},
13291    { WC_NID_netscape_cert_type, NETSCAPE_CT_OID, oidCertNameType,
13292      "nsCertType", "Netscape Cert Type"},
13293
13294#if defined(WOLFSSL_CERT_REQ) || defined(WOLFSSL_CERT_NAME_ALL)
13295    { WC_NID_pkcs9_challengePassword, CHALLENGE_PASSWORD_OID,
13296            oidCsrAttrType, "challengePassword", "challengePassword"},
13297    { WC_NID_pkcs9_contentType, PKCS9_CONTENT_TYPE_OID,
13298        oidCsrAttrType, "contentType", "contentType" },
13299    { WC_NID_pkcs9_unstructuredName, UNSTRUCTURED_NAME_OID,
13300        oidCsrAttrType, "unstructuredName", "unstructuredName" },
13301    { WC_NID_name, WC_NAME_NAME_OID, oidCsrAttrType, "name", "name" },
13302    { WC_NID_surname, SURNAME_OID,
13303        oidCsrAttrType, "surname", "surname" },
13304    { WC_NID_givenName, WC_NAME_GIVEN_NAME_OID,
13305        oidCsrAttrType, "givenName", "givenName" },
13306    { WC_NID_initials, WC_NAME_INITIALIS_OID,
13307        oidCsrAttrType, "initials", "initials" },
13308    { WC_NID_dnQualifier, DNQUALIFIER_OID,
13309        oidCsrAttrType, "dnQualifer", "dnQualifier" },
13310#endif
13311#endif
13312#ifdef OPENSSL_EXTRA /* OPENSSL_EXTRA_X509_SMALL only needs the above */
13313        /* oidHashType */
13314    #ifdef WOLFSSL_MD2
13315        { WC_NID_md2, MD2h, oidHashType, "MD2", "md2"},
13316    #endif
13317    #ifndef NO_MD4
13318        { WC_NID_md4, MD4h, oidHashType, "MD4", "md4"},
13319    #endif
13320    #ifndef NO_MD5
13321        { WC_NID_md5, MD5h, oidHashType, "MD5", "md5"},
13322    #endif
13323    #ifndef NO_SHA
13324        { WC_NID_sha1, SHAh, oidHashType, "SHA1", "sha1"},
13325    #endif
13326    #ifdef WOLFSSL_SHA224
13327        { WC_NID_sha224, SHA224h, oidHashType, "SHA224", "sha224"},
13328    #endif
13329    #ifndef NO_SHA256
13330        { WC_NID_sha256, SHA256h, oidHashType, "SHA256", "sha256"},
13331    #endif
13332    #ifdef WOLFSSL_SHA384
13333        { WC_NID_sha384, SHA384h, oidHashType, "SHA384", "sha384"},
13334    #endif
13335    #ifdef WOLFSSL_SHA512
13336        { WC_NID_sha512, SHA512h, oidHashType, "SHA512", "sha512"},
13337    #endif
13338    #ifdef WOLFSSL_SHA3
13339        #ifndef WOLFSSL_NOSHA3_224
13340        { WC_NID_sha3_224, SHA3_224h, oidHashType, "SHA3-224", "sha3-224"},
13341        #endif
13342        #ifndef WOLFSSL_NOSHA3_256
13343        { WC_NID_sha3_256, SHA3_256h, oidHashType, "SHA3-256", "sha3-256"},
13344        #endif
13345        #ifndef WOLFSSL_NOSHA3_384
13346        { WC_NID_sha3_384, SHA3_384h, oidHashType, "SHA3-384", "sha3-384"},
13347        #endif
13348        #ifndef WOLFSSL_NOSHA3_512
13349        { WC_NID_sha3_512, SHA3_512h, oidHashType, "SHA3-512", "sha3-512"},
13350        #endif
13351    #endif /* WOLFSSL_SHA3 */
13352    #ifdef WOLFSSL_SM3
13353        { WC_NID_sm3, SM3h, oidHashType, "SM3", "sm3"},
13354    #endif
13355    #ifdef WOLFSSL_SHAKE128
13356        { WC_NID_shake128, SHAKE128h, oidHashType, "SHAKE128", "shake128"},
13357    #endif
13358    #ifdef WOLFSSL_SHAKE256
13359        { WC_NID_shake256, SHAKE256h, oidHashType, "SHAKE256", "shake256"},
13360    #endif
13361        /* oidSigType */
13362    #ifndef NO_DSA
13363        #ifndef NO_SHA
13364        { WC_NID_dsaWithSHA1, CTC_SHAwDSA, oidSigType,
13365          "DSA-SHA1", "dsaWithSHA1"},
13366        { WC_NID_dsa_with_SHA256, CTC_SHA256wDSA, oidSigType, "dsa_with_SHA256",
13367          "dsa_with_SHA256"},
13368        #endif
13369    #endif /* NO_DSA */
13370    #ifndef NO_RSA
13371        #ifdef WOLFSSL_MD2
13372        { WC_NID_md2WithRSAEncryption, CTC_MD2wRSA, oidSigType, "RSA-MD2",
13373          "md2WithRSAEncryption"},
13374        #endif
13375        #ifndef NO_MD5
13376        { WC_NID_md5WithRSAEncryption, CTC_MD5wRSA, oidSigType, "RSA-MD5",
13377          "md5WithRSAEncryption"},
13378        #endif
13379        #ifndef NO_SHA
13380        { WC_NID_sha1WithRSAEncryption, CTC_SHAwRSA, oidSigType, "RSA-SHA1",
13381          "sha1WithRSAEncryption"},
13382        #endif
13383        #ifdef WOLFSSL_SHA224
13384        { WC_NID_sha224WithRSAEncryption, CTC_SHA224wRSA, oidSigType,
13385          "RSA-SHA224", "sha224WithRSAEncryption"},
13386        #endif
13387        #ifndef NO_SHA256
13388        { WC_NID_sha256WithRSAEncryption, CTC_SHA256wRSA, oidSigType,
13389          "RSA-SHA256", "sha256WithRSAEncryption"},
13390        #endif
13391        #ifdef WOLFSSL_SHA384
13392        { WC_NID_sha384WithRSAEncryption, CTC_SHA384wRSA, oidSigType,
13393          "RSA-SHA384", "sha384WithRSAEncryption"},
13394        #endif
13395        #ifdef WOLFSSL_SHA512
13396        { WC_NID_sha512WithRSAEncryption, CTC_SHA512wRSA, oidSigType,
13397          "RSA-SHA512", "sha512WithRSAEncryption"},
13398        #endif
13399        #ifdef WOLFSSL_SHA3
13400        #ifndef WOLFSSL_NOSHA3_224
13401        { WC_NID_RSA_SHA3_224, CTC_SHA3_224wRSA, oidSigType, "RSA-SHA3-224",
13402          "sha3-224WithRSAEncryption"},
13403        #endif
13404        #ifndef WOLFSSL_NOSHA3_256
13405        { WC_NID_RSA_SHA3_256, CTC_SHA3_256wRSA, oidSigType, "RSA-SHA3-256",
13406          "sha3-256WithRSAEncryption"},
13407        #endif
13408        #ifndef WOLFSSL_NOSHA3_384
13409        { WC_NID_RSA_SHA3_384, CTC_SHA3_384wRSA, oidSigType, "RSA-SHA3-384",
13410          "sha3-384WithRSAEncryption"},
13411        #endif
13412        #ifndef WOLFSSL_NOSHA3_512
13413        { WC_NID_RSA_SHA3_512, CTC_SHA3_512wRSA, oidSigType, "RSA-SHA3-512",
13414          "sha3-512WithRSAEncryption"},
13415        #endif
13416        #endif
13417        #ifdef WC_RSA_PSS
13418        { WC_NID_rsassaPss, CTC_RSASSAPSS, oidSigType,
13419          "RSASSA-PSS", "rsassaPss" },
13420        #endif
13421    #endif /* NO_RSA */
13422    #ifdef HAVE_ECC
13423        #ifndef NO_SHA
13424        { WC_NID_ecdsa_with_SHA1, CTC_SHAwECDSA, oidSigType, "ecdsa-with-SHA1",
13425          "shaWithECDSA"},
13426        #endif
13427        #ifdef WOLFSSL_SHA224
13428        { WC_NID_ecdsa_with_SHA224, CTC_SHA224wECDSA, oidSigType,
13429          "ecdsa-with-SHA224","sha224WithECDSA"},
13430        #endif
13431        #ifndef NO_SHA256
13432        { WC_NID_ecdsa_with_SHA256, CTC_SHA256wECDSA, oidSigType,
13433          "ecdsa-with-SHA256","sha256WithECDSA"},
13434        #endif
13435        #ifdef WOLFSSL_SHA384
13436        { WC_NID_ecdsa_with_SHA384, CTC_SHA384wECDSA, oidSigType,
13437          "ecdsa-with-SHA384","sha384WithECDSA"},
13438        #endif
13439        #ifdef WOLFSSL_SHA512
13440        { WC_NID_ecdsa_with_SHA512, CTC_SHA512wECDSA, oidSigType,
13441          "ecdsa-with-SHA512","sha512WithECDSA"},
13442        #endif
13443        #ifdef WOLFSSL_SHA3
13444        #ifndef WOLFSSL_NOSHA3_224
13445        { WC_NID_ecdsa_with_SHA3_224, CTC_SHA3_224wECDSA, oidSigType,
13446          "id-ecdsa-with-SHA3-224", "ecdsa_with_SHA3-224"},
13447        #endif
13448        #ifndef WOLFSSL_NOSHA3_256
13449        { WC_NID_ecdsa_with_SHA3_256, CTC_SHA3_256wECDSA, oidSigType,
13450          "id-ecdsa-with-SHA3-256", "ecdsa_with_SHA3-256"},
13451        #endif
13452        #ifndef WOLFSSL_NOSHA3_384
13453        { WC_NID_ecdsa_with_SHA3_384, CTC_SHA3_384wECDSA, oidSigType,
13454          "id-ecdsa-with-SHA3-384", "ecdsa_with_SHA3-384"},
13455        #endif
13456        #ifndef WOLFSSL_NOSHA3_512
13457        { WC_NID_ecdsa_with_SHA3_512, CTC_SHA3_512wECDSA, oidSigType,
13458          "id-ecdsa-with-SHA3-512", "ecdsa_with_SHA3-512"},
13459        #endif
13460        #endif
13461    #endif /* HAVE_ECC */
13462
13463        /* oidKeyType */
13464    #ifndef NO_DSA
13465        { WC_NID_dsa, DSAk, oidKeyType, "DSA", "dsaEncryption"},
13466    #endif /* NO_DSA */
13467    #ifndef NO_RSA
13468        { WC_NID_rsaEncryption, RSAk, oidKeyType, "rsaEncryption",
13469          "rsaEncryption"},
13470    #ifdef WC_RSA_PSS
13471        { WC_NID_rsassaPss, RSAPSSk, oidKeyType, "RSASSA-PSS", "rsassaPss"},
13472    #endif
13473    #endif /* NO_RSA */
13474    #ifdef HAVE_ECC
13475        { WC_NID_X9_62_id_ecPublicKey, ECDSAk, oidKeyType, "id-ecPublicKey",
13476                                                        "id-ecPublicKey"},
13477    #endif /* HAVE_ECC */
13478    #ifndef NO_DH
13479        { WC_NID_dhKeyAgreement, DHk, oidKeyType, "dhKeyAgreement",
13480          "dhKeyAgreement"},
13481    #endif
13482    #ifdef HAVE_ED448
13483        { WC_NID_ED448, ED448k,  oidKeyType, "ED448", "ED448"},
13484    #endif
13485    #ifdef HAVE_ED25519
13486        { WC_NID_ED25519, ED25519k,  oidKeyType, "ED25519", "ED25519"},
13487    #endif
13488    #ifdef HAVE_FALCON
13489        { CTC_FALCON_LEVEL1, FALCON_LEVEL1k,  oidKeyType, "Falcon Level 1",
13490                                                          "Falcon Level 1"},
13491        { CTC_FALCON_LEVEL5, FALCON_LEVEL5k,  oidKeyType, "Falcon Level 5",
13492                                                          "Falcon Level 5"},
13493    #endif /* HAVE_FALCON */
13494    #ifdef HAVE_DILITHIUM
13495    #ifdef WOLFSSL_DILITHIUM_FIPS204_DRAFT
13496        { CTC_DILITHIUM_LEVEL2, DILITHIUM_LEVEL2k,  oidKeyType,
13497          "Dilithium Level 2", "Dilithium Level 2"},
13498        { CTC_DILITHIUM_LEVEL3, DILITHIUM_LEVEL3k,  oidKeyType,
13499          "Dilithium Level 3", "Dilithium Level 3"},
13500        { CTC_DILITHIUM_LEVEL5, DILITHIUM_LEVEL5k,  oidKeyType,
13501          "Dilithium Level 5", "Dilithium Level 5"},
13502    #endif /* WOLFSSL_DILITHIUM_FIPS204_DRAFT */
13503        { CTC_ML_DSA_LEVEL2, ML_DSA_LEVEL2k,  oidKeyType,
13504          "ML-DSA 44", "ML-DSA 44"},
13505        { CTC_ML_DSA_LEVEL3, ML_DSA_LEVEL3k,  oidKeyType,
13506          "ML-DSA 65", "ML-DSA 65"},
13507        { CTC_ML_DSA_LEVEL5, ML_DSA_LEVEL5k,  oidKeyType,
13508          "ML-DSA 87", "ML-DSA 87"},
13509    #endif /* HAVE_DILITHIUM */
13510
13511        /* oidCurveType */
13512    #ifdef HAVE_ECC
13513        { WC_NID_X9_62_prime192v1, ECC_SECP192R1_OID, oidCurveType,
13514          "prime192v1", "prime192v1"},
13515        { WC_NID_X9_62_prime192v2, ECC_PRIME192V2_OID, oidCurveType,
13516          "prime192v2", "prime192v2"},
13517        { WC_NID_X9_62_prime192v3, ECC_PRIME192V3_OID, oidCurveType,
13518          "prime192v3", "prime192v3"},
13519
13520        { WC_NID_X9_62_prime239v1, ECC_PRIME239V1_OID, oidCurveType,
13521          "prime239v1", "prime239v1"},
13522        { WC_NID_X9_62_prime239v2, ECC_PRIME239V2_OID, oidCurveType,
13523          "prime239v2", "prime239v2"},
13524        { WC_NID_X9_62_prime239v3, ECC_PRIME239V3_OID, oidCurveType,
13525          "prime239v3", "prime239v3"},
13526
13527        { WC_NID_X9_62_prime256v1, ECC_SECP256R1_OID, oidCurveType,
13528          "prime256v1", "prime256v1"},
13529
13530        { WC_NID_secp112r1, ECC_SECP112R1_OID,  oidCurveType, "secp112r1",
13531          "secp112r1"},
13532        { WC_NID_secp112r2, ECC_SECP112R2_OID,  oidCurveType, "secp112r2",
13533          "secp112r2"},
13534
13535        { WC_NID_secp128r1, ECC_SECP128R1_OID,  oidCurveType, "secp128r1",
13536          "secp128r1"},
13537        { WC_NID_secp128r2, ECC_SECP128R2_OID,  oidCurveType, "secp128r2",
13538          "secp128r2"},
13539
13540        { WC_NID_secp160r1, ECC_SECP160R1_OID,  oidCurveType, "secp160r1",
13541          "secp160r1"},
13542        { WC_NID_secp160r2, ECC_SECP160R2_OID,  oidCurveType, "secp160r2",
13543          "secp160r2"},
13544
13545        { WC_NID_secp224r1, ECC_SECP224R1_OID,  oidCurveType, "secp224r1",
13546          "secp224r1"},
13547        { WC_NID_secp384r1, ECC_SECP384R1_OID,  oidCurveType, "secp384r1",
13548          "secp384r1"},
13549        { WC_NID_secp521r1, ECC_SECP521R1_OID,  oidCurveType, "secp521r1",
13550          "secp521r1"},
13551
13552        { WC_NID_secp160k1, ECC_SECP160K1_OID,  oidCurveType, "secp160k1",
13553          "secp160k1"},
13554        { WC_NID_secp192k1, ECC_SECP192K1_OID,  oidCurveType, "secp192k1",
13555          "secp192k1"},
13556        { WC_NID_secp224k1, ECC_SECP224K1_OID,  oidCurveType, "secp224k1",
13557          "secp224k1"},
13558        { WC_NID_secp256k1, ECC_SECP256K1_OID,  oidCurveType, "secp256k1",
13559          "secp256k1"},
13560
13561        { WC_NID_brainpoolP160r1, ECC_BRAINPOOLP160R1_OID,  oidCurveType,
13562          "brainpoolP160r1", "brainpoolP160r1"},
13563        { WC_NID_brainpoolP192r1, ECC_BRAINPOOLP192R1_OID,  oidCurveType,
13564          "brainpoolP192r1", "brainpoolP192r1"},
13565        { WC_NID_brainpoolP224r1, ECC_BRAINPOOLP224R1_OID,  oidCurveType,
13566          "brainpoolP224r1", "brainpoolP224r1"},
13567        { WC_NID_brainpoolP256r1, ECC_BRAINPOOLP256R1_OID,  oidCurveType,
13568          "brainpoolP256r1", "brainpoolP256r1"},
13569        { WC_NID_brainpoolP320r1, ECC_BRAINPOOLP320R1_OID,  oidCurveType,
13570          "brainpoolP320r1", "brainpoolP320r1"},
13571        { WC_NID_brainpoolP384r1, ECC_BRAINPOOLP384R1_OID,  oidCurveType,
13572          "brainpoolP384r1", "brainpoolP384r1"},
13573        { WC_NID_brainpoolP512r1, ECC_BRAINPOOLP512R1_OID,  oidCurveType,
13574          "brainpoolP512r1", "brainpoolP512r1"},
13575
13576    #ifdef WOLFSSL_SM2
13577        { WC_NID_sm2, ECC_SM2P256V1_OID, oidCurveType, "sm2", "sm2"},
13578    #endif
13579    #endif /* HAVE_ECC */
13580
13581        /* oidBlkType */
13582    #ifdef WOLFSSL_AES_128
13583        { AES128CBCb, AES128CBCb, oidBlkType, "AES-128-CBC", "aes-128-cbc"},
13584    #endif
13585    #ifdef WOLFSSL_AES_192
13586        { AES192CBCb, AES192CBCb, oidBlkType, "AES-192-CBC", "aes-192-cbc"},
13587    #endif
13588    #ifdef WOLFSSL_AES_256
13589        { AES256CBCb, AES256CBCb, oidBlkType, "AES-256-CBC", "aes-256-cbc"},
13590    #endif
13591    #ifndef NO_DES3
13592        { WC_NID_des, DESb, oidBlkType, "DES-CBC", "des-cbc"},
13593        { WC_NID_des3, DES3b, oidBlkType, "DES-EDE3-CBC", "des-ede3-cbc"},
13594    #endif /* !NO_DES3 */
13595    #if defined(HAVE_CHACHA) && defined(HAVE_POLY1305)
13596        { WC_NID_chacha20_poly1305, WC_NID_chacha20_poly1305, oidBlkType,
13597          "ChaCha20-Poly1305", "chacha20-poly1305"},
13598    #endif
13599
13600        /* oidOcspType */
13601    #ifdef HAVE_OCSP
13602        { WC_NID_id_pkix_OCSP_basic, OCSP_BASIC_OID, oidOcspType,
13603          "basicOCSPResponse", "Basic OCSP Response"},
13604        { OCSP_NONCE_OID, OCSP_NONCE_OID, oidOcspType, "Nonce", "OCSP Nonce"},
13605    #endif /* HAVE_OCSP */
13606
13607    #ifndef NO_PWDBASED
13608        /* oidKdfType */
13609        { PBKDF2_OID, PBKDF2_OID, oidKdfType, "PBKDFv2", "PBKDF2"},
13610
13611        /* oidPBEType */
13612        { PBE_SHA1_RC4_128, PBE_SHA1_RC4_128, oidPBEType,
13613          "PBE-SHA1-RC4-128", "pbeWithSHA1And128BitRC4"},
13614        { PBE_SHA1_DES, PBE_SHA1_DES, oidPBEType, "PBE-SHA1-DES",
13615          "pbeWithSHA1AndDES-CBC"},
13616        { PBE_SHA1_DES3, PBE_SHA1_DES3, oidPBEType, "PBE-SHA1-3DES",
13617          "pbeWithSHA1And3-KeyTripleDES-CBC"},
13618    #endif
13619
13620        /* oidKeyWrapType */
13621    #ifdef WOLFSSL_AES_128
13622        { AES128_WRAP, AES128_WRAP, oidKeyWrapType, "AES-128 wrap",
13623          "aes128-wrap"},
13624    #endif
13625    #ifdef WOLFSSL_AES_192
13626        { AES192_WRAP, AES192_WRAP, oidKeyWrapType, "AES-192 wrap",
13627          "aes192-wrap"},
13628    #endif
13629    #ifdef WOLFSSL_AES_256
13630        { AES256_WRAP, AES256_WRAP, oidKeyWrapType, "AES-256 wrap",
13631          "aes256-wrap"},
13632    #endif
13633
13634    #ifndef NO_PKCS7
13635        #ifndef NO_DH
13636        /* oidCmsKeyAgreeType */
13637            #ifndef NO_SHA
13638        { dhSinglePass_stdDH_sha1kdf_scheme, dhSinglePass_stdDH_sha1kdf_scheme,
13639          oidCmsKeyAgreeType, "dhSinglePass-stdDH-sha1kdf-scheme",
13640          "dhSinglePass-stdDH-sha1kdf-scheme"},
13641            #endif
13642            #ifdef WOLFSSL_SHA224
13643        { dhSinglePass_stdDH_sha224kdf_scheme,
13644          dhSinglePass_stdDH_sha224kdf_scheme, oidCmsKeyAgreeType,
13645          "dhSinglePass-stdDH-sha224kdf-scheme",
13646          "dhSinglePass-stdDH-sha224kdf-scheme"},
13647            #endif
13648            #ifndef NO_SHA256
13649        { dhSinglePass_stdDH_sha256kdf_scheme,
13650          dhSinglePass_stdDH_sha256kdf_scheme, oidCmsKeyAgreeType,
13651          "dhSinglePass-stdDH-sha256kdf-scheme",
13652          "dhSinglePass-stdDH-sha256kdf-scheme"},
13653            #endif
13654            #ifdef WOLFSSL_SHA384
13655        { dhSinglePass_stdDH_sha384kdf_scheme,
13656          dhSinglePass_stdDH_sha384kdf_scheme, oidCmsKeyAgreeType,
13657          "dhSinglePass-stdDH-sha384kdf-scheme",
13658          "dhSinglePass-stdDH-sha384kdf-scheme"},
13659            #endif
13660            #ifdef WOLFSSL_SHA512
13661        { dhSinglePass_stdDH_sha512kdf_scheme,
13662          dhSinglePass_stdDH_sha512kdf_scheme, oidCmsKeyAgreeType,
13663          "dhSinglePass-stdDH-sha512kdf-scheme",
13664          "dhSinglePass-stdDH-sha512kdf-scheme"},
13665            #endif
13666        #endif
13667    #endif
13668    #if defined(WOLFSSL_APACHE_HTTPD)
13669        /* "1.3.6.1.5.5.7.8.7" */
13670        { WC_NID_id_on_dnsSRV, WOLFSSL_DNS_SRV_SUM, oidCertNameType,
13671            WOLFSSL_SN_DNS_SRV, WOLFSSL_LN_DNS_SRV },
13672
13673        /* "1.3.6.1.4.1.311.20.2.3" */
13674        { WC_NID_ms_upn, WOLFSSL_MS_UPN_SUM, oidCertExtType, WOLFSSL_SN_MS_UPN,
13675            WOLFSSL_LN_MS_UPN },
13676
13677        /* "1.3.6.1.5.5.7.1.24" */
13678        { WC_NID_tlsfeature, WOLFSSL_TLS_FEATURE_SUM, oidTlsExtType,
13679            WOLFSSL_SN_TLS_FEATURE, WOLFSSL_LN_TLS_FEATURE },
13680    #endif
13681#endif /* OPENSSL_EXTRA */
13682};
13683
13684#define WOLFSSL_OBJECT_INFO_SZ \
13685                (sizeof(wolfssl_object_info) / sizeof(*wolfssl_object_info))
13686const size_t wolfssl_object_info_sz = WOLFSSL_OBJECT_INFO_SZ;
13687#endif /* OPENSSL_EXTRA || OPENSSL_EXTRA_X509_SMALL */
13688
13689#if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)
13690/* Free the dynamically allocated data.
13691 *
13692 * p  Pointer to dynamically allocated memory.
13693 */
13694void wolfSSL_OPENSSL_free(void* p)
13695{
13696    WOLFSSL_MSG("wolfSSL_OPENSSL_free");
13697
13698    XFREE(p, NULL, DYNAMIC_TYPE_OPENSSL);
13699}
13700#endif /* OPENSSL_EXTRA || OPENSSL_EXTRA_X509_SMALL */
13701
13702#ifdef OPENSSL_EXTRA
13703
13704void *wolfSSL_OPENSSL_malloc(size_t a)
13705{
13706    return (void *)XMALLOC(a, NULL, DYNAMIC_TYPE_OPENSSL);
13707}
13708
13709int wolfSSL_OPENSSL_hexchar2int(unsigned char c)
13710{
13711    /* 'char' is unsigned on some platforms. */
13712    return (int)(signed char)HexCharToByte((char)c);
13713}
13714
13715unsigned char *wolfSSL_OPENSSL_hexstr2buf(const char *str, long *len)
13716{
13717    unsigned char* targetBuf;
13718    int srcDigitHigh = 0;
13719    int srcDigitLow = 0;
13720    size_t srcLen;
13721    size_t srcIdx = 0;
13722    long targetIdx = 0;
13723
13724    srcLen = XSTRLEN(str);
13725    targetBuf = (unsigned char*)XMALLOC(srcLen / 2, NULL, DYNAMIC_TYPE_OPENSSL);
13726    if (targetBuf == NULL) {
13727        return NULL;
13728    }
13729
13730    while (srcIdx < srcLen) {
13731        if (str[srcIdx] == ':') {
13732            srcIdx++;
13733            continue;
13734        }
13735
13736        srcDigitHigh = wolfSSL_OPENSSL_hexchar2int((unsigned char)str[srcIdx++]);
13737        srcDigitLow = wolfSSL_OPENSSL_hexchar2int((unsigned char)str[srcIdx++]);
13738        if (srcDigitHigh < 0 || srcDigitLow < 0) {
13739            WOLFSSL_MSG("Invalid hex character.");
13740            XFREE(targetBuf, NULL, DYNAMIC_TYPE_OPENSSL);
13741            return NULL;
13742        }
13743
13744        targetBuf[targetIdx++] = (unsigned char)((srcDigitHigh << 4) |
13745                                                  srcDigitLow       );
13746    }
13747
13748    if (len != NULL)
13749        *len = targetIdx;
13750
13751    return targetBuf;
13752}
13753
13754int wolfSSL_OPENSSL_init_ssl(word64 opts, const WOLFSSL_INIT_SETTINGS *settings)
13755{
13756    (void)opts;
13757    (void)settings;
13758    return wolfSSL_library_init();
13759}
13760
13761int wolfSSL_OPENSSL_init_crypto(word64 opts,
13762    const WOLFSSL_INIT_SETTINGS* settings)
13763{
13764    (void)opts;
13765    (void)settings;
13766    return wolfSSL_library_init();
13767}
13768
13769/* Colon separated list of <public key>+<digest> algorithms.
13770 * Replaces list in context.
13771 */
13772int wolfSSL_CTX_set1_sigalgs_list(WOLFSSL_CTX* ctx, const char* list)
13773{
13774    WOLFSSL_MSG("wolfSSL_CTX_set1_sigalg_list");
13775
13776    if (ctx == NULL || list == NULL) {
13777        WOLFSSL_MSG("Bad function arguments");
13778        return WOLFSSL_FAILURE;
13779    }
13780
13781    if (AllocateCtxSuites(ctx) != 0)
13782        return WOLFSSL_FAILURE;
13783
13784    return SetSuitesHashSigAlgo(ctx->suites, list);
13785}
13786
13787/* Colon separated list of <public key>+<digest> algorithms.
13788 * Replaces list in SSL.
13789 */
13790int wolfSSL_set1_sigalgs_list(WOLFSSL* ssl, const char* list)
13791{
13792    WOLFSSL_MSG("wolfSSL_set1_sigalg_list");
13793
13794    if (ssl == NULL || list == NULL) {
13795        WOLFSSL_MSG("Bad function arguments");
13796        return WOLFSSL_FAILURE;
13797    }
13798
13799    if (AllocateSuites(ssl) != 0)
13800        return WOLFSSL_FAILURE;
13801
13802    return SetSuitesHashSigAlgo(ssl->suites, list);
13803}
13804
13805static int HashToNid(byte hashAlgo, int* nid)
13806{
13807    int ret = WOLFSSL_SUCCESS;
13808
13809    /* Cast for compiler to check everything is implemented */
13810    switch ((enum wc_MACAlgorithm)hashAlgo) {
13811        case no_mac:
13812        case rmd_mac:
13813            *nid = WC_NID_undef;
13814            break;
13815        case md5_mac:
13816            *nid = WC_NID_md5;
13817            break;
13818        case sha_mac:
13819            *nid = WC_NID_sha1;
13820            break;
13821        case sha224_mac:
13822            *nid = WC_NID_sha224;
13823            break;
13824        case sha256_mac:
13825            *nid = WC_NID_sha256;
13826            break;
13827        case sha384_mac:
13828            *nid = WC_NID_sha384;
13829            break;
13830        case sha512_mac:
13831            *nid = WC_NID_sha512;
13832            break;
13833        case blake2b_mac:
13834            *nid = WC_NID_blake2b512;
13835            break;
13836        case sm3_mac:
13837            *nid = WC_NID_sm3;
13838            break;
13839        default:
13840            ret = WOLFSSL_FAILURE;
13841            break;
13842    }
13843
13844    return ret;
13845}
13846
13847static int SaToNid(byte sa, int* nid)
13848{
13849    int ret = WOLFSSL_SUCCESS;
13850    /* Cast for compiler to check everything is implemented */
13851    switch ((enum SignatureAlgorithm)sa) {
13852        case anonymous_sa_algo:
13853            *nid = WC_NID_undef;
13854            break;
13855        case rsa_sa_algo:
13856            *nid = WC_NID_rsaEncryption;
13857            break;
13858        case dsa_sa_algo:
13859            *nid = WC_NID_dsa;
13860            break;
13861        case ecc_dsa_sa_algo:
13862        case ecc_brainpool_sa_algo:
13863            *nid = WC_NID_X9_62_id_ecPublicKey;
13864            break;
13865        case rsa_pss_sa_algo:
13866            *nid = WC_NID_rsassaPss;
13867            break;
13868        case ed25519_sa_algo:
13869#ifdef HAVE_ED25519
13870            *nid = WC_NID_ED25519;
13871#else
13872            ret = WOLFSSL_FAILURE;
13873#endif
13874            break;
13875        case rsa_pss_pss_algo:
13876            *nid = WC_NID_rsassaPss;
13877            break;
13878        case ed448_sa_algo:
13879#ifdef HAVE_ED448
13880            *nid = WC_NID_ED448;
13881#else
13882            ret = WOLFSSL_FAILURE;
13883#endif
13884            break;
13885        case falcon_level1_sa_algo:
13886            *nid = CTC_FALCON_LEVEL1;
13887            break;
13888        case falcon_level5_sa_algo:
13889            *nid = CTC_FALCON_LEVEL5;
13890            break;
13891        case dilithium_level2_sa_algo:
13892            *nid = CTC_ML_DSA_LEVEL2;
13893            break;
13894        case dilithium_level3_sa_algo:
13895            *nid = CTC_ML_DSA_LEVEL3;
13896            break;
13897        case dilithium_level5_sa_algo:
13898            *nid = CTC_ML_DSA_LEVEL5;
13899            break;
13900        case sm2_sa_algo:
13901            *nid = WC_NID_sm2;
13902            break;
13903        case invalid_sa_algo:
13904        case any_sa_algo:
13905        default:
13906            ret = WOLFSSL_FAILURE;
13907            break;
13908    }
13909    return ret;
13910}
13911
13912/* This API returns the hash selected. */
13913int wolfSSL_get_signature_nid(WOLFSSL *ssl, int* nid)
13914{
13915    WOLFSSL_MSG("wolfSSL_get_signature_nid");
13916
13917    if (ssl == NULL || nid == NULL) {
13918        WOLFSSL_MSG("Bad function arguments");
13919        return WOLFSSL_FAILURE;
13920    }
13921
13922    return HashToNid(ssl->options.hashAlgo, nid);
13923}
13924
13925/* This API returns the signature selected. */
13926int wolfSSL_get_signature_type_nid(const WOLFSSL* ssl, int* nid)
13927{
13928    WOLFSSL_MSG("wolfSSL_get_signature_type_nid");
13929
13930    if (ssl == NULL || nid == NULL) {
13931        WOLFSSL_MSG("Bad function arguments");
13932        return WOLFSSL_FAILURE;
13933    }
13934
13935    return SaToNid(ssl->options.sigAlgo, nid);
13936}
13937
13938int wolfSSL_get_peer_signature_nid(WOLFSSL* ssl, int* nid)
13939{
13940    WOLFSSL_MSG("wolfSSL_get_peer_signature_nid");
13941
13942    if (ssl == NULL || nid == NULL) {
13943        WOLFSSL_MSG("Bad function arguments");
13944        return WOLFSSL_FAILURE;
13945    }
13946
13947    return HashToNid(ssl->options.peerHashAlgo, nid);
13948}
13949
13950int wolfSSL_get_peer_signature_type_nid(const WOLFSSL* ssl, int* nid)
13951{
13952    WOLFSSL_MSG("wolfSSL_get_peer_signature_type_nid");
13953
13954    if (ssl == NULL || nid == NULL) {
13955        WOLFSSL_MSG("Bad function arguments");
13956        return WOLFSSL_FAILURE;
13957    }
13958
13959    return SaToNid(ssl->options.peerSigAlgo, nid);
13960}
13961
13962#ifdef HAVE_ECC
13963
13964#if defined(WOLFSSL_TLS13) && defined(HAVE_SUPPORTED_CURVES)
13965int wolfSSL_CTX_set1_groups_list(WOLFSSL_CTX *ctx, const char *list)
13966{
13967    if (!ctx || !list) {
13968        return WOLFSSL_FAILURE;
13969    }
13970
13971    return set_curves_list(NULL, ctx, list, 0);
13972}
13973
13974int wolfSSL_set1_groups_list(WOLFSSL *ssl, const char *list)
13975{
13976    if (!ssl || !list) {
13977        return WOLFSSL_FAILURE;
13978    }
13979
13980    return set_curves_list(ssl, NULL, list, 0);
13981}
13982#endif /* WOLFSSL_TLS13 */
13983
13984#endif /* HAVE_ECC */
13985
13986#endif /* OPENSSL_EXTRA */
13987
13988#ifdef WOLFSSL_ALT_CERT_CHAINS
13989int wolfSSL_is_peer_alt_cert_chain(const WOLFSSL* ssl)
13990{
13991    int isUsing = 0;
13992    if (ssl)
13993        isUsing = ssl->options.usingAltCertChain;
13994    return isUsing;
13995}
13996#endif /* WOLFSSL_ALT_CERT_CHAINS */
13997
13998
13999#ifdef SESSION_CERTS
14000
14001#ifdef WOLFSSL_ALT_CERT_CHAINS
14002/* Get peer's alternate certificate chain */
14003WOLFSSL_X509_CHAIN* wolfSSL_get_peer_alt_chain(WOLFSSL* ssl)
14004{
14005    WOLFSSL_ENTER("wolfSSL_get_peer_alt_chain");
14006    if (ssl)
14007        return &ssl->session->altChain;
14008
14009    return 0;
14010}
14011#endif /* WOLFSSL_ALT_CERT_CHAINS */
14012
14013
14014/* Get peer's certificate chain */
14015WOLFSSL_X509_CHAIN* wolfSSL_get_peer_chain(WOLFSSL* ssl)
14016{
14017    WOLFSSL_ENTER("wolfSSL_get_peer_chain");
14018    if (ssl)
14019        return &ssl->session->chain;
14020
14021    return 0;
14022}
14023
14024
14025/* Get peer's certificate chain total count */
14026int wolfSSL_get_chain_count(WOLFSSL_X509_CHAIN* chain)
14027{
14028    WOLFSSL_ENTER("wolfSSL_get_chain_count");
14029    if (chain)
14030        return chain->count;
14031
14032    return 0;
14033}
14034
14035
14036/* Get peer's ASN.1 DER certificate at index (idx) length in bytes */
14037int wolfSSL_get_chain_length(WOLFSSL_X509_CHAIN* chain, int idx)
14038{
14039    WOLFSSL_ENTER("wolfSSL_get_chain_length");
14040    if (chain)
14041        return chain->certs[idx].length;
14042
14043    return 0;
14044}
14045
14046
14047/* Get peer's ASN.1 DER certificate at index (idx) */
14048byte* wolfSSL_get_chain_cert(WOLFSSL_X509_CHAIN* chain, int idx)
14049{
14050    WOLFSSL_ENTER("wolfSSL_get_chain_cert");
14051    if (chain)
14052        return chain->certs[idx].buffer;
14053
14054    return 0;
14055}
14056
14057
14058/* Get peer's wolfSSL X509 certificate at index (idx) */
14059WOLFSSL_X509* wolfSSL_get_chain_X509(WOLFSSL_X509_CHAIN* chain, int idx)
14060{
14061    int          ret = 0;
14062    WOLFSSL_X509* x509 = NULL;
14063    WC_DECLARE_VAR(cert, DecodedCert, 1, 0);
14064
14065    WOLFSSL_ENTER("wolfSSL_get_chain_X509");
14066    if (chain != NULL && idx < MAX_CHAIN_DEPTH) {
14067    #ifdef WOLFSSL_SMALL_STACK
14068        cert = (DecodedCert*)XMALLOC(sizeof(DecodedCert), NULL,
14069                                                       DYNAMIC_TYPE_DCERT);
14070        if (cert != NULL)
14071    #endif
14072        {
14073            InitDecodedCert(cert, chain->certs[idx].buffer,
14074                                  (word32)chain->certs[idx].length, NULL);
14075
14076            if ((ret = ParseCertRelative(cert, CERT_TYPE, 0, NULL, NULL)) != 0) {
14077                WOLFSSL_MSG("Failed to parse cert");
14078            }
14079            else {
14080                x509 = (WOLFSSL_X509*)XMALLOC(sizeof(WOLFSSL_X509), NULL,
14081                                                             DYNAMIC_TYPE_X509);
14082                if (x509 == NULL) {
14083                    WOLFSSL_MSG("Failed alloc X509");
14084                }
14085                else {
14086                    InitX509(x509, 1, NULL);
14087
14088                    if ((ret = CopyDecodedToX509(x509, cert)) != 0) {
14089                        WOLFSSL_MSG("Failed to copy decoded");
14090                        wolfSSL_X509_free(x509);
14091                        x509 = NULL;
14092                    }
14093                }
14094            }
14095
14096            FreeDecodedCert(cert);
14097            WC_FREE_VAR_EX(cert, NULL, DYNAMIC_TYPE_DCERT);
14098        }
14099    }
14100    (void)ret;
14101
14102    return x509;
14103}
14104
14105
14106/* Get peer's PEM certificate at index (idx), output to buffer if inLen big
14107   enough else return error (-1). If buffer is NULL only calculate
14108   outLen. Output length is in *outLen WOLFSSL_SUCCESS on ok */
14109int  wolfSSL_get_chain_cert_pem(WOLFSSL_X509_CHAIN* chain, int idx,
14110                               unsigned char* buf, int inLen, int* outLen)
14111{
14112#if defined(WOLFSSL_PEM_TO_DER) || defined(WOLFSSL_DER_TO_PEM)
14113    const char* header = NULL;
14114    const char* footer = NULL;
14115    int headerLen;
14116    int footerLen;
14117    int i;
14118    int err;
14119    word32 szNeeded = 0;
14120
14121    WOLFSSL_ENTER("wolfSSL_get_chain_cert_pem");
14122    if (!chain || !outLen || idx < 0 || idx >= wolfSSL_get_chain_count(chain))
14123        return BAD_FUNC_ARG;
14124
14125    err = wc_PemGetHeaderFooter(CERT_TYPE, &header, &footer);
14126    if (err != 0)
14127        return err;
14128
14129    headerLen = (int)XSTRLEN(header);
14130    footerLen = (int)XSTRLEN(footer);
14131
14132    /* Null output buffer return size needed in outLen */
14133    if(!buf) {
14134        if(Base64_Encode(chain->certs[idx].buffer,
14135                    (word32)chain->certs[idx].length,
14136                    NULL, &szNeeded) != WC_NO_ERR_TRACE(LENGTH_ONLY_E))
14137            return WOLFSSL_FAILURE;
14138        *outLen = (int)szNeeded + headerLen + footerLen;
14139        return WC_NO_ERR_TRACE(LENGTH_ONLY_E);
14140    }
14141
14142    /* don't even try if inLen too short */
14143    if (inLen < headerLen + footerLen + chain->certs[idx].length)
14144        return BAD_FUNC_ARG;
14145
14146    /* header */
14147    if (XMEMCPY(buf, header, (size_t)headerLen) == NULL)
14148        return WOLFSSL_FATAL_ERROR;
14149
14150    i = headerLen;
14151
14152    /* body */
14153    *outLen = inLen;  /* input to Base64_Encode */
14154    if ( (err = Base64_Encode(chain->certs[idx].buffer,
14155                       (word32)chain->certs[idx].length, buf + i,
14156                       (word32*)outLen)) < 0)
14157        return err;
14158    i += *outLen;
14159
14160    /* footer */
14161    if ( (i + footerLen) > inLen)
14162        return BAD_FUNC_ARG;
14163    if (XMEMCPY(buf + i, footer, (size_t)footerLen) == NULL)
14164        return WOLFSSL_FATAL_ERROR;
14165    *outLen += headerLen + footerLen;
14166
14167    return WOLFSSL_SUCCESS;
14168#else
14169    (void)chain;
14170    (void)idx;
14171    (void)buf;
14172    (void)inLen;
14173    (void)outLen;
14174    return WOLFSSL_FAILURE;
14175#endif /* WOLFSSL_PEM_TO_DER || WOLFSSL_DER_TO_PEM */
14176}
14177
14178#endif /* SESSION_CERTS */
14179
14180#ifdef HAVE_FUZZER
14181void wolfSSL_SetFuzzerCb(WOLFSSL* ssl, CallbackFuzzer cbf, void* fCtx)
14182{
14183    if (ssl) {
14184        ssl->fuzzerCb  = cbf;
14185        ssl->fuzzerCtx = fCtx;
14186    }
14187}
14188#endif
14189
14190#ifndef NO_CERTS
14191#ifdef  HAVE_PK_CALLBACKS
14192
14193/* callback for premaster secret generation */
14194void  wolfSSL_CTX_SetGenPreMasterCb(WOLFSSL_CTX* ctx, CallbackGenPreMaster cb)
14195{
14196    if (ctx)
14197        ctx->GenPreMasterCb = cb;
14198}
14199/* Set premaster secret generation callback context */
14200void  wolfSSL_SetGenPreMasterCtx(WOLFSSL* ssl, void *ctx)
14201{
14202    if (ssl)
14203        ssl->GenPreMasterCtx = ctx;
14204}
14205/* Get premaster secret generation callback context */
14206void* wolfSSL_GetGenPreMasterCtx(WOLFSSL* ssl)
14207{
14208    if (ssl)
14209        return ssl->GenPreMasterCtx;
14210
14211    return NULL;
14212}
14213
14214/* callback for master secret generation */
14215void  wolfSSL_CTX_SetGenMasterSecretCb(WOLFSSL_CTX* ctx,
14216    CallbackGenMasterSecret cb)
14217{
14218    if (ctx)
14219        ctx->GenMasterCb = cb;
14220}
14221/* Set master secret generation callback context */
14222void  wolfSSL_SetGenMasterSecretCtx(WOLFSSL* ssl, void *ctx)
14223{
14224    if (ssl)
14225        ssl->GenMasterCtx = ctx;
14226}
14227/* Get master secret generation callback context */
14228void* wolfSSL_GetGenMasterSecretCtx(WOLFSSL* ssl)
14229{
14230    if (ssl)
14231        return ssl->GenMasterCtx;
14232
14233    return NULL;
14234}
14235
14236/* callback for extended master secret generation */
14237void  wolfSSL_CTX_SetGenExtMasterSecretCb(WOLFSSL_CTX* ctx,
14238    CallbackGenExtMasterSecret cb)
14239{
14240    if (ctx)
14241        ctx->GenExtMasterCb = cb;
14242}
14243/* Set extended master secret generation callback context */
14244void  wolfSSL_SetGenExtMasterSecretCtx(WOLFSSL* ssl, void *ctx)
14245{
14246    if (ssl)
14247        ssl->GenExtMasterCtx = ctx;
14248}
14249/* Get extended master secret generation callback context */
14250void* wolfSSL_GetGenExtMasterSecretCtx(WOLFSSL* ssl)
14251{
14252    if (ssl)
14253        return ssl->GenExtMasterCtx;
14254
14255    return NULL;
14256}
14257
14258
14259/* callback for session key generation */
14260void  wolfSSL_CTX_SetGenSessionKeyCb(WOLFSSL_CTX* ctx, CallbackGenSessionKey cb)
14261{
14262    if (ctx)
14263        ctx->GenSessionKeyCb = cb;
14264}
14265/* Set session key generation callback context */
14266void  wolfSSL_SetGenSessionKeyCtx(WOLFSSL* ssl, void *ctx)
14267{
14268    if (ssl)
14269        ssl->GenSessionKeyCtx = ctx;
14270}
14271/* Get session key generation callback context */
14272void* wolfSSL_GetGenSessionKeyCtx(WOLFSSL* ssl)
14273{
14274    if (ssl)
14275        return ssl->GenSessionKeyCtx;
14276
14277    return NULL;
14278}
14279
14280/* callback for setting encryption keys */
14281void  wolfSSL_CTX_SetEncryptKeysCb(WOLFSSL_CTX* ctx, CallbackEncryptKeys cb)
14282{
14283    if (ctx)
14284        ctx->EncryptKeysCb = cb;
14285}
14286/* Set encryption keys callback context */
14287void  wolfSSL_SetEncryptKeysCtx(WOLFSSL* ssl, void *ctx)
14288{
14289    if (ssl)
14290        ssl->EncryptKeysCtx = ctx;
14291}
14292/* Get encryption keys callback context */
14293void* wolfSSL_GetEncryptKeysCtx(WOLFSSL* ssl)
14294{
14295    if (ssl)
14296        return ssl->EncryptKeysCtx;
14297
14298    return NULL;
14299}
14300
14301/* callback for Tls finished */
14302/* the callback can be used to build TLS Finished message if enabled */
14303void  wolfSSL_CTX_SetTlsFinishedCb(WOLFSSL_CTX* ctx, CallbackTlsFinished cb)
14304{
14305    if (ctx)
14306        ctx->TlsFinishedCb = cb;
14307}
14308/* Set Tls finished callback context */
14309void  wolfSSL_SetTlsFinishedCtx(WOLFSSL* ssl, void *ctx)
14310{
14311    if (ssl)
14312        ssl->TlsFinishedCtx = ctx;
14313}
14314/* Get Tls finished callback context */
14315void* wolfSSL_GetTlsFinishedCtx(WOLFSSL* ssl)
14316{
14317    if (ssl)
14318        return ssl->TlsFinishedCtx;
14319
14320    return NULL;
14321}
14322#if !defined(WOLFSSL_NO_TLS12) && !defined(WOLFSSL_AEAD_ONLY)
14323/* callback for verify data */
14324void  wolfSSL_CTX_SetVerifyMacCb(WOLFSSL_CTX* ctx, CallbackVerifyMac cb)
14325{
14326    if (ctx)
14327        ctx->VerifyMacCb = cb;
14328}
14329
14330/* Set set keys callback context */
14331void  wolfSSL_SetVerifyMacCtx(WOLFSSL* ssl, void *ctx)
14332{
14333    if (ssl)
14334        ssl->VerifyMacCtx = ctx;
14335}
14336/* Get set  keys callback context */
14337void* wolfSSL_GetVerifyMacCtx(WOLFSSL* ssl)
14338{
14339    if (ssl)
14340        return ssl->VerifyMacCtx;
14341
14342    return NULL;
14343}
14344#endif /* !WOLFSSL_NO_TLS12 && !WOLFSSL_AEAD_ONLY */
14345
14346void wolfSSL_CTX_SetHKDFExpandLabelCb(WOLFSSL_CTX* ctx,
14347                                      CallbackHKDFExpandLabel cb)
14348{
14349    if (ctx)
14350        ctx->HKDFExpandLabelCb = cb;
14351}
14352#ifdef WOLFSSL_PUBLIC_ASN
14353void wolfSSL_CTX_SetProcessPeerCertCb(WOLFSSL_CTX* ctx,
14354                                        CallbackProcessPeerCert cb)
14355{
14356    if (ctx)
14357        ctx->ProcessPeerCertCb = cb;
14358}
14359#endif /* WOLFSSL_PUBLIC_ASN */
14360void wolfSSL_CTX_SetProcessServerSigKexCb(WOLFSSL_CTX* ctx,
14361                                       CallbackProcessServerSigKex cb)
14362{
14363    if (ctx)
14364        ctx->ProcessServerSigKexCb = cb;
14365}
14366void wolfSSL_CTX_SetPerformTlsRecordProcessingCb(WOLFSSL_CTX* ctx,
14367                                          CallbackPerformTlsRecordProcessing cb)
14368{
14369    if (ctx)
14370        ctx->PerformTlsRecordProcessingCb = cb;
14371}
14372#endif /* HAVE_PK_CALLBACKS */
14373#endif /* NO_CERTS */
14374
14375#if defined(HAVE_PK_CALLBACKS) && defined(HAVE_HKDF)
14376
14377void wolfSSL_CTX_SetHKDFExtractCb(WOLFSSL_CTX* ctx, CallbackHKDFExtract cb)
14378{
14379    if (ctx)
14380        ctx->HkdfExtractCb = cb;
14381}
14382
14383void wolfSSL_SetHKDFExtractCtx(WOLFSSL* ssl, void *ctx)
14384{
14385    if (ssl)
14386        ssl->HkdfExtractCtx = ctx;
14387}
14388
14389void* wolfSSL_GetHKDFExtractCtx(WOLFSSL* ssl)
14390{
14391    if (ssl)
14392        return ssl->HkdfExtractCtx;
14393
14394    return NULL;
14395}
14396#endif /* HAVE_PK_CALLBACKS && HAVE_HKDF */
14397
14398#ifdef WOLFSSL_HAVE_WOLFSCEP
14399    /* Used by autoconf to see if wolfSCEP is available */
14400    void wolfSSL_wolfSCEP(void) {}
14401#endif
14402
14403
14404#ifdef WOLFSSL_HAVE_CERT_SERVICE
14405    /* Used by autoconf to see if cert service is available */
14406    void wolfSSL_cert_service(void) {}
14407#endif
14408
14409#if (defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)) && \
14410    !defined(WOLFCRYPT_ONLY)
14411
14412    /* NID variables are dependent on compatibility header files currently
14413     *
14414     * returns a pointer to a new WOLFSSL_ASN1_OBJECT struct on success and NULL
14415     *         on fail
14416     */
14417
14418    WOLFSSL_ASN1_OBJECT* wolfSSL_OBJ_nid2obj(int id)
14419    {
14420        return wolfSSL_OBJ_nid2obj_ex(id, NULL);
14421    }
14422
14423
14424    WOLFSSL_LOCAL WOLFSSL_ASN1_OBJECT* wolfSSL_OBJ_nid2obj_ex(int id,
14425                                                WOLFSSL_ASN1_OBJECT* arg_obj)
14426    {
14427        word32 oidSz = 0;
14428        int nid = 0;
14429        const byte* oid;
14430        word32 type = 0;
14431        WOLFSSL_ASN1_OBJECT* obj = arg_obj;
14432        byte objBuf[MAX_OID_SZ + MAX_LENGTH_SZ + 1]; /* +1 for object tag */
14433        word32 objSz = 0;
14434        const char* sName = NULL;
14435        int i;
14436
14437#ifdef WOLFSSL_DEBUG_OPENSSL
14438        WOLFSSL_ENTER("wolfSSL_OBJ_nid2obj");
14439#endif
14440
14441        for (i = 0; i < (int)WOLFSSL_OBJECT_INFO_SZ; i++) {
14442            if (wolfssl_object_info[i].nid == id) {
14443                nid = id;
14444                id = wolfssl_object_info[i].id;
14445                sName = wolfssl_object_info[i].sName;
14446                type = wolfssl_object_info[i].type;
14447                break;
14448            }
14449        }
14450        if (i == (int)WOLFSSL_OBJECT_INFO_SZ) {
14451            WOLFSSL_MSG("NID not in table");
14452        #ifdef WOLFSSL_QT
14453            sName = NULL;
14454            type = (word32)id;
14455        #else
14456            return NULL;
14457        #endif
14458        }
14459
14460    #ifdef HAVE_ECC
14461         if (type == 0 && wc_ecc_get_oid((word32)id, &oid, &oidSz) > 0) {
14462             type = oidCurveType;
14463         }
14464    #endif /* HAVE_ECC */
14465
14466        if (sName != NULL) {
14467            if (XSTRLEN(sName) > WOLFSSL_MAX_SNAME - 1) {
14468                WOLFSSL_MSG("Attempted short name is too large");
14469                return NULL;
14470            }
14471        }
14472
14473        oid = OidFromId((word32)id, type, &oidSz);
14474
14475        /* set object ID to buffer */
14476        if (obj == NULL){
14477            obj = wolfSSL_ASN1_OBJECT_new();
14478            if (obj == NULL) {
14479                WOLFSSL_MSG("Issue creating WOLFSSL_ASN1_OBJECT struct");
14480                return NULL;
14481            }
14482        }
14483        obj->nid     = nid;
14484        obj->type    = id;
14485        obj->grp     = (int)type;
14486
14487        obj->sName[0] = '\0';
14488        if (sName != NULL) {
14489            XMEMCPY(obj->sName, (char*)sName, XSTRLEN((char*)sName));
14490        }
14491
14492        objBuf[0] = ASN_OBJECT_ID; objSz++;
14493        objSz += SetLength(oidSz, objBuf + 1);
14494        if (oidSz) {
14495            XMEMCPY(objBuf + objSz, oid, oidSz);
14496            objSz     += oidSz;
14497        }
14498
14499        if (obj->objSz == 0 || objSz != obj->objSz) {
14500            obj->objSz = objSz;
14501            if(((obj->dynamic & WOLFSSL_ASN1_DYNAMIC_DATA) != 0) ||
14502                                                           (obj->obj == NULL)) {
14503                if (obj->obj != NULL)
14504                    XFREE((byte*)obj->obj, NULL, DYNAMIC_TYPE_ASN1);
14505                obj->obj = (byte*)XMALLOC(obj->objSz, NULL, DYNAMIC_TYPE_ASN1);
14506                if (obj->obj == NULL) {
14507                    wolfSSL_ASN1_OBJECT_free(obj);
14508                    return NULL;
14509                }
14510                obj->dynamic |= WOLFSSL_ASN1_DYNAMIC_DATA;
14511            }
14512            else {
14513                obj->dynamic &= (unsigned char)~WOLFSSL_ASN1_DYNAMIC_DATA;
14514            }
14515        }
14516        XMEMCPY((byte*)obj->obj, objBuf, obj->objSz);
14517
14518        (void)type;
14519
14520        return obj;
14521    }
14522
14523    static const char* oid_translate_num_to_str(const char* oid)
14524    {
14525        const struct oid_dict {
14526            const char* num;
14527            const char* desc;
14528        } oid_dict[] = {
14529            { "2.5.29.37.0",       "Any Extended Key Usage" },
14530            { "1.3.6.1.5.5.7.3.1", "TLS Web Server Authentication" },
14531            { "1.3.6.1.5.5.7.3.2", "TLS Web Client Authentication" },
14532            { "1.3.6.1.5.5.7.3.3", "Code Signing" },
14533            { "1.3.6.1.5.5.7.3.4", "E-mail Protection" },
14534            { "1.3.6.1.5.5.7.3.8", "Time Stamping" },
14535            { "1.3.6.1.5.5.7.3.9", "OCSP Signing" },
14536            { NULL, NULL }
14537        };
14538        const struct oid_dict* idx;
14539
14540        for (idx = oid_dict; idx->num != NULL; idx++) {
14541            if (!XSTRCMP(oid, idx->num)) {
14542                return idx->desc;
14543            }
14544        }
14545        return NULL;
14546    }
14547
14548    static int wolfssl_obj2txt_numeric(char *buf, int bufLen,
14549                                       const WOLFSSL_ASN1_OBJECT *a)
14550    {
14551        int bufSz;
14552        int    length;
14553        word32 idx = 0;
14554        byte   tag;
14555
14556        if (GetASNTag(a->obj, &idx, &tag, a->objSz) != 0) {
14557            return WOLFSSL_FAILURE;
14558        }
14559
14560        if (tag != ASN_OBJECT_ID) {
14561            WOLFSSL_MSG("Bad ASN1 Object");
14562            return WOLFSSL_FAILURE;
14563        }
14564
14565        if (GetLength((const byte*)a->obj, &idx, &length,
14566                       a->objSz) < 0 || length < 0) {
14567            return ASN_PARSE_E;
14568        }
14569
14570        if (bufLen < MAX_OID_STRING_SZ) {
14571            bufSz = bufLen - 1;
14572        }
14573        else {
14574            bufSz = MAX_OID_STRING_SZ;
14575        }
14576
14577        if ((bufSz = DecodePolicyOID(buf, (word32)bufSz, a->obj + idx,
14578                    (word32)length)) <= 0) {
14579            WOLFSSL_MSG("Error decoding OID");
14580            return WOLFSSL_FAILURE;
14581        }
14582
14583        buf[bufSz] = '\0';
14584
14585        return bufSz;
14586    }
14587
14588    /* If no_name is one then use numerical form, otherwise short name.
14589     *
14590     * Returns the buffer size on success, WOLFSSL_FAILURE on error
14591     */
14592    int wolfSSL_OBJ_obj2txt(char *buf, int bufLen, const WOLFSSL_ASN1_OBJECT *a,
14593                            int no_name)
14594    {
14595        int bufSz;
14596        const char* desc;
14597        const char* name;
14598
14599        WOLFSSL_ENTER("wolfSSL_OBJ_obj2txt");
14600
14601        if (buf == NULL || bufLen <= 1 || a == NULL) {
14602            WOLFSSL_MSG("Bad input argument");
14603            return WOLFSSL_FAILURE;
14604        }
14605
14606        if (no_name == 1) {
14607            return wolfssl_obj2txt_numeric(buf, bufLen, a);
14608        }
14609
14610        /* return long name unless using x509small, then return short name */
14611#if defined(OPENSSL_EXTRA_X509_SMALL) && !defined(OPENSSL_EXTRA)
14612        name = a->sName;
14613#else
14614        name = wolfSSL_OBJ_nid2ln(wolfSSL_OBJ_obj2nid(a));
14615#endif
14616
14617        if (name == NULL) {
14618            WOLFSSL_MSG("Name not found");
14619            bufSz = 0;
14620        }
14621        else if (XSTRLEN(name) + 1 < (word32)bufLen - 1) {
14622            bufSz = (int)XSTRLEN(name);
14623        }
14624        else {
14625            bufSz = bufLen - 1;
14626        }
14627        if (bufSz) {
14628            XMEMCPY(buf, name, (size_t)bufSz);
14629        }
14630        else if (a->type == WOLFSSL_GEN_DNS || a->type == WOLFSSL_GEN_EMAIL ||
14631                 a->type == WOLFSSL_GEN_URI) {
14632            size_t objLen = XSTRLEN((const char*)a->obj);
14633            if (objLen >= (size_t)bufLen) {
14634                bufSz = bufLen - 1;
14635            }
14636            else {
14637                bufSz = (int)objLen;
14638            }
14639            XMEMCPY(buf, a->obj, (size_t)bufSz);
14640        }
14641        else if ((bufSz = wolfssl_obj2txt_numeric(buf, bufLen, a)) > 0) {
14642            if ((desc = oid_translate_num_to_str(buf))) {
14643                bufSz = (int)XSTRLEN(desc);
14644                bufSz = (int)min((word32)bufSz,(word32) bufLen - 1);
14645                XMEMCPY(buf, desc, (size_t)bufSz);
14646            }
14647        }
14648        else {
14649            bufSz = 0;
14650        }
14651
14652        buf[bufSz] = '\0';
14653
14654        return bufSz;
14655    }
14656#endif /* OPENSSL_EXTRA || OPENSSL_EXTRA_X509_SMALL */
14657
14658#if defined(OPENSSL_EXTRA) || defined(HAVE_LIGHTY) || \
14659    defined(WOLFSSL_MYSQL_COMPATIBLE) || defined(HAVE_STUNNEL) || \
14660    defined(WOLFSSL_NGINX) || defined(HAVE_POCO_LIB) || \
14661    defined(WOLFSSL_HAPROXY) || defined(WOLFSSL_WPAS_SMALL)
14662    /* Returns the long name that corresponds with an ASN1_OBJECT nid value.
14663     *  n : NID value of ASN1_OBJECT to search */
14664    const char* wolfSSL_OBJ_nid2ln(int n)
14665    {
14666        const WOLFSSL_ObjectInfo *obj_info = wolfssl_object_info;
14667        size_t i;
14668        WOLFSSL_ENTER("wolfSSL_OBJ_nid2ln");
14669        for (i = 0; i < WOLFSSL_OBJECT_INFO_SZ; i++, obj_info++) {
14670            if (obj_info->nid == n) {
14671                return obj_info->lName;
14672            }
14673        }
14674        WOLFSSL_MSG("NID not found in table");
14675        return NULL;
14676    }
14677#endif /* OPENSSL_EXTRA, HAVE_LIGHTY, WOLFSSL_MYSQL_COMPATIBLE, HAVE_STUNNEL,
14678          WOLFSSL_NGINX, HAVE_POCO_LIB, WOLFSSL_HAPROXY, WOLFSSL_WPAS_SMALL */
14679
14680#if defined(OPENSSL_EXTRA) || defined(HAVE_LIGHTY) || \
14681    defined(WOLFSSL_MYSQL_COMPATIBLE) || defined(HAVE_STUNNEL) || \
14682    defined(WOLFSSL_NGINX) || defined(HAVE_POCO_LIB) || \
14683    defined(WOLFSSL_HAPROXY)
14684    /* Return the corresponding short name for the nid <n>.
14685     * or NULL if short name can't be found.
14686     */
14687    const char * wolfSSL_OBJ_nid2sn(int n) {
14688        const WOLFSSL_ObjectInfo *obj_info = wolfssl_object_info;
14689        size_t i;
14690        WOLFSSL_ENTER("wolfSSL_OBJ_nid2sn");
14691
14692        if (n == WC_NID_md5) {
14693            /* WC_NID_surname == WC_NID_md5 and WC_NID_surname comes before WC_NID_md5 in
14694             * wolfssl_object_info. As a result, the loop below will incorrectly
14695             * return "SN" instead of "MD5." WC_NID_surname isn't the true OpenSSL
14696             * NID, but other functions rely on this table and modifying it to
14697             * conform with OpenSSL's NIDs isn't trivial. */
14698             return "MD5";
14699        }
14700        for (i = 0; i < WOLFSSL_OBJECT_INFO_SZ; i++, obj_info++) {
14701            if (obj_info->nid == n) {
14702                return obj_info->sName;
14703            }
14704        }
14705        WOLFSSL_MSG_EX("SN not found (nid:%d)",n);
14706        return NULL;
14707    }
14708
14709#if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)
14710    int wolfSSL_OBJ_sn2nid(const char *sn) {
14711        WOLFSSL_ENTER("wolfSSL_OBJ_sn2nid");
14712        if (sn == NULL)
14713            return WC_NID_undef;
14714        return wc_OBJ_sn2nid(sn);
14715    }
14716#endif
14717
14718    size_t wolfSSL_OBJ_length(const WOLFSSL_ASN1_OBJECT* o)
14719    {
14720        size_t ret = 0;
14721        int err = 0;
14722        word32 idx = 0;
14723        int len = 0;
14724
14725        WOLFSSL_ENTER("wolfSSL_OBJ_length");
14726
14727        if (o == NULL || o->obj == NULL) {
14728            WOLFSSL_MSG("Bad argument.");
14729            err = 1;
14730        }
14731
14732        if (err == 0 && GetASNObjectId(o->obj, &idx, &len, o->objSz)) {
14733            WOLFSSL_MSG("Error parsing ASN.1 header.");
14734            err = 1;
14735        }
14736        if (err == 0) {
14737            ret = (size_t)len;
14738        }
14739
14740        WOLFSSL_LEAVE("wolfSSL_OBJ_length", (int)ret);
14741
14742        return ret;
14743    }
14744
14745    const unsigned char* wolfSSL_OBJ_get0_data(const WOLFSSL_ASN1_OBJECT* o)
14746    {
14747        const unsigned char* ret = NULL;
14748        int err = 0;
14749        word32 idx = 0;
14750        int len = 0;
14751
14752        WOLFSSL_ENTER("wolfSSL_OBJ_get0_data");
14753
14754        if (o == NULL || o->obj == NULL) {
14755            WOLFSSL_MSG("Bad argument.");
14756            err = 1;
14757        }
14758
14759        if (err == 0 && GetASNObjectId(o->obj, &idx, &len, o->objSz)) {
14760            WOLFSSL_MSG("Error parsing ASN.1 header.");
14761            err = 1;
14762        }
14763        if (err == 0) {
14764            ret = o->obj + idx;
14765        }
14766
14767        return ret;
14768    }
14769
14770
14771    /* Gets the NID value that corresponds with the ASN1 object.
14772     *
14773     * o ASN1 object to get NID of
14774     *
14775     * Return NID on success and a negative value on failure
14776     */
14777    int wolfSSL_OBJ_obj2nid(const WOLFSSL_ASN1_OBJECT *o)
14778    {
14779        word32 oid = 0;
14780        word32 idx = 0;
14781        int ret;
14782
14783#ifdef WOLFSSL_DEBUG_OPENSSL
14784        WOLFSSL_ENTER("wolfSSL_OBJ_obj2nid");
14785#endif
14786
14787        if (o == NULL) {
14788            return WOLFSSL_FATAL_ERROR;
14789        }
14790
14791        #ifdef WOLFSSL_QT
14792        if (o->grp == oidCertExtType) {
14793            /* If nid is an unknown extension, return WC_NID_undef */
14794            if (wolfSSL_OBJ_nid2sn(o->nid) == NULL)
14795                return WC_NID_undef;
14796        }
14797        #endif
14798
14799        if (o->nid > 0)
14800            return o->nid;
14801        if ((ret = GetObjectId(o->obj, &idx, &oid,
14802                                    (word32)o->grp, o->objSz)) < 0) {
14803            if (ret == WC_NO_ERR_TRACE(ASN_OBJECT_ID_E)) {
14804                /* Put ASN object tag in front and try again */
14805                int len = SetObjectId((int)o->objSz, NULL) + (int)o->objSz;
14806                byte* buf = (byte*)XMALLOC((size_t)len, NULL,
14807                                            DYNAMIC_TYPE_TMP_BUFFER);
14808                if (!buf) {
14809                    WOLFSSL_MSG("malloc error");
14810                    return WOLFSSL_FATAL_ERROR;
14811                }
14812                idx = (word32)SetObjectId((int)o->objSz, buf);
14813                XMEMCPY(buf + idx, o->obj, o->objSz);
14814                idx = 0;
14815                ret = GetObjectId(buf, &idx, &oid, (word32)o->grp, (word32)len);
14816                XFREE(buf, NULL, DYNAMIC_TYPE_TMP_BUFFER);
14817                if (ret < 0) {
14818                    WOLFSSL_MSG("Issue getting OID of object");
14819                    return WOLFSSL_FATAL_ERROR;
14820                }
14821            }
14822            else {
14823                WOLFSSL_MSG("Issue getting OID of object");
14824                return WOLFSSL_FATAL_ERROR;
14825            }
14826        }
14827
14828        return oid2nid(oid, o->grp);
14829    }
14830
14831    /* Return the corresponding NID for the long name <ln>
14832     * or WC_NID_undef if NID can't be found.
14833     */
14834    int wolfSSL_OBJ_ln2nid(const char *ln)
14835    {
14836        const WOLFSSL_ObjectInfo *obj_info = wolfssl_object_info;
14837        size_t lnlen;
14838        WOLFSSL_ENTER("wolfSSL_OBJ_ln2nid");
14839        if (ln && (lnlen = XSTRLEN(ln)) > 0) {
14840            /* Accept input like "/commonName=" */
14841            if (ln[0] == '/') {
14842                ln++;
14843                lnlen--;
14844            }
14845            if (lnlen) {
14846                size_t i;
14847
14848                if (ln[lnlen-1] == '=') {
14849                    lnlen--;
14850                }
14851                for (i = 0; i < WOLFSSL_OBJECT_INFO_SZ; i++, obj_info++) {
14852                    if (lnlen == XSTRLEN(obj_info->lName) &&
14853                            XSTRNCMP(ln, obj_info->lName, lnlen) == 0) {
14854                        return obj_info->nid;
14855                    }
14856                }
14857            }
14858        }
14859        return WC_NID_undef;
14860    }
14861
14862    /* compares two objects, return 0 if equal */
14863    int wolfSSL_OBJ_cmp(const WOLFSSL_ASN1_OBJECT* a,
14864                        const WOLFSSL_ASN1_OBJECT* b)
14865    {
14866        WOLFSSL_ENTER("wolfSSL_OBJ_cmp");
14867
14868        if (a && b && a->obj && b->obj) {
14869            if (a->objSz == b->objSz) {
14870                return XMEMCMP(a->obj, b->obj, a->objSz);
14871            }
14872            else if (a->type == EXT_KEY_USAGE_OID ||
14873                     b->type == EXT_KEY_USAGE_OID) {
14874                /* Special case for EXT_KEY_USAGE_OID so that
14875                 * cmp will be treated as a substring search */
14876                /* Used in libest to check for id-kp-cmcRA in
14877                 * EXT_KEY_USAGE extension */
14878                unsigned int idx;
14879                const byte* s; /* shorter */
14880                unsigned int sLen;
14881                const byte* l; /* longer */
14882                unsigned int lLen;
14883                if (a->objSz > b->objSz) {
14884                    s = b->obj; sLen = b->objSz;
14885                    l = a->obj; lLen = a->objSz;
14886                }
14887                else {
14888                    s = a->obj; sLen = a->objSz;
14889                    l = b->obj; lLen = b->objSz;
14890                }
14891                for (idx = 0; idx <= lLen - sLen; idx++) {
14892                    if (XMEMCMP(l + idx, s, sLen) == 0) {
14893                        /* Found substring */
14894                        return 0;
14895                    }
14896                }
14897            }
14898        }
14899
14900        return WOLFSSL_FATAL_ERROR;
14901    }
14902#endif /* OPENSSL_EXTRA, HAVE_LIGHTY, WOLFSSL_MYSQL_COMPATIBLE, HAVE_STUNNEL,
14903          WOLFSSL_NGINX, HAVE_POCO_LIB, WOLFSSL_HAPROXY */
14904#if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL) || \
14905    defined(HAVE_LIGHTY) || defined(WOLFSSL_MYSQL_COMPATIBLE) || \
14906    defined(HAVE_STUNNEL) || defined(WOLFSSL_NGINX) || \
14907    defined(HAVE_POCO_LIB) || defined(WOLFSSL_HAPROXY)
14908    /* Gets the NID value that is related to the OID string passed in. Example
14909     * string would be "2.5.29.14" for subject key ID.
14910     *
14911     * returns NID value on success and WC_NID_undef on error
14912     */
14913    int wolfSSL_OBJ_txt2nid(const char* s)
14914    {
14915        unsigned int i;
14916    #ifdef WOLFSSL_CERT_EXT
14917        int ret;
14918        unsigned int sum = 0;
14919        unsigned int outSz = MAX_OID_SZ;
14920        unsigned char out[MAX_OID_SZ];
14921
14922        XMEMSET(out, 0, sizeof(out));
14923    #endif
14924
14925        WOLFSSL_ENTER("wolfSSL_OBJ_txt2nid");
14926
14927        if (s == NULL) {
14928            return WC_NID_undef;
14929        }
14930
14931    #ifdef WOLFSSL_CERT_EXT
14932        ret = EncodePolicyOID(out, &outSz, s, NULL);
14933        if (ret == 0) {
14934            /* sum OID */
14935            sum = wc_oid_sum(out, outSz);
14936        }
14937    #endif /* WOLFSSL_CERT_EXT */
14938
14939        /* get the group that the OID's sum is in
14940         * @TODO possible conflict with multiples */
14941        for (i = 0; i < WOLFSSL_OBJECT_INFO_SZ; i++) {
14942            int len;
14943        #ifdef WOLFSSL_CERT_EXT
14944            if (ret == 0) {
14945                if (wolfssl_object_info[i].id == (int)sum) {
14946                    return wolfssl_object_info[i].nid;
14947                }
14948            }
14949        #endif
14950
14951            /* try as a short name */
14952            len = (int)XSTRLEN(s);
14953            if ((int)XSTRLEN(wolfssl_object_info[i].sName) == len &&
14954                XSTRNCMP(wolfssl_object_info[i].sName, s, (word32)len) == 0) {
14955                return wolfssl_object_info[i].nid;
14956            }
14957
14958            /* try as a long name */
14959            if ((int)XSTRLEN(wolfssl_object_info[i].lName) == len &&
14960                XSTRNCMP(wolfssl_object_info[i].lName, s, (word32)len) == 0) {
14961                return wolfssl_object_info[i].nid;
14962            }
14963        }
14964
14965        return WC_NID_undef;
14966    }
14967#endif
14968#if defined(OPENSSL_EXTRA) || defined(HAVE_LIGHTY) || \
14969    defined(WOLFSSL_MYSQL_COMPATIBLE) || defined(HAVE_STUNNEL) || \
14970    defined(WOLFSSL_NGINX) || defined(HAVE_POCO_LIB) || \
14971    defined(WOLFSSL_HAPROXY)
14972
14973    /* Creates new ASN1_OBJECT from short name, long name, or text
14974     * representation of oid. If no_name is 0, then short name, long name, and
14975     * numerical value of oid are interpreted. If no_name is 1, then only the
14976     * numerical value of the oid is interpreted.
14977     *
14978     * Returns pointer to ASN1_OBJECT on success, or NULL on error.
14979     */
14980#if defined(WOLFSSL_CERT_EXT) && defined(WOLFSSL_CERT_GEN)
14981    WOLFSSL_ASN1_OBJECT* wolfSSL_OBJ_txt2obj(const char* s, int no_name)
14982    {
14983        int i, ret;
14984        int nid = WC_NID_undef;
14985        unsigned int outSz = MAX_OID_SZ;
14986        unsigned char out[MAX_OID_SZ];
14987        WOLFSSL_ASN1_OBJECT* obj;
14988
14989        WOLFSSL_ENTER("wolfSSL_OBJ_txt2obj");
14990
14991        if (s == NULL)
14992            return NULL;
14993
14994        /* If s is numerical value, try to sum oid */
14995        ret = EncodePolicyOID(out, &outSz, s, NULL);
14996        if (ret == 0 && outSz > 0) {
14997            /* If numerical encode succeeded then just
14998             * create object from that because sums are
14999             * not unique and can cause confusion. */
15000            obj = wolfSSL_ASN1_OBJECT_new();
15001            if (obj == NULL) {
15002                WOLFSSL_MSG("Issue creating WOLFSSL_ASN1_OBJECT struct");
15003                return NULL;
15004            }
15005            obj->dynamic |= WOLFSSL_ASN1_DYNAMIC;
15006            obj->obj = (byte*)XMALLOC(1 + MAX_LENGTH_SZ + outSz, NULL,
15007                    DYNAMIC_TYPE_ASN1);
15008            if (obj->obj == NULL) {
15009                wolfSSL_ASN1_OBJECT_free(obj);
15010                return NULL;
15011            }
15012            obj->dynamic |= WOLFSSL_ASN1_DYNAMIC_DATA;
15013            i = SetObjectId((int)outSz, (byte*)obj->obj);
15014            XMEMCPY((byte*)obj->obj + i, out, outSz);
15015            obj->objSz = (word32)i + outSz;
15016            return obj;
15017        }
15018
15019        /* TODO: update short names in wolfssl_object_info and check OID sums
15020           are correct */
15021        for (i = 0; i < (int)WOLFSSL_OBJECT_INFO_SZ; i++) {
15022            /* Short name, long name, and numerical value are interpreted */
15023            if (no_name == 0 &&
15024                ((XSTRCMP(s, wolfssl_object_info[i].sName) == 0) ||
15025                 (XSTRCMP(s, wolfssl_object_info[i].lName) == 0)))
15026            {
15027                    nid = wolfssl_object_info[i].nid;
15028            }
15029        }
15030
15031        if (nid != WC_NID_undef)
15032            return wolfSSL_OBJ_nid2obj(nid);
15033
15034        return NULL;
15035    }
15036#endif
15037
15038    /* compatibility function. Its intended use is to remove OID's from an
15039     * internal table that have been added with OBJ_create. wolfSSL manages its
15040     * own internal OID values and does not currently support OBJ_create. */
15041    void wolfSSL_OBJ_cleanup(void)
15042    {
15043        WOLFSSL_ENTER("wolfSSL_OBJ_cleanup");
15044    }
15045
15046    #ifndef NO_WOLFSSL_STUB
15047    int wolfSSL_OBJ_create(const char *oid, const char *sn, const char *ln)
15048    {
15049        (void)oid;
15050        (void)sn;
15051        (void)ln;
15052        WOLFSSL_STUB("wolfSSL_OBJ_create");
15053        return WOLFSSL_FAILURE;
15054    }
15055    #endif
15056
15057    void wolfSSL_set_verify_depth(WOLFSSL *ssl, int depth)
15058    {
15059    #if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)
15060        WOLFSSL_ENTER("wolfSSL_set_verify_depth");
15061        ssl->options.verifyDepth = (byte)depth;
15062    #endif
15063    }
15064
15065#endif /* OPENSSL_ALL || HAVE_LIGHTY || WOLFSSL_MYSQL_COMPATIBLE ||
15066    HAVE_STUNNEL || WOLFSSL_NGINX || HAVE_POCO_LIB || WOLFSSL_HAPROXY */
15067
15068#ifdef OPENSSL_EXTRA
15069
15070/* wolfSSL uses negative values for error states. This function returns an
15071 * unsigned type so the value returned is the absolute value of the error.
15072 */
15073unsigned long wolfSSL_ERR_peek_last_error_line(const char **file, int *line)
15074{
15075    WOLFSSL_ENTER("wolfSSL_ERR_peek_last_error");
15076
15077    (void)line;
15078    (void)file;
15079#ifdef WOLFSSL_HAVE_ERROR_QUEUE
15080    {
15081        int ret;
15082
15083        if ((ret = wc_PeekErrorNode(-1, file, NULL, line)) < 0) {
15084            WOLFSSL_MSG("Issue peeking at error node in queue");
15085            return 0;
15086        }
15087    #if defined(OPENSSL_ALL) || defined(WOLFSSL_NGINX) \
15088        || defined(WOLFSSL_HAPROXY)
15089        if (ret == -WC_NO_ERR_TRACE(ASN_NO_PEM_HEADER))
15090            return (ERR_LIB_PEM << 24) | PEM_R_NO_START_LINE;
15091    #endif
15092    #if defined(OPENSSL_ALL) && defined(WOLFSSL_PYTHON)
15093        if (ret == ASN1_R_HEADER_TOO_LONG) {
15094            return (ERR_LIB_ASN1 << 24) | ASN1_R_HEADER_TOO_LONG;
15095        }
15096    #endif
15097        return (unsigned long)ret;
15098    }
15099#else
15100    return (unsigned long)(0 - NOT_COMPILED_IN);
15101#endif
15102}
15103
15104#endif /* OPENSSL_EXTRA */
15105
15106#ifdef HAVE_EX_DATA_CRYPTO
15107CRYPTO_EX_cb_ctx* crypto_ex_cb_ctx_session = NULL;
15108
15109static int crypto_ex_cb_new(CRYPTO_EX_cb_ctx** dst, long ctx_l, void* ctx_ptr,
15110        WOLFSSL_CRYPTO_EX_new* new_func, WOLFSSL_CRYPTO_EX_dup* dup_func,
15111        WOLFSSL_CRYPTO_EX_free* free_func)
15112{
15113    CRYPTO_EX_cb_ctx* new_ctx = (CRYPTO_EX_cb_ctx*)XMALLOC(
15114            sizeof(CRYPTO_EX_cb_ctx), NULL, DYNAMIC_TYPE_OPENSSL);
15115    if (new_ctx == NULL)
15116        return WOLFSSL_FATAL_ERROR;
15117    new_ctx->ctx_l = ctx_l;
15118    new_ctx->ctx_ptr = ctx_ptr;
15119    new_ctx->new_func = new_func;
15120    new_ctx->free_func = free_func;
15121    new_ctx->dup_func = dup_func;
15122    new_ctx->next = NULL;
15123    /* Push to end of list */
15124    while (*dst != NULL)
15125        dst = &(*dst)->next;
15126    *dst = new_ctx;
15127    return 0;
15128}
15129
15130void crypto_ex_cb_free(CRYPTO_EX_cb_ctx* cb_ctx)
15131{
15132    while (cb_ctx != NULL) {
15133        CRYPTO_EX_cb_ctx* next = cb_ctx->next;
15134        XFREE(cb_ctx, NULL, DYNAMIC_TYPE_OPENSSL);
15135        cb_ctx = next;
15136    }
15137}
15138
15139void crypto_ex_cb_setup_new_data(void *new_obj, CRYPTO_EX_cb_ctx* cb_ctx,
15140        WOLFSSL_CRYPTO_EX_DATA* ex_data)
15141{
15142    int idx = 0;
15143    for (; cb_ctx != NULL; idx++, cb_ctx = cb_ctx->next) {
15144        if (cb_ctx->new_func != NULL)
15145            cb_ctx->new_func(new_obj, NULL, ex_data, idx, cb_ctx->ctx_l,
15146                    cb_ctx->ctx_ptr);
15147    }
15148}
15149
15150int crypto_ex_cb_dup_data(const WOLFSSL_CRYPTO_EX_DATA *in,
15151        WOLFSSL_CRYPTO_EX_DATA *out, CRYPTO_EX_cb_ctx* cb_ctx)
15152{
15153    int idx = 0;
15154    for (; cb_ctx != NULL; idx++, cb_ctx = cb_ctx->next) {
15155        if (cb_ctx->dup_func != NULL) {
15156            void* ptr = wolfSSL_CRYPTO_get_ex_data(in, idx);
15157            if (!cb_ctx->dup_func(out, in,
15158                    &ptr, idx,
15159                    cb_ctx->ctx_l, cb_ctx->ctx_ptr)) {
15160                return WOLFSSL_FAILURE;
15161            }
15162            wolfSSL_CRYPTO_set_ex_data(out, idx, ptr);
15163        }
15164    }
15165    return WOLFSSL_SUCCESS;
15166}
15167
15168void crypto_ex_cb_free_data(void *obj, CRYPTO_EX_cb_ctx* cb_ctx,
15169        WOLFSSL_CRYPTO_EX_DATA* ex_data)
15170{
15171    int idx = 0;
15172    for (; cb_ctx != NULL; idx++, cb_ctx = cb_ctx->next) {
15173        if (cb_ctx->free_func != NULL)
15174            cb_ctx->free_func(obj, NULL, ex_data, idx, cb_ctx->ctx_l,
15175                    cb_ctx->ctx_ptr);
15176    }
15177}
15178
15179/**
15180 * wolfssl_local_get_ex_new_index is a helper function for the following
15181 * xx_get_ex_new_index functions:
15182 *  - wolfSSL_CRYPTO_get_ex_new_index
15183 *  - wolfSSL_CTX_get_ex_new_index
15184 *  - wolfSSL_get_ex_new_index
15185 * Issues a unique index number for the specified class-index.
15186 * Returns an index number greater or equal to zero on success,
15187 * -1 on failure.
15188 */
15189int wolfssl_local_get_ex_new_index(int class_index, long ctx_l, void* ctx_ptr,
15190        WOLFSSL_CRYPTO_EX_new* new_func, WOLFSSL_CRYPTO_EX_dup* dup_func,
15191        WOLFSSL_CRYPTO_EX_free* free_func)
15192{
15193    /* index counter for each class index*/
15194    static int ctx_idx = 0;
15195    static int ssl_idx = 0;
15196    static int ssl_session_idx = 0;
15197    static int x509_idx = 0;
15198
15199    int idx = -1;
15200
15201    switch(class_index) {
15202        case WOLF_CRYPTO_EX_INDEX_SSL:
15203            WOLFSSL_CRYPTO_EX_DATA_IGNORE_PARAMS(ctx_l, ctx_ptr, new_func,
15204                    dup_func, free_func);
15205            idx = ssl_idx++;
15206            break;
15207        case WOLF_CRYPTO_EX_INDEX_SSL_CTX:
15208            WOLFSSL_CRYPTO_EX_DATA_IGNORE_PARAMS(ctx_l, ctx_ptr, new_func,
15209                    dup_func, free_func);
15210            idx = ctx_idx++;
15211            break;
15212        case WOLF_CRYPTO_EX_INDEX_X509:
15213            WOLFSSL_CRYPTO_EX_DATA_IGNORE_PARAMS(ctx_l, ctx_ptr, new_func,
15214                    dup_func, free_func);
15215            idx = x509_idx++;
15216            break;
15217        case WOLF_CRYPTO_EX_INDEX_SSL_SESSION:
15218            if (crypto_ex_cb_new(&crypto_ex_cb_ctx_session, ctx_l, ctx_ptr,
15219                    new_func, dup_func, free_func) != 0)
15220                return WOLFSSL_FATAL_ERROR;
15221            idx = ssl_session_idx++;
15222            break;
15223
15224        /* following class indexes are not supoprted */
15225        case WOLF_CRYPTO_EX_INDEX_X509_STORE:
15226        case WOLF_CRYPTO_EX_INDEX_X509_STORE_CTX:
15227        case WOLF_CRYPTO_EX_INDEX_DH:
15228        case WOLF_CRYPTO_EX_INDEX_DSA:
15229        case WOLF_CRYPTO_EX_INDEX_EC_KEY:
15230        case WOLF_CRYPTO_EX_INDEX_RSA:
15231        case WOLF_CRYPTO_EX_INDEX_ENGINE:
15232        case WOLF_CRYPTO_EX_INDEX_UI:
15233        case WOLF_CRYPTO_EX_INDEX_BIO:
15234        case WOLF_CRYPTO_EX_INDEX_APP:
15235        case WOLF_CRYPTO_EX_INDEX_UI_METHOD:
15236        case WOLF_CRYPTO_EX_INDEX_DRBG:
15237        default:
15238            break;
15239    }
15240    if (idx >= MAX_EX_DATA)
15241        return WOLFSSL_FATAL_ERROR;
15242    return idx;
15243}
15244#endif /* HAVE_EX_DATA_CRYPTO */
15245
15246#ifdef HAVE_EX_DATA_CRYPTO
15247int wolfSSL_CTX_get_ex_new_index(long idx, void* arg,
15248                                 WOLFSSL_CRYPTO_EX_new* new_func,
15249                                 WOLFSSL_CRYPTO_EX_dup* dup_func,
15250                                 WOLFSSL_CRYPTO_EX_free* free_func)
15251{
15252
15253    WOLFSSL_ENTER("wolfSSL_CTX_get_ex_new_index");
15254
15255    return wolfssl_local_get_ex_new_index(WOLF_CRYPTO_EX_INDEX_SSL_CTX, idx,
15256                                    arg, new_func, dup_func, free_func);
15257}
15258
15259/* Return the index that can be used for the WOLFSSL structure to store
15260 * application data.
15261 *
15262 */
15263int wolfSSL_get_ex_new_index(long argValue, void* arg,
15264        WOLFSSL_CRYPTO_EX_new* cb1, WOLFSSL_CRYPTO_EX_dup* cb2,
15265        WOLFSSL_CRYPTO_EX_free* cb3)
15266{
15267    WOLFSSL_ENTER("wolfSSL_get_ex_new_index");
15268
15269    return wolfssl_local_get_ex_new_index(WOLF_CRYPTO_EX_INDEX_SSL, argValue,
15270            arg, cb1, cb2, cb3);
15271}
15272#endif /* HAVE_EX_DATA_CRYPTO */
15273
15274#ifdef OPENSSL_EXTRA
15275void* wolfSSL_CTX_get_ex_data(const WOLFSSL_CTX* ctx, int idx)
15276{
15277    WOLFSSL_ENTER("wolfSSL_CTX_get_ex_data");
15278#ifdef HAVE_EX_DATA
15279    if (ctx != NULL) {
15280        return wolfSSL_CRYPTO_get_ex_data(&ctx->ex_data, idx);
15281    }
15282#else
15283    (void)ctx;
15284    (void)idx;
15285#endif
15286    return NULL;
15287}
15288
15289int wolfSSL_CTX_set_ex_data(WOLFSSL_CTX* ctx, int idx, void* data)
15290{
15291    WOLFSSL_ENTER("wolfSSL_CTX_set_ex_data");
15292#ifdef HAVE_EX_DATA
15293    if (ctx != NULL) {
15294        return wolfSSL_CRYPTO_set_ex_data(&ctx->ex_data, idx, data);
15295    }
15296#else
15297    (void)ctx;
15298    (void)idx;
15299    (void)data;
15300#endif
15301    return WOLFSSL_FAILURE;
15302}
15303
15304#ifdef HAVE_EX_DATA_CLEANUP_HOOKS
15305int wolfSSL_CTX_set_ex_data_with_cleanup(
15306    WOLFSSL_CTX* ctx,
15307    int idx,
15308    void* data,
15309    wolfSSL_ex_data_cleanup_routine_t cleanup_routine)
15310{
15311    WOLFSSL_ENTER("wolfSSL_CTX_set_ex_data_with_cleanup");
15312    if (ctx != NULL) {
15313        return wolfSSL_CRYPTO_set_ex_data_with_cleanup(&ctx->ex_data, idx, data,
15314                                                       cleanup_routine);
15315    }
15316    return WOLFSSL_FAILURE;
15317}
15318#endif /* HAVE_EX_DATA_CLEANUP_HOOKS */
15319#endif /* OPENSSL_EXTRA */
15320
15321#if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)
15322
15323/* Returns char* to app data stored in ex[0].
15324 *
15325 * ssl WOLFSSL structure to get app data from
15326 */
15327void* wolfSSL_get_app_data(const WOLFSSL *ssl)
15328{
15329    /* checkout exdata stuff... */
15330    WOLFSSL_ENTER("wolfSSL_get_app_data");
15331
15332    return wolfSSL_get_ex_data(ssl, 0);
15333}
15334
15335
15336/* Set ex array 0 to have app data
15337 *
15338 * ssl WOLFSSL struct to set app data in
15339 * arg data to be stored
15340 *
15341 * Returns WOLFSSL_SUCCESS on success and WOLFSSL_FAILURE on failure
15342 */
15343int wolfSSL_set_app_data(WOLFSSL *ssl, void* arg) {
15344    WOLFSSL_ENTER("wolfSSL_set_app_data");
15345
15346    return wolfSSL_set_ex_data(ssl, 0, arg);
15347}
15348
15349#endif /* OPENSSL_EXTRA || OPENSSL_EXTRA_X509_SMALL */
15350
15351int wolfSSL_set_ex_data(WOLFSSL* ssl, int idx, void* data)
15352{
15353    WOLFSSL_ENTER("wolfSSL_set_ex_data");
15354#ifdef HAVE_EX_DATA
15355    if (ssl != NULL) {
15356        return wolfSSL_CRYPTO_set_ex_data(&ssl->ex_data, idx, data);
15357    }
15358#else
15359    WOLFSSL_MSG("HAVE_EX_DATA macro is not defined");
15360    (void)ssl;
15361    (void)idx;
15362    (void)data;
15363#endif
15364    return WOLFSSL_FAILURE;
15365}
15366
15367#ifdef HAVE_EX_DATA_CLEANUP_HOOKS
15368int wolfSSL_set_ex_data_with_cleanup(
15369    WOLFSSL* ssl,
15370    int idx,
15371    void* data,
15372    wolfSSL_ex_data_cleanup_routine_t cleanup_routine)
15373{
15374    WOLFSSL_ENTER("wolfSSL_set_ex_data_with_cleanup");
15375    if (ssl != NULL)
15376    {
15377        return wolfSSL_CRYPTO_set_ex_data_with_cleanup(&ssl->ex_data, idx, data,
15378                                                       cleanup_routine);
15379    }
15380    return WOLFSSL_FAILURE;
15381}
15382#endif /* HAVE_EX_DATA_CLEANUP_HOOKS */
15383
15384void* wolfSSL_get_ex_data(const WOLFSSL* ssl, int idx)
15385{
15386    WOLFSSL_ENTER("wolfSSL_get_ex_data");
15387#ifdef HAVE_EX_DATA
15388    if (ssl != NULL) {
15389        return wolfSSL_CRYPTO_get_ex_data(&ssl->ex_data, idx);
15390    }
15391#else
15392    WOLFSSL_MSG("HAVE_EX_DATA macro is not defined");
15393    (void)ssl;
15394    (void)idx;
15395#endif
15396    return 0;
15397}
15398
15399#if defined(HAVE_LIGHTY) || defined(HAVE_STUNNEL) \
15400    || defined(WOLFSSL_MYSQL_COMPATIBLE) || defined(OPENSSL_EXTRA)
15401
15402/* returns the enum value associated with handshake state
15403 *
15404 * ssl the WOLFSSL structure to get state of
15405 */
15406int wolfSSL_get_state(const WOLFSSL* ssl)
15407{
15408    WOLFSSL_ENTER("wolfSSL_get_state");
15409
15410    if (ssl == NULL) {
15411        WOLFSSL_MSG("Null argument passed in");
15412        return WOLFSSL_FAILURE;
15413    }
15414
15415    return ssl->options.handShakeState;
15416}
15417#endif /* HAVE_LIGHTY || HAVE_STUNNEL || WOLFSSL_MYSQL_COMPATIBLE */
15418
15419#ifdef OPENSSL_EXTRA
15420void wolfSSL_certs_clear(WOLFSSL* ssl)
15421{
15422    WOLFSSL_ENTER("wolfSSL_certs_clear");
15423
15424    if (ssl == NULL)
15425        return;
15426
15427    /* ctx still owns certificate, certChain, key, dh, and cm */
15428    if (ssl->buffers.weOwnCert) {
15429        FreeDer(&ssl->buffers.certificate);
15430        ssl->buffers.weOwnCert = 0;
15431    }
15432    ssl->buffers.certificate = NULL;
15433    if (ssl->buffers.weOwnCertChain) {
15434        FreeDer(&ssl->buffers.certChain);
15435        ssl->buffers.weOwnCertChain = 0;
15436    }
15437    ssl->buffers.certChain = NULL;
15438#ifdef WOLFSSL_TLS13
15439    ssl->buffers.certChainCnt = 0;
15440#endif
15441    if (ssl->buffers.weOwnKey) {
15442        FreeDer(&ssl->buffers.key);
15443    #ifdef WOLFSSL_BLIND_PRIVATE_KEY
15444        FreeDer(&ssl->buffers.keyMask);
15445    #endif
15446        ssl->buffers.weOwnKey = 0;
15447    }
15448    ssl->buffers.key      = NULL;
15449#ifdef WOLFSSL_BLIND_PRIVATE_KEY
15450    ssl->buffers.keyMask  = NULL;
15451#endif
15452    ssl->buffers.keyType  = 0;
15453    ssl->buffers.keyId    = 0;
15454    ssl->buffers.keyLabel = 0;
15455    ssl->buffers.keySz    = 0;
15456    ssl->buffers.keyDevId = 0;
15457#ifdef WOLFSSL_DUAL_ALG_CERTS
15458    if (ssl->buffers.weOwnAltKey) {
15459        FreeDer(&ssl->buffers.altKey);
15460    #ifdef WOLFSSL_BLIND_PRIVATE_KEY
15461        FreeDer(&ssl->buffers.altKeyMask);
15462    #endif
15463        ssl->buffers.weOwnAltKey = 0;
15464    }
15465    ssl->buffers.altKey     = NULL;
15466#ifdef WOLFSSL_BLIND_PRIVATE_KEY
15467    ssl->buffers.altKeyMask = NULL;
15468#endif
15469#endif /* WOLFSSL_DUAL_ALG_CERTS */
15470}
15471#endif
15472
15473#if defined(OPENSSL_ALL) || defined(WOLFSSL_ASIO) || defined(WOLFSSL_HAPROXY) \
15474    || defined(WOLFSSL_NGINX) || defined(WOLFSSL_QT)
15475
15476long wolfSSL_ctrl(WOLFSSL* ssl, int cmd, long opt, void* pt)
15477{
15478    WOLFSSL_ENTER("wolfSSL_ctrl");
15479    if (ssl == NULL)
15480        return BAD_FUNC_ARG;
15481
15482    switch (cmd) {
15483        #if defined(WOLFSSL_NGINX) || defined(WOLFSSL_QT) || \
15484            defined(OPENSSL_ALL)
15485        #ifdef HAVE_SNI
15486        case SSL_CTRL_SET_TLSEXT_HOSTNAME:
15487            WOLFSSL_MSG("Entering Case: SSL_CTRL_SET_TLSEXT_HOSTNAME.");
15488            if (pt == NULL) {
15489                WOLFSSL_MSG("Passed in NULL Host Name.");
15490                break;
15491            }
15492            return wolfSSL_set_tlsext_host_name(ssl, (const char*) pt);
15493        #endif /* HAVE_SNI */
15494        #endif /* WOLFSSL_NGINX || WOLFSSL_QT || OPENSSL_ALL */
15495        default:
15496            WOLFSSL_MSG("Case not implemented.");
15497    }
15498    (void)opt;
15499    (void)pt;
15500    return WOLFSSL_FAILURE;
15501}
15502
15503long wolfSSL_CTX_ctrl(WOLFSSL_CTX* ctx, int cmd, long opt, void* pt)
15504{
15505#if defined(OPENSSL_EXTRA) || defined(HAVE_WEBSERVER)
15506    long ctrl_opt;
15507#endif
15508    long ret = WOLFSSL_SUCCESS;
15509
15510    WOLFSSL_ENTER("wolfSSL_CTX_ctrl");
15511    if (ctx == NULL)
15512        return WOLFSSL_FAILURE;
15513
15514    switch (cmd) {
15515    case SSL_CTRL_CHAIN:
15516#ifdef SESSION_CERTS
15517    {
15518        /*
15519         * We don't care about opt here because a copy of the certificate is
15520         * stored anyway so increasing the reference counter is not necessary.
15521         * Just check to make sure that it is set to one of the correct values.
15522         */
15523        WOLF_STACK_OF(WOLFSSL_X509)* sk = (WOLF_STACK_OF(WOLFSSL_X509)*) pt;
15524        WOLFSSL_X509* x509;
15525        int i;
15526        if (opt != 0 && opt != 1) {
15527            ret = WOLFSSL_FAILURE;
15528            break;
15529        }
15530        /* Clear certificate chain */
15531        FreeDer(&ctx->certChain);
15532        if (sk) {
15533            for (i = 0; i < wolfSSL_sk_X509_num(sk); i++) {
15534                x509 = wolfSSL_sk_X509_value(sk, i);
15535                /* Prevent wolfSSL_CTX_add_extra_chain_cert from freeing cert */
15536                if (wolfSSL_X509_up_ref(x509) != 1) {
15537                    WOLFSSL_MSG("Error increasing reference count");
15538                    continue;
15539                }
15540                if (wolfSSL_CTX_add_extra_chain_cert(ctx, x509) !=
15541                        WOLFSSL_SUCCESS) {
15542                    WOLFSSL_MSG("Error adding certificate to context");
15543                    /* Decrease reference count on failure */
15544                    wolfSSL_X509_free(x509);
15545                    x509 = NULL;
15546                }
15547            }
15548        }
15549        /* Free previous chain */
15550        wolfSSL_sk_X509_pop_free(ctx->x509Chain, NULL);
15551        ctx->x509Chain = sk;
15552        if (sk && opt == 1) {
15553            /* up all refs when opt == 1 */
15554            for (i = 0; i < wolfSSL_sk_X509_num(sk); i++) {
15555                x509 = wolfSSL_sk_X509_value(sk, i);
15556                if (wolfSSL_X509_up_ref(x509) != 1) {
15557                    WOLFSSL_MSG("Error increasing reference count");
15558                    continue;
15559                }
15560            }
15561        }
15562    }
15563#else
15564        WOLFSSL_MSG("Session certificates not compiled in");
15565        ret = WOLFSSL_FAILURE;
15566#endif
15567        break;
15568
15569#if defined(OPENSSL_EXTRA) || defined(HAVE_WEBSERVER)
15570    case SSL_CTRL_OPTIONS:
15571        WOLFSSL_MSG("Entering Case: SSL_CTRL_OPTIONS.");
15572        ctrl_opt = wolfSSL_CTX_set_options(ctx, opt);
15573
15574        #ifdef WOLFSSL_QT
15575        /* Set whether to use client or server cipher preference */
15576        if ((ctrl_opt & WOLFSSL_OP_CIPHER_SERVER_PREFERENCE)
15577                     == WOLFSSL_OP_CIPHER_SERVER_PREFERENCE) {
15578            WOLFSSL_MSG("Using Server's Cipher Preference.");
15579            ctx->useClientOrder = 0;
15580        } else {
15581            WOLFSSL_MSG("Using Client's Cipher Preference.");
15582            ctx->useClientOrder = 1;
15583        }
15584        #endif /* WOLFSSL_QT */
15585
15586        return ctrl_opt;
15587#endif /* OPENSSL_EXTRA || HAVE_WEBSERVER */
15588    case SSL_CTRL_EXTRA_CHAIN_CERT:
15589        WOLFSSL_MSG("Entering Case: SSL_CTRL_EXTRA_CHAIN_CERT.");
15590        if (pt == NULL) {
15591            WOLFSSL_MSG("Passed in x509 pointer NULL.");
15592            ret = WOLFSSL_FAILURE;
15593            break;
15594        }
15595        return wolfSSL_CTX_add_extra_chain_cert(ctx, (WOLFSSL_X509*)pt);
15596
15597#ifndef NO_DH
15598    case SSL_CTRL_SET_TMP_DH:
15599        WOLFSSL_MSG("Entering Case: SSL_CTRL_SET_TMP_DH.");
15600        if (pt == NULL) {
15601            WOLFSSL_MSG("Passed in DH pointer NULL.");
15602            ret = WOLFSSL_FAILURE;
15603            break;
15604        }
15605        return wolfSSL_CTX_set_tmp_dh(ctx, (WOLFSSL_DH*)pt);
15606#endif
15607
15608#ifdef HAVE_ECC
15609    case SSL_CTRL_SET_TMP_ECDH:
15610        WOLFSSL_MSG("Entering Case: SSL_CTRL_SET_TMP_ECDH.");
15611        if (pt == NULL) {
15612            WOLFSSL_MSG("Passed in ECDH pointer NULL.");
15613            ret = WOLFSSL_FAILURE;
15614            break;
15615        }
15616        return wolfSSL_SSL_CTX_set_tmp_ecdh(ctx, (WOLFSSL_EC_KEY*)pt);
15617#endif
15618    case SSL_CTRL_MODE:
15619        wolfSSL_CTX_set_mode(ctx,opt);
15620        break;
15621    case SSL_CTRL_SET_MIN_PROTO_VERSION:
15622        WOLFSSL_MSG("set min proto version");
15623        return wolfSSL_CTX_set_min_proto_version(ctx, (int)opt);
15624    case SSL_CTRL_SET_MAX_PROTO_VERSION:
15625        WOLFSSL_MSG("set max proto version");
15626        return wolfSSL_CTX_set_max_proto_version(ctx, (int)opt);
15627    case SSL_CTRL_GET_MIN_PROTO_VERSION:
15628        WOLFSSL_MSG("get min proto version");
15629        return wolfSSL_CTX_get_min_proto_version(ctx);
15630    case SSL_CTRL_GET_MAX_PROTO_VERSION:
15631        WOLFSSL_MSG("get max proto version");
15632        return wolfSSL_CTX_get_max_proto_version(ctx);
15633    default:
15634        WOLFSSL_MSG("CTX_ctrl cmd not implemented");
15635        ret = WOLFSSL_FAILURE;
15636        break;
15637    }
15638
15639    (void)ctx;
15640    (void)cmd;
15641    (void)opt;
15642    (void)pt;
15643    WOLFSSL_LEAVE("wolfSSL_CTX_ctrl", (int)ret);
15644    return ret;
15645}
15646
15647#ifndef NO_WOLFSSL_STUB
15648long wolfSSL_CTX_callback_ctrl(WOLFSSL_CTX* ctx, int cmd, void (*fp)(void))
15649{
15650    (void) ctx;
15651    (void) cmd;
15652    (void) fp;
15653    WOLFSSL_STUB("wolfSSL_CTX_callback_ctrl");
15654    return WOLFSSL_FAILURE;
15655
15656}
15657#endif /* NO_WOLFSSL_STUB */
15658
15659#ifndef NO_WOLFSSL_STUB
15660long wolfSSL_CTX_clear_extra_chain_certs(WOLFSSL_CTX* ctx)
15661{
15662    return wolfSSL_CTX_ctrl(ctx, SSL_CTRL_CLEAR_EXTRA_CHAIN_CERTS, 0L, NULL);
15663}
15664#endif
15665
15666/* Returns the verifyCallback from the ssl structure if successful.
15667Returns NULL otherwise. */
15668VerifyCallback wolfSSL_get_verify_callback(WOLFSSL* ssl)
15669{
15670    WOLFSSL_ENTER("wolfSSL_get_verify_callback");
15671    if (ssl) {
15672        return ssl->verifyCallback;
15673    }
15674    return NULL;
15675}
15676
15677#endif /* OPENSSL_ALL || WOLFSSL_ASIO || WOLFSSL_HAPROXY || WOLFSSL_QT */
15678
15679
15680/* stunnel compatibility functions*/
15681#if defined(OPENSSL_ALL) || (defined(OPENSSL_EXTRA) && \
15682    (defined(HAVE_STUNNEL) || defined(WOLFSSL_NGINX) || \
15683     defined(HAVE_LIGHTY) || defined(WOLFSSL_HAPROXY) || \
15684     defined(WOLFSSL_OPENSSH)))
15685void wolfSSL_ERR_remove_thread_state(void* pid)
15686{
15687    (void) pid;
15688    return;
15689}
15690
15691#ifndef NO_FILESYSTEM
15692/***TBD ***/
15693void wolfSSL_print_all_errors_fp(XFILE fp)
15694{
15695    (void)fp;
15696}
15697#endif /* !NO_FILESYSTEM */
15698
15699#endif /* OPENSSL_ALL || OPENSSL_EXTRA || HAVE_STUNNEL || WOLFSSL_NGINX ||
15700    HAVE_LIGHTY || WOLFSSL_HAPROXY || WOLFSSL_OPENSSH */
15701
15702/* Note: This is a huge section of API's - through
15703 *       wolfSSL_X509_OBJECT_get0_X509_CRL */
15704#if defined(OPENSSL_ALL) || defined(OPENSSL_EXTRA)
15705
15706#if defined(USE_WOLFSSL_MEMORY) && !defined(WOLFSSL_DEBUG_MEMORY) && \
15707    !defined(WOLFSSL_STATIC_MEMORY)
15708static wolfSSL_OSSL_Malloc_cb  ossl_malloc  = NULL;
15709static wolfSSL_OSSL_Free_cb    ossl_free    = NULL;
15710static wolfSSL_OSSL_Realloc_cb ossl_realloc = NULL;
15711
15712static void* OSSL_Malloc(size_t size)
15713{
15714    if (ossl_malloc != NULL)
15715        return ossl_malloc(size, NULL, 0);
15716    else
15717        return NULL;
15718}
15719
15720static void  OSSL_Free(void *ptr)
15721{
15722    if (ossl_free != NULL)
15723        ossl_free(ptr, NULL, 0);
15724}
15725
15726static void* OSSL_Realloc(void *ptr, size_t size)
15727{
15728    if (ossl_realloc != NULL)
15729        return ossl_realloc(ptr, size, NULL, 0);
15730    else
15731        return NULL;
15732}
15733#endif /* USE_WOLFSSL_MEMORY && !WOLFSSL_DEBUG_MEMORY &&
15734        * !WOLFSSL_STATIC_MEMORY */
15735
15736int wolfSSL_CRYPTO_set_mem_functions(
15737        wolfSSL_OSSL_Malloc_cb  m,
15738        wolfSSL_OSSL_Realloc_cb r,
15739        wolfSSL_OSSL_Free_cb    f)
15740{
15741#if defined(USE_WOLFSSL_MEMORY) && !defined(WOLFSSL_STATIC_MEMORY)
15742#ifdef WOLFSSL_DEBUG_MEMORY
15743    WOLFSSL_MSG("mem functions will receive function name instead of "
15744                "file name");
15745    if (wolfSSL_SetAllocators((wolfSSL_Malloc_cb)m, (wolfSSL_Free_cb)f,
15746            (wolfSSL_Realloc_cb)r) == 0)
15747        return WOLFSSL_SUCCESS;
15748#else
15749    WOLFSSL_MSG("wolfSSL was compiled without WOLFSSL_DEBUG_MEMORY mem "
15750                "functions will receive a NULL file name and 0 for the "
15751                "line number.");
15752    if (wolfSSL_SetAllocators((wolfSSL_Malloc_cb)OSSL_Malloc,
15753           (wolfSSL_Free_cb)OSSL_Free, (wolfSSL_Realloc_cb)OSSL_Realloc) == 0) {
15754        ossl_malloc = m;
15755        ossl_free = f;
15756        ossl_realloc = r;
15757        return WOLFSSL_SUCCESS;
15758    }
15759#endif
15760    else
15761        return WOLFSSL_FAILURE;
15762#else
15763    (void)m;
15764    (void)r;
15765    (void)f;
15766    WOLFSSL_MSG("wolfSSL allocator callback functions not compiled in");
15767    return WOLFSSL_FAILURE;
15768#endif
15769}
15770
15771int wolfSSL_ERR_load_ERR_strings(void)
15772{
15773    return WOLFSSL_SUCCESS;
15774}
15775
15776void wolfSSL_ERR_load_crypto_strings(void)
15777{
15778    WOLFSSL_ENTER("wolfSSL_ERR_load_crypto_strings");
15779    /* Do nothing */
15780    return;
15781}
15782
15783int wolfSSL_FIPS_mode(void)
15784{
15785#ifdef HAVE_FIPS
15786    return 1;
15787#else
15788    return 0;
15789#endif
15790}
15791
15792int wolfSSL_FIPS_mode_set(int r)
15793{
15794#ifdef HAVE_FIPS
15795    if (r == 0) {
15796        WOLFSSL_MSG("Cannot disable FIPS at runtime.");
15797        return WOLFSSL_FAILURE;
15798    }
15799    return WOLFSSL_SUCCESS;
15800#else
15801    if (r == 0) {
15802        return WOLFSSL_SUCCESS;
15803    }
15804    WOLFSSL_MSG("Cannot enable FIPS. This isn't the wolfSSL FIPS code.");
15805    return WOLFSSL_FAILURE;
15806#endif
15807}
15808
15809int wolfSSL_CIPHER_get_bits(const WOLFSSL_CIPHER *c, int *alg_bits)
15810{
15811    int ret = WC_NO_ERR_TRACE(WOLFSSL_FAILURE);
15812    WOLFSSL_ENTER("wolfSSL_CIPHER_get_bits");
15813
15814    #if defined(WOLFSSL_QT) || defined(OPENSSL_ALL)
15815    (void)alg_bits;
15816    if (c!= NULL)
15817        ret = c->bits;
15818    #else
15819    if (c != NULL && c->ssl != NULL) {
15820        ret = 8 * c->ssl->specs.key_size;
15821        if (alg_bits != NULL) {
15822            *alg_bits = ret;
15823        }
15824    }
15825    #endif
15826    return ret;
15827}
15828
15829#ifdef HAVE_SNI
15830int wolfSSL_set_tlsext_host_name(WOLFSSL* ssl, const char* host_name)
15831{
15832    int ret;
15833    WOLFSSL_ENTER("wolfSSL_set_tlsext_host_name");
15834    ret = wolfSSL_UseSNI(ssl, WOLFSSL_SNI_HOST_NAME,
15835            host_name, (word16)XSTRLEN(host_name));
15836    WOLFSSL_LEAVE("wolfSSL_set_tlsext_host_name", ret);
15837    return ret;
15838}
15839
15840#ifndef NO_WOLFSSL_SERVER
15841/* May be called by server to get the requested accepted name and by the client
15842 * to get the requested name. */
15843const char * wolfSSL_get_servername(WOLFSSL* ssl, byte type)
15844{
15845    void * serverName = NULL;
15846    if (ssl == NULL)
15847        return NULL;
15848    TLSX_SNI_GetRequest(ssl->extensions, type, &serverName,
15849            !wolfSSL_is_server(ssl));
15850    return (const char *)serverName;
15851}
15852#endif
15853
15854#endif /* HAVE_SNI */
15855
15856WOLFSSL_CTX* wolfSSL_set_SSL_CTX(WOLFSSL* ssl, WOLFSSL_CTX* ctx)
15857{
15858    int ret;
15859    /* This method requires some explanation. Its sibling is
15860     *   int SetSSL_CTX(WOLFSSL* ssl, WOLFSSL_CTX* ctx, int writeDup)
15861     * which re-inits the WOLFSSL* with all settings in the new CTX.
15862     * That one is the right one to use *before* a handshake is started.
15863     *
15864     * This method was added by OpenSSL to be used *during* the handshake, e.g.
15865     * when a server inspects the SNI in a ClientHello callback and
15866     * decides which set of certificates to use.
15867     *
15868     * Since, at the time the SNI callback is run, some decisions on
15869     * Extensions or the ServerHello might already have been taken, this
15870     * method is very restricted in what it does:
15871     * - changing the server certificate(s)
15872     * - changing the server id for session handling
15873     * and everything else in WOLFSSL* needs to remain untouched.
15874     */
15875    WOLFSSL_ENTER("wolfSSL_set_SSL_CTX");
15876    if (ssl == NULL || ctx == NULL)
15877        return NULL;
15878    if (ssl->ctx == ctx)
15879        return ssl->ctx;
15880
15881    if (ctx->suites == NULL) {
15882        /* suites */
15883        if (AllocateCtxSuites(ctx) != 0)
15884            return NULL;
15885        InitSSL_CTX_Suites(ctx);
15886    }
15887
15888    wolfSSL_RefWithMutexInc(&ctx->ref, &ret);
15889#ifdef WOLFSSL_REFCNT_ERROR_RETURN
15890    if (ret != 0) {
15891        /* can only fail on serious stuff, like mutex not working
15892         * or ctx refcount out of whack. */
15893        return NULL;
15894    }
15895#else
15896    (void)ret;
15897#endif
15898    if (ssl->ctx != NULL)
15899        wolfSSL_CTX_free(ssl->ctx);
15900    ssl->ctx = ctx;
15901
15902#ifndef NO_CERTS
15903#ifdef WOLFSSL_COPY_CERT
15904    /* If WOLFSSL_COPY_CERT defined, always make new copy of cert from ctx */
15905    if (ctx->certificate != NULL) {
15906        if (ssl->buffers.certificate != NULL) {
15907            FreeDer(&ssl->buffers.certificate);
15908            ssl->buffers.certificate = NULL;
15909        }
15910        ret = AllocCopyDer(&ssl->buffers.certificate, ctx->certificate->buffer,
15911            ctx->certificate->length, ctx->certificate->type,
15912            ctx->certificate->heap);
15913        if (ret != 0) {
15914            ssl->buffers.weOwnCert = 0;
15915            return NULL;
15916        }
15917
15918        ssl->buffers.weOwnCert = 1;
15919    }
15920    if (ctx->certChain != NULL) {
15921        if (ssl->buffers.certChain != NULL) {
15922            FreeDer(&ssl->buffers.certChain);
15923            ssl->buffers.certChain = NULL;
15924        }
15925        ret = AllocCopyDer(&ssl->buffers.certChain, ctx->certChain->buffer,
15926            ctx->certChain->length, ctx->certChain->type,
15927            ctx->certChain->heap);
15928        if (ret != 0) {
15929            ssl->buffers.weOwnCertChain = 0;
15930            return NULL;
15931        }
15932
15933        ssl->buffers.weOwnCertChain = 1;
15934    }
15935#else
15936    /* ctx owns certificate, certChain and key */
15937    ssl->buffers.certificate = ctx->certificate;
15938    ssl->buffers.certChain = ctx->certChain;
15939#endif
15940#ifdef WOLFSSL_TLS13
15941    ssl->buffers.certChainCnt = ctx->certChainCnt;
15942#endif
15943#ifndef WOLFSSL_BLIND_PRIVATE_KEY
15944#ifdef WOLFSSL_COPY_KEY
15945    if (ssl->buffers.key != NULL && ssl->buffers.weOwnKey) {
15946        FreeDer(&ssl->buffers.key);
15947    }
15948    if (ctx->privateKey != NULL) {
15949        ret = AllocCopyDer(&ssl->buffers.key, ctx->privateKey->buffer,
15950            ctx->privateKey->length, ctx->privateKey->type,
15951            ctx->privateKey->heap);
15952        if (ret != 0) {
15953            ssl->buffers.weOwnKey = 0;
15954            return NULL;
15955        }
15956        ssl->buffers.weOwnKey = 1;
15957    }
15958    else {
15959        ssl->buffers.key      = ctx->privateKey;
15960    }
15961#else
15962    ssl->buffers.key      = ctx->privateKey;
15963#endif
15964#else
15965    if (ctx->privateKey != NULL) {
15966        ret = AllocCopyDer(&ssl->buffers.key, ctx->privateKey->buffer,
15967            ctx->privateKey->length, ctx->privateKey->type,
15968            ctx->privateKey->heap);
15969        if (ret != 0) {
15970            return NULL;
15971        }
15972        /* Blind the private key for the SSL with new random mask. */
15973        wolfssl_priv_der_blind_toggle(ssl->buffers.key, ctx->privateKeyMask);
15974        ret = wolfssl_priv_der_blind(ssl->rng, ssl->buffers.key,
15975            &ssl->buffers.keyMask);
15976        if (ret != 0) {
15977            return NULL;
15978        }
15979    }
15980#endif
15981    ssl->buffers.keyType  = ctx->privateKeyType;
15982    ssl->buffers.keyId    = ctx->privateKeyId;
15983    ssl->buffers.keyLabel = ctx->privateKeyLabel;
15984    ssl->buffers.keySz    = ctx->privateKeySz;
15985    ssl->buffers.keyDevId = ctx->privateKeyDevId;
15986    /* flags indicating what certs/keys are available */
15987    ssl->options.haveRSA          = ctx->haveRSA;
15988    ssl->options.haveDH           = ctx->haveDH;
15989    ssl->options.haveECDSAsig     = ctx->haveECDSAsig;
15990    ssl->options.haveECC          = ctx->haveECC;
15991    ssl->options.haveStaticECC    = ctx->haveStaticECC;
15992    ssl->options.haveFalconSig    = ctx->haveFalconSig;
15993    ssl->options.haveDilithiumSig = ctx->haveDilithiumSig;
15994#ifdef WOLFSSL_DUAL_ALG_CERTS
15995#ifndef WOLFSSL_BLIND_PRIVATE_KEY
15996    ssl->buffers.altKey   = ctx->altPrivateKey;
15997#else
15998    if (ctx->altPrivateKey != NULL) {
15999        ret = AllocCopyDer(&ssl->buffers.altKey, ctx->altPrivateKey->buffer,
16000            ctx->altPrivateKey->length, ctx->altPrivateKey->type,
16001            ctx->altPrivateKey->heap);
16002        if (ret != 0) {
16003            return NULL;
16004        }
16005        /* Blind the private key for the SSL with new random mask. */
16006        wolfssl_priv_der_blind_toggle(ssl->buffers.altKey,
16007                                      ctx->altPrivateKeyMask);
16008        ret = wolfssl_priv_der_blind(ssl->rng, ssl->buffers.altKey,
16009            &ssl->buffers.altKeyMask);
16010        if (ret != 0) {
16011            return NULL;
16012        }
16013    }
16014#endif
16015    ssl->buffers.altKeySz   = ctx->altPrivateKeySz;
16016    ssl->buffers.altKeyType = ctx->altPrivateKeyType;
16017#endif /* WOLFSSL_DUAL_ALG_CERTS */
16018#endif
16019
16020#ifdef WOLFSSL_SESSION_ID_CTX
16021    /* copy over application session context ID */
16022    ssl->sessionCtxSz = ctx->sessionCtxSz;
16023    XMEMCPY(ssl->sessionCtx, ctx->sessionCtx, ctx->sessionCtxSz);
16024#endif
16025
16026    return ssl->ctx;
16027}
16028
16029
16030VerifyCallback wolfSSL_CTX_get_verify_callback(WOLFSSL_CTX* ctx)
16031{
16032    WOLFSSL_ENTER("wolfSSL_CTX_get_verify_callback");
16033    if(ctx)
16034        return ctx->verifyCallback;
16035    return NULL;
16036}
16037
16038#ifdef HAVE_SNI
16039/* this is a compatibility function, consider using
16040 * wolfSSL_CTX_set_servername_callback */
16041int wolfSSL_CTX_set_tlsext_servername_callback(WOLFSSL_CTX* ctx,
16042                                               CallbackSniRecv cb)
16043{
16044    WOLFSSL_ENTER("wolfSSL_CTX_set_tlsext_servername_callback");
16045    if (ctx) {
16046        ctx->sniRecvCb = cb;
16047        return WOLFSSL_SUCCESS;
16048    }
16049    return WOLFSSL_FAILURE;
16050}
16051
16052#endif /* HAVE_SNI */
16053
16054#ifndef NO_BIO
16055void wolfSSL_ERR_load_BIO_strings(void) {
16056    WOLFSSL_ENTER("wolfSSL_ERR_load_BIO_strings");
16057    /* do nothing */
16058}
16059#endif
16060
16061#ifndef NO_WOLFSSL_STUB
16062/* Set THREADID callback, return 1 on success, 0 on error */
16063int wolfSSL_THREADID_set_callback(
16064        void(*threadid_func)(WOLFSSL_CRYPTO_THREADID*))
16065{
16066    WOLFSSL_ENTER("wolfSSL_THREADID_set_callback");
16067    WOLFSSL_STUB("CRYPTO_THREADID_set_callback");
16068    (void)threadid_func;
16069    return 1;
16070}
16071#endif
16072
16073#ifndef NO_WOLFSSL_STUB
16074void wolfSSL_THREADID_set_numeric(void* id, unsigned long val)
16075{
16076    WOLFSSL_ENTER("wolfSSL_THREADID_set_numeric");
16077    WOLFSSL_STUB("CRYPTO_THREADID_set_numeric");
16078    (void)id;
16079    (void)val;
16080    return;
16081}
16082#endif
16083
16084#endif /* OPENSSL_ALL || OPENSSL_EXTRA */
16085
16086#ifdef HAVE_SNI
16087
16088void wolfSSL_CTX_set_servername_callback(WOLFSSL_CTX* ctx, CallbackSniRecv cb)
16089{
16090    WOLFSSL_ENTER("wolfSSL_CTX_set_servername_callback");
16091    if (ctx)
16092        ctx->sniRecvCb = cb;
16093}
16094
16095
16096int wolfSSL_CTX_set_servername_arg(WOLFSSL_CTX* ctx, void* arg)
16097{
16098    WOLFSSL_ENTER("wolfSSL_CTX_set_servername_arg");
16099    if (ctx) {
16100        ctx->sniRecvCbArg = arg;
16101        return WOLFSSL_SUCCESS;
16102    }
16103    return WOLFSSL_FAILURE;
16104}
16105
16106#endif /* HAVE_SNI */
16107
16108#if defined(OPENSSL_EXTRA)
16109
16110int wolfSSL_CRYPTO_memcmp(const void *a, const void *b, size_t size)
16111{
16112    if (!a || !b)
16113        return -1;
16114    return ConstantCompare((const byte*)a, (const byte*)b, (int)size);
16115}
16116
16117unsigned long wolfSSL_ERR_peek_last_error(void)
16118{
16119    WOLFSSL_ENTER("wolfSSL_ERR_peek_last_error");
16120
16121#ifdef WOLFSSL_HAVE_ERROR_QUEUE
16122    {
16123        int ret;
16124
16125        if ((ret = wc_PeekErrorNode(-1, NULL, NULL, NULL)) < 0) {
16126            WOLFSSL_MSG("Issue peeking at error node in queue");
16127            return 0;
16128        }
16129        if (ret == -WC_NO_ERR_TRACE(ASN_NO_PEM_HEADER))
16130            return (WOLFSSL_ERR_LIB_PEM << 24) | -WC_NO_ERR_TRACE(WOLFSSL_PEM_R_NO_START_LINE_E);
16131    #if defined(WOLFSSL_PYTHON)
16132        if (ret == ASN1_R_HEADER_TOO_LONG)
16133            return (WOLFSSL_ERR_LIB_ASN1 << 24) | -WC_NO_ERR_TRACE(WOLFSSL_ASN1_R_HEADER_TOO_LONG_E);
16134    #endif
16135        return (unsigned long)ret;
16136    }
16137#else
16138    return (unsigned long)(0 - NOT_COMPILED_IN);
16139#endif
16140}
16141
16142#endif /* OPENSSL_EXTRA */
16143
16144int wolfSSL_version(WOLFSSL* ssl)
16145{
16146    WOLFSSL_ENTER("wolfSSL_version");
16147    if (ssl->version.major == SSLv3_MAJOR) {
16148        switch (ssl->version.minor) {
16149            case SSLv3_MINOR :
16150                return SSL3_VERSION;
16151            case TLSv1_MINOR :
16152                return TLS1_VERSION;
16153            case TLSv1_1_MINOR :
16154                return TLS1_1_VERSION;
16155            case TLSv1_2_MINOR :
16156                return TLS1_2_VERSION;
16157            case TLSv1_3_MINOR :
16158                return TLS1_3_VERSION;
16159            default:
16160                return WOLFSSL_FAILURE;
16161        }
16162    }
16163    else if (ssl->version.major == DTLS_MAJOR) {
16164        switch (ssl->version.minor) {
16165            case DTLS_MINOR :
16166                return DTLS1_VERSION;
16167            case DTLSv1_2_MINOR :
16168                return DTLS1_2_VERSION;
16169            case DTLSv1_3_MINOR:
16170                return DTLS1_3_VERSION;
16171            default:
16172                return WOLFSSL_FAILURE;
16173        }
16174    }
16175    return WOLFSSL_FAILURE;
16176}
16177
16178WOLFSSL_CTX* wolfSSL_get_SSL_CTX(const WOLFSSL* ssl)
16179{
16180    WOLFSSL_ENTER("wolfSSL_get_SSL_CTX");
16181    return ssl->ctx;
16182}
16183
16184#if defined(OPENSSL_ALL) || defined(OPENSSL_EXTRA) || defined(HAVE_STUNNEL) || \
16185    defined(WOLFSSL_MYSQL_COMPATIBLE) || defined(WOLFSSL_NGINX)
16186
16187/* TODO: Doesn't currently track SSL_VERIFY_CLIENT_ONCE */
16188int wolfSSL_get_verify_mode(const WOLFSSL* ssl)
16189{
16190    int mode = 0;
16191    WOLFSSL_ENTER("wolfSSL_get_verify_mode");
16192
16193    if (!ssl) {
16194        return WOLFSSL_FAILURE;
16195    }
16196
16197    if (ssl->options.verifyNone) {
16198        mode = WOLFSSL_VERIFY_NONE;
16199    }
16200    else {
16201        if (ssl->options.verifyPeer) {
16202            mode |= WOLFSSL_VERIFY_PEER;
16203        }
16204        if (ssl->options.failNoCert) {
16205            mode |= WOLFSSL_VERIFY_FAIL_IF_NO_PEER_CERT;
16206        }
16207        if (ssl->options.failNoCertxPSK) {
16208            mode |= WOLFSSL_VERIFY_FAIL_EXCEPT_PSK;
16209        }
16210#if defined(WOLFSSL_TLS13) && defined(WOLFSSL_POST_HANDSHAKE_AUTH)
16211        if (ssl->options.verifyPostHandshake) {
16212            mode |= WOLFSSL_VERIFY_POST_HANDSHAKE;
16213        }
16214#endif
16215    }
16216
16217    WOLFSSL_LEAVE("wolfSSL_get_verify_mode", mode);
16218    return mode;
16219}
16220
16221int wolfSSL_CTX_get_verify_mode(const WOLFSSL_CTX* ctx)
16222{
16223    int mode = 0;
16224    WOLFSSL_ENTER("wolfSSL_CTX_get_verify_mode");
16225
16226    if (!ctx) {
16227        return WOLFSSL_FAILURE;
16228    }
16229
16230    if (ctx->verifyNone) {
16231        mode = WOLFSSL_VERIFY_NONE;
16232    }
16233    else {
16234        if (ctx->verifyPeer) {
16235            mode |= WOLFSSL_VERIFY_PEER;
16236        }
16237        if (ctx->failNoCert) {
16238            mode |= WOLFSSL_VERIFY_FAIL_IF_NO_PEER_CERT;
16239        }
16240        if (ctx->failNoCertxPSK) {
16241            mode |= WOLFSSL_VERIFY_FAIL_EXCEPT_PSK;
16242        }
16243#if defined(WOLFSSL_TLS13) && defined(WOLFSSL_POST_HANDSHAKE_AUTH)
16244        if (ctx->verifyPostHandshake) {
16245            mode |= WOLFSSL_VERIFY_POST_HANDSHAKE;
16246        }
16247#endif
16248    }
16249
16250    WOLFSSL_LEAVE("wolfSSL_CTX_get_verify_mode", mode);
16251    return mode;
16252}
16253
16254#endif
16255
16256#ifdef WOLFSSL_JNI
16257
16258int wolfSSL_set_jobject(WOLFSSL* ssl, void* objPtr)
16259{
16260    WOLFSSL_ENTER("wolfSSL_set_jobject");
16261    if (ssl != NULL)
16262    {
16263        ssl->jObjectRef = objPtr;
16264        return WOLFSSL_SUCCESS;
16265    }
16266    return WOLFSSL_FAILURE;
16267}
16268
16269void* wolfSSL_get_jobject(WOLFSSL* ssl)
16270{
16271    WOLFSSL_ENTER("wolfSSL_get_jobject");
16272    if (ssl != NULL)
16273        return ssl->jObjectRef;
16274    return NULL;
16275}
16276
16277#endif /* WOLFSSL_JNI */
16278
16279
16280#ifdef WOLFSSL_ASYNC_CRYPT
16281int wolfSSL_CTX_AsyncPoll(WOLFSSL_CTX* ctx, WOLF_EVENT** events, int maxEvents,
16282    WOLF_EVENT_FLAG flags, int* eventCount)
16283{
16284    if (ctx == NULL) {
16285        return BAD_FUNC_ARG;
16286    }
16287
16288    return wolfAsync_EventQueuePoll(&ctx->event_queue, NULL,
16289                                        events, maxEvents, flags, eventCount);
16290}
16291
16292int wolfSSL_AsyncPoll(WOLFSSL* ssl, WOLF_EVENT_FLAG flags)
16293{
16294    int ret, eventCount = 0;
16295    WOLF_EVENT* events[1];
16296
16297    if (ssl == NULL) {
16298        return BAD_FUNC_ARG;
16299    }
16300
16301    ret = wolfAsync_EventQueuePoll(&ssl->ctx->event_queue, ssl,
16302        events, sizeof(events)/sizeof(events[0]), flags, &eventCount);
16303    if (ret == 0) {
16304        ret = eventCount;
16305    }
16306
16307    return ret;
16308}
16309#endif /* WOLFSSL_ASYNC_CRYPT */
16310
16311#ifdef OPENSSL_EXTRA
16312
16313static int peek_ignore_err(int err)
16314{
16315  switch(err) {
16316    case -WC_NO_ERR_TRACE(WANT_READ):
16317    case -WC_NO_ERR_TRACE(WANT_WRITE):
16318    case -WC_NO_ERR_TRACE(ZERO_RETURN):
16319    case -WOLFSSL_ERROR_ZERO_RETURN:
16320    case -WC_NO_ERR_TRACE(SOCKET_PEER_CLOSED_E):
16321    case -WC_NO_ERR_TRACE(SOCKET_ERROR_E):
16322      return 1;
16323    default:
16324      return 0;
16325  }
16326}
16327
16328unsigned long wolfSSL_ERR_peek_error_line_data(const char **file, int *line,
16329                                               const char **data, int *flags)
16330{
16331  unsigned long err;
16332
16333    WOLFSSL_ENTER("wolfSSL_ERR_peek_error_line_data");
16334    err = wc_PeekErrorNodeLineData(file, line, data, flags, peek_ignore_err);
16335
16336    if (err == -WC_NO_ERR_TRACE(ASN_NO_PEM_HEADER))
16337        return (WOLFSSL_ERR_LIB_PEM << 24) | -WC_NO_ERR_TRACE(WOLFSSL_PEM_R_NO_START_LINE_E);
16338#ifdef OPENSSL_ALL
16339    /* PARSE_ERROR is returned if an HTTP request is detected. */
16340    else if (err == -WC_NO_ERR_TRACE(PARSE_ERROR))
16341        return (WOLFSSL_ERR_LIB_SSL << 24) | -WC_NO_ERR_TRACE(PARSE_ERROR) /* SSL_R_HTTP_REQUEST */;
16342#endif
16343#if defined(OPENSSL_ALL) && defined(WOLFSSL_PYTHON)
16344    else if (err == ASN1_R_HEADER_TOO_LONG)
16345        return (WOLFSSL_ERR_LIB_ASN1 << 24) | -WC_NO_ERR_TRACE(WOLFSSL_ASN1_R_HEADER_TOO_LONG_E);
16346#endif
16347  return err;
16348}
16349#endif
16350
16351#if defined(OPENSSL_EXTRA) || defined(OPENSSL_ALL) || \
16352    defined(WOLFSSL_NGINX) || defined(WOLFSSL_HAPROXY)
16353
16354#if !defined(WOLFSSL_USER_IO)
16355/* converts an IPv6 or IPv4 address into an octet string for use with rfc3280
16356 * example input would be "127.0.0.1" and the returned value would be 7F000001
16357 */
16358WOLFSSL_ASN1_STRING* wolfSSL_a2i_IPADDRESS(const char* ipa)
16359{
16360    int ipaSz = WOLFSSL_IP4_ADDR_LEN;
16361    char buf[WOLFSSL_IP6_ADDR_LEN + 1]; /* plus 1 for terminator */
16362    int  af = WOLFSSL_IP4;
16363    WOLFSSL_ASN1_STRING *ret = NULL;
16364
16365    if (ipa == NULL)
16366        return NULL;
16367
16368    if (XSTRSTR(ipa, ":") != NULL) {
16369        af = WOLFSSL_IP6;
16370        ipaSz = WOLFSSL_IP6_ADDR_LEN;
16371    }
16372
16373    buf[WOLFSSL_IP6_ADDR_LEN] = '\0';
16374#ifdef FREESCALE_MQX
16375    if (XINET_PTON(af, ipa, (void*)buf, sizeof(buf)) != RTCS_OK) {
16376#else
16377    if (XINET_PTON(af, ipa, (void*)buf) != 1) {
16378#endif
16379        WOLFSSL_MSG("Error parsing IP address");
16380        return NULL;
16381    }
16382
16383    ret = wolfSSL_ASN1_STRING_new();
16384    if (ret != NULL) {
16385        if (wolfSSL_ASN1_STRING_set(ret, buf, ipaSz) != WOLFSSL_SUCCESS) {
16386            WOLFSSL_MSG("Error setting the string");
16387            wolfSSL_ASN1_STRING_free(ret);
16388            ret = NULL;
16389        }
16390    }
16391
16392    return ret;
16393}
16394#endif /* !WOLFSSL_USER_IO */
16395
16396/* Is the specified cipher suite a fake one used an an extension proxy? */
16397static WC_INLINE int SCSV_Check(byte suite0, byte suite)
16398{
16399    (void)suite0;
16400    (void)suite;
16401#ifdef HAVE_RENEGOTIATION_INDICATION
16402    if (suite0 == CIPHER_BYTE && suite == TLS_EMPTY_RENEGOTIATION_INFO_SCSV)
16403        return 1;
16404#endif
16405    return 0;
16406}
16407
16408static WC_INLINE int sslCipherMinMaxCheck(const WOLFSSL *ssl, byte suite0,
16409        byte suite)
16410{
16411    const CipherSuiteInfo* cipher_names = GetCipherNames();
16412    int cipherSz = GetCipherNamesSize();
16413    int i;
16414    for (i = 0; i < cipherSz; i++)
16415        if (cipher_names[i].cipherSuite0 == suite0 &&
16416                cipher_names[i].cipherSuite == suite)
16417            break;
16418    if (i == cipherSz)
16419        return 1;
16420    /* Check min version */
16421    if (cipher_names[i].minor < ssl->options.minDowngrade) {
16422        if (ssl->options.minDowngrade <= TLSv1_2_MINOR &&
16423                cipher_names[i].minor >= TLSv1_MINOR)
16424            /* 1.0 ciphersuites are in general available in 1.1 and
16425             * 1.1 ciphersuites are in general available in 1.2 */
16426            return 0;
16427        return 1;
16428    }
16429    /* Check max version */
16430    switch (cipher_names[i].minor) {
16431    case SSLv3_MINOR :
16432        return ssl->options.mask & WOLFSSL_OP_NO_SSLv3;
16433    case TLSv1_MINOR :
16434        return ssl->options.mask & WOLFSSL_OP_NO_TLSv1;
16435    case TLSv1_1_MINOR :
16436        return ssl->options.mask & WOLFSSL_OP_NO_TLSv1_1;
16437    case TLSv1_2_MINOR :
16438        return ssl->options.mask & WOLFSSL_OP_NO_TLSv1_2;
16439    case TLSv1_3_MINOR :
16440        return ssl->options.mask & WOLFSSL_OP_NO_TLSv1_3;
16441    default:
16442        WOLFSSL_MSG("Unrecognized minor version");
16443        return 1;
16444    }
16445}
16446
16447/* returns a pointer to internal cipher suite list. Should not be free'd by
16448 * caller.
16449 */
16450WOLF_STACK_OF(WOLFSSL_CIPHER) *wolfSSL_get_ciphers_compat(const WOLFSSL *ssl)
16451{
16452    const Suites* suites;
16453#if defined(OPENSSL_ALL)
16454    const CipherSuiteInfo* cipher_names = GetCipherNames();
16455    int cipherSz = GetCipherNamesSize();
16456#endif
16457
16458    WOLFSSL_ENTER("wolfSSL_get_ciphers_compat");
16459    if (ssl == NULL)
16460        return NULL;
16461
16462    suites = WOLFSSL_SUITES(ssl);
16463    if (suites == NULL)
16464        return NULL;
16465
16466    /* check if stack needs populated */
16467    if (ssl->suitesStack == NULL) {
16468        int i;
16469
16470        ((WOLFSSL*)ssl)->suitesStack =
16471                wolfssl_sk_new_type_ex(STACK_TYPE_CIPHER, ssl->heap);
16472        if (ssl->suitesStack == NULL)
16473            return NULL;
16474
16475        /* higher priority of cipher suite will be on top of stack */
16476#if defined(OPENSSL_ALL)
16477        for (i = suites->suiteSz - 2; i >=0; i-=2)
16478#else
16479        for (i = 0; i < suites->suiteSz; i+=2)
16480#endif
16481        {
16482            struct WOLFSSL_CIPHER cipher;
16483
16484            /* A couple of suites are placeholders for special options,
16485             * skip those. */
16486            if (SCSV_Check(suites->suites[i], suites->suites[i+1])
16487                    || sslCipherMinMaxCheck(ssl, suites->suites[i],
16488                                            suites->suites[i+1])) {
16489                continue;
16490            }
16491
16492            XMEMSET(&cipher, 0, sizeof(cipher));
16493            cipher.cipherSuite0 = suites->suites[i];
16494            cipher.cipherSuite  = suites->suites[i+1];
16495            cipher.ssl          = ssl;
16496#if defined(OPENSSL_ALL)
16497            cipher.in_stack     = 1;
16498            {
16499                int j;
16500                for (j = 0; j < cipherSz; j++) {
16501                    if (cipher_names[j].cipherSuite0 == cipher.cipherSuite0 &&
16502                            cipher_names[j].cipherSuite == cipher.cipherSuite) {
16503                        cipher.offset = (unsigned long)j;
16504                        break;
16505                    }
16506                }
16507            }
16508#endif
16509            if (wolfSSL_sk_insert(ssl->suitesStack, &cipher, 0) <= 0) {
16510                WOLFSSL_MSG("Error inserting cipher onto stack");
16511                wolfSSL_sk_CIPHER_free(ssl->suitesStack);
16512                ((WOLFSSL*)ssl)->suitesStack = NULL;
16513                break;
16514            }
16515        }
16516
16517        /* If no ciphers were added, free empty stack and return NULL */
16518        if (ssl->suitesStack != NULL && wolfSSL_sk_num(ssl->suitesStack) == 0) {
16519            wolfSSL_sk_CIPHER_free(ssl->suitesStack);
16520            ((WOLFSSL*)ssl)->suitesStack = NULL;
16521        }
16522    }
16523    return ssl->suitesStack;
16524}
16525#endif /* OPENSSL_EXTRA || OPENSSL_ALL || WOLFSSL_NGINX || WOLFSSL_HAPROXY */
16526#ifdef OPENSSL_ALL
16527/* returned pointer is to an internal element in WOLFSSL struct and should not
16528 * be free'd. It gets free'd when the WOLFSSL struct is free'd. */
16529WOLF_STACK_OF(WOLFSSL_CIPHER)*  wolfSSL_get_client_ciphers(WOLFSSL* ssl)
16530{
16531    WOLF_STACK_OF(WOLFSSL_CIPHER)* ret = NULL;
16532    const CipherSuiteInfo* cipher_names = GetCipherNames();
16533    int cipherSz = GetCipherNamesSize();
16534    const Suites* suites;
16535
16536    WOLFSSL_ENTER("wolfSSL_get_client_ciphers");
16537
16538    if (ssl == NULL) {
16539        return NULL;
16540    }
16541
16542    /* return NULL if is client side */
16543    if (wolfSSL_is_server(ssl) == 0) {
16544        return NULL;
16545    }
16546
16547    suites = ssl->clSuites;
16548    if (suites == NULL) {
16549        WOLFSSL_MSG("No client suites stored");
16550    }
16551    else if (ssl->clSuitesStack != NULL) {
16552        ret = ssl->clSuitesStack;
16553    }
16554    else { /* generate cipher suites stack if not already done */
16555        int i;
16556        int j;
16557
16558        ret = wolfSSL_sk_new_node(ssl->heap);
16559        if (ret != NULL) {
16560            ret->type = STACK_TYPE_CIPHER;
16561
16562            /* higher priority of cipher suite will be on top of stack */
16563            for (i = suites->suiteSz - 2; i >= 0; i -= 2) {
16564                WOLFSSL_CIPHER cipher;
16565
16566                /* A couple of suites are placeholders for special options,
16567                 * skip those. */
16568                if (SCSV_Check(suites->suites[i], suites->suites[i+1])
16569                        || sslCipherMinMaxCheck(ssl, suites->suites[i],
16570                                                suites->suites[i+1])) {
16571                    continue;
16572                }
16573
16574                cipher.cipherSuite0 = suites->suites[i];
16575                cipher.cipherSuite  = suites->suites[i+1];
16576                cipher.ssl          = ssl;
16577                for (j = 0; j < cipherSz; j++) {
16578                    if (cipher_names[j].cipherSuite0 ==
16579                            cipher.cipherSuite0 &&
16580                            cipher_names[j].cipherSuite ==
16581                                    cipher.cipherSuite) {
16582                        cipher.offset = (unsigned long)j;
16583                        break;
16584                    }
16585                }
16586
16587                /* in_stack is checked in wolfSSL_CIPHER_description */
16588                cipher.in_stack     = 1;
16589
16590                if (wolfSSL_sk_CIPHER_push(ret, &cipher) <= 0) {
16591                    WOLFSSL_MSG("Error pushing client cipher onto stack");
16592                    wolfSSL_sk_CIPHER_free(ret);
16593                    ret = NULL;
16594                    break;
16595                }
16596            }
16597        }
16598        ssl->clSuitesStack = ret;
16599    }
16600    return ret;
16601}
16602#endif /* OPENSSL_ALL */
16603
16604#if defined(OPENSSL_EXTRA) || defined(HAVE_SECRET_CALLBACK)
16605long wolfSSL_SSL_CTX_get_timeout(const WOLFSSL_CTX *ctx)
16606{
16607    WOLFSSL_ENTER("wolfSSL_SSL_CTX_get_timeout");
16608
16609    if (ctx == NULL)
16610        return 0;
16611
16612    return ctx->timeout;
16613}
16614
16615
16616/* returns the time in seconds of the current timeout */
16617long wolfSSL_get_timeout(WOLFSSL* ssl)
16618{
16619    WOLFSSL_ENTER("wolfSSL_get_timeout");
16620
16621    if (ssl == NULL)
16622        return 0;
16623    return ssl->timeout;
16624}
16625#endif
16626
16627#if defined(OPENSSL_ALL) || defined(WOLFSSL_NGINX) || defined(WOLFSSL_HAPROXY) \
16628    || defined(OPENSSL_EXTRA) || defined(HAVE_LIGHTY)
16629
16630#ifdef HAVE_ECC
16631int wolfSSL_SSL_CTX_set_tmp_ecdh(WOLFSSL_CTX *ctx, WOLFSSL_EC_KEY *ecdh)
16632{
16633    WOLFSSL_ENTER("wolfSSL_SSL_CTX_set_tmp_ecdh");
16634
16635    if (ctx == NULL || ecdh == NULL)
16636        return BAD_FUNC_ARG;
16637
16638    ctx->ecdhCurveOID = (word32)ecdh->group->curve_oid;
16639
16640    return WOLFSSL_SUCCESS;
16641}
16642#endif
16643#ifndef NO_BIO
16644WOLFSSL_BIO *wolfSSL_SSL_get_rbio(const WOLFSSL *s)
16645{
16646    WOLFSSL_ENTER("wolfSSL_SSL_get_rbio");
16647    /* Nginx sets the buffer size if the read BIO is different to write BIO.
16648     * The setting buffer size doesn't do anything so return NULL for both.
16649     */
16650    if (s == NULL)
16651        return NULL;
16652
16653    return s->biord;
16654}
16655WOLFSSL_BIO *wolfSSL_SSL_get_wbio(const WOLFSSL *s)
16656{
16657    WOLFSSL_ENTER("wolfSSL_SSL_get_wbio");
16658    (void)s;
16659    /* Nginx sets the buffer size if the read BIO is different to write BIO.
16660     * The setting buffer size doesn't do anything so return NULL for both.
16661     */
16662    if (s == NULL)
16663        return NULL;
16664
16665    return s->biowr;
16666}
16667#endif /* !NO_BIO */
16668
16669#ifndef NO_TLS
16670int wolfSSL_SSL_do_handshake_internal(WOLFSSL *s)
16671{
16672    WOLFSSL_ENTER("wolfSSL_SSL_do_handshake_internal");
16673    if (s == NULL)
16674        return WOLFSSL_FAILURE;
16675
16676    if (s->options.side == WOLFSSL_CLIENT_END) {
16677    #ifndef NO_WOLFSSL_CLIENT
16678        return wolfSSL_connect(s);
16679    #else
16680        WOLFSSL_MSG("Client not compiled in");
16681        return WOLFSSL_FAILURE;
16682    #endif
16683    }
16684
16685#ifndef NO_WOLFSSL_SERVER
16686    return wolfSSL_accept(s);
16687#else
16688    WOLFSSL_MSG("Server not compiled in");
16689    return WOLFSSL_FAILURE;
16690#endif
16691}
16692
16693int wolfSSL_SSL_do_handshake(WOLFSSL *s)
16694{
16695    WOLFSSL_ENTER("wolfSSL_SSL_do_handshake");
16696#ifdef WOLFSSL_QUIC
16697    if (WOLFSSL_IS_QUIC(s)) {
16698        return wolfSSL_quic_do_handshake(s);
16699    }
16700#endif
16701    return wolfSSL_SSL_do_handshake_internal(s);
16702}
16703#endif /* !NO_TLS */
16704
16705#if defined(OPENSSL_VERSION_NUMBER) && OPENSSL_VERSION_NUMBER >= 0x10100000L
16706int wolfSSL_SSL_in_init(const WOLFSSL *ssl)
16707#else
16708int wolfSSL_SSL_in_init(WOLFSSL *ssl)
16709#endif
16710{
16711    WOLFSSL_ENTER("wolfSSL_SSL_in_init");
16712
16713    return !wolfSSL_is_init_finished(ssl);
16714}
16715
16716int wolfSSL_SSL_in_before(const WOLFSSL *ssl)
16717{
16718    WOLFSSL_ENTER("wolfSSL_SSL_in_before");
16719
16720    if (ssl == NULL)
16721        return WOLFSSL_FAILURE;
16722
16723    return ssl->options.handShakeState == NULL_STATE;
16724}
16725
16726int wolfSSL_SSL_in_connect_init(WOLFSSL* ssl)
16727{
16728    WOLFSSL_ENTER("wolfSSL_SSL_in_connect_init");
16729
16730    if (ssl == NULL)
16731        return WOLFSSL_FAILURE;
16732
16733    if (ssl->options.side == WOLFSSL_CLIENT_END) {
16734        return ssl->options.connectState > CONNECT_BEGIN &&
16735            ssl->options.connectState < SECOND_REPLY_DONE;
16736    }
16737
16738    return ssl->options.acceptState > ACCEPT_BEGIN &&
16739        ssl->options.acceptState < ACCEPT_THIRD_REPLY_DONE;
16740}
16741
16742#if defined(HAVE_SESSION_TICKET) && !defined(NO_WOLFSSL_SERVER)
16743/* Expected return values from implementations of OpenSSL ticket key callback.
16744 */
16745#define TICKET_KEY_CB_RET_FAILURE    (-1)
16746#define TICKET_KEY_CB_RET_NOT_FOUND   0
16747#define TICKET_KEY_CB_RET_OK          1
16748#define TICKET_KEY_CB_RET_RENEW       2
16749
16750/* Implementation of session ticket encryption/decryption using OpenSSL
16751 * callback to initialize the cipher and HMAC.
16752 *
16753 * ssl           The SSL/TLS object.
16754 * keyName       The key name - used to identify the key to be used.
16755 * iv            The IV to use.
16756 * mac           The MAC of the encrypted data.
16757 * enc           Encrypt ticket.
16758 * encTicket     The ticket data.
16759 * encTicketLen  The length of the ticket data.
16760 * encLen        The encrypted/decrypted ticket length - output length.
16761 * ctx           Ignored. Application specific data.
16762 * returns WOLFSSL_TICKET_RET_OK to indicate success,
16763 *         WOLFSSL_TICKET_RET_CREATE if a new ticket is required and
16764 *         WOLFSSL_TICKET_RET_FATAL on error.
16765 */
16766static int wolfSSL_TicketKeyCb(WOLFSSL* ssl,
16767        unsigned char keyName[WOLFSSL_TICKET_NAME_SZ],
16768        unsigned char iv[WOLFSSL_TICKET_IV_SZ],
16769        unsigned char mac[WOLFSSL_TICKET_MAC_SZ],
16770        int enc, unsigned char* encTicket,
16771        int encTicketLen, int* encLen, void* ctx)
16772{
16773    byte                    digest[WC_MAX_DIGEST_SIZE];
16774    WC_DECLARE_VAR(evpCtx, WOLFSSL_EVP_CIPHER_CTX, 1, 0);
16775    WOLFSSL_HMAC_CTX        hmacCtx;
16776    unsigned int            mdSz = 0;
16777    int                     len = 0;
16778    int                     ret = WOLFSSL_TICKET_RET_FATAL;
16779    int                     res;
16780    int                     totalSz = 0;
16781
16782    (void)ctx;
16783
16784    WOLFSSL_ENTER("wolfSSL_TicketKeyCb");
16785
16786    if (ssl == NULL || ssl->ctx == NULL || ssl->ctx->ticketEncWrapCb == NULL) {
16787        WOLFSSL_MSG("Bad parameter");
16788        return WOLFSSL_TICKET_RET_FATAL;
16789    }
16790
16791#ifdef WOLFSSL_SMALL_STACK
16792    evpCtx = (WOLFSSL_EVP_CIPHER_CTX *)XMALLOC(sizeof(*evpCtx), ssl->heap,
16793                                               DYNAMIC_TYPE_TMP_BUFFER);
16794    if (evpCtx == NULL) {
16795        WOLFSSL_MSG("out of memory");
16796        return WOLFSSL_TICKET_RET_FATAL;
16797    }
16798#endif
16799
16800    /* Initialize the cipher and HMAC. */
16801    wolfSSL_EVP_CIPHER_CTX_init(evpCtx);
16802    if (wolfSSL_HMAC_CTX_Init(&hmacCtx) != WOLFSSL_SUCCESS) {
16803        WOLFSSL_MSG("wolfSSL_HMAC_CTX_Init error");
16804        WC_FREE_VAR_EX(evpCtx, ssl->heap, DYNAMIC_TYPE_TMP_BUFFER);
16805        return WOLFSSL_TICKET_RET_FATAL;
16806    }
16807    res = ssl->ctx->ticketEncWrapCb(ssl, keyName,
16808            iv, evpCtx, &hmacCtx, enc);
16809    if (res != TICKET_KEY_CB_RET_OK && res != TICKET_KEY_CB_RET_RENEW) {
16810        WOLFSSL_MSG("Ticket callback error");
16811        ret = WOLFSSL_TICKET_RET_FATAL;
16812        goto end;
16813    }
16814
16815    if (wolfSSL_HMAC_size(&hmacCtx) > WOLFSSL_TICKET_MAC_SZ) {
16816        WOLFSSL_MSG("Ticket cipher MAC size error");
16817        goto end;
16818    }
16819
16820    if (enc)
16821    {
16822        /* Encrypt in place. */
16823        if (!wolfSSL_EVP_CipherUpdate(evpCtx, encTicket, &len,
16824                                      encTicket, encTicketLen))
16825            goto end;
16826        totalSz = len;
16827        if (totalSz > *encLen)
16828            goto end;
16829        if (!wolfSSL_EVP_EncryptFinal(evpCtx, &encTicket[len], &len))
16830            goto end;
16831        /* Total length of encrypted data. */
16832        totalSz += len;
16833        if (totalSz > *encLen)
16834            goto end;
16835
16836        /* HMAC the encrypted data into the parameter 'mac'. */
16837        if (!wolfSSL_HMAC_Update(&hmacCtx, encTicket, totalSz))
16838            goto end;
16839        if (!wolfSSL_HMAC_Final(&hmacCtx, mac, &mdSz))
16840            goto end;
16841    }
16842    else
16843    {
16844        /* HMAC the encrypted data and compare it to the passed in data. */
16845        if (!wolfSSL_HMAC_Update(&hmacCtx, encTicket, encTicketLen))
16846            goto end;
16847        if (!wolfSSL_HMAC_Final(&hmacCtx, digest, &mdSz))
16848            goto end;
16849        if (ConstantCompare(mac, digest, (int)mdSz) != 0)
16850            goto end;
16851
16852        /* Decrypt the ticket data in place. */
16853        if (!wolfSSL_EVP_CipherUpdate(evpCtx, encTicket, &len,
16854                                      encTicket, encTicketLen))
16855            goto end;
16856        totalSz = len;
16857        if (totalSz > encTicketLen)
16858            goto end;
16859        if (!wolfSSL_EVP_DecryptFinal(evpCtx, &encTicket[len], &len))
16860            goto end;
16861        /* Total length of decrypted data. */
16862        totalSz += len;
16863        if (totalSz > encTicketLen)
16864            goto end;
16865    }
16866    *encLen = totalSz;
16867
16868    if (res == TICKET_KEY_CB_RET_RENEW && !IsAtLeastTLSv1_3(ssl->version)
16869            && !enc)
16870        ret = WOLFSSL_TICKET_RET_CREATE;
16871    else
16872        ret = WOLFSSL_TICKET_RET_OK;
16873end:
16874
16875    (void)wc_HmacFree(&hmacCtx.hmac);
16876    (void)wolfSSL_EVP_CIPHER_CTX_cleanup(evpCtx);
16877
16878    WC_FREE_VAR_EX(evpCtx, ssl->heap, DYNAMIC_TYPE_TMP_BUFFER);
16879
16880    return ret;
16881}
16882
16883/* Set the callback to use when encrypting/decrypting tickets.
16884 *
16885 * ctx  The SSL/TLS context object.
16886 * cb   The OpenSSL session ticket callback.
16887 * returns WOLFSSL_SUCCESS to indicate success.
16888 */
16889int wolfSSL_CTX_set_tlsext_ticket_key_cb(WOLFSSL_CTX *ctx, ticketCompatCb cb)
16890{
16891
16892    /* Set the ticket encryption callback to be a wrapper around OpenSSL
16893     * callback.
16894     */
16895    ctx->ticketEncCb = wolfSSL_TicketKeyCb;
16896    ctx->ticketEncWrapCb = cb;
16897
16898    return WOLFSSL_SUCCESS;
16899}
16900
16901#endif /* HAVE_SESSION_TICKET */
16902
16903#endif /* OPENSSL_ALL || WOLFSSL_NGINX || WOLFSSL_HAPROXY ||
16904    OPENSSL_EXTRA || HAVE_LIGHTY */
16905
16906#if defined(HAVE_SESSION_TICKET) && !defined(WOLFSSL_NO_DEF_TICKET_ENC_CB) && \
16907    !defined(NO_WOLFSSL_SERVER)
16908/* Serialize the session ticket encryption keys.
16909 *
16910 * @param [in]  ctx     SSL/TLS context object.
16911 * @param [in]  keys    Buffer to hold session ticket keys.
16912 * @param [in]  keylen  Length of buffer.
16913 * @return  WOLFSSL_SUCCESS on success.
16914 * @return  WOLFSSL_FAILURE when ctx is NULL, keys is NULL or keylen is not the
16915 *          correct length.
16916 */
16917long wolfSSL_CTX_get_tlsext_ticket_keys(WOLFSSL_CTX *ctx,
16918     unsigned char *keys, int keylen)
16919{
16920    if (ctx == NULL || keys == NULL) {
16921        return WOLFSSL_FAILURE;
16922    }
16923    if (keylen != WOLFSSL_TICKET_KEYS_SZ) {
16924        return WOLFSSL_FAILURE;
16925    }
16926
16927    XMEMCPY(keys, ctx->ticketKeyCtx.name, WOLFSSL_TICKET_NAME_SZ);
16928    keys += WOLFSSL_TICKET_NAME_SZ;
16929    XMEMCPY(keys, ctx->ticketKeyCtx.key[0], WOLFSSL_TICKET_KEY_SZ);
16930    keys += WOLFSSL_TICKET_KEY_SZ;
16931    XMEMCPY(keys, ctx->ticketKeyCtx.key[1], WOLFSSL_TICKET_KEY_SZ);
16932    keys += WOLFSSL_TICKET_KEY_SZ;
16933    c32toa(ctx->ticketKeyCtx.expirary[0], keys);
16934    keys += OPAQUE32_LEN;
16935    c32toa(ctx->ticketKeyCtx.expirary[1], keys);
16936
16937    return WOLFSSL_SUCCESS;
16938}
16939
16940/* Deserialize the session ticket encryption keys.
16941 *
16942 * @param [in]  ctx     SSL/TLS context object.
16943 * @param [in]  keys    Session ticket keys.
16944 * @param [in]  keylen  Length of data.
16945 * @return  WOLFSSL_SUCCESS on success.
16946 * @return  WOLFSSL_FAILURE when ctx is NULL, keys is NULL or keylen is not the
16947 *          correct length.
16948 */
16949long wolfSSL_CTX_set_tlsext_ticket_keys(WOLFSSL_CTX *ctx,
16950     const void *keys_vp, int keylen)
16951{
16952    const byte* keys = (const byte*)keys_vp;
16953    if (ctx == NULL || keys == NULL) {
16954        return WOLFSSL_FAILURE;
16955    }
16956    if (keylen != WOLFSSL_TICKET_KEYS_SZ) {
16957        return WOLFSSL_FAILURE;
16958    }
16959
16960    XMEMCPY(ctx->ticketKeyCtx.name, keys, WOLFSSL_TICKET_NAME_SZ);
16961    keys += WOLFSSL_TICKET_NAME_SZ;
16962    XMEMCPY(ctx->ticketKeyCtx.key[0], keys, WOLFSSL_TICKET_KEY_SZ);
16963    keys += WOLFSSL_TICKET_KEY_SZ;
16964    XMEMCPY(ctx->ticketKeyCtx.key[1], keys, WOLFSSL_TICKET_KEY_SZ);
16965    keys += WOLFSSL_TICKET_KEY_SZ;
16966    ato32(keys, &ctx->ticketKeyCtx.expirary[0]);
16967    keys += OPAQUE32_LEN;
16968    ato32(keys, &ctx->ticketKeyCtx.expirary[1]);
16969
16970    return WOLFSSL_SUCCESS;
16971}
16972#endif
16973
16974#if defined(WOLFSSL_NGINX) || defined(WOLFSSL_HAPROXY) || \
16975    defined(OPENSSL_EXTRA) || defined(OPENSSL_ALL)
16976int wolfSSL_CTX_get_extra_chain_certs(WOLFSSL_CTX* ctx,
16977    WOLF_STACK_OF(X509)** chain)
16978{
16979    word32         idx;
16980    word32         length;
16981    WOLFSSL_STACK* node;
16982    WOLFSSL_STACK* last = NULL;
16983
16984    if (ctx == NULL || chain == NULL) {
16985        chain = NULL;
16986        return WOLFSSL_FAILURE;
16987    }
16988    if (ctx->x509Chain != NULL) {
16989        *chain = ctx->x509Chain;
16990        return WOLFSSL_SUCCESS;
16991    }
16992
16993    /* If there are no chains then success! */
16994    *chain = NULL;
16995    if (ctx->certChain == NULL || ctx->certChain->length == 0) {
16996        return WOLFSSL_SUCCESS;
16997    }
16998
16999    /* Create a new stack of WOLFSSL_X509 object from chain buffer. */
17000    for (idx = 0; idx < ctx->certChain->length; ) {
17001        node = wolfSSL_sk_X509_new_null();
17002        if (node == NULL)
17003            return WOLFSSL_FAILURE;
17004        node->next = NULL;
17005
17006        /* 3 byte length | X509 DER data */
17007        ato24(ctx->certChain->buffer + idx, &length);
17008        idx += 3;
17009
17010        /* Create a new X509 from DER encoded data. */
17011        node->data.x509 = wolfSSL_X509_d2i_ex(NULL,
17012            ctx->certChain->buffer + idx, (int)length, ctx->heap);
17013        if (node->data.x509 == NULL) {
17014            XFREE(node, NULL, DYNAMIC_TYPE_OPENSSL);
17015            /* Return as much of the chain as we created. */
17016            ctx->x509Chain = *chain;
17017            return WOLFSSL_FAILURE;
17018        }
17019        idx += length;
17020
17021        /* Add object to the end of the stack. */
17022        if (last == NULL) {
17023            node->num = 1;
17024            *chain = node;
17025        }
17026        else {
17027            (*chain)->num++;
17028            last->next = node;
17029        }
17030
17031        last = node;
17032    }
17033
17034    ctx->x509Chain = *chain;
17035
17036    return WOLFSSL_SUCCESS;
17037}
17038
17039int wolfSSL_CTX_get0_chain_certs(WOLFSSL_CTX *ctx,
17040        WOLF_STACK_OF(WOLFSSL_X509) **sk)
17041{
17042    WOLFSSL_ENTER("wolfSSL_CTX_get0_chain_certs");
17043    if (ctx == NULL || sk == NULL) {
17044        WOLFSSL_MSG("Bad parameter");
17045        return WOLFSSL_FAILURE;
17046    }
17047
17048    /* This function should return ctx->x509Chain if it is populated, otherwise
17049       it should be populated from ctx->certChain.  This matches the behavior of
17050       wolfSSL_CTX_get_extra_chain_certs, so it is used directly. */
17051    return wolfSSL_CTX_get_extra_chain_certs(ctx, sk);
17052}
17053
17054#ifdef KEEP_OUR_CERT
17055int wolfSSL_get0_chain_certs(WOLFSSL *ssl,
17056        WOLF_STACK_OF(WOLFSSL_X509) **sk)
17057{
17058    WOLFSSL_ENTER("wolfSSL_get0_chain_certs");
17059    if (ssl == NULL || sk == NULL) {
17060        WOLFSSL_MSG("Bad parameter");
17061        return WOLFSSL_FAILURE;
17062    }
17063    *sk = ssl->ourCertChain;
17064    return WOLFSSL_SUCCESS;
17065}
17066#endif
17067
17068void wolfSSL_WOLFSSL_STRING_free(WOLFSSL_STRING s)
17069{
17070    WOLFSSL_ENTER("wolfSSL_WOLFSSL_STRING_free");
17071
17072    XFREE(s, NULL, DYNAMIC_TYPE_OPENSSL);
17073}
17074
17075#endif /* WOLFSSL_NGINX || WOLFSSL_HAPROXY || OPENSSL_EXTRA || OPENSSL_ALL */
17076
17077#if defined(OPENSSL_ALL) || defined(WOLFSSL_NGINX) || \
17078    defined(WOLFSSL_HAPROXY) || defined(HAVE_LIGHTY) || \
17079    defined(WOLFSSL_QUIC)
17080#ifdef HAVE_ALPN
17081void wolfSSL_get0_alpn_selected(const WOLFSSL *ssl, const unsigned char **data,
17082                                unsigned int *len)
17083{
17084    word16 nameLen = 0;
17085
17086    if (ssl != NULL && data != NULL && len != NULL) {
17087        TLSX_ALPN_GetRequest(ssl->extensions, (void **)data, &nameLen);
17088        *len = nameLen;
17089    }
17090}
17091
17092int wolfSSL_select_next_proto(unsigned char **out, unsigned char *outLen,
17093                              const unsigned char *in, unsigned int inLen,
17094                              const unsigned char *clientNames,
17095                              unsigned int clientLen)
17096{
17097    unsigned int i, j;
17098    byte lenIn, lenClient;
17099
17100    if (out == NULL || outLen == NULL || in == NULL || clientNames == NULL)
17101        return WOLFSSL_NPN_UNSUPPORTED;
17102
17103    for (i = 0; i < inLen; i += lenIn) {
17104        lenIn = in[i++];
17105        if (lenIn == 0 || i + lenIn > inLen)
17106            break;
17107        for (j = 0; j < clientLen; j += lenClient) {
17108            lenClient = clientNames[j++];
17109            if (lenClient == 0 || j + lenClient > clientLen)
17110                break;
17111
17112            if (lenIn != lenClient)
17113                continue;
17114
17115            if (XMEMCMP(in + i, clientNames + j, lenIn) == 0) {
17116                *out = (unsigned char *)(in + i);
17117                *outLen = lenIn;
17118                return WOLFSSL_NPN_NEGOTIATED;
17119            }
17120        }
17121    }
17122
17123    if (clientLen > 0 && (unsigned int)clientNames[0] + 1 <= clientLen) {
17124        *out = (unsigned char *)clientNames + 1;
17125        *outLen = clientNames[0];
17126    }
17127    else {
17128        *out = (unsigned char *)clientNames;
17129        *outLen = 0;
17130    }
17131    return WOLFSSL_NPN_NO_OVERLAP;
17132}
17133
17134void wolfSSL_set_alpn_select_cb(WOLFSSL *ssl,
17135                                int (*cb) (WOLFSSL *ssl,
17136                                           const unsigned char **out,
17137                                           unsigned char *outlen,
17138                                           const unsigned char *in,
17139                                           unsigned int inlen,
17140                                           void *arg), void *arg)
17141{
17142    if (ssl != NULL) {
17143        ssl->alpnSelect = cb;
17144        ssl->alpnSelectArg = arg;
17145    }
17146}
17147
17148void wolfSSL_CTX_set_alpn_select_cb(WOLFSSL_CTX *ctx,
17149                                    int (*cb) (WOLFSSL *ssl,
17150                                               const unsigned char **out,
17151                                               unsigned char *outlen,
17152                                               const unsigned char *in,
17153                                               unsigned int inlen,
17154                                               void *arg), void *arg)
17155{
17156    if (ctx != NULL) {
17157        ctx->alpnSelect = cb;
17158        ctx->alpnSelectArg = arg;
17159    }
17160}
17161
17162void wolfSSL_CTX_set_next_protos_advertised_cb(WOLFSSL_CTX *s,
17163                                           int (*cb) (WOLFSSL *ssl,
17164                                                      const unsigned char
17165                                                      **out,
17166                                                      unsigned int *outlen,
17167                                                      void *arg), void *arg)
17168{
17169    (void)s;
17170    (void)cb;
17171    (void)arg;
17172    WOLFSSL_STUB("wolfSSL_CTX_set_next_protos_advertised_cb");
17173}
17174
17175void wolfSSL_CTX_set_next_proto_select_cb(WOLFSSL_CTX *s,
17176                                      int (*cb) (WOLFSSL *ssl,
17177                                                 unsigned char **out,
17178                                                 unsigned char *outlen,
17179                                                 const unsigned char *in,
17180                                                 unsigned int inlen,
17181                                                 void *arg), void *arg)
17182{
17183    (void)s;
17184    (void)cb;
17185    (void)arg;
17186    WOLFSSL_STUB("wolfSSL_CTX_set_next_proto_select_cb");
17187}
17188
17189void wolfSSL_get0_next_proto_negotiated(const WOLFSSL *s,
17190    const unsigned char **data, unsigned *len)
17191{
17192    (void)s;
17193    (void)data;
17194    (void)len;
17195    WOLFSSL_STUB("wolfSSL_get0_next_proto_negotiated");
17196}
17197#endif /* HAVE_ALPN */
17198
17199#endif /* WOLFSSL_NGINX  / WOLFSSL_HAPROXY */
17200
17201#if defined(OPENSSL_EXTRA) || defined(HAVE_CURL)
17202int wolfSSL_curve_is_disabled(const WOLFSSL* ssl, word16 curve_id)
17203{
17204    int ret = 0;
17205
17206    WOLFSSL_ENTER("wolfSSL_curve_is_disabled");
17207    WOLFSSL_MSG_EX("wolfSSL_curve_is_disabled checking for %d", curve_id);
17208
17209    /* (curve_id >= WOLFSSL_FFDHE_START) - DH parameters are never disabled. */
17210    if (curve_id < WOLFSSL_FFDHE_START) {
17211        if (curve_id > WOLFSSL_ECC_MAX_AVAIL) {
17212            WOLFSSL_MSG("Curve id out of supported range");
17213            /* Disabled if not in valid range. */
17214            ret = 1;
17215        }
17216        else if (curve_id >= 32) {
17217            /* 0 is for invalid and 1-14 aren't used otherwise. */
17218            ret = (ssl->disabledCurves & (1U << (curve_id - 32))) != 0;
17219        }
17220        else {
17221            ret = (ssl->disabledCurves & (1U << curve_id)) != 0;
17222        }
17223    }
17224
17225    WOLFSSL_LEAVE("wolfSSL_curve_is_disabled", ret);
17226    return ret;
17227}
17228
17229#if (defined(HAVE_ECC) || \
17230    defined(HAVE_CURVE25519) || defined(HAVE_CURVE448))
17231#define CURVE_NAME(c) XSTR_SIZEOF((c)), (c)
17232
17233const WOLF_EC_NIST_NAME kNistCurves[] = {
17234#ifdef HAVE_ECC
17235    {CURVE_NAME("P-160"),   WC_NID_secp160r1, WOLFSSL_ECC_SECP160R1},
17236    {CURVE_NAME("P-160-2"), WC_NID_secp160r2, WOLFSSL_ECC_SECP160R2},
17237    {CURVE_NAME("P-192"),   WC_NID_X9_62_prime192v1, WOLFSSL_ECC_SECP192R1},
17238    {CURVE_NAME("P-224"),   WC_NID_secp224r1, WOLFSSL_ECC_SECP224R1},
17239    {CURVE_NAME("P-256"),   WC_NID_X9_62_prime256v1, WOLFSSL_ECC_SECP256R1},
17240    {CURVE_NAME("P-384"),   WC_NID_secp384r1, WOLFSSL_ECC_SECP384R1},
17241    {CURVE_NAME("P-521"),   WC_NID_secp521r1, WOLFSSL_ECC_SECP521R1},
17242    {CURVE_NAME("K-160"),   WC_NID_secp160k1, WOLFSSL_ECC_SECP160K1},
17243    {CURVE_NAME("K-192"),   WC_NID_secp192k1, WOLFSSL_ECC_SECP192K1},
17244    {CURVE_NAME("K-224"),   WC_NID_secp224k1, WOLFSSL_ECC_SECP224K1},
17245    {CURVE_NAME("K-256"),   WC_NID_secp256k1, WOLFSSL_ECC_SECP256K1},
17246    {CURVE_NAME("B-256"),   WC_NID_brainpoolP256r1,
17247     WOLFSSL_ECC_BRAINPOOLP256R1},
17248    {CURVE_NAME("B-384"),   WC_NID_brainpoolP384r1,
17249     WOLFSSL_ECC_BRAINPOOLP384R1},
17250    {CURVE_NAME("B-512"),   WC_NID_brainpoolP512r1,
17251     WOLFSSL_ECC_BRAINPOOLP512R1},
17252#endif
17253#ifdef HAVE_CURVE25519
17254    {CURVE_NAME("X25519"),  WC_NID_X25519, WOLFSSL_ECC_X25519},
17255#endif
17256#ifdef HAVE_CURVE448
17257    {CURVE_NAME("X448"),    WC_NID_X448, WOLFSSL_ECC_X448},
17258#endif
17259#ifdef WOLFSSL_HAVE_MLKEM
17260#ifndef WOLFSSL_NO_ML_KEM
17261    {CURVE_NAME("ML_KEM_512"), WOLFSSL_ML_KEM_512, WOLFSSL_ML_KEM_512},
17262    {CURVE_NAME("ML_KEM_768"), WOLFSSL_ML_KEM_768, WOLFSSL_ML_KEM_768},
17263    {CURVE_NAME("ML_KEM_1024"), WOLFSSL_ML_KEM_1024, WOLFSSL_ML_KEM_1024},
17264#if defined(HAVE_ECC)
17265    #ifdef WOLFSSL_PQC_HYBRIDS
17266    {CURVE_NAME("SecP256r1MLKEM768"), WOLFSSL_SECP256R1MLKEM768,
17267     WOLFSSL_SECP256R1MLKEM768},
17268    {CURVE_NAME("SecP384r1MLKEM1024"), WOLFSSL_SECP384R1MLKEM1024,
17269     WOLFSSL_SECP384R1MLKEM1024},
17270    {CURVE_NAME("X25519MLKEM768"), WOLFSSL_X25519MLKEM768,
17271     WOLFSSL_X25519MLKEM768},
17272    #endif /* WOLFSSL_PQC_HYBRIDS */
17273    #ifdef WOLFSSL_EXTRA_PQC_HYBRIDS
17274    {CURVE_NAME("SecP256r1MLKEM512"), WOLFSSL_SECP256R1MLKEM512,
17275     WOLFSSL_SECP256R1MLKEM512},
17276    {CURVE_NAME("SecP384r1MLKEM768"), WOLFSSL_SECP384R1MLKEM768,
17277     WOLFSSL_SECP384R1MLKEM768},
17278    {CURVE_NAME("SecP521r1MLKEM1024"), WOLFSSL_SECP521R1MLKEM1024,
17279     WOLFSSL_SECP521R1MLKEM1024},
17280    {CURVE_NAME("X25519MLKEM512"), WOLFSSL_X25519MLKEM512,
17281     WOLFSSL_X25519MLKEM512},
17282    {CURVE_NAME("X448MLKEM768"), WOLFSSL_X448MLKEM768,
17283     WOLFSSL_X448MLKEM768},
17284    #endif /* WOLFSSL_EXTRA_PQC_HYBRIDS */
17285#endif
17286#endif /* !WOLFSSL_NO_ML_KEM */
17287#ifdef WOLFSSL_MLKEM_KYBER
17288    {CURVE_NAME("KYBER_LEVEL1"), WOLFSSL_KYBER_LEVEL1, WOLFSSL_KYBER_LEVEL1},
17289    {CURVE_NAME("KYBER_LEVEL3"), WOLFSSL_KYBER_LEVEL3, WOLFSSL_KYBER_LEVEL3},
17290    {CURVE_NAME("KYBER_LEVEL5"), WOLFSSL_KYBER_LEVEL5, WOLFSSL_KYBER_LEVEL5},
17291#if defined(HAVE_ECC)
17292    {CURVE_NAME("P256_KYBER_LEVEL1"), WOLFSSL_P256_KYBER_LEVEL1,
17293     WOLFSSL_P256_KYBER_LEVEL1},
17294    {CURVE_NAME("P384_KYBER_LEVEL3"), WOLFSSL_P384_KYBER_LEVEL3,
17295     WOLFSSL_P384_KYBER_LEVEL3},
17296    {CURVE_NAME("P256_KYBER_LEVEL3"), WOLFSSL_P256_KYBER_LEVEL3,
17297     WOLFSSL_P256_KYBER_LEVEL3},
17298    {CURVE_NAME("P521_KYBER_LEVEL5"), WOLFSSL_P521_KYBER_LEVEL5,
17299     WOLFSSL_P521_KYBER_LEVEL5},
17300    {CURVE_NAME("X25519_KYBER_LEVEL1"), WOLFSSL_X25519_KYBER_LEVEL1,
17301     WOLFSSL_X25519_KYBER_LEVEL1},
17302    {CURVE_NAME("X448_KYBER_LEVEL3"), WOLFSSL_X448_KYBER_LEVEL3,
17303     WOLFSSL_X448_KYBER_LEVEL3},
17304    {CURVE_NAME("X25519_KYBER_LEVEL3"), WOLFSSL_X25519_KYBER_LEVEL3,
17305     WOLFSSL_X25519_KYBER_LEVEL3},
17306#endif
17307#endif /* WOLFSSL_MLKEM_KYBER */
17308#endif /* WOLFSSL_HAVE_MLKEM */
17309#ifdef WOLFSSL_SM2
17310    {CURVE_NAME("SM2"),     WC_NID_sm2, WOLFSSL_ECC_SM2P256V1},
17311#endif
17312#ifdef HAVE_ECC
17313    /* Alternative curve names */
17314    {CURVE_NAME("prime256v1"), WC_NID_X9_62_prime256v1, WOLFSSL_ECC_SECP256R1},
17315    {CURVE_NAME("secp256r1"),  WC_NID_X9_62_prime256v1, WOLFSSL_ECC_SECP256R1},
17316    {CURVE_NAME("secp384r1"),  WC_NID_secp384r1, WOLFSSL_ECC_SECP384R1},
17317    {CURVE_NAME("secp521r1"),  WC_NID_secp521r1, WOLFSSL_ECC_SECP521R1},
17318#endif
17319#ifdef WOLFSSL_SM2
17320    {CURVE_NAME("sm2p256v1"),  WC_NID_sm2, WOLFSSL_ECC_SM2P256V1},
17321#endif
17322    {0, NULL, 0, 0},
17323};
17324
17325int set_curves_list(WOLFSSL* ssl, WOLFSSL_CTX *ctx, const char* names,
17326        byte curves_only)
17327{
17328    int idx, start = 0, len, i, ret = WOLFSSL_FAILURE;
17329    word16 curve;
17330    word32 disabled;
17331    char name[MAX_CURVE_NAME_SZ];
17332    byte groups_len = 0;
17333#ifdef WOLFSSL_SMALL_STACK
17334    void *heap = ssl? ssl->heap : ctx ? ctx->heap : NULL;
17335    int *groups;
17336#else
17337    int groups[WOLFSSL_MAX_GROUP_COUNT];
17338#endif
17339    const WOLF_EC_NIST_NAME* nist_name;
17340
17341    WC_ALLOC_VAR_EX(groups, int, WOLFSSL_MAX_GROUP_COUNT, heap,
17342        DYNAMIC_TYPE_TMP_BUFFER,
17343    {
17344        ret=MEMORY_E;
17345        goto leave;
17346    });
17347
17348    for (idx = 1; names[idx-1] != '\0'; idx++) {
17349        if (names[idx] != ':' && names[idx] != '\0')
17350            continue;
17351
17352        len = idx - start;
17353        if (len > MAX_CURVE_NAME_SZ - 1)
17354            goto leave;
17355
17356        XMEMCPY(name, names + start, (size_t)len);
17357        name[len] = 0;
17358        curve = WOLFSSL_NAMED_GROUP_INVALID;
17359
17360        for (nist_name = kNistCurves; nist_name->name != NULL; nist_name++) {
17361            if (len == nist_name->name_len &&
17362                    XSTRNCMP(name, nist_name->name, (size_t)len) == 0) {
17363                curve = nist_name->curve;
17364                break;
17365            }
17366        }
17367
17368        if (curve == WOLFSSL_NAMED_GROUP_INVALID) {
17369        #if !defined(HAVE_FIPS) && !defined(HAVE_SELFTEST) && defined(HAVE_ECC)
17370            int   nret;
17371            const ecc_set_type *eccSet;
17372
17373            nret = wc_ecc_get_curve_idx_from_name(name);
17374            if (nret < 0) {
17375                WOLFSSL_MSG("Could not find name in set");
17376                goto leave;
17377            }
17378
17379            eccSet = wc_ecc_get_curve_params(nret);
17380            if (eccSet == NULL) {
17381                WOLFSSL_MSG("NULL set returned");
17382                goto leave;
17383            }
17384
17385            curve = GetCurveByOID((int)eccSet->oidSum);
17386        #else
17387            WOLFSSL_MSG("API not present to search farther using name");
17388            goto leave;
17389        #endif
17390        }
17391
17392        if ((curves_only && curve >= WOLFSSL_ECC_MAX_AVAIL) ||
17393                curve == WOLFSSL_NAMED_GROUP_INVALID) {
17394            WOLFSSL_MSG("curve value is not supported");
17395            goto leave;
17396        }
17397
17398        for (i = 0; i < groups_len; ++i) {
17399            if (groups[i] == curve) {
17400                /* silently drop duplicates */
17401                break;
17402            }
17403        }
17404        if (i >= groups_len) {
17405            if (groups_len >= WOLFSSL_MAX_GROUP_COUNT) {
17406                WOLFSSL_MSG_EX("setting %d or more supported "
17407                               "curves is not permitted", groups_len);
17408                goto leave;
17409            }
17410            groups[groups_len++] = (int)curve;
17411        }
17412
17413        start = idx + 1;
17414    }
17415
17416    /* Disable all curves so that only the ones the user wants are enabled. */
17417    disabled = 0xFFFFFFFFUL;
17418    for (i = 0; i < groups_len; ++i) {
17419        /* Switch the bit to off and therefore is enabled. */
17420        curve = (word16)groups[i];
17421        if (curve >= 64) {
17422            WC_DO_NOTHING;
17423        }
17424        else if (curve >= 32) {
17425            /* 0 is for invalid and 1-14 aren't used otherwise. */
17426            disabled &= ~(1U << (curve - 32));
17427        }
17428        else {
17429            disabled &= ~(1U << curve);
17430        }
17431    #if defined(HAVE_SUPPORTED_CURVES) && !defined(NO_TLS)
17432    #if !defined(WOLFSSL_OLD_SET_CURVES_LIST)
17433        /* using the wolfSSL API to set the groups, this will populate
17434         * (ssl|ctx)->groups and reset any TLSX_SUPPORTED_GROUPS.
17435         * The order in (ssl|ctx)->groups will then be respected
17436         * when TLSX_KEY_SHARE needs to be established */
17437        if ((ssl && wolfSSL_set_groups(ssl, groups, groups_len)
17438                        != WOLFSSL_SUCCESS)
17439            || (ctx && wolfSSL_CTX_set_groups(ctx, groups, groups_len)
17440                           != WOLFSSL_SUCCESS)) {
17441            WOLFSSL_MSG("Unable to set supported curve");
17442            goto leave;
17443        }
17444    #elif !defined(NO_WOLFSSL_CLIENT)
17445        /* set the supported curve so client TLS extension contains only the
17446         * desired curves */
17447        if ((ssl && wolfSSL_UseSupportedCurve(ssl, curve) != WOLFSSL_SUCCESS)
17448            || (ctx && wolfSSL_CTX_UseSupportedCurve(ctx, curve)
17449                           != WOLFSSL_SUCCESS)) {
17450            WOLFSSL_MSG("Unable to set supported curve");
17451            goto leave;
17452        }
17453    #endif
17454    #endif /* HAVE_SUPPORTED_CURVES && !NO_TLS */
17455    }
17456
17457    if (ssl != NULL)
17458        ssl->disabledCurves = disabled;
17459    else if (ctx != NULL)
17460        ctx->disabledCurves = disabled;
17461    ret = WOLFSSL_SUCCESS;
17462
17463leave:
17464#ifdef WOLFSSL_SMALL_STACK
17465    if (groups)
17466        XFREE((void*)groups, heap, DYNAMIC_TYPE_TMP_BUFFER);
17467#endif
17468    return ret;
17469}
17470
17471int wolfSSL_CTX_set1_curves_list(WOLFSSL_CTX* ctx, const char* names)
17472{
17473    WOLFSSL_ENTER("wolfSSL_CTX_set1_curves_list");
17474    if (ctx == NULL || names == NULL) {
17475        WOLFSSL_MSG("ctx or names was NULL");
17476        return WOLFSSL_FAILURE;
17477    }
17478    return set_curves_list(NULL, ctx, names, 1);
17479}
17480
17481int wolfSSL_set1_curves_list(WOLFSSL* ssl, const char* names)
17482{
17483    WOLFSSL_ENTER("wolfSSL_set1_curves_list");
17484    if (ssl == NULL || names == NULL) {
17485        WOLFSSL_MSG("ssl or names was NULL");
17486        return WOLFSSL_FAILURE;
17487    }
17488    return set_curves_list(ssl, NULL, names, 1);
17489}
17490#endif /* (HAVE_ECC || HAVE_CURVE25519 || HAVE_CURVE448) */
17491#endif /* OPENSSL_EXTRA || HAVE_CURL */
17492
17493
17494#ifdef OPENSSL_EXTRA
17495/* Sets a callback for when sending and receiving protocol messages.
17496 * This callback is copied to all WOLFSSL objects created from the ctx.
17497 *
17498 * ctx WOLFSSL_CTX structure to set callback in
17499 * cb  callback to use
17500 *
17501 * return WOLFSSL_SUCCESS on success and WOLFSSL_FAILURE with error case
17502 */
17503int wolfSSL_CTX_set_msg_callback(WOLFSSL_CTX *ctx, SSL_Msg_Cb cb)
17504{
17505    WOLFSSL_ENTER("wolfSSL_CTX_set_msg_callback");
17506    if (ctx == NULL) {
17507        WOLFSSL_MSG("Null ctx passed in");
17508        return WOLFSSL_FAILURE;
17509    }
17510
17511    ctx->protoMsgCb = cb;
17512    return WOLFSSL_SUCCESS;
17513}
17514
17515
17516/* Sets a callback for when sending and receiving protocol messages.
17517 *
17518 * ssl WOLFSSL structure to set callback in
17519 * cb  callback to use
17520 *
17521 * return WOLFSSL_SUCCESS on success and WOLFSSL_FAILURE with error case
17522 */
17523int wolfSSL_set_msg_callback(WOLFSSL *ssl, SSL_Msg_Cb cb)
17524{
17525    WOLFSSL_ENTER("wolfSSL_set_msg_callback");
17526
17527    if (ssl == NULL) {
17528        return WOLFSSL_FAILURE;
17529    }
17530
17531    if (cb != NULL) {
17532        ssl->toInfoOn = 1;
17533    }
17534
17535    ssl->protoMsgCb = cb;
17536    return WOLFSSL_SUCCESS;
17537}
17538
17539
17540/* set the user argument to pass to the msg callback when called
17541 * return WOLFSSL_SUCCESS on success */
17542int wolfSSL_CTX_set_msg_callback_arg(WOLFSSL_CTX *ctx, void* arg)
17543{
17544    WOLFSSL_ENTER("wolfSSL_CTX_set_msg_callback_arg");
17545    if (ctx == NULL) {
17546        WOLFSSL_MSG("Null WOLFSSL_CTX passed in");
17547        return WOLFSSL_FAILURE;
17548    }
17549
17550    ctx->protoMsgCtx = arg;
17551    return WOLFSSL_SUCCESS;
17552}
17553
17554
17555int wolfSSL_set_msg_callback_arg(WOLFSSL *ssl, void* arg)
17556{
17557    WOLFSSL_ENTER("wolfSSL_set_msg_callback_arg");
17558    if (ssl == NULL)
17559        return WOLFSSL_FAILURE;
17560
17561    ssl->protoMsgCtx = arg;
17562    return WOLFSSL_SUCCESS;
17563}
17564
17565void *wolfSSL_OPENSSL_memdup(const void *data, size_t siz, const char* file,
17566    int line)
17567{
17568    void *ret;
17569    (void)file;
17570    (void)line;
17571
17572    if (data == NULL || siz >= INT_MAX)
17573        return NULL;
17574
17575    ret = wolfSSL_OPENSSL_malloc(siz);
17576    if (ret == NULL) {
17577        return NULL;
17578    }
17579    return XMEMCPY(ret, data, siz);
17580}
17581
17582void wolfSSL_OPENSSL_cleanse(void *ptr, size_t len)
17583{
17584    if (ptr)
17585        ForceZero(ptr, (word32)len);
17586}
17587
17588int wolfSSL_CTX_set_alpn_protos(WOLFSSL_CTX *ctx, const unsigned char *p,
17589                            unsigned int p_len)
17590{
17591    WOLFSSL_ENTER("wolfSSL_CTX_set_alpn_protos");
17592    if (ctx == NULL || p == NULL)
17593        return BAD_FUNC_ARG;
17594    if (ctx->alpn_cli_protos != NULL) {
17595        XFREE((void*)ctx->alpn_cli_protos, ctx->heap, DYNAMIC_TYPE_OPENSSL);
17596    }
17597
17598    ctx->alpn_cli_protos = (const unsigned char*)XMALLOC(p_len,
17599        ctx->heap, DYNAMIC_TYPE_OPENSSL);
17600    if (ctx->alpn_cli_protos == NULL) {
17601#if defined(WOLFSSL_ERROR_CODE_OPENSSL)
17602        /* 0 on success in OpenSSL, non-0 on failure in OpenSSL
17603         * the function reverses the return value convention.
17604         */
17605        return 1;
17606#else
17607        return WOLFSSL_FAILURE;
17608#endif
17609    }
17610    XMEMCPY((void*)ctx->alpn_cli_protos, p, p_len);
17611    ctx->alpn_cli_protos_len = p_len;
17612
17613#if defined(WOLFSSL_ERROR_CODE_OPENSSL)
17614    /* 0 on success in OpenSSL, non-0 on failure in OpenSSL
17615     * the function reverses the return value convention.
17616     */
17617    return 0;
17618#else
17619    return WOLFSSL_SUCCESS;
17620#endif
17621}
17622
17623
17624#ifdef HAVE_ALPN
17625#ifndef NO_BIO
17626/* Sets the ALPN extension protos
17627 *
17628 * example format is
17629 * unsigned char p[] = {
17630 *      8, 'h', 't', 't', 'p', '/', '1', '.', '1'
17631 * };
17632 *
17633 * returns WOLFSSL_SUCCESS on success */
17634int wolfSSL_set_alpn_protos(WOLFSSL* ssl,
17635        const unsigned char* p, unsigned int p_len)
17636{
17637    char* pt = NULL;
17638    unsigned int ptIdx;
17639    unsigned int sz;
17640    unsigned int idx = 0;
17641    /* RFC 7301: a server that does not select any of the client's offered
17642     * protocols MUST send no_application_protocol. Match that contract on
17643     * the OpenSSL-compat surface rather than silently continuing. */
17644    int alpn_opt = WOLFSSL_ALPN_FAILED_ON_MISMATCH;
17645    int ret;
17646
17647    WOLFSSL_ENTER("wolfSSL_set_alpn_protos");
17648
17649    if (ssl == NULL || p_len <= 1 || p == NULL) {
17650#if defined(WOLFSSL_ERROR_CODE_OPENSSL)
17651        /* 0 on success in OpenSSL, non-0 on failure in OpenSSL
17652         * the function reverses the return value convention.
17653         */
17654        return 1;
17655#else
17656        return WOLFSSL_FAILURE;
17657#endif
17658    }
17659
17660    /* Replacing leading number with trailing ',' and adding '\0'. */
17661    pt = (char*)XMALLOC(p_len + 1, ssl->heap, DYNAMIC_TYPE_OPENSSL);
17662    if (pt == NULL) {
17663#if defined(WOLFSSL_ERROR_CODE_OPENSSL)
17664        /* 0 on success in OpenSSL, non-0 on failure in OpenSSL
17665         * the function reverses the return value convention.
17666         */
17667        return 1;
17668#else
17669        return WOLFSSL_FAILURE;
17670#endif
17671    }
17672
17673    ptIdx = 0;
17674    /* convert into comma separated list */
17675    while (idx < p_len - 1) {
17676        unsigned int i;
17677
17678        sz = p[idx++];
17679        if (idx + sz > p_len) {
17680            WOLFSSL_MSG("Bad list format");
17681            XFREE(pt, ssl->heap, DYNAMIC_TYPE_OPENSSL);
17682    #if defined(WOLFSSL_ERROR_CODE_OPENSSL)
17683            /* 0 on success in OpenSSL, non-0 on failure in OpenSSL
17684             * the function reverses the return value convention.
17685             */
17686            return 1;
17687    #else
17688            return WOLFSSL_FAILURE;
17689    #endif
17690        }
17691        if (sz > 0) {
17692            for (i = 0; i < sz; i++) {
17693                pt[ptIdx++] = p[idx++];
17694            }
17695            if (idx < p_len - 1) {
17696                pt[ptIdx++] = ',';
17697            }
17698        }
17699    }
17700    pt[ptIdx++] = '\0';
17701
17702    /* clears out all current ALPN extensions set */
17703    TLSX_Remove(&ssl->extensions, TLSX_APPLICATION_LAYER_PROTOCOL, ssl->heap);
17704
17705    ret = wolfSSL_UseALPN(ssl, pt, ptIdx, (byte)alpn_opt);
17706    XFREE(pt, ssl->heap, DYNAMIC_TYPE_OPENSSL);
17707#if defined(WOLFSSL_ERROR_CODE_OPENSSL)
17708    /* 0 on success in OpenSSL, non-0 on failure in OpenSSL
17709     * the function reverses the return value convention.
17710     */
17711    if (ret != WOLFSSL_SUCCESS)
17712        return 1;
17713    return 0;
17714#else
17715    if (ret != WOLFSSL_SUCCESS)
17716        return WOLFSSL_FAILURE;
17717    return WOLFSSL_SUCCESS;
17718#endif
17719}
17720#endif /* !NO_BIO */
17721#endif /* HAVE_ALPN */
17722#endif /* OPENSSL_EXTRA */
17723
17724#if defined(OPENSSL_EXTRA)
17725
17726#ifndef NO_BIO
17727#define WOLFSSL_BIO_INCLUDED
17728#include "src/bio.c"
17729#endif
17730
17731#endif /* OPENSSL_EXTRA */
17732
17733#if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)
17734
17735word32 nid2oid(int nid, int grp)
17736{
17737    /* get OID type */
17738    switch (grp) {
17739        /* oidHashType */
17740        case oidHashType:
17741            switch (nid) {
17742            #ifdef WOLFSSL_MD2
17743                case WC_NID_md2:
17744                    return MD2h;
17745            #endif
17746            #ifndef NO_MD5
17747                case WC_NID_md5:
17748                    return MD5h;
17749            #endif
17750            #ifndef NO_SHA
17751                case WC_NID_sha1:
17752                    return SHAh;
17753            #endif
17754                case WC_NID_sha224:
17755                    return SHA224h;
17756            #ifndef NO_SHA256
17757                case WC_NID_sha256:
17758                    return SHA256h;
17759            #endif
17760            #ifdef WOLFSSL_SHA384
17761                case WC_NID_sha384:
17762                    return SHA384h;
17763            #endif
17764            #ifdef WOLFSSL_SHA512
17765                case WC_NID_sha512:
17766                    return SHA512h;
17767            #endif
17768            #ifndef WOLFSSL_NOSHA3_224
17769                case WC_NID_sha3_224:
17770                    return SHA3_224h;
17771            #endif
17772            #ifndef WOLFSSL_NOSHA3_256
17773                case WC_NID_sha3_256:
17774                    return SHA3_256h;
17775            #endif
17776            #ifndef WOLFSSL_NOSHA3_384
17777                case WC_NID_sha3_384:
17778                    return SHA3_384h;
17779            #endif
17780            #ifndef WOLFSSL_NOSHA3_512
17781                case WC_NID_sha3_512:
17782                    return SHA3_512h;
17783            #endif
17784            }
17785            break;
17786
17787        /*  oidSigType */
17788        case oidSigType:
17789            switch (nid) {
17790            #ifndef NO_DSA
17791                case WC_NID_dsaWithSHA1:
17792                    return CTC_SHAwDSA;
17793                case WC_NID_dsa_with_SHA256:
17794                    return CTC_SHA256wDSA;
17795            #endif /* NO_DSA */
17796            #ifndef NO_RSA
17797                case WC_NID_md2WithRSAEncryption:
17798                    return CTC_MD2wRSA;
17799                case WC_NID_md5WithRSAEncryption:
17800                    return CTC_MD5wRSA;
17801                case WC_NID_sha1WithRSAEncryption:
17802                    return CTC_SHAwRSA;
17803                case WC_NID_sha224WithRSAEncryption:
17804                    return CTC_SHA224wRSA;
17805                case WC_NID_sha256WithRSAEncryption:
17806                    return CTC_SHA256wRSA;
17807                case WC_NID_sha384WithRSAEncryption:
17808                    return CTC_SHA384wRSA;
17809                case WC_NID_sha512WithRSAEncryption:
17810                    return CTC_SHA512wRSA;
17811                #ifdef WOLFSSL_SHA3
17812                case WC_NID_RSA_SHA3_224:
17813                    return CTC_SHA3_224wRSA;
17814                case WC_NID_RSA_SHA3_256:
17815                    return CTC_SHA3_256wRSA;
17816                case WC_NID_RSA_SHA3_384:
17817                    return CTC_SHA3_384wRSA;
17818                case WC_NID_RSA_SHA3_512:
17819                    return CTC_SHA3_512wRSA;
17820                #endif
17821            #endif /* NO_RSA */
17822            #ifdef HAVE_ECC
17823                case WC_NID_ecdsa_with_SHA1:
17824                    return CTC_SHAwECDSA;
17825                case WC_NID_ecdsa_with_SHA224:
17826                    return CTC_SHA224wECDSA;
17827                case WC_NID_ecdsa_with_SHA256:
17828                    return CTC_SHA256wECDSA;
17829                case WC_NID_ecdsa_with_SHA384:
17830                    return CTC_SHA384wECDSA;
17831                case WC_NID_ecdsa_with_SHA512:
17832                    return CTC_SHA512wECDSA;
17833                #ifdef WOLFSSL_SHA3
17834                case WC_NID_ecdsa_with_SHA3_224:
17835                    return CTC_SHA3_224wECDSA;
17836                case WC_NID_ecdsa_with_SHA3_256:
17837                    return CTC_SHA3_256wECDSA;
17838                case WC_NID_ecdsa_with_SHA3_384:
17839                    return CTC_SHA3_384wECDSA;
17840                case WC_NID_ecdsa_with_SHA3_512:
17841                    return CTC_SHA3_512wECDSA;
17842                #endif
17843            #endif /* HAVE_ECC */
17844            #ifdef HAVE_ED25519
17845                case WC_NID_ED25519:
17846                    return CTC_ED25519;
17847            #endif /* HAVE_ED25519 */
17848            #ifdef HAVE_ED448
17849                case WC_NID_ED448:
17850                    return CTC_ED448;
17851            #endif /* HAVE_ED448 */
17852            }
17853            break;
17854
17855        /* oidKeyType */
17856        case oidKeyType:
17857            switch (nid) {
17858            #ifndef NO_DSA
17859                case WC_NID_dsa:
17860                    return DSAk;
17861            #endif /* NO_DSA */
17862            #ifndef NO_RSA
17863                case WC_NID_rsaEncryption:
17864                    return RSAk;
17865            #endif /* NO_RSA */
17866            #ifdef HAVE_ECC
17867                case WC_NID_X9_62_id_ecPublicKey:
17868                    return ECDSAk;
17869            #endif /* HAVE_ECC */
17870            #ifdef HAVE_ED25519
17871                case WC_NID_ED25519:
17872                    return ED25519k;
17873            #endif /* HAVE_ED25519 */
17874            #ifdef HAVE_ED448
17875                case WC_NID_ED448:
17876                    return ED448k;
17877            #endif /* HAVE_ED448 */
17878            }
17879            break;
17880
17881
17882    #ifdef HAVE_ECC
17883        case oidCurveType:
17884            switch (nid) {
17885            case WC_NID_X9_62_prime192v1:
17886                return ECC_SECP192R1_OID;
17887            case WC_NID_X9_62_prime192v2:
17888                return ECC_PRIME192V2_OID;
17889            case WC_NID_X9_62_prime192v3:
17890                return ECC_PRIME192V3_OID;
17891            case WC_NID_X9_62_prime239v1:
17892                return ECC_PRIME239V1_OID;
17893            case WC_NID_X9_62_prime239v2:
17894                return ECC_PRIME239V2_OID;
17895            case WC_NID_X9_62_prime239v3:
17896                return ECC_PRIME239V3_OID;
17897            case WC_NID_X9_62_prime256v1:
17898                return ECC_SECP256R1_OID;
17899            case WC_NID_secp112r1:
17900                return ECC_SECP112R1_OID;
17901            case WC_NID_secp112r2:
17902                return ECC_SECP112R2_OID;
17903            case WC_NID_secp128r1:
17904                return ECC_SECP128R1_OID;
17905            case WC_NID_secp128r2:
17906                return ECC_SECP128R2_OID;
17907            case WC_NID_secp160r1:
17908                return ECC_SECP160R1_OID;
17909            case WC_NID_secp160r2:
17910                return ECC_SECP160R2_OID;
17911            case WC_NID_secp224r1:
17912                return ECC_SECP224R1_OID;
17913            case WC_NID_secp384r1:
17914                return ECC_SECP384R1_OID;
17915            case WC_NID_secp521r1:
17916                return ECC_SECP521R1_OID;
17917            case WC_NID_secp160k1:
17918                return ECC_SECP160K1_OID;
17919            case WC_NID_secp192k1:
17920                return ECC_SECP192K1_OID;
17921            case WC_NID_secp224k1:
17922                return ECC_SECP224K1_OID;
17923            case WC_NID_secp256k1:
17924                return ECC_SECP256K1_OID;
17925            case WC_NID_brainpoolP160r1:
17926                return ECC_BRAINPOOLP160R1_OID;
17927            case WC_NID_brainpoolP192r1:
17928                return ECC_BRAINPOOLP192R1_OID;
17929            case WC_NID_brainpoolP224r1:
17930                return ECC_BRAINPOOLP224R1_OID;
17931            case WC_NID_brainpoolP256r1:
17932                return ECC_BRAINPOOLP256R1_OID;
17933            case WC_NID_brainpoolP320r1:
17934                return ECC_BRAINPOOLP320R1_OID;
17935            case WC_NID_brainpoolP384r1:
17936                return ECC_BRAINPOOLP384R1_OID;
17937            case WC_NID_brainpoolP512r1:
17938                return ECC_BRAINPOOLP512R1_OID;
17939            }
17940            break;
17941    #endif /* HAVE_ECC */
17942
17943        /* oidBlkType */
17944        case oidBlkType:
17945            switch (nid) {
17946            #ifdef WOLFSSL_AES_128
17947                case AES128CBCb:
17948                    return AES128CBCb;
17949            #endif
17950            #ifdef WOLFSSL_AES_192
17951                case AES192CBCb:
17952                    return AES192CBCb;
17953            #endif
17954            #ifdef WOLFSSL_AES_256
17955                case AES256CBCb:
17956                    return AES256CBCb;
17957            #endif
17958            #ifndef NO_DES3
17959                case WC_NID_des:
17960                    return DESb;
17961                case WC_NID_des3:
17962                    return DES3b;
17963            #endif
17964            }
17965            break;
17966
17967    #ifdef HAVE_OCSP
17968        case oidOcspType:
17969            switch (nid) {
17970                case WC_NID_id_pkix_OCSP_basic:
17971                    return OCSP_BASIC_OID;
17972                case OCSP_NONCE_OID:
17973                    return OCSP_NONCE_OID;
17974            }
17975            break;
17976    #endif /* HAVE_OCSP */
17977
17978        /* oidCertExtType */
17979        case oidCertExtType:
17980            switch (nid) {
17981                case WC_NID_basic_constraints:
17982                    return BASIC_CA_OID;
17983                case WC_NID_subject_alt_name:
17984                    return ALT_NAMES_OID;
17985                case WC_NID_crl_distribution_points:
17986                    return CRL_DIST_OID;
17987                case WC_NID_info_access:
17988                    return AUTH_INFO_OID;
17989                case WC_NID_authority_key_identifier:
17990                    return AUTH_KEY_OID;
17991                case WC_NID_subject_key_identifier:
17992                    return SUBJ_KEY_OID;
17993                case WC_NID_inhibit_any_policy:
17994                    return INHIBIT_ANY_OID;
17995                case WC_NID_key_usage:
17996                    return KEY_USAGE_OID;
17997                case WC_NID_name_constraints:
17998                    return NAME_CONS_OID;
17999                case WC_NID_certificate_policies:
18000                    return CERT_POLICY_OID;
18001                case WC_NID_ext_key_usage:
18002                    return EXT_KEY_USAGE_OID;
18003            }
18004            break;
18005
18006        /* oidCertAuthInfoType */
18007        case oidCertAuthInfoType:
18008            switch (nid) {
18009                case WC_NID_ad_OCSP:
18010                    return AIA_OCSP_OID;
18011                case WC_NID_ad_ca_issuers:
18012                    return AIA_CA_ISSUER_OID;
18013            }
18014            break;
18015
18016        /* oidCertPolicyType */
18017        case oidCertPolicyType:
18018            switch (nid) {
18019                case WC_NID_any_policy:
18020                    return CP_ANY_OID;
18021            }
18022            break;
18023
18024        /* oidCertAltNameType */
18025        case oidCertAltNameType:
18026            switch (nid) {
18027                case WC_NID_hw_name_oid:
18028                    return HW_NAME_OID;
18029            }
18030            break;
18031
18032        /* oidCertKeyUseType */
18033        case oidCertKeyUseType:
18034            switch (nid) {
18035                case WC_NID_anyExtendedKeyUsage:
18036                    return EKU_ANY_OID;
18037                case EKU_SERVER_AUTH_OID:
18038                    return EKU_SERVER_AUTH_OID;
18039                case EKU_CLIENT_AUTH_OID:
18040                    return EKU_CLIENT_AUTH_OID;
18041                case EKU_OCSP_SIGN_OID:
18042                    return EKU_OCSP_SIGN_OID;
18043            }
18044            break;
18045
18046        /* oidKdfType */
18047        case oidKdfType:
18048            switch (nid) {
18049                case PBKDF2_OID:
18050                    return PBKDF2_OID;
18051            }
18052            break;
18053
18054        /* oidPBEType */
18055        case oidPBEType:
18056            switch (nid) {
18057                case PBE_SHA1_RC4_128:
18058                    return PBE_SHA1_RC4_128;
18059                case PBE_SHA1_DES:
18060                    return PBE_SHA1_DES;
18061                case PBE_SHA1_DES3:
18062                    return PBE_SHA1_DES3;
18063            }
18064            break;
18065
18066        /* oidKeyWrapType */
18067        case oidKeyWrapType:
18068            switch (nid) {
18069            #ifdef WOLFSSL_AES_128
18070                case AES128_WRAP:
18071                    return AES128_WRAP;
18072            #endif
18073            #ifdef WOLFSSL_AES_192
18074                case AES192_WRAP:
18075                    return AES192_WRAP;
18076            #endif
18077            #ifdef WOLFSSL_AES_256
18078                case AES256_WRAP:
18079                    return AES256_WRAP;
18080            #endif
18081            }
18082            break;
18083
18084        /* oidCmsKeyAgreeType */
18085        case oidCmsKeyAgreeType:
18086            switch (nid) {
18087                #ifndef NO_SHA
18088                case dhSinglePass_stdDH_sha1kdf_scheme:
18089                    return dhSinglePass_stdDH_sha1kdf_scheme;
18090                #endif
18091                #ifdef WOLFSSL_SHA224
18092                case dhSinglePass_stdDH_sha224kdf_scheme:
18093                    return dhSinglePass_stdDH_sha224kdf_scheme;
18094                #endif
18095                #ifndef NO_SHA256
18096                case dhSinglePass_stdDH_sha256kdf_scheme:
18097                    return dhSinglePass_stdDH_sha256kdf_scheme;
18098                #endif
18099                #ifdef WOLFSSL_SHA384
18100                case dhSinglePass_stdDH_sha384kdf_scheme:
18101                    return dhSinglePass_stdDH_sha384kdf_scheme;
18102                #endif
18103                #ifdef WOLFSSL_SHA512
18104                case dhSinglePass_stdDH_sha512kdf_scheme:
18105                    return dhSinglePass_stdDH_sha512kdf_scheme;
18106                #endif
18107            }
18108            break;
18109
18110        /* oidCmsKeyAgreeType */
18111    #ifdef WOLFSSL_CERT_REQ
18112        case oidCsrAttrType:
18113            switch (nid) {
18114                case WC_NID_pkcs9_contentType:
18115                    return PKCS9_CONTENT_TYPE_OID;
18116                case WC_NID_pkcs9_challengePassword:
18117                    return CHALLENGE_PASSWORD_OID;
18118                case WC_NID_serialNumber:
18119                    return SERIAL_NUMBER_OID;
18120                case WC_NID_userId:
18121                    return USER_ID_OID;
18122                case WC_NID_surname:
18123                    return SURNAME_OID;
18124            }
18125            break;
18126    #endif
18127
18128        default:
18129            WOLFSSL_MSG("NID not in table");
18130            /* MSVC warns without the cast */
18131            return (word32)-1;
18132    }
18133
18134    /* MSVC warns without the cast */
18135    return (word32)-1;
18136}
18137
18138int oid2nid(word32 oid, int grp)
18139{
18140    size_t i;
18141    /* get OID type */
18142    switch (grp) {
18143        /* oidHashType */
18144        case oidHashType:
18145            switch (oid) {
18146            #ifdef WOLFSSL_MD2
18147                case MD2h:
18148                    return WC_NID_md2;
18149            #endif
18150            #ifndef NO_MD5
18151                case MD5h:
18152                    return WC_NID_md5;
18153            #endif
18154            #ifndef NO_SHA
18155                case SHAh:
18156                    return WC_NID_sha1;
18157            #endif
18158                case SHA224h:
18159                    return WC_NID_sha224;
18160            #ifndef NO_SHA256
18161                case SHA256h:
18162                    return WC_NID_sha256;
18163            #endif
18164            #ifdef WOLFSSL_SHA384
18165                case SHA384h:
18166                    return WC_NID_sha384;
18167            #endif
18168            #ifdef WOLFSSL_SHA512
18169                case SHA512h:
18170                    return WC_NID_sha512;
18171            #endif
18172            }
18173            break;
18174
18175        /*  oidSigType */
18176        case oidSigType:
18177            switch (oid) {
18178            #ifndef NO_DSA
18179                case CTC_SHAwDSA:
18180                    return WC_NID_dsaWithSHA1;
18181                case CTC_SHA256wDSA:
18182                    return WC_NID_dsa_with_SHA256;
18183            #endif /* NO_DSA */
18184            #ifndef NO_RSA
18185                case CTC_MD2wRSA:
18186                    return WC_NID_md2WithRSAEncryption;
18187                case CTC_MD5wRSA:
18188                    return WC_NID_md5WithRSAEncryption;
18189                case CTC_SHAwRSA:
18190                    return WC_NID_sha1WithRSAEncryption;
18191                case CTC_SHA224wRSA:
18192                    return WC_NID_sha224WithRSAEncryption;
18193                case CTC_SHA256wRSA:
18194                    return WC_NID_sha256WithRSAEncryption;
18195                case CTC_SHA384wRSA:
18196                    return WC_NID_sha384WithRSAEncryption;
18197                case CTC_SHA512wRSA:
18198                    return WC_NID_sha512WithRSAEncryption;
18199                #ifdef WOLFSSL_SHA3
18200                case CTC_SHA3_224wRSA:
18201                    return WC_NID_RSA_SHA3_224;
18202                case CTC_SHA3_256wRSA:
18203                    return WC_NID_RSA_SHA3_256;
18204                case CTC_SHA3_384wRSA:
18205                    return WC_NID_RSA_SHA3_384;
18206                case CTC_SHA3_512wRSA:
18207                    return WC_NID_RSA_SHA3_512;
18208                #endif
18209                #ifdef WC_RSA_PSS
18210                case CTC_RSASSAPSS:
18211                    return WC_NID_rsassaPss;
18212                #endif
18213            #endif /* NO_RSA */
18214            #ifdef HAVE_ECC
18215                case CTC_SHAwECDSA:
18216                    return WC_NID_ecdsa_with_SHA1;
18217                case CTC_SHA224wECDSA:
18218                    return WC_NID_ecdsa_with_SHA224;
18219                case CTC_SHA256wECDSA:
18220                    return WC_NID_ecdsa_with_SHA256;
18221                case CTC_SHA384wECDSA:
18222                    return WC_NID_ecdsa_with_SHA384;
18223                case CTC_SHA512wECDSA:
18224                    return WC_NID_ecdsa_with_SHA512;
18225                #ifdef WOLFSSL_SHA3
18226                case CTC_SHA3_224wECDSA:
18227                    return WC_NID_ecdsa_with_SHA3_224;
18228                case CTC_SHA3_256wECDSA:
18229                    return WC_NID_ecdsa_with_SHA3_256;
18230                case CTC_SHA3_384wECDSA:
18231                    return WC_NID_ecdsa_with_SHA3_384;
18232                case CTC_SHA3_512wECDSA:
18233                    return WC_NID_ecdsa_with_SHA3_512;
18234                #endif
18235            #endif /* HAVE_ECC */
18236            #ifdef HAVE_ED25519
18237                case CTC_ED25519:
18238                    return WC_NID_ED25519;
18239            #endif /* HAVE_ED25519 */
18240            #ifdef HAVE_ED448
18241                case CTC_ED448:
18242                    return WC_NID_ED448;
18243            #endif /* HAVE_ED448 */
18244            }
18245            break;
18246
18247        /* oidKeyType */
18248        case oidKeyType:
18249            switch (oid) {
18250            #ifndef NO_DSA
18251                case DSAk:
18252                    return WC_NID_dsa;
18253            #endif /* NO_DSA */
18254            #ifndef NO_RSA
18255                case RSAk:
18256                    return WC_NID_rsaEncryption;
18257                #ifdef WC_RSA_PSS
18258                case RSAPSSk:
18259                    return WC_NID_rsassaPss;
18260                #endif
18261            #endif /* NO_RSA */
18262            #ifdef HAVE_ECC
18263                case ECDSAk:
18264                    return WC_NID_X9_62_id_ecPublicKey;
18265            #endif /* HAVE_ECC */
18266            #ifdef HAVE_ED25519
18267                case ED25519k:
18268                    return WC_NID_ED25519;
18269            #endif /* HAVE_ED25519 */
18270            #ifdef HAVE_ED448
18271                case ED448k:
18272                    return WC_NID_ED448;
18273            #endif /* HAVE_ED448 */
18274            }
18275            break;
18276
18277
18278    #ifdef HAVE_ECC
18279        case oidCurveType:
18280            switch (oid) {
18281            case ECC_SECP192R1_OID:
18282                return WC_NID_X9_62_prime192v1;
18283            case ECC_PRIME192V2_OID:
18284                return WC_NID_X9_62_prime192v2;
18285            case ECC_PRIME192V3_OID:
18286                return WC_NID_X9_62_prime192v3;
18287            case ECC_PRIME239V1_OID:
18288                return WC_NID_X9_62_prime239v1;
18289            case ECC_PRIME239V2_OID:
18290                return WC_NID_X9_62_prime239v2;
18291            case ECC_PRIME239V3_OID:
18292                return WC_NID_X9_62_prime239v3;
18293            case ECC_SECP256R1_OID:
18294                return WC_NID_X9_62_prime256v1;
18295            case ECC_SECP112R1_OID:
18296                return WC_NID_secp112r1;
18297            case ECC_SECP112R2_OID:
18298                return WC_NID_secp112r2;
18299            case ECC_SECP128R1_OID:
18300                return WC_NID_secp128r1;
18301            case ECC_SECP128R2_OID:
18302                return WC_NID_secp128r2;
18303            case ECC_SECP160R1_OID:
18304                return WC_NID_secp160r1;
18305            case ECC_SECP160R2_OID:
18306                return WC_NID_secp160r2;
18307            case ECC_SECP224R1_OID:
18308                return WC_NID_secp224r1;
18309            case ECC_SECP384R1_OID:
18310                return WC_NID_secp384r1;
18311            case ECC_SECP521R1_OID:
18312                return WC_NID_secp521r1;
18313            case ECC_SECP160K1_OID:
18314                return WC_NID_secp160k1;
18315            case ECC_SECP192K1_OID:
18316                return WC_NID_secp192k1;
18317            case ECC_SECP224K1_OID:
18318                return WC_NID_secp224k1;
18319            case ECC_SECP256K1_OID:
18320                return WC_NID_secp256k1;
18321            case ECC_BRAINPOOLP160R1_OID:
18322                return WC_NID_brainpoolP160r1;
18323            case ECC_BRAINPOOLP192R1_OID:
18324                return WC_NID_brainpoolP192r1;
18325            case ECC_BRAINPOOLP224R1_OID:
18326                return WC_NID_brainpoolP224r1;
18327            case ECC_BRAINPOOLP256R1_OID:
18328                return WC_NID_brainpoolP256r1;
18329            case ECC_BRAINPOOLP320R1_OID:
18330                return WC_NID_brainpoolP320r1;
18331            case ECC_BRAINPOOLP384R1_OID:
18332                return WC_NID_brainpoolP384r1;
18333            case ECC_BRAINPOOLP512R1_OID:
18334                return WC_NID_brainpoolP512r1;
18335            }
18336            break;
18337    #endif /* HAVE_ECC */
18338
18339        /* oidBlkType */
18340        case oidBlkType:
18341            switch (oid) {
18342            #ifdef WOLFSSL_AES_128
18343                case AES128CBCb:
18344                    return AES128CBCb;
18345            #endif
18346            #ifdef WOLFSSL_AES_192
18347                case AES192CBCb:
18348                    return AES192CBCb;
18349            #endif
18350            #ifdef WOLFSSL_AES_256
18351                case AES256CBCb:
18352                    return AES256CBCb;
18353            #endif
18354            #ifndef NO_DES3
18355                case DESb:
18356                    return WC_NID_des;
18357                case DES3b:
18358                    return WC_NID_des3;
18359            #endif
18360            }
18361            break;
18362
18363    #ifdef HAVE_OCSP
18364        case oidOcspType:
18365            switch (oid) {
18366                case OCSP_BASIC_OID:
18367                    return WC_NID_id_pkix_OCSP_basic;
18368                case OCSP_NONCE_OID:
18369                    return OCSP_NONCE_OID;
18370            }
18371            break;
18372    #endif /* HAVE_OCSP */
18373
18374        /* oidCertExtType */
18375        case oidCertExtType:
18376            switch (oid) {
18377                case BASIC_CA_OID:
18378                    return WC_NID_basic_constraints;
18379                case ALT_NAMES_OID:
18380                    return WC_NID_subject_alt_name;
18381                case CRL_DIST_OID:
18382                    return WC_NID_crl_distribution_points;
18383                case AUTH_INFO_OID:
18384                    return WC_NID_info_access;
18385                case AUTH_KEY_OID:
18386                    return WC_NID_authority_key_identifier;
18387                case SUBJ_KEY_OID:
18388                    return WC_NID_subject_key_identifier;
18389                case INHIBIT_ANY_OID:
18390                    return WC_NID_inhibit_any_policy;
18391                case KEY_USAGE_OID:
18392                    return WC_NID_key_usage;
18393                case NAME_CONS_OID:
18394                    return WC_NID_name_constraints;
18395                case CERT_POLICY_OID:
18396                    return WC_NID_certificate_policies;
18397                case EXT_KEY_USAGE_OID:
18398                    return WC_NID_ext_key_usage;
18399            }
18400            break;
18401
18402        /* oidCertAuthInfoType */
18403        case oidCertAuthInfoType:
18404            switch (oid) {
18405                case AIA_OCSP_OID:
18406                    return WC_NID_ad_OCSP;
18407                case AIA_CA_ISSUER_OID:
18408                    return WC_NID_ad_ca_issuers;
18409            }
18410            break;
18411
18412        /* oidCertPolicyType */
18413        case oidCertPolicyType:
18414            switch (oid) {
18415                case CP_ANY_OID:
18416                    return WC_NID_any_policy;
18417            }
18418            break;
18419
18420        /* oidCertAltNameType */
18421        case oidCertAltNameType:
18422            switch (oid) {
18423                case HW_NAME_OID:
18424                    return WC_NID_hw_name_oid;
18425            }
18426            break;
18427
18428        /* oidCertKeyUseType */
18429        case oidCertKeyUseType:
18430            switch (oid) {
18431                case EKU_ANY_OID:
18432                    return WC_NID_anyExtendedKeyUsage;
18433                case EKU_SERVER_AUTH_OID:
18434                    return EKU_SERVER_AUTH_OID;
18435                case EKU_CLIENT_AUTH_OID:
18436                    return EKU_CLIENT_AUTH_OID;
18437                case EKU_OCSP_SIGN_OID:
18438                    return EKU_OCSP_SIGN_OID;
18439            }
18440            break;
18441
18442        /* oidKdfType */
18443        case oidKdfType:
18444            switch (oid) {
18445                case PBKDF2_OID:
18446                    return PBKDF2_OID;
18447            }
18448            break;
18449
18450        /* oidPBEType */
18451        case oidPBEType:
18452            switch (oid) {
18453                case PBE_SHA1_RC4_128:
18454                    return PBE_SHA1_RC4_128;
18455                case PBE_SHA1_DES:
18456                    return PBE_SHA1_DES;
18457                case PBE_SHA1_DES3:
18458                    return PBE_SHA1_DES3;
18459            }
18460            break;
18461
18462        /* oidKeyWrapType */
18463        case oidKeyWrapType:
18464            switch (oid) {
18465            #ifdef WOLFSSL_AES_128
18466                case AES128_WRAP:
18467                    return AES128_WRAP;
18468            #endif
18469            #ifdef WOLFSSL_AES_192
18470                case AES192_WRAP:
18471                    return AES192_WRAP;
18472            #endif
18473            #ifdef WOLFSSL_AES_256
18474                case AES256_WRAP:
18475                    return AES256_WRAP;
18476            #endif
18477            }
18478            break;
18479
18480        /* oidCmsKeyAgreeType */
18481        case oidCmsKeyAgreeType:
18482            switch (oid) {
18483                #ifndef NO_SHA
18484                case dhSinglePass_stdDH_sha1kdf_scheme:
18485                    return dhSinglePass_stdDH_sha1kdf_scheme;
18486                #endif
18487                #ifdef WOLFSSL_SHA224
18488                case dhSinglePass_stdDH_sha224kdf_scheme:
18489                    return dhSinglePass_stdDH_sha224kdf_scheme;
18490                #endif
18491                #ifndef NO_SHA256
18492                case dhSinglePass_stdDH_sha256kdf_scheme:
18493                    return dhSinglePass_stdDH_sha256kdf_scheme;
18494                #endif
18495                #ifdef WOLFSSL_SHA384
18496                case dhSinglePass_stdDH_sha384kdf_scheme:
18497                    return dhSinglePass_stdDH_sha384kdf_scheme;
18498                #endif
18499                #ifdef WOLFSSL_SHA512
18500                case dhSinglePass_stdDH_sha512kdf_scheme:
18501                    return dhSinglePass_stdDH_sha512kdf_scheme;
18502                #endif
18503            }
18504            break;
18505
18506#ifdef WOLFSSL_CERT_REQ
18507        case oidCsrAttrType:
18508            switch (oid) {
18509                case PKCS9_CONTENT_TYPE_OID:
18510                    return WC_NID_pkcs9_contentType;
18511                case CHALLENGE_PASSWORD_OID:
18512                    return WC_NID_pkcs9_challengePassword;
18513                case SERIAL_NUMBER_OID:
18514                    return WC_NID_serialNumber;
18515                case USER_ID_OID:
18516                    return WC_NID_userId;
18517            }
18518            break;
18519#endif
18520
18521        default:
18522            WOLFSSL_MSG("OID not in table");
18523    }
18524    /* If not found in above switch then try the table */
18525    for (i = 0; i < WOLFSSL_OBJECT_INFO_SZ; i++) {
18526        if (wolfssl_object_info[i].id == (int)oid) {
18527            return wolfssl_object_info[i].nid;
18528        }
18529    }
18530
18531    return WOLFSSL_FATAL_ERROR;
18532}
18533
18534#endif /* OPENSSL_EXTRA || OPENSSL_EXTRA_X509_SMALL */
18535
18536#if defined(OPENSSL_EXTRA)
18537
18538/* frees all nodes in the current threads error queue
18539 *
18540 * id  thread id. ERR_remove_state is depreciated and id is ignored. The
18541 *     current threads queue will be free'd.
18542 */
18543void wolfSSL_ERR_remove_state(unsigned long id)
18544{
18545    WOLFSSL_ENTER("wolfSSL_ERR_remove_state");
18546    (void)id;
18547    if (wc_ERR_remove_state() != 0) {
18548        WOLFSSL_MSG("Error with removing the state");
18549    }
18550}
18551
18552#endif /* OPENSSL_EXTRA */
18553
18554#ifdef WOLFSSL_STATIC_EPHEMERAL
18555int wolfSSL_StaticEphemeralKeyLoad(WOLFSSL* ssl, int keyAlgo, void* keyPtr)
18556{
18557    int ret;
18558    word32 idx = 0;
18559    DerBuffer* der = NULL;
18560
18561    if (ssl == NULL || ssl->ctx == NULL || keyPtr == NULL) {
18562        return BAD_FUNC_ARG;
18563    }
18564
18565#ifndef SINGLE_THREADED
18566    if (!ssl->ctx->staticKELockInit) {
18567        return BUFFER_E; /* no keys set */
18568    }
18569    ret = wc_LockMutex(&ssl->ctx->staticKELock);
18570    if (ret != 0) {
18571        return ret;
18572    }
18573#endif
18574
18575    ret = BUFFER_E; /* set default error */
18576    switch (keyAlgo) {
18577    #ifndef NO_DH
18578        case WC_PK_TYPE_DH:
18579            if (ssl != NULL)
18580                der = ssl->staticKE.dhKey;
18581            if (der == NULL)
18582                der = ssl->ctx->staticKE.dhKey;
18583            if (der != NULL) {
18584                DhKey* key = (DhKey*)keyPtr;
18585                WOLFSSL_MSG("Using static DH key");
18586                ret = wc_DhKeyDecode(der->buffer, &idx, key, der->length);
18587            }
18588            break;
18589    #endif
18590    #ifdef HAVE_ECC
18591        case WC_PK_TYPE_ECDH:
18592            if (ssl != NULL)
18593                der = ssl->staticKE.ecKey;
18594            if (der == NULL)
18595                der = ssl->ctx->staticKE.ecKey;
18596            if (der != NULL) {
18597                ecc_key* key = (ecc_key*)keyPtr;
18598                WOLFSSL_MSG("Using static ECDH key");
18599                ret = wc_EccPrivateKeyDecode(der->buffer, &idx, key,
18600                    der->length);
18601            }
18602            break;
18603    #endif
18604    #ifdef HAVE_CURVE25519
18605        case WC_PK_TYPE_CURVE25519:
18606            if (ssl != NULL)
18607                der = ssl->staticKE.x25519Key;
18608            if (der == NULL)
18609                der = ssl->ctx->staticKE.x25519Key;
18610            if (der != NULL) {
18611                curve25519_key* key = (curve25519_key*)keyPtr;
18612                WOLFSSL_MSG("Using static X25519 key");
18613
18614            #ifdef WOLFSSL_CURVE25519_BLINDING
18615                ret = wc_curve25519_set_rng(key, ssl->rng);
18616                if (ret == 0)
18617            #endif
18618                    ret = wc_Curve25519PrivateKeyDecode(der->buffer, &idx, key,
18619                        der->length);
18620            }
18621            break;
18622    #endif
18623    #ifdef HAVE_CURVE448
18624        case WC_PK_TYPE_CURVE448:
18625            if (ssl != NULL)
18626                der = ssl->staticKE.x448Key;
18627            if (der == NULL)
18628                der = ssl->ctx->staticKE.x448Key;
18629            if (der != NULL) {
18630                curve448_key* key = (curve448_key*)keyPtr;
18631                WOLFSSL_MSG("Using static X448 key");
18632                ret = wc_Curve448PrivateKeyDecode(der->buffer, &idx, key,
18633                    der->length);
18634            }
18635            break;
18636    #endif
18637        default:
18638            /* not supported */
18639            ret = NOT_COMPILED_IN;
18640            break;
18641    }
18642
18643#ifndef SINGLE_THREADED
18644    wc_UnLockMutex(&ssl->ctx->staticKELock);
18645#endif
18646    return ret;
18647}
18648
18649static int SetStaticEphemeralKey(WOLFSSL_CTX* ctx,
18650    StaticKeyExchangeInfo_t* staticKE, int keyAlgo, const char* key,
18651    unsigned int keySz, int format, void* heap)
18652{
18653    int ret = 0;
18654    DerBuffer* der = NULL;
18655    byte* keyBuf = NULL;
18656#ifndef NO_FILESYSTEM
18657    const char* keyFile = NULL;
18658#endif
18659
18660    /* allow empty key to free buffer */
18661    if (staticKE == NULL || (key == NULL && keySz > 0)) {
18662        return BAD_FUNC_ARG;
18663    }
18664
18665    WOLFSSL_ENTER("SetStaticEphemeralKey");
18666
18667    /* if just free'ing key then skip loading */
18668    if (key != NULL) {
18669    #ifndef NO_FILESYSTEM
18670        /* load file from filesystem */
18671        if (key != NULL && keySz == 0) {
18672            size_t keyBufSz = 0;
18673            keyFile = (const char*)key;
18674            ret = wc_FileLoad(keyFile, &keyBuf, &keyBufSz, heap);
18675            if (ret != 0) {
18676                return ret;
18677            }
18678            keySz = (unsigned int)keyBufSz;
18679        }
18680        else
18681    #endif
18682        {
18683            /* use as key buffer directly */
18684            keyBuf = (byte*)key;
18685        }
18686
18687        if (format == WOLFSSL_FILETYPE_PEM) {
18688        #ifdef WOLFSSL_PEM_TO_DER
18689            int keyFormat = 0;
18690            ret = PemToDer(keyBuf, keySz, PRIVATEKEY_TYPE, &der,
18691                heap, NULL, &keyFormat);
18692            /* auto detect key type */
18693            if (ret == 0 && keyAlgo == WC_PK_TYPE_NONE) {
18694                if (keyFormat == ECDSAk)
18695                    keyAlgo = WC_PK_TYPE_ECDH;
18696                else if (keyFormat == X25519k)
18697                    keyAlgo = WC_PK_TYPE_CURVE25519;
18698                else
18699                    keyAlgo = WC_PK_TYPE_DH;
18700            }
18701        #else
18702            ret = NOT_COMPILED_IN;
18703        #endif
18704        }
18705        else {
18706            /* Detect PK type (if required) */
18707        #ifdef HAVE_ECC
18708            if (keyAlgo == WC_PK_TYPE_NONE) {
18709                word32 idx = 0;
18710                WC_DECLARE_VAR(eccKey, ecc_key, 1, heap);
18711                WC_ALLOC_VAR_EX(eccKey, ecc_key, 1, heap, DYNAMIC_TYPE_ECC,
18712                                ret = MEMORY_E);
18713                if (ret == 0)
18714                    ret = wc_ecc_init_ex(eccKey, heap, INVALID_DEVID);
18715                if (ret == 0) {
18716                    ret = wc_EccPrivateKeyDecode(keyBuf, &idx, eccKey, keySz);
18717                    if (ret == 0)
18718                        keyAlgo = WC_PK_TYPE_ECDH;
18719                    wc_ecc_free(eccKey);
18720                    ret = 0; /* clear error to enable key-type detect cascade */
18721                }
18722                WC_FREE_VAR_EX(eccKey, heap, DYNAMIC_TYPE_ECC);
18723            }
18724        #endif
18725        #if !defined(NO_DH) && defined(WOLFSSL_DH_EXTRA)
18726            if (keyAlgo == WC_PK_TYPE_NONE) {
18727                word32 idx = 0;
18728                WC_DECLARE_VAR(dhKey, DhKey, 1, heap);
18729                WC_ALLOC_VAR_EX(dhKey, DhKey, 1, heap, DYNAMIC_TYPE_DH,
18730                                ret = MEMORY_E);
18731                if (ret == 0)
18732                    ret = wc_InitDhKey_ex(dhKey, heap, INVALID_DEVID);
18733                if (ret == 0) {
18734                    ret = wc_DhKeyDecode(keyBuf, &idx, dhKey, keySz);
18735                    if (ret == 0)
18736                        keyAlgo = WC_PK_TYPE_DH;
18737                    wc_FreeDhKey(dhKey);
18738                    ret = 0; /* clear error to enable key-type detect cascade */
18739                }
18740                WC_FREE_VAR_EX(dhKey, heap, DYNAMIC_TYPE_DH);
18741            }
18742        #endif
18743        #ifdef HAVE_CURVE25519
18744            if (keyAlgo == WC_PK_TYPE_NONE) {
18745                word32 idx = 0;
18746                WC_DECLARE_VAR(x25519Key, curve25519_key, 1, heap);
18747                WC_ALLOC_VAR_EX(x25519Key, curve25519_key, 1, heap,
18748                                DYNAMIC_TYPE_CURVE25519, ret = MEMORY_E);
18749                if (ret == 0)
18750                    ret = wc_curve25519_init_ex(x25519Key, heap, INVALID_DEVID);
18751                if (ret == 0) {
18752                    ret = wc_Curve25519PrivateKeyDecode(keyBuf, &idx,
18753                        x25519Key, keySz);
18754                    if (ret == 0)
18755                        keyAlgo = WC_PK_TYPE_CURVE25519;
18756                    wc_curve25519_free(x25519Key);
18757                    ret = 0; /* clear error to enable key-type detect cascade */
18758                }
18759                WC_FREE_VAR_EX(x25519Key, heap, DYNAMIC_TYPE_CURVE25519);
18760            }
18761        #endif
18762        #ifdef HAVE_CURVE448
18763            if (keyAlgo == WC_PK_TYPE_NONE) {
18764                word32 idx = 0;
18765                WC_DECLARE_VAR(x448Key, curve448_key, 1, heap);
18766                WC_ALLOC_VAR_EX(x448Key, curve448_key, 1, heap,
18767                                DYNAMIC_TYPE_CURVE448, ret = MEMORY_E);
18768                if (ret == 0)
18769                    ret = wc_curve448_init(x448Key);
18770                if (ret == 0) {
18771                    ret = wc_Curve448PrivateKeyDecode(keyBuf, &idx, x448Key,
18772                        keySz);
18773                    if (ret == 0)
18774                        keyAlgo = WC_PK_TYPE_CURVE448;
18775                    wc_curve448_free(x448Key);
18776                    ret = 0; /* clear error to enable key-type detect cascade */
18777                }
18778                WC_FREE_VAR_EX(x448Key, heap, DYNAMIC_TYPE_CURVE448);
18779            }
18780        #endif
18781
18782            if (keyAlgo != WC_PK_TYPE_NONE) {
18783                ret = AllocDer(&der, keySz, PRIVATEKEY_TYPE, heap);
18784                if (ret == 0) {
18785                    XMEMCPY(der->buffer, keyBuf, keySz);
18786                }
18787            }
18788        }
18789    }
18790
18791#ifndef NO_FILESYSTEM
18792    /* done with keyFile buffer */
18793    if (keyFile && keyBuf) {
18794        ForceZero(keyBuf, keySz);
18795        XFREE(keyBuf, heap, DYNAMIC_TYPE_TMP_BUFFER);
18796    }
18797#endif
18798
18799#ifndef SINGLE_THREADED
18800    if (ret == 0 && !ctx->staticKELockInit) {
18801        ret = wc_InitMutex(&ctx->staticKELock);
18802        if (ret == 0) {
18803            ctx->staticKELockInit = 1;
18804        }
18805    }
18806#endif
18807    if (ret == 0
18808    #ifndef SINGLE_THREADED
18809        && (ret = wc_LockMutex(&ctx->staticKELock)) == 0
18810    #endif
18811    ) {
18812        switch (keyAlgo) {
18813        #ifndef NO_DH
18814            case WC_PK_TYPE_DH:
18815                FreeDer(&staticKE->dhKey);
18816                staticKE->dhKey = der; der = NULL;
18817                break;
18818        #endif
18819        #ifdef HAVE_ECC
18820            case WC_PK_TYPE_ECDH:
18821                FreeDer(&staticKE->ecKey);
18822                staticKE->ecKey = der; der = NULL;
18823                break;
18824        #endif
18825        #ifdef HAVE_CURVE25519
18826            case WC_PK_TYPE_CURVE25519:
18827                FreeDer(&staticKE->x25519Key);
18828                staticKE->x25519Key = der; der = NULL;
18829                break;
18830        #endif
18831        #ifdef HAVE_CURVE448
18832            case WC_PK_TYPE_CURVE448:
18833                FreeDer(&staticKE->x448Key);
18834                staticKE->x448Key = der; der = NULL;
18835                break;
18836        #endif
18837            default:
18838                /* not supported */
18839                ret = NOT_COMPILED_IN;
18840                break;
18841        }
18842
18843    #ifndef SINGLE_THREADED
18844        wc_UnLockMutex(&ctx->staticKELock);
18845    #endif
18846    }
18847
18848    if (ret != 0) {
18849        FreeDer(&der);
18850    }
18851
18852    (void)ctx; /* not used for single threaded */
18853
18854    WOLFSSL_LEAVE("SetStaticEphemeralKey", ret);
18855
18856    return ret;
18857}
18858
18859int wolfSSL_CTX_set_ephemeral_key(WOLFSSL_CTX* ctx, int keyAlgo,
18860    const char* key, unsigned int keySz, int format)
18861{
18862    if (ctx == NULL) {
18863        return BAD_FUNC_ARG;
18864    }
18865    return SetStaticEphemeralKey(ctx, &ctx->staticKE, keyAlgo,
18866        key, keySz, format, ctx->heap);
18867}
18868int wolfSSL_set_ephemeral_key(WOLFSSL* ssl, int keyAlgo,
18869    const char* key, unsigned int keySz, int format)
18870{
18871    if (ssl == NULL || ssl->ctx == NULL) {
18872        return BAD_FUNC_ARG;
18873    }
18874    return SetStaticEphemeralKey(ssl->ctx, &ssl->staticKE, keyAlgo,
18875        key, keySz, format, ssl->heap);
18876}
18877
18878static int GetStaticEphemeralKey(WOLFSSL_CTX* ctx, WOLFSSL* ssl,
18879    int keyAlgo, const unsigned char** key, unsigned int* keySz)
18880{
18881    int ret = 0;
18882    DerBuffer* der = NULL;
18883
18884    if (key)   *key = NULL;
18885    if (keySz) *keySz = 0;
18886
18887#ifndef SINGLE_THREADED
18888    if (ctx->staticKELockInit &&
18889        (ret = wc_LockMutex(&ctx->staticKELock)) != 0) {
18890        return ret;
18891    }
18892#endif
18893
18894    switch (keyAlgo) {
18895    #ifndef NO_DH
18896        case WC_PK_TYPE_DH:
18897            if (ssl != NULL)
18898                der = ssl->staticKE.dhKey;
18899            if (der == NULL)
18900                der = ctx->staticKE.dhKey;
18901            break;
18902    #endif
18903    #ifdef HAVE_ECC
18904        case WC_PK_TYPE_ECDH:
18905            if (ssl != NULL)
18906                der = ssl->staticKE.ecKey;
18907            if (der == NULL)
18908                der = ctx->staticKE.ecKey;
18909            break;
18910    #endif
18911    #ifdef HAVE_CURVE25519
18912        case WC_PK_TYPE_CURVE25519:
18913            if (ssl != NULL)
18914                der = ssl->staticKE.x25519Key;
18915            if (der == NULL)
18916                der = ctx->staticKE.x25519Key;
18917            break;
18918    #endif
18919    #ifdef HAVE_CURVE448
18920        case WC_PK_TYPE_CURVE448:
18921            if (ssl != NULL)
18922                der = ssl->staticKE.x448Key;
18923            if (der == NULL)
18924                der = ctx->staticKE.x448Key;
18925            break;
18926    #endif
18927        default:
18928            /* not supported */
18929            ret = NOT_COMPILED_IN;
18930            break;
18931    }
18932
18933    if (der) {
18934        if (key)
18935            *key = der->buffer;
18936        if (keySz)
18937            *keySz = der->length;
18938    }
18939
18940#ifndef SINGLE_THREADED
18941    wc_UnLockMutex(&ctx->staticKELock);
18942#endif
18943
18944    return ret;
18945}
18946
18947/* returns pointer to currently loaded static ephemeral as ASN.1 */
18948/* this can be converted to PEM using wc_DerToPem */
18949int wolfSSL_CTX_get_ephemeral_key(WOLFSSL_CTX* ctx, int keyAlgo,
18950    const unsigned char** key, unsigned int* keySz)
18951{
18952    if (ctx == NULL) {
18953        return BAD_FUNC_ARG;
18954    }
18955
18956    return GetStaticEphemeralKey(ctx, NULL, keyAlgo, key, keySz);
18957}
18958int wolfSSL_get_ephemeral_key(WOLFSSL* ssl, int keyAlgo,
18959    const unsigned char** key, unsigned int* keySz)
18960{
18961    if (ssl == NULL || ssl->ctx == NULL) {
18962        return BAD_FUNC_ARG;
18963    }
18964
18965    return GetStaticEphemeralKey(ssl->ctx, ssl, keyAlgo, key, keySz);
18966}
18967
18968#endif /* WOLFSSL_STATIC_EPHEMERAL */
18969
18970#if defined(OPENSSL_EXTRA)
18971/* wolfSSL_THREADID_current is provided as a compat API with
18972 * CRYPTO_THREADID_current to register current thread id into given id object.
18973 * However, CRYPTO_THREADID_current API has been deprecated and no longer
18974 * exists in the OpenSSL 1.0.0 or later.This API only works as a stub
18975 * like as existing wolfSSL_THREADID_set_numeric.
18976 */
18977void wolfSSL_THREADID_current(WOLFSSL_CRYPTO_THREADID* id)
18978{
18979    (void)id;
18980    return;
18981}
18982/* wolfSSL_THREADID_hash is provided as a compatible API with
18983 * CRYPTO_THREADID_hash which returns a hash value calculated from the
18984 * specified thread id. However, CRYPTO_THREADID_hash API has been
18985 * deprecated and no longer exists in the OpenSSL 1.0.0 or later.
18986 * This API only works as a stub to returns 0. This behavior is
18987 * equivalent to the latest OpenSSL CRYPTO_THREADID_hash.
18988 */
18989unsigned long wolfSSL_THREADID_hash(const WOLFSSL_CRYPTO_THREADID* id)
18990{
18991    (void)id;
18992    return 0UL;
18993}
18994/* wolfSSL_set_ecdh_auto is provided as compatible API with
18995 * SSL_set_ecdh_auto to enable auto ecdh curve selection functionality.
18996 * Since this functionality is enabled by default in wolfSSL,
18997 * this API exists as a stub.
18998 */
18999int wolfSSL_set_ecdh_auto(WOLFSSL* ssl, int onoff)
19000{
19001    (void)ssl;
19002    (void)onoff;
19003    return WOLFSSL_SUCCESS;
19004}
19005/* wolfSSL_CTX_set_ecdh_auto is provided as compatible API with
19006 * SSL_CTX_set_ecdh_auto to enable auto ecdh curve selection functionality.
19007 * Since this functionality is enabled by default in wolfSSL,
19008 * this API exists as a stub.
19009 */
19010int wolfSSL_CTX_set_ecdh_auto(WOLFSSL_CTX* ctx, int onoff)
19011{
19012    (void)ctx;
19013    (void)onoff;
19014    return WOLFSSL_SUCCESS;
19015}
19016
19017/* wolfSSL_CTX_set_dh_auto is provided as compatible API with
19018 * SSL_CTX_set_dh_auto to enable auto dh selection functionality.
19019 * Since this functionality is enabled by default in wolfSSL,
19020 * this API exists as a stub.
19021 */
19022int wolfSSL_CTX_set_dh_auto(WOLFSSL_CTX* ctx, int onoff)
19023{
19024    (void)ctx;
19025    (void)onoff;
19026    return WOLFSSL_SUCCESS;
19027}
19028
19029/**
19030 * Set security level (wolfSSL doesn't support setting the security level).
19031 *
19032 * The security level can only be set through a system wide crypto-policy
19033 * with wolfSSL_crypto_policy_enable().
19034 *
19035 * @param ctx  a pointer to WOLFSSL_CTX structure
19036 * @param level security level
19037 */
19038void wolfSSL_CTX_set_security_level(WOLFSSL_CTX* ctx, int level)
19039{
19040    WOLFSSL_ENTER("wolfSSL_CTX_set_security_level");
19041    (void)ctx;
19042    (void)level;
19043}
19044
19045int wolfSSL_CTX_get_security_level(const WOLFSSL_CTX * ctx)
19046{
19047    WOLFSSL_ENTER("wolfSSL_CTX_get_security_level");
19048    #if defined(WOLFSSL_SYS_CRYPTO_POLICY)
19049    if (ctx == NULL) {
19050        return BAD_FUNC_ARG;
19051    }
19052
19053    return ctx->secLevel;
19054    #else
19055    (void)ctx;
19056    return 0;
19057    #endif /* WOLFSSL_SYS_CRYPTO_POLICY */
19058}
19059
19060#if defined(OPENSSL_EXTRA) && defined(HAVE_SECRET_CALLBACK)
19061/*
19062 * This API accepts a user callback which puts key-log records into
19063 * a KEY LOGFILE. The callback is stored into a CTX and propagated to
19064 * each SSL object on its creation timing.
19065 */
19066void wolfSSL_CTX_set_keylog_callback(WOLFSSL_CTX* ctx,
19067    wolfSSL_CTX_keylog_cb_func cb)
19068{
19069    WOLFSSL_ENTER("wolfSSL_CTX_set_keylog_callback");
19070    /* stores the callback into WOLFSSL_CTX */
19071    if (ctx != NULL) {
19072        ctx->keyLogCb = cb;
19073    }
19074}
19075wolfSSL_CTX_keylog_cb_func wolfSSL_CTX_get_keylog_callback(
19076    const WOLFSSL_CTX* ctx)
19077{
19078    WOLFSSL_ENTER("wolfSSL_CTX_get_keylog_callback");
19079    if (ctx != NULL)
19080        return ctx->keyLogCb;
19081    return NULL;
19082}
19083#endif /* OPENSSL_EXTRA && HAVE_SECRET_CALLBACK */
19084
19085#endif /* OPENSSL_EXTRA */
19086
19087#ifdef WOLFSSL_THREADED_CRYPT
19088int wolfSSL_AsyncEncryptReady(WOLFSSL* ssl, int idx)
19089{
19090    ThreadCrypt* encrypt;
19091
19092    if (ssl == NULL) {
19093        return 0;
19094    }
19095
19096    encrypt = &ssl->buffers.encrypt[idx];
19097    return (encrypt->avail == 0) && (encrypt->done == 0);
19098}
19099
19100int wolfSSL_AsyncEncryptStop(WOLFSSL* ssl, int idx)
19101{
19102    ThreadCrypt* encrypt;
19103
19104    if (ssl == NULL) {
19105        return 1;
19106    }
19107
19108    encrypt = &ssl->buffers.encrypt[idx];
19109    return encrypt->stop;
19110}
19111
19112int wolfSSL_AsyncEncrypt(WOLFSSL* ssl, int idx)
19113{
19114    int ret = WC_NO_ERR_TRACE(NOT_COMPILED_IN);
19115    ThreadCrypt* encrypt = &ssl->buffers.encrypt[idx];
19116
19117    if (ssl->specs.bulk_cipher_algorithm == wolfssl_aes_gcm) {
19118        unsigned char* out = encrypt->buffer.buffer + encrypt->offset;
19119        unsigned char* input = encrypt->buffer.buffer + encrypt->offset;
19120        word32 encSz = encrypt->buffer.length - encrypt->offset;
19121
19122        ret =
19123#if !defined(NO_GCM_ENCRYPT_EXTRA) && \
19124    ((!defined(HAVE_FIPS) && !defined(HAVE_SELFTEST)) || \
19125    (defined(HAVE_FIPS_VERSION) && (HAVE_FIPS_VERSION >= 2)))
19126              wc_AesGcmEncrypt_ex
19127#else
19128              wc_AesGcmEncrypt
19129#endif
19130              (encrypt->encrypt.aes,
19131               out + AESGCM_EXP_IV_SZ, input + AESGCM_EXP_IV_SZ,
19132               encSz - AESGCM_EXP_IV_SZ - ssl->specs.aead_mac_size,
19133               encrypt->nonce, AESGCM_NONCE_SZ,
19134               out + encSz - ssl->specs.aead_mac_size,
19135               ssl->specs.aead_mac_size,
19136               encrypt->additional, AEAD_AUTH_DATA_SZ);
19137#if !defined(NO_PUBLIC_GCM_SET_IV) && \
19138    ((!defined(HAVE_FIPS) && !defined(HAVE_SELFTEST)) || \
19139    (defined(HAVE_FIPS_VERSION) && (HAVE_FIPS_VERSION >= 2)))
19140        XMEMCPY(out, encrypt->nonce + AESGCM_IMP_IV_SZ, AESGCM_EXP_IV_SZ);
19141#endif
19142        encrypt->done = 1;
19143    }
19144
19145    return ret;
19146}
19147
19148int wolfSSL_AsyncEncryptSetSignal(WOLFSSL* ssl, int idx,
19149    WOLFSSL_THREAD_SIGNAL signal, void* ctx)
19150{
19151    int ret = 0;
19152
19153    if (ssl == NULL) {
19154        ret = BAD_FUNC_ARG;
19155    }
19156    else {
19157        ssl->buffers.encrypt[idx].signal = signal;
19158        ssl->buffers.encrypt[idx].signalCtx = ctx;
19159    }
19160
19161    return ret;
19162}
19163#endif
19164
19165
19166#ifndef NO_CERT
19167#define WOLFSSL_X509_INCLUDED
19168#include "src/x509.c"
19169#endif
19170
19171/*******************************************************************************
19172 * START OF standard C library wrapping APIs
19173 ******************************************************************************/
19174#if defined(OPENSSL_ALL) || (defined(OPENSSL_EXTRA) && \
19175    (defined(HAVE_STUNNEL) || defined(WOLFSSL_NGINX) || \
19176     defined(HAVE_LIGHTY) || defined(WOLFSSL_HAPROXY) || \
19177     defined(WOLFSSL_OPENSSH)))
19178#ifndef NO_WOLFSSL_STUB
19179int wolfSSL_CRYPTO_set_mem_ex_functions(void *(*m) (size_t, const char *, int),
19180                                void *(*r) (void *, size_t, const char *,
19181                                            int), void (*f) (void *))
19182{
19183    (void) m;
19184    (void) r;
19185    (void) f;
19186    WOLFSSL_ENTER("wolfSSL_CRYPTO_set_mem_ex_functions");
19187    WOLFSSL_STUB("CRYPTO_set_mem_ex_functions");
19188
19189    return WOLFSSL_FAILURE;
19190}
19191#endif
19192#endif
19193
19194#if defined(OPENSSL_EXTRA)
19195
19196/**
19197 * free allocated memory resource
19198 * @param str  a pointer to resource to be freed
19199 * @param file dummy argument
19200 * @param line dummy argument
19201 */
19202void wolfSSL_CRYPTO_free(void *str, const char *file, int line)
19203{
19204    (void)file;
19205    (void)line;
19206    XFREE(str, 0, DYNAMIC_TYPE_TMP_BUFFER);
19207}
19208/**
19209 * allocate memory with size of num
19210 * @param num  size of memory allocation to be malloced
19211 * @param file dummy argument
19212 * @param line dummy argument
19213 * @return a pointer to allocated memory on succssesful, otherwise NULL
19214 */
19215void *wolfSSL_CRYPTO_malloc(size_t num, const char *file, int line)
19216{
19217    (void)file;
19218    (void)line;
19219    return XMALLOC(num, 0, DYNAMIC_TYPE_TMP_BUFFER);
19220}
19221
19222#endif
19223
19224/*******************************************************************************
19225 * END OF standard C library wrapping APIs
19226 ******************************************************************************/
19227
19228/*******************************************************************************
19229 * START OF EX_DATA APIs
19230 ******************************************************************************/
19231#ifdef HAVE_EX_DATA
19232void wolfSSL_CRYPTO_cleanup_all_ex_data(void)
19233{
19234    WOLFSSL_ENTER("wolfSSL_CRYPTO_cleanup_all_ex_data");
19235}
19236
19237void* wolfSSL_CRYPTO_get_ex_data(const WOLFSSL_CRYPTO_EX_DATA* ex_data, int idx)
19238{
19239    WOLFSSL_ENTER("wolfSSL_CRYPTO_get_ex_data");
19240#ifdef MAX_EX_DATA
19241    if (ex_data && idx < MAX_EX_DATA && idx >= 0) {
19242        return ex_data->ex_data[idx];
19243    }
19244#else
19245    (void)ex_data;
19246    (void)idx;
19247#endif
19248    return NULL;
19249}
19250
19251int wolfSSL_CRYPTO_set_ex_data(WOLFSSL_CRYPTO_EX_DATA* ex_data, int idx,
19252    void *data)
19253{
19254    WOLFSSL_ENTER("wolfSSL_CRYPTO_set_ex_data");
19255#ifdef MAX_EX_DATA
19256    if (ex_data && idx < MAX_EX_DATA && idx >= 0) {
19257#ifdef HAVE_EX_DATA_CLEANUP_HOOKS
19258        if (ex_data->ex_data_cleanup_routines[idx]) {
19259            /* call cleanup then remove cleanup callback,
19260             * since different value is being set */
19261            if (ex_data->ex_data[idx])
19262                ex_data->ex_data_cleanup_routines[idx](ex_data->ex_data[idx]);
19263            ex_data->ex_data_cleanup_routines[idx] = NULL;
19264        }
19265#endif
19266        ex_data->ex_data[idx] = data;
19267        return WOLFSSL_SUCCESS;
19268    }
19269#else
19270    (void)ex_data;
19271    (void)idx;
19272    (void)data;
19273#endif
19274    return WOLFSSL_FAILURE;
19275}
19276
19277#ifdef HAVE_EX_DATA_CLEANUP_HOOKS
19278int wolfSSL_CRYPTO_set_ex_data_with_cleanup(
19279    WOLFSSL_CRYPTO_EX_DATA* ex_data,
19280    int idx,
19281    void *data,
19282    wolfSSL_ex_data_cleanup_routine_t cleanup_routine)
19283{
19284    WOLFSSL_ENTER("wolfSSL_CRYPTO_set_ex_data_with_cleanup");
19285    if (ex_data && idx < MAX_EX_DATA && idx >= 0) {
19286        if (ex_data->ex_data_cleanup_routines[idx] && ex_data->ex_data[idx])
19287            ex_data->ex_data_cleanup_routines[idx](ex_data->ex_data[idx]);
19288        ex_data->ex_data[idx] = data;
19289        ex_data->ex_data_cleanup_routines[idx] = cleanup_routine;
19290        return WOLFSSL_SUCCESS;
19291    }
19292    return WOLFSSL_FAILURE;
19293}
19294#endif /* HAVE_EX_DATA_CLEANUP_HOOKS */
19295#endif /* HAVE_EX_DATA */
19296
19297#ifdef HAVE_EX_DATA_CRYPTO
19298/**
19299 * Issues unique index for the class specified by class_index.
19300 * Other parameter except class_index are ignored.
19301 * Currently, following class_index are accepted:
19302 *  - WOLF_CRYPTO_EX_INDEX_SSL
19303 *  - WOLF_CRYPTO_EX_INDEX_SSL_CTX
19304 *  - WOLF_CRYPTO_EX_INDEX_X509
19305 * @param class_index index one of CRYPTO_EX_INDEX_xxx
19306 * @param argp  parameters to be saved
19307 * @param argl  parameters to be saved
19308 * @param new_func a pointer to WOLFSSL_CRYPTO_EX_new
19309 * @param dup_func a pointer to WOLFSSL_CRYPTO_EX_dup
19310 * @param free_func a pointer to WOLFSSL_CRYPTO_EX_free
19311 * @return index value grater or equal to zero on success, -1 on failure.
19312 */
19313int wolfSSL_CRYPTO_get_ex_new_index(int class_index, long argl, void *argp,
19314                                           WOLFSSL_CRYPTO_EX_new* new_func,
19315                                           WOLFSSL_CRYPTO_EX_dup* dup_func,
19316                                           WOLFSSL_CRYPTO_EX_free* free_func)
19317{
19318    WOLFSSL_ENTER("wolfSSL_CRYPTO_get_ex_new_index");
19319
19320    return wolfssl_local_get_ex_new_index(class_index, argl, argp, new_func,
19321            dup_func, free_func);
19322}
19323#endif /* HAVE_EX_DATA_CRYPTO */
19324
19325/*******************************************************************************
19326 * END OF EX_DATA APIs
19327 ******************************************************************************/
19328
19329/*******************************************************************************
19330 * START OF BUF_MEM API
19331 ******************************************************************************/
19332
19333#if defined(OPENSSL_EXTRA)
19334
19335/* Begin functions for openssl/buffer.h */
19336WOLFSSL_BUF_MEM* wolfSSL_BUF_MEM_new(void)
19337{
19338    WOLFSSL_BUF_MEM* buf;
19339    buf = (WOLFSSL_BUF_MEM*)XMALLOC(sizeof(WOLFSSL_BUF_MEM), NULL,
19340                                                        DYNAMIC_TYPE_OPENSSL);
19341    if (buf) {
19342        XMEMSET(buf, 0, sizeof(WOLFSSL_BUF_MEM));
19343    }
19344    return buf;
19345}
19346
19347/* non-compat API returns length of buffer on success */
19348int wolfSSL_BUF_MEM_grow_ex(WOLFSSL_BUF_MEM* buf, size_t len,
19349        char zeroFill)
19350{
19351
19352    int len_int = (int)len;
19353    int mx;
19354    char* tmp;
19355
19356    /* verify provided arguments */
19357    if (buf == NULL || len_int < 0) {
19358        return 0; /* BAD_FUNC_ARG; */
19359    }
19360
19361    /* check to see if fits in existing length */
19362    if (buf->length > len) {
19363        buf->length = len;
19364        return len_int;
19365    }
19366
19367    /* check to see if fits in max buffer */
19368    if (buf->max >= len) {
19369        if (buf->data != NULL && zeroFill) {
19370            XMEMSET(&buf->data[buf->length], 0, len - buf->length);
19371        }
19372        buf->length = len;
19373        return len_int;
19374    }
19375
19376    /* expand size, to handle growth */
19377    mx = (len_int + 3) / 3 * 4;
19378
19379#ifdef WOLFSSL_NO_REALLOC
19380    tmp = (char*)XMALLOC(mx, NULL, DYNAMIC_TYPE_OPENSSL);
19381    if (tmp != NULL && buf->data != NULL) {
19382       XMEMCPY(tmp, buf->data, len_int);
19383       XFREE(buf->data, NULL, DYNAMIC_TYPE_OPENSSL);
19384       buf->data = NULL;
19385    }
19386#else
19387    /* use realloc */
19388    tmp = (char*)XREALLOC(buf->data, mx, NULL, DYNAMIC_TYPE_OPENSSL);
19389#endif
19390
19391    if (tmp == NULL) {
19392        return 0; /* ERR_R_MALLOC_FAILURE; */
19393    }
19394    buf->data = tmp;
19395
19396    buf->max = (size_t)mx;
19397    if (zeroFill)
19398        XMEMSET(&buf->data[buf->length], 0, len - buf->length);
19399    buf->length = len;
19400
19401    return len_int;
19402
19403}
19404
19405/* returns length of buffer on success */
19406int wolfSSL_BUF_MEM_grow(WOLFSSL_BUF_MEM* buf, size_t len)
19407{
19408    return wolfSSL_BUF_MEM_grow_ex(buf, len, 1);
19409}
19410
19411/* non-compat API returns length of buffer on success */
19412int wolfSSL_BUF_MEM_resize(WOLFSSL_BUF_MEM* buf, size_t len)
19413{
19414    char* tmp;
19415    int mx;
19416
19417    /* verify provided arguments */
19418    if (buf == NULL || len == 0 || (int)len <= 0) {
19419        return 0; /* BAD_FUNC_ARG; */
19420    }
19421
19422    if (len == buf->length)
19423        return (int)len;
19424
19425    if (len > buf->length)
19426        return wolfSSL_BUF_MEM_grow_ex(buf, len, 0);
19427
19428    /* expand size, to handle growth */
19429    mx = ((int)len + 3) / 3 * 4;
19430
19431    /* We want to shrink the internal buffer */
19432#ifdef WOLFSSL_NO_REALLOC
19433    tmp = (char*)XMALLOC(mx, NULL, DYNAMIC_TYPE_OPENSSL);
19434    if (tmp != NULL && buf->data != NULL)
19435    {
19436        XMEMCPY(tmp, buf->data, len);
19437        XFREE(buf->data,NULL,DYNAMIC_TYPE_OPENSSL);
19438        buf->data = NULL;
19439    }
19440#else
19441    tmp = (char*)XREALLOC(buf->data, mx, NULL, DYNAMIC_TYPE_OPENSSL);
19442#endif
19443
19444    if (tmp == NULL)
19445        return 0;
19446
19447    buf->data = tmp;
19448    buf->length = len;
19449    buf->max = (size_t)mx;
19450
19451    return (int)len;
19452}
19453
19454void wolfSSL_BUF_MEM_free(WOLFSSL_BUF_MEM* buf)
19455{
19456    if (buf) {
19457        XFREE(buf->data, NULL, DYNAMIC_TYPE_OPENSSL);
19458        buf->data = NULL;
19459        buf->max = 0;
19460        buf->length = 0;
19461        XFREE(buf, NULL, DYNAMIC_TYPE_OPENSSL);
19462    }
19463}
19464/* End Functions for openssl/buffer.h */
19465
19466#endif /* OPENSSL_EXTRA */
19467
19468/*******************************************************************************
19469 * END OF BUF_MEM API
19470 ******************************************************************************/
19471
19472#define WOLFSSL_CONF_INCLUDED
19473#include <src/conf.c>
19474
19475/*******************************************************************************
19476 * START OF RAND API
19477 ******************************************************************************/
19478
19479#if defined(OPENSSL_EXTRA) && !defined(WOLFSSL_NO_OPENSSL_RAND_CB)
19480static int wolfSSL_RAND_InitMutex(void)
19481{
19482#ifndef WOLFSSL_MUTEX_INITIALIZER
19483    if (gRandMethodsInit == 0) {
19484        if (wc_InitMutex(&gRandMethodMutex) != 0) {
19485            WOLFSSL_MSG("Bad Init Mutex rand methods");
19486            return BAD_MUTEX_E;
19487        }
19488        gRandMethodsInit = 1;
19489    }
19490#endif
19491    return 0;
19492}
19493#endif
19494
19495#ifdef OPENSSL_EXTRA
19496
19497#if defined(HAVE_GETPID) && !defined(WOLFSSL_NO_GETPID) && \
19498    ((defined(HAVE_FIPS) && FIPS_VERSION3_LE(6,0,0)) || defined(HAVE_SELFTEST))
19499/* In older FIPS bundles add check for reseed here since it does not exist in
19500 * the older random.c certified files. */
19501static pid_t currentRandPid = 0;
19502#endif
19503
19504/* Checks if the global RNG has been created. If not then one is created.
19505 *
19506 * Returns WOLFSSL_SUCCESS when no error is encountered.
19507 */
19508int wolfSSL_RAND_Init(void)
19509{
19510    int ret = WC_NO_ERR_TRACE(WOLFSSL_FAILURE);
19511#ifdef HAVE_GLOBAL_RNG
19512    if (wc_LockMutex(&globalRNGMutex) == 0) {
19513        if (initGlobalRNG == 0) {
19514            ret = wc_InitRng(&globalRNG);
19515            if (ret == 0) {
19516            #if defined(HAVE_GETPID) && !defined(WOLFSSL_NO_GETPID) && \
19517                ((defined(HAVE_FIPS) && FIPS_VERSION3_LE(6,0,0)) || \
19518                 defined(HAVE_SELFTEST))
19519
19520                currentRandPid = getpid();
19521            #endif
19522                initGlobalRNG = 1;
19523                ret = WOLFSSL_SUCCESS;
19524            }
19525        }
19526        else {
19527            /* GlobalRNG is already initialized */
19528            ret = WOLFSSL_SUCCESS;
19529        }
19530
19531        wc_UnLockMutex(&globalRNGMutex);
19532    }
19533#endif
19534    return ret;
19535}
19536
19537
19538/* WOLFSSL_SUCCESS on ok */
19539int wolfSSL_RAND_seed(const void* seed, int len)
19540{
19541#ifndef WOLFSSL_NO_OPENSSL_RAND_CB
19542    if (wolfSSL_RAND_InitMutex() == 0 && wc_LockMutex(&gRandMethodMutex) == 0) {
19543        if (gRandMethods && gRandMethods->seed) {
19544            int ret = gRandMethods->seed(seed, len);
19545            wc_UnLockMutex(&gRandMethodMutex);
19546            return ret;
19547        }
19548        wc_UnLockMutex(&gRandMethodMutex);
19549    }
19550#else
19551    (void)seed;
19552    (void)len;
19553#endif
19554
19555    /* Make sure global shared RNG (globalRNG) is initialized */
19556    return wolfSSL_RAND_Init();
19557}
19558
19559
19560/* Returns the path for reading seed data from.
19561 * Uses the env variable $RANDFILE first if set, if not then used $HOME/.rnd
19562 *
19563 * Note uses stdlib by default unless XGETENV macro is overwritten
19564 *
19565 * fname buffer to hold path
19566 * len   length of fname buffer
19567 *
19568 * Returns a pointer to fname on success and NULL on failure
19569 */
19570const char* wolfSSL_RAND_file_name(char* fname, unsigned long len)
19571{
19572#if !defined(NO_FILESYSTEM) && defined(XGETENV) && !defined(NO_GETENV)
19573    char* rt;
19574
19575    WOLFSSL_ENTER("wolfSSL_RAND_file_name");
19576
19577    if (fname == NULL) {
19578        return NULL;
19579    }
19580
19581    XMEMSET(fname, 0, len);
19582
19583/* // NOLINTBEGIN(concurrency-mt-unsafe) */
19584    if ((rt = XGETENV("RANDFILE")) != NULL) {
19585        if (len > XSTRLEN(rt)) {
19586            XMEMCPY(fname, rt, XSTRLEN(rt));
19587        }
19588        else {
19589            WOLFSSL_MSG("RANDFILE too large for buffer");
19590            rt = NULL;
19591        }
19592    }
19593/* // NOLINTEND(concurrency-mt-unsafe) */
19594
19595    /* $RANDFILE was not set or is too large, check $HOME */
19596    if (rt == NULL) {
19597        const char ap[] = "/.rnd";
19598
19599        WOLFSSL_MSG("Environment variable RANDFILE not set");
19600
19601/* // NOLINTBEGIN(concurrency-mt-unsafe) */
19602        if ((rt = XGETENV("HOME")) == NULL) {
19603            #ifdef XALTHOMEVARNAME
19604            if ((rt = XGETENV(XALTHOMEVARNAME)) == NULL) {
19605                WOLFSSL_MSG("Environment variable HOME and " XALTHOMEVARNAME
19606                            " not set");
19607                return NULL;
19608            }
19609            #else
19610            WOLFSSL_MSG("Environment variable HOME not set");
19611            return NULL;
19612            #endif
19613        }
19614/* // NOLINTEND(concurrency-mt-unsafe) */
19615
19616        if (len > XSTRLEN(rt) + XSTRLEN(ap)) {
19617            fname[0] = '\0';
19618            XSTRNCAT(fname, rt, len);
19619            XSTRNCAT(fname, ap, len - XSTRLEN(rt));
19620            return fname;
19621        }
19622        else {
19623            WOLFSSL_MSG("Path too large for buffer");
19624            return NULL;
19625        }
19626    }
19627
19628    return fname;
19629#else
19630    WOLFSSL_ENTER("wolfSSL_RAND_file_name");
19631    WOLFSSL_MSG("RAND_file_name requires filesystem and getenv support, "
19632                "not compiled in");
19633    (void)fname;
19634    (void)len;
19635    return NULL;
19636#endif
19637}
19638
19639
19640/* Writes 1024 bytes from the RNG to the given file name.
19641 *
19642 * fname name of file to write to
19643 *
19644 * Returns the number of bytes written
19645 */
19646int wolfSSL_RAND_write_file(const char* fname)
19647{
19648    int bytes = 0;
19649
19650    WOLFSSL_ENTER("wolfSSL_RAND_write_file");
19651
19652    if (fname == NULL) {
19653        return WOLFSSL_FAILURE;
19654    }
19655
19656#ifndef NO_FILESYSTEM
19657    {
19658    #ifndef WOLFSSL_SMALL_STACK
19659        unsigned char buf[1024];
19660    #else
19661        unsigned char* buf = (unsigned char *)XMALLOC(1024, NULL,
19662                                                       DYNAMIC_TYPE_TMP_BUFFER);
19663        if (buf == NULL) {
19664            WOLFSSL_MSG("malloc failed");
19665            return WOLFSSL_FAILURE;
19666        }
19667    #endif
19668        bytes = 1024; /* default size of buf */
19669
19670        if (initGlobalRNG == 0 && wolfSSL_RAND_Init() != WOLFSSL_SUCCESS) {
19671            WOLFSSL_MSG("No RNG to use");
19672            WC_FREE_VAR_EX(buf, NULL, DYNAMIC_TYPE_TMP_BUFFER);
19673            return 0;
19674        }
19675
19676        if (wc_RNG_GenerateBlock(&globalRNG, buf, (word32)bytes) != 0) {
19677            WOLFSSL_MSG("Error generating random buffer");
19678            bytes = 0;
19679        }
19680        else {
19681            XFILE f;
19682
19683        #ifdef WOLFSSL_CHECK_MEM_ZERO
19684            wc_MemZero_Add("wolfSSL_RAND_write_file buf", buf, bytes);
19685        #endif
19686
19687            f = XFOPEN(fname, "wb");
19688            if (f == XBADFILE) {
19689                WOLFSSL_MSG("Error opening the file");
19690                bytes = 0;
19691            }
19692            else {
19693                size_t bytes_written = XFWRITE(buf, 1, (size_t)bytes, f);
19694                bytes = (int)bytes_written;
19695                XFCLOSE(f);
19696            }
19697        }
19698        ForceZero(buf, (word32)bytes);
19699    #ifdef WOLFSSL_SMALL_STACK
19700        XFREE(buf, NULL, DYNAMIC_TYPE_TMP_BUFFER);
19701    #elif defined(WOLFSSL_CHECK_MEM_ZERO)
19702        wc_MemZero_Check(buf, sizeof(buf));
19703    #endif
19704    }
19705#endif
19706
19707    return bytes;
19708}
19709
19710#ifndef FREERTOS_TCP
19711
19712/* These constant values are protocol values made by egd */
19713#if defined(USE_WOLFSSL_IO) && !defined(USE_WINDOWS_API) && \
19714    !defined(HAVE_FIPS) && defined(HAVE_HASHDRBG) && !defined(NETOS) && \
19715    defined(HAVE_SYS_UN_H)
19716    #define WOLFSSL_EGD_NBLOCK 0x01
19717    #include <sys/un.h>
19718#endif
19719
19720/* This collects entropy from the path nm and seeds the global PRNG with it.
19721 *
19722 * nm is the file path to the egd server
19723 *
19724 * Returns the number of bytes read.
19725 */
19726int wolfSSL_RAND_egd(const char* nm)
19727{
19728#ifdef WOLFSSL_EGD_NBLOCK
19729    struct sockaddr_un rem;
19730    int fd;
19731    int ret = WOLFSSL_SUCCESS;
19732    word32 bytes = 0;
19733    word32 idx   = 0;
19734#ifndef WOLFSSL_SMALL_STACK
19735    unsigned char buf[256];
19736#else
19737    unsigned char* buf;
19738    buf = (unsigned char*)XMALLOC(256, NULL, DYNAMIC_TYPE_TMP_BUFFER);
19739    if (buf == NULL) {
19740        WOLFSSL_MSG("Not enough memory");
19741        return WOLFSSL_FATAL_ERROR;
19742    }
19743#endif
19744
19745    XMEMSET(&rem, 0, sizeof(struct sockaddr_un));
19746    if (nm == NULL) {
19747        WC_FREE_VAR_EX(buf, NULL, DYNAMIC_TYPE_TMP_BUFFER);
19748        return WOLFSSL_FATAL_ERROR;
19749    }
19750
19751    fd = wc_socket_cloexec(AF_UNIX, SOCK_STREAM, 0);
19752    if (fd < 0) {
19753        WOLFSSL_MSG("Error creating socket");
19754        WC_FREE_VAR_EX(buf, NULL, DYNAMIC_TYPE_TMP_BUFFER);
19755        return WOLFSSL_FATAL_ERROR;
19756    }
19757    rem.sun_family = AF_UNIX;
19758    XSTRNCPY(rem.sun_path, nm, sizeof(rem.sun_path) - 1);
19759    rem.sun_path[sizeof(rem.sun_path)-1] = '\0';
19760
19761    /* connect to egd server */
19762    if (connect(fd, (struct sockaddr*)&rem, sizeof(struct sockaddr_un)) == -1) {
19763        WOLFSSL_MSG("error connecting to egd server");
19764        ret = WOLFSSL_FATAL_ERROR;
19765    }
19766
19767#ifdef WOLFSSL_CHECK_MEM_ZERO
19768    if (ret == WOLFSSL_SUCCESS) {
19769        wc_MemZero_Add("wolfSSL_RAND_egd buf", buf, 256);
19770    }
19771#endif
19772    while (ret == WOLFSSL_SUCCESS && bytes < 255 && idx + 2 < 256) {
19773        buf[idx]     = WOLFSSL_EGD_NBLOCK;
19774        buf[idx + 1] = 255 - bytes; /* request 255 bytes from server */
19775        ret = (int)write(fd, buf + idx, 2);
19776        if (ret != 2) {
19777            if (errno == EAGAIN) {
19778                ret = WOLFSSL_SUCCESS;
19779                continue;
19780            }
19781            WOLFSSL_MSG("error requesting entropy from egd server");
19782            ret = WOLFSSL_FATAL_ERROR;
19783            break;
19784        }
19785
19786        /* attempting to read */
19787        buf[idx] = 0;
19788        ret = (int)read(fd, buf + idx, 256 - bytes);
19789        if (ret == 0) {
19790            WOLFSSL_MSG("error reading entropy from egd server");
19791            ret = WOLFSSL_FATAL_ERROR;
19792            break;
19793        }
19794        if (ret > 0 && buf[idx] > 0) {
19795            bytes += buf[idx]; /* egd stores amount sent in first byte */
19796            if (bytes + idx > 255 || buf[idx] > ret) {
19797                WOLFSSL_MSG("Buffer error");
19798                ret = WOLFSSL_FATAL_ERROR;
19799                break;
19800            }
19801            XMEMMOVE(buf + idx, buf + idx + 1, buf[idx]);
19802            idx = bytes;
19803            ret = WOLFSSL_SUCCESS;
19804            if (bytes >= 255) {
19805                break;
19806            }
19807        }
19808        else {
19809            if (errno == EAGAIN || errno == EINTR) {
19810                WOLFSSL_MSG("EGD would read");
19811                ret = WOLFSSL_SUCCESS; /* try again */
19812            }
19813            else if (buf[idx] == 0) {
19814                /* if egd returned 0 then there is no more entropy to be had.
19815                   Do not try more reads. */
19816                ret = WOLFSSL_SUCCESS;
19817                break;
19818            }
19819            else {
19820                WOLFSSL_MSG("Error with read");
19821                ret = WOLFSSL_FATAL_ERROR;
19822            }
19823        }
19824    }
19825
19826    if (bytes > 0 && ret == WOLFSSL_SUCCESS) {
19827        /* call to check global RNG is created */
19828        if (wolfSSL_RAND_Init() != WOLFSSL_SUCCESS) {
19829            WOLFSSL_MSG("Error with initializing global RNG structure");
19830            ret = WOLFSSL_FATAL_ERROR;
19831        }
19832        else if (wc_RNG_DRBG_Reseed(&globalRNG, (const byte*) buf, bytes)
19833                != 0) {
19834            WOLFSSL_MSG("Error with reseeding DRBG structure");
19835            ret = WOLFSSL_FATAL_ERROR;
19836        }
19837        #ifdef SHOW_SECRETS
19838        else { /* print out entropy found only when no error occurred */
19839            word32 i;
19840            printf("EGD Entropy = ");
19841            for (i = 0; i < bytes; i++) {
19842                printf("%02X", buf[i]);
19843            }
19844            printf("\n");
19845        }
19846        #endif
19847    }
19848
19849    ForceZero(buf, bytes);
19850#ifdef WOLFSSL_SMALL_STACK
19851    XFREE(buf, NULL, DYNAMIC_TYPE_TMP_BUFFER);
19852#elif defined(WOLFSSL_CHECK_MEM_ZERO)
19853    wc_MemZero_Check(buf, 256);
19854#endif
19855    close(fd);
19856
19857    if (ret == WOLFSSL_SUCCESS) {
19858        return (int)bytes;
19859    }
19860    else {
19861        return ret;
19862    }
19863#else
19864    WOLFSSL_MSG("Type of socket needed is not available");
19865    WOLFSSL_MSG("\tor using mode where DRBG API is not available");
19866    (void)nm;
19867
19868    return WOLFSSL_FATAL_ERROR;
19869#endif /* WOLFSSL_EGD_NBLOCK */
19870}
19871
19872#endif /* !FREERTOS_TCP */
19873
19874void wolfSSL_RAND_Cleanup(void)
19875{
19876#ifndef WOLFSSL_NO_OPENSSL_RAND_CB
19877    if (wolfSSL_RAND_InitMutex() == 0 && wc_LockMutex(&gRandMethodMutex) == 0) {
19878        if (gRandMethods && gRandMethods->cleanup)
19879            gRandMethods->cleanup();
19880        wc_UnLockMutex(&gRandMethodMutex);
19881    }
19882
19883    #ifndef WOLFSSL_MUTEX_INITIALIZER
19884    if (wc_FreeMutex(&gRandMethodMutex) == 0)
19885        gRandMethodsInit = 0;
19886    #endif
19887#endif
19888#ifdef HAVE_GLOBAL_RNG
19889    if (wc_LockMutex(&globalRNGMutex) == 0) {
19890        if (initGlobalRNG) {
19891            wc_FreeRng(&globalRNG);
19892            initGlobalRNG = 0;
19893        }
19894        wc_UnLockMutex(&globalRNGMutex);
19895    }
19896#endif
19897}
19898
19899/* returns WOLFSSL_SUCCESS if the bytes generated are valid otherwise
19900 * WOLFSSL_FAILURE */
19901int wolfSSL_RAND_pseudo_bytes(unsigned char* buf, int num)
19902{
19903    int ret;
19904    int hash;
19905    byte secret[DRBG_SEED_LEN]; /* secret length arbitrarily chosen */
19906
19907#ifndef WOLFSSL_NO_OPENSSL_RAND_CB
19908    if (wolfSSL_RAND_InitMutex() == 0 && wc_LockMutex(&gRandMethodMutex) == 0) {
19909        if (gRandMethods && gRandMethods->pseudorand) {
19910            ret = gRandMethods->pseudorand(buf, num);
19911            wc_UnLockMutex(&gRandMethodMutex);
19912            return ret;
19913        }
19914        wc_UnLockMutex(&gRandMethodMutex);
19915    }
19916#endif
19917
19918#ifdef WOLFSSL_HAVE_PRF
19919    #ifndef NO_SHA256
19920    hash = WC_SHA256;
19921    #elif defined(WOLFSSL_SHA384)
19922    hash = WC_SHA384;
19923    #elif !defined(NO_SHA)
19924    hash = WC_SHA;
19925    #elif !defined(NO_MD5)
19926    hash = WC_MD5;
19927    #endif
19928
19929    /* get secret value from source of entropy */
19930    ret = wolfSSL_RAND_bytes(secret, DRBG_SEED_LEN);
19931
19932    /* uses input buffer to seed for pseudo random number generation, each
19933     * thread will potentially have different results this way */
19934    if (ret == WOLFSSL_SUCCESS) {
19935        PRIVATE_KEY_UNLOCK();
19936        ret = wc_PRF(buf, num, secret, DRBG_SEED_LEN, (const byte*)buf, num,
19937                hash, NULL, INVALID_DEVID);
19938        PRIVATE_KEY_LOCK();
19939        ret = (ret == 0) ? WOLFSSL_SUCCESS: WOLFSSL_FAILURE;
19940    }
19941#else
19942    /* fall back to just doing wolfSSL_RAND_bytes if PRF not avialbale */
19943    ret = wolfSSL_RAND_bytes(buf, num);
19944    (void)hash;
19945    (void)secret;
19946#endif
19947    return ret;
19948}
19949
19950/* returns WOLFSSL_SUCCESS (1) if the bytes generated are valid otherwise 0
19951 * on failure */
19952int wolfSSL_RAND_bytes(unsigned char* buf, int num)
19953{
19954    int     ret = 0;
19955    WC_RNG* rng = NULL;
19956    WC_DECLARE_VAR(tmpRNG, WC_RNG, 1, 0);
19957    int initTmpRng = 0;
19958#ifdef HAVE_GLOBAL_RNG
19959    int used_global = 0;
19960#endif
19961
19962    WOLFSSL_ENTER("wolfSSL_RAND_bytes");
19963    /* sanity check */
19964    if (buf == NULL || num < 0)
19965        /* return code compliant with OpenSSL */
19966        return 0;
19967
19968    /* if a RAND callback has been set try and use it */
19969#ifndef WOLFSSL_NO_OPENSSL_RAND_CB
19970    if (wolfSSL_RAND_InitMutex() == 0 && wc_LockMutex(&gRandMethodMutex) == 0) {
19971        if (gRandMethods && gRandMethods->bytes) {
19972            ret = gRandMethods->bytes(buf, num);
19973            wc_UnLockMutex(&gRandMethodMutex);
19974            return ret;
19975        }
19976        wc_UnLockMutex(&gRandMethodMutex);
19977    }
19978#endif
19979#ifdef HAVE_GLOBAL_RNG
19980    if (initGlobalRNG) {
19981        if (wc_LockMutex(&globalRNGMutex) != 0) {
19982            WOLFSSL_MSG("Bad Lock Mutex rng");
19983            return ret;
19984        }
19985        /* the above access to initGlobalRNG is racey -- recheck it now that we
19986         * have the lock.
19987         */
19988        if (initGlobalRNG) {
19989        #if defined(HAVE_GETPID) && !defined(WOLFSSL_NO_GETPID) && \
19990                ((defined(HAVE_FIPS) && FIPS_VERSION3_LE(6,0,0)) || \
19991                 defined(HAVE_SELFTEST))
19992            pid_t p;
19993
19994            p = getpid();
19995            if (p != currentRandPid) {
19996                wc_UnLockMutex(&globalRNGMutex);
19997                if (wolfSSL_RAND_poll() != WOLFSSL_SUCCESS) {
19998                    WOLFSSL_MSG("Issue with check pid and reseed");
19999                    ret = WOLFSSL_FAILURE;
20000                }
20001
20002                /* reclaim lock after wolfSSL_RAND_poll */
20003                if (wc_LockMutex(&globalRNGMutex) != 0) {
20004                    WOLFSSL_MSG("Bad Lock Mutex rng");
20005                    return ret;
20006                }
20007                currentRandPid = p;
20008            }
20009        #endif
20010            rng = &globalRNG;
20011            used_global = 1;
20012        }
20013        else {
20014            wc_UnLockMutex(&globalRNGMutex);
20015        }
20016    }
20017
20018    if (used_global == 0)
20019#endif
20020    {
20021        WC_ALLOC_VAR_EX(tmpRNG, WC_RNG, 1, NULL, DYNAMIC_TYPE_RNG,
20022            return ret);
20023        if (wc_InitRng(tmpRNG) == 0) {
20024            rng = tmpRNG;
20025            initTmpRng = 1;
20026        }
20027    }
20028    if (rng) {
20029        /* handles size greater than RNG_MAX_BLOCK_LEN */
20030        int blockCount = num / RNG_MAX_BLOCK_LEN;
20031
20032        while (blockCount--) {
20033            ret = wc_RNG_GenerateBlock(rng, buf, RNG_MAX_BLOCK_LEN);
20034            if (ret != 0) {
20035                WOLFSSL_MSG("Bad wc_RNG_GenerateBlock");
20036                break;
20037            }
20038            num -= RNG_MAX_BLOCK_LEN;
20039            buf += RNG_MAX_BLOCK_LEN;
20040        }
20041
20042        if (ret == 0 && num)
20043            ret = wc_RNG_GenerateBlock(rng, buf, (word32)num);
20044
20045        if (ret != 0)
20046            WOLFSSL_MSG("Bad wc_RNG_GenerateBlock");
20047        else
20048            ret = WOLFSSL_SUCCESS;
20049    }
20050
20051#ifdef HAVE_GLOBAL_RNG
20052    if (used_global == 1)
20053        wc_UnLockMutex(&globalRNGMutex);
20054#endif
20055    if (initTmpRng)
20056        wc_FreeRng(tmpRNG);
20057    WC_FREE_VAR_EX(tmpRNG, NULL, DYNAMIC_TYPE_RNG);
20058
20059    return ret;
20060}
20061
20062
20063int wolfSSL_RAND_poll(void)
20064{
20065    byte  entropy[16];
20066    int  ret = 0;
20067    word32 entropy_sz = 16;
20068
20069    WOLFSSL_ENTER("wolfSSL_RAND_poll");
20070    if (initGlobalRNG == 0){
20071        WOLFSSL_MSG("Global RNG no Init");
20072        return  WOLFSSL_FAILURE;
20073    }
20074    ret = wc_GenerateSeed(&globalRNG.seed, entropy, entropy_sz);
20075    if (ret != 0) {
20076        WOLFSSL_MSG("Bad wc_RNG_GenerateBlock");
20077        ret = WOLFSSL_FAILURE;
20078    }
20079    else {
20080#ifdef HAVE_HASHDRBG
20081        if (wc_LockMutex(&globalRNGMutex) != 0) {
20082            WOLFSSL_MSG("Bad Lock Mutex rng");
20083            return ret;
20084        }
20085
20086        ret = wc_RNG_DRBG_Reseed(&globalRNG, entropy, entropy_sz);
20087        if (ret != 0) {
20088            WOLFSSL_MSG("Error reseeding DRBG");
20089            ret = WOLFSSL_FAILURE;
20090        }
20091        else {
20092            ret = WOLFSSL_SUCCESS;
20093        }
20094        wc_UnLockMutex(&globalRNGMutex);
20095#elif defined(HAVE_INTEL_RDRAND)
20096        WOLFSSL_MSG("Not polling with RAND_poll, RDRAND used without "
20097                    "HAVE_HASHDRBG");
20098        ret = WOLFSSL_SUCCESS;
20099#else
20100        WOLFSSL_MSG("RAND_poll called with HAVE_HASHDRBG not set");
20101        ret = WOLFSSL_FAILURE;
20102#endif
20103    }
20104
20105    return ret;
20106}
20107
20108    /* If a valid struct is provided with function pointers, will override
20109       RAND_seed, bytes, cleanup, add, pseudo_bytes and status.  If a NULL
20110       pointer is passed in, it will cancel any previous function overrides.
20111
20112       Returns WOLFSSL_SUCCESS on success, WOLFSSL_FAILURE on failure. */
20113    int wolfSSL_RAND_set_rand_method(const WOLFSSL_RAND_METHOD *methods)
20114    {
20115    #ifndef WOLFSSL_NO_OPENSSL_RAND_CB
20116        if (wolfSSL_RAND_InitMutex() == 0 &&
20117                wc_LockMutex(&gRandMethodMutex) == 0) {
20118            gRandMethods = methods;
20119            wc_UnLockMutex(&gRandMethodMutex);
20120            return WOLFSSL_SUCCESS;
20121        }
20122    #else
20123        (void)methods;
20124    #endif
20125        return WOLFSSL_FAILURE;
20126    }
20127
20128    /* Returns WOLFSSL_SUCCESS if the RNG has been seeded with enough data */
20129    int wolfSSL_RAND_status(void)
20130    {
20131        int ret = WOLFSSL_SUCCESS;
20132    #ifndef WOLFSSL_NO_OPENSSL_RAND_CB
20133        if (wolfSSL_RAND_InitMutex() == 0 &&
20134                wc_LockMutex(&gRandMethodMutex) == 0) {
20135            if (gRandMethods && gRandMethods->status)
20136                ret = gRandMethods->status();
20137            wc_UnLockMutex(&gRandMethodMutex);
20138        }
20139        else {
20140            ret = WOLFSSL_FAILURE;
20141        }
20142    #else
20143        /* wolfCrypt provides enough seed internally, so return success */
20144    #endif
20145        return ret;
20146    }
20147
20148    void wolfSSL_RAND_add(const void* add, int len, double entropy)
20149    {
20150    #ifndef WOLFSSL_NO_OPENSSL_RAND_CB
20151        if (wolfSSL_RAND_InitMutex() == 0 &&
20152                wc_LockMutex(&gRandMethodMutex) == 0) {
20153            if (gRandMethods && gRandMethods->add) {
20154                /* callback has return code, but RAND_add does not */
20155                (void)gRandMethods->add(add, len, entropy);
20156            }
20157            wc_UnLockMutex(&gRandMethodMutex);
20158        }
20159    #else
20160        /* wolfSSL seeds/adds internally, use explicit RNG if you want
20161           to take control */
20162        (void)add;
20163        (void)len;
20164        (void)entropy;
20165    #endif
20166    }
20167
20168
20169#ifndef NO_WOLFSSL_STUB
20170void wolfSSL_RAND_screen(void)
20171{
20172    WOLFSSL_STUB("RAND_screen");
20173}
20174#endif
20175
20176int wolfSSL_RAND_load_file(const char* fname, long len)
20177{
20178    (void)fname;
20179    /* wolfCrypt provides enough entropy internally or will report error */
20180    if (len == -1)
20181        return 1024;
20182    else
20183        return (int)len;
20184}
20185
20186#endif /* OPENSSL_EXTRA */
20187
20188/*******************************************************************************
20189 * END OF RAND API
20190 ******************************************************************************/
20191
20192/*******************************************************************************
20193 * START OF EVP_CIPHER API
20194 ******************************************************************************/
20195
20196#ifdef OPENSSL_EXTRA
20197
20198    /* store for external read of iv, WOLFSSL_SUCCESS on success */
20199    int  wolfSSL_StoreExternalIV(WOLFSSL_EVP_CIPHER_CTX* ctx)
20200    {
20201        WOLFSSL_ENTER("wolfSSL_StoreExternalIV");
20202
20203        if (ctx == NULL) {
20204            WOLFSSL_MSG("Bad function argument");
20205            return WOLFSSL_FATAL_ERROR;
20206        }
20207
20208        switch (ctx->cipherType) {
20209#ifndef NO_AES
20210#if defined(HAVE_AES_CBC) || defined(WOLFSSL_AES_DIRECT)
20211            case WC_AES_128_CBC_TYPE :
20212            case WC_AES_192_CBC_TYPE :
20213            case WC_AES_256_CBC_TYPE :
20214                WOLFSSL_MSG("AES CBC");
20215                XMEMCPY(ctx->iv, &ctx->cipher.aes.reg, ctx->ivSz);
20216                break;
20217#endif
20218#ifdef HAVE_AESGCM
20219            case WC_AES_128_GCM_TYPE :
20220            case WC_AES_192_GCM_TYPE :
20221            case WC_AES_256_GCM_TYPE :
20222                WOLFSSL_MSG("AES GCM");
20223                XMEMCPY(ctx->iv, &ctx->cipher.aes.reg, ctx->ivSz);
20224                break;
20225#endif /* HAVE_AESGCM */
20226#ifdef HAVE_AESCCM
20227            case WC_AES_128_CCM_TYPE :
20228            case WC_AES_192_CCM_TYPE :
20229            case WC_AES_256_CCM_TYPE :
20230                WOLFSSL_MSG("AES CCM");
20231                XMEMCPY(ctx->iv, &ctx->cipher.aes.reg, ctx->ivSz);
20232                break;
20233#endif /* HAVE_AESCCM */
20234#ifdef HAVE_AES_ECB
20235            case WC_AES_128_ECB_TYPE :
20236            case WC_AES_192_ECB_TYPE :
20237            case WC_AES_256_ECB_TYPE :
20238                WOLFSSL_MSG("AES ECB");
20239                break;
20240#endif
20241#ifdef WOLFSSL_AES_COUNTER
20242            case WC_AES_128_CTR_TYPE :
20243            case WC_AES_192_CTR_TYPE :
20244            case WC_AES_256_CTR_TYPE :
20245                WOLFSSL_MSG("AES CTR");
20246                XMEMCPY(ctx->iv, &ctx->cipher.aes.reg, WC_AES_BLOCK_SIZE);
20247                break;
20248#endif /* WOLFSSL_AES_COUNTER */
20249#ifdef WOLFSSL_AES_CFB
20250#if !defined(HAVE_SELFTEST) && !defined(HAVE_FIPS)
20251            case WC_AES_128_CFB1_TYPE:
20252            case WC_AES_192_CFB1_TYPE:
20253            case WC_AES_256_CFB1_TYPE:
20254                WOLFSSL_MSG("AES CFB1");
20255                break;
20256            case WC_AES_128_CFB8_TYPE:
20257            case WC_AES_192_CFB8_TYPE:
20258            case WC_AES_256_CFB8_TYPE:
20259                WOLFSSL_MSG("AES CFB8");
20260                break;
20261#endif /* !HAVE_SELFTEST && !HAVE_FIPS */
20262            case WC_AES_128_CFB128_TYPE:
20263            case WC_AES_192_CFB128_TYPE:
20264            case WC_AES_256_CFB128_TYPE:
20265                WOLFSSL_MSG("AES CFB128");
20266                break;
20267#endif /* WOLFSSL_AES_CFB */
20268#if defined(WOLFSSL_AES_OFB)
20269            case WC_AES_128_OFB_TYPE:
20270            case WC_AES_192_OFB_TYPE:
20271            case WC_AES_256_OFB_TYPE:
20272                WOLFSSL_MSG("AES OFB");
20273                break;
20274#endif /* WOLFSSL_AES_OFB */
20275#ifdef WOLFSSL_AES_XTS
20276            case WC_AES_128_XTS_TYPE:
20277            case WC_AES_256_XTS_TYPE:
20278                WOLFSSL_MSG("AES XTS");
20279                break;
20280#endif /* WOLFSSL_AES_XTS */
20281#endif /* NO_AES */
20282
20283#ifdef HAVE_ARIA
20284            case WC_ARIA_128_GCM_TYPE :
20285            case WC_ARIA_192_GCM_TYPE :
20286            case WC_ARIA_256_GCM_TYPE :
20287                WOLFSSL_MSG("ARIA GCM");
20288                XMEMCPY(ctx->iv, &ctx->cipher.aria.nonce, ARIA_BLOCK_SIZE);
20289                break;
20290#endif /* HAVE_ARIA */
20291
20292#ifndef NO_DES3
20293            case WC_DES_CBC_TYPE :
20294                WOLFSSL_MSG("DES CBC");
20295                XMEMCPY(ctx->iv, &ctx->cipher.des.reg, DES_BLOCK_SIZE);
20296                break;
20297
20298            case WC_DES_EDE3_CBC_TYPE :
20299                WOLFSSL_MSG("DES EDE3 CBC");
20300                XMEMCPY(ctx->iv, &ctx->cipher.des3.reg, DES_BLOCK_SIZE);
20301                break;
20302#endif
20303#ifdef WOLFSSL_DES_ECB
20304            case WC_DES_ECB_TYPE :
20305                WOLFSSL_MSG("DES ECB");
20306                break;
20307            case WC_DES_EDE3_ECB_TYPE :
20308                WOLFSSL_MSG("DES3 ECB");
20309                break;
20310#endif
20311            case WC_ARC4_TYPE :
20312                WOLFSSL_MSG("ARC4");
20313                break;
20314
20315#if defined(HAVE_CHACHA) && defined(HAVE_POLY1305)
20316            case WC_CHACHA20_POLY1305_TYPE:
20317                break;
20318#endif
20319
20320#ifdef HAVE_CHACHA
20321            case WC_CHACHA20_TYPE:
20322                break;
20323#endif
20324
20325#ifdef WOLFSSL_SM4_ECB
20326            case WC_SM4_ECB_TYPE:
20327                break;
20328#endif
20329#ifdef WOLFSSL_SM4_CBC
20330            case WC_SM4_CBC_TYPE:
20331                WOLFSSL_MSG("SM4 CBC");
20332                XMEMCPY(&ctx->cipher.sm4.iv, ctx->iv, SM4_BLOCK_SIZE);
20333                break;
20334#endif
20335#ifdef WOLFSSL_SM4_CTR
20336            case WC_SM4_CTR_TYPE:
20337                WOLFSSL_MSG("SM4 CTR");
20338                XMEMCPY(&ctx->cipher.sm4.iv, ctx->iv, SM4_BLOCK_SIZE);
20339                break;
20340#endif
20341#ifdef WOLFSSL_SM4_GCM
20342            case WC_SM4_GCM_TYPE:
20343                WOLFSSL_MSG("SM4 GCM");
20344                XMEMCPY(&ctx->cipher.sm4.iv, ctx->iv, SM4_BLOCK_SIZE);
20345                break;
20346#endif
20347#ifdef WOLFSSL_SM4_CCM
20348            case WC_SM4_CCM_TYPE:
20349                WOLFSSL_MSG("SM4 CCM");
20350                XMEMCPY(&ctx->cipher.sm4.iv, ctx->iv, SM4_BLOCK_SIZE);
20351                break;
20352#endif
20353
20354            case WC_NULL_CIPHER_TYPE :
20355                WOLFSSL_MSG("NULL");
20356                break;
20357
20358            default: {
20359                WOLFSSL_MSG("bad type");
20360                return WOLFSSL_FATAL_ERROR;
20361            }
20362        }
20363        return WOLFSSL_SUCCESS;
20364    }
20365
20366    /* set internal IV from external, WOLFSSL_SUCCESS on success */
20367    int  wolfSSL_SetInternalIV(WOLFSSL_EVP_CIPHER_CTX* ctx)
20368    {
20369
20370        WOLFSSL_ENTER("wolfSSL_SetInternalIV");
20371
20372        if (ctx == NULL) {
20373            WOLFSSL_MSG("Bad function argument");
20374            return WOLFSSL_FATAL_ERROR;
20375        }
20376
20377        switch (ctx->cipherType) {
20378
20379#ifndef NO_AES
20380#if defined(HAVE_AES_CBC) || defined(WOLFSSL_AES_DIRECT)
20381            case WC_AES_128_CBC_TYPE :
20382            case WC_AES_192_CBC_TYPE :
20383            case WC_AES_256_CBC_TYPE :
20384                WOLFSSL_MSG("AES CBC");
20385                XMEMCPY(&ctx->cipher.aes.reg, ctx->iv, WC_AES_BLOCK_SIZE);
20386                break;
20387#endif
20388#ifdef HAVE_AESGCM
20389            case WC_AES_128_GCM_TYPE :
20390            case WC_AES_192_GCM_TYPE :
20391            case WC_AES_256_GCM_TYPE :
20392                WOLFSSL_MSG("AES GCM");
20393                XMEMCPY(&ctx->cipher.aes.reg, ctx->iv, WC_AES_BLOCK_SIZE);
20394                break;
20395#endif
20396#ifdef HAVE_AES_ECB
20397            case WC_AES_128_ECB_TYPE :
20398            case WC_AES_192_ECB_TYPE :
20399            case WC_AES_256_ECB_TYPE :
20400                WOLFSSL_MSG("AES ECB");
20401                break;
20402#endif
20403#ifdef WOLFSSL_AES_COUNTER
20404            case WC_AES_128_CTR_TYPE :
20405            case WC_AES_192_CTR_TYPE :
20406            case WC_AES_256_CTR_TYPE :
20407                WOLFSSL_MSG("AES CTR");
20408                XMEMCPY(&ctx->cipher.aes.reg, ctx->iv, WC_AES_BLOCK_SIZE);
20409                break;
20410#endif
20411
20412#endif /* NO_AES */
20413
20414#ifdef HAVE_ARIA
20415            case WC_ARIA_128_GCM_TYPE :
20416            case WC_ARIA_192_GCM_TYPE :
20417            case WC_ARIA_256_GCM_TYPE :
20418                WOLFSSL_MSG("ARIA GCM");
20419                XMEMCPY(&ctx->cipher.aria.nonce, ctx->iv, ARIA_BLOCK_SIZE);
20420                break;
20421#endif /* HAVE_ARIA */
20422
20423#ifndef NO_DES3
20424            case WC_DES_CBC_TYPE :
20425                WOLFSSL_MSG("DES CBC");
20426                XMEMCPY(&ctx->cipher.des.reg, ctx->iv, DES_BLOCK_SIZE);
20427                break;
20428
20429            case WC_DES_EDE3_CBC_TYPE :
20430                WOLFSSL_MSG("DES EDE3 CBC");
20431                XMEMCPY(&ctx->cipher.des3.reg, ctx->iv, DES_BLOCK_SIZE);
20432                break;
20433#endif
20434#ifdef WOLFSSL_DES_ECB
20435            case WC_DES_ECB_TYPE :
20436                WOLFSSL_MSG("DES ECB");
20437                break;
20438            case WC_DES_EDE3_ECB_TYPE :
20439                WOLFSSL_MSG("DES3 ECB");
20440                break;
20441#endif
20442
20443            case WC_ARC4_TYPE :
20444                WOLFSSL_MSG("ARC4");
20445                break;
20446
20447#if defined(HAVE_CHACHA) && defined(HAVE_POLY1305)
20448            case WC_CHACHA20_POLY1305_TYPE:
20449                break;
20450#endif
20451
20452#ifdef HAVE_CHACHA
20453            case WC_CHACHA20_TYPE:
20454                break;
20455#endif
20456
20457#ifdef WOLFSSL_SM4_ECB
20458            case WC_SM4_ECB_TYPE:
20459                break;
20460#endif
20461#ifdef WOLFSSL_SM4_CBC
20462            case WC_SM4_CBC_TYPE:
20463                WOLFSSL_MSG("SM4 CBC");
20464                XMEMCPY(ctx->iv, &ctx->cipher.sm4.iv, ctx->ivSz);
20465                break;
20466#endif
20467#ifdef WOLFSSL_SM4_CTR
20468            case WC_SM4_CTR_TYPE:
20469                WOLFSSL_MSG("SM4 CTR");
20470                XMEMCPY(ctx->iv, &ctx->cipher.sm4.iv, ctx->ivSz);
20471                break;
20472#endif
20473#ifdef WOLFSSL_SM4_GCM
20474            case WC_SM4_GCM_TYPE:
20475                WOLFSSL_MSG("SM4 GCM");
20476                XMEMCPY(ctx->iv, &ctx->cipher.sm4.iv, ctx->ivSz);
20477                break;
20478#endif
20479#ifdef WOLFSSL_SM4_CCM
20480            case WC_SM4_CCM_TYPE:
20481                WOLFSSL_MSG("SM4 CCM");
20482                XMEMCPY(ctx->iv, &ctx->cipher.sm4.iv, ctx->ivSz);
20483                break;
20484#endif
20485
20486            case WC_NULL_CIPHER_TYPE :
20487                WOLFSSL_MSG("NULL");
20488                break;
20489
20490            default: {
20491                WOLFSSL_MSG("bad type");
20492                return WOLFSSL_FATAL_ERROR;
20493            }
20494        }
20495        return WOLFSSL_SUCCESS;
20496    }
20497
20498#ifndef NO_DES3
20499
20500void wolfSSL_3des_iv(WOLFSSL_EVP_CIPHER_CTX* ctx, int doset,
20501                            unsigned char* iv, int len)
20502{
20503    (void)len;
20504
20505    WOLFSSL_MSG("wolfSSL_3des_iv");
20506
20507    if (ctx == NULL || iv == NULL) {
20508        WOLFSSL_MSG("Bad function argument");
20509        return;
20510    }
20511
20512    if (doset)
20513        wc_Des3_SetIV(&ctx->cipher.des3, iv);  /* OpenSSL compat, no ret */
20514    else
20515        XMEMCPY(iv, &ctx->cipher.des3.reg, DES_BLOCK_SIZE);
20516}
20517
20518#endif /* NO_DES3 */
20519
20520
20521#ifndef NO_AES
20522
20523void wolfSSL_aes_ctr_iv(WOLFSSL_EVP_CIPHER_CTX* ctx, int doset,
20524                      unsigned char* iv, int len)
20525{
20526    (void)len;
20527
20528    WOLFSSL_MSG("wolfSSL_aes_ctr_iv");
20529
20530    if (ctx == NULL || iv == NULL) {
20531        WOLFSSL_MSG("Bad function argument");
20532        return;
20533    }
20534
20535    if (doset)
20536       (void)wc_AesSetIV(&ctx->cipher.aes, iv);  /* OpenSSL compat, no ret */
20537    else
20538        XMEMCPY(iv, &ctx->cipher.aes.reg, WC_AES_BLOCK_SIZE);
20539}
20540
20541#endif /* NO_AES */
20542
20543#endif /* OPENSSL_EXTRA */
20544
20545/*******************************************************************************
20546 * END OF EVP_CIPHER API
20547 ******************************************************************************/
20548
20549#ifndef NO_CERTS
20550
20551#define WOLFSSL_X509_STORE_INCLUDED
20552#include <src/x509_str.c>
20553
20554#define WOLFSSL_SSL_P7P12_INCLUDED
20555#include <src/ssl_p7p12.c>
20556
20557#endif /* !NO_CERTS */
20558
20559
20560/*******************************************************************************
20561 * BEGIN OPENSSL FIPS DRBG APIs
20562 ******************************************************************************/
20563#if defined(OPENSSL_EXTRA) && !defined(WC_NO_RNG) && defined(HAVE_HASHDRBG)
20564int wolfSSL_FIPS_drbg_init(WOLFSSL_DRBG_CTX *ctx, int type, unsigned int flags)
20565{
20566    int ret = WC_NO_ERR_TRACE(WOLFSSL_FAILURE);
20567    if (ctx != NULL) {
20568        XMEMSET(ctx, 0, sizeof(WOLFSSL_DRBG_CTX));
20569        ctx->type = type;
20570        ctx->xflags = (int)flags;
20571        ctx->status = DRBG_STATUS_UNINITIALISED;
20572        ret = WOLFSSL_SUCCESS;
20573    }
20574    return ret;
20575}
20576WOLFSSL_DRBG_CTX* wolfSSL_FIPS_drbg_new(int type, unsigned int flags)
20577{
20578    int ret = WC_NO_ERR_TRACE(WOLFSSL_FAILURE);
20579    WOLFSSL_DRBG_CTX* ctx = (WOLFSSL_DRBG_CTX*)XMALLOC(sizeof(WOLFSSL_DRBG_CTX),
20580        NULL, DYNAMIC_TYPE_OPENSSL);
20581    ret = wolfSSL_FIPS_drbg_init(ctx, type, flags);
20582    if (ret == WOLFSSL_SUCCESS && type != 0) {
20583        ret = wolfSSL_FIPS_drbg_instantiate(ctx, NULL, 0);
20584    }
20585    if (ret != WOLFSSL_SUCCESS) {
20586        WOLFSSL_ERROR(ret);
20587        wolfSSL_FIPS_drbg_free(ctx);
20588        ctx = NULL;
20589    }
20590    return ctx;
20591}
20592int wolfSSL_FIPS_drbg_instantiate(WOLFSSL_DRBG_CTX* ctx,
20593    const unsigned char* pers, size_t perslen)
20594{
20595    int ret = WC_NO_ERR_TRACE(WOLFSSL_FAILURE);
20596    if (ctx != NULL && ctx->rng == NULL) {
20597    #if !defined(HAVE_SELFTEST) && (!defined(HAVE_FIPS) || \
20598        (defined(HAVE_FIPS) && FIPS_VERSION_GE(5,0)))
20599        ctx->rng = wc_rng_new((byte*)pers, (word32)perslen, NULL);
20600    #else
20601        ctx->rng = (WC_RNG*)XMALLOC(sizeof(WC_RNG), NULL, DYNAMIC_TYPE_RNG);
20602        if (ctx->rng != NULL) {
20603        #if defined(HAVE_FIPS) && FIPS_VERSION_GE(2,0)
20604            ret = wc_InitRngNonce(ctx->rng, (byte*)pers, (word32)perslen);
20605        #else
20606            ret = wc_InitRng(ctx->rng);
20607            (void)pers;
20608            (void)perslen;
20609        #endif
20610            if (ret != 0) {
20611                WOLFSSL_ERROR(ret);
20612                XFREE(ctx->rng, NULL, DYNAMIC_TYPE_RNG);
20613                ctx->rng = NULL;
20614            }
20615        }
20616    #endif
20617    }
20618    if (ctx != NULL && ctx->rng != NULL) {
20619        ctx->status = DRBG_STATUS_READY;
20620        ret = WOLFSSL_SUCCESS;
20621    }
20622    return ret;
20623}
20624int wolfSSL_FIPS_drbg_set_callbacks(WOLFSSL_DRBG_CTX* ctx,
20625    drbg_entropy_get entropy_get, drbg_entropy_clean entropy_clean,
20626    size_t entropy_blocklen,
20627    drbg_nonce_get none_get, drbg_nonce_clean nonce_clean)
20628{
20629    int ret = WC_NO_ERR_TRACE(WOLFSSL_FAILURE);
20630    if (ctx != NULL) {
20631        ctx->entropy_get = entropy_get;
20632        ctx->entropy_clean = entropy_clean;
20633        ctx->entropy_blocklen = entropy_blocklen;
20634        ctx->none_get = none_get;
20635        ctx->nonce_clean = nonce_clean;
20636        ret = WOLFSSL_SUCCESS;
20637    }
20638    return ret;
20639}
20640void wolfSSL_FIPS_rand_add(const void* buf, int num, double entropy)
20641{
20642    /* not implemented */
20643    (void)buf;
20644    (void)num;
20645    (void)entropy;
20646}
20647int wolfSSL_FIPS_drbg_reseed(WOLFSSL_DRBG_CTX* ctx, const unsigned char* adin,
20648    size_t adinlen)
20649{
20650    int ret = WC_NO_ERR_TRACE(WOLFSSL_FAILURE);
20651    if (ctx != NULL && ctx->rng != NULL) {
20652    #if !defined(HAVE_SELFTEST) && (!defined(HAVE_FIPS) || \
20653        (defined(HAVE_FIPS) && FIPS_VERSION_GE(2,0)))
20654        if (wc_RNG_DRBG_Reseed(ctx->rng, adin, (word32)adinlen) == 0) {
20655            ret = WOLFSSL_SUCCESS;
20656        }
20657    #else
20658        ret = WOLFSSL_SUCCESS;
20659        (void)adin;
20660        (void)adinlen;
20661    #endif
20662    }
20663    return ret;
20664}
20665int wolfSSL_FIPS_drbg_generate(WOLFSSL_DRBG_CTX* ctx, unsigned char* out,
20666    size_t outlen, int prediction_resistance, const unsigned char* adin,
20667    size_t adinlen)
20668{
20669    int ret = WC_NO_ERR_TRACE(WOLFSSL_FAILURE);
20670    if (ctx != NULL && ctx->rng != NULL) {
20671        ret = wc_RNG_GenerateBlock(ctx->rng, out, (word32)outlen);
20672        if (ret == 0) {
20673            ret = WOLFSSL_SUCCESS;
20674        }
20675    }
20676    (void)prediction_resistance;
20677    (void)adin;
20678    (void)adinlen;
20679    return ret;
20680}
20681int wolfSSL_FIPS_drbg_uninstantiate(WOLFSSL_DRBG_CTX *ctx)
20682{
20683    if (ctx != NULL && ctx->rng != NULL) {
20684    #if !defined(HAVE_SELFTEST) && (!defined(HAVE_FIPS) || \
20685        (defined(HAVE_FIPS) && FIPS_VERSION_GE(5,0)))
20686        wc_rng_free(ctx->rng);
20687    #else
20688        wc_FreeRng(ctx->rng);
20689        XFREE(ctx->rng, NULL, DYNAMIC_TYPE_RNG);
20690    #endif
20691        ctx->rng = NULL;
20692        ctx->status = DRBG_STATUS_UNINITIALISED;
20693    }
20694    return WOLFSSL_SUCCESS;
20695}
20696void wolfSSL_FIPS_drbg_free(WOLFSSL_DRBG_CTX *ctx)
20697{
20698    if (ctx != NULL) {
20699        /* As safety check if free'ing the default drbg, then mark global NULL.
20700         * Technically the user should not call free on the default drbg. */
20701        if (ctx == gDrbgDefCtx) {
20702            gDrbgDefCtx = NULL;
20703        }
20704        wolfSSL_FIPS_drbg_uninstantiate(ctx);
20705        XFREE(ctx, NULL, DYNAMIC_TYPE_OPENSSL);
20706    }
20707}
20708WOLFSSL_DRBG_CTX* wolfSSL_FIPS_get_default_drbg(void)
20709{
20710    if (gDrbgDefCtx == NULL) {
20711        gDrbgDefCtx = wolfSSL_FIPS_drbg_new(0, 0);
20712    }
20713    return gDrbgDefCtx;
20714}
20715void wolfSSL_FIPS_get_timevec(unsigned char* buf, unsigned long* pctr)
20716{
20717    /* not implemented */
20718    (void)buf;
20719    (void)pctr;
20720}
20721void* wolfSSL_FIPS_drbg_get_app_data(WOLFSSL_DRBG_CTX *ctx)
20722{
20723    if (ctx != NULL) {
20724        return ctx->app_data;
20725    }
20726    return NULL;
20727}
20728void wolfSSL_FIPS_drbg_set_app_data(WOLFSSL_DRBG_CTX *ctx, void *app_data)
20729{
20730    if (ctx != NULL) {
20731        ctx->app_data = app_data;
20732    }
20733}
20734#endif
20735/*******************************************************************************
20736 * END OF OPENSSL FIPS DRBG APIs
20737 ******************************************************************************/
20738
20739
20740#endif /* !WOLFCRYPT_ONLY */