cjson
fuzzing
inputs
test1 test10 test11 test2 test3 test3.bu test3.uf test3.uu test4 test5 test6 test7 test8 test9library_config
cJSONConfig.cmake.in cJSONConfigVersion.cmake.in libcjson.pc.in libcjson_utils.pc.in uninstall.cmaketests
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.expectedjson-patch-tests
.editorconfig .gitignore .npmignore README.md cjson-utils-tests.json package.json spec_tests.json tests.jsonunity
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.pydocs
ThrowTheSwitchCodingStandard.md UnityAssertionsCheatSheetSuitableforPrintingandPossiblyFraming.pdf UnityAssertionsReference.md UnityConfigurationGuide.md UnityGettingStartedGuide.md UnityHelperScriptsGuide.md license.txtexamples
unity_config.hcurl
.github
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.yamlworkflows
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.ymlCMake
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.cmakedocs
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.mdexamples
.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.cinternals
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.mdlibcurl
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.incinclude
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.hlib
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.hvauth
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.hvquic
curl_ngtcp2.c curl_ngtcp2.h curl_quiche.c curl_quiche.h vquic-tls.c vquic-tls.h vquic.c vquic.h vquic_int.hvtls
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.hm4
.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.m4projects
OS400
.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.hWindows
tmpl
.gitattributes README.txt curl-all.sln curl.sln curl.vcxproj curl.vcxproj.filters libcurl.sln libcurl.vcxproj libcurl.vcxproj.filtersvms
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.hscripts
.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 wcurlsrc
.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.htests
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.prmdata
.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 test999http
testenv
__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.pylibtest
.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.hserver
.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.ctunit
.gitignore CMakeLists.txt Makefile.am Makefile.inc README.md tool1394.c tool1604.c tool1621.c tool1622.c tool1623.c tool1720.cunit
.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.cexamples
.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.luainiparser
example
iniexample.c iniwrite.c parse.c twisted-errors.ini twisted-genhuge.py twisted-ofkey.ini twisted-ofval.ini twisted.initest
CMakeLists.txt test_dictionary.c test_iniparser.c unity-config.yml unity_config.hjinjac
libjinjac
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.htest
.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.jinjalibev
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-h1luajit
doc
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.htmldynasm
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.luasrc
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.cjit
.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.luawolfssl
.github
workflows
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.ymlIDE
ARDUINO
Arduino_README_prepend.md README.md include.am keywords.txt library.properties.template wolfssl-arduino.cpp wolfssl-arduino.sh wolfssl.hECLIPSE
Espressif
ESP-IDF
examples
template
CMakeLists.txt Makefile README.md partitions_singleapp_large.csv sdkconfig.defaults sdkconfig.defaults.esp8266wolfssl_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.vgdbprojwolfssl_client
CMakeLists.txt Makefile README.md README_server_sm.md partitions_singleapp_large.csv sdkconfig.defaults sdkconfig.defaults.esp32c2 sdkconfig.defaults.esp8266 wolfssl_client_ESP8266.vgdbprojwolfssl_server
CMakeLists.txt Makefile README.md README_server_sm.md partitions_singleapp_large.csv sdkconfig.defaults sdkconfig.defaults.esp32c2 sdkconfig.defaults.esp8266 wolfssl_server_ESP8266.vgdbprojwolfssl_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.vgdbprojGCC-ARM
Makefile Makefile.bench Makefile.client Makefile.common Makefile.server Makefile.static Makefile.test README.md include.am linker.ld linker_fips.ldIAR-EWARM
embOS
SAMV71_XULT
embOS_SAMV71_XULT_user_settings
user_settings.h user_settings_simple_example.h user_settings_verbose_example.hembOS_wolfcrypt_benchmark_SAMV71_XULT
README_wolfcrypt_benchmark wolfcrypt_benchmark.ewd wolfcrypt_benchmark.ewpINTIME-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.vcxprojMQX
Makefile README-jp.md README.md client-tls.c include.am server-tls.c user_config.h user_settings.hMSVS-2019-AZSPHERE
wolfssl_new_azsphere
.gitignore CMakeLists.txt CMakeSettings.json app_manifest.json applibs_versions.h launch.vs.json main.cNETOS
Makefile.wolfcrypt.inc README.md include.am user_settings.h user_settings.h-cert2425 user_settings.h-cert3389 wolfssl_netos_custom.cPlatformIO
examples
wolfssl_benchmark
CMakeLists.txt README.md platformio.ini sdkconfig.defaults wolfssl_benchmark.code-workspaceROWLEY-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.hzpRenesas
e2studio
RA6M3
README.md README_APRA6M_en.md README_APRA6M_jp.md include.amRX72N
EnvisionKit
Simple
README_EN.md README_JP.mdwolfssl_demo
key_data.c key_data.h user_settings.h wolfssl_demo.c wolfssl_demo.h wolfssl_tsip_unit_test.cSTM32Cube
README.md STM32_Benchmarks.md default_conf.ftl include.am main.c wolfssl_example.c wolfssl_example.hWIN
README.txt include.am test.vcxproj user_settings.h user_settings_dtls.h wolfssl-fips.sln wolfssl-fips.vcxprojWIN-SRTP-KDF-140-3
README.txt include.am resource.h test.vcxproj user_settings.h wolfssl-fips.rc wolfssl-fips.sln wolfssl-fips.vcxprojWIN10
README.txt include.am resource.h test.vcxproj user_settings.h wolfssl-fips.rc wolfssl-fips.sln wolfssl-fips.vcxprojXCODE
Benchmark
include.amXilinxSDK
README.md bench.sh combine.sh eclipse_formatter_profile.xml graph.sh include.am user_settings.h wolfssl_example.capple-universal
wolfssl-multiplatform
iotsafe
Makefile README.md ca-cert.c devices.c devices.h include.am main.c memory-tls.c startup.c target.ld user_settings.hmynewt
README.md apps.wolfcrypttest.pkg.yml crypto.wolfssl.pkg.yml crypto.wolfssl.syscfg.yml include.am setup.shcerts
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.pemcrl
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.pemdilithium
bench_dilithium_level2_key.der bench_dilithium_level3_key.der bench_dilithium_level5_key.der include.amecc
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.cnfed25519
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.pemed448
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.pemexternal
DigiCertGlobalRootCA.pem README.txt ca-digicert-ev.pem ca-globalsign-root.pem ca-google-root.pem ca_collection.pem include.amintermediate
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.conflms
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.ammldsa
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.derocsp
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.derp521
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.pemrpk
client-cert-rpk.der client-ecc-cert-rpk.der include.am server-cert-rpk.der server-ecc-cert-rpk.derrsapss
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.pemslhdsa
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.pemsm2
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.pemstatickeys
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.pemtest
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.p7stest-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.shtest-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.pemxmss
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.amcmake
Config.cmake.in README.md config.in functions.cmake include.am options.h.in wolfssl-config-version.cmake.in wolfssl-targets.cmake.indebian
changelog.in control.in copyright include.am libwolfssl-dev.install libwolfssl.install rules.indoc
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.hheader_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.hexamples
async
Makefile README.md async_client.c async_server.c async_tls.c async_tls.h include.am user_settings.hconfigs
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.hechoclient
echoclient.c echoclient.h echoclient.sln echoclient.vcproj echoclient.vcxproj include.am quitlinuxkm
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.cm4
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.m4mqx
wolfcrypt_benchmark
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.launchwolfcrypt_test
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.launchwolfssl_client
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.launchscripts
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.shsrc
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.ctests
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.hwolfcrypt
benchmark
README.md benchmark-VS2022.sln benchmark-VS2022.vcxproj benchmark-VS2022.vcxproj.user benchmark.c benchmark.h benchmark.sln benchmark.vcproj benchmark.vcxproj include.amsrc
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.pyRenesas
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.carm
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.ccaam
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.cdevcrypto
README.md devcrypto_aes.c devcrypto_ecdsa.c devcrypto_hash.c devcrypto_hmac.c devcrypto_rsa.c devcrypto_x25519.c wc_devcrypto.criscv
riscv-64-aes.c riscv-64-chacha.c riscv-64-poly1305.c riscv-64-sha256.c riscv-64-sha3.c riscv-64-sha512.cwolfssl
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.hwolfcrypt
port
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.hcaam
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.hwrapper
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.adbtests
src
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.adbCSharp
wolfSSL-Example-IOCallbacks
App.config wolfSSL-Example-IOCallbacks.cs wolfSSL-Example-IOCallbacks.csprojwolfSSL-TLS-ServerThreaded
App.config wolfSSL-TLS-ServerThreaded.cs wolfSSL-TLS-ServerThreaded.csprojrust
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.rstests
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.rszephyr
samples
wolfssl_benchmark
CMakeLists.txt README install_test.sh prj.conf sample.yaml zephyr_legacy.conf zephyr_v4.1.confwolfssl_test
CMakeLists.txt README install_test.sh prj-no-malloc.conf prj.conf sample.yaml zephyr_legacy.conf zephyr_v4.1.conf
wolfssl/src/wolfio.c
raw
1/* wolfio.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
23#ifndef WOLFSSL_STRERROR_BUFFER_SIZE
24#define WOLFSSL_STRERROR_BUFFER_SIZE 256
25#endif
26
27#include <wolfssl/wolfcrypt/libwolfssl_sources.h>
28
29#ifndef WOLFCRYPT_ONLY
30
31#if defined(HAVE_ERRNO_H) && defined(WOLFSSL_NO_SOCK) && \
32 (defined(USE_WOLFSSL_IO) || defined(HAVE_HTTP_CLIENT))
33 /* error codes are needed for TranslateIoReturnCode() and
34 * wolfIO_TcpConnect() even if defined(WOLFSSL_NO_SOCK), which inhibits
35 * inclusion of errno.h by wolfio.h.
36 */
37 #include <errno.h>
38#endif
39
40#include <wolfssl/internal.h>
41#include <wolfssl/error-ssl.h>
42#include <wolfssl/wolfio.h>
43#include <wolfssl/wolfcrypt/logging.h>
44
45
46#ifdef NUCLEUS_PLUS_2_3
47/* Holds last Nucleus networking error number */
48int Nucleus_Net_Errno;
49#endif
50
51#if defined(USE_WOLFSSL_IO) || defined(HAVE_HTTP_CLIENT)
52 #ifdef USE_WINDOWS_API
53 #include <winsock2.h>
54 #else
55 #if defined(WOLFSSL_LWIP) && !defined(WOLFSSL_APACHE_MYNEWT)
56 #elif defined(ARDUINO)
57 #elif defined(FREESCALE_MQX)
58 #elif defined(FREESCALE_KSDK_MQX)
59 #elif (defined(WOLFSSL_MDK_ARM) || defined(WOLFSSL_KEIL_TCP_NET))
60 #elif defined(WOLFSSL_CMSIS_RTOS)
61 #elif defined(WOLFSSL_CMSIS_RTOSv2)
62 #elif defined(WOLFSSL_TIRTOS)
63 #elif defined(FREERTOS_TCP)
64 #elif defined(WOLFSSL_IAR_ARM)
65 #elif defined(HAVE_NETX_BSD)
66 #elif defined(WOLFSSL_VXWORKS)
67 #elif defined(WOLFSSL_NUCLEUS_1_2)
68 #elif defined(WOLFSSL_LINUXKM)
69 /* the requisite linux/net.h is included in wc_port.h, with incompatible warnings masked out. */
70 #elif defined(WOLFSSL_ATMEL)
71 #elif defined(INTIME_RTOS)
72 #include <netdb.h>
73 #elif defined(WOLFSSL_PRCONNECT_PRO)
74 #include <netdb.h>
75 #include <sys/ioctl.h>
76 #elif defined(WOLFSSL_SGX)
77 #elif defined(WOLFSSL_APACHE_MYNEWT) && !defined(WOLFSSL_LWIP)
78 #elif defined(WOLFSSL_DEOS)
79 #elif defined(WOLFSSL_ZEPHYR)
80 #elif defined(MICROCHIP_PIC32)
81 #elif defined(HAVE_NETX)
82 #elif defined(FUSION_RTOS)
83 #elif !defined(WOLFSSL_NO_SOCK)
84 #if defined(HAVE_RTP_SYS)
85 #elif defined(EBSNET)
86 #elif defined(NETOS)
87 #elif !defined(DEVKITPRO) && !defined(WOLFSSL_PICOTCP) \
88 && !defined(WOLFSSL_CONTIKI) && !defined(WOLFSSL_WICED) \
89 && !defined(WOLFSSL_GNRC) && !defined(WOLFSSL_RIOT_OS)
90 #ifdef HAVE_NETDB_H
91 #include <netdb.h>
92 #endif
93 #ifdef __PPU
94 #include <netex/errno.h>
95 #else
96 #ifdef HAVE_SYS_IOCTL_H
97 #include <sys/ioctl.h>
98 #endif
99 #endif
100 #endif
101 #endif
102
103 #endif /* USE_WINDOWS_API */
104#endif /* defined(USE_WOLFSSL_IO) || defined(HAVE_HTTP_CLIENT) */
105
106
107#if defined(HAVE_HTTP_CLIENT)
108 #include <stdlib.h> /* strtol() */
109#endif
110
111/*
112Possible IO enable options:
113 * WOLFSSL_USER_IO: Disables default Embed* callbacks and default: off
114 allows user to define their own using
115 wolfSSL_CTX_SetIORecv and wolfSSL_CTX_SetIOSend
116 * USE_WOLFSSL_IO: Enables the wolfSSL IO functions default: on
117 * HAVE_HTTP_CLIENT: Enables HTTP client API's default: off
118 (unless HAVE_OCSP or HAVE_CRL_IO defined)
119 * HAVE_IO_TIMEOUT: Enables support for connect timeout default: off
120 *
121 * DTLS_RECEIVEFROM_NO_TIMEOUT_ON_INVALID_PEER: This flag has effect only if
122 * ASN_NO_TIME is enabled. If enabled invalid peers messages are ignored
123 * indefinitely. If not enabled EmbedReceiveFrom will return timeout after
124 * DTLS_RECEIVEFROM_MAX_INVALID_PEER number of packets from invalid peers. When
125 * enabled, without a timer, EmbedReceivefrom can't check if the timeout is
126 * expired and it may never return under a continuous flow of invalid packets.
127 * default: off
128 */
129
130
131/* if user writes own I/O callbacks they can define WOLFSSL_USER_IO to remove
132 automatic setting of default I/O functions EmbedSend() and EmbedReceive()
133 but they'll still need SetCallback xxx() at end of file
134*/
135
136#if defined(NO_ASN_TIME) && !defined(DTLS_RECEIVEFROM_NO_TIMEOUT_ON_INVALID_PEER) \
137 && !defined(DTLS_RECEIVEFROM_MAX_INVALID_PEER)
138#define DTLS_RECEIVEFROM_MAX_INVALID_PEER 10
139#endif
140
141#if defined(USE_WOLFSSL_IO) || defined(HAVE_HTTP_CLIENT)
142
143static WC_INLINE int wolfSSL_LastError(int err, SOCKET_T sd)
144{
145 (void)sd;
146
147 if (err > 0)
148 return 0;
149
150#ifdef USE_WINDOWS_API
151 return WSAGetLastError();
152#elif defined(EBSNET)
153 return xn_getlasterror();
154#elif defined(WOLFSSL_LINUXKM)
155 return -err; /* Return provided error value with corrected sign. */
156#elif defined(WOLFSSL_EMNET)
157 /* Any negative recv/send return is a SOCKET_ERROR sentinel under
158 * emNET; the canonical IP_ERR_* lives in the socket SO_ERROR.
159 * Retrieving it via IP_SOCK_getsockopt works across both emNET
160 * integrator conventions (native: recv returns IP_ERR_* directly;
161 * POSIX facade: recv returns -1 with errno set). If the lookup
162 * itself fails, fall back to IP_ERR_FAULT rather than returning
163 * the raw -1 sentinel - the latter matches no SOCKET_E* constant
164 * and would regress into WOLFSSL_CBIO_ERR_GENERAL. */
165 if (err < 0) {
166 int sock_err = err;
167 if (IP_SOCK_getsockopt(sd, SOL_SOCKET, SO_ERROR, &sock_err,
168 (int)sizeof(sock_err)) == 0) {
169 err = sock_err;
170 }
171 else if (err == -1) {
172 err = IP_ERR_FAULT;
173 }
174 }
175 return err;
176#elif defined(FUSION_RTOS)
177 #include <fclerrno.h>
178 return FCL_GET_ERRNO;
179#elif defined(NUCLEUS_PLUS_2_3)
180 return Nucleus_Net_Errno;
181#elif defined(FREESCALE_MQX) || defined(FREESCALE_KSDK_MQX)
182 if ((err == 0) || (err == -SOCKET_EWOULDBLOCK)) {
183 return SOCKET_EWOULDBLOCK; /* convert to BSD style wouldblock */
184 } else {
185 err = RTCS_geterror(sd);
186 if ((err == RTCSERR_TCP_CONN_CLOSING) ||
187 (err == RTCSERR_TCP_CONN_RLSD))
188 {
189 err = SOCKET_ECONNRESET;
190 }
191 return err;
192 }
193#else
194 return errno;
195#endif
196}
197
198/* Translates return codes returned from
199 * send(), recv(), and other network I/O calls.
200 */
201static int TranslateIoReturnCode(int err, SOCKET_T sd, int direction)
202{
203#if defined(_WIN32) && !defined(__WATCOMC__) && !defined(_WIN32_WCE) && \
204 !defined(INTIME_RTOS)
205 size_t errstr_offset;
206 char errstr[WOLFSSL_STRERROR_BUFFER_SIZE];
207#endif /* _WIN32 */
208
209#if defined(FREESCALE_MQX) || defined(FREESCALE_KSDK_MQX)
210 if (err > 0)
211 return err;
212#else
213 if (err >= 0)
214 return err;
215#endif
216
217 err = wolfSSL_LastError(err, sd);
218
219#if SOCKET_EWOULDBLOCK != SOCKET_EAGAIN
220 if ((err == SOCKET_EWOULDBLOCK) || (err == SOCKET_EAGAIN))
221#else
222 if (err == SOCKET_EWOULDBLOCK)
223#endif
224 {
225 WOLFSSL_MSG("\tWould block");
226 if (direction == SOCKET_SENDING)
227 return WOLFSSL_CBIO_ERR_WANT_WRITE;
228 else if (direction == SOCKET_RECEIVING)
229 return WOLFSSL_CBIO_ERR_WANT_READ;
230 else
231 return WOLFSSL_CBIO_ERR_GENERAL;
232 }
233
234#ifdef SOCKET_ETIMEDOUT
235 else if (err == SOCKET_ETIMEDOUT) {
236 WOLFSSL_MSG("\tTimed out");
237 if (direction == SOCKET_SENDING)
238 return WOLFSSL_CBIO_ERR_WANT_WRITE;
239 else if (direction == SOCKET_RECEIVING)
240 return WOLFSSL_CBIO_ERR_WANT_READ;
241 else
242 return WOLFSSL_CBIO_ERR_TIMEOUT;
243 }
244#endif /* SOCKET_ETIMEDOUT */
245
246 else if (err == SOCKET_ECONNRESET) {
247 WOLFSSL_MSG("\tConnection reset");
248 return WOLFSSL_CBIO_ERR_CONN_RST;
249 }
250 else if (err == SOCKET_EINTR) {
251 WOLFSSL_MSG("\tSocket interrupted");
252 return WOLFSSL_CBIO_ERR_ISR;
253 }
254 else if (err == SOCKET_EPIPE) {
255 WOLFSSL_MSG("\tBroken pipe");
256 return WOLFSSL_CBIO_ERR_CONN_CLOSE;
257 }
258 else if (err == SOCKET_ECONNABORTED) {
259 WOLFSSL_MSG("\tConnection aborted");
260 return WOLFSSL_CBIO_ERR_CONN_CLOSE;
261 }
262
263#if defined(_WIN32) && !defined(__WATCOMC__) && !defined(_WIN32_WCE) && \
264 !defined(INTIME_RTOS)
265 strcpy_s(errstr, sizeof(errstr), "\tGeneral error: ");
266 errstr_offset = strlen(errstr);
267 FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
268 NULL,
269 err,
270 MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
271 (LPSTR)(errstr + errstr_offset),
272 (DWORD)(sizeof(errstr) - errstr_offset),
273 NULL);
274 WOLFSSL_MSG(errstr);
275#else
276 WOLFSSL_MSG_EX("\tGeneral error: %d", err);
277#endif
278 return WOLFSSL_CBIO_ERR_GENERAL;
279}
280#endif /* USE_WOLFSSL_IO || HAVE_HTTP_CLIENT */
281
282#ifdef OPENSSL_EXTRA
283#ifndef NO_BIO
284
285int wolfSSL_BioSend(WOLFSSL* ssl, char *buf, int sz, void *ctx)
286{
287 return SslBioSend(ssl, buf, sz, ctx);
288}
289
290int wolfSSL_BioReceive(WOLFSSL* ssl, char* buf, int sz, void* ctx)
291{
292 return SslBioReceive(ssl, buf, sz, ctx);
293}
294
295int BioReceiveInternal(WOLFSSL_BIO* biord, WOLFSSL_BIO* biowr, char* buf,
296 int sz)
297{
298 int recvd = WC_NO_ERR_TRACE(WOLFSSL_CBIO_ERR_GENERAL);
299
300 WOLFSSL_ENTER("SslBioReceive");
301
302 if (biord == NULL) {
303 WOLFSSL_MSG("WOLFSSL biord not set");
304 return WOLFSSL_CBIO_ERR_GENERAL;
305 }
306
307 recvd = wolfSSL_BIO_read(biord, buf, sz);
308 if (recvd <= 0) {
309 if (biowr != NULL &&
310 /* ssl->biowr->wrIdx is checked for Bind9 */
311 wolfSSL_BIO_method_type(biowr) == WOLFSSL_BIO_BIO &&
312 wolfSSL_BIO_wpending(biowr) != 0 &&
313 /* Not sure this pending check is necessary but let's double
314 * check that the read BIO is empty before we signal a write
315 * need */
316 wolfSSL_BIO_supports_pending(biord) &&
317 wolfSSL_BIO_ctrl_pending(biord) == 0) {
318 /* Let's signal to the app layer that we have
319 * data pending that needs to be sent. */
320 return WOLFSSL_CBIO_ERR_WANT_WRITE;
321 }
322 else if (biord->type == WOLFSSL_BIO_SOCKET) {
323 if (recvd == 0) {
324 WOLFSSL_MSG("SslBioReceive connection closed");
325 return WOLFSSL_CBIO_ERR_CONN_CLOSE;
326 }
327 #ifdef USE_WOLFSSL_IO
328 recvd = TranslateIoReturnCode(recvd, biord->num.fd,
329 SOCKET_RECEIVING);
330 #endif
331 return recvd;
332 }
333
334 /* If retry and read flags are set, return WANT_READ */
335 if ((biord->flags & WOLFSSL_BIO_FLAG_READ) &&
336 (biord->flags & WOLFSSL_BIO_FLAG_RETRY)) {
337 return WOLFSSL_CBIO_ERR_WANT_READ;
338 }
339
340 WOLFSSL_MSG("BIO general error");
341 return WOLFSSL_CBIO_ERR_GENERAL;
342 }
343
344 return recvd;
345}
346
347/* Use the WOLFSSL read BIO for receiving data. This is set by the function
348 * wolfSSL_set_bio and can also be set by wolfSSL_CTX_SetIORecv.
349 *
350 * ssl WOLFSSL struct passed in that has this function set as the receive
351 * callback.
352 * buf buffer to fill with data read
353 * sz size of buf buffer
354 * ctx a user set context
355 *
356 * returns the amount of data read or want read. See WOLFSSL_CBIO_ERR_* values.
357 */
358int SslBioReceive(WOLFSSL* ssl, char* buf, int sz, void* ctx)
359{
360 WOLFSSL_ENTER("SslBioReceive");
361 (void)ctx;
362 return BioReceiveInternal(ssl->biord, ssl->biowr, buf, sz);
363}
364
365
366/* Use the WOLFSSL write BIO for sending data. This is set by the function
367 * wolfSSL_set_bio and can also be set by wolfSSL_CTX_SetIOSend.
368 *
369 * ssl WOLFSSL struct passed in that has this function set as the send callback.
370 * buf buffer with data to write out
371 * sz size of buf buffer
372 * ctx a user set context
373 *
374 * returns the amount of data sent or want send. See WOLFSSL_CBIO_ERR_* values.
375 */
376int SslBioSend(WOLFSSL* ssl, char *buf, int sz, void *ctx)
377{
378 int sent = WC_NO_ERR_TRACE(WOLFSSL_CBIO_ERR_GENERAL);
379
380 WOLFSSL_ENTER("SslBioSend");
381
382 if (ssl->biowr == NULL) {
383 WOLFSSL_MSG("WOLFSSL biowr not set");
384 return WOLFSSL_CBIO_ERR_GENERAL;
385 }
386
387 sent = wolfSSL_BIO_write(ssl->biowr, buf, sz);
388 if (sent <= 0) {
389 if (ssl->biowr->type == WOLFSSL_BIO_SOCKET) {
390 #ifdef USE_WOLFSSL_IO
391 sent = TranslateIoReturnCode(sent, ssl->biowr->num.fd,
392 SOCKET_SENDING);
393 #endif
394 return sent;
395 }
396 else if (ssl->biowr->type == WOLFSSL_BIO_BIO) {
397 if (sent == WOLFSSL_BIO_ERROR) {
398 WOLFSSL_MSG("\tWould Block");
399 return WOLFSSL_CBIO_ERR_WANT_WRITE;
400 }
401 }
402
403 /* If retry and write flags are set, return WANT_WRITE */
404 if ((ssl->biowr->flags & WOLFSSL_BIO_FLAG_WRITE) &&
405 (ssl->biowr->flags & WOLFSSL_BIO_FLAG_RETRY)) {
406 return WOLFSSL_CBIO_ERR_WANT_WRITE;
407 }
408
409 return WOLFSSL_CBIO_ERR_GENERAL;
410 }
411 (void)ctx;
412
413 return sent;
414}
415#endif /* !NO_BIO */
416#endif /* OPENSSL_EXTRA */
417
418
419#ifdef USE_WOLFSSL_IO
420
421#ifndef WOLFSSL_DTLS_ONLY
422/* The receive embedded callback
423 * return : nb bytes read, or error
424 */
425int EmbedReceive(WOLFSSL *ssl, char *buf, int sz, void *ctx)
426{
427 int recvd;
428#ifndef WOLFSSL_LINUXKM
429 int sd = *(int*)ctx;
430#else
431 struct socket *sd = (struct socket*)ctx;
432#endif
433
434 recvd = wolfIO_Recv(sd, buf, sz, ssl->rflags);
435 if (recvd < 0) {
436 WOLFSSL_MSG("Embed Receive error");
437 }
438 else if (recvd == 0) {
439 WOLFSSL_MSG("Embed receive connection closed");
440 return WOLFSSL_CBIO_ERR_CONN_CLOSE;
441 }
442
443 return recvd;
444}
445
446/* The send embedded callback
447 * return : nb bytes sent, or error
448 */
449int EmbedSend(WOLFSSL* ssl, char *buf, int sz, void *ctx)
450{
451 int sent;
452#ifndef WOLFSSL_LINUXKM
453 int sd = *(int*)ctx;
454#else
455 struct socket *sd = (struct socket*)ctx;
456#endif
457
458#ifdef WOLFSSL_MAX_SEND_SZ
459 if (sz > WOLFSSL_MAX_SEND_SZ)
460 sz = WOLFSSL_MAX_SEND_SZ;
461#endif
462
463 sent = wolfIO_Send(sd, buf, sz, ssl->wflags);
464 if (sent < 0) {
465 WOLFSSL_MSG("Embed Send error");
466 }
467
468 return sent;
469}
470#endif /* !WOLFSSL_DTLS_ONLY */
471
472
473#ifdef WOLFSSL_DTLS
474
475#include <wolfssl/wolfcrypt/sha.h>
476
477#if defined(NUCLEUS_PLUS_2_3)
478STATIC INT32 nucyassl_recv(INT sd, CHAR *buf, UINT16 sz, INT16 flags)
479{
480 int recvd;
481
482 /* Read data from socket */
483 recvd = NU_Recv(sd, buf, sz, flags);
484 if (recvd < 0) {
485 if (recvd == NU_NOT_CONNECTED) {
486 recvd = 0;
487 } else {
488 Nucleus_Net_Errno = recvd;
489 recvd = WOLFSSL_FATAL_ERROR;
490 }
491 } else {
492 Nucleus_Net_Errno = 0;
493 }
494
495 return (recvd);
496}
497
498
499STATIC int nucyassl_send(INT sd, CHAR *buf, UINT16 sz, INT16 flags)
500{
501 int sent;
502
503 /* Write data to socket */
504 sent = NU_Send(sd, buf, sz, flags);
505
506 if (sent < 0) {
507 Nucleus_Net_Errno = sent;
508 sent = WOLFSSL_FATAL_ERROR;
509 } else {
510 Nucleus_Net_Errno = 0;
511 }
512
513 return sent;
514}
515
516#define SELECT_FUNCTION nucyassl_select
517
518int nucyassl_select(INT sd, UINT32 timeout)
519{
520 FD_SET readfs;
521 STATUS status;
522
523 /* Init fs data for socket */
524 NU_FD_Init(&readfs);
525 NU_FD_Set(sd, &readfs);
526
527 /* Wait for data to arrive */
528 status = NU_Select((sd + 1), &readfs, NU_NULL, NU_NULL,
529 (timeout * NU_TICKS_PER_SECOND));
530
531 if (status < 0) {
532 Nucleus_Net_Errno = status;
533 status = WOLFSSL_FATAL_ERROR;
534 }
535
536 return status;
537}
538
539#define sockaddr_storage addr_struct
540#define sockaddr addr_struct
541
542STATIC INT32 nucyassl_recvfrom(INT sd, CHAR *buf, UINT16 sz, INT16 flags,
543 SOCKADDR *peer, XSOCKLENT *peersz)
544{
545 int recvd;
546
547 memset(peer, 0, sizeof(struct addr_struct));
548
549 recvd = NU_Recv_From(sd, buf, sz, flags, (struct addr_struct *) peer,
550 (INT16*) peersz);
551 if (recvd < 0) {
552 Nucleus_Net_Errno = recvd;
553 recvd = WOLFSSL_FATAL_ERROR;
554 } else {
555 Nucleus_Net_Errno = 0;
556 }
557
558 return recvd;
559
560}
561
562STATIC int nucyassl_sendto(INT sd, CHAR *buf, UINT16 sz, INT16 flags,
563 const SOCKADDR *peer, INT16 peersz)
564{
565 int sent;
566
567 sent = NU_Send_To(sd, buf, sz, flags, (const struct addr_struct *) peer,
568 peersz);
569
570 if (sent < 0) {
571 Nucleus_Net_Errno = sent;
572 sent = WOLFSSL_FATAL_ERROR;
573 } else {
574 Nucleus_Net_Errno = 0;
575 }
576
577 return sent;
578}
579#endif /* NUCLEUS_PLUS_2_3 */
580
581#ifndef DTLS_SENDTO_FUNCTION
582 #define DTLS_SENDTO_FUNCTION sendto
583#endif
584#ifndef DTLS_RECVFROM_FUNCTION
585 #define DTLS_RECVFROM_FUNCTION recvfrom
586#endif
587
588int sockAddrEqual(
589 SOCKADDR_S *a, XSOCKLENT aLen, SOCKADDR_S *b, XSOCKLENT bLen)
590{
591 if (aLen != bLen)
592 return 0;
593
594 if (a->ss_family != b->ss_family)
595 return 0;
596
597 if (a->ss_family == WOLFSSL_IP4) {
598
599 if (aLen < (XSOCKLENT)sizeof(SOCKADDR_IN))
600 return 0;
601
602 if (((SOCKADDR_IN*)a)->sin_port != ((SOCKADDR_IN*)b)->sin_port)
603 return 0;
604
605 if (((SOCKADDR_IN*)a)->sin_addr.s_addr !=
606 ((SOCKADDR_IN*)b)->sin_addr.s_addr)
607 return 0;
608
609 return 1;
610 }
611
612#ifdef WOLFSSL_IPV6
613 if (a->ss_family == WOLFSSL_IP6) {
614 SOCKADDR_IN6 *a6, *b6;
615
616 if (aLen < (XSOCKLENT)sizeof(SOCKADDR_IN6))
617 return 0;
618
619 a6 = (SOCKADDR_IN6*)a;
620 b6 = (SOCKADDR_IN6*)b;
621
622 if (((SOCKADDR_IN6*)a)->sin6_port != ((SOCKADDR_IN6*)b)->sin6_port)
623 return 0;
624
625 if (XMEMCMP((void*)&a6->sin6_addr, (void*)&b6->sin6_addr,
626 sizeof(a6->sin6_addr)) != 0)
627 return 0;
628
629 return 1;
630 }
631#endif /* WOLFSSL_IPV6 */
632
633 return 0;
634}
635
636#ifndef WOLFSSL_IPV6
637static int PeerIsIpv6(const SOCKADDR_S *peer, XSOCKLENT len)
638{
639 if (len < (XSOCKLENT)sizeof(peer->ss_family))
640 return 0;
641 return peer->ss_family == WOLFSSL_IP6;
642}
643#endif /* !WOLFSSL_IPV6 */
644
645static int isDGramSock(int sfd)
646{
647 int type = 0;
648 /* optvalue 'type' is of size int */
649 XSOCKLENT length = (XSOCKLENT)sizeof(type);
650
651 if (getsockopt(sfd, SOL_SOCKET, SO_TYPE, (XSOCKOPT_TYPE_OPTVAL_TYPE)&type,
652 &length) == 0 && type != SOCK_DGRAM) {
653 return 0;
654 }
655 else {
656 return 1;
657 }
658}
659
660void wolfSSL_SetRecvFrom(WOLFSSL* ssl, WolfSSLRecvFrom recvFrom)
661{
662 if (ssl != NULL)
663 ssl->buffers.dtlsCtx.recvfrom = recvFrom;
664}
665
666void wolfSSL_SetSendTo(WOLFSSL* ssl, WolfSSLSento sendTo)
667{
668 if (ssl != NULL)
669 ssl->buffers.dtlsCtx.sendto = sendTo;
670}
671
672/* The receive embedded callback
673 * return : nb bytes read, or error
674 */
675int EmbedReceiveFrom(WOLFSSL *ssl, char *buf, int sz, void *ctx)
676{
677 WOLFSSL_DTLS_CTX* dtlsCtx = (WOLFSSL_DTLS_CTX*)ctx;
678 int recvd;
679 int sd = dtlsCtx->rfd;
680 int dtls_timeout = wolfSSL_dtls_get_current_timeout(ssl);
681 byte doDtlsTimeout;
682 SOCKADDR_S lclPeer;
683 SOCKADDR_S* peer;
684 XSOCKLENT peerSz = 0;
685#ifndef NO_ASN_TIME
686 word32 start = 0;
687#elif !defined(DTLS_RECEIVEFROM_NO_TIMEOUT_ON_INVALID_PEER)
688 word32 invalidPeerPackets = 0;
689#endif
690 int newPeer = 0;
691 int ret = 0;
692
693 WOLFSSL_ENTER("EmbedReceiveFrom");
694 (void)ret; /* possibly unused */
695
696 if (sz < 0)
697 return WOLFSSL_CBIO_ERR_GENERAL;
698
699 XMEMSET(&lclPeer, 0, sizeof(lclPeer));
700
701#ifdef WOLFSSL_RW_THREADED
702 if (wc_LockRwLock_Rd(&ssl->buffers.dtlsCtx.peerLock) != 0)
703 return WOLFSSL_CBIO_ERR_GENERAL;
704#endif
705
706 if (dtlsCtx->connected) {
707 peer = NULL;
708 }
709 else if (dtlsCtx->userSet) {
710#ifndef WOLFSSL_IPV6
711 if (PeerIsIpv6((SOCKADDR_S*)dtlsCtx->peer.sa, dtlsCtx->peer.sz)) {
712 WOLFSSL_MSG("ipv6 dtls peer set but no ipv6 support compiled");
713 ret = WOLFSSL_CBIO_ERR_GENERAL;
714 }
715#endif
716 peer = &lclPeer;
717 peerSz = sizeof(lclPeer);
718 }
719 else {
720 /* Store the peer address. It is used to calculate the DTLS cookie. */
721 newPeer = dtlsCtx->peer.sa == NULL || !ssl->options.dtlsStateful;
722 peer = &lclPeer;
723 peerSz = sizeof(lclPeer);
724 }
725
726#ifdef WOLFSSL_RW_THREADED
727 /* We make a copy above to avoid holding the lock for the entire function */
728 if (wc_UnLockRwLock(&ssl->buffers.dtlsCtx.peerLock) != 0)
729 return WOLFSSL_CBIO_ERR_GENERAL;
730#endif
731
732 if (ret != 0)
733 return ret;
734
735 /* Don't use ssl->options.handShakeDone since it is true even if
736 * we are in the process of renegotiation */
737 doDtlsTimeout = ssl->options.handShakeState != HANDSHAKE_DONE;
738
739#ifdef WOLFSSL_DTLS13
740 if (ssl->options.dtls && IsAtLeastTLSv1_3(ssl->version)) {
741 doDtlsTimeout = doDtlsTimeout || ssl->dtls13Rtx.rtxRecords != NULL;
742#ifdef WOLFSSL_RW_THREADED
743 ret = wc_LockMutex(&ssl->dtls13Rtx.mutex);
744 if (ret != 0)
745 return ret;
746#endif
747 doDtlsTimeout = doDtlsTimeout ||
748 (ssl->dtls13FastTimeout && ssl->dtls13Rtx.seenRecords != NULL);
749#ifdef WOLFSSL_RW_THREADED
750 wc_UnLockMutex(&ssl->dtls13Rtx.mutex);
751#endif
752 }
753#endif /* WOLFSSL_DTLS13 */
754
755 do {
756
757 if (!doDtlsTimeout) {
758 dtls_timeout = 0;
759 }
760 else {
761#ifndef NO_ASN_TIME
762 if (start == 0) {
763 start = LowResTimer();
764 }
765 else {
766 dtls_timeout -= (int) (LowResTimer() - start);
767 start = LowResTimer();
768 if (dtls_timeout < 0 || dtls_timeout > DTLS_TIMEOUT_MAX)
769 return WOLFSSL_CBIO_ERR_TIMEOUT;
770 }
771#endif
772 }
773
774 if (!wolfSSL_get_using_nonblock(ssl)) {
775 #ifdef USE_WINDOWS_API
776 DWORD timeout = dtls_timeout * 1000;
777 #ifdef WOLFSSL_DTLS13
778 if (wolfSSL_dtls13_use_quick_timeout(ssl) &&
779 IsAtLeastTLSv1_3(ssl->version))
780 timeout /= 4;
781 #endif /* WOLFSSL_DTLS13 */
782 #else
783 struct timeval timeout;
784 XMEMSET(&timeout, 0, sizeof(timeout));
785 #ifdef WOLFSSL_DTLS13
786 if (wolfSSL_dtls13_use_quick_timeout(ssl) &&
787 IsAtLeastTLSv1_3(ssl->version)) {
788 if (dtls_timeout >= 4)
789 timeout.tv_sec = dtls_timeout / 4;
790 else
791 timeout.tv_usec = dtls_timeout * 1000000 / 4;
792 }
793 else
794 #endif /* WOLFSSL_DTLS13 */
795 timeout.tv_sec = dtls_timeout;
796 #endif /* USE_WINDOWS_API */
797 if (setsockopt(sd, SOL_SOCKET, SO_RCVTIMEO, (char*)&timeout,
798 sizeof(timeout)) != 0) {
799 WOLFSSL_MSG("setsockopt rcvtimeo failed");
800 }
801 }
802#ifndef NO_ASN_TIME
803 else if (IsSCR(ssl)) {
804 if (ssl->dtls_start_timeout &&
805 LowResTimer() - ssl->dtls_start_timeout >
806 (word32)dtls_timeout) {
807 ssl->dtls_start_timeout = 0;
808 return WOLFSSL_CBIO_ERR_TIMEOUT;
809 }
810 else if (!ssl->dtls_start_timeout) {
811 ssl->dtls_start_timeout = LowResTimer();
812 }
813 }
814#endif /* !NO_ASN_TIME */
815
816 {
817 XSOCKLENT inPeerSz = peerSz;
818 if (dtlsCtx->recvfrom == NULL) {
819 recvd = (int)DTLS_RECVFROM_FUNCTION(sd, buf, (size_t)sz,
820 ssl->rflags, (SOCKADDR*)peer,
821 peer != NULL ? &inPeerSz : NULL);
822 }
823 else {
824 recvd = (int)dtlsCtx->recvfrom(sd, buf, (size_t) sz,
825 ssl->rflags, (SOCKADDR*) peer,
826 peer != NULL ? &inPeerSz : NULL);
827 }
828 /* Truncate peerSz. From the RECV(2) man page
829 * The returned address is truncated if the buffer provided is too
830 * small; in this case, addrlen will return a value greater than was
831 * supplied to the call.
832 */
833 peerSz = MIN(peerSz, inPeerSz);
834 }
835
836 recvd = TranslateIoReturnCode(recvd, sd, SOCKET_RECEIVING);
837
838 if (recvd < 0) {
839 WOLFSSL_MSG("Embed Receive From error");
840 if (recvd == WC_NO_ERR_TRACE(WOLFSSL_CBIO_ERR_WANT_READ) &&
841 !wolfSSL_dtls_get_using_nonblock(ssl)) {
842 recvd = WOLFSSL_CBIO_ERR_TIMEOUT;
843 }
844 return recvd;
845 }
846 else if (recvd == 0) {
847 if (!isDGramSock(sd)) {
848 /* Closed TCP connection */
849 recvd = WOLFSSL_CBIO_ERR_CONN_CLOSE;
850 }
851 else {
852 WOLFSSL_MSG("Ignoring 0-length datagram");
853 continue;
854 }
855 return recvd;
856 }
857 else if (dtlsCtx->connected) {
858 /* Nothing to do */
859 }
860 else if (dtlsCtx->userSet) {
861 /* Check we received the packet from the correct peer */
862 int ignore = 0;
863#ifdef WOLFSSL_RW_THREADED
864 if (wc_LockRwLock_Rd(&ssl->buffers.dtlsCtx.peerLock) != 0)
865 return WOLFSSL_CBIO_ERR_GENERAL;
866#endif
867 if (dtlsCtx->peer.sz > 0 &&
868 (peerSz != (XSOCKLENT)dtlsCtx->peer.sz ||
869 !sockAddrEqual(peer, peerSz, (SOCKADDR_S*)dtlsCtx->peer.sa,
870 dtlsCtx->peer.sz))) {
871 WOLFSSL_MSG(" Ignored packet from invalid peer");
872 ignore = 1;
873 }
874#ifdef WOLFSSL_RW_THREADED
875 if (wc_UnLockRwLock(&ssl->buffers.dtlsCtx.peerLock) != 0)
876 return WOLFSSL_CBIO_ERR_GENERAL;
877#endif
878 if (ignore) {
879#if defined(NO_ASN_TIME) && \
880 !defined(DTLS_RECEIVEFROM_NO_TIMEOUT_ON_INVALID_PEER)
881 if (doDtlsTimeout) {
882 invalidPeerPackets++;
883 if (invalidPeerPackets > DTLS_RECEIVEFROM_MAX_INVALID_PEER)
884 return wolfSSL_dtls_get_using_nonblock(ssl)
885 ? WOLFSSL_CBIO_ERR_WANT_READ
886 : WOLFSSL_CBIO_ERR_TIMEOUT;
887 }
888#endif /* NO_ASN_TIME && !DTLS_RECEIVEFROM_NO_TIMEOUT_ON_INVALID_PEER */
889 continue;
890 }
891 }
892 else {
893 if (newPeer) {
894 /* Store size of saved address. Locking handled internally. */
895 if (wolfSSL_dtls_set_peer(ssl, peer, peerSz) != WOLFSSL_SUCCESS)
896 return WOLFSSL_CBIO_ERR_GENERAL;
897 dtlsCtx->userSet = 0;
898 }
899#ifndef WOLFSSL_PEER_ADDRESS_CHANGES
900 else {
901 ret = 0;
902 #ifdef WOLFSSL_RW_THREADED
903 if (wc_LockRwLock_Rd(&ssl->buffers.dtlsCtx.peerLock) != 0)
904 return WOLFSSL_CBIO_ERR_GENERAL;
905 #endif /* WOLFSSL_RW_THREADED */
906 if (!sockAddrEqual(peer, peerSz, (SOCKADDR_S*)dtlsCtx->peer.sa,
907 dtlsCtx->peer.sz)) {
908 ret = WOLFSSL_CBIO_ERR_GENERAL;
909 }
910 #ifdef WOLFSSL_RW_THREADED
911 if (wc_UnLockRwLock(&ssl->buffers.dtlsCtx.peerLock) != 0)
912 return WOLFSSL_CBIO_ERR_GENERAL;
913 #endif /* WOLFSSL_RW_THREADED */
914 if (ret != 0)
915 return ret;
916 }
917#endif /* !WOLFSSL_PEER_ADDRESS_CHANGES */
918 }
919#ifndef NO_ASN_TIME
920 ssl->dtls_start_timeout = 0;
921#endif /* !NO_ASN_TIME */
922 break;
923 } while (1);
924
925 return recvd;
926}
927
928
929/* The send embedded callback
930 * return : nb bytes sent, or error
931 */
932int EmbedSendTo(WOLFSSL* ssl, char *buf, int sz, void *ctx)
933{
934 WOLFSSL_DTLS_CTX* dtlsCtx = (WOLFSSL_DTLS_CTX*)ctx;
935 int sd = dtlsCtx->wfd;
936 int sent;
937 const SOCKADDR_S* peer = NULL;
938 XSOCKLENT peerSz = 0;
939
940 WOLFSSL_ENTER("EmbedSendTo");
941
942 if (sz < 0)
943 return WOLFSSL_CBIO_ERR_GENERAL;
944
945 if (!isDGramSock(sd)) {
946 /* Probably a TCP socket. peer and peerSz MUST be NULL and 0 */
947 }
948 else if (!dtlsCtx->connected) {
949 peer = (const SOCKADDR_S*)dtlsCtx->peer.sa;
950 peerSz = dtlsCtx->peer.sz;
951#ifndef WOLFSSL_IPV6
952 if (PeerIsIpv6(peer, peerSz)) {
953 WOLFSSL_MSG("ipv6 dtls peer set but no ipv6 support compiled");
954 return NOT_COMPILED_IN;
955 }
956#endif
957 }
958
959 if (dtlsCtx->sendto == NULL) {
960 sent = (int)DTLS_SENDTO_FUNCTION(sd, buf, (size_t)sz, ssl->wflags,
961 (const SOCKADDR*)peer, peerSz);
962 }
963 else {
964 sent = (int)dtlsCtx->sendto(sd, buf, (size_t)sz, ssl->wflags,
965 (const SOCKADDR*)peer, peerSz);
966 }
967
968 sent = TranslateIoReturnCode(sent, sd, SOCKET_SENDING);
969
970 if (sent < 0) {
971 WOLFSSL_MSG("Embed Send To error");
972 }
973
974 return sent;
975}
976
977
978#ifdef WOLFSSL_MULTICAST
979
980/* The alternate receive embedded callback for Multicast
981 * return : nb bytes read, or error
982 */
983int EmbedReceiveFromMcast(WOLFSSL *ssl, char *buf, int sz, void *ctx)
984{
985 WOLFSSL_DTLS_CTX* dtlsCtx = (WOLFSSL_DTLS_CTX*)ctx;
986 int recvd;
987 int sd = dtlsCtx->rfd;
988
989 WOLFSSL_ENTER("EmbedReceiveFromMcast");
990
991 if (sz < 0)
992 return WOLFSSL_CBIO_ERR_GENERAL;
993
994 recvd = (int)DTLS_RECVFROM_FUNCTION(sd, buf, (size_t)sz, ssl->rflags, NULL, NULL);
995
996 recvd = TranslateIoReturnCode(recvd, sd, SOCKET_RECEIVING);
997
998 if (recvd < 0) {
999 WOLFSSL_MSG("Embed Receive From error");
1000 if (recvd == WC_NO_ERR_TRACE(WOLFSSL_CBIO_ERR_WANT_READ) &&
1001 !wolfSSL_dtls_get_using_nonblock(ssl)) {
1002 recvd = WOLFSSL_CBIO_ERR_TIMEOUT;
1003 }
1004 }
1005
1006 return recvd;
1007}
1008#endif /* WOLFSSL_MULTICAST */
1009
1010
1011/* The DTLS Generate Cookie callback
1012 * return : number of bytes copied into buf, or error
1013 */
1014int EmbedGenerateCookie(WOLFSSL* ssl, byte *buf, int sz, void *ctx)
1015{
1016 int sd = ssl->wfd;
1017 SOCKADDR_S peer;
1018 XSOCKLENT peerSz = sizeof(peer);
1019 byte digest[WC_SHA256_DIGEST_SIZE];
1020 int ret = 0;
1021
1022 (void)ctx;
1023
1024 if (sz < 0)
1025 return BAD_FUNC_ARG;
1026
1027 XMEMSET(&peer, 0, sizeof(peer));
1028 if (getpeername(sd, (SOCKADDR*)&peer, &peerSz) != 0) {
1029 WOLFSSL_MSG("getpeername failed in EmbedGenerateCookie");
1030 return GEN_COOKIE_E;
1031 }
1032
1033 ret = wc_Sha256Hash((byte*)&peer, peerSz, digest);
1034 if (ret != 0)
1035 return ret;
1036
1037 if (sz > WC_SHA256_DIGEST_SIZE)
1038 sz = WC_SHA256_DIGEST_SIZE;
1039 XMEMCPY(buf, digest, (size_t)sz);
1040
1041 return sz;
1042}
1043#endif /* WOLFSSL_DTLS */
1044
1045#ifdef WOLFSSL_SESSION_EXPORT
1046
1047#ifdef WOLFSSL_DTLS
1048 static int EmbedGetPeerDTLS(WOLFSSL* ssl, char* ip, int* ipSz,
1049 unsigned short* port, int* fam)
1050 {
1051 SOCKADDR_S peer;
1052 word32 peerSz;
1053 int ret;
1054
1055 /* get peer information stored in ssl struct */
1056 peerSz = sizeof(SOCKADDR_S);
1057 if ((ret = wolfSSL_dtls_get_peer(ssl, (void*)&peer, &peerSz))
1058 != WOLFSSL_SUCCESS) {
1059 return ret;
1060 }
1061
1062 /* extract family, ip, and port */
1063 *fam = ((SOCKADDR_S*)&peer)->ss_family;
1064 switch (*fam) {
1065 case WOLFSSL_IP4:
1066 if (XINET_NTOP(*fam, &(((SOCKADDR_IN*)&peer)->sin_addr),
1067 ip, *ipSz) == NULL) {
1068 WOLFSSL_MSG("XINET_NTOP error");
1069 return SOCKET_ERROR_E;
1070 }
1071 *port = XNTOHS(((SOCKADDR_IN*)&peer)->sin_port);
1072 break;
1073
1074 case WOLFSSL_IP6:
1075 #ifdef WOLFSSL_IPV6
1076 if (XINET_NTOP(*fam, &(((SOCKADDR_IN6*)&peer)->sin6_addr),
1077 ip, *ipSz) == NULL) {
1078 WOLFSSL_MSG("XINET_NTOP error");
1079 return SOCKET_ERROR_E;
1080 }
1081 *port = XNTOHS(((SOCKADDR_IN6*)&peer)->sin6_port);
1082 #endif /* WOLFSSL_IPV6 */
1083 break;
1084
1085 default:
1086 WOLFSSL_MSG("Unknown family type");
1087 return SOCKET_ERROR_E;
1088 }
1089 ip[*ipSz - 1] = '\0'; /* make sure has terminator */
1090 *ipSz = (word16)XSTRLEN(ip);
1091
1092 return WOLFSSL_SUCCESS;
1093 }
1094
1095 static int EmbedSetPeerDTLS(WOLFSSL* ssl, char* ip, int ipSz,
1096 unsigned short port, int fam)
1097 {
1098 int ret;
1099 SOCKADDR_S addr;
1100
1101 /* sanity checks on arguments */
1102 if (ssl == NULL || ip == NULL || ipSz < 0 || ipSz > MAX_EXPORT_IP) {
1103 return BAD_FUNC_ARG;
1104 }
1105
1106 addr.ss_family = fam;
1107 switch (addr.ss_family) {
1108 case WOLFSSL_IP4:
1109 if (XINET_PTON(addr.ss_family, ip,
1110 &(((SOCKADDR_IN*)&addr)->sin_addr)) <= 0) {
1111 WOLFSSL_MSG("XINET_PTON error");
1112 return SOCKET_ERROR_E;
1113 }
1114 ((SOCKADDR_IN*)&addr)->sin_port = XHTONS(port);
1115
1116 /* peer sa is free'd in wolfSSL_ResourceFree */
1117 if ((ret = wolfSSL_dtls_set_peer(ssl, (SOCKADDR_IN*)&addr,
1118 sizeof(SOCKADDR_IN)))!= WOLFSSL_SUCCESS) {
1119 WOLFSSL_MSG("Import DTLS peer info error");
1120 return ret;
1121 }
1122 break;
1123
1124 case WOLFSSL_IP6:
1125 #ifdef WOLFSSL_IPV6
1126 if (XINET_PTON(addr.ss_family, ip,
1127 &(((SOCKADDR_IN6*)&addr)->sin6_addr)) <= 0) {
1128 WOLFSSL_MSG("XINET_PTON error");
1129 return SOCKET_ERROR_E;
1130 }
1131 ((SOCKADDR_IN6*)&addr)->sin6_port = XHTONS(port);
1132
1133 /* peer sa is free'd in wolfSSL_ResourceFree */
1134 if ((ret = wolfSSL_dtls_set_peer(ssl, (SOCKADDR_IN6*)&addr,
1135 sizeof(SOCKADDR_IN6)))!= WOLFSSL_SUCCESS) {
1136 WOLFSSL_MSG("Import DTLS peer info error");
1137 return ret;
1138 }
1139 #endif /* WOLFSSL_IPV6 */
1140 break;
1141
1142 default:
1143 WOLFSSL_MSG("Unknown address family");
1144 return BUFFER_E;
1145 }
1146
1147 return WOLFSSL_SUCCESS;
1148 }
1149#endif /* WOLFSSL_DTLS */
1150
1151 /* get the peer information in human readable form (ip, port, family)
1152 * default function assumes BSD sockets
1153 * can be overridden with wolfSSL_CTX_SetIOGetPeer
1154 */
1155 int EmbedGetPeer(WOLFSSL* ssl, char* ip, int* ipSz,
1156 unsigned short* port, int* fam)
1157 {
1158 if (ssl == NULL || ip == NULL || ipSz == NULL ||
1159 port == NULL || fam == NULL) {
1160 return BAD_FUNC_ARG;
1161 }
1162
1163 if (ssl->options.dtls) {
1164 #ifdef WOLFSSL_DTLS
1165 return EmbedGetPeerDTLS(ssl, ip, ipSz, port, fam);
1166 #else
1167 return NOT_COMPILED_IN;
1168 #endif
1169 }
1170 else {
1171 *port = wolfSSL_get_fd(ssl);
1172 ip[0] = '\0';
1173 *ipSz = 0;
1174 *fam = 0;
1175 return WOLFSSL_SUCCESS;
1176 }
1177 }
1178
1179 /* set the peer information in human readable form (ip, port, family)
1180 * default function assumes BSD sockets
1181 * can be overridden with wolfSSL_CTX_SetIOSetPeer
1182 */
1183 int EmbedSetPeer(WOLFSSL* ssl, char* ip, int ipSz,
1184 unsigned short port, int fam)
1185 {
1186 /* sanity checks on arguments */
1187 if (ssl == NULL || ip == NULL || ipSz < 0 || ipSz > MAX_EXPORT_IP) {
1188 return BAD_FUNC_ARG;
1189 }
1190
1191 if (ssl->options.dtls) {
1192 #ifdef WOLFSSL_DTLS
1193 return EmbedSetPeerDTLS(ssl, ip, ipSz, port, fam);
1194 #else
1195 return NOT_COMPILED_IN;
1196 #endif
1197 }
1198 else {
1199 wolfSSL_set_fd(ssl, port);
1200 (void)fam;
1201 return WOLFSSL_SUCCESS;
1202 }
1203 }
1204#endif /* WOLFSSL_SESSION_EXPORT */
1205
1206#ifdef WOLFSSL_LINUXKM
1207static int linuxkm_send(struct socket *socket, void *buf, int size,
1208 unsigned int flags)
1209{
1210 size_t len;
1211 int ret;
1212 struct kvec vec;
1213 struct msghdr msg = { .msg_flags = flags };
1214
1215 if (size < 0)
1216 return -EINVAL;
1217 if (size == 0)
1218 return 0;
1219
1220 len = (size_t)size;
1221 vec.iov_base = buf;
1222 vec.iov_len = len;
1223
1224 ret = kernel_sendmsg(socket, &msg, &vec, 1, len);
1225 return ret;
1226}
1227
1228static int linuxkm_recv(struct socket *socket, void *buf, int size,
1229 unsigned int flags)
1230{
1231 size_t len;
1232 int ret;
1233 struct kvec vec;
1234 struct msghdr msg = { .msg_flags = flags };
1235
1236 if (size < 0)
1237 return -EINVAL;
1238 if (size == 0)
1239 return 0;
1240
1241 len = (size_t)size;
1242 vec.iov_base = buf;
1243 vec.iov_len = len;
1244
1245 ret = kernel_recvmsg(socket, &msg, &vec, 1, len, msg.msg_flags);
1246 return ret;
1247}
1248#endif /* WOLFSSL_LINUXKM */
1249
1250
1251int wolfIO_Recv(SOCKET_T sd, char *buf, int sz, int rdFlags)
1252{
1253 int recvd;
1254
1255 if (sz < 0)
1256 return WOLFSSL_CBIO_ERR_GENERAL;
1257
1258 recvd = (int)RECV_FUNCTION(sd, buf, (size_t)sz, rdFlags);
1259 recvd = TranslateIoReturnCode(recvd, sd, SOCKET_RECEIVING);
1260
1261 return recvd;
1262}
1263
1264int wolfIO_Send(SOCKET_T sd, char *buf, int sz, int wrFlags)
1265{
1266 int sent;
1267
1268 if (sz < 0)
1269 return WOLFSSL_CBIO_ERR_GENERAL;
1270
1271 sent = (int)SEND_FUNCTION(sd, buf, (size_t)sz, wrFlags);
1272 sent = TranslateIoReturnCode(sent, sd, SOCKET_SENDING);
1273
1274 return sent;
1275}
1276
1277#if defined(WOLFSSL_HAVE_BIO_ADDR) && defined(WOLFSSL_DTLS) && defined(OPENSSL_EXTRA)
1278
1279int wolfIO_RecvFrom(SOCKET_T sd, WOLFSSL_BIO_ADDR *addr, char *buf, int sz, int rdFlags)
1280{
1281 int recvd;
1282 socklen_t addr_len = (socklen_t)sizeof(*addr);
1283
1284 if (sz < 0)
1285 return WOLFSSL_CBIO_ERR_GENERAL;
1286
1287 recvd = (int)DTLS_RECVFROM_FUNCTION(sd, buf, (size_t)sz, rdFlags,
1288 addr ? &addr->sa : NULL,
1289 addr ? &addr_len : 0);
1290 recvd = TranslateIoReturnCode(recvd, sd, SOCKET_RECEIVING);
1291
1292 return recvd;
1293}
1294
1295int wolfIO_SendTo(SOCKET_T sd, WOLFSSL_BIO_ADDR *addr, char *buf, int sz, int wrFlags)
1296{
1297 int sent;
1298 socklen_t addr_len = addr ? wolfSSL_BIO_ADDR_size(addr) : 0;
1299
1300 if (sz < 0)
1301 return WOLFSSL_CBIO_ERR_GENERAL;
1302
1303 sent = (int)DTLS_SENDTO_FUNCTION(sd, buf, (size_t)sz, wrFlags,
1304 addr ? &addr->sa : NULL,
1305 addr_len);
1306 sent = TranslateIoReturnCode(sent, sd, SOCKET_SENDING);
1307
1308 return sent;
1309}
1310
1311#endif /* WOLFSSL_HAVE_BIO_ADDR && WOLFSSL_DTLS && OPENSSL_EXTRA */
1312
1313#endif /* USE_WOLFSSL_IO */
1314
1315
1316#ifdef HAVE_HTTP_CLIENT
1317
1318#ifndef HAVE_IO_TIMEOUT
1319 #define io_timeout_sec 0
1320#else
1321
1322 #ifndef DEFAULT_TIMEOUT_SEC
1323 #define DEFAULT_TIMEOUT_SEC 0 /* no timeout */
1324 #endif
1325
1326 static int io_timeout_sec = DEFAULT_TIMEOUT_SEC;
1327
1328 void wolfIO_SetTimeout(int to_sec)
1329 {
1330 io_timeout_sec = to_sec;
1331 }
1332
1333 int wolfIO_SetBlockingMode(SOCKET_T sockfd, int non_blocking)
1334 {
1335 int ret = 0;
1336
1337 #ifdef USE_WINDOWS_API
1338 unsigned long blocking = non_blocking;
1339 ret = ioctlsocket(sockfd, FIONBIO, &blocking);
1340 if (ret == SOCKET_ERROR)
1341 ret = WOLFSSL_FATAL_ERROR;
1342 #elif defined(__WATCOMC__) && defined(__OS2__)
1343 if (ioctl(sockfd, FIONBIO, &non_blocking) == -1)
1344 ret = WOLFSSL_FATAL_ERROR;
1345 #else
1346 ret = fcntl(sockfd, F_GETFL, 0);
1347 if (ret >= 0) {
1348 if (non_blocking)
1349 ret |= O_NONBLOCK;
1350 else
1351 ret &= ~O_NONBLOCK;
1352 ret = fcntl(sockfd, F_SETFL, ret);
1353 }
1354 #endif
1355 if (ret < 0) {
1356 WOLFSSL_MSG("wolfIO_SetBlockingMode failed");
1357 }
1358
1359 return ret;
1360 }
1361
1362 int wolfIO_Select(SOCKET_T sockfd, int to_sec)
1363 {
1364 fd_set rfds, wfds;
1365 int nfds = 0;
1366 struct timeval timeout = { (to_sec > 0) ? to_sec : 0, 0};
1367 int ret;
1368
1369 #ifndef USE_WINDOWS_API
1370 nfds = (int)sockfd + 1;
1371
1372 if ((sockfd < 0) || (sockfd >= FD_SETSIZE)) {
1373 WOLFSSL_MSG("socket fd out of FDSET range");
1374 return WOLFSSL_FATAL_ERROR;
1375 }
1376 #endif
1377
1378 FD_ZERO(&rfds);
1379 FD_SET(sockfd, &rfds);
1380 wfds = rfds;
1381
1382 ret = select(nfds, &rfds, &wfds, NULL, &timeout);
1383 if (ret == 0) {
1384 #ifdef DEBUG_HTTP
1385 fprintf(stderr, "Timeout: %d\n", ret);
1386 #endif
1387 return HTTP_TIMEOUT;
1388 }
1389 else if (ret > 0) {
1390 if (FD_ISSET(sockfd, &wfds)) {
1391 if (!FD_ISSET(sockfd, &rfds)) {
1392 return 0;
1393 }
1394 }
1395 }
1396
1397 WOLFSSL_MSG("Select error");
1398 return SOCKET_ERROR_E;
1399 }
1400#endif /* HAVE_IO_TIMEOUT */
1401
1402static word32 wolfIO_Word16ToString(char* d, word16 number)
1403{
1404 word32 i = 0;
1405 word16 order = 10000;
1406 word16 digit;
1407
1408 if (d == NULL)
1409 return i;
1410
1411 if (number == 0)
1412 d[i++] = '0';
1413 else {
1414 while (order) {
1415 digit = number / order;
1416 if (i > 0 || digit != 0)
1417 d[i++] = (char)digit + '0';
1418 if (digit != 0)
1419 number = (word16) (number % (digit * order));
1420
1421 order = (order > 1) ? order / 10 : 0;
1422 }
1423 }
1424 d[i] = 0; /* null terminate */
1425
1426 return i;
1427}
1428
1429int wolfIO_TcpConnect(SOCKET_T* sockfd, const char* ip, word16 port, int to_sec)
1430{
1431#ifdef HAVE_SOCKADDR
1432 int ret = 0;
1433 SOCKADDR_S addr;
1434 socklen_t sockaddr_len;
1435#if defined(HAVE_GETADDRINFO)
1436 /* use getaddrinfo */
1437 ADDRINFO hints;
1438 ADDRINFO* answer = NULL;
1439 char strPort[6];
1440#else
1441 /* use gethostbyname */
1442#if defined(__GLIBC__) && (__GLIBC__ >= 2) && defined(__USE_MISC) && \
1443 !defined(SINGLE_THREADED)
1444 HOSTENT entry_buf, *entry = NULL;
1445 char *ghbn_r_buf = NULL;
1446 int ghbn_r_errno;
1447#else
1448 HOSTENT *entry;
1449#endif
1450#ifdef WOLFSSL_IPV6
1451 SOCKADDR_IN6 *sin;
1452#else
1453 SOCKADDR_IN *sin;
1454#endif /* WOLFSSL_IPV6 */
1455#endif /* HAVE_GETADDRINFO */
1456
1457 if (sockfd == NULL || ip == NULL) {
1458 return WOLFSSL_FATAL_ERROR;
1459 }
1460
1461#if !defined(HAVE_GETADDRINFO)
1462#ifdef WOLFSSL_IPV6
1463 sockaddr_len = sizeof(SOCKADDR_IN6);
1464#else
1465 sockaddr_len = sizeof(SOCKADDR_IN);
1466#endif /* WOLFSSL_IPV6 */
1467#endif /* !HAVE_GETADDRINFO */
1468 XMEMSET(&addr, 0, sizeof(addr));
1469
1470#ifdef WOLFIO_DEBUG
1471 printf("TCP Connect: %s:%d\n", ip, port);
1472#endif
1473
1474 /* use gethostbyname for c99 */
1475#if defined(HAVE_GETADDRINFO)
1476 XMEMSET(&hints, 0, sizeof(hints));
1477#ifdef WOLFSSL_IPV6
1478 hints.ai_family = AF_UNSPEC; /* detect IPv4 or IPv6 */
1479#else
1480 hints.ai_family = AF_INET; /* detect only IPv4 */
1481#endif
1482 hints.ai_socktype = SOCK_STREAM;
1483 hints.ai_protocol = IPPROTO_TCP;
1484
1485 if (wolfIO_Word16ToString(strPort, port) == 0) {
1486 WOLFSSL_MSG("invalid port number for responder");
1487 return WOLFSSL_FATAL_ERROR;
1488 }
1489
1490 if (getaddrinfo(ip, strPort, &hints, &answer) < 0 || answer == NULL) {
1491 WOLFSSL_MSG("no addr info for responder");
1492 return WOLFSSL_FATAL_ERROR;
1493 }
1494
1495 sockaddr_len = answer->ai_addrlen;
1496 XMEMCPY(&addr, answer->ai_addr, (size_t)sockaddr_len);
1497 freeaddrinfo(answer);
1498#else
1499#if defined(__GLIBC__) && (__GLIBC__ >= 2) && defined(__USE_MISC) && \
1500 !defined(SINGLE_THREADED)
1501 /* 2048 is a magic number that empirically works. the header and
1502 * documentation provide no guidance on appropriate buffer size other than
1503 * "if buf is too small, the functions will return ERANGE, and the call
1504 * should be retried with a larger buffer."
1505 */
1506 ghbn_r_buf = (char *)XMALLOC(2048, NULL, DYNAMIC_TYPE_TMP_BUFFER);
1507 if (ghbn_r_buf != NULL) {
1508 gethostbyname_r(ip, &entry_buf, ghbn_r_buf, 2048, &entry, &ghbn_r_errno);
1509 }
1510#else
1511 entry = gethostbyname(ip);
1512#endif
1513
1514 if (entry) {
1515 #ifdef WOLFSSL_IPV6
1516 sin = (SOCKADDR_IN6 *)&addr;
1517 sin->sin6_family = AF_INET6;
1518 sin->sin6_port = XHTONS(port);
1519 XMEMCPY(&sin->sin6_addr, entry->h_addr_list[0], entry->h_length);
1520 #else
1521 sin = (SOCKADDR_IN *)&addr;
1522 sin->sin_family = AF_INET;
1523 sin->sin_port = XHTONS(port);
1524 XMEMCPY(&sin->sin_addr.s_addr, entry->h_addr_list[0],
1525 (size_t)entry->h_length);
1526 #endif
1527 }
1528
1529#if defined(__GLIBC__) && (__GLIBC__ >= 2) && defined(__USE_MISC) && \
1530 !defined(SINGLE_THREADED)
1531 XFREE(ghbn_r_buf, NULL, DYNAMIC_TYPE_TMP_BUFFER);
1532#endif
1533
1534 if (entry == NULL) {
1535 WOLFSSL_MSG("no addr info for responder");
1536 return WOLFSSL_FATAL_ERROR;
1537 }
1538#endif
1539
1540 *sockfd = (SOCKET_T)wc_socket_cloexec(addr.ss_family, SOCK_STREAM, 0);
1541#ifdef USE_WINDOWS_API
1542 if (*sockfd == SOCKET_INVALID)
1543#else
1544 if (*sockfd <= SOCKET_INVALID)
1545#endif
1546 {
1547 WOLFSSL_MSG("bad socket fd, out of fds?");
1548 *sockfd = SOCKET_INVALID;
1549 return WOLFSSL_FATAL_ERROR;
1550 }
1551
1552#ifdef HAVE_IO_TIMEOUT
1553 /* if timeout value provided then set socket non-blocking */
1554 if (to_sec > 0) {
1555 wolfIO_SetBlockingMode(*sockfd, 1);
1556 }
1557#else
1558 (void)to_sec;
1559#endif /* HAVE_IO_TIMEOUT */
1560
1561 ret = connect(*sockfd, (SOCKADDR *)&addr, sockaddr_len);
1562#ifdef HAVE_IO_TIMEOUT
1563 if ((ret != 0) && (to_sec > 0)) {
1564#ifdef USE_WINDOWS_API
1565 if ((ret == SOCKET_ERROR) &&
1566 (wolfSSL_LastError(ret, *sockfd) == SOCKET_EWOULDBLOCK))
1567#else
1568 if (errno == EINPROGRESS)
1569#endif
1570 {
1571 /* wait for connect to complete */
1572 ret = wolfIO_Select(*sockfd, to_sec);
1573
1574 /* restore blocking mode */
1575 wolfIO_SetBlockingMode(*sockfd, 0);
1576 }
1577 }
1578#endif /* HAVE_IO_TIMEOUT */
1579 if (ret != 0) {
1580 WOLFSSL_MSG("Responder tcp connect failed");
1581 CloseSocket(*sockfd);
1582 *sockfd = SOCKET_INVALID;
1583 return WOLFSSL_FATAL_ERROR;
1584 }
1585 return ret;
1586#else
1587 (void)sockfd;
1588 (void)ip;
1589 (void)port;
1590 (void)to_sec;
1591 return WOLFSSL_FATAL_ERROR;
1592#endif /* HAVE_SOCKADDR */
1593}
1594
1595int wolfIO_TcpBind(SOCKET_T* sockfd, word16 port)
1596{
1597#ifdef HAVE_SOCKADDR
1598 int ret = 0;
1599 SOCKADDR_S addr;
1600#ifdef WOLFSSL_IPV6
1601 socklen_t sockaddr_len = sizeof(SOCKADDR_IN6);
1602 SOCKADDR_IN6 *sin = (SOCKADDR_IN6 *)&addr;
1603#else
1604 socklen_t sockaddr_len = sizeof(SOCKADDR_IN);
1605 SOCKADDR_IN *sin = (SOCKADDR_IN *)&addr;
1606#endif
1607
1608 if (sockfd == NULL || port < 1) {
1609 return WOLFSSL_FATAL_ERROR;
1610 }
1611
1612 XMEMSET(&addr, 0, sizeof(addr));
1613
1614#ifdef WOLFSSL_IPV6
1615 sin->sin6_family = AF_INET6;
1616 sin->sin6_addr = in6addr_any;
1617 sin->sin6_port = XHTONS(port);
1618 *sockfd = (SOCKET_T)wc_socket_cloexec(AF_INET6, SOCK_STREAM, 0);
1619#else
1620 sin->sin_family = AF_INET;
1621 sin->sin_addr.s_addr = INADDR_ANY;
1622 sin->sin_port = XHTONS(port);
1623 *sockfd = (SOCKET_T)wc_socket_cloexec(AF_INET, SOCK_STREAM, 0);
1624#endif
1625
1626#ifdef USE_WINDOWS_API
1627 if (*sockfd == SOCKET_INVALID)
1628#else
1629 if (*sockfd <= SOCKET_INVALID)
1630#endif
1631 {
1632 WOLFSSL_MSG("socket failed");
1633 *sockfd = SOCKET_INVALID;
1634 return WOLFSSL_FATAL_ERROR;
1635 }
1636
1637#if !defined(USE_WINDOWS_API) && !defined(WOLFSSL_MDK_ARM)\
1638 && !defined(WOLFSSL_KEIL_TCP_NET) && !defined(WOLFSSL_ZEPHYR)
1639 {
1640 int optval = 1;
1641 XSOCKLENT optlen = sizeof(optval);
1642 ret = setsockopt(*sockfd, SOL_SOCKET, SO_REUSEADDR, &optval, optlen);
1643 }
1644#endif
1645
1646 if (ret == 0)
1647 ret = bind(*sockfd, (SOCKADDR *)sin, sockaddr_len);
1648 if (ret == 0)
1649 ret = listen(*sockfd, SOMAXCONN);
1650
1651 if (ret != 0) {
1652 WOLFSSL_MSG("wolfIO_TcpBind failed");
1653 CloseSocket(*sockfd);
1654 *sockfd = SOCKET_INVALID;
1655 ret = WOLFSSL_FATAL_ERROR;
1656 }
1657
1658 return ret;
1659#else
1660 (void)sockfd;
1661 (void)port;
1662 return WOLFSSL_FATAL_ERROR;
1663#endif /* HAVE_SOCKADDR */
1664}
1665
1666#ifdef HAVE_SOCKADDR
1667int wolfIO_TcpAccept(SOCKET_T sockfd, SOCKADDR* peer_addr, XSOCKLENT* peer_len)
1668{
1669 return (int)wc_accept_cloexec((int)sockfd, peer_addr, peer_len);
1670}
1671#endif /* HAVE_SOCKADDR */
1672
1673#ifndef HTTP_SCRATCH_BUFFER_SIZE
1674 #define HTTP_SCRATCH_BUFFER_SIZE 512
1675#endif
1676#ifndef MAX_URL_ITEM_SIZE
1677 #define MAX_URL_ITEM_SIZE 80
1678#endif
1679
1680int wolfIO_DecodeUrl(const char* url, int urlSz, char* outName, char* outPath,
1681 word16* outPort)
1682{
1683 int result = -1;
1684
1685 if (url == NULL || urlSz == 0) {
1686 if (outName)
1687 *outName = 0;
1688 if (outPath)
1689 *outPath = 0;
1690 if (outPort)
1691 *outPort = 0;
1692 }
1693 else {
1694 int i, cur;
1695
1696 /* need to break the url down into scheme, address, and port */
1697 /* "http://example.com:8080/" */
1698 /* "http://[::1]:443/" */
1699 if (XSTRNCMP(url, "http://", 7) == 0) {
1700 cur = 7;
1701 } else cur = 0;
1702
1703 i = 0;
1704 if (url[cur] == '[') {
1705 cur++;
1706 /* copy until ']' */
1707 while (i < MAX_URL_ITEM_SIZE-1 && cur < urlSz && url[cur] != 0 &&
1708 url[cur] != ']') {
1709 if (outName)
1710 outName[i] = url[cur];
1711 i++; cur++;
1712 }
1713 cur++; /* skip ']' */
1714 }
1715 else {
1716 while (i < MAX_URL_ITEM_SIZE-1 && cur < urlSz && url[cur] != 0 &&
1717 url[cur] != ':' && url[cur] != '/') {
1718 if (outName)
1719 outName[i] = url[cur];
1720 i++; cur++;
1721 }
1722 }
1723 if (outName)
1724 outName[i] = 0;
1725 /* Need to pick out the path after the domain name */
1726
1727 if (cur < urlSz && url[cur] == ':') {
1728 char port[6];
1729 int j;
1730 word32 bigPort = 0;
1731 i = 0;
1732 cur++;
1733
1734 XMEMSET(port, 0, sizeof(port));
1735
1736 while (i < 6 && cur < urlSz && url[cur] != 0 && url[cur] != '/') {
1737 port[i] = url[cur];
1738 i++; cur++;
1739 }
1740
1741 for (j = 0; j < i; j++) {
1742 if (port[j] < '0' || port[j] > '9') return WOLFSSL_FATAL_ERROR;
1743 bigPort = (bigPort * 10) + (word32)(port[j] - '0');
1744 }
1745 if (outPort)
1746 *outPort = (word16)bigPort;
1747 }
1748 else if (outPort)
1749 *outPort = 80;
1750
1751
1752 if (cur < urlSz && url[cur] == '/') {
1753 i = 0;
1754 while (i < MAX_URL_ITEM_SIZE-1 && cur < urlSz && url[cur] != 0) {
1755 if (outPath)
1756 outPath[i] = url[cur];
1757 i++; cur++;
1758 }
1759 if (outPath)
1760 outPath[i] = 0;
1761 }
1762 else if (outPath) {
1763 outPath[0] = '/';
1764 outPath[1] = 0;
1765 }
1766
1767 result = 0;
1768 }
1769
1770 return result;
1771}
1772
1773#ifndef WOLFIO_HTTP_MAX_BODY
1774/* Upper bound on an HTTP body that will be buffered in memory. */
1775#define WOLFIO_HTTP_MAX_BODY (32 * 1024 * 1024)
1776#endif
1777
1778static int wolfIO_HttpProcessResponseBuf(WolfSSLGenericIORecvCb ioCb,
1779 void* ioCbCtx, byte **recvBuf, int* recvBufSz, int chunkSz, char* start,
1780 int len, int dynType, void* heap)
1781{
1782 byte* newRecvBuf = NULL;
1783 int newRecvSz;
1784 int pos = 0;
1785
1786 WOLFSSL_MSG("Processing HTTP response");
1787#ifdef WOLFIO_DEBUG
1788 printf("HTTP Chunk %d->%d\n", *recvBufSz, chunkSz);
1789#endif
1790
1791 (void)heap;
1792 (void)dynType;
1793
1794 if (chunkSz < 0 || len < 0) {
1795 WOLFSSL_MSG("wolfIO_HttpProcessResponseBuf invalid chunk or length size");
1796 return MEMORY_E;
1797 }
1798
1799 if (chunkSz > WOLFIO_HTTP_MAX_BODY) {
1800 WOLFSSL_MSG("wolfIO_HttpProcessResponseBuf chunk too large");
1801 return BUFFER_ERROR;
1802 }
1803
1804 if (*recvBufSz < 0 || *recvBufSz > WOLFIO_HTTP_MAX_BODY - chunkSz) {
1805 WOLFSSL_MSG("wolfIO_HttpProcessResponseBuf aggregate body too large");
1806 return BUFFER_ERROR;
1807 }
1808
1809 if (len > chunkSz) {
1810 WOLFSSL_MSG("wolfIO_HttpProcessResponseBuf len exceeds chunk size");
1811 return WOLFSSL_FATAL_ERROR;
1812 }
1813
1814 newRecvSz = *recvBufSz + chunkSz;
1815
1816 if (newRecvSz <= 0) {
1817 WOLFSSL_MSG("wolfIO_HttpProcessResponseBuf new receive size overflow");
1818 return MEMORY_E;
1819 }
1820
1821 newRecvBuf = (byte*)XMALLOC((size_t)newRecvSz, heap, dynType);
1822 if (newRecvBuf == NULL) {
1823 WOLFSSL_MSG("wolfIO_HttpProcessResponseBuf malloc failed");
1824 return MEMORY_E;
1825 }
1826
1827 /* if buffer already exists, then we are growing it */
1828 if (*recvBuf) {
1829 XMEMCPY(&newRecvBuf[pos], *recvBuf, (size_t) *recvBufSz);
1830 XFREE(*recvBuf, heap, dynType);
1831 pos += *recvBufSz;
1832 *recvBuf = NULL;
1833 }
1834
1835 /* copy the remainder of the httpBuf into the respBuf */
1836 if (len != 0) {
1837 if (pos + len <= newRecvSz) {
1838 XMEMCPY(&newRecvBuf[pos], start, (size_t)len);
1839 pos += len;
1840 }
1841 else {
1842 WOLFSSL_MSG("wolfIO_HttpProcessResponseBuf bad size");
1843 XFREE(newRecvBuf, heap, dynType);
1844 return WOLFSSL_FATAL_ERROR;
1845 }
1846 }
1847
1848 /* receive the remainder of chunk */
1849 while (len < chunkSz) {
1850 int rxSz = ioCb((char*)&newRecvBuf[pos], chunkSz-len, ioCbCtx);
1851 if (rxSz > 0) {
1852 len += rxSz;
1853 pos += rxSz;
1854 }
1855 else {
1856 WOLFSSL_MSG("wolfIO_HttpProcessResponseBuf recv failed");
1857 XFREE(newRecvBuf, heap, dynType);
1858 return WOLFSSL_FATAL_ERROR;
1859 }
1860 }
1861
1862 *recvBuf = newRecvBuf;
1863 *recvBufSz = newRecvSz;
1864
1865 return 0;
1866}
1867
1868int wolfIO_HttpProcessResponseGenericIO(WolfSSLGenericIORecvCb ioCb,
1869 void* ioCbCtx, const char** appStrList, unsigned char** respBuf,
1870 unsigned char* httpBuf, int httpBufSz, int dynType, void* heap)
1871{
1872 static const char HTTP_PROTO[] = "HTTP/1.";
1873 static const char HTTP_STATUS_200[] = "200";
1874 int result = 0;
1875 int len = 0;
1876 char *start, *end;
1877 int respBufSz = 0;
1878 int isChunked = 0, chunkSz = 0;
1879 enum phr_state { phr_init, phr_http_start, phr_have_length, phr_have_type,
1880 phr_wait_end, phr_get_chunk_len, phr_get_chunk_data,
1881 phr_http_end
1882 } state = phr_init;
1883
1884 WOLFSSL_ENTER("wolfIO_HttpProcessResponse");
1885
1886 *respBuf = NULL;
1887 start = end = NULL;
1888 do {
1889 if (state == phr_get_chunk_data) {
1890 /* get chunk of data */
1891 result = wolfIO_HttpProcessResponseBuf(ioCb, ioCbCtx, respBuf,
1892 &respBufSz, chunkSz, start, len, dynType, heap);
1893
1894 state = (result != 0) ? phr_http_end : phr_get_chunk_len;
1895 end = NULL;
1896 len = 0;
1897 }
1898
1899 /* read data if no \r\n or first time */
1900 if ((start == NULL) || (end == NULL)) {
1901 if (httpBufSz < len + 1) {
1902 return BUFFER_ERROR; /* can't happen, but Coverity thinks it
1903 * can.
1904 */
1905 }
1906 result = ioCb((char*)httpBuf+len, httpBufSz-len-1, ioCbCtx);
1907 if (result > 0) {
1908 len += result;
1909 start = (char*)httpBuf;
1910 start[len] = 0;
1911 }
1912 else {
1913 if (result == WC_NO_ERR_TRACE(WOLFSSL_CBIO_ERR_WANT_READ)) {
1914 return OCSP_WANT_READ;
1915 }
1916
1917 WOLFSSL_MSG("wolfIO_HttpProcessResponse recv http from peer failed");
1918 return HTTP_RECV_ERR;
1919 }
1920 }
1921 end = XSTRSTR(start, "\r\n"); /* locate end */
1922
1923 /* handle incomplete rx */
1924 if (end == NULL) {
1925 if (len != 0)
1926 XMEMMOVE(httpBuf, start, (size_t)len);
1927 start = end = NULL;
1928 }
1929 /* when start is "\r\n" */
1930 else if (end == start) {
1931 /* if waiting for end or need chunk len */
1932 if (state == phr_wait_end || state == phr_get_chunk_len) {
1933 state = (isChunked) ? phr_get_chunk_len : phr_http_end;
1934 len -= 2; start += 2; /* skip \r\n */
1935 }
1936 else {
1937 WOLFSSL_MSG("wolfIO_HttpProcessResponse header ended early");
1938 return HTTP_HEADER_ERR;
1939 }
1940 }
1941 else {
1942 *end = 0; /* null terminate */
1943 len -= (int)(end - start) + 2;
1944 /* adjust len to remove the first line including the /r/n */
1945
1946 #ifdef WOLFIO_DEBUG
1947 printf("HTTP Resp: %s\n", start);
1948 #endif
1949
1950 switch (state) {
1951 case phr_init:
1952 /* length of "HTTP/1.x 200" == 12*/
1953 if (XSTRLEN(start) < 12) {
1954 WOLFSSL_MSG("wolfIO_HttpProcessResponse HTTP header "
1955 "too short.");
1956 return HTTP_HEADER_ERR;
1957 }
1958 if (XSTRNCASECMP(start, HTTP_PROTO,
1959 sizeof(HTTP_PROTO) - 1) != 0) {
1960 WOLFSSL_MSG("wolfIO_HttpProcessResponse HTTP header "
1961 "doesn't start with HTTP/1.");
1962 return HTTP_PROTO_ERR;
1963 }
1964 /* +2 for HTTP minor version and space between version and
1965 * status code. */
1966 start += sizeof(HTTP_PROTO) - 1 + 2 ;
1967 if (XSTRNCASECMP(start, HTTP_STATUS_200,
1968 sizeof(HTTP_STATUS_200) - 1) != 0) {
1969 WOLFSSL_MSG("wolfIO_HttpProcessResponse HTTP header "
1970 "doesn't have status code 200.");
1971 return HTTP_STATUS_ERR;
1972 }
1973 state = phr_http_start;
1974 break;
1975 case phr_http_start:
1976 case phr_have_length:
1977 case phr_have_type:
1978 if (XSTRNCASECMP(start, "Content-Type:", 13) == 0) {
1979 int i;
1980
1981 start += 13;
1982 while (*start == ' ') start++;
1983
1984 /* try and match against appStrList */
1985 i = 0;
1986 while (appStrList[i] != NULL) {
1987 if (XSTRNCASECMP(start, appStrList[i],
1988 XSTRLEN(appStrList[i])) == 0) {
1989 break;
1990 }
1991 i++;
1992 }
1993 if (appStrList[i] == NULL) {
1994 WOLFSSL_MSG("wolfIO_HttpProcessResponse appstr mismatch");
1995 return HTTP_APPSTR_ERR;
1996 }
1997 state = (state == phr_http_start) ? phr_have_type : phr_wait_end;
1998 }
1999 else if (XSTRNCASECMP(start, "Content-Length:", 15) == 0) {
2000 start += 15;
2001 while (*start == ' ') start++;
2002 chunkSz = XATOI(start);
2003 state = (state == phr_http_start) ? phr_have_length : phr_wait_end;
2004 }
2005 else if (XSTRNCASECMP(start, "Transfer-Encoding:", 18) == 0) {
2006 start += 18;
2007 while (*start == ' ') start++;
2008 if (XSTRNCASECMP(start, "chunked", 7) == 0) {
2009 isChunked = 1;
2010 state = (state == phr_http_start) ? phr_have_length : phr_wait_end;
2011 }
2012 }
2013 break;
2014 case phr_get_chunk_len:
2015 chunkSz = (int)strtol(start, NULL, 16); /* hex format */
2016 state = (chunkSz == 0) ? phr_http_end : phr_get_chunk_data;
2017 break;
2018 case phr_get_chunk_data:
2019 /* processing for chunk data done above, since \r\n isn't required */
2020 case phr_wait_end:
2021 case phr_http_end:
2022 /* do nothing */
2023 break;
2024 } /* switch (state) */
2025
2026 /* skip to end plus \r\n */
2027 start = end + 2;
2028 }
2029 } while (state != phr_http_end);
2030
2031 if (!isChunked) {
2032 result = wolfIO_HttpProcessResponseBuf(ioCb, ioCbCtx, respBuf,
2033 &respBufSz, chunkSz, start, len, dynType, heap);
2034 }
2035
2036 if (result >= 0) {
2037 result = respBufSz;
2038 }
2039 else {
2040 WOLFSSL_ERROR(result);
2041 }
2042
2043 return result;
2044}
2045
2046static int httpResponseIoCb(char* buf, int sz, void* ctx)
2047{
2048 /* Double cast to silence the compiler int/pointer width msg */
2049 return wolfIO_Recv((SOCKET_T)(uintptr_t)ctx, buf, sz, 0);
2050}
2051
2052int wolfIO_HttpProcessResponse(int sfd, const char** appStrList,
2053 byte** respBuf, byte* httpBuf, int httpBufSz, int dynType, void* heap)
2054{
2055 return wolfIO_HttpProcessResponseGenericIO(httpResponseIoCb,
2056 /* Double cast to silence the compiler int/pointer width msg */
2057 (void*)(uintptr_t)sfd, appStrList, respBuf, httpBuf, httpBufSz,
2058 dynType, heap);
2059}
2060
2061int wolfIO_HttpBuildRequest(const char *reqType, const char *domainName,
2062 const char *path, int pathLen, int reqSz, const char *contentType,
2063 byte *buf, int bufSize)
2064{
2065 return wolfIO_HttpBuildRequest_ex(reqType, domainName, path, pathLen, reqSz, contentType, "", buf, bufSize);
2066}
2067
2068int wolfIO_HttpBuildRequest_ex(const char *reqType, const char *domainName,
2069 const char *path, int pathLen, int reqSz, const char *contentType,
2070 const char *exHdrs, byte *buf, int bufSize)
2071 {
2072 word32 reqTypeLen, domainNameLen, reqSzStrLen, contentTypeLen, exHdrsLen, maxLen;
2073 char reqSzStr[6];
2074 char* req = (char*)buf;
2075 const char* blankStr = " ";
2076 const char* http11Str = " HTTP/1.1";
2077 const char* hostStr = "\r\nHost: ";
2078 const char* contentLenStr = "\r\nContent-Length: ";
2079 const char* contentTypeStr = "\r\nContent-Type: ";
2080 const char* singleCrLfStr = "\r\n";
2081 const char* doubleCrLfStr = "\r\n\r\n";
2082 word32 blankStrLen, http11StrLen, hostStrLen, contentLenStrLen,
2083 contentTypeStrLen, singleCrLfStrLen, doubleCrLfStrLen;
2084
2085 reqTypeLen = (word32)XSTRLEN(reqType);
2086 domainNameLen = (word32)XSTRLEN(domainName);
2087 reqSzStrLen = wolfIO_Word16ToString(reqSzStr, (word16)reqSz);
2088 contentTypeLen = (word32)XSTRLEN(contentType);
2089
2090 blankStrLen = (word32)XSTRLEN(blankStr);
2091 http11StrLen = (word32)XSTRLEN(http11Str);
2092 hostStrLen = (word32)XSTRLEN(hostStr);
2093 contentLenStrLen = (word32)XSTRLEN(contentLenStr);
2094 contentTypeStrLen = (word32)XSTRLEN(contentTypeStr);
2095
2096 if(exHdrs){
2097 singleCrLfStrLen = (word32)XSTRLEN(singleCrLfStr);
2098 exHdrsLen = (word32)XSTRLEN(exHdrs);
2099 } else {
2100 singleCrLfStrLen = 0;
2101 exHdrsLen = 0;
2102 }
2103
2104 doubleCrLfStrLen = (word32)XSTRLEN(doubleCrLfStr);
2105
2106 /* determine max length and check it */
2107 maxLen =
2108 reqTypeLen +
2109 blankStrLen +
2110 (word32)pathLen +
2111 http11StrLen +
2112 hostStrLen +
2113 domainNameLen +
2114 contentLenStrLen +
2115 reqSzStrLen +
2116 contentTypeStrLen +
2117 contentTypeLen +
2118 singleCrLfStrLen +
2119 exHdrsLen +
2120 doubleCrLfStrLen +
2121 (word32)1 /* null term */;
2122 if (maxLen > (word32)bufSize)
2123 return 0;
2124
2125 XSTRNCPY((char*)buf, reqType, (size_t)bufSize);
2126 buf += reqTypeLen; bufSize -= (int)reqTypeLen;
2127 XSTRNCPY((char*)buf, blankStr, (size_t)bufSize);
2128 buf += blankStrLen; bufSize -= (int)blankStrLen;
2129 XSTRNCPY((char*)buf, path, (size_t)bufSize);
2130 buf += pathLen; bufSize -= (int)pathLen;
2131 XSTRNCPY((char*)buf, http11Str, (size_t)bufSize);
2132 buf += http11StrLen; bufSize -= (int)http11StrLen;
2133 if (domainNameLen > 0) {
2134 XSTRNCPY((char*)buf, hostStr, (size_t)bufSize);
2135 buf += hostStrLen; bufSize -= (int)hostStrLen;
2136 XSTRNCPY((char*)buf, domainName, (size_t)bufSize);
2137 buf += domainNameLen; bufSize -= (int)domainNameLen;
2138 }
2139 if (reqSz > 0 && reqSzStrLen > 0) {
2140 XSTRNCPY((char*)buf, contentLenStr, (size_t)bufSize);
2141 buf += contentLenStrLen; bufSize -= (int)contentLenStrLen;
2142 XSTRNCPY((char*)buf, reqSzStr, (size_t)bufSize);
2143 buf += reqSzStrLen; bufSize -= (int)reqSzStrLen;
2144 }
2145 if (contentTypeLen > 0) {
2146 XSTRNCPY((char*)buf, contentTypeStr, (size_t)bufSize);
2147 buf += contentTypeStrLen; bufSize -= (int)contentTypeStrLen;
2148 XSTRNCPY((char*)buf, contentType, (size_t)bufSize);
2149 buf += contentTypeLen; bufSize -= (int)contentTypeLen;
2150 }
2151 if (exHdrsLen > 0)
2152 {
2153 XSTRNCPY((char *)buf, singleCrLfStr, (size_t)bufSize);
2154 buf += singleCrLfStrLen;
2155 bufSize -= (int)singleCrLfStrLen;
2156 XSTRNCPY((char *)buf, exHdrs, (size_t)bufSize);
2157 buf += exHdrsLen;
2158 bufSize -= (int)exHdrsLen;
2159 }
2160 XSTRNCPY((char*)buf, doubleCrLfStr, (size_t)bufSize);
2161 buf += doubleCrLfStrLen;
2162
2163#ifdef WOLFIO_DEBUG
2164 printf("HTTP %s: %s", reqType, req);
2165#endif
2166
2167 /* calculate actual length based on original and new pointer */
2168 return (int)((char*)buf - req);
2169}
2170
2171
2172#ifdef HAVE_OCSP
2173
2174int wolfIO_HttpBuildRequestOcsp(const char* domainName, const char* path,
2175 int ocspReqSz, byte* buf, int bufSize)
2176{
2177 const char *cacheCtl = "Cache-Control: no-cache";
2178 return wolfIO_HttpBuildRequest_ex("POST", domainName, path, (int)XSTRLEN(path),
2179 ocspReqSz, "application/ocsp-request", cacheCtl, buf, bufSize);
2180}
2181
2182static const char* ocspAppStrList[] = {
2183 "application/ocsp-response",
2184 NULL
2185};
2186
2187int wolfIO_HttpProcessResponseOcspGenericIO(
2188 WolfSSLGenericIORecvCb ioCb, void* ioCbCtx, unsigned char** respBuf,
2189 unsigned char* httpBuf, int httpBufSz, void* heap)
2190{
2191 return wolfIO_HttpProcessResponseGenericIO(ioCb, ioCbCtx,
2192 ocspAppStrList, respBuf, httpBuf, httpBufSz, DYNAMIC_TYPE_OCSP, heap);
2193}
2194
2195/* return: >0 OCSP Response Size
2196 * -1 error */
2197int wolfIO_HttpProcessResponseOcsp(int sfd, byte** respBuf,
2198 byte* httpBuf, int httpBufSz, void* heap)
2199{
2200 return wolfIO_HttpProcessResponse(sfd, ocspAppStrList,
2201 respBuf, httpBuf, httpBufSz, DYNAMIC_TYPE_OCSP, heap);
2202}
2203
2204/* in default wolfSSL callback ctx is the heap pointer */
2205int EmbedOcspLookup(void* ctx, const char* url, int urlSz,
2206 byte* ocspReqBuf, int ocspReqSz, byte** ocspRespBuf)
2207{
2208 SOCKET_T sfd = SOCKET_INVALID;
2209 word16 port;
2210 int ret = -1;
2211#ifdef WOLFSSL_SMALL_STACK
2212 char* path;
2213 char* domainName;
2214#else
2215 char path[MAX_URL_ITEM_SIZE];
2216 char domainName[MAX_URL_ITEM_SIZE];
2217#endif
2218
2219#ifdef WOLFSSL_SMALL_STACK
2220 path = (char*)XMALLOC(MAX_URL_ITEM_SIZE, NULL, DYNAMIC_TYPE_TMP_BUFFER);
2221 if (path == NULL)
2222 return MEMORY_E;
2223
2224 domainName = (char*)XMALLOC(MAX_URL_ITEM_SIZE, NULL,
2225 DYNAMIC_TYPE_TMP_BUFFER);
2226 if (domainName == NULL) {
2227 XFREE(path, NULL, DYNAMIC_TYPE_TMP_BUFFER);
2228 return MEMORY_E;
2229 }
2230#endif
2231
2232 if (ocspReqBuf == NULL || ocspReqSz == 0) {
2233 WOLFSSL_MSG("OCSP request is required for lookup");
2234 }
2235 else if (ocspRespBuf == NULL) {
2236 WOLFSSL_MSG("Cannot save OCSP response");
2237 }
2238 else if (wolfIO_DecodeUrl(url, urlSz, domainName, path, &port) < 0) {
2239 WOLFSSL_MSG("Unable to decode OCSP URL");
2240 }
2241 else {
2242 /* Note, the library uses the EmbedOcspRespFree() callback to
2243 * free this buffer. */
2244 int httpBufSz = HTTP_SCRATCH_BUFFER_SIZE;
2245 byte* httpBuf = (byte*)XMALLOC((size_t)httpBufSz, ctx, DYNAMIC_TYPE_OCSP);
2246
2247 if (httpBuf == NULL) {
2248 WOLFSSL_MSG("Unable to create OCSP response buffer");
2249 }
2250 else {
2251 httpBufSz = wolfIO_HttpBuildRequestOcsp(domainName, path, ocspReqSz,
2252 httpBuf, httpBufSz);
2253
2254 ret = wolfIO_TcpConnect(&sfd, domainName, port, io_timeout_sec);
2255 if (ret != 0) {
2256 WOLFSSL_MSG("OCSP Responder connection failed");
2257 }
2258 else if (wolfIO_Send(sfd, (char*)httpBuf, httpBufSz, 0) !=
2259 httpBufSz) {
2260 WOLFSSL_MSG("OCSP http request failed");
2261 }
2262 else if (wolfIO_Send(sfd, (char*)ocspReqBuf, ocspReqSz, 0) !=
2263 ocspReqSz) {
2264 WOLFSSL_MSG("OCSP ocsp request failed");
2265 }
2266 else {
2267 ret = wolfIO_HttpProcessResponseOcsp((int)sfd, ocspRespBuf, httpBuf,
2268 HTTP_SCRATCH_BUFFER_SIZE, ctx);
2269 }
2270 if (sfd != SOCKET_INVALID)
2271 CloseSocket(sfd);
2272 XFREE(httpBuf, ctx, DYNAMIC_TYPE_OCSP);
2273 }
2274 }
2275
2276 WC_FREE_VAR_EX(path, NULL, DYNAMIC_TYPE_TMP_BUFFER);
2277 WC_FREE_VAR_EX(domainName, NULL, DYNAMIC_TYPE_TMP_BUFFER);
2278
2279 return ret;
2280}
2281
2282/* in default callback ctx is heap hint */
2283void EmbedOcspRespFree(void* ctx, byte *resp)
2284{
2285 XFREE(resp, ctx, DYNAMIC_TYPE_OCSP);
2286
2287 (void)ctx;
2288}
2289#endif /* HAVE_OCSP */
2290
2291
2292#if defined(HAVE_CRL) && defined(HAVE_CRL_IO)
2293
2294int wolfIO_HttpBuildRequestCrl(const char* url, int urlSz,
2295 const char* domainName, byte* buf, int bufSize)
2296{
2297 const char *cacheCtl = "Cache-Control: no-cache";
2298 return wolfIO_HttpBuildRequest_ex("GET", domainName, url, urlSz, 0, "",
2299 cacheCtl, buf, bufSize);
2300}
2301
2302int wolfIO_HttpProcessResponseCrl(WOLFSSL_CRL* crl, int sfd, byte* httpBuf,
2303 int httpBufSz)
2304{
2305 int ret;
2306 byte *respBuf = NULL;
2307
2308 const char* appStrList[] = {
2309 "application/pkix-crl",
2310 "application/x-pkcs7-crl",
2311 NULL
2312 };
2313
2314
2315 ret = wolfIO_HttpProcessResponse(sfd, appStrList,
2316 &respBuf, httpBuf, httpBufSz, DYNAMIC_TYPE_CRL, crl->heap);
2317 if (ret >= 0) {
2318 ret = BufferLoadCRL(crl, respBuf, ret, WOLFSSL_FILETYPE_ASN1, 0);
2319 }
2320 XFREE(respBuf, crl->heap, DYNAMIC_TYPE_CRL);
2321
2322 return ret;
2323}
2324
2325int EmbedCrlLookup(WOLFSSL_CRL* crl, const char* url, int urlSz)
2326{
2327 SOCKET_T sfd = SOCKET_INVALID;
2328 word16 port;
2329 int ret = -1;
2330 WC_DECLARE_VAR(domainName, char, MAX_URL_ITEM_SIZE, 0);
2331
2332#ifdef WOLFSSL_SMALL_STACK
2333 domainName = (char*)XMALLOC(MAX_URL_ITEM_SIZE, crl->heap,
2334 DYNAMIC_TYPE_TMP_BUFFER);
2335 if (domainName == NULL) {
2336 return MEMORY_E;
2337 }
2338#endif
2339
2340 if (wolfIO_DecodeUrl(url, urlSz, domainName, NULL, &port) < 0) {
2341 WOLFSSL_MSG("Unable to decode CRL URL");
2342 }
2343 else {
2344 int httpBufSz = HTTP_SCRATCH_BUFFER_SIZE;
2345 byte* httpBuf = (byte*)XMALLOC((size_t)httpBufSz, crl->heap,
2346 DYNAMIC_TYPE_CRL);
2347 if (httpBuf == NULL) {
2348 WOLFSSL_MSG("Unable to create CRL response buffer");
2349 }
2350 else {
2351 httpBufSz = wolfIO_HttpBuildRequestCrl(url, urlSz, domainName,
2352 httpBuf, httpBufSz);
2353
2354 ret = wolfIO_TcpConnect(&sfd, domainName, port, io_timeout_sec);
2355 if (ret != 0) {
2356 WOLFSSL_MSG("CRL connection failed");
2357 }
2358 else if (wolfIO_Send(sfd, (char*)httpBuf, httpBufSz, 0)
2359 != httpBufSz) {
2360 WOLFSSL_MSG("CRL http get failed");
2361 }
2362 else {
2363 ret = wolfIO_HttpProcessResponseCrl(crl, sfd, httpBuf,
2364 HTTP_SCRATCH_BUFFER_SIZE);
2365 }
2366 if (sfd != SOCKET_INVALID)
2367 CloseSocket(sfd);
2368 XFREE(httpBuf, crl->heap, DYNAMIC_TYPE_CRL);
2369 }
2370 }
2371
2372 WC_FREE_VAR_EX(domainName, crl->heap, DYNAMIC_TYPE_TMP_BUFFER);
2373
2374 return ret;
2375}
2376#endif /* HAVE_CRL && HAVE_CRL_IO */
2377
2378#endif /* HAVE_HTTP_CLIENT */
2379
2380
2381
2382void wolfSSL_CTX_SetIORecv(WOLFSSL_CTX *ctx, CallbackIORecv CBIORecv)
2383{
2384 if (ctx) {
2385 ctx->CBIORecv = CBIORecv;
2386 #ifdef OPENSSL_EXTRA
2387 ctx->cbioFlag |= WOLFSSL_CBIO_RECV;
2388 #endif
2389 }
2390}
2391
2392
2393void wolfSSL_CTX_SetIOSend(WOLFSSL_CTX *ctx, CallbackIOSend CBIOSend)
2394{
2395 if (ctx) {
2396 ctx->CBIOSend = CBIOSend;
2397 #ifdef OPENSSL_EXTRA
2398 ctx->cbioFlag |= WOLFSSL_CBIO_SEND;
2399 #endif
2400 }
2401}
2402
2403
2404/* sets the IO callback to use for receives at WOLFSSL level */
2405void wolfSSL_SSLSetIORecv(WOLFSSL *ssl, CallbackIORecv CBIORecv)
2406{
2407 if (ssl) {
2408 ssl->CBIORecv = CBIORecv;
2409 #ifdef OPENSSL_EXTRA
2410 ssl->cbioFlag |= WOLFSSL_CBIO_RECV;
2411 #endif
2412 }
2413}
2414
2415
2416/* sets the IO callback to use for sends at WOLFSSL level */
2417void wolfSSL_SSLSetIOSend(WOLFSSL *ssl, CallbackIOSend CBIOSend)
2418{
2419 if (ssl) {
2420 ssl->CBIOSend = CBIOSend;
2421 #ifdef OPENSSL_EXTRA
2422 ssl->cbioFlag |= WOLFSSL_CBIO_SEND;
2423 #endif
2424 }
2425}
2426
2427void wolfSSL_SSLDisableRead(WOLFSSL *ssl)
2428{
2429 if (ssl) {
2430 ssl->options.disableRead = 1;
2431 }
2432}
2433
2434void wolfSSL_SSLEnableRead(WOLFSSL *ssl)
2435{
2436 if (ssl) {
2437 ssl->options.disableRead = 0;
2438 }
2439}
2440
2441
2442void wolfSSL_SetIOReadCtx(WOLFSSL* ssl, void *rctx)
2443{
2444 if (ssl)
2445 ssl->IOCB_ReadCtx = rctx;
2446}
2447
2448
2449void wolfSSL_SetIOWriteCtx(WOLFSSL* ssl, void *wctx)
2450{
2451 if (ssl)
2452 ssl->IOCB_WriteCtx = wctx;
2453}
2454
2455
2456void* wolfSSL_GetIOReadCtx(WOLFSSL* ssl)
2457{
2458 if (ssl)
2459 return ssl->IOCB_ReadCtx;
2460
2461 return NULL;
2462}
2463
2464
2465void* wolfSSL_GetIOWriteCtx(WOLFSSL* ssl)
2466{
2467 if (ssl)
2468 return ssl->IOCB_WriteCtx;
2469
2470 return NULL;
2471}
2472
2473
2474void wolfSSL_SetIOReadFlags(WOLFSSL* ssl, int flags)
2475{
2476 if (ssl)
2477 ssl->rflags = flags;
2478}
2479
2480
2481void wolfSSL_SetIOWriteFlags(WOLFSSL* ssl, int flags)
2482{
2483 if (ssl)
2484 ssl->wflags = flags;
2485}
2486
2487
2488#ifdef WOLFSSL_DTLS
2489
2490void wolfSSL_CTX_SetGenCookie(WOLFSSL_CTX* ctx, CallbackGenCookie cb)
2491{
2492 if (ctx)
2493 ctx->CBIOCookie = cb;
2494}
2495
2496
2497void wolfSSL_SetCookieCtx(WOLFSSL* ssl, void *ctx)
2498{
2499 if (ssl)
2500 ssl->IOCB_CookieCtx = ctx;
2501}
2502
2503
2504void* wolfSSL_GetCookieCtx(WOLFSSL* ssl)
2505{
2506 if (ssl)
2507 return ssl->IOCB_CookieCtx;
2508
2509 return NULL;
2510}
2511#endif /* WOLFSSL_DTLS */
2512
2513#ifdef WOLFSSL_SESSION_EXPORT
2514
2515void wolfSSL_CTX_SetIOGetPeer(WOLFSSL_CTX* ctx, CallbackGetPeer cb)
2516{
2517 if (ctx)
2518 ctx->CBGetPeer = cb;
2519}
2520
2521
2522void wolfSSL_CTX_SetIOSetPeer(WOLFSSL_CTX* ctx, CallbackSetPeer cb)
2523{
2524 if (ctx)
2525 ctx->CBSetPeer = cb;
2526}
2527
2528#endif /* WOLFSSL_SESSION_EXPORT */
2529
2530
2531#ifdef HAVE_NETX
2532
2533/* The NetX receive callback
2534 * return : bytes read, or error
2535 */
2536int NetX_Receive(WOLFSSL *ssl, char *buf, int sz, void *ctx)
2537{
2538 NetX_Ctx* nxCtx = (NetX_Ctx*)ctx;
2539 ULONG left;
2540 ULONG total;
2541 ULONG copied = 0;
2542 UINT status;
2543
2544 (void)ssl;
2545
2546 if (nxCtx == NULL || nxCtx->nxSocket == NULL) {
2547 WOLFSSL_MSG("NetX Recv NULL parameters");
2548 return WOLFSSL_CBIO_ERR_GENERAL;
2549 }
2550
2551 if (nxCtx->nxPacket == NULL) {
2552 status = nx_tcp_socket_receive(nxCtx->nxSocket, &nxCtx->nxPacket,
2553 nxCtx->nxWait);
2554 if (status != NX_SUCCESS) {
2555 WOLFSSL_MSG("NetX Recv receive error");
2556 return WOLFSSL_CBIO_ERR_GENERAL;
2557 }
2558 }
2559
2560 if (nxCtx->nxPacket) {
2561 status = nx_packet_length_get(nxCtx->nxPacket, &total);
2562 if (status != NX_SUCCESS) {
2563 WOLFSSL_MSG("NetX Recv length get error");
2564 return WOLFSSL_CBIO_ERR_GENERAL;
2565 }
2566
2567 left = total - nxCtx->nxOffset;
2568 status = nx_packet_data_extract_offset(nxCtx->nxPacket, nxCtx->nxOffset,
2569 buf, sz, &copied);
2570 if (status != NX_SUCCESS) {
2571 WOLFSSL_MSG("NetX Recv data extract offset error");
2572 return WOLFSSL_CBIO_ERR_GENERAL;
2573 }
2574
2575 nxCtx->nxOffset += copied;
2576
2577 if (copied == left) {
2578 WOLFSSL_MSG("NetX Recv Drained packet");
2579 nx_packet_release(nxCtx->nxPacket);
2580 nxCtx->nxPacket = NULL;
2581 nxCtx->nxOffset = 0;
2582 }
2583 }
2584
2585 return copied;
2586}
2587
2588
2589/* The NetX send callback
2590 * return : bytes sent, or error
2591 */
2592int NetX_Send(WOLFSSL* ssl, char *buf, int sz, void *ctx)
2593{
2594 NetX_Ctx* nxCtx = (NetX_Ctx*)ctx;
2595 NX_PACKET* packet;
2596 NX_PACKET_POOL* pool; /* shorthand */
2597 UINT status;
2598
2599 (void)ssl;
2600
2601 if (nxCtx == NULL || nxCtx->nxSocket == NULL) {
2602 WOLFSSL_MSG("NetX Send NULL parameters");
2603 return WOLFSSL_CBIO_ERR_GENERAL;
2604 }
2605
2606 pool = nxCtx->nxSocket->nx_tcp_socket_ip_ptr->nx_ip_default_packet_pool;
2607 status = nx_packet_allocate(pool, &packet, NX_TCP_PACKET,
2608 nxCtx->nxWait);
2609 if (status != NX_SUCCESS) {
2610 WOLFSSL_MSG("NetX Send packet alloc error");
2611 return WOLFSSL_CBIO_ERR_GENERAL;
2612 }
2613
2614 status = nx_packet_data_append(packet, buf, sz, pool, nxCtx->nxWait);
2615 if (status != NX_SUCCESS) {
2616 nx_packet_release(packet);
2617 WOLFSSL_MSG("NetX Send data append error");
2618 return WOLFSSL_CBIO_ERR_GENERAL;
2619 }
2620
2621 status = nx_tcp_socket_send(nxCtx->nxSocket, packet, nxCtx->nxWait);
2622 if (status != NX_SUCCESS) {
2623 nx_packet_release(packet);
2624 WOLFSSL_MSG("NetX Send socket send error");
2625 return WOLFSSL_CBIO_ERR_GENERAL;
2626 }
2627
2628 return sz;
2629}
2630
2631
2632/* like set_fd, but for default NetX context */
2633void wolfSSL_SetIO_NetX(WOLFSSL* ssl, NX_TCP_SOCKET* nxSocket, ULONG waitOption)
2634{
2635 if (ssl) {
2636 ssl->nxCtx.nxSocket = nxSocket;
2637 ssl->nxCtx.nxWait = waitOption;
2638 }
2639}
2640
2641#endif /* HAVE_NETX */
2642
2643
2644#ifdef MICRIUM
2645
2646/* Micrium uTCP/IP port, using the NetSock API
2647 * TCP and UDP are currently supported with the callbacks below.
2648 *
2649 * WOLFSSL_SESSION_EXPORT is not yet supported, would need EmbedGetPeer()
2650 * and EmbedSetPeer() callbacks implemented.
2651 *
2652 * HAVE_CRL is not yet supported, would need an EmbedCrlLookup()
2653 * callback implemented.
2654 *
2655 * HAVE_OCSP is not yet supported, would need an EmbedOCSPLookup()
2656 * callback implemented.
2657 */
2658
2659/* The Micrium uTCP/IP send callback
2660 * return : bytes sent, or error
2661 */
2662int MicriumSend(WOLFSSL* ssl, char* buf, int sz, void* ctx)
2663{
2664 NET_SOCK_ID sd = *(int*)ctx;
2665 NET_SOCK_RTN_CODE ret;
2666 NET_ERR err;
2667
2668 ret = NetSock_TxData(sd, buf, sz, ssl->wflags, &err);
2669 if (ret < 0) {
2670 WOLFSSL_MSG("Embed Send error");
2671
2672 if (err == NET_ERR_TX) {
2673 WOLFSSL_MSG("\tWould block");
2674 return WOLFSSL_CBIO_ERR_WANT_WRITE;
2675
2676 } else {
2677 WOLFSSL_MSG("\tGeneral error");
2678 return WOLFSSL_CBIO_ERR_GENERAL;
2679 }
2680 }
2681
2682 return ret;
2683}
2684
2685/* The Micrium uTCP/IP receive callback
2686 * return : nb bytes read, or error
2687 */
2688int MicriumReceive(WOLFSSL *ssl, char *buf, int sz, void *ctx)
2689{
2690 NET_SOCK_ID sd = *(int*)ctx;
2691 NET_SOCK_RTN_CODE ret;
2692 NET_ERR err;
2693
2694 #ifdef WOLFSSL_DTLS
2695 {
2696 int dtls_timeout = wolfSSL_dtls_get_current_timeout(ssl);
2697 /* Don't use ssl->options.handShakeDone since it is true even if
2698 * we are in the process of renegotiation */
2699 byte doDtlsTimeout = ssl->options.handShakeState != HANDSHAKE_DONE;
2700 #ifdef WOLFSSL_DTLS13
2701 if (ssl->options.dtls && IsAtLeastTLSv1_3(ssl->version)) {
2702 doDtlsTimeout =
2703 doDtlsTimeout || ssl->dtls13Rtx.rtxRecords != NULL ||
2704 (ssl->dtls13FastTimeout && ssl->dtls13Rtx.seenRecords != NULL);
2705 }
2706 #endif /* WOLFSSL_DTLS13 */
2707
2708 if (!doDtlsTimeout)
2709 dtls_timeout = 0;
2710
2711 if (!wolfSSL_dtls_get_using_nonblock(ssl)) {
2712 /* needs timeout in milliseconds */
2713 #ifdef WOLFSSL_DTLS13
2714 if (wolfSSL_dtls13_use_quick_timeout(ssl) &&
2715 IsAtLeastTLSv1_3(ssl->version)) {
2716 dtls_timeout = (1000 * dtls_timeout) / 4;
2717 } else
2718 #endif /* WOLFSSL_DTLS13 */
2719 dtls_timeout = 1000 * dtls_timeout;
2720 NetSock_CfgTimeoutRxQ_Set(sd, dtls_timeout, &err);
2721 if (err != NET_SOCK_ERR_NONE) {
2722 WOLFSSL_MSG("NetSock_CfgTimeoutRxQ_Set failed");
2723 }
2724 }
2725 }
2726 #endif /* WOLFSSL_DTLS */
2727
2728 ret = NetSock_RxData(sd, buf, sz, ssl->rflags, &err);
2729 if (ret < 0) {
2730 WOLFSSL_MSG("Embed Receive error");
2731
2732 if (err == NET_ERR_RX || err == NET_SOCK_ERR_RX_Q_EMPTY ||
2733 err == NET_ERR_FAULT_LOCK_ACQUIRE) {
2734 if (!wolfSSL_dtls(ssl) || wolfSSL_dtls_get_using_nonblock(ssl)) {
2735 WOLFSSL_MSG("\tWould block");
2736 return WOLFSSL_CBIO_ERR_WANT_READ;
2737 }
2738 else {
2739 WOLFSSL_MSG("\tSocket timeout");
2740 return WOLFSSL_CBIO_ERR_TIMEOUT;
2741 }
2742
2743 } else if (err == NET_SOCK_ERR_CLOSED) {
2744 WOLFSSL_MSG("Embed receive connection closed");
2745 return WOLFSSL_CBIO_ERR_CONN_CLOSE;
2746
2747 } else {
2748 WOLFSSL_MSG("\tGeneral error");
2749 return WOLFSSL_CBIO_ERR_GENERAL;
2750 }
2751 }
2752
2753 return ret;
2754}
2755
2756/* The Micrium uTCP/IP receivefrom callback
2757 * return : nb bytes read, or error
2758 */
2759int MicriumReceiveFrom(WOLFSSL *ssl, char *buf, int sz, void *ctx)
2760{
2761 WOLFSSL_DTLS_CTX* dtlsCtx = (WOLFSSL_DTLS_CTX*)ctx;
2762 NET_SOCK_ID sd = dtlsCtx->rfd;
2763 NET_SOCK_ADDR peer;
2764 NET_SOCK_ADDR_LEN peerSz = sizeof(peer);
2765 NET_SOCK_RTN_CODE ret;
2766 NET_ERR err;
2767
2768 WOLFSSL_ENTER("MicriumReceiveFrom");
2769
2770#ifdef WOLFSSL_DTLS
2771 {
2772 int dtls_timeout = wolfSSL_dtls_get_current_timeout(ssl);
2773 /* Don't use ssl->options.handShakeDone since it is true even if
2774 * we are in the process of renegotiation */
2775 byte doDtlsTimeout = ssl->options.handShakeState != HANDSHAKE_DONE;
2776
2777 #ifdef WOLFSSL_DTLS13
2778 if (ssl->options.dtls && IsAtLeastTLSv1_3(ssl->version)) {
2779 doDtlsTimeout =
2780 doDtlsTimeout || ssl->dtls13Rtx.rtxRecords != NULL ||
2781 (ssl->dtls13FastTimeout && ssl->dtls13Rtx.seenRecords != NULL);
2782 }
2783 #endif /* WOLFSSL_DTLS13 */
2784
2785 if (!doDtlsTimeout)
2786 dtls_timeout = 0;
2787
2788 if (!wolfSSL_dtls_get_using_nonblock(ssl)) {
2789 /* needs timeout in milliseconds */
2790 #ifdef WOLFSSL_DTLS13
2791 if (wolfSSL_dtls13_use_quick_timeout(ssl) &&
2792 IsAtLeastTLSv1_3(ssl->version)) {
2793 dtls_timeout = (1000 * dtls_timeout) / 4;
2794 } else
2795 #endif /* WOLFSSL_DTLS13 */
2796 dtls_timeout = 1000 * dtls_timeout;
2797 NetSock_CfgTimeoutRxQ_Set(sd, dtls_timeout, &err);
2798 if (err != NET_SOCK_ERR_NONE) {
2799 WOLFSSL_MSG("NetSock_CfgTimeoutRxQ_Set failed");
2800 }
2801 }
2802 }
2803#endif /* WOLFSSL_DTLS */
2804
2805 ret = NetSock_RxDataFrom(sd, buf, sz, ssl->rflags, &peer, &peerSz,
2806 0, 0, 0, &err);
2807 if (ret < 0) {
2808 WOLFSSL_MSG("Embed Receive From error");
2809
2810 if (err == NET_ERR_RX || err == NET_SOCK_ERR_RX_Q_EMPTY ||
2811 err == NET_ERR_FAULT_LOCK_ACQUIRE) {
2812 if (wolfSSL_dtls_get_using_nonblock(ssl)) {
2813 WOLFSSL_MSG("\tWould block");
2814 return WOLFSSL_CBIO_ERR_WANT_READ;
2815 }
2816 else {
2817 WOLFSSL_MSG("\tSocket timeout");
2818 return WOLFSSL_CBIO_ERR_TIMEOUT;
2819 }
2820 } else {
2821 WOLFSSL_MSG("\tGeneral error");
2822 return WOLFSSL_CBIO_ERR_GENERAL;
2823 }
2824 }
2825 else {
2826 if (dtlsCtx->peer.sz > 0) {
2827 NET_SOCK_ADDR_LEN expectedPeerSz =
2828 (NET_SOCK_ADDR_LEN)dtlsCtx->peer.sz;
2829 if (dtlsCtx->peer.sa == NULL ||
2830 peerSz != expectedPeerSz ||
2831 XMEMCMP(&peer, dtlsCtx->peer.sa, expectedPeerSz) != 0) {
2832 WOLFSSL_MSG("\tIgnored packet from invalid peer");
2833 return WOLFSSL_CBIO_ERR_WANT_READ;
2834 }
2835 }
2836 }
2837
2838 return ret;
2839}
2840
2841/* The Micrium uTCP/IP sendto callback
2842 * return : nb bytes sent, or error
2843 */
2844int MicriumSendTo(WOLFSSL* ssl, char *buf, int sz, void *ctx)
2845{
2846 WOLFSSL_DTLS_CTX* dtlsCtx = (WOLFSSL_DTLS_CTX*)ctx;
2847 NET_SOCK_ID sd = dtlsCtx->wfd;
2848 NET_SOCK_RTN_CODE ret;
2849 NET_ERR err;
2850
2851 WOLFSSL_ENTER("MicriumSendTo");
2852
2853 ret = NetSock_TxDataTo(sd, buf, sz, ssl->wflags,
2854 (NET_SOCK_ADDR*)dtlsCtx->peer.sa,
2855 (NET_SOCK_ADDR_LEN)dtlsCtx->peer.sz,
2856 &err);
2857 if (err < 0) {
2858 WOLFSSL_MSG("Embed Send To error");
2859
2860 if (err == NET_ERR_TX) {
2861 WOLFSSL_MSG("\tWould block");
2862 return WOLFSSL_CBIO_ERR_WANT_WRITE;
2863
2864 } else {
2865 WOLFSSL_MSG("\tGeneral error");
2866 return WOLFSSL_CBIO_ERR_GENERAL;
2867 }
2868 }
2869
2870 return ret;
2871}
2872
2873/* Micrium DTLS Generate Cookie callback
2874 * return : number of bytes copied into buf, or error
2875 */
2876#if defined(NO_SHA) && !defined(NO_SHA256)
2877 #define MICRIUM_COOKIE_DIGEST_SIZE WC_SHA256_DIGEST_SIZE
2878#elif !defined(NO_SHA)
2879 #define MICRIUM_COOKIE_DIGEST_SIZE WC_SHA_DIGEST_SIZE
2880#else
2881 #error Must enable either SHA-1 or SHA256 (or both) for Micrium.
2882#endif
2883int MicriumGenerateCookie(WOLFSSL* ssl, byte *buf, int sz, void *ctx)
2884{
2885 NET_SOCK_ADDR peer;
2886 NET_SOCK_ADDR_LEN peerSz = sizeof(peer);
2887 byte digest[MICRIUM_COOKIE_DIGEST_SIZE];
2888 int ret = 0;
2889
2890 (void)ctx;
2891
2892 XMEMSET(&peer, 0, sizeof(peer));
2893 if (wolfSSL_dtls_get_peer(ssl, (void*)&peer,
2894 (unsigned int*)&peerSz) != WOLFSSL_SUCCESS) {
2895 WOLFSSL_MSG("getpeername failed in MicriumGenerateCookie");
2896 return GEN_COOKIE_E;
2897 }
2898
2899#if defined(NO_SHA) && !defined(NO_SHA256)
2900 ret = wc_Sha256Hash((byte*)&peer, peerSz, digest);
2901#else
2902 ret = wc_ShaHash((byte*)&peer, peerSz, digest);
2903#endif
2904 if (ret != 0)
2905 return ret;
2906
2907 if (sz > MICRIUM_COOKIE_DIGEST_SIZE)
2908 sz = MICRIUM_COOKIE_DIGEST_SIZE;
2909 XMEMCPY(buf, digest, sz);
2910
2911 return sz;
2912}
2913
2914#endif /* MICRIUM */
2915
2916#if defined(WOLFSSL_APACHE_MYNEWT) && !defined(WOLFSSL_LWIP)
2917
2918#include <os/os_error.h>
2919#include <os/os_mbuf.h>
2920#include <os/os_mempool.h>
2921
2922#define MB_NAME "wolfssl_mb"
2923
2924typedef struct Mynewt_Ctx {
2925 struct mn_socket *mnSocket; /* send/recv socket handler */
2926 struct mn_sockaddr_in mnSockAddrIn; /* socket address */
2927 struct os_mbuf *mnPacket; /* incoming packet handle
2928 for short reads */
2929 int reading; /* reading flag */
2930
2931 /* private */
2932 void *mnMemBuffer; /* memory buffer for mempool */
2933 struct os_mempool mnMempool; /* mempool */
2934 struct os_mbuf_pool mnMbufpool; /* mbuf pool */
2935} Mynewt_Ctx;
2936
2937void mynewt_ctx_clear(void *ctx) {
2938 Mynewt_Ctx *mynewt_ctx = (Mynewt_Ctx*)ctx;
2939 if(!mynewt_ctx) return;
2940
2941 if(mynewt_ctx->mnPacket) {
2942 os_mbuf_free_chain(mynewt_ctx->mnPacket);
2943 mynewt_ctx->mnPacket = NULL;
2944 }
2945 os_mempool_clear(&mynewt_ctx->mnMempool);
2946 XFREE(mynewt_ctx->mnMemBuffer, 0, 0);
2947 XFREE(mynewt_ctx, 0, 0);
2948}
2949
2950/* return Mynewt_Ctx instance */
2951void* mynewt_ctx_new() {
2952 int rc = 0;
2953 Mynewt_Ctx *mynewt_ctx;
2954 int mem_buf_count = MYNEWT_VAL(WOLFSSL_MNSOCK_MEM_BUF_COUNT);
2955 int mem_buf_size = MYNEWT_VAL(WOLFSSL_MNSOCK_MEM_BUF_SIZE);
2956 int mempool_bytes = OS_MEMPOOL_BYTES(mem_buf_count, mem_buf_size);
2957
2958 mynewt_ctx = (Mynewt_Ctx *)XMALLOC(sizeof(struct Mynewt_Ctx),
2959 NULL, DYNAMIC_TYPE_TMP_BUFFER);
2960 if(!mynewt_ctx) return NULL;
2961
2962 XMEMSET(mynewt_ctx, 0, sizeof(Mynewt_Ctx));
2963 mynewt_ctx->mnMemBuffer = (void *)XMALLOC(mempool_bytes, 0, 0);
2964 if(!mynewt_ctx->mnMemBuffer) {
2965 mynewt_ctx_clear((void*)mynewt_ctx);
2966 return NULL;
2967 }
2968
2969 rc = os_mempool_init(&mynewt_ctx->mnMempool,
2970 mem_buf_count, mem_buf_size,
2971 mynewt_ctx->mnMemBuffer, MB_NAME);
2972 if(rc != 0) {
2973 mynewt_ctx_clear((void*)mynewt_ctx);
2974 return NULL;
2975 }
2976 rc = os_mbuf_pool_init(&mynewt_ctx->mnMbufpool, &mynewt_ctx->mnMempool,
2977 mem_buf_count, mem_buf_size);
2978 if(rc != 0) {
2979 mynewt_ctx_clear((void*)mynewt_ctx);
2980 return NULL;
2981 }
2982
2983 return mynewt_ctx;
2984}
2985
2986static void mynewt_sock_writable(void *arg, int err);
2987static void mynewt_sock_readable(void *arg, int err);
2988static const union mn_socket_cb mynewt_sock_cbs = {
2989 .socket.writable = mynewt_sock_writable,
2990 .socket.readable = mynewt_sock_readable,
2991};
2992static void mynewt_sock_writable(void *arg, int err)
2993{
2994 /* do nothing */
2995}
2996static void mynewt_sock_readable(void *arg, int err)
2997{
2998 Mynewt_Ctx *mynewt_ctx = (Mynewt_Ctx *)arg;
2999 if (err && mynewt_ctx->reading) {
3000 mynewt_ctx->reading = 0;
3001 }
3002}
3003
3004/* The Mynewt receive callback
3005 * return : bytes read, or error
3006 */
3007int Mynewt_Receive(WOLFSSL *ssl, char *buf, int sz, void *ctx)
3008{
3009 Mynewt_Ctx *mynewt_ctx = (Mynewt_Ctx*)ctx;
3010 int rc = 0;
3011 struct mn_sockaddr_in from;
3012 struct os_mbuf *m;
3013 int read_sz = 0;
3014 word16 total;
3015
3016 if (mynewt_ctx == NULL || mynewt_ctx->mnSocket == NULL) {
3017 WOLFSSL_MSG("Mynewt Recv NULL parameters");
3018 return WOLFSSL_CBIO_ERR_GENERAL;
3019 }
3020
3021 if(mynewt_ctx->mnPacket == NULL) {
3022 mynewt_ctx->mnPacket = os_mbuf_get_pkthdr(&mynewt_ctx->mnMbufpool, 0);
3023 if(mynewt_ctx->mnPacket == NULL) {
3024 return MEMORY_E;
3025 }
3026
3027 mynewt_ctx->reading = 1;
3028 while(mynewt_ctx->reading && rc == 0) {
3029 rc = mn_recvfrom(mynewt_ctx->mnSocket, &m, (struct mn_sockaddr *) &from);
3030 if(rc == MN_ECONNABORTED) {
3031 rc = 0;
3032 mynewt_ctx->reading = 0;
3033 break;
3034 }
3035 if (!(rc == 0 || rc == MN_EAGAIN)) {
3036 WOLFSSL_MSG("Mynewt Recv receive error");
3037 mynewt_ctx->reading = 0;
3038 break;
3039 }
3040 if(rc == 0) {
3041 int len = OS_MBUF_PKTLEN(m);
3042 if(len == 0) {
3043 break;
3044 }
3045 rc = os_mbuf_appendfrom(mynewt_ctx->mnPacket, m, 0, len);
3046 if(rc != 0) {
3047 WOLFSSL_MSG("Mynewt Recv os_mbuf_appendfrom error");
3048 break;
3049 }
3050 os_mbuf_free_chain(m);
3051 m = NULL;
3052 } else if(rc == MN_EAGAIN) {
3053 /* continue to until reading all of packet data. */
3054 rc = 0;
3055 break;
3056 }
3057 }
3058 if(rc != 0) {
3059 mynewt_ctx->reading = 0;
3060 os_mbuf_free_chain(mynewt_ctx->mnPacket);
3061 mynewt_ctx->mnPacket = NULL;
3062 return rc;
3063 }
3064 }
3065
3066 if(mynewt_ctx->mnPacket) {
3067 total = OS_MBUF_PKTLEN(mynewt_ctx->mnPacket);
3068 read_sz = (total >= sz)? sz : total;
3069
3070 os_mbuf_copydata(mynewt_ctx->mnPacket, 0, read_sz, (void*)buf);
3071 os_mbuf_adj(mynewt_ctx->mnPacket, read_sz);
3072
3073 if (read_sz == total) {
3074 WOLFSSL_MSG("Mynewt Recv Drained packet");
3075 os_mbuf_free_chain(mynewt_ctx->mnPacket);
3076 mynewt_ctx->mnPacket = NULL;
3077 }
3078 }
3079
3080 return read_sz;
3081}
3082
3083/* The Mynewt send callback
3084 * return : bytes sent, or error
3085 */
3086int Mynewt_Send(WOLFSSL* ssl, char *buf, int sz, void *ctx)
3087{
3088 Mynewt_Ctx *mynewt_ctx = (Mynewt_Ctx*)ctx;
3089 int rc = 0;
3090 struct os_mbuf *m;
3091 int write_sz = 0;
3092 m = os_msys_get_pkthdr(sz, 0);
3093 if (!m) {
3094 WOLFSSL_MSG("Mynewt Send os_msys_get_pkthdr error");
3095 return WOLFSSL_CBIO_ERR_GENERAL;
3096 }
3097 rc = os_mbuf_copyinto(m, 0, buf, sz);
3098 if (rc != 0) {
3099 WOLFSSL_MSG("Mynewt Send os_mbuf_copyinto error");
3100 os_mbuf_free_chain(m);
3101 return rc;
3102 }
3103 rc = mn_sendto(mynewt_ctx->mnSocket, m, (struct mn_sockaddr *)&mynewt_ctx->mnSockAddrIn);
3104 if(rc != 0) {
3105 WOLFSSL_MSG("Mynewt Send mn_sendto error");
3106 os_mbuf_free_chain(m);
3107 return rc;
3108 }
3109 write_sz = sz;
3110 return write_sz;
3111}
3112
3113/* like set_fd, but for default NetX context */
3114void wolfSSL_SetIO_Mynewt(WOLFSSL* ssl, struct mn_socket* mnSocket, struct mn_sockaddr_in* mnSockAddrIn)
3115{
3116 if (ssl && ssl->mnCtx) {
3117 Mynewt_Ctx *mynewt_ctx = (Mynewt_Ctx *)ssl->mnCtx;
3118 mynewt_ctx->mnSocket = mnSocket;
3119 XMEMCPY(&mynewt_ctx->mnSockAddrIn, mnSockAddrIn, sizeof(struct mn_sockaddr_in));
3120 mn_socket_set_cbs(mynewt_ctx->mnSocket, mnSocket, &mynewt_sock_cbs);
3121 }
3122}
3123
3124#endif /* defined(WOLFSSL_APACHE_MYNEWT) && !defined(WOLFSSL_LWIP) */
3125
3126#ifdef WOLFSSL_UIP
3127#include <uip.h>
3128#include <stdio.h>
3129
3130/* uIP TCP/IP port, using the native tcp/udp socket api.
3131 * TCP and UDP are currently supported with the callbacks below.
3132 *
3133 */
3134/* The uIP tcp send callback
3135 * return : bytes sent, or error
3136 */
3137int uIPSend(WOLFSSL* ssl, char* buf, int sz, void* _ctx)
3138{
3139 uip_wolfssl_ctx *ctx = (struct uip_wolfssl_ctx *)_ctx;
3140 int total_written = 0;
3141 (void)ssl;
3142 do {
3143 int ret;
3144 unsigned int bytes_left = sz - total_written;
3145 unsigned int max_sendlen = tcp_socket_max_sendlen(&ctx->conn.tcp);
3146 if (bytes_left > max_sendlen) {
3147 fprintf(stderr, "uIPSend: Send limited by buffer\r\n");
3148 bytes_left = max_sendlen;
3149 }
3150 if (bytes_left == 0) {
3151 fprintf(stderr, "uIPSend: Buffer full!\r\n");
3152 break;
3153 }
3154 ret = tcp_socket_send(&ctx->conn.tcp, (unsigned char *)buf + total_written, bytes_left);
3155 if (ret <= 0)
3156 break;
3157 total_written += ret;
3158 } while(total_written < sz);
3159 if (total_written == 0)
3160 return WOLFSSL_CBIO_ERR_WANT_WRITE;
3161 return total_written;
3162}
3163
3164int uIPSendTo(WOLFSSL* ssl, char* buf, int sz, void* _ctx)
3165{
3166 uip_wolfssl_ctx *ctx = (struct uip_wolfssl_ctx *)_ctx;
3167 int ret = 0;
3168 (void)ssl;
3169 ret = udp_socket_sendto(&ctx->conn.udp, (unsigned char *)buf, sz, &ctx->peer_addr, ctx->peer_port );
3170 if (ret == 0)
3171 return WOLFSSL_CBIO_ERR_WANT_WRITE;
3172 return ret;
3173}
3174
3175/* The uIP uTCP/IP receive callback
3176 * return : nb bytes read, or error
3177 */
3178int uIPReceive(WOLFSSL *ssl, char *buf, int sz, void *_ctx)
3179{
3180 uip_wolfssl_ctx *ctx = (uip_wolfssl_ctx *)_ctx;
3181 if (!ctx || !ctx->ssl_rx_databuf)
3182 return WOLFSSL_FATAL_ERROR;
3183 (void)ssl;
3184 if (ctx->ssl_rb_len > 0) {
3185 if (sz > ctx->ssl_rb_len - ctx->ssl_rb_off)
3186 sz = ctx->ssl_rb_len - ctx->ssl_rb_off;
3187 XMEMCPY(buf, ctx->ssl_rx_databuf + ctx->ssl_rb_off, sz);
3188 ctx->ssl_rb_off += sz;
3189 if (ctx->ssl_rb_off >= ctx->ssl_rb_len) {
3190 ctx->ssl_rb_len = 0;
3191 ctx->ssl_rb_off = 0;
3192 }
3193 return sz;
3194 } else {
3195 return WOLFSSL_CBIO_ERR_WANT_READ;
3196 }
3197}
3198
3199/* uIP DTLS Generate Cookie callback
3200 * return : number of bytes copied into buf, or error
3201 */
3202#if defined(NO_SHA) && !defined(NO_SHA256)
3203 #define UIP_COOKIE_DIGEST_SIZE WC_SHA256_DIGEST_SIZE
3204#elif !defined(NO_SHA)
3205 #define UIP_COOKIE_DIGEST_SIZE WC_SHA_DIGEST_SIZE
3206#else
3207 #error Must enable either SHA-1 or SHA256 (or both) for uIP.
3208#endif
3209int uIPGenerateCookie(WOLFSSL* ssl, byte *buf, int sz, void *_ctx)
3210{
3211 uip_wolfssl_ctx *ctx = (uip_wolfssl_ctx *)_ctx;
3212 byte token[32];
3213 byte digest[UIP_COOKIE_DIGEST_SIZE];
3214 int ret = 0;
3215 XMEMSET(token, 0, sizeof(token));
3216 XMEMCPY(token, &ctx->peer_addr, sizeof(uip_ipaddr_t));
3217 XMEMCPY(token + sizeof(uip_ipaddr_t), &ctx->peer_port, sizeof(word16));
3218#if defined(NO_SHA) && !defined(NO_SHA256)
3219 ret = wc_Sha256Hash(token, sizeof(uip_ipaddr_t) + sizeof(word16), digest);
3220#else
3221 ret = wc_ShaHash(token, sizeof(uip_ipaddr_t) + sizeof(word16), digest);
3222#endif
3223 if (ret != 0)
3224 return ret;
3225 if (sz > UIP_COOKIE_DIGEST_SIZE)
3226 sz = UIP_COOKIE_DIGEST_SIZE;
3227 XMEMCPY(buf, digest, sz);
3228 return sz;
3229}
3230
3231#endif /* WOLFSSL_UIP */
3232
3233#ifdef WOLFSSL_GNRC
3234
3235#include <net/sock.h>
3236#include <net/sock/tcp.h>
3237#include <stdio.h>
3238
3239/* GNRC TCP/IP port, using the native tcp/udp socket api.
3240 * TCP and UDP are currently supported with the callbacks below.
3241 *
3242 */
3243/* The GNRC tcp send callback
3244 * return : bytes sent, or error
3245 */
3246
3247int GNRC_SendTo(WOLFSSL* ssl, char* buf, int sz, void* _ctx)
3248{
3249 sock_tls_t *ctx = (sock_tls_t *)_ctx;
3250 int ret = 0;
3251 (void)ssl;
3252 if (!ctx)
3253 return WOLFSSL_CBIO_ERR_GENERAL;
3254 ret = sock_udp_send(&ctx->conn.udp, (unsigned char *)buf, sz, &ctx->peer_addr);
3255 if (ret == 0)
3256 return WOLFSSL_CBIO_ERR_WANT_WRITE;
3257 return ret;
3258}
3259
3260/* The GNRC TCP/IP receive callback
3261 * return : nb bytes read, or error
3262 */
3263int GNRC_ReceiveFrom(WOLFSSL *ssl, char *buf, int sz, void *_ctx)
3264{
3265 sock_udp_ep_t ep;
3266 int ret;
3267 word32 timeout = wolfSSL_dtls_get_current_timeout(ssl) * 1000000;
3268 sock_tls_t *ctx = (sock_tls_t *)_ctx;
3269 if (!ctx)
3270 return WOLFSSL_CBIO_ERR_GENERAL;
3271 (void)ssl;
3272 if (wolfSSL_get_using_nonblock(ctx->ssl)) {
3273 timeout = 0;
3274 }
3275 ret = sock_udp_recv(&ctx->conn.udp, buf, sz, timeout, &ep);
3276 if (ret > 0) {
3277 if (ctx->peer_addr.port == 0)
3278 XMEMCPY(&ctx->peer_addr, &ep, sizeof(sock_udp_ep_t));
3279 }
3280 if (ret == -ETIMEDOUT) {
3281 return WOLFSSL_CBIO_ERR_WANT_READ;
3282 }
3283 return ret;
3284}
3285
3286/* GNRC DTLS Generate Cookie callback
3287 * return : number of bytes copied into buf, or error
3288 */
3289#define GNRC_MAX_TOKEN_SIZE (32)
3290#if defined(NO_SHA) && !defined(NO_SHA256)
3291 #define GNRC_COOKIE_DIGEST_SIZE WC_SHA256_DIGEST_SIZE
3292#elif !defined(NO_SHA)
3293 #define GNRC_COOKIE_DIGEST_SIZE WC_SHA_DIGEST_SIZE
3294#else
3295 #error Must enable either SHA-1 or SHA256 (or both) for GNRC.
3296#endif
3297int GNRC_GenerateCookie(WOLFSSL* ssl, byte *buf, int sz, void *_ctx)
3298{
3299 sock_tls_t *ctx = (sock_tls_t *)_ctx;
3300 if (!ctx)
3301 return WOLFSSL_CBIO_ERR_GENERAL;
3302 byte token[GNRC_MAX_TOKEN_SIZE];
3303 byte digest[GNRC_COOKIE_DIGEST_SIZE];
3304 int ret = 0;
3305 size_t token_size = sizeof(sock_udp_ep_t);
3306 (void)ssl;
3307 if (token_size > GNRC_MAX_TOKEN_SIZE)
3308 token_size = GNRC_MAX_TOKEN_SIZE;
3309 XMEMSET(token, 0, GNRC_MAX_TOKEN_SIZE);
3310 XMEMCPY(token, &ctx->peer_addr, token_size);
3311#if defined(NO_SHA) && !defined(NO_SHA256)
3312 ret = wc_Sha256Hash(token, token_size, digest);
3313#else
3314 ret = wc_ShaHash(token, token_size, digest);
3315#endif
3316 if (ret != 0)
3317 return ret;
3318 if (sz > GNRC_COOKIE_DIGEST_SIZE)
3319 sz = GNRC_COOKIE_DIGEST_SIZE;
3320 XMEMCPY(buf, digest, sz);
3321 return sz;
3322}
3323
3324#endif /* WOLFSSL_GNRC */
3325
3326#ifdef WOLFSSL_LWIP_NATIVE
3327int LwIPNativeSend(WOLFSSL* ssl, char* buf, int sz, void* ctx)
3328{
3329 err_t ret;
3330 WOLFSSL_LWIP_NATIVE_STATE* nlwip = (WOLFSSL_LWIP_NATIVE_STATE*)ctx;
3331
3332 if (sz < 0 || sz > (int)WOLFSSL_MAX_16BIT) {
3333 return BAD_FUNC_ARG;
3334 }
3335
3336 ret = tcp_write(nlwip->pcb, buf, (u16_t)sz, TCP_WRITE_FLAG_COPY);
3337 if (ret != ERR_OK) {
3338 sz = WOLFSSL_FATAL_ERROR;
3339 }
3340
3341 return sz;
3342}
3343
3344
3345int LwIPNativeReceive(WOLFSSL* ssl, char* buf, int sz, void* ctx)
3346{
3347 struct pbuf *current, *head;
3348 WOLFSSL_LWIP_NATIVE_STATE* nlwip;
3349 int ret = 0;
3350
3351 if (ctx == NULL) {
3352 return WOLFSSL_CBIO_ERR_GENERAL;
3353 }
3354 nlwip = (WOLFSSL_LWIP_NATIVE_STATE*)ctx;
3355
3356 current = nlwip->pbuf;
3357 if (current == NULL || sz > current->tot_len) {
3358 WOLFSSL_MSG("LwIP native pbuf list is null or not enough data, want read");
3359 ret = WOLFSSL_CBIO_ERR_WANT_READ;
3360 }
3361 else {
3362 int read = 0; /* total amount read */
3363 head = nlwip->pbuf; /* save pointer to current head */
3364
3365 /* loop through buffers reading data */
3366 while (current != NULL) {
3367 int len; /* current amount to be read */
3368
3369 len = (current->len - nlwip->pulled < sz) ?
3370 (current->len - nlwip->pulled) : sz;
3371
3372 if (read + len > sz) {
3373 /* should never be hit but have sanity check before use */
3374 return WOLFSSL_CBIO_ERR_GENERAL;
3375 }
3376
3377 /* check if is a partial read from before */
3378 XMEMCPY(&buf[read],
3379 (const char *)&(((char *)(current->payload))[nlwip->pulled]),
3380
3381 len);
3382 nlwip->pulled = nlwip->pulled + len;
3383 if (nlwip->pulled >= current->len) {
3384 WOLFSSL_MSG("Native LwIP read full pbuf");
3385 nlwip->pbuf = current->next;
3386 current = nlwip->pbuf;
3387 nlwip->pulled = 0;
3388 }
3389 read = read + len;
3390 ret = read;
3391
3392 /* read enough break out */
3393 if (read >= sz) {
3394 /* if more pbuf's are left in the chain then increment the
3395 * ref count for next in chain and free all from beginning till
3396 * next */
3397 if (current != NULL) {
3398 pbuf_ref(current);
3399 }
3400
3401 /* ack and start free'ing from the current head of the chain */
3402 pbuf_free(head);
3403 break;
3404 }
3405 }
3406 }
3407 WOLFSSL_LEAVE("LwIPNativeReceive", ret);
3408 return ret;
3409}
3410
3411
3412static err_t LwIPNativeReceiveCB(void* cb, struct tcp_pcb* pcb,
3413 struct pbuf* pbuf, err_t err)
3414{
3415 WOLFSSL_LWIP_NATIVE_STATE* nlwip;
3416
3417 if (cb == NULL || pcb == NULL) {
3418 WOLFSSL_MSG("Expected callback was null, abort");
3419 return ERR_ABRT;
3420 }
3421
3422 nlwip = (WOLFSSL_LWIP_NATIVE_STATE*)cb;
3423 if (pbuf == NULL && err == ERR_OK) {
3424 return ERR_OK;
3425 }
3426
3427 if (nlwip->pbuf == NULL) {
3428 nlwip->pbuf = pbuf;
3429 }
3430 else {
3431 if (nlwip->pbuf != pbuf) {
3432 tcp_recved(nlwip->pcb, pbuf->tot_len);
3433 pbuf_cat(nlwip->pbuf, pbuf); /* add chain to head */
3434 }
3435 }
3436
3437 if (nlwip->recv_fn) {
3438 return nlwip->recv_fn(nlwip->arg, pcb, pbuf, err);
3439 }
3440
3441 WOLFSSL_LEAVE("LwIPNativeReceiveCB", nlwip->pbuf->tot_len);
3442 return ERR_OK;
3443}
3444
3445
3446static err_t LwIPNativeSentCB(void* cb, struct tcp_pcb* pcb, u16_t len)
3447{
3448 WOLFSSL_LWIP_NATIVE_STATE* nlwip;
3449
3450 if (cb == NULL || pcb == NULL) {
3451 WOLFSSL_MSG("Expected callback was null, abort");
3452 return ERR_ABRT;
3453 }
3454
3455 nlwip = (WOLFSSL_LWIP_NATIVE_STATE*)cb;
3456 if (nlwip->sent_fn) {
3457 return nlwip->sent_fn(nlwip->arg, pcb, len);
3458 }
3459 return ERR_OK;
3460}
3461
3462
3463int wolfSSL_SetIO_LwIP(WOLFSSL* ssl, void* pcb,
3464 tcp_recv_fn recv_fn, tcp_sent_fn sent_fn, void *arg)
3465{
3466 if (ssl == NULL || pcb == NULL)
3467 return BAD_FUNC_ARG;
3468
3469 ssl->lwipCtx.pcb = (struct tcp_pcb *)pcb;
3470 ssl->lwipCtx.recv_fn = recv_fn; /* recv user callback */
3471 ssl->lwipCtx.sent_fn = sent_fn; /* sent user callback */
3472 ssl->lwipCtx.arg = arg;
3473 ssl->lwipCtx.pbuf = 0;
3474 ssl->lwipCtx.pulled = 0;
3475 ssl->lwipCtx.wait = 0;
3476
3477 /* wolfSSL_LwIP_recv/sent_cb invokes recv/sent user callback in them. */
3478 tcp_recv(pcb, LwIPNativeReceiveCB);
3479 tcp_sent(pcb, LwIPNativeSentCB);
3480 tcp_arg (pcb, (void *)&ssl->lwipCtx);
3481 wolfSSL_SetIOReadCtx(ssl, &ssl->lwipCtx);
3482 wolfSSL_SetIOWriteCtx(ssl, &ssl->lwipCtx);
3483
3484 return ERR_OK;
3485}
3486#endif /* WOLFSSL_LWIP_NATIVE */
3487
3488#ifdef WOLFSSL_ISOTP
3489static int isotp_send_single_frame(struct isotp_wolfssl_ctx *ctx, char *buf,
3490 word16 length)
3491{
3492 /* Length will be at most 7 bytes to get here. Packet is length and type
3493 * for the first byte, then up to 7 bytes of data */
3494 ctx->frame.data[0] = ((byte)length) | (ISOTP_FRAME_TYPE_SINGLE << 4);
3495 XMEMCPY(&ctx->frame.data[1], buf, length);
3496 ctx->frame.length = length + 1;
3497 return ctx->send_fn(&ctx->frame, ctx->arg);
3498}
3499
3500static int isotp_send_flow_control(struct isotp_wolfssl_ctx *ctx,
3501 byte overflow)
3502{
3503 int ret;
3504 /* Overflow is set it if we have been asked to receive more data than the
3505 * user allocated a buffer for */
3506 if (overflow) {
3507 ctx->frame.data[0] = ISOTP_FLOW_CONTROL_ABORT |
3508 (ISOTP_FRAME_TYPE_CONTROL << 4);
3509 } else {
3510 ctx->frame.data[0] = ISOTP_FLOW_CONTROL_CTS |
3511 (ISOTP_FRAME_TYPE_CONTROL << 4);
3512 }
3513 /* Set the number of frames between flow control to infinite */
3514 ctx->frame.data[1] = ISOTP_FLOW_CONTROL_FRAMES;
3515 /* User specified frame delay */
3516 ctx->frame.data[2] = ctx->receive_delay;
3517 ctx->frame.length = ISOTP_FLOW_CONTROL_PACKET_SIZE;
3518 ret = ctx->send_fn(&ctx->frame, ctx->arg);
3519 return ret;
3520}
3521
3522static int isotp_receive_flow_control(struct isotp_wolfssl_ctx *ctx)
3523{
3524 int ret;
3525 enum isotp_frame_type type;
3526 enum isotp_flow_control flow_control;
3527 ret = ctx->recv_fn(&ctx->frame, ctx->arg, ISOTP_DEFAULT_TIMEOUT);
3528 if (ret == 0) {
3529 return WOLFSSL_CBIO_ERR_TIMEOUT;
3530 } else if (ret < 0) {
3531 WOLFSSL_MSG("ISO-TP error receiving flow control packet");
3532 return WOLFSSL_CBIO_ERR_GENERAL;
3533 }
3534 /* Flow control is the frame type and flow response for the first byte,
3535 * number of frames until the next flow control packet for the second
3536 * byte, time between frames for the third byte */
3537 type = ctx->frame.data[0] >> 4;
3538
3539 if (type != ISOTP_FRAME_TYPE_CONTROL) {
3540 WOLFSSL_MSG("ISO-TP frames out of sequence");
3541 return WOLFSSL_CBIO_ERR_GENERAL;
3542 }
3543
3544 flow_control = ctx->frame.data[0] & 0xf;
3545
3546 ctx->flow_counter = 0;
3547 ctx->flow_packets = ctx->frame.data[1];
3548 ctx->frame_delay = ctx->frame.data[2];
3549
3550 return flow_control;
3551}
3552
3553static int isotp_send_consecutive_frame(struct isotp_wolfssl_ctx *ctx)
3554{
3555 /* Sequence is 0 - 15 and then starts again, the first frame has an
3556 * implied sequence of '0' */
3557 ctx->sequence += 1;
3558 if (ctx->sequence > ISOTP_MAX_SEQUENCE_COUNTER) {
3559 ctx->sequence = 0;
3560 }
3561 ctx->flow_counter++;
3562 /* First byte it type and sequence number, up to 7 bytes of data */
3563 ctx->frame.data[0] = ctx->sequence | (ISOTP_FRAME_TYPE_CONSECUTIVE << 4);
3564 if (ctx->buf_length > ISOTP_MAX_CONSECUTIVE_FRAME_DATA_SIZE) {
3565 XMEMCPY(&ctx->frame.data[1], ctx->buf_ptr,
3566 ISOTP_MAX_CONSECUTIVE_FRAME_DATA_SIZE);
3567 ctx->buf_ptr += ISOTP_MAX_CONSECUTIVE_FRAME_DATA_SIZE;
3568 ctx->buf_length -= ISOTP_MAX_CONSECUTIVE_FRAME_DATA_SIZE;
3569 ctx->frame.length = ISOTP_CAN_BUS_PAYLOAD_SIZE;
3570 } else {
3571 XMEMCPY(&ctx->frame.data[1], ctx->buf_ptr, ctx->buf_length);
3572 ctx->frame.length = ctx->buf_length + 1;
3573 ctx->buf_length = 0;
3574 }
3575 return ctx->send_fn(&ctx->frame, ctx->arg);
3576
3577}
3578
3579static int isotp_send_first_frame(struct isotp_wolfssl_ctx *ctx, char *buf,
3580 word16 length)
3581{
3582 int ret;
3583 ctx->sequence = 0;
3584 /* Set to 1 to trigger a flow control straight away, the flow control
3585 * packet will set these properly */
3586 ctx->flow_packets = ctx->flow_counter = 1;
3587 /* First frame has 1 nibble for type, 3 nibbles for length followed by
3588 * 6 bytes for data*/
3589 ctx->frame.data[0] = (length >> 8) | (ISOTP_FRAME_TYPE_FIRST << 4);
3590 ctx->frame.data[1] = length & 0xff;
3591 XMEMCPY(&ctx->frame.data[2], buf, ISOTP_FIRST_FRAME_DATA_SIZE);
3592 ctx->buf_ptr = buf + ISOTP_FIRST_FRAME_DATA_SIZE;
3593 ctx->buf_length = length - ISOTP_FIRST_FRAME_DATA_SIZE;
3594 ctx->frame.length = ISOTP_CAN_BUS_PAYLOAD_SIZE;
3595 ret = ctx->send_fn(&ctx->frame, ctx->arg);
3596 if (ret <= 0) {
3597 WOLFSSL_MSG("ISO-TP error sending first frame");
3598 return WOLFSSL_CBIO_ERR_GENERAL;
3599 }
3600 while(ctx->buf_length) {
3601 /* The receiver can set how often to get a flow control packet. If it
3602 * is time, then get the packet. Note that this will always happen
3603 * after the first packet */
3604 if ((ctx->flow_packets > 0) &&
3605 (ctx->flow_counter == ctx->flow_packets)) {
3606 ret = isotp_receive_flow_control(ctx);
3607 }
3608 /* Frame delay <= 0x7f is in ms, 0xfX is X * 100 us */
3609 if (ctx->frame_delay) {
3610 if (ctx->frame_delay <= ISOTP_MAX_MS_FRAME_DELAY) {
3611 ctx->delay_fn(ctx->frame_delay * 1000);
3612 } else {
3613 ctx->delay_fn((ctx->frame_delay & 0xf) * 100);
3614 }
3615 }
3616 switch (ret) {
3617 /* Clear to send */
3618 case ISOTP_FLOW_CONTROL_CTS:
3619 if (isotp_send_consecutive_frame(ctx) < 0) {
3620 WOLFSSL_MSG("ISO-TP error sending consecutive frame");
3621 return WOLFSSL_CBIO_ERR_GENERAL;
3622 }
3623 break;
3624 /* Receiver says "WAIT", so we wait for another flow control
3625 * packet, or abort if we have waited too long */
3626 case ISOTP_FLOW_CONTROL_WAIT:
3627 ctx->wait_counter += 1;
3628 if (ctx->wait_counter > ISOTP_DEFAULT_WAIT_COUNT) {
3629 WOLFSSL_MSG("ISO-TP receiver told us to wait too many"
3630 " times");
3631 return WOLFSSL_CBIO_ERR_WANT_WRITE;
3632 }
3633 break;
3634 /* Receiver is not ready to receive packet, so abort */
3635 case ISOTP_FLOW_CONTROL_ABORT:
3636 WOLFSSL_MSG("ISO-TP receiver aborted transmission");
3637 return WOLFSSL_CBIO_ERR_WANT_WRITE;
3638 default:
3639 WOLFSSL_MSG("ISO-TP got unexpected flow control packet");
3640 return WOLFSSL_CBIO_ERR_GENERAL;
3641 }
3642 }
3643 return 0;
3644}
3645
3646int ISOTP_Send(WOLFSSL* ssl, char* buf, int sz, void* ctx)
3647{
3648 int ret;
3649 struct isotp_wolfssl_ctx *isotp_ctx;
3650 (void) ssl;
3651
3652 if (!ctx) {
3653 WOLFSSL_MSG("ISO-TP requires wolfSSL_SetIO_ISOTP to be called first");
3654 return WOLFSSL_CBIO_ERR_GENERAL;
3655 }
3656 isotp_ctx = (struct isotp_wolfssl_ctx*) ctx;
3657
3658 /* ISO-TP cannot send more than 4095 bytes, this limits the packet size
3659 * and wolfSSL will try again with the remaining data */
3660 if (sz > ISOTP_MAX_DATA_SIZE) {
3661 sz = ISOTP_MAX_DATA_SIZE;
3662 }
3663 /* Can't send whilst we are receiving */
3664 if (isotp_ctx->state != ISOTP_CONN_STATE_IDLE) {
3665 return WOLFSSL_ERROR_WANT_WRITE;
3666 }
3667 isotp_ctx->state = ISOTP_CONN_STATE_SENDING;
3668
3669 /* Assuming normal addressing */
3670 if (sz <= ISOTP_SINGLE_FRAME_DATA_SIZE) {
3671 ret = isotp_send_single_frame(isotp_ctx, buf, (word16)sz);
3672 } else {
3673 ret = isotp_send_first_frame(isotp_ctx, buf, (word16)sz);
3674 }
3675 isotp_ctx->state = ISOTP_CONN_STATE_IDLE;
3676
3677 if (ret == 0) {
3678 return sz;
3679 }
3680 return ret;
3681}
3682
3683static int isotp_receive_single_frame(struct isotp_wolfssl_ctx *ctx)
3684{
3685 byte data_size;
3686
3687 /* 1 nibble for data size which will be 1 - 7 in a regular 8 byte CAN
3688 * packet */
3689 data_size = (byte)ctx->frame.data[0] & 0xf;
3690 if (ctx->receive_buffer_size < (int)data_size) {
3691 WOLFSSL_MSG("ISO-TP buffer is too small to receive data");
3692 return BUFFER_E;
3693 }
3694 XMEMCPY(ctx->receive_buffer, &ctx->frame.data[1], data_size);
3695 return data_size;
3696}
3697
3698static int isotp_receive_multi_frame(struct isotp_wolfssl_ctx *ctx)
3699{
3700 int ret;
3701 word16 data_size;
3702 byte delay = 0;
3703
3704 /* Increase receive timeout for enforced ms delay */
3705 if (ctx->receive_delay <= ISOTP_MAX_MS_FRAME_DELAY) {
3706 delay = ctx->receive_delay;
3707 }
3708 /* Still processing first frame.
3709 * Full data size is lower nibble of first byte for the most significant
3710 * followed by the second byte for the rest. Last 6 bytes are data */
3711 data_size = ((ctx->frame.data[0] & 0xf) << 8) + ctx->frame.data[1];
3712 XMEMCPY(ctx->receive_buffer, &ctx->frame.data[2], ISOTP_FIRST_FRAME_DATA_SIZE);
3713 /* Need to send a flow control packet to either cancel or continue
3714 * transmission of data */
3715 if (ctx->receive_buffer_size < data_size) {
3716 isotp_send_flow_control(ctx, TRUE);
3717 WOLFSSL_MSG("ISO-TP buffer is too small to receive data");
3718 return BUFFER_E;
3719 }
3720 isotp_send_flow_control(ctx, FALSE);
3721
3722 ctx->buf_length = ISOTP_FIRST_FRAME_DATA_SIZE;
3723 ctx->buf_ptr = ctx->receive_buffer + ISOTP_FIRST_FRAME_DATA_SIZE;
3724 data_size -= ISOTP_FIRST_FRAME_DATA_SIZE;
3725 ctx->sequence = 1;
3726
3727 while(data_size) {
3728 enum isotp_frame_type type;
3729 byte sequence;
3730 byte frame_len;
3731 ret = ctx->recv_fn(&ctx->frame, ctx->arg, ISOTP_DEFAULT_TIMEOUT +
3732 (delay / 1000));
3733 if (ret == 0) {
3734 return WOLFSSL_CBIO_ERR_TIMEOUT;
3735 }
3736 type = ctx->frame.data[0] >> 4;
3737 /* Consecutive frames have sequence number as lower nibble */
3738 sequence = ctx->frame.data[0] & 0xf;
3739 if (type != ISOTP_FRAME_TYPE_CONSECUTIVE) {
3740 WOLFSSL_MSG("ISO-TP frames out of sequence");
3741 return WOLFSSL_CBIO_ERR_GENERAL;
3742 }
3743 if (sequence != ctx->sequence) {
3744 WOLFSSL_MSG("ISO-TP frames out of sequence");
3745 return WOLFSSL_CBIO_ERR_GENERAL;
3746 }
3747 /* Last 7 bytes or whatever we got after the first byte is data */
3748 frame_len = ctx->frame.length - 1;
3749 XMEMCPY(ctx->buf_ptr, &ctx->frame.data[1], frame_len);
3750 ctx->buf_ptr += frame_len;
3751 ctx->buf_length += frame_len;
3752 data_size -= frame_len;
3753
3754 /* Sequence is 0 - 15 (first 0 is implied for first packet */
3755 ctx->sequence++;
3756 if (ctx->sequence > ISOTP_MAX_SEQUENCE_COUNTER) {
3757 ctx->sequence = 0;
3758 }
3759 }
3760 return ctx->buf_length;
3761
3762}
3763
3764/* The wolfSSL receive callback, needs to buffer because we need to grab all
3765 * incoming data, even if wolfSSL doesn't want it all yet */
3766int ISOTP_Receive(WOLFSSL* ssl, char* buf, int sz, void* ctx)
3767{
3768 enum isotp_frame_type type;
3769 int ret;
3770 struct isotp_wolfssl_ctx *isotp_ctx;
3771 (void) ssl;
3772
3773 if (!ctx) {
3774 WOLFSSL_MSG("ISO-TP requires wolfSSL_SetIO_ISOTP to be called first");
3775 return WOLFSSL_CBIO_ERR_TIMEOUT;
3776 }
3777 isotp_ctx = (struct isotp_wolfssl_ctx*)ctx;
3778
3779 /* Is buffer empty? If so, fill it */
3780 if (!isotp_ctx->receive_buffer_len) {
3781 /* Can't send whilst we are receiving */
3782 if (isotp_ctx->state != ISOTP_CONN_STATE_IDLE) {
3783 return WOLFSSL_ERROR_WANT_READ;
3784 }
3785 isotp_ctx->state = ISOTP_CONN_STATE_RECEIVING;
3786 do {
3787 ret = isotp_ctx->recv_fn(&isotp_ctx->frame, isotp_ctx->arg,
3788 ISOTP_DEFAULT_TIMEOUT);
3789 } while (ret == 0);
3790 if (ret == 0) {
3791 isotp_ctx->state = ISOTP_CONN_STATE_IDLE;
3792 return WOLFSSL_CBIO_ERR_TIMEOUT;
3793 } else if (ret < 0) {
3794 isotp_ctx->state = ISOTP_CONN_STATE_IDLE;
3795 WOLFSSL_MSG("ISO-TP receive error");
3796 return WOLFSSL_CBIO_ERR_GENERAL;
3797 }
3798
3799 type = (enum isotp_frame_type) isotp_ctx->frame.data[0] >> 4;
3800
3801 if (type == ISOTP_FRAME_TYPE_SINGLE) {
3802 isotp_ctx->receive_buffer_len =
3803 isotp_receive_single_frame(isotp_ctx);
3804 } else if (type == ISOTP_FRAME_TYPE_FIRST) {
3805 isotp_ctx->receive_buffer_len =
3806 isotp_receive_multi_frame(isotp_ctx);
3807 } else {
3808 /* Should never get here */
3809 isotp_ctx->state = ISOTP_CONN_STATE_IDLE;
3810 WOLFSSL_MSG("ISO-TP frames out of sequence");
3811 return WOLFSSL_CBIO_ERR_GENERAL;
3812 }
3813 if (isotp_ctx->receive_buffer_len <= 1) {
3814 isotp_ctx->state = ISOTP_CONN_STATE_IDLE;
3815 return isotp_ctx->receive_buffer_len;
3816 } else {
3817 isotp_ctx->receive_buffer_ptr = isotp_ctx->receive_buffer;
3818 }
3819 isotp_ctx->state = ISOTP_CONN_STATE_IDLE;
3820 }
3821
3822 /* Return from the buffer */
3823 if (isotp_ctx->receive_buffer_len >= sz) {
3824 XMEMCPY(buf, isotp_ctx->receive_buffer_ptr, sz);
3825 isotp_ctx->receive_buffer_ptr+= sz;
3826 isotp_ctx->receive_buffer_len-= sz;
3827 return sz;
3828 } else {
3829 XMEMCPY(buf, isotp_ctx->receive_buffer_ptr,
3830 isotp_ctx->receive_buffer_len);
3831 sz = isotp_ctx->receive_buffer_len;
3832 isotp_ctx->receive_buffer_len = 0;
3833 return sz;
3834 }
3835}
3836
3837int wolfSSL_SetIO_ISOTP(WOLFSSL *ssl, isotp_wolfssl_ctx *ctx,
3838 can_recv_fn recv_fn, can_send_fn send_fn, can_delay_fn delay_fn,
3839 word32 receive_delay, char *receive_buffer, int receive_buffer_size,
3840 void *arg)
3841{
3842 if (!ctx || !recv_fn || !send_fn || !delay_fn || !receive_buffer) {
3843 WOLFSSL_MSG("ISO-TP has missing required parameter");
3844 return WOLFSSL_CBIO_ERR_GENERAL;
3845 }
3846 ctx->recv_fn = recv_fn;
3847 ctx->send_fn = send_fn;
3848 ctx->arg = arg;
3849 ctx->delay_fn = delay_fn;
3850 ctx->frame_delay = 0;
3851 ctx->receive_buffer = receive_buffer;
3852 ctx->receive_buffer_size = receive_buffer_size;
3853 ctx->receive_buffer_len = 0;
3854 ctx->state = ISOTP_CONN_STATE_IDLE;
3855
3856 wolfSSL_SetIOReadCtx(ssl, ctx);
3857 wolfSSL_SetIOWriteCtx(ssl, ctx);
3858
3859 /* Delay of 100 - 900us is 0xfX where X is value / 100. Delay of
3860 * >= 1000 is divided by 1000. > 127ms is invalid */
3861 if (receive_delay < 1000) {
3862 ctx->receive_delay = 0xf0 + (receive_delay / 100);
3863 } else if (receive_delay <= ISOTP_MAX_MS_FRAME_DELAY * 1000) {
3864 ctx->receive_delay = receive_delay / 1000;
3865 } else {
3866 WOLFSSL_MSG("ISO-TP delay parameter out of bounds");
3867 return WOLFSSL_CBIO_ERR_GENERAL;
3868 }
3869 return 0;
3870}
3871#endif /* WOLFSSL_ISOTP */
3872#endif /* WOLFCRYPT_ONLY */