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/ssl.c
raw
1/* ssl.c
2 *
3 * Copyright (C) 2006-2026 wolfSSL Inc.
4 *
5 * This file is part of wolfSSL.
6 *
7 * wolfSSL is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 3 of the License, or
10 * (at your option) any later version.
11 *
12 * wolfSSL is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA
20 */
21
22#include <wolfssl/wolfcrypt/libwolfssl_sources.h>
23
24#if defined(OPENSSL_EXTRA) && !defined(_WIN32) && !defined(_GNU_SOURCE)
25 /* turn on GNU extensions for XISASCII */
26 #define _GNU_SOURCE 1
27#endif
28
29#if !defined(WOLFCRYPT_ONLY) || defined(OPENSSL_EXTRA) || \
30 defined(OPENSSL_EXTRA_X509_SMALL)
31
32#include <wolfssl/internal.h>
33#include <wolfssl/error-ssl.h>
34#include <wolfssl/wolfcrypt/error-crypt.h>
35#include <wolfssl/wolfcrypt/coding.h>
36#include <wolfssl/wolfcrypt/kdf.h>
37#ifdef NO_INLINE
38 #include <wolfssl/wolfcrypt/misc.h>
39#else
40 #define WOLFSSL_MISC_INCLUDED
41 #include <wolfcrypt/src/misc.c>
42#endif
43
44#ifdef HAVE_ERRNO_H
45 #include <errno.h>
46#endif
47
48
49#if !defined(WOLFSSL_ALLOW_NO_SUITES) && !defined(WOLFCRYPT_ONLY)
50 #if defined(NO_DH) && !defined(HAVE_ECC) && !defined(WOLFSSL_STATIC_RSA) \
51 && !defined(WOLFSSL_STATIC_DH) && !defined(WOLFSSL_STATIC_PSK) \
52 && !defined(HAVE_CURVE25519) && !defined(HAVE_CURVE448)
53 #error "No cipher suites defined because DH disabled, ECC disabled, " \
54 "and no static suites defined. Please see top of README"
55 #endif
56 #ifdef WOLFSSL_CERT_GEN
57 /* need access to Cert struct for creating certificate */
58 #include <wolfssl/wolfcrypt/asn_public.h>
59 #endif
60#endif
61
62#if !defined(WOLFCRYPT_ONLY) && (defined(OPENSSL_EXTRA) \
63 || defined(OPENSSL_EXTRA_X509_SMALL) \
64 || defined(HAVE_WEBSERVER) || defined(WOLFSSL_KEY_GEN))
65 #include <wolfssl/openssl/evp.h>
66 /* openssl headers end, wolfssl internal headers next */
67#endif
68
69#include <wolfssl/wolfcrypt/wc_encrypt.h>
70
71#ifndef NO_RSA
72 #include <wolfssl/wolfcrypt/rsa.h>
73#endif
74
75#ifdef OPENSSL_EXTRA
76 /* openssl headers begin */
77 #include <wolfssl/openssl/ssl.h>
78 #include <wolfssl/openssl/aes.h>
79#ifndef WOLFCRYPT_ONLY
80 #include <wolfssl/openssl/hmac.h>
81 #include <wolfssl/openssl/cmac.h>
82#endif
83 #include <wolfssl/openssl/crypto.h>
84 #include <wolfssl/openssl/des.h>
85 #include <wolfssl/openssl/bn.h>
86 #include <wolfssl/openssl/buffer.h>
87 #include <wolfssl/openssl/dh.h>
88 #include <wolfssl/openssl/rsa.h>
89 #include <wolfssl/openssl/fips_rand.h>
90 #include <wolfssl/openssl/pem.h>
91 #include <wolfssl/openssl/ec.h>
92 #include <wolfssl/openssl/ec25519.h>
93 #include <wolfssl/openssl/ed25519.h>
94 #include <wolfssl/openssl/ec448.h>
95 #include <wolfssl/openssl/ed448.h>
96 #include <wolfssl/openssl/ecdsa.h>
97 #include <wolfssl/openssl/ecdh.h>
98 #include <wolfssl/openssl/err.h>
99 #include <wolfssl/openssl/modes.h>
100 #include <wolfssl/openssl/opensslv.h>
101 #include <wolfssl/openssl/rc4.h>
102 #include <wolfssl/openssl/stack.h>
103 #include <wolfssl/openssl/x509_vfy.h>
104 /* openssl headers end, wolfssl internal headers next */
105 #include <wolfssl/wolfcrypt/hmac.h>
106 #include <wolfssl/wolfcrypt/random.h>
107 #include <wolfssl/wolfcrypt/des3.h>
108 #include <wolfssl/wolfcrypt/ecc.h>
109 #include <wolfssl/wolfcrypt/md4.h>
110 #include <wolfssl/wolfcrypt/md5.h>
111 #include <wolfssl/wolfcrypt/arc4.h>
112 #include <wolfssl/wolfcrypt/curve25519.h>
113 #include <wolfssl/wolfcrypt/ed25519.h>
114 #include <wolfssl/wolfcrypt/curve448.h>
115 #if defined(HAVE_FALCON)
116 #include <wolfssl/wolfcrypt/falcon.h>
117 #endif /* HAVE_FALCON */
118 #if defined(HAVE_DILITHIUM)
119 #include <wolfssl/wolfcrypt/dilithium.h>
120 #endif /* HAVE_DILITHIUM */
121 #if defined(OPENSSL_ALL) || defined(HAVE_STUNNEL)
122 #ifdef HAVE_OCSP
123 #include <wolfssl/openssl/ocsp.h>
124 #endif
125 #include <wolfssl/openssl/lhash.h>
126 #include <wolfssl/openssl/txt_db.h>
127 #endif /* WITH_STUNNEL */
128 #if defined(WOLFSSL_SHA512) || defined(WOLFSSL_SHA384)
129 #include <wolfssl/wolfcrypt/sha512.h>
130 #endif
131 #if defined(WOLFCRYPT_HAVE_SRP) && !defined(NO_SHA256) \
132 && !defined(WC_NO_RNG)
133 #include <wolfssl/wolfcrypt/srp.h>
134 #endif
135#endif
136
137#if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)
138 #include <wolfssl/openssl/x509v3.h>
139 int wolfssl_bn_get_value(WOLFSSL_BIGNUM* bn, mp_int* mpi);
140 int wolfssl_bn_set_value(WOLFSSL_BIGNUM** bn, mp_int* mpi);
141#endif
142
143#if defined(WOLFSSL_QT)
144 #include <wolfssl/wolfcrypt/sha.h>
145#endif
146
147#ifdef NO_ASN
148 #include <wolfssl/wolfcrypt/dh.h>
149#endif
150#endif /* !WOLFCRYPT_ONLY || OPENSSL_EXTRA */
151
152/*
153 * ssl.c Build Options:
154 *
155 * See also: tls.c for TLS extension/protocol options, tls13.c for TLS 1.3,
156 * internal.c for handshake internals, wc_port.c for platform/memory.
157 *
158 * OpenSSL Compatibility:
159 * OPENSSL_EXTRA: Enable OpenSSL compatibility API default: off
160 * OPENSSL_ALL: Enable all OpenSSL compat APIs default: off
161 * OPENSSL_EXTRA_X509_SMALL: Minimal OpenSSL X509 compat APIs default: off
162 * OPENSSL_EXTRA_NO_ASN1: OpenSSL extra without ASN1 objects default: off
163 * OPENSSL_COMPATIBLE_DEFAULTS:
164 * Default behavior compatible with OpenSSL default: off
165 * NO_WOLFSSL_STUB: Disable stubs for unimplemented funcs default: off
166 * WOLFSSL_DEBUG_OPENSSL: Debug logging for OpenSSL compat layer default: off
167 * WOLFSSL_HAVE_ERROR_QUEUE: OpenSSL-compatible error queue default: off
168 * WOLFSSL_ERROR_CODE_OPENSSL: Use OpenSSL-compatible error codes default: off
169 * WOLFSSL_CIPHER_INTERNALNAME:
170 * Use wolfSSL internal cipher suite names default: off
171 * NO_CIPHER_SUITE_ALIASES: Disable cipher suite name aliases default: off
172 * WOLFSSL_SET_CIPHER_BYTES: Set cipher suites by raw byte values default: off
173 * WOLFSSL_OLD_SET_CURVES_LIST:
174 * Old-style curve list parsing for compat default: off
175 * WOLFSSL_NO_OPENSSL_RAND_CB: Disable OpenSSL RAND callback compat default: off
176 * NO_ERROR_STRINGS: Disable human-readable error strings default: off
177 * WOLFSSL_PUBLIC_ASN: Make ASN parsing functions public default: off
178 *
179 * Extra Data / BIO:
180 * HAVE_EX_DATA: Enable ex_data on SSL/CTX/X509 objects default: off
181 * HAVE_EX_DATA_CLEANUP_HOOKS: Cleanup callbacks for ex_data default: off
182 * HAVE_EX_DATA_CRYPTO: ex_data support for wolfCrypt objects default: off
183 * MAX_EX_DATA: Max ex_data entries per object default: 5
184 * NO_BIO: Disable BIO abstraction layer default: off
185 *
186 * Session & Cache:
187 * NO_SESSION_CACHE: Disable server session cache default: off
188 * NO_SESSION_CACHE_REF: wolfSSL_get_session returns ssl->session
189 * reference instead of ClientCache ref default: off
190 * SESSION_CACHE_DYNAMIC_MEM: Dynamically allocate session cache default: off
191 * NO_CLIENT_CACHE: Disable client-side session cache default: off
192 * SESSION_CERTS: Store full cert chain in session default: off
193 * WOLFSSL_SESSION_ID_CTX: Session ID context for cache sharing default: off
194 *
195 * I/O & Transport:
196 * USE_WOLFSSL_IO: Use built-in I/O callbacks default: on
197 * WOLFSSL_USER_IO: Application provides custom I/O default: off
198 * WOLFSSL_NO_SOCK: Build without socket support default: off
199 * NO_WRITEV: Disable writev() scatter/gather I/O default: off
200 * WOLFSSL_DTLS_MTU: Enable DTLS MTU management APIs default: off
201 * WOLFSSL_DTLS_DROP_STATS: Track DTLS packet drop statistics default: off
202 * WOLFSSL_MULTICAST: Enable DTLS multicast support default: off
203 *
204 * Callbacks & Features:
205 * WOLFSSL_CHECK_ALERT_ON_ERR: Check alerts on handshake error default: off
206 * ATOMIC_USER: User-defined record layer callbacks default: off
207 * HAVE_WRITE_DUP: Separate threads for SSL read/write default: off
208 * WOLFSSL_CALLBACKS: Handshake monitoring callbacks default: off
209 * NO_HANDSHAKE_DONE_CB: Disable handshake completion callback default: off
210 * WOLFSSL_SHUTDOWNONCE: Send close_notify only once default: off
211 * WOLFSSL_COPY_CERT: Copy certificate buffer (own copy) default: off
212 * WOLFSSL_COPY_KEY: Copy private key buffer (own copy) default: off
213 * WOLF_PRIVATE_KEY_ID: Reference private keys by ID default: off
214 * WOLFSSL_REFCNT_ERROR_RETURN:
215 * Return errors on ref counting failures default: off
216 * WOLFSSL_ALLOW_MAX_FRAGMENT_ADJUST:
217 * Allow runtime max fragment size adjustment default: off
218 * WOLFSSL_ALLOW_NO_SUITES: Allow SSL objects with no cipher suites default: off
219 *
220 * Certificates & Keys:
221 * KEEP_PEER_CERT: Keep peer cert after handshake default: off
222 * KEEP_OUR_CERT: Keep our cert after handshake default: off
223 * WOLFSSL_STATIC_RSA: Enable static RSA key exchange default: off
224 * WOLFSSL_HAVE_CERT_SERVICE: Certificate service callbacks default: off
225 * WOLFSSL_SYS_CA_CERTS: Load system CA certs from OS default: off
226 *
227 * Application Compatibility:
228 * HAVE_CURL: APIs for libcurl compatibility default: off
229 * HAVE_LIGHTY: APIs for lighttpd compatibility default: off
230 * HAVE_MEMCACHED: APIs for memcached compatibility default: off
231 * WOLFSSL_APACHE_HTTPD: APIs for Apache httpd compatibility default: off
232 * WOLFSSL_NGINX: APIs for nginx compatibility default: off
233 * WOLFSSL_HAPROXY: APIs for HAProxy compatibility default: off
234 * WOLFSSL_ASIO: APIs for Boost.Asio compatibility default: off
235 * WOLFSSL_PYTHON: APIs for Python module compatibility default: off
236 * WOLFSSL_QT: APIs for Qt framework compatibility default: off
237 * WOLFSSL_JNI: APIs for Java JNI/JSSE compatibility default: off
238 *
239 * Protocol Features:
240 * WOLFSSL_HAVE_WOLFSCEP: Enable wolfSCEP protocol support default: off
241 * WOLFCRYPT_HAVE_SRP: Enable SRP protocol support default: off
242 * HAVE_LIBZ: Enable zlib TLS compression default: off
243 * WOLFSSL_EXTRA: Extra SSL session info APIs default: off
244 * WOLFSSL_WPAS_SMALL: Minimal wpa_supplicant/hostapd APIs default: off
245 * HAVE_FUZZER: Fuzzing callback support default: off
246 *
247 * Memory & Threading:
248 * WOLFSSL_STATIC_MEMORY_LEAN: Lean static memory allocation default: off
249 * WOLFSSL_THREADED_CRYPT: Multi-threaded crypto operations default: off
250 * WOLFSSL_CLEANUP_THREADSAFE_BY_ATOMIC_OPS:
251 * Thread-safe cleanup via atomics default: off
252 * WOLFSSL_ATOMIC_INITIALIZER: Static init for atomic variables default: off
253 * WOLFSSL_DEBUG_MEMORY: Log malloc/free with file/line info default: off
254 * WOLFSSL_NO_REALLOC: Disable realloc, use malloc+copy+free default: off
255 * WOLFSSL_HEAP_TEST: Heap-related testing utilities default: off
256 *
257 * Debugging & Build:
258 * SHOW_SIZES: Display struct sizes at init default: off
259 * WOLFSSL_DEBUG_TRACE_ERROR_CODES:
260 * Trace error code origins for debugging default: off
261 * HAVE_ATEXIT: Register wolfSSL_Cleanup via atexit default: off
262 * WOLFSSL_SYS_CRYPTO_POLICY: Honor system crypto policy settings default: off
263 *
264 * Hardware TLS:
265 * WOLFSSL_RENESAS_TSIP_TLS: Renesas TSIP hardware crypto for TLS default: off
266 * WOLFSSL_RENESAS_FSPSM_TLS: Renesas FSP Security Module for TLS default: off
267 * WOLFSSL_EGD_NBLOCK: Non-blocking EGD entropy support default: off
268 */
269
270#define WOLFSSL_SSL_MISC_INCLUDED
271#include "src/ssl_misc.c"
272
273#define WOLFSSL_EVP_INCLUDED
274#include "wolfcrypt/src/evp.c"
275
276/* Crypto code uses EVP APIs. */
277#define WOLFSSL_SSL_CRYPTO_INCLUDED
278#include "src/ssl_crypto.c"
279
280#ifndef WOLFCRYPT_ONLY
281#define WOLFSSL_SSL_CERTMAN_INCLUDED
282#include "src/ssl_certman.c"
283
284#define WOLFSSL_SSL_SESS_INCLUDED
285#include "src/ssl_sess.c"
286
287#define WOLFSSL_SSL_API_CERT_INCLUDED
288#include "src/ssl_api_cert.c"
289
290#define WOLFSSL_SSL_API_PK_INCLUDED
291#include "src/ssl_api_pk.c"
292#endif
293
294#if (defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)) && \
295 !defined(WOLFCRYPT_ONLY)
296/* Convert shortname to NID.
297 *
298 * For OpenSSL compatibility.
299 *
300 * @param [in] sn Short name of OID.
301 * @return NID corresponding to shortname on success.
302 * @return WC_NID_undef when not recognized.
303 */
304int wc_OBJ_sn2nid(const char *sn)
305{
306 const WOLFSSL_ObjectInfo *obj_info = wolfssl_object_info;
307 size_t i;
308 WOLFSSL_ENTER("wc_OBJ_sn2nid");
309 for (i = 0; i < wolfssl_object_info_sz; i++, obj_info++) {
310 if (XSTRCMP(sn, obj_info->sName) == 0)
311 return obj_info->nid;
312 }
313 WOLFSSL_MSG("short name not found in table");
314 return WC_NID_undef;
315}
316#endif /* OPENSSL_EXTRA || OPENSSL_EXTRA_X509_SMALL */
317
318#ifndef WOLFCRYPT_ONLY
319
320
321#if defined(WOLFSSL_SYS_CRYPTO_POLICY)
322/* The system wide crypto-policy. Configured by wolfSSL_crypto_policy_enable.
323 * */
324static struct SystemCryptoPolicy crypto_policy;
325#endif /* WOLFSSL_SYS_CRYPTO_POLICY */
326
327#if !defined(NO_RSA) || !defined(NO_DH) || defined(HAVE_ECC) || \
328 (defined(OPENSSL_EXTRA) && defined(WOLFSSL_KEY_GEN) && !defined(NO_DSA))
329
330#define HAVE_GLOBAL_RNG /* consolidate flags for using globalRNG */
331static WC_RNG globalRNG;
332static volatile int initGlobalRNG = 0;
333
334#if defined(OPENSSL_EXTRA) || !defined(WOLFSSL_MUTEX_INITIALIZER)
335static WC_MAYBE_UNUSED wolfSSL_Mutex globalRNGMutex
336 WOLFSSL_MUTEX_INITIALIZER_CLAUSE(globalRNGMutex);
337#endif
338#ifndef WOLFSSL_MUTEX_INITIALIZER
339static int globalRNGMutex_valid = 0;
340#endif
341
342#if defined(OPENSSL_EXTRA) && defined(HAVE_HASHDRBG)
343static WOLFSSL_DRBG_CTX* gDrbgDefCtx = NULL;
344#endif
345
346WC_RNG* wolfssl_get_global_rng(void)
347{
348 WC_RNG* ret = NULL;
349
350 if (initGlobalRNG == 0)
351 WOLFSSL_MSG("Global RNG no Init");
352 else
353 ret = &globalRNG;
354
355 return ret;
356}
357
358/* Make a global RNG and return.
359 *
360 * @return Global RNG on success.
361 * @return NULL on error.
362 */
363WC_RNG* wolfssl_make_global_rng(void)
364{
365 WC_RNG* ret;
366
367#ifdef HAVE_GLOBAL_RNG
368 /* Get the global random number generator instead. */
369 ret = wolfssl_get_global_rng();
370#ifdef OPENSSL_EXTRA
371 if (ret == NULL) {
372 /* Create a global random if possible. */
373 (void)wolfSSL_RAND_Init();
374 ret = wolfssl_get_global_rng();
375 }
376#endif
377#else
378 WOLFSSL_ERROR_MSG("Bad RNG Init");
379 ret = NULL;
380#endif
381
382 return ret;
383}
384
385/* Too many defines to check explicitly - prototype it and always include
386 * for RSA, DH, ECC and DSA for BN. */
387WC_RNG* wolfssl_make_rng(WC_RNG* rng, int* local);
388
389/* Make a random number generator or get global if possible.
390 *
391 * Global may not be available and NULL will be returned.
392 *
393 * @param [in, out] rng Local random number generator.
394 * @param [out] local Local random number generator returned.
395 * @return NULL on failure.
396 * @return A random number generator object.
397 */
398WC_RNG* wolfssl_make_rng(WC_RNG* rng, int* local)
399{
400 WC_RNG* ret = NULL;
401#ifdef WOLFSSL_SMALL_STACK
402 int freeRng = 0;
403
404 /* Allocate RNG object . */
405 if (rng == NULL) {
406 rng = (WC_RNG*)XMALLOC(sizeof(WC_RNG), NULL, DYNAMIC_TYPE_RNG);
407 freeRng = 1;
408 }
409#endif
410
411 if (rng != NULL) {
412 if (wc_InitRng(rng) == 0) {
413 ret = rng;
414 *local = 1;
415 }
416 else {
417 WOLFSSL_MSG("Bad RNG Init");
418#ifdef WOLFSSL_SMALL_STACK
419 if (freeRng) {
420 XFREE(rng, NULL, DYNAMIC_TYPE_RNG);
421 rng = NULL;
422 }
423#endif
424 }
425 }
426 if (ret == NULL) {
427#ifdef HAVE_GLOBAL_RNG
428 WOLFSSL_MSG("trying global RNG");
429#endif
430 ret = wolfssl_make_global_rng();
431 }
432
433 return ret;
434}
435#endif
436
437#ifdef OPENSSL_EXTRA
438 /* WOLFSSL_NO_OPENSSL_RAND_CB: Allows way to reduce code size for
439 * OPENSSL_EXTRA where RAND callbacks are not used */
440 #ifndef WOLFSSL_NO_OPENSSL_RAND_CB
441 static const WOLFSSL_RAND_METHOD* gRandMethods = NULL;
442 static wolfSSL_Mutex gRandMethodMutex
443 WOLFSSL_MUTEX_INITIALIZER_CLAUSE(gRandMethodMutex);
444 #ifndef WOLFSSL_MUTEX_INITIALIZER
445 static int gRandMethodsInit = 0;
446 #endif
447 #endif /* !WOLFSSL_NO_OPENSSL_RAND_CB */
448#endif /* OPENSSL_EXTRA */
449
450#define WOLFSSL_SSL_BN_INCLUDED
451#include "src/ssl_bn.c"
452
453#ifndef OPENSSL_EXTRA_NO_ASN1
454#define WOLFSSL_SSL_ASN1_INCLUDED
455#include "src/ssl_asn1.c"
456#endif /* OPENSSL_EXTRA_NO_ASN1 */
457
458#define WOLFSSL_PK_INCLUDED
459#include "src/pk.c"
460
461#define WOLFSSL_EVP_PK_INCLUDED
462#include "wolfcrypt/src/evp_pk.c"
463
464#if defined(OPENSSL_EXTRA) || defined(WOLFSSL_WPAS_SMALL)
465/* copies over data of "in" to "out" */
466static void wolfSSL_CIPHER_copy(WOLFSSL_CIPHER* in, WOLFSSL_CIPHER* out)
467{
468 if (in == NULL || out == NULL)
469 return;
470
471 *out = *in;
472}
473
474
475#if defined(OPENSSL_ALL)
476static WOLFSSL_X509_OBJECT* wolfSSL_X509_OBJECT_dup(WOLFSSL_X509_OBJECT* obj)
477{
478 WOLFSSL_X509_OBJECT* ret = NULL;
479 if (obj) {
480 ret = wolfSSL_X509_OBJECT_new();
481 if (ret) {
482 ret->type = obj->type;
483 switch (ret->type) {
484 case WOLFSSL_X509_LU_NONE:
485 break;
486 case WOLFSSL_X509_LU_X509:
487 ret->data.x509 = wolfSSL_X509_dup(obj->data.x509);
488 break;
489 case WOLFSSL_X509_LU_CRL:
490 #if defined(HAVE_CRL)
491 ret->data.crl = wolfSSL_X509_CRL_dup(obj->data.crl);
492 #endif
493 break;
494 }
495 }
496 }
497 return ret;
498}
499#endif /* OPENSSL_ALL */
500
501#endif /* OPENSSL_EXTRA || WOLFSSL_WPAS_SMALL */
502
503#define WOLFSSL_SSL_SK_INCLUDED
504#include "src/ssl_sk.c"
505
506
507#include <wolfssl/wolfcrypt/hpke.h>
508
509#define WOLFSSL_SSL_ECH_INCLUDED
510#include "src/ssl_ech.c"
511
512#ifdef OPENSSL_EXTRA
513static int wolfSSL_parse_cipher_list(WOLFSSL_CTX* ctx, WOLFSSL* ssl,
514 Suites* suites, const char* list);
515#endif
516
517#if defined(WOLFSSL_RENESAS_TSIP_TLS) || defined(WOLFSSL_RENESAS_FSPSM_TLS)
518#include <wolfssl/wolfcrypt/port/Renesas/renesas_cmn.h>
519#endif
520
521/* prevent multiple mutex initializations */
522
523/* note, initRefCount is not used for thread synchronization, only for
524 * bookkeeping while inits_count_mutex is held.
525 */
526static volatile WC_THREADSHARED int initRefCount = 0;
527
528/* init ref count mutex */
529static WC_THREADSHARED wolfSSL_Mutex inits_count_mutex
530 WOLFSSL_MUTEX_INITIALIZER_CLAUSE(inits_count_mutex);
531#ifndef WOLFSSL_MUTEX_INITIALIZER
532static WC_THREADSHARED volatile int inits_count_mutex_valid = 0;
533#endif
534
535#ifdef NO_TLS
536static const WOLFSSL_METHOD gNoTlsMethod;
537#endif
538
539/* Create a new WOLFSSL_CTX struct and return the pointer to created struct.
540 WOLFSSL_METHOD pointer passed in is given to ctx to manage.
541 This function frees the passed in WOLFSSL_METHOD struct on failure and on
542 success is freed when ctx is freed.
543 */
544WOLFSSL_CTX* wolfSSL_CTX_new_ex(WOLFSSL_METHOD* method, void* heap)
545{
546 WOLFSSL_CTX* ctx = NULL;
547
548 WOLFSSL_ENTER("wolfSSL_CTX_new_ex");
549
550 if (initRefCount == 0) {
551 /* user no longer forced to call Init themselves */
552 int ret = wolfSSL_Init();
553 if (ret != WOLFSSL_SUCCESS) {
554 WOLFSSL_MSG("wolfSSL_Init failed");
555 WOLFSSL_LEAVE("wolfSSL_CTX_new_ex", 0);
556 XFREE(method, heap, DYNAMIC_TYPE_METHOD);
557 return NULL;
558 }
559 }
560
561#ifndef NO_TLS
562 if (method == NULL)
563 return ctx;
564#else
565 /* a blank TLS method */
566 method = (WOLFSSL_METHOD*)&gNoTlsMethod;
567#endif
568
569 ctx = (WOLFSSL_CTX*)XMALLOC(sizeof(WOLFSSL_CTX), heap, DYNAMIC_TYPE_CTX);
570 if (ctx) {
571 int ret;
572
573 ret = InitSSL_Ctx(ctx, method, heap);
574 #ifdef WOLFSSL_STATIC_MEMORY
575 if (heap != NULL) {
576 ctx->onHeapHint = 1; /* free the memory back to heap when done */
577 }
578 #endif
579 if (ret < 0) {
580 WOLFSSL_MSG("Init CTX failed");
581 wolfSSL_CTX_free(ctx);
582 ctx = NULL;
583 }
584#if defined(OPENSSL_EXTRA) && defined(WOLFCRYPT_HAVE_SRP) \
585 && !defined(NO_SHA256) && !defined(WC_NO_RNG)
586 else {
587 ctx->srp = (Srp*)XMALLOC(sizeof(Srp), heap, DYNAMIC_TYPE_SRP);
588 if (ctx->srp == NULL){
589 WOLFSSL_MSG("Init CTX failed");
590 wolfSSL_CTX_free(ctx);
591 return NULL;
592 }
593 XMEMSET(ctx->srp, 0, sizeof(Srp));
594 }
595#endif
596 }
597 else {
598 WOLFSSL_MSG("Alloc CTX failed, method freed");
599 XFREE(method, heap, DYNAMIC_TYPE_METHOD);
600 }
601
602#ifdef OPENSSL_COMPATIBLE_DEFAULTS
603 if (ctx) {
604 wolfSSL_CTX_set_verify(ctx, WOLFSSL_VERIFY_NONE, NULL);
605 wolfSSL_CTX_set_mode(ctx, WOLFSSL_MODE_AUTO_RETRY);
606 if (wolfSSL_CTX_set_min_proto_version(ctx,
607 (method->version.major == DTLS_MAJOR) ?
608 DTLS1_VERSION : SSL3_VERSION) != WOLFSSL_SUCCESS ||
609#ifdef HAVE_ANON
610 wolfSSL_CTX_allow_anon_cipher(ctx) != WOLFSSL_SUCCESS ||
611#endif
612 wolfSSL_CTX_set_group_messages(ctx) != WOLFSSL_SUCCESS) {
613 WOLFSSL_MSG("Setting OpenSSL CTX defaults failed");
614 wolfSSL_CTX_free(ctx);
615 ctx = NULL;
616 }
617 }
618#endif
619
620#if defined(WOLFSSL_SYS_CRYPTO_POLICY)
621 /* Load the crypto-policy ciphers if configured. */
622 if (ctx && wolfSSL_crypto_policy_is_enabled()) {
623 const char * list = wolfSSL_crypto_policy_get_ciphers();
624 int ret = 0;
625
626 if (list != NULL && *list != '\0') {
627 if (AllocateCtxSuites(ctx) != 0) {
628 WOLFSSL_MSG("allocate ctx suites failed");
629 wolfSSL_CTX_free(ctx);
630 ctx = NULL;
631 }
632 else {
633 ret = wolfSSL_parse_cipher_list(ctx, NULL, ctx->suites, list);
634 if (ret != WOLFSSL_SUCCESS) {
635 WOLFSSL_MSG("parse cipher list failed");
636 wolfSSL_CTX_free(ctx);
637 ctx = NULL;
638 }
639 }
640 }
641 }
642#endif /* WOLFSSL_SYS_CRYPTO_POLICY */
643
644 WOLFSSL_LEAVE("wolfSSL_CTX_new_ex", 0);
645 return ctx;
646}
647
648
649WOLFSSL_ABI
650WOLFSSL_CTX* wolfSSL_CTX_new(WOLFSSL_METHOD* method)
651{
652#ifdef WOLFSSL_HEAP_TEST
653 /* if testing the heap hint then set top level CTX to have test value */
654 return wolfSSL_CTX_new_ex(method, (void*)WOLFSSL_HEAP_TEST);
655#else
656 return wolfSSL_CTX_new_ex(method, NULL);
657#endif
658}
659
660/* increases CTX reference count to track proper time to "free" */
661int wolfSSL_CTX_up_ref(WOLFSSL_CTX* ctx)
662{
663 int ret;
664 wolfSSL_RefWithMutexInc(&ctx->ref, &ret);
665#ifdef WOLFSSL_REFCNT_ERROR_RETURN
666 return ((ret == 0) ? WOLFSSL_SUCCESS : WOLFSSL_FAILURE);
667#else
668 (void)ret;
669 return WOLFSSL_SUCCESS;
670#endif
671}
672
673WOLFSSL_ABI
674void wolfSSL_CTX_free(WOLFSSL_CTX* ctx)
675{
676 WOLFSSL_ENTER("wolfSSL_CTX_free");
677 if (ctx) {
678 FreeSSL_Ctx(ctx);
679 }
680
681 WOLFSSL_LEAVE("wolfSSL_CTX_free", 0);
682}
683
684
685#ifdef HAVE_ENCRYPT_THEN_MAC
686/**
687 * Sets whether Encrypt-Then-MAC extension can be negotiated against context.
688 * The default value: enabled.
689 *
690 * ctx SSL/TLS context.
691 * set Whether to allow or not: 1 is allow and 0 is disallow.
692 * returns WOLFSSL_SUCCESS
693 */
694int wolfSSL_CTX_AllowEncryptThenMac(WOLFSSL_CTX *ctx, int set)
695{
696 ctx->disallowEncThenMac = !set;
697 return WOLFSSL_SUCCESS;
698}
699
700/**
701 * Sets whether Encrypt-Then-MAC extension can be negotiated against context.
702 * The default value comes from context.
703 *
704 * ctx SSL/TLS context.
705 * set Whether to allow or not: 1 is allow and 0 is disallow.
706 * returns WOLFSSL_SUCCESS
707 */
708int wolfSSL_AllowEncryptThenMac(WOLFSSL *ssl, int set)
709{
710 ssl->options.disallowEncThenMac = !set;
711 return WOLFSSL_SUCCESS;
712}
713#endif
714
715#ifdef SINGLE_THREADED
716/* no locking in single threaded mode, allow a CTX level rng to be shared with
717 * WOLFSSL objects, WOLFSSL_SUCCESS on ok */
718int wolfSSL_CTX_new_rng(WOLFSSL_CTX* ctx)
719{
720 WC_RNG* rng;
721 int ret;
722
723 if (ctx == NULL) {
724 return BAD_FUNC_ARG;
725 }
726
727 rng = (WC_RNG*)XMALLOC(sizeof(WC_RNG), ctx->heap, DYNAMIC_TYPE_RNG);
728 if (rng == NULL) {
729 return MEMORY_E;
730 }
731
732#ifndef HAVE_FIPS
733 ret = wc_InitRng_ex(rng, ctx->heap, ctx->devId);
734#else
735 ret = wc_InitRng(rng);
736#endif
737 if (ret != 0) {
738 XFREE(rng, ctx->heap, DYNAMIC_TYPE_RNG);
739 return ret;
740 }
741
742 ctx->rng = rng;
743 return WOLFSSL_SUCCESS;
744}
745#endif
746
747
748WOLFSSL_ABI
749WOLFSSL* wolfSSL_new(WOLFSSL_CTX* ctx)
750{
751 WOLFSSL* ssl = NULL;
752 int ret = 0;
753
754 WOLFSSL_ENTER("wolfSSL_new");
755
756 if (ctx == NULL) {
757 WOLFSSL_MSG("wolfSSL_new ctx is null");
758 return NULL;
759 }
760
761 ssl = (WOLFSSL*) XMALLOC(sizeof(WOLFSSL), ctx->heap, DYNAMIC_TYPE_SSL);
762
763 if (ssl == NULL) {
764 WOLFSSL_MSG_EX("ssl xmalloc failed to allocate %d bytes",
765 (int)sizeof(WOLFSSL));
766 }
767 else {
768 ret = InitSSL(ssl, ctx, 0);
769 if (ret < 0) {
770 WOLFSSL_MSG_EX("wolfSSL_new failed during InitSSL. err = %d", ret);
771 FreeSSL(ssl, ctx->heap);
772 ssl = NULL;
773 }
774 else if (ret == 0) {
775 WOLFSSL_MSG("wolfSSL_new InitSSL success");
776 }
777 else {
778 /* Only success (0) or negative values should ever be seen. */
779 WOLFSSL_MSG_EX("WARNING: wolfSSL_new unexpected InitSSL return"
780 " value = %d", ret);
781 } /* InitSSL check */
782 } /* ssl XMALLOC success */
783
784 WOLFSSL_LEAVE("wolfSSL_new InitSSL =", ret);
785 (void)ret;
786
787 return ssl;
788}
789
790
791WOLFSSL_ABI
792void wolfSSL_free(WOLFSSL* ssl)
793{
794 WOLFSSL_ENTER("wolfSSL_free");
795
796 if (ssl) {
797 WOLFSSL_MSG_EX("Free SSL: %p", (wc_ptr_t)ssl);
798 FreeSSL(ssl, ssl->ctx->heap);
799 }
800 else {
801 WOLFSSL_MSG("Free SSL: wolfSSL_free already null");
802 }
803 WOLFSSL_LEAVE("wolfSSL_free", 0);
804}
805
806
807int wolfSSL_is_server(WOLFSSL* ssl)
808{
809 if (ssl == NULL)
810 return BAD_FUNC_ARG;
811 return ssl->options.side == WOLFSSL_SERVER_END;
812}
813
814#ifdef HAVE_WRITE_DUP
815
816/*
817 * Release resources around WriteDup object
818 *
819 * ssl WOLFSSL object
820 *
821 * no return, destruction so make best attempt
822*/
823void FreeWriteDup(WOLFSSL* ssl)
824{
825 int doFree = 0;
826
827 WOLFSSL_ENTER("FreeWriteDup");
828
829 if (ssl->dupWrite) {
830 if (wc_LockMutex(&ssl->dupWrite->dupMutex) == 0) {
831 ssl->dupWrite->dupCount--;
832 if (ssl->dupWrite->dupCount == 0) {
833 doFree = 1;
834 } else {
835 WOLFSSL_MSG("WriteDup count not zero, no full free");
836 }
837 wc_UnLockMutex(&ssl->dupWrite->dupMutex);
838 }
839 }
840
841 if (doFree) {
842#ifdef WOLFSSL_DTLS13
843 struct Dtls13RecordNumber* rn = ssl->dupWrite->sendAckList;
844 while (rn != NULL) {
845 struct Dtls13RecordNumber* next = rn->next;
846 XFREE(rn, ssl->heap, DYNAMIC_TYPE_DTLS_MSG);
847 rn = next;
848 }
849#endif
850#if defined(WOLFSSL_TLS13) && defined(WOLFSSL_POST_HANDSHAKE_AUTH)
851 Free_HS_Hashes(ssl->dupWrite->postHandshakeHashState, ssl->heap);
852 {
853 CertReqCtx* ctx = ssl->dupWrite->postHandshakeCertReqCtx;
854 while (ctx != NULL) {
855 CertReqCtx* nxt = ctx->next;
856 XFREE(ctx, ssl->heap, DYNAMIC_TYPE_TMP_BUFFER);
857 ctx = nxt;
858 }
859 }
860#endif /* WOLFSSL_TLS13 && WOLFSSL_POST_HANDSHAKE_AUTH */
861 wc_FreeMutex(&ssl->dupWrite->dupMutex);
862 XFREE(ssl->dupWrite, ssl->heap, DYNAMIC_TYPE_WRITEDUP);
863 ssl->dupWrite = NULL;
864 WOLFSSL_MSG("Did WriteDup full free, count to zero");
865 }
866}
867
868
869/*
870 * duplicate existing ssl members into dup needed for writing
871 *
872 * dup write only WOLFSSL
873 * ssl existing WOLFSSL
874 *
875 * 0 on success
876*/
877static int DupSSL(WOLFSSL* dup, WOLFSSL* ssl)
878{
879 word16 tmp_weOwnRng;
880#ifdef HAVE_ONE_TIME_AUTH
881#ifdef HAVE_POLY1305
882 Poly1305* tmp_poly1305 = NULL;
883#endif
884#endif
885
886 /* shared dupWrite setup */
887 ssl->dupWrite = (WriteDup*)XMALLOC(sizeof(WriteDup), ssl->heap,
888 DYNAMIC_TYPE_WRITEDUP);
889 if (ssl->dupWrite == NULL) {
890 return MEMORY_E;
891 }
892 XMEMSET(ssl->dupWrite, 0, sizeof(WriteDup));
893
894 if (wc_InitMutex(&ssl->dupWrite->dupMutex) != 0) {
895 XFREE(ssl->dupWrite, ssl->heap, DYNAMIC_TYPE_WRITEDUP);
896 ssl->dupWrite = NULL;
897 return BAD_MUTEX_E;
898 }
899
900 /* Pre-allocate any objects that can fail BEFORE performing destructive
901 * state mutations on ssl, so an allocation failure cannot leave ssl
902 * with a zeroed encrypt context and a poisoned dupWrite.
903 * dup->heap == ssl->heap here because dup was initialised with ssl->ctx;
904 * use ssl->heap consistently for cleanup symmetry. */
905#ifdef HAVE_ONE_TIME_AUTH
906#ifdef HAVE_POLY1305
907 if (ssl->auth.setup && ssl->auth.poly1305 != NULL) {
908 tmp_poly1305 = (Poly1305*)XMALLOC(sizeof(Poly1305), ssl->heap,
909 DYNAMIC_TYPE_CIPHER);
910 if (tmp_poly1305 == NULL) {
911 wc_FreeMutex(&ssl->dupWrite->dupMutex);
912 XFREE(ssl->dupWrite, ssl->heap, DYNAMIC_TYPE_WRITEDUP);
913 ssl->dupWrite = NULL;
914 return MEMORY_E;
915 }
916 }
917#endif
918#endif
919
920 ssl->dupWrite->dupCount = 2; /* both sides have a count to start */
921 dup->dupWrite = ssl->dupWrite; /* each side uses */
922
923 tmp_weOwnRng = dup->options.weOwnRng;
924
925 /* copy write parts over to dup writer */
926 XMEMCPY(&dup->specs, &ssl->specs, sizeof(CipherSpecs));
927 XMEMCPY(&dup->options, &ssl->options, sizeof(Options));
928 XMEMCPY(&dup->keys, &ssl->keys, sizeof(Keys));
929 XMEMCPY(&dup->encrypt, &ssl->encrypt, sizeof(Ciphers));
930 XMEMCPY(&dup->version, &ssl->version, sizeof(ProtocolVersion));
931 XMEMCPY(&dup->chVersion, &ssl->chVersion, sizeof(ProtocolVersion));
932
933 /* dup side now owns encrypt/write ciphers */
934 XMEMSET(&ssl->encrypt, 0, sizeof(Ciphers));
935
936#ifdef HAVE_ONE_TIME_AUTH
937#ifdef HAVE_POLY1305
938 if (tmp_poly1305 != NULL) {
939 dup->auth.poly1305 = tmp_poly1305;
940 dup->auth.setup = 1;
941 }
942#endif
943#endif
944
945#ifdef WOLFSSL_TLS13
946 if (IsAtLeastTLSv1_3(ssl->version)) {
947 /* Copy TLS 1.3 application traffic secrets so the write side can
948 * derive updated keys when wolfSSL_update_keys() is called. */
949 XMEMCPY(dup->clientSecret, ssl->clientSecret, SECRET_LEN);
950 XMEMCPY(dup->serverSecret, ssl->serverSecret, SECRET_LEN);
951
952#ifdef WOLFSSL_DTLS13
953 if (ssl->options.dtls) {
954 /* Copy epoch array (contains only value types -- safe to memcpy). */
955 XMEMCPY(dup->dtls13Epochs, ssl->dtls13Epochs,
956 sizeof(ssl->dtls13Epochs));
957
958 /* Re-point dtls13EncryptEpoch into dup's own epoch array. */
959 if (ssl->dtls13EncryptEpoch != NULL) {
960 dup->dtls13EncryptEpoch =
961 &dup->dtls13Epochs[ssl->dtls13EncryptEpoch -
962 ssl->dtls13Epochs];
963 }
964
965 /* Copy current write epoch number. */
966 dup->dtls13Epoch = ssl->dtls13Epoch;
967
968 /* Transfer record-number encryption cipher ownership to dup. */
969 XMEMCPY(&dup->dtlsRecordNumberEncrypt,
970 &ssl->dtlsRecordNumberEncrypt, sizeof(RecordNumberCiphers));
971 XMEMSET(&ssl->dtlsRecordNumberEncrypt,
972 0, sizeof(RecordNumberCiphers));
973 }
974#endif /* WOLFSSL_DTLS13 */
975 }
976#endif /* WOLFSSL_TLS13 */
977
978
979 dup->IOCB_WriteCtx = ssl->IOCB_WriteCtx;
980 dup->CBIOSend = ssl->CBIOSend;
981#ifdef OPENSSL_EXTRA
982 dup->cbioFlag = ssl->cbioFlag;
983#endif
984 dup->wfd = ssl->wfd;
985 dup->wflags = ssl->wflags;
986#ifndef WOLFSSL_AEAD_ONLY
987 dup->hmac = ssl->hmac;
988#endif
989#ifdef HAVE_TRUNCATED_HMAC
990 dup->truncated_hmac = ssl->truncated_hmac;
991#endif
992
993 /* Restore rng option */
994 dup->options.weOwnRng = tmp_weOwnRng;
995
996 /* unique side dup setup */
997 dup->dupSide = WRITE_DUP_SIDE;
998 ssl->dupSide = READ_DUP_SIDE;
999
1000 return 0;
1001}
1002
1003
1004/*
1005 * duplicate a WOLFSSL object post handshake for writing only
1006 * turn existing object into read only. Allows concurrent access from two
1007 * different threads.
1008 *
1009 * ssl existing WOLFSSL object
1010 *
1011 * return dup'd WOLFSSL object on success
1012*/
1013WOLFSSL* wolfSSL_write_dup(WOLFSSL* ssl)
1014{
1015 WOLFSSL* dup = NULL;
1016 int ret = 0;
1017
1018 (void)ret;
1019 WOLFSSL_ENTER("wolfSSL_write_dup");
1020
1021 if (ssl == NULL) {
1022 return ssl;
1023 }
1024
1025 if (ssl->options.handShakeDone == 0) {
1026 WOLFSSL_MSG("wolfSSL_write_dup called before handshake complete");
1027 return NULL;
1028 }
1029
1030 if (ssl->dupWrite) {
1031 WOLFSSL_MSG("wolfSSL_write_dup already called once");
1032 return NULL;
1033 }
1034
1035 dup = (WOLFSSL*) XMALLOC(sizeof(WOLFSSL), ssl->ctx->heap, DYNAMIC_TYPE_SSL);
1036 if (dup) {
1037 if ( (ret = InitSSL(dup, ssl->ctx, 1)) < 0) {
1038 FreeSSL(dup, ssl->ctx->heap);
1039 dup = NULL;
1040 } else if ( (ret = DupSSL(dup, ssl)) < 0) {
1041 FreeSSL(dup, ssl->ctx->heap);
1042 dup = NULL;
1043 }
1044 }
1045
1046 WOLFSSL_LEAVE("wolfSSL_write_dup", ret);
1047
1048 return dup;
1049}
1050
1051
1052/*
1053 * Notify write dup side of fatal error or close notify
1054 *
1055 * ssl WOLFSSL object
1056 * err Notify err
1057 *
1058 * 0 on success
1059*/
1060int NotifyWriteSide(WOLFSSL* ssl, int err)
1061{
1062 int ret;
1063
1064 WOLFSSL_ENTER("NotifyWriteSide");
1065
1066 ret = wc_LockMutex(&ssl->dupWrite->dupMutex);
1067 if (ret == 0) {
1068 ssl->dupWrite->dupErr = err;
1069 ret = wc_UnLockMutex(&ssl->dupWrite->dupMutex);
1070 }
1071
1072 return ret;
1073}
1074
1075
1076#endif /* HAVE_WRITE_DUP */
1077
1078
1079#ifdef HAVE_POLY1305
1080/* set if to use old poly 1 for yes 0 to use new poly */
1081int wolfSSL_use_old_poly(WOLFSSL* ssl, int value)
1082{
1083 (void)ssl;
1084 (void)value;
1085
1086#ifndef WOLFSSL_NO_TLS12
1087 WOLFSSL_ENTER("wolfSSL_use_old_poly");
1088 WOLFSSL_MSG("Warning SSL connection auto detects old/new and this function"
1089 "is depreciated");
1090 ssl->options.oldPoly = (word16)value;
1091 WOLFSSL_LEAVE("wolfSSL_use_old_poly", 0);
1092#endif
1093 return 0;
1094}
1095#endif
1096
1097
1098WOLFSSL_ABI
1099int wolfSSL_set_fd(WOLFSSL* ssl, int fd)
1100{
1101 int ret;
1102
1103 WOLFSSL_ENTER("wolfSSL_set_fd");
1104
1105 if (ssl == NULL) {
1106 return BAD_FUNC_ARG;
1107 }
1108
1109 ret = wolfSSL_set_read_fd(ssl, fd);
1110 if (ret == WOLFSSL_SUCCESS) {
1111 ret = wolfSSL_set_write_fd(ssl, fd);
1112 }
1113
1114 return ret;
1115}
1116
1117#ifdef WOLFSSL_DTLS
1118int wolfSSL_set_dtls_fd_connected(WOLFSSL* ssl, int fd)
1119{
1120 int ret;
1121
1122 WOLFSSL_ENTER("wolfSSL_set_dtls_fd_connected");
1123
1124 if (ssl == NULL) {
1125 return BAD_FUNC_ARG;
1126 }
1127
1128 ret = wolfSSL_set_fd(ssl, fd);
1129 if (ret == WOLFSSL_SUCCESS)
1130 ssl->buffers.dtlsCtx.connected = 1;
1131
1132 return ret;
1133}
1134#endif
1135
1136
1137int wolfSSL_set_read_fd(WOLFSSL* ssl, int fd)
1138{
1139 WOLFSSL_ENTER("wolfSSL_set_read_fd");
1140
1141 if (ssl == NULL) {
1142 return BAD_FUNC_ARG;
1143 }
1144
1145 ssl->rfd = fd; /* not used directly to allow IO callbacks */
1146 ssl->IOCB_ReadCtx = &ssl->rfd;
1147
1148 #ifdef WOLFSSL_DTLS
1149 ssl->buffers.dtlsCtx.connected = 0;
1150 if (ssl->options.dtls) {
1151 ssl->IOCB_ReadCtx = &ssl->buffers.dtlsCtx;
1152 ssl->buffers.dtlsCtx.rfd = fd;
1153 }
1154 #endif
1155
1156 WOLFSSL_LEAVE("wolfSSL_set_read_fd", WOLFSSL_SUCCESS);
1157 return WOLFSSL_SUCCESS;
1158}
1159
1160
1161int wolfSSL_set_write_fd(WOLFSSL* ssl, int fd)
1162{
1163 WOLFSSL_ENTER("wolfSSL_set_write_fd");
1164
1165 if (ssl == NULL) {
1166 return BAD_FUNC_ARG;
1167 }
1168
1169 ssl->wfd = fd; /* not used directly to allow IO callbacks */
1170 ssl->IOCB_WriteCtx = &ssl->wfd;
1171
1172 #ifdef WOLFSSL_DTLS
1173 ssl->buffers.dtlsCtx.connected = 0;
1174 if (ssl->options.dtls) {
1175 ssl->IOCB_WriteCtx = &ssl->buffers.dtlsCtx;
1176 ssl->buffers.dtlsCtx.wfd = fd;
1177 }
1178 #endif
1179
1180 WOLFSSL_LEAVE("wolfSSL_set_write_fd", WOLFSSL_SUCCESS);
1181 return WOLFSSL_SUCCESS;
1182}
1183
1184
1185/**
1186 * Get the name of cipher at priority level passed in.
1187 */
1188char* wolfSSL_get_cipher_list(int priority)
1189{
1190 const CipherSuiteInfo* ciphers = GetCipherNames();
1191
1192 if (priority >= GetCipherNamesSize() || priority < 0) {
1193 return 0;
1194 }
1195
1196 return (char*)ciphers[priority].name;
1197}
1198
1199
1200/**
1201 * Get the name of cipher at priority level passed in.
1202 */
1203char* wolfSSL_get_cipher_list_ex(WOLFSSL* ssl, int priority)
1204{
1205
1206 if (ssl == NULL) {
1207 return NULL;
1208 }
1209 else {
1210 const char* cipher;
1211
1212 if ((cipher = wolfSSL_get_cipher_name_internal(ssl)) != NULL) {
1213 if (priority == 0) {
1214 return (char*)cipher;
1215 }
1216 else {
1217 return NULL;
1218 }
1219 }
1220 else {
1221 return wolfSSL_get_cipher_list(priority);
1222 }
1223 }
1224}
1225
1226
1227int wolfSSL_get_ciphers(char* buf, int len)
1228{
1229 const CipherSuiteInfo* ciphers = GetCipherNames();
1230 int ciphersSz = GetCipherNamesSize();
1231 int i;
1232
1233 if (buf == NULL || len <= 0)
1234 return BAD_FUNC_ARG;
1235
1236 /* Add each member to the buffer delimited by a : */
1237 for (i = 0; i < ciphersSz; i++) {
1238 int cipherNameSz = (int)XSTRLEN(ciphers[i].name);
1239 if (cipherNameSz + 1 < len) {
1240 XSTRNCPY(buf, ciphers[i].name, (size_t)len);
1241 buf += cipherNameSz;
1242
1243 if (i < ciphersSz - 1)
1244 *buf++ = ':';
1245 *buf = 0;
1246
1247 len -= cipherNameSz + 1;
1248 }
1249 else
1250 return BUFFER_E;
1251 }
1252 return WOLFSSL_SUCCESS;
1253}
1254
1255
1256#ifndef NO_ERROR_STRINGS
1257/* places a list of all supported cipher suites in TLS_* format into "buf"
1258 * return WOLFSSL_SUCCESS on success */
1259int wolfSSL_get_ciphers_iana(char* buf, int len)
1260{
1261 const CipherSuiteInfo* ciphers = GetCipherNames();
1262 int ciphersSz = GetCipherNamesSize();
1263 int i;
1264 int cipherNameSz;
1265
1266 if (buf == NULL || len <= 0)
1267 return BAD_FUNC_ARG;
1268
1269 /* Add each member to the buffer delimited by a : */
1270 for (i = 0; i < ciphersSz; i++) {
1271#ifndef NO_CIPHER_SUITE_ALIASES
1272 if (ciphers[i].flags & WOLFSSL_CIPHER_SUITE_FLAG_NAMEALIAS)
1273 continue;
1274#endif
1275 cipherNameSz = (int)XSTRLEN(ciphers[i].name_iana);
1276 if (cipherNameSz + 1 < len) {
1277 XSTRNCPY(buf, ciphers[i].name_iana, (size_t)len);
1278 buf += cipherNameSz;
1279
1280 if (i < ciphersSz - 1)
1281 *buf++ = ':';
1282 *buf = 0;
1283
1284 len -= cipherNameSz + 1;
1285 }
1286 else
1287 return BUFFER_E;
1288 }
1289 return WOLFSSL_SUCCESS;
1290}
1291#endif /* NO_ERROR_STRINGS */
1292
1293
1294const char* wolfSSL_get_shared_ciphers(WOLFSSL* ssl, char* buf, int len)
1295{
1296 const char* cipher;
1297
1298 if (ssl == NULL || len <= 0)
1299 return NULL;
1300
1301 cipher = wolfSSL_get_cipher_name_iana(ssl);
1302 len = (int)min((word32)len, (word32)(XSTRLEN(cipher) + 1));
1303 XMEMCPY(buf, cipher, (size_t)len);
1304 return buf;
1305}
1306
1307int wolfSSL_get_fd(const WOLFSSL* ssl)
1308{
1309 int fd = -1;
1310 WOLFSSL_ENTER("wolfSSL_get_fd");
1311 if (ssl) {
1312 fd = ssl->rfd;
1313 }
1314 WOLFSSL_LEAVE("wolfSSL_get_fd", fd);
1315 return fd;
1316}
1317
1318int wolfSSL_get_wfd(const WOLFSSL* ssl)
1319{
1320 int fd = -1;
1321 WOLFSSL_ENTER("wolfSSL_get_fd");
1322 if (ssl) {
1323 fd = ssl->wfd;
1324 }
1325 WOLFSSL_LEAVE("wolfSSL_get_fd", fd);
1326 return fd;
1327}
1328
1329
1330int wolfSSL_dtls(WOLFSSL* ssl)
1331{
1332 int dtlsOpt = 0;
1333 if (ssl)
1334 dtlsOpt = ssl->options.dtls;
1335 return dtlsOpt;
1336}
1337
1338#ifdef WOLFSSL_WOLFSENTRY_HOOKS
1339
1340int wolfSSL_CTX_set_AcceptFilter(
1341 WOLFSSL_CTX *ctx,
1342 NetworkFilterCallback_t AcceptFilter,
1343 void *AcceptFilter_arg)
1344{
1345 if (ctx == NULL)
1346 return BAD_FUNC_ARG;
1347 ctx->AcceptFilter = AcceptFilter;
1348 ctx->AcceptFilter_arg = AcceptFilter_arg;
1349 return 0;
1350}
1351
1352int wolfSSL_set_AcceptFilter(
1353 WOLFSSL *ssl,
1354 NetworkFilterCallback_t AcceptFilter,
1355 void *AcceptFilter_arg)
1356{
1357 if (ssl == NULL)
1358 return BAD_FUNC_ARG;
1359 ssl->AcceptFilter = AcceptFilter;
1360 ssl->AcceptFilter_arg = AcceptFilter_arg;
1361 return 0;
1362}
1363
1364int wolfSSL_CTX_set_ConnectFilter(
1365 WOLFSSL_CTX *ctx,
1366 NetworkFilterCallback_t ConnectFilter,
1367 void *ConnectFilter_arg)
1368{
1369 if (ctx == NULL)
1370 return BAD_FUNC_ARG;
1371 ctx->ConnectFilter = ConnectFilter;
1372 ctx->ConnectFilter_arg = ConnectFilter_arg;
1373 return 0;
1374}
1375
1376int wolfSSL_set_ConnectFilter(
1377 WOLFSSL *ssl,
1378 NetworkFilterCallback_t ConnectFilter,
1379 void *ConnectFilter_arg)
1380{
1381 if (ssl == NULL)
1382 return BAD_FUNC_ARG;
1383 ssl->ConnectFilter = ConnectFilter;
1384 ssl->ConnectFilter_arg = ConnectFilter_arg;
1385 return 0;
1386}
1387
1388#endif /* WOLFSSL_WOLFSENTRY_HOOKS */
1389
1390#ifndef WOLFSSL_LEANPSK
1391#if defined(WOLFSSL_DTLS) && defined(XINET_PTON) && \
1392 !defined(WOLFSSL_NO_SOCK) && defined(HAVE_SOCKADDR)
1393void* wolfSSL_dtls_create_peer(int port, char* ip)
1394{
1395 SOCKADDR_IN *addr;
1396 addr = (SOCKADDR_IN*)XMALLOC(sizeof(*addr), NULL,
1397 DYNAMIC_TYPE_SOCKADDR);
1398 if (addr == NULL) {
1399 return NULL;
1400 }
1401
1402 addr->sin_family = AF_INET;
1403 addr->sin_port = XHTONS((word16)port);
1404 if (XINET_PTON(AF_INET, ip, &addr->sin_addr) < 1) {
1405 XFREE(addr, NULL, DYNAMIC_TYPE_SOCKADDR);
1406 return NULL;
1407 }
1408
1409 return addr;
1410}
1411
1412int wolfSSL_dtls_free_peer(void* addr)
1413{
1414 XFREE(addr, NULL, DYNAMIC_TYPE_SOCKADDR);
1415 return WOLFSSL_SUCCESS;
1416}
1417#endif
1418
1419#ifdef WOLFSSL_DTLS
1420static int SockAddrSet(WOLFSSL_SOCKADDR* sockAddr, void* peer,
1421 unsigned int peerSz, void* heap)
1422{
1423 if (peer == NULL || peerSz == 0) {
1424 if (sockAddr->sa != NULL)
1425 XFREE(sockAddr->sa, heap, DYNAMIC_TYPE_SOCKADDR);
1426 sockAddr->sa = NULL;
1427 sockAddr->sz = 0;
1428 sockAddr->bufSz = 0;
1429 return WOLFSSL_SUCCESS;
1430 }
1431
1432 if (peerSz > sockAddr->bufSz) {
1433 if (sockAddr->sa != NULL)
1434 XFREE(sockAddr->sa, heap, DYNAMIC_TYPE_SOCKADDR);
1435 sockAddr->sa =
1436 (void*)XMALLOC(peerSz, heap, DYNAMIC_TYPE_SOCKADDR);
1437 if (sockAddr->sa == NULL) {
1438 sockAddr->sz = 0;
1439 sockAddr->bufSz = 0;
1440 return WOLFSSL_FAILURE;
1441 }
1442 sockAddr->bufSz = peerSz;
1443 }
1444 XMEMCPY(sockAddr->sa, peer, peerSz);
1445 sockAddr->sz = peerSz;
1446 return WOLFSSL_SUCCESS;
1447}
1448#endif
1449
1450int wolfSSL_dtls_set_peer(WOLFSSL* ssl, void* peer, unsigned int peerSz)
1451{
1452#ifdef WOLFSSL_DTLS
1453 int ret;
1454
1455 if (ssl == NULL)
1456 return WOLFSSL_FAILURE;
1457#ifdef WOLFSSL_RW_THREADED
1458 if (wc_LockRwLock_Wr(&ssl->buffers.dtlsCtx.peerLock) != 0)
1459 return WOLFSSL_FAILURE;
1460#endif
1461 ret = SockAddrSet(&ssl->buffers.dtlsCtx.peer, peer, peerSz, ssl->heap);
1462 if (ret == WOLFSSL_SUCCESS && !(peer == NULL || peerSz == 0))
1463 ssl->buffers.dtlsCtx.userSet = 1;
1464 else
1465 ssl->buffers.dtlsCtx.userSet = 0;
1466#ifdef WOLFSSL_RW_THREADED
1467 if (wc_UnLockRwLock(&ssl->buffers.dtlsCtx.peerLock) != 0)
1468 ret = WOLFSSL_FAILURE;
1469#endif
1470 return ret;
1471#else
1472 (void)ssl;
1473 (void)peer;
1474 (void)peerSz;
1475 return WOLFSSL_NOT_IMPLEMENTED;
1476#endif
1477}
1478
1479#if defined(WOLFSSL_DTLS_CID) && !defined(WOLFSSL_NO_SOCK)
1480int wolfSSL_dtls_set_pending_peer(WOLFSSL* ssl, void* peer, unsigned int peerSz)
1481{
1482#ifdef WOLFSSL_DTLS
1483 int ret = WC_NO_ERR_TRACE(WOLFSSL_FAILURE);
1484
1485 if (ssl == NULL)
1486 return WOLFSSL_FAILURE;
1487#ifdef WOLFSSL_RW_THREADED
1488 if (wc_LockRwLock_Rd(&ssl->buffers.dtlsCtx.peerLock) != 0)
1489 return WOLFSSL_FAILURE;
1490#endif
1491 if (ssl->buffers.dtlsCtx.peer.sa != NULL &&
1492 ssl->buffers.dtlsCtx.peer.sz == peerSz &&
1493 sockAddrEqual((SOCKADDR_S*)ssl->buffers.dtlsCtx.peer.sa,
1494 (XSOCKLENT)ssl->buffers.dtlsCtx.peer.sz, (SOCKADDR_S*)peer,
1495 (XSOCKLENT)peerSz)) {
1496 /* Already the current peer. */
1497 if (ssl->buffers.dtlsCtx.pendingPeer.sa != NULL) {
1498 /* Clear any other pendingPeer */
1499 XFREE(ssl->buffers.dtlsCtx.pendingPeer.sa, ssl->heap,
1500 DYNAMIC_TYPE_SOCKADDR);
1501 ssl->buffers.dtlsCtx.pendingPeer.sa = NULL;
1502 ssl->buffers.dtlsCtx.pendingPeer.sz = 0;
1503 ssl->buffers.dtlsCtx.pendingPeer.bufSz = 0;
1504 }
1505 ret = WOLFSSL_SUCCESS;
1506 }
1507 else {
1508 ret = SockAddrSet(&ssl->buffers.dtlsCtx.pendingPeer, peer, peerSz,
1509 ssl->heap);
1510 }
1511 if (ret == WOLFSSL_SUCCESS)
1512 ssl->buffers.dtlsCtx.processingPendingRecord = 0;
1513#ifdef WOLFSSL_RW_THREADED
1514 if (wc_UnLockRwLock(&ssl->buffers.dtlsCtx.peerLock) != 0)
1515 ret = WOLFSSL_FAILURE;
1516#endif
1517 return ret;
1518#else
1519 (void)ssl;
1520 (void)peer;
1521 (void)peerSz;
1522 return WOLFSSL_NOT_IMPLEMENTED;
1523#endif
1524}
1525#endif /* WOLFSSL_DTLS_CID && !WOLFSSL_NO_SOCK */
1526
1527int wolfSSL_dtls_get_peer(WOLFSSL* ssl, void* peer, unsigned int* peerSz)
1528{
1529#ifdef WOLFSSL_DTLS
1530 int ret = WC_NO_ERR_TRACE(WOLFSSL_FAILURE);
1531 if (ssl == NULL)
1532 return WOLFSSL_FAILURE;
1533#ifdef WOLFSSL_RW_THREADED
1534 if (wc_LockRwLock_Rd(&ssl->buffers.dtlsCtx.peerLock) != 0)
1535 return WOLFSSL_FAILURE;
1536#endif
1537 if (peer != NULL && peerSz != NULL
1538 && *peerSz >= ssl->buffers.dtlsCtx.peer.sz
1539 && ssl->buffers.dtlsCtx.peer.sa != NULL) {
1540 *peerSz = ssl->buffers.dtlsCtx.peer.sz;
1541 XMEMCPY(peer, ssl->buffers.dtlsCtx.peer.sa, *peerSz);
1542 ret = WOLFSSL_SUCCESS;
1543 }
1544#ifdef WOLFSSL_RW_THREADED
1545 if (wc_UnLockRwLock(&ssl->buffers.dtlsCtx.peerLock) != 0)
1546 ret = WOLFSSL_FAILURE;
1547#endif
1548 return ret;
1549#else
1550 (void)ssl;
1551 (void)peer;
1552 (void)peerSz;
1553 return WOLFSSL_NOT_IMPLEMENTED;
1554#endif
1555}
1556
1557int wolfSSL_dtls_get0_peer(WOLFSSL* ssl, const void** peer,
1558 unsigned int* peerSz)
1559{
1560#if defined(WOLFSSL_DTLS) && !defined(WOLFSSL_RW_THREADED)
1561 if (ssl == NULL)
1562 return WOLFSSL_FAILURE;
1563
1564 if (peer == NULL || peerSz == NULL)
1565 return WOLFSSL_FAILURE;
1566
1567 *peer = ssl->buffers.dtlsCtx.peer.sa;
1568 *peerSz = ssl->buffers.dtlsCtx.peer.sz;
1569 return WOLFSSL_SUCCESS;
1570#else
1571 (void)ssl;
1572 (void)peer;
1573 (void)peerSz;
1574 return WOLFSSL_NOT_IMPLEMENTED;
1575#endif
1576}
1577
1578
1579#if defined(WOLFSSL_SCTP) && defined(WOLFSSL_DTLS)
1580
1581int wolfSSL_CTX_dtls_set_sctp(WOLFSSL_CTX* ctx)
1582{
1583 WOLFSSL_ENTER("wolfSSL_CTX_dtls_set_sctp");
1584
1585 if (ctx == NULL)
1586 return BAD_FUNC_ARG;
1587
1588 ctx->dtlsSctp = 1;
1589 return WOLFSSL_SUCCESS;
1590}
1591
1592
1593int wolfSSL_dtls_set_sctp(WOLFSSL* ssl)
1594{
1595 WOLFSSL_ENTER("wolfSSL_dtls_set_sctp");
1596
1597 if (ssl == NULL)
1598 return BAD_FUNC_ARG;
1599
1600 ssl->options.dtlsSctp = 1;
1601 return WOLFSSL_SUCCESS;
1602}
1603
1604#endif /* WOLFSSL_DTLS && WOLFSSL_SCTP */
1605
1606#if (defined(WOLFSSL_SCTP) || defined(WOLFSSL_DTLS_MTU)) && \
1607 defined(WOLFSSL_DTLS)
1608
1609int wolfSSL_CTX_dtls_set_mtu(WOLFSSL_CTX* ctx, word16 newMtu)
1610{
1611 if (ctx == NULL || newMtu > MAX_RECORD_SIZE)
1612 return BAD_FUNC_ARG;
1613
1614 ctx->dtlsMtuSz = newMtu;
1615 return WOLFSSL_SUCCESS;
1616}
1617
1618
1619int wolfSSL_dtls_set_mtu(WOLFSSL* ssl, word16 newMtu)
1620{
1621 if (ssl == NULL)
1622 return BAD_FUNC_ARG;
1623
1624 if (newMtu > MAX_RECORD_SIZE) {
1625 ssl->error = BAD_FUNC_ARG;
1626 return WOLFSSL_FAILURE;
1627 }
1628
1629 ssl->dtlsMtuSz = newMtu;
1630 return WOLFSSL_SUCCESS;
1631}
1632
1633#ifdef OPENSSL_EXTRA
1634/* Maps to compatibility API SSL_set_mtu and is same as wolfSSL_dtls_set_mtu,
1635 * but expects only success or failure returns. */
1636int wolfSSL_set_mtu_compat(WOLFSSL* ssl, unsigned short mtu)
1637{
1638 if (wolfSSL_dtls_set_mtu(ssl, mtu) == WOLFSSL_SUCCESS)
1639 return WOLFSSL_SUCCESS;
1640 else
1641 return WOLFSSL_FAILURE;
1642}
1643#endif /* OPENSSL_EXTRA */
1644
1645#endif /* WOLFSSL_DTLS && (WOLFSSL_SCTP || WOLFSSL_DTLS_MTU) */
1646
1647#ifdef WOLFSSL_SRTP
1648
1649static const WOLFSSL_SRTP_PROTECTION_PROFILE gSrtpProfiles[] = {
1650 /* AES CCM 128, Salt:112-bits, Auth HMAC-SHA1 Tag: 80-bits
1651 * (master_key:128bits + master_salt:112bits) * 2 = 480 bits (60) */
1652 {"SRTP_AES128_CM_SHA1_80", SRTP_AES128_CM_SHA1_80,
1653 (((128 + 112) * 2) / 8) },
1654 /* AES CCM 128, Salt:112-bits, Auth HMAC-SHA1 Tag: 32-bits
1655 * (master_key:128bits + master_salt:112bits) * 2 = 480 bits (60) */
1656 {"SRTP_AES128_CM_SHA1_32", SRTP_AES128_CM_SHA1_32,
1657 (((128 + 112) * 2) / 8) },
1658 /* NULL Cipher, Salt:112-bits, Auth HMAC-SHA1 Tag 80-bits */
1659 {"SRTP_NULL_SHA1_80", SRTP_NULL_SHA1_80, ((112 * 2) / 8)},
1660 /* NULL Cipher, Salt:112-bits, Auth HMAC-SHA1 Tag 32-bits */
1661 {"SRTP_NULL_SHA1_32", SRTP_NULL_SHA1_32, ((112 * 2) / 8)},
1662 /* AES GCM 128, Salt: 96-bits, Auth GCM Tag 128-bits
1663 * (master_key:128bits + master_salt:96bits) * 2 = 448 bits (56) */
1664 {"SRTP_AEAD_AES_128_GCM", SRTP_AEAD_AES_128_GCM, (((128 + 96) * 2) / 8) },
1665 /* AES GCM 256, Salt: 96-bits, Auth GCM Tag 128-bits
1666 * (master_key:256bits + master_salt:96bits) * 2 = 704 bits (88) */
1667 {"SRTP_AEAD_AES_256_GCM", SRTP_AEAD_AES_256_GCM, (((256 + 96) * 2) / 8) },
1668};
1669
1670static const WOLFSSL_SRTP_PROTECTION_PROFILE* DtlsSrtpFindProfile(
1671 const char* profile_str, word32 profile_str_len, unsigned long id)
1672{
1673 int i;
1674 const WOLFSSL_SRTP_PROTECTION_PROFILE* profile = NULL;
1675 for (i=0;
1676 i<(int)(sizeof(gSrtpProfiles)/sizeof(WOLFSSL_SRTP_PROTECTION_PROFILE));
1677 i++) {
1678 if (profile_str != NULL) {
1679 word32 srtp_profile_len = (word32)XSTRLEN(gSrtpProfiles[i].name);
1680 if (srtp_profile_len == profile_str_len &&
1681 XMEMCMP(gSrtpProfiles[i].name, profile_str, profile_str_len)
1682 == 0) {
1683 profile = &gSrtpProfiles[i];
1684 break;
1685 }
1686 }
1687 else if (id != 0 && gSrtpProfiles[i].id == id) {
1688 profile = &gSrtpProfiles[i];
1689 break;
1690 }
1691 }
1692 return profile;
1693}
1694
1695/* profile_str: accepts ":" colon separated list of SRTP profiles */
1696static int DtlsSrtpSelProfiles(word16* id, const char* profile_str)
1697{
1698 const WOLFSSL_SRTP_PROTECTION_PROFILE* profile;
1699 const char *current, *next = NULL;
1700 word32 length = 0, current_length;
1701
1702 *id = 0; /* reset destination ID's */
1703
1704 if (profile_str == NULL) {
1705 return WOLFSSL_FAILURE;
1706 }
1707
1708 /* loop on end of line or colon ":" */
1709 next = profile_str;
1710 length = (word32)XSTRLEN(profile_str);
1711 do {
1712 current = next;
1713 next = XSTRSTR(current, ":");
1714 if (next) {
1715 current_length = (word32)(next - current);
1716 ++next; /* ++ needed to skip ':' */
1717 } else {
1718 current_length = (word32)XSTRLEN(current);
1719 }
1720 if (current_length < length)
1721 length = current_length;
1722 profile = DtlsSrtpFindProfile(current, current_length, 0);
1723 if (profile != NULL) {
1724 *id |= (1 << profile->id); /* selected bit based on ID */
1725 }
1726 } while (next != NULL);
1727 return WOLFSSL_SUCCESS;
1728}
1729
1730/**
1731 * @brief Set the SRTP protection profiles for DTLS.
1732 *
1733 * @param ctx Pointer to the WOLFSSL_CTX structure representing the SSL/TLS
1734 * context.
1735 * @param profile_str A colon-separated string of SRTP profile names.
1736 * @return 0 on success to match OpenSSL
1737 * @return 1 on error to match OpenSSL
1738 */
1739int wolfSSL_CTX_set_tlsext_use_srtp(WOLFSSL_CTX* ctx, const char* profile_str)
1740{
1741 int ret = WC_NO_ERR_TRACE(WOLFSSL_FAILURE);
1742 if (ctx != NULL) {
1743 ret = DtlsSrtpSelProfiles(&ctx->dtlsSrtpProfiles, profile_str);
1744 }
1745
1746 if (ret == WC_NO_ERR_TRACE(WOLFSSL_FAILURE)) {
1747 ret = 1;
1748 } else {
1749 ret = 0;
1750 }
1751
1752 return ret;
1753}
1754
1755/**
1756 * @brief Set the SRTP protection profiles for DTLS.
1757 *
1758 * @param ssl Pointer to the WOLFSSL structure representing the SSL/TLS
1759 * session.
1760 * @param profile_str A colon-separated string of SRTP profile names.
1761 * @return 0 on success to match OpenSSL
1762 * @return 1 on error to match OpenSSL
1763 */
1764int wolfSSL_set_tlsext_use_srtp(WOLFSSL* ssl, const char* profile_str)
1765{
1766 int ret = WC_NO_ERR_TRACE(WOLFSSL_FAILURE);
1767 if (ssl != NULL) {
1768 ret = DtlsSrtpSelProfiles(&ssl->dtlsSrtpProfiles, profile_str);
1769 }
1770
1771 if (ret == WC_NO_ERR_TRACE(WOLFSSL_FAILURE)) {
1772 ret = 1;
1773 } else {
1774 ret = 0;
1775 }
1776
1777 return ret;
1778}
1779
1780const WOLFSSL_SRTP_PROTECTION_PROFILE* wolfSSL_get_selected_srtp_profile(
1781 WOLFSSL* ssl)
1782{
1783 const WOLFSSL_SRTP_PROTECTION_PROFILE* profile = NULL;
1784 if (ssl) {
1785 profile = DtlsSrtpFindProfile(NULL, 0, ssl->dtlsSrtpId);
1786 }
1787 return profile;
1788}
1789#ifndef NO_WOLFSSL_STUB
1790WOLF_STACK_OF(WOLFSSL_SRTP_PROTECTION_PROFILE)* wolfSSL_get_srtp_profiles(
1791 WOLFSSL* ssl)
1792{
1793 /* Not yet implemented - should return list of available SRTP profiles
1794 * ssl->dtlsSrtpProfiles */
1795 (void)ssl;
1796 return NULL;
1797}
1798#endif
1799
1800#define DTLS_SRTP_KEYING_MATERIAL_LABEL "EXTRACTOR-dtls_srtp"
1801
1802int wolfSSL_export_dtls_srtp_keying_material(WOLFSSL* ssl,
1803 unsigned char* out, size_t* olen)
1804{
1805 const WOLFSSL_SRTP_PROTECTION_PROFILE* profile = NULL;
1806
1807 if (ssl == NULL || olen == NULL) {
1808 return BAD_FUNC_ARG;
1809 }
1810
1811 profile = DtlsSrtpFindProfile(NULL, 0, ssl->dtlsSrtpId);
1812 if (profile == NULL) {
1813 WOLFSSL_MSG("Not using DTLS SRTP");
1814 return EXT_MISSING;
1815 }
1816 if (out == NULL) {
1817 *olen = (size_t)profile->kdfBits;
1818 return WC_NO_ERR_TRACE(LENGTH_ONLY_E);
1819 }
1820
1821 if (*olen < (size_t)profile->kdfBits) {
1822 return BUFFER_E;
1823 }
1824
1825 return wolfSSL_export_keying_material(ssl, out, (size_t)profile->kdfBits,
1826 DTLS_SRTP_KEYING_MATERIAL_LABEL,
1827 XSTR_SIZEOF(DTLS_SRTP_KEYING_MATERIAL_LABEL), NULL, 0, 0);
1828}
1829
1830#endif /* WOLFSSL_SRTP */
1831
1832
1833#ifdef WOLFSSL_DTLS_DROP_STATS
1834
1835int wolfSSL_dtls_get_drop_stats(WOLFSSL* ssl,
1836 word32* macDropCount, word32* replayDropCount)
1837{
1838 int ret;
1839
1840 WOLFSSL_ENTER("wolfSSL_dtls_get_drop_stats");
1841
1842 if (ssl == NULL)
1843 ret = BAD_FUNC_ARG;
1844 else {
1845 ret = WOLFSSL_SUCCESS;
1846 if (macDropCount != NULL)
1847 *macDropCount = ssl->macDropCount;
1848 if (replayDropCount != NULL)
1849 *replayDropCount = ssl->replayDropCount;
1850 }
1851
1852 WOLFSSL_LEAVE("wolfSSL_dtls_get_drop_stats", ret);
1853 return ret;
1854}
1855
1856#endif /* WOLFSSL_DTLS_DROP_STATS */
1857
1858
1859#if defined(WOLFSSL_MULTICAST)
1860
1861int wolfSSL_CTX_mcast_set_member_id(WOLFSSL_CTX* ctx, word16 id)
1862{
1863 int ret = 0;
1864
1865 WOLFSSL_ENTER("wolfSSL_CTX_mcast_set_member_id");
1866
1867 if (ctx == NULL || id > WOLFSSL_MAX_8BIT)
1868 ret = BAD_FUNC_ARG;
1869
1870 if (ret == 0) {
1871 ctx->haveEMS = 0;
1872 ctx->haveMcast = 1;
1873 ctx->mcastID = (byte)id;
1874#ifndef WOLFSSL_USER_IO
1875 ctx->CBIORecv = EmbedReceiveFromMcast;
1876#endif /* WOLFSSL_USER_IO */
1877
1878 ret = WOLFSSL_SUCCESS;
1879 }
1880 WOLFSSL_LEAVE("wolfSSL_CTX_mcast_set_member_id", ret);
1881 return ret;
1882}
1883
1884int wolfSSL_mcast_get_max_peers(void)
1885{
1886 return WOLFSSL_MULTICAST_PEERS;
1887}
1888
1889#ifdef WOLFSSL_DTLS
1890static WC_INLINE word32 UpdateHighwaterMark(word32 cur, word32 first,
1891 word32 second, word32 high)
1892{
1893 word32 newCur = 0;
1894
1895 if (cur < first)
1896 newCur = first;
1897 else if (cur < second)
1898 newCur = second;
1899 else if (cur < high)
1900 newCur = high;
1901
1902 return newCur;
1903}
1904#endif /* WOLFSSL_DTLS */
1905
1906
1907int wolfSSL_set_secret(WOLFSSL* ssl, word16 epoch,
1908 const byte* preMasterSecret, word32 preMasterSz,
1909 const byte* clientRandom, const byte* serverRandom,
1910 const byte* suite)
1911{
1912 int ret = 0;
1913
1914 WOLFSSL_ENTER("wolfSSL_set_secret");
1915
1916 if (ssl == NULL || preMasterSecret == NULL ||
1917 preMasterSz == 0 || preMasterSz > ENCRYPT_LEN ||
1918 clientRandom == NULL || serverRandom == NULL || suite == NULL) {
1919
1920 ret = BAD_FUNC_ARG;
1921 }
1922
1923 if (ret == 0 && ssl->arrays->preMasterSecret == NULL) {
1924 ssl->arrays->preMasterSz = ENCRYPT_LEN;
1925 ssl->arrays->preMasterSecret = (byte*)XMALLOC(ENCRYPT_LEN, ssl->heap,
1926 DYNAMIC_TYPE_SECRET);
1927 if (ssl->arrays->preMasterSecret == NULL) {
1928 ret = MEMORY_E;
1929 }
1930 }
1931
1932 if (ret == 0) {
1933 XMEMCPY(ssl->arrays->preMasterSecret, preMasterSecret, preMasterSz);
1934 XMEMSET(ssl->arrays->preMasterSecret + preMasterSz, 0,
1935 ENCRYPT_LEN - preMasterSz);
1936 ssl->arrays->preMasterSz = preMasterSz;
1937 XMEMCPY(ssl->arrays->clientRandom, clientRandom, RAN_LEN);
1938 XMEMCPY(ssl->arrays->serverRandom, serverRandom, RAN_LEN);
1939 ssl->options.cipherSuite0 = suite[0];
1940 ssl->options.cipherSuite = suite[1];
1941
1942 ret = SetCipherSpecs(ssl);
1943 }
1944
1945 if (ret == 0)
1946 ret = MakeTlsMasterSecret(ssl);
1947
1948 if (ret == 0) {
1949 ssl->keys.encryptionOn = 1;
1950 ret = SetKeysSide(ssl, ENCRYPT_AND_DECRYPT_SIDE);
1951 }
1952
1953 if (ret == 0) {
1954 if (ssl->options.dtls) {
1955 #ifdef WOLFSSL_DTLS
1956 WOLFSSL_DTLS_PEERSEQ* peerSeq;
1957 int i;
1958
1959 ssl->keys.dtls_epoch = epoch;
1960 for (i = 0, peerSeq = ssl->keys.peerSeq;
1961 i < WOLFSSL_DTLS_PEERSEQ_SZ;
1962 i++, peerSeq++) {
1963
1964 peerSeq->nextEpoch = epoch;
1965 peerSeq->prevSeq_lo = peerSeq->nextSeq_lo;
1966 peerSeq->prevSeq_hi = peerSeq->nextSeq_hi;
1967 peerSeq->nextSeq_lo = 0;
1968 peerSeq->nextSeq_hi = 0;
1969 XMEMCPY(peerSeq->prevWindow, peerSeq->window, DTLS_SEQ_SZ);
1970 XMEMSET(peerSeq->window, 0, DTLS_SEQ_SZ);
1971 peerSeq->highwaterMark = UpdateHighwaterMark(0,
1972 ssl->ctx->mcastFirstSeq,
1973 ssl->ctx->mcastSecondSeq,
1974 ssl->ctx->mcastMaxSeq);
1975 }
1976 #else
1977 (void)epoch;
1978 #endif
1979 }
1980 FreeHandshakeResources(ssl);
1981 ret = WOLFSSL_SUCCESS;
1982 }
1983 else {
1984 if (ssl)
1985 ssl->error = ret;
1986 ret = WOLFSSL_FATAL_ERROR;
1987 }
1988 WOLFSSL_LEAVE("wolfSSL_set_secret", ret);
1989 return ret;
1990}
1991
1992
1993#ifdef WOLFSSL_DTLS
1994
1995int wolfSSL_mcast_peer_add(WOLFSSL* ssl, word16 peerId, int sub)
1996{
1997 WOLFSSL_DTLS_PEERSEQ* p = NULL;
1998 int ret = WOLFSSL_SUCCESS;
1999 int i;
2000
2001 WOLFSSL_ENTER("wolfSSL_mcast_peer_add");
2002 if (ssl == NULL || peerId > WOLFSSL_MAX_8BIT)
2003 return BAD_FUNC_ARG;
2004
2005 if (!sub) {
2006 /* Make sure it isn't already present, while keeping the first
2007 * open spot. */
2008 for (i = 0; i < WOLFSSL_DTLS_PEERSEQ_SZ; i++) {
2009 if (ssl->keys.peerSeq[i].peerId == INVALID_PEER_ID)
2010 p = &ssl->keys.peerSeq[i];
2011 if (ssl->keys.peerSeq[i].peerId == peerId) {
2012 WOLFSSL_MSG("Peer ID already in multicast peer list.");
2013 p = NULL;
2014 }
2015 }
2016
2017 if (p != NULL) {
2018 XMEMSET(p, 0, sizeof(WOLFSSL_DTLS_PEERSEQ));
2019 p->peerId = peerId;
2020 p->highwaterMark = UpdateHighwaterMark(0,
2021 ssl->ctx->mcastFirstSeq,
2022 ssl->ctx->mcastSecondSeq,
2023 ssl->ctx->mcastMaxSeq);
2024 }
2025 else {
2026 WOLFSSL_MSG("No room in peer list.");
2027 ret = WOLFSSL_FATAL_ERROR;
2028 }
2029 }
2030 else {
2031 for (i = 0; i < WOLFSSL_DTLS_PEERSEQ_SZ; i++) {
2032 if (ssl->keys.peerSeq[i].peerId == peerId)
2033 p = &ssl->keys.peerSeq[i];
2034 }
2035
2036 if (p != NULL) {
2037 p->peerId = INVALID_PEER_ID;
2038 }
2039 else {
2040 WOLFSSL_MSG("Peer not found in list.");
2041 }
2042 }
2043
2044 WOLFSSL_LEAVE("wolfSSL_mcast_peer_add", ret);
2045 return ret;
2046}
2047
2048
2049/* If peerId is in the list of peers and its last sequence number is non-zero,
2050 * return 1, otherwise return 0. */
2051int wolfSSL_mcast_peer_known(WOLFSSL* ssl, unsigned short peerId)
2052{
2053 int known = 0;
2054 int i;
2055
2056 WOLFSSL_ENTER("wolfSSL_mcast_peer_known");
2057
2058 if (ssl == NULL || peerId > WOLFSSL_MAX_8BIT) {
2059 return BAD_FUNC_ARG;
2060 }
2061
2062 for (i = 0; i < WOLFSSL_DTLS_PEERSEQ_SZ; i++) {
2063 if (ssl->keys.peerSeq[i].peerId == peerId) {
2064 if (ssl->keys.peerSeq[i].nextSeq_hi ||
2065 ssl->keys.peerSeq[i].nextSeq_lo) {
2066
2067 known = 1;
2068 }
2069 break;
2070 }
2071 }
2072
2073 WOLFSSL_LEAVE("wolfSSL_mcast_peer_known", known);
2074 return known;
2075}
2076
2077
2078int wolfSSL_CTX_mcast_set_highwater_cb(WOLFSSL_CTX* ctx, word32 maxSeq,
2079 word32 first, word32 second,
2080 CallbackMcastHighwater cb)
2081{
2082 if (ctx == NULL || (second && first > second) ||
2083 first > maxSeq || second > maxSeq || cb == NULL) {
2084
2085 return BAD_FUNC_ARG;
2086 }
2087
2088 ctx->mcastHwCb = cb;
2089 ctx->mcastFirstSeq = first;
2090 ctx->mcastSecondSeq = second;
2091 ctx->mcastMaxSeq = maxSeq;
2092
2093 return WOLFSSL_SUCCESS;
2094}
2095
2096
2097int wolfSSL_mcast_set_highwater_ctx(WOLFSSL* ssl, void* ctx)
2098{
2099 if (ssl == NULL || ctx == NULL)
2100 return BAD_FUNC_ARG;
2101
2102 ssl->mcastHwCbCtx = ctx;
2103
2104 return WOLFSSL_SUCCESS;
2105}
2106
2107#endif /* WOLFSSL_DTLS */
2108
2109#endif /* WOLFSSL_MULTICAST */
2110
2111
2112#endif /* WOLFSSL_LEANPSK */
2113
2114#ifndef NO_TLS
2115/* return underlying connect or accept, WOLFSSL_SUCCESS on ok */
2116int wolfSSL_negotiate(WOLFSSL* ssl)
2117{
2118 int err = WC_NO_ERR_TRACE(WOLFSSL_FATAL_ERROR);
2119
2120 WOLFSSL_ENTER("wolfSSL_negotiate");
2121
2122 if (ssl == NULL)
2123 return WOLFSSL_FATAL_ERROR;
2124
2125#ifndef NO_WOLFSSL_SERVER
2126 if (ssl->options.side == WOLFSSL_SERVER_END) {
2127#ifdef WOLFSSL_TLS13
2128 if (IsAtLeastTLSv1_3(ssl->version))
2129 err = wolfSSL_accept_TLSv13(ssl);
2130 else
2131#endif
2132 err = wolfSSL_accept(ssl);
2133 }
2134#endif
2135
2136#ifndef NO_WOLFSSL_CLIENT
2137 if (ssl->options.side == WOLFSSL_CLIENT_END) {
2138#ifdef WOLFSSL_TLS13
2139 if (IsAtLeastTLSv1_3(ssl->version))
2140 err = wolfSSL_connect_TLSv13(ssl);
2141 else
2142#endif
2143 err = wolfSSL_connect(ssl);
2144 }
2145#endif
2146
2147 (void)ssl;
2148
2149 WOLFSSL_LEAVE("wolfSSL_negotiate", err);
2150
2151 return err;
2152}
2153#endif /* !NO_TLS */
2154
2155WOLFSSL_ABI
2156WC_RNG* wolfSSL_GetRNG(WOLFSSL* ssl)
2157{
2158 if (ssl) {
2159 return ssl->rng;
2160 }
2161
2162 return NULL;
2163}
2164
2165
2166#ifndef WOLFSSL_LEANPSK
2167/* object size based on build */
2168int wolfSSL_GetObjectSize(void)
2169{
2170#ifdef SHOW_SIZES
2171 printf("sizeof suites = %lu\n", (unsigned long)sizeof(Suites));
2172 printf("sizeof ciphers(2) = %lu\n", (unsigned long)sizeof(Ciphers));
2173#ifndef NO_RC4
2174 printf("\tsizeof arc4 = %lu\n", (unsigned long)sizeof(Arc4));
2175#endif
2176 printf("\tsizeof aes = %lu\n", (unsigned long)sizeof(Aes));
2177#ifndef NO_DES3
2178 printf("\tsizeof des3 = %lu\n", (unsigned long)sizeof(Des3));
2179#endif
2180#ifdef HAVE_CHACHA
2181 printf("\tsizeof chacha = %lu\n", (unsigned long)sizeof(ChaCha));
2182#endif
2183#ifdef WOLFSSL_SM4
2184 printf("\tsizeof sm4 = %lu\n", (unsigned long)sizeof(Sm4));
2185#endif
2186 printf("sizeof cipher specs = %lu\n", (unsigned long)
2187 sizeof(CipherSpecs));
2188 printf("sizeof keys = %lu\n", (unsigned long)sizeof(Keys));
2189 printf("sizeof Hashes(2) = %lu\n", (unsigned long)sizeof(Hashes));
2190#ifndef NO_MD5
2191 printf("\tsizeof MD5 = %lu\n", (unsigned long)sizeof(wc_Md5));
2192#endif
2193#ifndef NO_SHA
2194 printf("\tsizeof SHA = %lu\n", (unsigned long)sizeof(wc_Sha));
2195#endif
2196#ifdef WOLFSSL_SHA224
2197 printf("\tsizeof SHA224 = %lu\n", (unsigned long)sizeof(wc_Sha224));
2198#endif
2199#ifndef NO_SHA256
2200 printf("\tsizeof SHA256 = %lu\n", (unsigned long)sizeof(wc_Sha256));
2201#endif
2202#ifdef WOLFSSL_SHA384
2203 printf("\tsizeof SHA384 = %lu\n", (unsigned long)sizeof(wc_Sha384));
2204#endif
2205#ifdef WOLFSSL_SHA384
2206 printf("\tsizeof SHA512 = %lu\n", (unsigned long)sizeof(wc_Sha512));
2207#endif
2208#ifdef WOLFSSL_SM3
2209 printf("\tsizeof sm3 = %lu\n", (unsigned long)sizeof(Sm3));
2210#endif
2211 printf("sizeof Buffers = %lu\n", (unsigned long)sizeof(Buffers));
2212 printf("sizeof Options = %lu\n", (unsigned long)sizeof(Options));
2213 printf("sizeof Arrays = %lu\n", (unsigned long)sizeof(Arrays));
2214#ifndef NO_RSA
2215 printf("sizeof RsaKey = %lu\n", (unsigned long)sizeof(RsaKey));
2216#endif
2217#ifdef HAVE_ECC
2218 printf("sizeof ecc_key = %lu\n", (unsigned long)sizeof(ecc_key));
2219#endif
2220 printf("sizeof WOLFSSL_CIPHER = %lu\n", (unsigned long)
2221 sizeof(WOLFSSL_CIPHER));
2222 printf("sizeof WOLFSSL_SESSION = %lu\n", (unsigned long)
2223 sizeof(WOLFSSL_SESSION));
2224 printf("sizeof WOLFSSL = %lu\n", (unsigned long)sizeof(WOLFSSL));
2225 printf("sizeof WOLFSSL_CTX = %lu\n", (unsigned long)
2226 sizeof(WOLFSSL_CTX));
2227#endif
2228
2229 return sizeof(WOLFSSL);
2230}
2231
2232int wolfSSL_CTX_GetObjectSize(void)
2233{
2234 return sizeof(WOLFSSL_CTX);
2235}
2236
2237int wolfSSL_METHOD_GetObjectSize(void)
2238{
2239 return sizeof(WOLFSSL_METHOD);
2240}
2241#endif
2242
2243
2244#ifdef WOLFSSL_STATIC_MEMORY
2245
2246int wolfSSL_CTX_load_static_memory(WOLFSSL_CTX** ctx,
2247 wolfSSL_method_func method, unsigned char* buf, unsigned int sz, int flag,
2248 int maxSz)
2249{
2250 WOLFSSL_HEAP_HINT* hint = NULL;
2251
2252 if (ctx == NULL || buf == NULL) {
2253 return BAD_FUNC_ARG;
2254 }
2255
2256 if (*ctx == NULL && method == NULL) {
2257 return BAD_FUNC_ARG;
2258 }
2259
2260 /* If there is a heap already, capture it in hint. */
2261 if (*ctx && (*ctx)->heap != NULL) {
2262 hint = (*ctx)->heap;
2263 }
2264
2265 if (wc_LoadStaticMemory(&hint, buf, sz, flag, maxSz)) {
2266 WOLFSSL_MSG("Error loading static memory");
2267 return WOLFSSL_FAILURE;
2268 }
2269
2270 if (*ctx) {
2271 if ((*ctx)->heap == NULL) {
2272 (*ctx)->heap = (void*)hint;
2273 }
2274 }
2275 else {
2276 /* create ctx if needed */
2277 *ctx = wolfSSL_CTX_new_ex(method(hint), hint);
2278 if (*ctx == NULL) {
2279 WOLFSSL_MSG("Error creating ctx");
2280 return WOLFSSL_FAILURE;
2281 }
2282 }
2283
2284 return WOLFSSL_SUCCESS;
2285}
2286
2287
2288int wolfSSL_is_static_memory(WOLFSSL* ssl, WOLFSSL_MEM_CONN_STATS* mem_stats)
2289{
2290 if (ssl == NULL) {
2291 return BAD_FUNC_ARG;
2292 }
2293 WOLFSSL_ENTER("wolfSSL_is_static_memory");
2294
2295#ifndef WOLFSSL_STATIC_MEMORY_LEAN
2296 /* fill out statistics if wanted and WOLFMEM_TRACK_STATS flag */
2297 if (mem_stats != NULL && ssl->heap != NULL) {
2298 WOLFSSL_HEAP_HINT* hint = ((WOLFSSL_HEAP_HINT*)(ssl->heap));
2299 WOLFSSL_HEAP* heap = hint->memory;
2300 if (heap->flag & WOLFMEM_TRACK_STATS && hint->stats != NULL) {
2301 XMEMCPY(mem_stats, hint->stats, sizeof(WOLFSSL_MEM_CONN_STATS));
2302 }
2303 }
2304#endif
2305
2306 (void)mem_stats;
2307 return (ssl->heap) ? 1 : 0;
2308}
2309
2310
2311int wolfSSL_CTX_is_static_memory(WOLFSSL_CTX* ctx, WOLFSSL_MEM_STATS* mem_stats)
2312{
2313 if (ctx == NULL) {
2314 return BAD_FUNC_ARG;
2315 }
2316 WOLFSSL_ENTER("wolfSSL_CTX_is_static_memory");
2317
2318#ifndef WOLFSSL_STATIC_MEMORY_LEAN
2319 /* fill out statistics if wanted */
2320 if (mem_stats != NULL && ctx->heap != NULL) {
2321 WOLFSSL_HEAP* heap = ((WOLFSSL_HEAP_HINT*)(ctx->heap))->memory;
2322 if (wolfSSL_GetMemStats(heap, mem_stats) != 1) {
2323 return MEMORY_E;
2324 }
2325 }
2326#endif
2327
2328 (void)mem_stats;
2329 return (ctx->heap) ? 1 : 0;
2330}
2331
2332#endif /* WOLFSSL_STATIC_MEMORY */
2333
2334#ifndef NO_TLS
2335/* return max record layer size plaintext input size */
2336int wolfSSL_GetMaxOutputSize(WOLFSSL* ssl)
2337{
2338 WOLFSSL_ENTER("wolfSSL_GetMaxOutputSize");
2339
2340 if (ssl == NULL)
2341 return BAD_FUNC_ARG;
2342
2343 if (ssl->options.handShakeState != HANDSHAKE_DONE) {
2344 WOLFSSL_MSG("Handshake not complete yet");
2345 return BAD_FUNC_ARG;
2346 }
2347
2348 return min(OUTPUT_RECORD_SIZE, wolfssl_local_GetMaxPlaintextSize(ssl));
2349}
2350
2351
2352/* return record layer size of plaintext input size */
2353int wolfSSL_GetOutputSize(WOLFSSL* ssl, int inSz)
2354{
2355 int maxSize;
2356
2357 WOLFSSL_ENTER("wolfSSL_GetOutputSize");
2358
2359 if (inSz < 0)
2360 return BAD_FUNC_ARG;
2361
2362 maxSize = wolfSSL_GetMaxOutputSize(ssl);
2363 if (maxSize < 0)
2364 return maxSize; /* error */
2365 if (inSz > maxSize)
2366 return INPUT_SIZE_E;
2367
2368 return wolfssl_local_GetRecordSize(ssl, inSz, 1);
2369}
2370
2371
2372#ifdef HAVE_ECC
2373int wolfSSL_CTX_SetMinEccKey_Sz(WOLFSSL_CTX* ctx, short keySz)
2374{
2375 short keySzBytes;
2376
2377 WOLFSSL_ENTER("wolfSSL_CTX_SetMinEccKey_Sz");
2378 if (ctx == NULL || keySz < 0) {
2379 WOLFSSL_MSG("Key size must be positive value or ctx was null");
2380 return BAD_FUNC_ARG;
2381 }
2382
2383 if (keySz % 8 == 0) {
2384 keySzBytes = keySz / 8;
2385 }
2386 else {
2387 keySzBytes = (keySz / 8) + 1;
2388 }
2389
2390#if defined(WOLFSSL_SYS_CRYPTO_POLICY)
2391 if (crypto_policy.enabled) {
2392 if (ctx->minEccKeySz > (keySzBytes)) {
2393 return CRYPTO_POLICY_FORBIDDEN;
2394 }
2395 }
2396#endif /* WOLFSSL_SYS_CRYPTO_POLICY */
2397
2398 ctx->minEccKeySz = keySzBytes;
2399#ifndef NO_CERTS
2400 ctx->cm->minEccKeySz = keySzBytes;
2401#endif
2402 return WOLFSSL_SUCCESS;
2403}
2404
2405
2406int wolfSSL_SetMinEccKey_Sz(WOLFSSL* ssl, short keySz)
2407{
2408 short keySzBytes;
2409
2410 WOLFSSL_ENTER("wolfSSL_SetMinEccKey_Sz");
2411 if (ssl == NULL || keySz < 0) {
2412 WOLFSSL_MSG("Key size must be positive value or ctx was null");
2413 return BAD_FUNC_ARG;
2414 }
2415
2416 if (keySz % 8 == 0) {
2417 keySzBytes = keySz / 8;
2418 }
2419 else {
2420 keySzBytes = (keySz / 8) + 1;
2421 }
2422
2423#if defined(WOLFSSL_SYS_CRYPTO_POLICY)
2424 if (crypto_policy.enabled) {
2425 if (ssl->options.minEccKeySz > (keySzBytes)) {
2426 return CRYPTO_POLICY_FORBIDDEN;
2427 }
2428 }
2429#endif /* WOLFSSL_SYS_CRYPTO_POLICY */
2430
2431 ssl->options.minEccKeySz = keySzBytes;
2432 return WOLFSSL_SUCCESS;
2433}
2434
2435#endif /* HAVE_ECC */
2436
2437#ifndef NO_RSA
2438int wolfSSL_CTX_SetMinRsaKey_Sz(WOLFSSL_CTX* ctx, short keySz)
2439{
2440 if (ctx == NULL || keySz < 0 || keySz % 8 != 0) {
2441 WOLFSSL_MSG("Key size must be divisible by 8 or ctx was null");
2442 return BAD_FUNC_ARG;
2443 }
2444
2445#if defined(WOLFSSL_SYS_CRYPTO_POLICY)
2446 if (crypto_policy.enabled) {
2447 if (ctx->minRsaKeySz > (keySz / 8)) {
2448 return CRYPTO_POLICY_FORBIDDEN;
2449 }
2450 }
2451#endif /* WOLFSSL_SYS_CRYPTO_POLICY */
2452
2453 ctx->minRsaKeySz = keySz / 8;
2454 ctx->cm->minRsaKeySz = keySz / 8;
2455 return WOLFSSL_SUCCESS;
2456}
2457
2458
2459int wolfSSL_SetMinRsaKey_Sz(WOLFSSL* ssl, short keySz)
2460{
2461 if (ssl == NULL || keySz < 0 || keySz % 8 != 0) {
2462 WOLFSSL_MSG("Key size must be divisible by 8 or ssl was null");
2463 return BAD_FUNC_ARG;
2464 }
2465
2466#if defined(WOLFSSL_SYS_CRYPTO_POLICY)
2467 if (crypto_policy.enabled) {
2468 if (ssl->options.minRsaKeySz > (keySz / 8)) {
2469 return CRYPTO_POLICY_FORBIDDEN;
2470 }
2471 }
2472#endif /* WOLFSSL_SYS_CRYPTO_POLICY */
2473
2474 ssl->options.minRsaKeySz = keySz / 8;
2475 return WOLFSSL_SUCCESS;
2476}
2477#endif /* !NO_RSA */
2478
2479#ifndef NO_DH
2480
2481#if !defined(WOLFSSL_OLD_PRIME_CHECK) && !defined(HAVE_FIPS) && \
2482 !defined(HAVE_SELFTEST)
2483/* Enables or disables the session's DH key prime test. */
2484int wolfSSL_SetEnableDhKeyTest(WOLFSSL* ssl, int enable)
2485{
2486 WOLFSSL_ENTER("wolfSSL_SetEnableDhKeyTest");
2487
2488 if (ssl == NULL)
2489 return BAD_FUNC_ARG;
2490
2491 if (!enable)
2492 ssl->options.dhDoKeyTest = 0;
2493 else
2494 ssl->options.dhDoKeyTest = 1;
2495
2496 WOLFSSL_LEAVE("wolfSSL_SetEnableDhKeyTest", WOLFSSL_SUCCESS);
2497 return WOLFSSL_SUCCESS;
2498}
2499#endif
2500
2501int wolfSSL_CTX_SetMinDhKey_Sz(WOLFSSL_CTX* ctx, word16 keySz_bits)
2502{
2503 if (ctx == NULL || keySz_bits > 16000 || keySz_bits % 8 != 0)
2504 return BAD_FUNC_ARG;
2505
2506#if defined(WOLFSSL_SYS_CRYPTO_POLICY)
2507 if (crypto_policy.enabled) {
2508 if (ctx->minDhKeySz > (keySz_bits / 8)) {
2509 return CRYPTO_POLICY_FORBIDDEN;
2510 }
2511 }
2512#endif /* WOLFSSL_SYS_CRYPTO_POLICY */
2513
2514 ctx->minDhKeySz = keySz_bits / 8;
2515 return WOLFSSL_SUCCESS;
2516}
2517
2518
2519int wolfSSL_SetMinDhKey_Sz(WOLFSSL* ssl, word16 keySz_bits)
2520{
2521 if (ssl == NULL || keySz_bits > 16000 || keySz_bits % 8 != 0)
2522 return BAD_FUNC_ARG;
2523
2524#if defined(WOLFSSL_SYS_CRYPTO_POLICY)
2525 if (crypto_policy.enabled) {
2526 if (ssl->options.minDhKeySz > (keySz_bits / 8)) {
2527 return CRYPTO_POLICY_FORBIDDEN;
2528 }
2529 }
2530#endif /* WOLFSSL_SYS_CRYPTO_POLICY */
2531
2532 ssl->options.minDhKeySz = keySz_bits / 8;
2533 return WOLFSSL_SUCCESS;
2534}
2535
2536
2537int wolfSSL_CTX_SetMaxDhKey_Sz(WOLFSSL_CTX* ctx, word16 keySz_bits)
2538{
2539 if (ctx == NULL || keySz_bits > 16000 || keySz_bits % 8 != 0)
2540 return BAD_FUNC_ARG;
2541
2542#if defined(WOLFSSL_SYS_CRYPTO_POLICY)
2543 if (crypto_policy.enabled) {
2544 if (ctx->minDhKeySz > (keySz_bits / 8)) {
2545 return CRYPTO_POLICY_FORBIDDEN;
2546 }
2547 }
2548#endif /* WOLFSSL_SYS_CRYPTO_POLICY */
2549
2550 ctx->maxDhKeySz = keySz_bits / 8;
2551 return WOLFSSL_SUCCESS;
2552}
2553
2554
2555int wolfSSL_SetMaxDhKey_Sz(WOLFSSL* ssl, word16 keySz_bits)
2556{
2557 if (ssl == NULL || keySz_bits > 16000 || keySz_bits % 8 != 0)
2558 return BAD_FUNC_ARG;
2559
2560#if defined(WOLFSSL_SYS_CRYPTO_POLICY)
2561 if (crypto_policy.enabled) {
2562 if (ssl->options.minDhKeySz > (keySz_bits / 8)) {
2563 return CRYPTO_POLICY_FORBIDDEN;
2564 }
2565 }
2566#endif /* WOLFSSL_SYS_CRYPTO_POLICY */
2567
2568 ssl->options.maxDhKeySz = keySz_bits / 8;
2569 return WOLFSSL_SUCCESS;
2570}
2571
2572
2573int wolfSSL_GetDhKey_Sz(WOLFSSL* ssl)
2574{
2575 if (ssl == NULL)
2576 return BAD_FUNC_ARG;
2577
2578 return (ssl->options.dhKeySz * 8);
2579}
2580
2581#endif /* !NO_DH */
2582
2583
2584static int wolfSSL_write_internal(WOLFSSL* ssl, const void* data, size_t sz)
2585{
2586 int ret = 0;
2587
2588 WOLFSSL_ENTER("wolfSSL_write");
2589
2590 if (ssl == NULL || data == NULL)
2591 return BAD_FUNC_ARG;
2592
2593#ifdef WOLFSSL_QUIC
2594 if (WOLFSSL_IS_QUIC(ssl)) {
2595 WOLFSSL_MSG("SSL_write() on QUIC not allowed");
2596 return BAD_FUNC_ARG;
2597 }
2598#endif
2599
2600#ifdef HAVE_WRITE_DUP
2601 if (ssl->dupSide == READ_DUP_SIDE) {
2602 WOLFSSL_MSG("Read dup side cannot write");
2603 return WRITE_DUP_WRITE_E;
2604 }
2605 /* Only enter special dupWrite logic when error is cleared. This will help
2606 * with handling async data and other edge case errors. */
2607 if (ssl->dupWrite != NULL && ssl->error == 0) {
2608 int dupErr = 0; /* local copy */
2609 /* Lock ssl->dupWrite to gather what needs to be done. */
2610 if (wc_LockMutex(&ssl->dupWrite->dupMutex) != 0)
2611 return BAD_MUTEX_E;
2612 dupErr = ssl->dupWrite->dupErr;
2613#ifdef WOLFSSL_TLS13
2614 if (IsAtLeastTLSv1_3(ssl->version)) {
2615 /* TLS 1.3: if the read side received a KeyUpdate(update_requested)
2616 * it cannot respond; send the response from here. */
2617 ssl->keys.keyUpdateRespond |= ssl->dupWrite->keyUpdateRespond;
2618 ssl->dupWrite->keyUpdateRespond = 0;
2619#ifdef WOLFSSL_POST_HANDSHAKE_AUTH
2620 ssl->postHandshakeAuthPending |=
2621 ssl->dupWrite->postHandshakeAuthPending;
2622 ssl->dupWrite->postHandshakeAuthPending = 0;
2623 if (ssl->postHandshakeAuthPending) {
2624 /* Take ownership of the delegated auth state. */
2625 CertReqCtx** tail = &ssl->dupWrite->postHandshakeCertReqCtx;
2626 while (*tail != NULL)
2627 tail = &(*tail)->next;
2628 *tail = ssl->certReqCtx;
2629 ssl->certReqCtx = ssl->dupWrite->postHandshakeCertReqCtx;
2630 ssl->dupWrite->postHandshakeCertReqCtx = NULL;
2631 FreeHandshakeHashes(ssl);
2632 ssl->hsHashes = ssl->dupWrite->postHandshakeHashState;
2633 ssl->dupWrite->postHandshakeHashState = NULL;
2634 ssl->options.sendVerify = ssl->dupWrite->postHandshakeSendVerify;
2635 ssl->options.sigAlgo = ssl->dupWrite->postHandshakeSigAlgo;
2636 ssl->options.hashAlgo = ssl->dupWrite->postHandshakeHashAlgo;
2637 }
2638#endif /* WOLFSSL_POST_HANDSHAKE_AUTH */
2639#ifdef WOLFSSL_DTLS13
2640 if (ssl->options.dtls) {
2641 /* Schedule key update to be sent. */
2642 if (ssl->keys.keyUpdateRespond)
2643 ssl->dtls13DoKeyUpdate = 1;
2644
2645 /* Copy over ACKs */
2646 ssl->dtls13Rtx.sendAcks |= ssl->dupWrite->sendAcks;
2647 if (ssl->dupWrite->sendAcks) {
2648 /* Insert each record number so the
2649 * ACK message is properly ordered. */
2650 struct Dtls13RecordNumber* rn;
2651 for (rn = ssl->dupWrite->sendAckList; rn != NULL;
2652 rn = rn->next) {
2653 ret = Dtls13RtxAddAck(ssl, rn->epoch, rn->seq);
2654 if (ret != 0)
2655 break;
2656 }
2657 /* Clear only on success so no ACKs get dropped */
2658 if (ret == 0) {
2659 rn = ssl->dupWrite->sendAckList;
2660 ssl->dupWrite->sendAckList = NULL;
2661 ssl->dupWrite->sendAcks = 0;
2662 while (rn != NULL) {
2663 struct Dtls13RecordNumber* next = rn->next;
2664 XFREE(rn, ssl->heap, DYNAMIC_TYPE_DTLS_MSG);
2665 rn = next;
2666 }
2667 }
2668 }
2669
2670 /* Remove KeyUpdate record from RTX list. */
2671 if (ssl->dupWrite->keyUpdateAcked) {
2672 Dtls13RtxRemoveRecord(ssl, ssl->dupWrite->keyUpdateEpoch,
2673 ssl->dupWrite->keyUpdateSeq);
2674 }
2675 /* Store if KeyUpdate was ACKed. */
2676 ssl->dtls13KeyUpdateAcked |= ssl->dupWrite->keyUpdateAcked;
2677 ssl->dupWrite->keyUpdateAcked = 0;
2678 }
2679#endif /* WOLFSSL_DTLS13 */
2680 }
2681#endif /* WOLFSSL_TLS13 */
2682 wc_UnLockMutex(&ssl->dupWrite->dupMutex);
2683
2684 if (dupErr != 0) {
2685 WOLFSSL_MSG("Write dup error from other side");
2686 ssl->error = dupErr;
2687 return WOLFSSL_FATAL_ERROR;
2688 }
2689 if (ret != 0) {
2690 ssl->error = ret;
2691 return WOLFSSL_FATAL_ERROR;
2692 }
2693
2694
2695#ifdef WOLFSSL_TLS13
2696 if (IsAtLeastTLSv1_3(ssl->version)) {
2697#ifdef WOLFSSL_POST_HANDSHAKE_AUTH
2698 /* Read side received a CertificateRequest but couldn't write;
2699 * send Certificate+CertificateVerify+Finished from the write side. */
2700 if (ssl->postHandshakeAuthPending) {
2701 /* reset handshake states */
2702 ssl->postHandshakeAuthPending = 0;
2703 ssl->options.clientState = CLIENT_HELLO_COMPLETE;
2704 ssl->options.connectState = FIRST_REPLY_DONE;
2705 ssl->options.handShakeState = CLIENT_HELLO_COMPLETE;
2706 ssl->options.processReply = 0; /* doProcessInit */
2707 if (wolfSSL_connect_TLSv13(ssl) != WOLFSSL_SUCCESS) {
2708 if (ssl->error != WC_NO_ERR_TRACE(WANT_WRITE) &&
2709 ssl->error != WC_NO_ERR_TRACE(WC_PENDING_E)) {
2710 WOLFSSL_MSG("Post-handshake auth send failed");
2711 ssl->error = POST_HAND_AUTH_ERROR;
2712 }
2713 return WOLFSSL_FATAL_ERROR;
2714 }
2715 }
2716#endif /* WOLFSSL_POST_HANDSHAKE_AUTH */
2717#ifdef WOLFSSL_DTLS13
2718 if (ssl->options.dtls) {
2719 if (ssl->dtls13KeyUpdateAcked)
2720 ret = DoDtls13KeyUpdateAck(ssl);
2721 ssl->dtls13KeyUpdateAcked = 0;
2722 if (ret == 0)
2723 ret = Dtls13DoScheduledWork(ssl);
2724 }
2725 else
2726#endif /* WOLFSSL_DTLS13 */
2727 if (ssl->keys.keyUpdateRespond) /* cleared in SendTls13KeyUpdate */
2728 ret = Tls13UpdateKeys(ssl);
2729 if (ret != 0) {
2730 ssl->error = ret;
2731 return WOLFSSL_FATAL_ERROR;
2732 }
2733 /* WANT_WRITE is safe to clear. Data is buffered in output buffer
2734 * or in DTLS RTX queue */
2735 ret = 0;
2736 }
2737#endif /* WOLFSSL_TLS13 */
2738 }
2739#endif
2740
2741#ifdef HAVE_ERRNO_H
2742 errno = 0;
2743#endif
2744
2745 #ifdef OPENSSL_EXTRA
2746 if (ssl->CBIS != NULL) {
2747 ssl->CBIS(ssl, WOLFSSL_CB_WRITE, WOLFSSL_SUCCESS);
2748 ssl->cbmode = WOLFSSL_CB_WRITE;
2749 }
2750 #endif
2751 ret = SendData(ssl, data, sz);
2752
2753 WOLFSSL_LEAVE("wolfSSL_write", ret);
2754
2755 if (ret < 0)
2756 return WOLFSSL_FATAL_ERROR;
2757 else
2758 return ret;
2759}
2760
2761WOLFSSL_ABI
2762int wolfSSL_write(WOLFSSL* ssl, const void* data, int sz)
2763{
2764 WOLFSSL_ENTER("wolfSSL_write");
2765
2766 if (sz < 0)
2767 return BAD_FUNC_ARG;
2768
2769 return wolfSSL_write_internal(ssl, data, (size_t)sz);
2770}
2771
2772int wolfSSL_inject(WOLFSSL* ssl, const void* data, int sz)
2773{
2774 int maxLength;
2775 int usedLength;
2776
2777 WOLFSSL_ENTER("wolfSSL_inject");
2778
2779 if (ssl == NULL || data == NULL || sz <= 0)
2780 return BAD_FUNC_ARG;
2781
2782 usedLength = (int)(ssl->buffers.inputBuffer.length -
2783 ssl->buffers.inputBuffer.idx);
2784 maxLength = (int)(ssl->buffers.inputBuffer.bufferSize -
2785 (word32)usedLength);
2786
2787 if (sz > maxLength) {
2788 /* Need to make space */
2789 int ret;
2790 if (ssl->buffers.clearOutputBuffer.length > 0) {
2791 /* clearOutputBuffer points into so reallocating inputBuffer will
2792 * invalidate clearOutputBuffer and lose app data */
2793 WOLFSSL_MSG("Can't inject while there is application data to read");
2794 return APP_DATA_READY;
2795 }
2796 ret = GrowInputBuffer(ssl, sz, usedLength);
2797 if (ret < 0)
2798 return ret;
2799 }
2800
2801 XMEMCPY(ssl->buffers.inputBuffer.buffer + ssl->buffers.inputBuffer.idx,
2802 data, sz);
2803 ssl->buffers.inputBuffer.length += sz;
2804
2805 return WOLFSSL_SUCCESS;
2806}
2807
2808
2809int wolfSSL_write_ex(WOLFSSL* ssl, const void* data, size_t sz, size_t* wr)
2810{
2811 int ret;
2812
2813 if (wr != NULL) {
2814 *wr = 0;
2815 }
2816
2817 ret = wolfSSL_write_internal(ssl, data, sz);
2818 if (ret >= 0) {
2819 if (wr != NULL) {
2820 *wr = (size_t)ret;
2821 }
2822
2823 /* handle partial write cases, if not set then a partial write is
2824 * considered a failure case, or if set and ret is 0 then is a fail */
2825 if (ret == 0 && ssl->options.partialWrite) {
2826 ret = 0;
2827 }
2828 else if ((size_t)ret < sz && !ssl->options.partialWrite) {
2829 ret = 0;
2830 }
2831 else {
2832 /* wrote out all application data, or wrote out 1 byte or more with
2833 * partial write flag set */
2834 ret = 1;
2835 }
2836 }
2837 else {
2838 ret = 0;
2839 }
2840
2841 return ret;
2842}
2843
2844
2845static int wolfSSL_read_internal(WOLFSSL* ssl, void* data, size_t sz, int peek)
2846{
2847 int ret;
2848
2849 WOLFSSL_ENTER("wolfSSL_read_internal");
2850
2851 if (ssl == NULL || data == NULL)
2852 return BAD_FUNC_ARG;
2853
2854#ifdef WOLFSSL_QUIC
2855 if (WOLFSSL_IS_QUIC(ssl)) {
2856 WOLFSSL_MSG("SSL_read() on QUIC not allowed");
2857 return BAD_FUNC_ARG;
2858 }
2859#endif
2860#if defined(WOLFSSL_ERROR_CODE_OPENSSL) && defined(OPENSSL_EXTRA)
2861 /* This additional logic is meant to simulate following openSSL behavior:
2862 * After bidirectional SSL_shutdown complete, SSL_read returns 0 and
2863 * SSL_get_error_code returns SSL_ERROR_ZERO_RETURN.
2864 * This behavior is used to know the disconnect of the underlying
2865 * transport layer.
2866 *
2867 * In this logic, CBIORecv is called with a read size of 0 to check the
2868 * transport layer status. It also returns WOLFSSL_FAILURE so that
2869 * SSL_read does not return a positive number on failure.
2870 */
2871
2872 /* make sure bidirectional TLS shutdown completes */
2873 if (ssl->error == WOLFSSL_ERROR_SYSCALL || ssl->options.shutdownDone) {
2874 /* ask the underlying transport the connection is closed */
2875 if (ssl->CBIORecv(ssl, (char*)data, 0, ssl->IOCB_ReadCtx)
2876 == WC_NO_ERR_TRACE(WOLFSSL_CBIO_ERR_CONN_CLOSE))
2877 {
2878 ssl->options.isClosed = 1;
2879 ssl->error = WOLFSSL_ERROR_ZERO_RETURN;
2880 }
2881 return WOLFSSL_FAILURE;
2882 }
2883#endif
2884
2885#ifdef HAVE_WRITE_DUP
2886 if (ssl->dupWrite && ssl->dupSide == WRITE_DUP_SIDE) {
2887 WOLFSSL_MSG("Write dup side cannot read");
2888 return WRITE_DUP_READ_E;
2889 }
2890#endif
2891
2892#ifdef HAVE_ERRNO_H
2893 errno = 0;
2894#endif
2895
2896 ret = ReceiveData(ssl, (byte*)data, sz, peek);
2897
2898#ifdef HAVE_WRITE_DUP
2899 if (ssl->dupWrite) {
2900 if (ssl->error != 0 && ssl->error != WC_NO_ERR_TRACE(WANT_READ)
2901 #ifdef WOLFSSL_ASYNC_CRYPT
2902 && ssl->error != WC_NO_ERR_TRACE(WC_PENDING_E)
2903 #endif
2904 ) {
2905 int notifyErr;
2906
2907 WOLFSSL_MSG("Notifying write side of fatal read error");
2908 notifyErr = NotifyWriteSide(ssl, ssl->error);
2909 if (notifyErr < 0) {
2910 ret = ssl->error = notifyErr;
2911 }
2912 }
2913 }
2914#endif
2915
2916 WOLFSSL_LEAVE("wolfSSL_read_internal", ret);
2917
2918 if (ret < 0)
2919 return WOLFSSL_FATAL_ERROR;
2920 else
2921 return ret;
2922}
2923
2924
2925int wolfSSL_peek(WOLFSSL* ssl, void* data, int sz)
2926{
2927 WOLFSSL_ENTER("wolfSSL_peek");
2928
2929 if (sz < 0)
2930 return BAD_FUNC_ARG;
2931
2932 return wolfSSL_read_internal(ssl, data, (size_t)sz, TRUE);
2933}
2934
2935
2936WOLFSSL_ABI
2937int wolfSSL_read(WOLFSSL* ssl, void* data, int sz)
2938{
2939 WOLFSSL_ENTER("wolfSSL_read");
2940
2941 if (sz < 0)
2942 return BAD_FUNC_ARG;
2943
2944 #ifdef OPENSSL_EXTRA
2945 if (ssl == NULL) {
2946 return BAD_FUNC_ARG;
2947 }
2948 if (ssl->CBIS != NULL) {
2949 ssl->CBIS(ssl, WOLFSSL_CB_READ, WOLFSSL_SUCCESS);
2950 ssl->cbmode = WOLFSSL_CB_READ;
2951 }
2952 #endif
2953 return wolfSSL_read_internal(ssl, data, (size_t)sz, FALSE);
2954}
2955
2956
2957/* returns 0 on failure and 1 on read */
2958int wolfSSL_read_ex(WOLFSSL* ssl, void* data, size_t sz, size_t* rd)
2959{
2960 int ret;
2961
2962 #ifdef OPENSSL_EXTRA
2963 if (ssl == NULL) {
2964 return BAD_FUNC_ARG;
2965 }
2966 if (ssl->CBIS != NULL) {
2967 ssl->CBIS(ssl, WOLFSSL_CB_READ, WOLFSSL_SUCCESS);
2968 ssl->cbmode = WOLFSSL_CB_READ;
2969 }
2970 #endif
2971 ret = wolfSSL_read_internal(ssl, data, sz, FALSE);
2972
2973 if (ret > 0 && rd != NULL) {
2974 *rd = (size_t)ret;
2975 }
2976
2977 return ret > 0 ? 1 : 0;
2978}
2979
2980#ifdef WOLFSSL_MULTICAST
2981
2982int wolfSSL_mcast_read(WOLFSSL* ssl, word16* id, void* data, int sz)
2983{
2984 int ret = 0;
2985
2986 WOLFSSL_ENTER("wolfSSL_mcast_read");
2987
2988 if ((ssl == NULL) || (sz < 0))
2989 return BAD_FUNC_ARG;
2990
2991 ret = wolfSSL_read_internal(ssl, data, (size_t)sz, FALSE);
2992 if (ssl->options.dtls && ssl->options.haveMcast && id != NULL)
2993 *id = ssl->keys.curPeerId;
2994 return ret;
2995}
2996
2997#endif /* WOLFSSL_MULTICAST */
2998#endif /* !NO_TLS */
2999
3000/* helpers to set the device id, WOLFSSL_SUCCESS on ok */
3001WOLFSSL_ABI
3002int wolfSSL_SetDevId(WOLFSSL* ssl, int devId)
3003{
3004 if (ssl == NULL)
3005 return BAD_FUNC_ARG;
3006
3007 ssl->devId = devId;
3008
3009 return WOLFSSL_SUCCESS;
3010}
3011
3012WOLFSSL_ABI
3013int wolfSSL_CTX_SetDevId(WOLFSSL_CTX* ctx, int devId)
3014{
3015 if (ctx == NULL)
3016 return BAD_FUNC_ARG;
3017
3018 ctx->devId = devId;
3019
3020 return WOLFSSL_SUCCESS;
3021}
3022
3023/* helpers to get device id and heap */
3024WOLFSSL_ABI
3025int wolfSSL_CTX_GetDevId(WOLFSSL_CTX* ctx, WOLFSSL* ssl)
3026{
3027 int devId = INVALID_DEVID;
3028 if (ssl != NULL)
3029 devId = ssl->devId;
3030 if (ctx != NULL && devId == INVALID_DEVID)
3031 devId = ctx->devId;
3032 return devId;
3033}
3034void* wolfSSL_CTX_GetHeap(WOLFSSL_CTX* ctx, WOLFSSL* ssl)
3035{
3036 void* heap = NULL;
3037 if (ctx != NULL)
3038 heap = ctx->heap;
3039 else if (ssl != NULL)
3040 heap = ssl->heap;
3041 return heap;
3042}
3043
3044
3045#ifndef NO_TLS
3046#ifdef HAVE_SNI
3047
3048WOLFSSL_ABI
3049int wolfSSL_UseSNI(WOLFSSL* ssl, byte type, const void* data, word16 size)
3050{
3051 if (ssl == NULL)
3052 return BAD_FUNC_ARG;
3053
3054 return TLSX_UseSNI(&ssl->extensions, type, data, size, ssl->heap);
3055}
3056
3057
3058WOLFSSL_ABI
3059int wolfSSL_CTX_UseSNI(WOLFSSL_CTX* ctx, byte type, const void* data,
3060 word16 size)
3061{
3062 if (ctx == NULL)
3063 return BAD_FUNC_ARG;
3064
3065 return TLSX_UseSNI(&ctx->extensions, type, data, size, ctx->heap);
3066}
3067
3068#ifndef NO_WOLFSSL_SERVER
3069
3070void wolfSSL_SNI_SetOptions(WOLFSSL* ssl, byte type, byte options)
3071{
3072 if (ssl && ssl->extensions)
3073 TLSX_SNI_SetOptions(ssl->extensions, type, options);
3074}
3075
3076
3077void wolfSSL_CTX_SNI_SetOptions(WOLFSSL_CTX* ctx, byte type, byte options)
3078{
3079 if (ctx && ctx->extensions)
3080 TLSX_SNI_SetOptions(ctx->extensions, type, options);
3081}
3082
3083
3084byte wolfSSL_SNI_Status(WOLFSSL* ssl, byte type)
3085{
3086 return TLSX_SNI_Status(ssl ? ssl->extensions : NULL, type);
3087}
3088
3089
3090word16 wolfSSL_SNI_GetRequest(WOLFSSL* ssl, byte type, void** data)
3091{
3092 if (data)
3093 *data = NULL;
3094
3095 if (ssl && ssl->extensions)
3096 return TLSX_SNI_GetRequest(ssl->extensions, type, data, 0);
3097
3098 return 0;
3099}
3100
3101
3102int wolfSSL_SNI_GetFromBuffer(const byte* clientHello, word32 helloSz,
3103 byte type, byte* sni, word32* inOutSz)
3104{
3105 if (clientHello && helloSz > 0 && sni && inOutSz && *inOutSz > 0)
3106 return TLSX_SNI_GetFromBuffer(clientHello, helloSz, type, sni, inOutSz);
3107
3108 return BAD_FUNC_ARG;
3109}
3110
3111#endif /* !NO_WOLFSSL_SERVER */
3112
3113#endif /* HAVE_SNI */
3114
3115
3116#ifdef HAVE_TRUSTED_CA
3117
3118int wolfSSL_UseTrustedCA(WOLFSSL* ssl, byte type,
3119 const byte* certId, word32 certIdSz)
3120{
3121 if (ssl == NULL)
3122 return BAD_FUNC_ARG;
3123
3124 if (type == WOLFSSL_TRUSTED_CA_PRE_AGREED) {
3125 if (certId != NULL || certIdSz != 0)
3126 return BAD_FUNC_ARG;
3127 }
3128 else if (type == WOLFSSL_TRUSTED_CA_X509_NAME) {
3129 if (certId == NULL || certIdSz == 0)
3130 return BAD_FUNC_ARG;
3131 }
3132 #ifndef NO_SHA
3133 else if (type == WOLFSSL_TRUSTED_CA_KEY_SHA1 ||
3134 type == WOLFSSL_TRUSTED_CA_CERT_SHA1) {
3135 if (certId == NULL || certIdSz != WC_SHA_DIGEST_SIZE)
3136 return BAD_FUNC_ARG;
3137 }
3138 #endif
3139 else
3140 return BAD_FUNC_ARG;
3141
3142 return TLSX_UseTrustedCA(&ssl->extensions,
3143 type, certId, certIdSz, ssl->heap);
3144}
3145
3146#endif /* HAVE_TRUSTED_CA */
3147
3148
3149#ifdef HAVE_MAX_FRAGMENT
3150#ifndef NO_WOLFSSL_CLIENT
3151
3152int wolfSSL_UseMaxFragment(WOLFSSL* ssl, byte mfl)
3153{
3154 if (ssl == NULL)
3155 return BAD_FUNC_ARG;
3156
3157#ifdef WOLFSSL_ALLOW_MAX_FRAGMENT_ADJUST
3158 /* The following is a non-standard way to reconfigure the max packet size
3159 post-handshake for wolfSSL_write/wolfSSL_read */
3160 if (ssl->options.handShakeState == HANDSHAKE_DONE) {
3161 switch (mfl) {
3162 case WOLFSSL_MFL_2_8 : ssl->max_fragment = 256; break;
3163 case WOLFSSL_MFL_2_9 : ssl->max_fragment = 512; break;
3164 case WOLFSSL_MFL_2_10: ssl->max_fragment = 1024; break;
3165 case WOLFSSL_MFL_2_11: ssl->max_fragment = 2048; break;
3166 case WOLFSSL_MFL_2_12: ssl->max_fragment = 4096; break;
3167 case WOLFSSL_MFL_2_13: ssl->max_fragment = 8192; break;
3168 default: ssl->max_fragment = MAX_RECORD_SIZE; break;
3169 }
3170 return WOLFSSL_SUCCESS;
3171 }
3172#endif /* WOLFSSL_MAX_FRAGMENT_ADJUST */
3173
3174 /* This call sets the max fragment TLS extension, which gets sent to server.
3175 The server_hello response is what sets the `ssl->max_fragment` in
3176 TLSX_MFL_Parse */
3177 return TLSX_UseMaxFragment(&ssl->extensions, mfl, ssl->heap);
3178}
3179
3180
3181int wolfSSL_CTX_UseMaxFragment(WOLFSSL_CTX* ctx, byte mfl)
3182{
3183 if (ctx == NULL)
3184 return BAD_FUNC_ARG;
3185
3186 return TLSX_UseMaxFragment(&ctx->extensions, mfl, ctx->heap);
3187}
3188
3189#endif /* NO_WOLFSSL_CLIENT */
3190#endif /* HAVE_MAX_FRAGMENT */
3191
3192#ifdef HAVE_TRUNCATED_HMAC
3193#ifndef NO_WOLFSSL_CLIENT
3194
3195int wolfSSL_UseTruncatedHMAC(WOLFSSL* ssl)
3196{
3197 if (ssl == NULL)
3198 return BAD_FUNC_ARG;
3199
3200 return TLSX_UseTruncatedHMAC(&ssl->extensions, ssl->heap);
3201}
3202
3203
3204int wolfSSL_CTX_UseTruncatedHMAC(WOLFSSL_CTX* ctx)
3205{
3206 if (ctx == NULL)
3207 return BAD_FUNC_ARG;
3208
3209 return TLSX_UseTruncatedHMAC(&ctx->extensions, ctx->heap);
3210}
3211
3212#endif /* NO_WOLFSSL_CLIENT */
3213#endif /* HAVE_TRUNCATED_HMAC */
3214
3215/* Elliptic Curves */
3216#if defined(HAVE_SUPPORTED_CURVES)
3217
3218static int isValidCurveGroup(word16 name)
3219{
3220 switch (name) {
3221 case WOLFSSL_ECC_SECP160K1:
3222 case WOLFSSL_ECC_SECP160R1:
3223 case WOLFSSL_ECC_SECP160R2:
3224 case WOLFSSL_ECC_SECP192K1:
3225 case WOLFSSL_ECC_SECP192R1:
3226 case WOLFSSL_ECC_SECP224K1:
3227 case WOLFSSL_ECC_SECP224R1:
3228 case WOLFSSL_ECC_SECP256K1:
3229 case WOLFSSL_ECC_SECP256R1:
3230 case WOLFSSL_ECC_SECP384R1:
3231 case WOLFSSL_ECC_SECP521R1:
3232 case WOLFSSL_ECC_BRAINPOOLP256R1:
3233 case WOLFSSL_ECC_BRAINPOOLP384R1:
3234 case WOLFSSL_ECC_BRAINPOOLP512R1:
3235 case WOLFSSL_ECC_SM2P256V1:
3236 case WOLFSSL_ECC_X25519:
3237 case WOLFSSL_ECC_X448:
3238 case WOLFSSL_ECC_BRAINPOOLP256R1TLS13:
3239 case WOLFSSL_ECC_BRAINPOOLP384R1TLS13:
3240 case WOLFSSL_ECC_BRAINPOOLP512R1TLS13:
3241
3242 case WOLFSSL_FFDHE_2048:
3243 case WOLFSSL_FFDHE_3072:
3244 case WOLFSSL_FFDHE_4096:
3245 case WOLFSSL_FFDHE_6144:
3246 case WOLFSSL_FFDHE_8192:
3247
3248#ifdef WOLFSSL_HAVE_MLKEM
3249#ifndef WOLFSSL_NO_ML_KEM
3250 #ifndef WOLFSSL_TLS_NO_MLKEM_STANDALONE
3251 case WOLFSSL_ML_KEM_512:
3252 case WOLFSSL_ML_KEM_768:
3253 case WOLFSSL_ML_KEM_1024:
3254 #endif /* !WOLFSSL_TLS_NO_MLKEM_STANDALONE */
3255 #ifdef WOLFSSL_PQC_HYBRIDS
3256 case WOLFSSL_SECP384R1MLKEM1024:
3257 case WOLFSSL_X25519MLKEM768:
3258 case WOLFSSL_SECP256R1MLKEM768:
3259 #endif /* WOLFSSL_PQC_HYBRIDS */
3260 #ifdef WOLFSSL_EXTRA_PQC_HYBRIDS
3261 case WOLFSSL_SECP256R1MLKEM512:
3262 case WOLFSSL_SECP384R1MLKEM768:
3263 case WOLFSSL_SECP521R1MLKEM1024:
3264 case WOLFSSL_X25519MLKEM512:
3265 case WOLFSSL_X448MLKEM768:
3266 #endif /* WOLFSSL_EXTRA_PQC_HYBRIDS */
3267#endif /* !WOLFSSL_NO_ML_KEM */
3268#ifdef WOLFSSL_MLKEM_KYBER
3269 case WOLFSSL_KYBER_LEVEL1:
3270 case WOLFSSL_KYBER_LEVEL3:
3271 case WOLFSSL_KYBER_LEVEL5:
3272 case WOLFSSL_P256_KYBER_LEVEL1:
3273 case WOLFSSL_P384_KYBER_LEVEL3:
3274 case WOLFSSL_P521_KYBER_LEVEL5:
3275 case WOLFSSL_X25519_KYBER_LEVEL1:
3276 case WOLFSSL_X448_KYBER_LEVEL3:
3277 case WOLFSSL_X25519_KYBER_LEVEL3:
3278 case WOLFSSL_P256_KYBER_LEVEL3:
3279#endif /* WOLFSSL_MLKEM_KYBER */
3280#endif
3281 return 1;
3282
3283 default:
3284 return 0;
3285 }
3286}
3287
3288int wolfSSL_UseSupportedCurve(WOLFSSL* ssl, word16 name)
3289{
3290 if (ssl == NULL || !isValidCurveGroup(name))
3291 return BAD_FUNC_ARG;
3292
3293 ssl->options.userCurves = 1;
3294#if defined(NO_TLS)
3295 return WOLFSSL_FAILURE;
3296#else
3297 return TLSX_UseSupportedCurve(&ssl->extensions, name, ssl->heap);
3298#endif /* NO_TLS */
3299}
3300
3301
3302int wolfSSL_CTX_UseSupportedCurve(WOLFSSL_CTX* ctx, word16 name)
3303{
3304 if (ctx == NULL || !isValidCurveGroup(name))
3305 return BAD_FUNC_ARG;
3306
3307 ctx->userCurves = 1;
3308#if defined(NO_TLS)
3309 return WOLFSSL_FAILURE;
3310#else
3311 return TLSX_UseSupportedCurve(&ctx->extensions, name, ctx->heap);
3312#endif /* NO_TLS */
3313}
3314
3315#if defined(OPENSSL_EXTRA)
3316int wolfSSL_CTX_set1_groups(WOLFSSL_CTX* ctx, int* groups,
3317 int count)
3318{
3319 int i;
3320 int _groups[WOLFSSL_MAX_GROUP_COUNT];
3321 WOLFSSL_ENTER("wolfSSL_CTX_set1_groups");
3322 if (count == 0) {
3323 WOLFSSL_MSG("Group count is zero");
3324 return WOLFSSL_FAILURE;
3325 }
3326 if (count > WOLFSSL_MAX_GROUP_COUNT) {
3327 WOLFSSL_MSG("Group count exceeds maximum");
3328 return WOLFSSL_FAILURE;
3329 }
3330 for (i = 0; i < count; i++) {
3331 if (isValidCurveGroup((word16)groups[i])) {
3332 _groups[i] = groups[i];
3333 }
3334#ifdef HAVE_ECC
3335 else {
3336 /* groups may be populated with curve NIDs */
3337 int oid = (int)nid2oid(groups[i], oidCurveType);
3338 int name = (int)GetCurveByOID(oid);
3339 if (name == 0) {
3340 WOLFSSL_MSG("Invalid group name");
3341 return WOLFSSL_FAILURE;
3342 }
3343 _groups[i] = name;
3344 }
3345#else
3346 else {
3347 WOLFSSL_MSG("Invalid group name");
3348 return WOLFSSL_FAILURE;
3349 }
3350#endif
3351 }
3352 return wolfSSL_CTX_set_groups(ctx, _groups, count) == WOLFSSL_SUCCESS ?
3353 WOLFSSL_SUCCESS : WOLFSSL_FAILURE;
3354}
3355
3356int wolfSSL_set1_groups(WOLFSSL* ssl, int* groups, int count)
3357{
3358 int i;
3359 int _groups[WOLFSSL_MAX_GROUP_COUNT];
3360 WOLFSSL_ENTER("wolfSSL_CTX_set1_groups");
3361 if (count == 0) {
3362 WOLFSSL_MSG("Group count is zero");
3363 return WOLFSSL_FAILURE;
3364 }
3365 if (count > WOLFSSL_MAX_GROUP_COUNT) {
3366 WOLFSSL_MSG("Group count exceeds maximum");
3367 return WOLFSSL_FAILURE;
3368 }
3369 for (i = 0; i < count; i++) {
3370 if (isValidCurveGroup((word16)groups[i])) {
3371 _groups[i] = groups[i];
3372 }
3373#ifdef HAVE_ECC
3374 else {
3375 /* groups may be populated with curve NIDs */
3376 int oid = (int)nid2oid(groups[i], oidCurveType);
3377 int name = (int)GetCurveByOID(oid);
3378 if (name == 0) {
3379 WOLFSSL_MSG("Invalid group name");
3380 return WOLFSSL_FAILURE;
3381 }
3382 _groups[i] = name;
3383 }
3384#else
3385 else {
3386 WOLFSSL_MSG("Invalid group name");
3387 return WOLFSSL_FAILURE;
3388 }
3389#endif
3390 }
3391 return wolfSSL_set_groups(ssl, _groups, count) == WOLFSSL_SUCCESS ?
3392 WOLFSSL_SUCCESS : WOLFSSL_FAILURE;
3393}
3394#endif /* OPENSSL_EXTRA */
3395#endif /* HAVE_SUPPORTED_CURVES */
3396
3397/* Application-Layer Protocol Negotiation */
3398#ifdef HAVE_ALPN
3399
3400WOLFSSL_ABI
3401int wolfSSL_UseALPN(WOLFSSL* ssl, char *protocol_name_list,
3402 word32 protocol_name_listSz, byte options)
3403{
3404 char *list, *ptr = NULL, **token;
3405 word16 len;
3406 int idx = 0;
3407 int ret = WC_NO_ERR_TRACE(WOLFSSL_FAILURE);
3408
3409 WOLFSSL_ENTER("wolfSSL_UseALPN");
3410
3411 if (ssl == NULL || protocol_name_list == NULL)
3412 return BAD_FUNC_ARG;
3413
3414 if (protocol_name_listSz > (WOLFSSL_MAX_ALPN_NUMBER *
3415 WOLFSSL_MAX_ALPN_PROTO_NAME_LEN +
3416 WOLFSSL_MAX_ALPN_NUMBER)) {
3417 WOLFSSL_MSG("Invalid arguments, protocol name list too long");
3418 return BAD_FUNC_ARG;
3419 }
3420
3421 if (!(options & WOLFSSL_ALPN_CONTINUE_ON_MISMATCH) &&
3422 !(options & WOLFSSL_ALPN_FAILED_ON_MISMATCH)) {
3423 WOLFSSL_MSG("Invalid arguments, options not supported");
3424 return BAD_FUNC_ARG;
3425 }
3426
3427
3428 list = (char *)XMALLOC(protocol_name_listSz+1, ssl->heap,
3429 DYNAMIC_TYPE_ALPN);
3430 if (list == NULL) {
3431 WOLFSSL_MSG("Memory failure");
3432 return MEMORY_ERROR;
3433 }
3434
3435 token = (char **)XMALLOC(sizeof(char *) * (WOLFSSL_MAX_ALPN_NUMBER+1),
3436 ssl->heap, DYNAMIC_TYPE_ALPN);
3437 if (token == NULL) {
3438 XFREE(list, ssl->heap, DYNAMIC_TYPE_ALPN);
3439 WOLFSSL_MSG("Memory failure");
3440 return MEMORY_ERROR;
3441 }
3442 XMEMSET(token, 0, sizeof(char *) * (WOLFSSL_MAX_ALPN_NUMBER+1));
3443
3444 XSTRNCPY(list, protocol_name_list, protocol_name_listSz);
3445 list[protocol_name_listSz] = '\0';
3446
3447 /* read all protocol name from the list */
3448 token[idx] = XSTRTOK(list, ",", &ptr);
3449 while (idx < WOLFSSL_MAX_ALPN_NUMBER && token[idx] != NULL)
3450 token[++idx] = XSTRTOK(NULL, ",", &ptr);
3451
3452 /* add protocol name list in the TLS extension in reverse order */
3453 while ((idx--) > 0) {
3454 len = (word16)XSTRLEN(token[idx]);
3455
3456 ret = TLSX_UseALPN(&ssl->extensions, token[idx], len, options,
3457 ssl->heap);
3458 if (ret != WOLFSSL_SUCCESS) {
3459 WOLFSSL_MSG("TLSX_UseALPN failure");
3460 break;
3461 }
3462 }
3463
3464 XFREE(token, ssl->heap, DYNAMIC_TYPE_ALPN);
3465 XFREE(list, ssl->heap, DYNAMIC_TYPE_ALPN);
3466
3467 return ret;
3468}
3469
3470int wolfSSL_ALPN_GetProtocol(WOLFSSL* ssl, char **protocol_name, word16 *size)
3471{
3472 return TLSX_ALPN_GetRequest(ssl ? ssl->extensions : NULL,
3473 (void **)protocol_name, size);
3474}
3475
3476int wolfSSL_ALPN_GetPeerProtocol(WOLFSSL* ssl, char **list, word16 *listSz)
3477{
3478 int i, len;
3479 char *p;
3480 byte *s;
3481
3482 if (ssl == NULL || list == NULL || listSz == NULL)
3483 return BAD_FUNC_ARG;
3484
3485 if (ssl->alpn_peer_requested == NULL
3486 || ssl->alpn_peer_requested_length == 0)
3487 return BUFFER_ERROR;
3488
3489 /* ssl->alpn_peer_requested are the original bytes sent in a ClientHello,
3490 * formatted as (len-byte chars+)+. To turn n protocols into a
3491 * comma-separated C string, one needs (n-1) commas and a final 0 byte
3492 * which has the same length as the original.
3493 * The returned length is the strlen() of the C string, so -1 of that. */
3494 *listSz = ssl->alpn_peer_requested_length-1;
3495 *list = p = (char *)XMALLOC(ssl->alpn_peer_requested_length, ssl->heap,
3496 DYNAMIC_TYPE_TLSX);
3497 if (p == NULL)
3498 return MEMORY_ERROR;
3499
3500 for (i = 0, s = ssl->alpn_peer_requested;
3501 i < ssl->alpn_peer_requested_length;
3502 p += len, i += len)
3503 {
3504 if (i)
3505 *p++ = ',';
3506 len = s[i++];
3507 /* guard against bad length bytes. */
3508 if (i + len > ssl->alpn_peer_requested_length) {
3509 XFREE(*list, ssl->heap, DYNAMIC_TYPE_TLSX);
3510 *list = NULL;
3511 return WOLFSSL_FAILURE;
3512 }
3513 XMEMCPY(p, s + i, (size_t)len);
3514 }
3515 *p = 0;
3516
3517 return WOLFSSL_SUCCESS;
3518}
3519
3520
3521/* used to free memory allocated by wolfSSL_ALPN_GetPeerProtocol */
3522int wolfSSL_ALPN_FreePeerProtocol(WOLFSSL* ssl, char **list)
3523{
3524 if (ssl == NULL) {
3525 return BAD_FUNC_ARG;
3526 }
3527
3528 XFREE(*list, ssl->heap, DYNAMIC_TYPE_TLSX);
3529 *list = NULL;
3530
3531 return WOLFSSL_SUCCESS;
3532}
3533
3534#endif /* HAVE_ALPN */
3535
3536/* Secure Renegotiation */
3537#ifdef HAVE_SERVER_RENEGOTIATION_INFO
3538
3539/* user is forcing ability to use secure renegotiation, we discourage it */
3540int wolfSSL_UseSecureRenegotiation(WOLFSSL* ssl)
3541{
3542 int ret = WC_NO_ERR_TRACE(BAD_FUNC_ARG);
3543#if defined(NO_TLS)
3544 (void)ssl;
3545#else
3546 if (ssl)
3547 ret = TLSX_UseSecureRenegotiation(&ssl->extensions, ssl->heap);
3548 else
3549 ret = BAD_FUNC_ARG;
3550
3551 if (ret == WOLFSSL_SUCCESS) {
3552 TLSX* extension = TLSX_Find(ssl->extensions, TLSX_RENEGOTIATION_INFO);
3553
3554 if (extension)
3555 ssl->secure_renegotiation = (SecureRenegotiation*)extension->data;
3556 }
3557#endif /* !NO_TLS */
3558 return ret;
3559}
3560
3561int wolfSSL_CTX_UseSecureRenegotiation(WOLFSSL_CTX* ctx)
3562{
3563 if (ctx == NULL)
3564 return BAD_FUNC_ARG;
3565
3566 ctx->useSecureReneg = 1;
3567 return WOLFSSL_SUCCESS;
3568}
3569
3570#ifdef HAVE_SECURE_RENEGOTIATION
3571/* do a secure renegotiation handshake, user forced, we discourage */
3572static int _Rehandshake(WOLFSSL* ssl)
3573{
3574 int ret;
3575
3576 if (ssl == NULL)
3577 return BAD_FUNC_ARG;
3578
3579 if (IsAtLeastTLSv1_3(ssl->version)) {
3580 WOLFSSL_MSG("Secure Renegotiation not supported in TLS 1.3");
3581 return SECURE_RENEGOTIATION_E;
3582 }
3583
3584 if (ssl->secure_renegotiation == NULL) {
3585 WOLFSSL_MSG("Secure Renegotiation not forced on by user");
3586 return SECURE_RENEGOTIATION_E;
3587 }
3588
3589 if (ssl->secure_renegotiation->enabled == 0) {
3590 WOLFSSL_MSG("Secure Renegotiation not enabled at extension level");
3591 return SECURE_RENEGOTIATION_E;
3592 }
3593
3594#ifdef WOLFSSL_DTLS
3595 if (ssl->options.dtls && ssl->keys.dtls_epoch == 0xFFFF) {
3596 WOLFSSL_MSG("Secure Renegotiation not allowed. Epoch would wrap");
3597 return SECURE_RENEGOTIATION_E;
3598 }
3599#endif
3600
3601 /* If the client started the renegotiation, the server will already
3602 * have processed the client's hello. */
3603 if (ssl->options.side != WOLFSSL_SERVER_END ||
3604 ssl->options.acceptState != ACCEPT_FIRST_REPLY_DONE) {
3605
3606 if (ssl->options.handShakeState != HANDSHAKE_DONE) {
3607 if (!ssl->options.handShakeDone) {
3608 WOLFSSL_MSG("Can't renegotiate until initial "
3609 "handshake complete");
3610 return SECURE_RENEGOTIATION_E;
3611 }
3612 else {
3613 WOLFSSL_MSG("Renegotiation already started. "
3614 "Moving it forward.");
3615 ret = wolfSSL_negotiate(ssl);
3616 if (ret == WOLFSSL_SUCCESS)
3617 ssl->secure_rene_count++;
3618 return ret;
3619 }
3620 }
3621
3622 /* reset handshake states */
3623 ssl->options.sendVerify = 0;
3624 ssl->options.serverState = NULL_STATE;
3625 ssl->options.clientState = NULL_STATE;
3626 ssl->options.connectState = CONNECT_BEGIN;
3627 ssl->options.acceptState = ACCEPT_BEGIN_RENEG;
3628 ssl->options.handShakeState = NULL_STATE;
3629 ssl->options.processReply = 0; /* TODO, move states in internal.h */
3630
3631 XMEMSET(&ssl->msgsReceived, 0, sizeof(ssl->msgsReceived));
3632
3633 ssl->secure_renegotiation->cache_status = SCR_CACHE_NEEDED;
3634
3635#if !defined(NO_WOLFSSL_SERVER) && !defined(WOLFSSL_NO_TLS12)
3636 if (ssl->options.side == WOLFSSL_SERVER_END) {
3637 ret = SendHelloRequest(ssl);
3638 if (ret != 0) {
3639 ssl->error = ret;
3640 return WOLFSSL_FATAL_ERROR;
3641 }
3642 }
3643#endif /* !NO_WOLFSSL_SERVER && !WOLFSSL_NO_TLS12 */
3644
3645 ret = InitHandshakeHashes(ssl);
3646 if (ret != 0) {
3647 ssl->error = ret;
3648 return WOLFSSL_FATAL_ERROR;
3649 }
3650 }
3651 ret = wolfSSL_negotiate(ssl);
3652 if (ret == WOLFSSL_SUCCESS)
3653 ssl->secure_rene_count++;
3654 return ret;
3655}
3656
3657
3658/* do a secure renegotiation handshake, user forced, we discourage */
3659int wolfSSL_Rehandshake(WOLFSSL* ssl)
3660{
3661 int ret;
3662 WOLFSSL_ENTER("wolfSSL_Rehandshake");
3663
3664 if (ssl == NULL)
3665 return WOLFSSL_FAILURE;
3666
3667#ifdef HAVE_SESSION_TICKET
3668 ret = WOLFSSL_SUCCESS;
3669#endif
3670
3671 if (ssl->options.side == WOLFSSL_SERVER_END) {
3672 /* Reset option to send certificate verify. */
3673 ssl->options.sendVerify = 0;
3674 /* Reset resuming flag to do full secure handshake. */
3675 ssl->options.resuming = 0;
3676 }
3677 else {
3678 /* Reset resuming flag to do full secure handshake. */
3679 ssl->options.resuming = 0;
3680 #if defined(HAVE_SESSION_TICKET) && !defined(NO_WOLFSSL_CLIENT)
3681 /* Clearing the ticket. */
3682 ret = wolfSSL_UseSessionTicket(ssl);
3683 #endif
3684 }
3685 /* CLIENT/SERVER: Reset peer authentication for full secure handshake. */
3686 ssl->options.peerAuthGood = 0;
3687
3688#ifdef HAVE_SESSION_TICKET
3689 if (ret == WOLFSSL_SUCCESS)
3690#endif
3691 ret = _Rehandshake(ssl);
3692
3693 return ret;
3694}
3695
3696
3697#ifndef NO_WOLFSSL_CLIENT
3698
3699/* do a secure resumption handshake, user forced, we discourage */
3700int wolfSSL_SecureResume(WOLFSSL* ssl)
3701{
3702 WOLFSSL_ENTER("wolfSSL_SecureResume");
3703
3704 if (ssl == NULL)
3705 return BAD_FUNC_ARG;
3706
3707 if (ssl->options.side == WOLFSSL_SERVER_END) {
3708 ssl->error = SIDE_ERROR;
3709 return WOLFSSL_FATAL_ERROR;
3710 }
3711
3712 return _Rehandshake(ssl);
3713}
3714
3715#endif /* NO_WOLFSSL_CLIENT */
3716
3717#endif /* HAVE_SECURE_RENEGOTIATION */
3718
3719long wolfSSL_SSL_get_secure_renegotiation_support(WOLFSSL* ssl)
3720{
3721 WOLFSSL_ENTER("wolfSSL_SSL_get_secure_renegotiation_support");
3722
3723 if (!ssl || !ssl->secure_renegotiation)
3724 return WOLFSSL_FAILURE;
3725 return ssl->secure_renegotiation->enabled;
3726}
3727
3728#endif /* HAVE_SECURE_RENEGOTIATION_INFO */
3729
3730#if !defined(NO_WOLFSSL_CLIENT) && !defined(WOLFSSL_NO_TLS12) && \
3731 defined(WOLFSSL_HARDEN_TLS) && !defined(WOLFSSL_HARDEN_TLS_NO_SCR_CHECK)
3732WOLFSSL_API int wolfSSL_get_scr_check_enabled(const WOLFSSL* ssl)
3733{
3734 WOLFSSL_ENTER("wolfSSL_get_scr_check_enabled");
3735
3736 if (ssl == NULL)
3737 return BAD_FUNC_ARG;
3738
3739 return ssl->scr_check_enabled;
3740}
3741
3742WOLFSSL_API int wolfSSL_set_scr_check_enabled(WOLFSSL* ssl, byte enabled)
3743{
3744 WOLFSSL_ENTER("wolfSSL_set_scr_check_enabled");
3745
3746 if (ssl == NULL)
3747 return BAD_FUNC_ARG;
3748
3749 ssl->scr_check_enabled = !!enabled;
3750 return WOLFSSL_SUCCESS;
3751}
3752#endif
3753
3754#if defined(HAVE_SESSION_TICKET)
3755/* Session Ticket */
3756
3757#if !defined(NO_WOLFSSL_SERVER)
3758int wolfSSL_CTX_NoTicketTLSv12(WOLFSSL_CTX* ctx)
3759{
3760 if (ctx == NULL)
3761 return BAD_FUNC_ARG;
3762
3763 ctx->noTicketTls12 = 1;
3764
3765 return WOLFSSL_SUCCESS;
3766}
3767
3768int wolfSSL_NoTicketTLSv12(WOLFSSL* ssl)
3769{
3770 if (ssl == NULL)
3771 return BAD_FUNC_ARG;
3772
3773 ssl->options.noTicketTls12 = 1;
3774
3775 return WOLFSSL_SUCCESS;
3776}
3777
3778/* WOLFSSL_SUCCESS on ok */
3779int wolfSSL_CTX_set_TicketEncCb(WOLFSSL_CTX* ctx, SessionTicketEncCb cb)
3780{
3781 if (ctx == NULL)
3782 return BAD_FUNC_ARG;
3783
3784 ctx->ticketEncCb = cb;
3785
3786 return WOLFSSL_SUCCESS;
3787}
3788
3789/* set hint interval, WOLFSSL_SUCCESS on ok */
3790int wolfSSL_CTX_set_TicketHint(WOLFSSL_CTX* ctx, int hint)
3791{
3792 if (ctx == NULL)
3793 return BAD_FUNC_ARG;
3794
3795 /* RFC8446 Section 4.6.1: Servers MUST NOT use any value greater than
3796 * 604800 seconds (7 days). */
3797 if (hint < 0 || hint > 604800)
3798 return BAD_FUNC_ARG;
3799
3800 ctx->ticketHint = hint;
3801
3802 return WOLFSSL_SUCCESS;
3803}
3804
3805/* set user context, WOLFSSL_SUCCESS on ok */
3806int wolfSSL_CTX_set_TicketEncCtx(WOLFSSL_CTX* ctx, void* userCtx)
3807{
3808 if (ctx == NULL)
3809 return BAD_FUNC_ARG;
3810
3811 ctx->ticketEncCtx = userCtx;
3812
3813 return WOLFSSL_SUCCESS;
3814}
3815
3816/* get user context - returns userCtx on success, NULL on failure */
3817void* wolfSSL_CTX_get_TicketEncCtx(WOLFSSL_CTX* ctx)
3818{
3819 if (ctx == NULL)
3820 return NULL;
3821
3822 return ctx->ticketEncCtx;
3823}
3824
3825#ifdef WOLFSSL_TLS13
3826/* set the maximum number of tickets to send
3827 * return WOLFSSL_SUCCESS on success and WOLFSSL_FAILURE on fail
3828 */
3829int wolfSSL_CTX_set_num_tickets(WOLFSSL_CTX* ctx, size_t mxTickets)
3830{
3831 if (ctx == NULL)
3832 return WOLFSSL_FAILURE;
3833
3834 ctx->maxTicketTls13 = (unsigned int)mxTickets;
3835 return WOLFSSL_SUCCESS;
3836}
3837
3838/* get the maximum number of tickets to send
3839 * return number of tickets set to be sent
3840 */
3841size_t wolfSSL_CTX_get_num_tickets(WOLFSSL_CTX* ctx)
3842{
3843 if (ctx == NULL)
3844 return 0;
3845
3846 return (size_t)ctx->maxTicketTls13;
3847}
3848#endif /* WOLFSSL_TLS13 */
3849#endif /* !NO_WOLFSSL_SERVER */
3850
3851#if !defined(NO_WOLFSSL_CLIENT)
3852int wolfSSL_UseSessionTicket(WOLFSSL* ssl)
3853{
3854 if (ssl == NULL)
3855 return BAD_FUNC_ARG;
3856
3857 return TLSX_UseSessionTicket(&ssl->extensions, NULL, ssl->heap);
3858}
3859
3860int wolfSSL_CTX_UseSessionTicket(WOLFSSL_CTX* ctx)
3861{
3862 if (ctx == NULL)
3863 return BAD_FUNC_ARG;
3864
3865 return TLSX_UseSessionTicket(&ctx->extensions, NULL, ctx->heap);
3866}
3867
3868int wolfSSL_get_SessionTicket(WOLFSSL* ssl, byte* buf, word32* bufSz)
3869{
3870 if (ssl == NULL || bufSz == NULL)
3871 return BAD_FUNC_ARG;
3872
3873 if (*bufSz == 0 && buf == NULL) {
3874 *bufSz = ssl->session->ticketLen;
3875 return LENGTH_ONLY_E;
3876 }
3877
3878 if (buf == NULL)
3879 return BAD_FUNC_ARG;
3880
3881 if (ssl->session->ticketLen <= *bufSz) {
3882 XMEMCPY(buf, ssl->session->ticket, ssl->session->ticketLen);
3883 *bufSz = ssl->session->ticketLen;
3884 }
3885 else
3886 *bufSz = 0;
3887
3888 return WOLFSSL_SUCCESS;
3889}
3890
3891int wolfSSL_set_SessionTicket(WOLFSSL* ssl, const byte* buf,
3892 word32 bufSz)
3893{
3894 if (ssl == NULL || (buf == NULL && bufSz > 0))
3895 return BAD_FUNC_ARG;
3896
3897 if (bufSz > 0) {
3898 /* Ticket will fit into static ticket */
3899 if (bufSz <= SESSION_TICKET_LEN) {
3900 if (ssl->session->ticketLenAlloc > 0) {
3901 XFREE(ssl->session->ticket, ssl->session->heap,
3902 DYNAMIC_TYPE_SESSION_TICK);
3903 ssl->session->ticketLenAlloc = 0;
3904 ssl->session->ticket = ssl->session->staticTicket;
3905 }
3906 }
3907 else { /* Ticket requires dynamic ticket storage */
3908 /* is dyn buffer big enough */
3909 if (ssl->session->ticketLen < bufSz) {
3910 if (ssl->session->ticketLenAlloc > 0) {
3911 XFREE(ssl->session->ticket, ssl->session->heap,
3912 DYNAMIC_TYPE_SESSION_TICK);
3913 }
3914 ssl->session->ticket = (byte*)XMALLOC(bufSz, ssl->session->heap,
3915 DYNAMIC_TYPE_SESSION_TICK);
3916 if(ssl->session->ticket == NULL) {
3917 ssl->session->ticket = ssl->session->staticTicket;
3918 ssl->session->ticketLenAlloc = 0;
3919 return MEMORY_ERROR;
3920 }
3921 ssl->session->ticketLenAlloc = (word16)bufSz;
3922 }
3923 }
3924 XMEMCPY(ssl->session->ticket, buf, bufSz);
3925 }
3926 ssl->session->ticketLen = (word16)bufSz;
3927
3928 return WOLFSSL_SUCCESS;
3929}
3930
3931
3932int wolfSSL_set_SessionTicket_cb(WOLFSSL* ssl,
3933 CallbackSessionTicket cb, void* ctx)
3934{
3935 if (ssl == NULL)
3936 return BAD_FUNC_ARG;
3937
3938 ssl->session_ticket_cb = cb;
3939 ssl->session_ticket_ctx = ctx;
3940
3941 return WOLFSSL_SUCCESS;
3942}
3943#endif /* !NO_WOLFSSL_CLIENT */
3944
3945#endif /* HAVE_SESSION_TICKET */
3946
3947
3948#ifdef HAVE_EXTENDED_MASTER
3949#ifndef NO_WOLFSSL_CLIENT
3950
3951int wolfSSL_CTX_DisableExtendedMasterSecret(WOLFSSL_CTX* ctx)
3952{
3953 if (ctx == NULL)
3954 return BAD_FUNC_ARG;
3955
3956 ctx->haveEMS = 0;
3957
3958 return WOLFSSL_SUCCESS;
3959}
3960
3961
3962int wolfSSL_DisableExtendedMasterSecret(WOLFSSL* ssl)
3963{
3964 if (ssl == NULL)
3965 return BAD_FUNC_ARG;
3966
3967 ssl->options.haveEMS = 0;
3968
3969 return WOLFSSL_SUCCESS;
3970}
3971
3972#endif
3973#endif
3974
3975
3976#ifndef WOLFSSL_LEANPSK
3977
3978int wolfSSL_send(WOLFSSL* ssl, const void* data, int sz, int flags)
3979{
3980 int ret;
3981 int oldFlags;
3982
3983 WOLFSSL_ENTER("wolfSSL_send");
3984
3985 if (ssl == NULL || data == NULL || sz < 0)
3986 return BAD_FUNC_ARG;
3987
3988 oldFlags = ssl->wflags;
3989
3990 ssl->wflags = flags;
3991 ret = wolfSSL_write(ssl, data, sz);
3992 ssl->wflags = oldFlags;
3993
3994 WOLFSSL_LEAVE("wolfSSL_send", ret);
3995
3996 return ret;
3997}
3998
3999
4000int wolfSSL_recv(WOLFSSL* ssl, void* data, int sz, int flags)
4001{
4002 int ret;
4003 int oldFlags;
4004
4005 WOLFSSL_ENTER("wolfSSL_recv");
4006
4007 if (ssl == NULL || data == NULL || sz < 0)
4008 return BAD_FUNC_ARG;
4009
4010 oldFlags = ssl->rflags;
4011
4012 ssl->rflags = flags;
4013 ret = wolfSSL_read(ssl, data, sz);
4014 ssl->rflags = oldFlags;
4015
4016 WOLFSSL_LEAVE("wolfSSL_recv", ret);
4017
4018 return ret;
4019}
4020#endif
4021
4022int wolfSSL_SendUserCanceled(WOLFSSL* ssl)
4023{
4024 int ret = WC_NO_ERR_TRACE(WOLFSSL_FAILURE);
4025 WOLFSSL_ENTER("wolfSSL_recv");
4026
4027 if (ssl != NULL) {
4028 ssl->error = SendAlert(ssl, alert_warning, user_canceled);
4029 if (ssl->error < 0) {
4030 WOLFSSL_ERROR(ssl->error);
4031 }
4032 else {
4033 ret = wolfSSL_shutdown(ssl);
4034 }
4035 }
4036
4037 WOLFSSL_LEAVE("wolfSSL_SendUserCanceled", ret);
4038
4039 return ret;
4040}
4041
4042/* WOLFSSL_SUCCESS on ok */
4043WOLFSSL_ABI
4044int wolfSSL_shutdown(WOLFSSL* ssl)
4045{
4046 int ret = WC_NO_ERR_TRACE(WOLFSSL_FATAL_ERROR);
4047 WOLFSSL_ENTER("wolfSSL_shutdown");
4048
4049 if (ssl == NULL)
4050 return WOLFSSL_FATAL_ERROR;
4051
4052 if (ssl->options.quietShutdown) {
4053 WOLFSSL_MSG("quiet shutdown, no close notify sent");
4054 ret = WOLFSSL_SUCCESS;
4055 }
4056 else {
4057
4058 /* Try to flush the buffer first, it might contain the alert */
4059 if (ssl->error == WC_NO_ERR_TRACE(WANT_WRITE) &&
4060 ssl->buffers.outputBuffer.length > 0) {
4061 ret = SendBuffered(ssl);
4062 if (ret != 0) {
4063 ssl->error = ret;
4064 /* for error tracing */
4065 if (ret != WC_NO_ERR_TRACE(WANT_WRITE))
4066 WOLFSSL_ERROR(ret);
4067 ret = WOLFSSL_FATAL_ERROR;
4068 WOLFSSL_LEAVE("wolfSSL_shutdown", ret);
4069 return ret;
4070 }
4071
4072 ssl->error = WOLFSSL_ERROR_NONE;
4073 /* we succeeded in sending the alert now */
4074 if (ssl->options.sentNotify) {
4075 /* just after we send the alert, if we didn't receive the alert
4076 * from the other peer yet, return WOLFSSL_STHUDOWN_NOT_DONE */
4077 if (!ssl->options.closeNotify) {
4078 ret = WOLFSSL_SHUTDOWN_NOT_DONE;
4079 WOLFSSL_LEAVE("wolfSSL_shutdown", ret);
4080 return ret;
4081 }
4082 else {
4083 ssl->options.shutdownDone = 1;
4084 ret = WOLFSSL_SUCCESS;
4085 }
4086 }
4087 }
4088
4089 /* try to send close notify, not an error if can't */
4090 if (!ssl->options.isClosed && !ssl->options.connReset &&
4091 !ssl->options.sentNotify) {
4092 ssl->error = SendAlert(ssl, alert_warning, close_notify);
4093
4094 /* the alert is now sent or sitting in the buffer,
4095 * where will be sent eventually */
4096 if (ssl->error == 0 || ssl->error == WC_NO_ERR_TRACE(WANT_WRITE))
4097 ssl->options.sentNotify = 1;
4098
4099 if (ssl->error < 0) {
4100 WOLFSSL_ERROR(ssl->error);
4101 return WOLFSSL_FATAL_ERROR;
4102 }
4103
4104 if (ssl->options.closeNotify) {
4105 ret = WOLFSSL_SUCCESS;
4106 ssl->options.shutdownDone = 1;
4107 }
4108 else {
4109 ret = WOLFSSL_SHUTDOWN_NOT_DONE;
4110 WOLFSSL_LEAVE("wolfSSL_shutdown", ret);
4111 return ret;
4112 }
4113 }
4114
4115#ifdef WOLFSSL_SHUTDOWNONCE
4116 if (ssl->options.isClosed || ssl->options.connReset) {
4117 /* Shutdown has already occurred.
4118 * Caller is free to ignore this error. */
4119 return SSL_SHUTDOWN_ALREADY_DONE_E;
4120 }
4121#endif
4122
4123 /* wolfSSL_shutdown called again for bidirectional shutdown */
4124 if (ssl->options.sentNotify && !ssl->options.closeNotify) {
4125 ret = ProcessReply(ssl);
4126 if ((ret == WC_NO_ERR_TRACE(ZERO_RETURN)) ||
4127 (ret == WC_NO_ERR_TRACE(SOCKET_ERROR_E))) {
4128 /* simulate OpenSSL behavior */
4129 ssl->options.shutdownDone = 1;
4130 /* Clear error */
4131 ssl->error = WOLFSSL_ERROR_NONE;
4132 ret = WOLFSSL_SUCCESS;
4133 }
4134 else if (ret == WC_NO_ERR_TRACE(MEMORY_E)) {
4135 ret = WOLFSSL_FATAL_ERROR;
4136 }
4137 else if (ret == WC_NO_ERR_TRACE(WANT_READ)) {
4138 ssl->error = ret;
4139 ret = WOLFSSL_FATAL_ERROR;
4140 }
4141 else if (ssl->error == WOLFSSL_ERROR_NONE) {
4142 ret = WOLFSSL_SHUTDOWN_NOT_DONE;
4143 }
4144 else {
4145 WOLFSSL_ERROR(ssl->error);
4146 ret = WOLFSSL_FATAL_ERROR;
4147 }
4148 }
4149 }
4150
4151#if defined(OPENSSL_EXTRA) || defined(WOLFSSL_WPAS_SMALL)
4152 /* reset WOLFSSL structure state for possible reuse */
4153 if (ret == WOLFSSL_SUCCESS) {
4154 if (wolfSSL_clear(ssl) != WOLFSSL_SUCCESS) {
4155 WOLFSSL_MSG("could not clear WOLFSSL");
4156 ret = WOLFSSL_FATAL_ERROR;
4157 }
4158 }
4159#endif
4160
4161 WOLFSSL_LEAVE("wolfSSL_shutdown", ret);
4162
4163 return ret;
4164}
4165#endif /* !NO_TLS */
4166
4167/* get current error state value */
4168int wolfSSL_state(WOLFSSL* ssl)
4169{
4170 if (ssl == NULL) {
4171 return BAD_FUNC_ARG;
4172 }
4173
4174 return ssl->error;
4175}
4176
4177
4178WOLFSSL_ABI
4179int wolfSSL_get_error(WOLFSSL* ssl, int ret)
4180{
4181 WOLFSSL_ENTER("wolfSSL_get_error");
4182
4183 if (ret > 0)
4184 return WOLFSSL_ERROR_NONE;
4185 if (ssl == NULL)
4186 return BAD_FUNC_ARG;
4187
4188 WOLFSSL_LEAVE("wolfSSL_get_error", ssl->error);
4189
4190 /* make sure converted types are handled in SetErrorString() too */
4191 if (ssl->error == WC_NO_ERR_TRACE(WANT_READ))
4192 return WOLFSSL_ERROR_WANT_READ; /* convert to OpenSSL type */
4193 else if (ssl->error == WC_NO_ERR_TRACE(WANT_WRITE))
4194 return WOLFSSL_ERROR_WANT_WRITE; /* convert to OpenSSL type */
4195 else if (ssl->error == WC_NO_ERR_TRACE(ZERO_RETURN) ||
4196 ssl->options.shutdownDone)
4197 return WOLFSSL_ERROR_ZERO_RETURN; /* convert to OpenSSL type */
4198#ifdef OPENSSL_EXTRA
4199 else if (ssl->error == WC_NO_ERR_TRACE(MATCH_SUITE_ERROR))
4200 return WOLFSSL_ERROR_SYSCALL; /* convert to OpenSSL type */
4201 else if (ssl->error == WC_NO_ERR_TRACE(SOCKET_PEER_CLOSED_E))
4202 return WOLFSSL_ERROR_SYSCALL; /* convert to OpenSSL type */
4203#endif
4204#ifdef WOLFSSL_ASYNC_CRYPT
4205 else if (ssl->error == WC_NO_ERR_TRACE(MP_WOULDBLOCK))
4206 return WC_PENDING_E; /* map non-blocking crypto */
4207#endif
4208 return ssl->error;
4209}
4210
4211
4212/* retrieve alert history, WOLFSSL_SUCCESS on ok */
4213int wolfSSL_get_alert_history(WOLFSSL* ssl, WOLFSSL_ALERT_HISTORY *h)
4214{
4215 if (ssl && h) {
4216 *h = ssl->alert_history;
4217 }
4218 return WOLFSSL_SUCCESS;
4219}
4220
4221#ifdef OPENSSL_EXTRA
4222/* returns SSL_WRITING, SSL_READING or SSL_NOTHING */
4223int wolfSSL_want(WOLFSSL* ssl)
4224{
4225 int rw_state = WOLFSSL_NOTHING;
4226 if (ssl) {
4227 if (ssl->error == WC_NO_ERR_TRACE(WANT_READ))
4228 rw_state = WOLFSSL_READING;
4229 else if (ssl->error == WC_NO_ERR_TRACE(WANT_WRITE))
4230 rw_state = WOLFSSL_WRITING;
4231 }
4232 return rw_state;
4233}
4234#endif
4235
4236/* return TRUE if current error is want read */
4237int wolfSSL_want_read(WOLFSSL* ssl)
4238{
4239 WOLFSSL_ENTER("wolfSSL_want_read");
4240 if (ssl->error == WC_NO_ERR_TRACE(WANT_READ))
4241 return 1;
4242
4243 return 0;
4244}
4245
4246/* return TRUE if current error is want write */
4247int wolfSSL_want_write(WOLFSSL* ssl)
4248{
4249 WOLFSSL_ENTER("wolfSSL_want_write");
4250 if (ssl->error == WC_NO_ERR_TRACE(WANT_WRITE))
4251 return 1;
4252
4253 return 0;
4254}
4255
4256char* wolfSSL_ERR_error_string(unsigned long errNumber, char* data)
4257{
4258 WOLFSSL_ENTER("wolfSSL_ERR_error_string");
4259 if (data) {
4260 SetErrorString((int)errNumber, data);
4261 return data;
4262 }
4263 else {
4264 static char tmp[WOLFSSL_MAX_ERROR_SZ] = {0};
4265 SetErrorString((int)errNumber, tmp);
4266 return tmp;
4267 }
4268}
4269
4270
4271void wolfSSL_ERR_error_string_n(unsigned long e, char* buf, unsigned long len)
4272{
4273 WOLFSSL_ENTER("wolfSSL_ERR_error_string_n");
4274 if (len >= WOLFSSL_MAX_ERROR_SZ)
4275 wolfSSL_ERR_error_string(e, buf);
4276 else {
4277 WOLFSSL_MSG("Error buffer too short, truncating");
4278 if (len) {
4279 char tmp[WOLFSSL_MAX_ERROR_SZ];
4280 wolfSSL_ERR_error_string(e, tmp);
4281 XMEMCPY(buf, tmp, len-1);
4282 buf[len-1] = '\0';
4283 }
4284 }
4285}
4286
4287
4288/* don't free temporary arrays at end of handshake */
4289void wolfSSL_KeepArrays(WOLFSSL* ssl)
4290{
4291 if (ssl)
4292 ssl->options.saveArrays = 1;
4293}
4294
4295
4296/* user doesn't need temporary arrays anymore, Free */
4297void wolfSSL_FreeArrays(WOLFSSL* ssl)
4298{
4299 if (ssl && ssl->options.handShakeState == HANDSHAKE_DONE) {
4300 ssl->options.saveArrays = 0;
4301 FreeArrays(ssl, 1);
4302 }
4303}
4304
4305/* Set option to indicate that the resources are not to be freed after
4306 * handshake.
4307 *
4308 * ssl The SSL/TLS object.
4309 * returns BAD_FUNC_ARG when ssl is NULL and 0 on success.
4310 */
4311int wolfSSL_KeepHandshakeResources(WOLFSSL* ssl)
4312{
4313 if (ssl == NULL)
4314 return BAD_FUNC_ARG;
4315
4316 ssl->options.keepResources = 1;
4317
4318 return 0;
4319}
4320
4321/* Free the handshake resources after handshake.
4322 *
4323 * ssl The SSL/TLS object.
4324 * returns BAD_FUNC_ARG when ssl is NULL and 0 on success.
4325 */
4326int wolfSSL_FreeHandshakeResources(WOLFSSL* ssl)
4327{
4328 if (ssl == NULL)
4329 return BAD_FUNC_ARG;
4330
4331 FreeHandshakeResources(ssl);
4332
4333 return 0;
4334}
4335
4336/* Use the client's order of preference when matching cipher suites.
4337 *
4338 * ssl The SSL/TLS context object.
4339 * returns BAD_FUNC_ARG when ssl is NULL and 0 on success.
4340 */
4341int wolfSSL_CTX_UseClientSuites(WOLFSSL_CTX* ctx)
4342{
4343 if (ctx == NULL)
4344 return BAD_FUNC_ARG;
4345
4346 ctx->useClientOrder = 1;
4347
4348 return 0;
4349}
4350
4351/* Use the client's order of preference when matching cipher suites.
4352 *
4353 * ssl The SSL/TLS object.
4354 * returns BAD_FUNC_ARG when ssl is NULL and 0 on success.
4355 */
4356int wolfSSL_UseClientSuites(WOLFSSL* ssl)
4357{
4358 if (ssl == NULL)
4359 return BAD_FUNC_ARG;
4360
4361 ssl->options.useClientOrder = 1;
4362
4363 return 0;
4364}
4365
4366#ifdef WOLFSSL_DTLS
4367const byte* wolfSSL_GetDtlsMacSecret(WOLFSSL* ssl, int verify, int epochOrder)
4368{
4369#ifndef WOLFSSL_AEAD_ONLY
4370 Keys* keys = NULL;
4371
4372 (void)epochOrder;
4373
4374 if (ssl == NULL)
4375 return NULL;
4376
4377#ifdef HAVE_SECURE_RENEGOTIATION
4378 switch (epochOrder) {
4379 case PEER_ORDER:
4380 if (IsDtlsMsgSCRKeys(ssl))
4381 keys = &ssl->secure_renegotiation->tmp_keys;
4382 else
4383 keys = &ssl->keys;
4384 break;
4385 case PREV_ORDER:
4386 keys = &ssl->keys;
4387 break;
4388 case CUR_ORDER:
4389 if (DtlsUseSCRKeys(ssl))
4390 keys = &ssl->secure_renegotiation->tmp_keys;
4391 else
4392 keys = &ssl->keys;
4393 break;
4394 default:
4395 WOLFSSL_MSG("Unknown epoch order");
4396 return NULL;
4397 }
4398#else
4399 keys = &ssl->keys;
4400#endif
4401
4402 if ( (ssl->options.side == WOLFSSL_CLIENT_END && !verify) ||
4403 (ssl->options.side == WOLFSSL_SERVER_END && verify) )
4404 return keys->client_write_MAC_secret;
4405 else
4406 return keys->server_write_MAC_secret;
4407#else
4408 (void)ssl;
4409 (void)verify;
4410 (void)epochOrder;
4411
4412 return NULL;
4413#endif
4414}
4415#endif /* WOLFSSL_DTLS */
4416
4417const byte* wolfSSL_GetMacSecret(WOLFSSL* ssl, int verify)
4418{
4419#ifndef WOLFSSL_AEAD_ONLY
4420 if (ssl == NULL)
4421 return NULL;
4422
4423 if ( (ssl->options.side == WOLFSSL_CLIENT_END && !verify) ||
4424 (ssl->options.side == WOLFSSL_SERVER_END && verify) )
4425 return ssl->keys.client_write_MAC_secret;
4426 else
4427 return ssl->keys.server_write_MAC_secret;
4428#else
4429 (void)ssl;
4430 (void)verify;
4431
4432 return NULL;
4433#endif
4434}
4435
4436int wolfSSL_GetSide(WOLFSSL* ssl)
4437{
4438 if (ssl)
4439 return ssl->options.side;
4440
4441 return BAD_FUNC_ARG;
4442}
4443
4444#ifdef ATOMIC_USER
4445
4446void wolfSSL_CTX_SetMacEncryptCb(WOLFSSL_CTX* ctx, CallbackMacEncrypt cb)
4447{
4448 if (ctx)
4449 ctx->MacEncryptCb = cb;
4450}
4451
4452
4453void wolfSSL_SetMacEncryptCtx(WOLFSSL* ssl, void *ctx)
4454{
4455 if (ssl)
4456 ssl->MacEncryptCtx = ctx;
4457}
4458
4459
4460void* wolfSSL_GetMacEncryptCtx(WOLFSSL* ssl)
4461{
4462 if (ssl)
4463 return ssl->MacEncryptCtx;
4464
4465 return NULL;
4466}
4467
4468
4469void wolfSSL_CTX_SetDecryptVerifyCb(WOLFSSL_CTX* ctx, CallbackDecryptVerify cb)
4470{
4471 if (ctx)
4472 ctx->DecryptVerifyCb = cb;
4473}
4474
4475
4476void wolfSSL_SetDecryptVerifyCtx(WOLFSSL* ssl, void *ctx)
4477{
4478 if (ssl)
4479 ssl->DecryptVerifyCtx = ctx;
4480}
4481
4482
4483void* wolfSSL_GetDecryptVerifyCtx(WOLFSSL* ssl)
4484{
4485 if (ssl)
4486 return ssl->DecryptVerifyCtx;
4487
4488 return NULL;
4489}
4490
4491#if defined(HAVE_ENCRYPT_THEN_MAC) && !defined(WOLFSSL_AEAD_ONLY)
4492/**
4493 * Set the callback, against the context, that encrypts then MACs.
4494 *
4495 * ctx SSL/TLS context.
4496 * cb Callback function to use with Encrypt-Then-MAC.
4497 */
4498void wolfSSL_CTX_SetEncryptMacCb(WOLFSSL_CTX* ctx, CallbackEncryptMac cb)
4499{
4500 if (ctx)
4501 ctx->EncryptMacCb = cb;
4502}
4503
4504/**
4505 * Set the context to use with callback that encrypts then MACs.
4506 *
4507 * ssl SSL/TLS object.
4508 * ctx Callback function's context.
4509 */
4510void wolfSSL_SetEncryptMacCtx(WOLFSSL* ssl, void *ctx)
4511{
4512 if (ssl)
4513 ssl->EncryptMacCtx = ctx;
4514}
4515
4516/**
4517 * Get the context being used with callback that encrypts then MACs.
4518 *
4519 * ssl SSL/TLS object.
4520 * returns callback function's context or NULL if SSL/TLS object is NULL.
4521 */
4522void* wolfSSL_GetEncryptMacCtx(WOLFSSL* ssl)
4523{
4524 if (ssl)
4525 return ssl->EncryptMacCtx;
4526
4527 return NULL;
4528}
4529
4530
4531/**
4532 * Set the callback, against the context, that MAC verifies then decrypts.
4533 *
4534 * ctx SSL/TLS context.
4535 * cb Callback function to use with Encrypt-Then-MAC.
4536 */
4537void wolfSSL_CTX_SetVerifyDecryptCb(WOLFSSL_CTX* ctx, CallbackVerifyDecrypt cb)
4538{
4539 if (ctx)
4540 ctx->VerifyDecryptCb = cb;
4541}
4542
4543/**
4544 * Set the context to use with callback that MAC verifies then decrypts.
4545 *
4546 * ssl SSL/TLS object.
4547 * ctx Callback function's context.
4548 */
4549void wolfSSL_SetVerifyDecryptCtx(WOLFSSL* ssl, void *ctx)
4550{
4551 if (ssl)
4552 ssl->VerifyDecryptCtx = ctx;
4553}
4554
4555/**
4556 * Get the context being used with callback that MAC verifies then decrypts.
4557 *
4558 * ssl SSL/TLS object.
4559 * returns callback function's context or NULL if SSL/TLS object is NULL.
4560 */
4561void* wolfSSL_GetVerifyDecryptCtx(WOLFSSL* ssl)
4562{
4563 if (ssl)
4564 return ssl->VerifyDecryptCtx;
4565
4566 return NULL;
4567}
4568#endif /* HAVE_ENCRYPT_THEN_MAC !WOLFSSL_AEAD_ONLY */
4569
4570
4571
4572const byte* wolfSSL_GetClientWriteKey(WOLFSSL* ssl)
4573{
4574 if (ssl)
4575 return ssl->keys.client_write_key;
4576
4577 return NULL;
4578}
4579
4580
4581const byte* wolfSSL_GetClientWriteIV(WOLFSSL* ssl)
4582{
4583 if (ssl)
4584 return ssl->keys.client_write_IV;
4585
4586 return NULL;
4587}
4588
4589
4590const byte* wolfSSL_GetServerWriteKey(WOLFSSL* ssl)
4591{
4592 if (ssl)
4593 return ssl->keys.server_write_key;
4594
4595 return NULL;
4596}
4597
4598
4599const byte* wolfSSL_GetServerWriteIV(WOLFSSL* ssl)
4600{
4601 if (ssl)
4602 return ssl->keys.server_write_IV;
4603
4604 return NULL;
4605}
4606
4607int wolfSSL_GetKeySize(WOLFSSL* ssl)
4608{
4609 if (ssl)
4610 return ssl->specs.key_size;
4611
4612 return BAD_FUNC_ARG;
4613}
4614
4615
4616int wolfSSL_GetIVSize(WOLFSSL* ssl)
4617{
4618 if (ssl)
4619 return ssl->specs.iv_size;
4620
4621 return BAD_FUNC_ARG;
4622}
4623
4624
4625int wolfSSL_GetBulkCipher(WOLFSSL* ssl)
4626{
4627 if (ssl)
4628 return ssl->specs.bulk_cipher_algorithm;
4629
4630 return BAD_FUNC_ARG;
4631}
4632
4633
4634int wolfSSL_GetCipherType(WOLFSSL* ssl)
4635{
4636 if (ssl == NULL)
4637 return BAD_FUNC_ARG;
4638
4639#ifndef WOLFSSL_AEAD_ONLY
4640 if (ssl->specs.cipher_type == block)
4641 return WOLFSSL_BLOCK_TYPE;
4642 if (ssl->specs.cipher_type == stream)
4643 return WOLFSSL_STREAM_TYPE;
4644#endif
4645 if (ssl->specs.cipher_type == aead)
4646 return WOLFSSL_AEAD_TYPE;
4647
4648 return WOLFSSL_FATAL_ERROR;
4649}
4650
4651
4652int wolfSSL_GetCipherBlockSize(WOLFSSL* ssl)
4653{
4654 if (ssl == NULL)
4655 return BAD_FUNC_ARG;
4656
4657 return ssl->specs.block_size;
4658}
4659
4660
4661int wolfSSL_GetAeadMacSize(WOLFSSL* ssl)
4662{
4663 if (ssl == NULL)
4664 return BAD_FUNC_ARG;
4665
4666 return ssl->specs.aead_mac_size;
4667}
4668
4669
4670int wolfSSL_IsTLSv1_1(WOLFSSL* ssl)
4671{
4672 if (ssl == NULL)
4673 return BAD_FUNC_ARG;
4674
4675 if (ssl->options.tls1_1)
4676 return 1;
4677
4678 return 0;
4679}
4680
4681
4682
4683int wolfSSL_GetHmacSize(WOLFSSL* ssl)
4684{
4685 /* AEAD ciphers don't have HMAC keys */
4686 if (ssl)
4687 return (ssl->specs.cipher_type != aead) ? ssl->specs.hash_size : 0;
4688
4689 return BAD_FUNC_ARG;
4690}
4691
4692#ifdef WORD64_AVAILABLE
4693int wolfSSL_GetPeerSequenceNumber(WOLFSSL* ssl, word64 *seq)
4694{
4695 if ((ssl == NULL) || (seq == NULL))
4696 return BAD_FUNC_ARG;
4697
4698 *seq = ((word64)ssl->keys.peer_sequence_number_hi << 32) |
4699 ssl->keys.peer_sequence_number_lo;
4700 return !(*seq);
4701}
4702
4703int wolfSSL_GetSequenceNumber(WOLFSSL* ssl, word64 *seq)
4704{
4705 if ((ssl == NULL) || (seq == NULL))
4706 return BAD_FUNC_ARG;
4707
4708 *seq = ((word64)ssl->keys.sequence_number_hi << 32) |
4709 ssl->keys.sequence_number_lo;
4710 return !(*seq);
4711}
4712#endif
4713
4714#endif /* ATOMIC_USER */
4715
4716#if !defined(NO_FILESYSTEM) && !defined(NO_STDIO_FILESYSTEM) \
4717 && defined(XFPRINTF)
4718
4719void wolfSSL_ERR_print_errors_fp(XFILE fp, int err)
4720{
4721 char data[WOLFSSL_MAX_ERROR_SZ + 1];
4722
4723 WOLFSSL_ENTER("wolfSSL_ERR_print_errors_fp");
4724 SetErrorString(err, data);
4725 if (XFPRINTF(fp, "%s", data) < 0)
4726 WOLFSSL_MSG("fprintf failed in wolfSSL_ERR_print_errors_fp");
4727}
4728
4729#if defined(OPENSSL_EXTRA) || defined(DEBUG_WOLFSSL_VERBOSE)
4730void wolfSSL_ERR_dump_errors_fp(XFILE fp)
4731{
4732 wc_ERR_print_errors_fp(fp);
4733}
4734
4735void wolfSSL_ERR_print_errors_cb (int (*cb)(const char *str, size_t len,
4736 void *u), void *u)
4737{
4738 wc_ERR_print_errors_cb(cb, u);
4739}
4740#endif
4741#endif /* !NO_FILESYSTEM && !NO_STDIO_FILESYSTEM && XFPRINTF */
4742
4743/*
4744 * TODO This ssl parameter needs to be changed to const once our ABI checker
4745 * stops flagging qualifier additions as ABI breaking.
4746 */
4747WOLFSSL_ABI
4748int wolfSSL_pending(WOLFSSL* ssl)
4749{
4750 WOLFSSL_ENTER("wolfSSL_pending");
4751 if (ssl == NULL)
4752 return WOLFSSL_FAILURE;
4753
4754 return (int)ssl->buffers.clearOutputBuffer.length;
4755}
4756
4757int wolfSSL_has_pending(const WOLFSSL* ssl)
4758{
4759 WOLFSSL_ENTER("wolfSSL_has_pending");
4760 if (ssl == NULL)
4761 return WOLFSSL_FAILURE;
4762
4763 return ssl->buffers.clearOutputBuffer.length > 0;
4764}
4765
4766#ifndef WOLFSSL_LEANPSK
4767/* turn on handshake group messages for context */
4768int wolfSSL_CTX_set_group_messages(WOLFSSL_CTX* ctx)
4769{
4770 if (ctx == NULL)
4771 return BAD_FUNC_ARG;
4772
4773 ctx->groupMessages = 1;
4774
4775 return WOLFSSL_SUCCESS;
4776}
4777
4778int wolfSSL_CTX_clear_group_messages(WOLFSSL_CTX* ctx)
4779{
4780 if (ctx == NULL)
4781 return BAD_FUNC_ARG;
4782
4783 ctx->groupMessages = 0;
4784
4785 return WOLFSSL_SUCCESS;
4786}
4787#endif
4788
4789
4790#if !defined(NO_WOLFSSL_CLIENT) && !defined(NO_TLS)
4791/* connect enough to get peer cert chain */
4792int wolfSSL_connect_cert(WOLFSSL* ssl)
4793{
4794 int ret;
4795
4796 if (ssl == NULL)
4797 return WOLFSSL_FAILURE;
4798
4799 ssl->options.certOnly = 1;
4800 ret = wolfSSL_connect(ssl);
4801 ssl->options.certOnly = 0;
4802
4803 return ret;
4804}
4805#endif
4806
4807
4808#ifndef WOLFSSL_LEANPSK
4809/* turn on handshake group messages for ssl object */
4810int wolfSSL_set_group_messages(WOLFSSL* ssl)
4811{
4812 if (ssl == NULL)
4813 return BAD_FUNC_ARG;
4814
4815 ssl->options.groupMessages = 1;
4816
4817 return WOLFSSL_SUCCESS;
4818}
4819
4820int wolfSSL_clear_group_messages(WOLFSSL* ssl)
4821{
4822 if (ssl == NULL)
4823 return BAD_FUNC_ARG;
4824
4825 ssl->options.groupMessages = 0;
4826
4827 return WOLFSSL_SUCCESS;
4828}
4829
4830/* make minVersion the internal equivalent SSL version */
4831static int SetMinVersionHelper(byte* minVersion, int version)
4832{
4833 (void)minVersion;
4834
4835 switch (version) {
4836#if defined(WOLFSSL_ALLOW_SSLV3) && !defined(NO_OLD_TLS)
4837 case WOLFSSL_SSLV3:
4838 *minVersion = SSLv3_MINOR;
4839 break;
4840#endif
4841
4842#ifndef NO_TLS
4843 #ifndef NO_OLD_TLS
4844 #ifdef WOLFSSL_ALLOW_TLSV10
4845 case WOLFSSL_TLSV1:
4846 *minVersion = TLSv1_MINOR;
4847 break;
4848 #endif
4849
4850 case WOLFSSL_TLSV1_1:
4851 *minVersion = TLSv1_1_MINOR;
4852 break;
4853 #endif
4854 #ifndef WOLFSSL_NO_TLS12
4855 case WOLFSSL_TLSV1_2:
4856 *minVersion = TLSv1_2_MINOR;
4857 break;
4858 #endif
4859#endif
4860 #ifdef WOLFSSL_TLS13
4861 case WOLFSSL_TLSV1_3:
4862 *minVersion = TLSv1_3_MINOR;
4863 break;
4864 #endif
4865
4866#ifdef WOLFSSL_DTLS
4867 case WOLFSSL_DTLSV1:
4868 *minVersion = DTLS_MINOR;
4869 break;
4870 case WOLFSSL_DTLSV1_2:
4871 *minVersion = DTLSv1_2_MINOR;
4872 break;
4873#ifdef WOLFSSL_DTLS13
4874 case WOLFSSL_DTLSV1_3:
4875 *minVersion = DTLSv1_3_MINOR;
4876 break;
4877#endif /* WOLFSSL_DTLS13 */
4878#endif /* WOLFSSL_DTLS */
4879
4880 default:
4881 WOLFSSL_MSG("Bad function argument");
4882 return BAD_FUNC_ARG;
4883 }
4884
4885 return WOLFSSL_SUCCESS;
4886}
4887
4888
4889/* Set minimum downgrade version allowed, WOLFSSL_SUCCESS on ok */
4890WOLFSSL_ABI
4891int wolfSSL_CTX_SetMinVersion(WOLFSSL_CTX* ctx, int version)
4892{
4893 WOLFSSL_ENTER("wolfSSL_CTX_SetMinVersion");
4894
4895 if (ctx == NULL) {
4896 WOLFSSL_MSG("Bad function argument");
4897 return BAD_FUNC_ARG;
4898 }
4899
4900#if defined(WOLFSSL_SYS_CRYPTO_POLICY)
4901 if (crypto_policy.enabled) {
4902 return CRYPTO_POLICY_FORBIDDEN;
4903 }
4904#endif /* WOLFSSL_SYS_CRYPTO_POLICY */
4905
4906 return SetMinVersionHelper(&ctx->minDowngrade, version);
4907}
4908
4909
4910/* Set minimum downgrade version allowed, WOLFSSL_SUCCESS on ok */
4911int wolfSSL_SetMinVersion(WOLFSSL* ssl, int version)
4912{
4913 WOLFSSL_ENTER("wolfSSL_SetMinVersion");
4914
4915 if (ssl == NULL) {
4916 WOLFSSL_MSG("Bad function argument");
4917 return BAD_FUNC_ARG;
4918 }
4919
4920#if defined(WOLFSSL_SYS_CRYPTO_POLICY)
4921 if (crypto_policy.enabled) {
4922 return CRYPTO_POLICY_FORBIDDEN;
4923 }
4924#endif /* WOLFSSL_SYS_CRYPTO_POLICY */
4925
4926 return SetMinVersionHelper(&ssl->options.minDowngrade, version);
4927}
4928
4929
4930/* Function to get version as WOLFSSL_ enum value for wolfSSL_SetVersion */
4931int wolfSSL_GetVersion(const WOLFSSL* ssl)
4932{
4933 if (ssl == NULL)
4934 return BAD_FUNC_ARG;
4935
4936 if (ssl->version.major == SSLv3_MAJOR) {
4937 switch (ssl->version.minor) {
4938 case SSLv3_MINOR :
4939 return WOLFSSL_SSLV3;
4940 case TLSv1_MINOR :
4941 return WOLFSSL_TLSV1;
4942 case TLSv1_1_MINOR :
4943 return WOLFSSL_TLSV1_1;
4944 case TLSv1_2_MINOR :
4945 return WOLFSSL_TLSV1_2;
4946 case TLSv1_3_MINOR :
4947 return WOLFSSL_TLSV1_3;
4948 default:
4949 break;
4950 }
4951 }
4952#ifdef WOLFSSL_DTLS
4953 if (ssl->version.major == DTLS_MAJOR) {
4954 switch (ssl->version.minor) {
4955 case DTLS_MINOR :
4956 return WOLFSSL_DTLSV1;
4957 case DTLSv1_2_MINOR :
4958 return WOLFSSL_DTLSV1_2;
4959 case DTLSv1_3_MINOR :
4960 return WOLFSSL_DTLSV1_3;
4961 default:
4962 break;
4963 }
4964 }
4965#endif /* WOLFSSL_DTLS */
4966
4967 return VERSION_ERROR;
4968}
4969
4970int wolfSSL_SetVersion(WOLFSSL* ssl, int version)
4971{
4972 word16 haveRSA = 1;
4973 word16 havePSK = 0;
4974 int keySz = 0;
4975
4976 WOLFSSL_ENTER("wolfSSL_SetVersion");
4977
4978 if (ssl == NULL) {
4979 WOLFSSL_MSG("Bad function argument");
4980 return BAD_FUNC_ARG;
4981 }
4982
4983 switch (version) {
4984#if defined(WOLFSSL_ALLOW_SSLV3) && !defined(NO_OLD_TLS)
4985 case WOLFSSL_SSLV3:
4986 ssl->version = MakeSSLv3();
4987 break;
4988#endif
4989
4990#ifndef NO_TLS
4991 #ifndef NO_OLD_TLS
4992 #ifdef WOLFSSL_ALLOW_TLSV10
4993 case WOLFSSL_TLSV1:
4994 ssl->version = MakeTLSv1();
4995 break;
4996 #endif
4997
4998 case WOLFSSL_TLSV1_1:
4999 ssl->version = MakeTLSv1_1();
5000 break;
5001 #endif
5002 #ifndef WOLFSSL_NO_TLS12
5003 case WOLFSSL_TLSV1_2:
5004 ssl->version = MakeTLSv1_2();
5005 break;
5006 #endif
5007
5008 #ifdef WOLFSSL_TLS13
5009 case WOLFSSL_TLSV1_3:
5010 ssl->version = MakeTLSv1_3();
5011 break;
5012 #endif /* WOLFSSL_TLS13 */
5013#endif
5014
5015 default:
5016 WOLFSSL_MSG("Bad function argument");
5017 return BAD_FUNC_ARG;
5018 }
5019
5020 ssl->options.downgrade = 0;
5021
5022 #ifdef NO_RSA
5023 haveRSA = 0;
5024 #endif
5025 #ifndef NO_PSK
5026 havePSK = ssl->options.havePSK;
5027 #endif
5028 #ifndef NO_CERTS
5029 keySz = ssl->buffers.keySz;
5030 #endif
5031
5032 if (AllocateSuites(ssl) != 0)
5033 return WOLFSSL_FAILURE;
5034 InitSuites(ssl->suites, ssl->version, keySz, haveRSA, havePSK,
5035 ssl->options.haveDH, ssl->options.haveECDSAsig,
5036 ssl->options.haveECC, TRUE, ssl->options.haveStaticECC,
5037 ssl->options.useAnon, TRUE, TRUE, TRUE, TRUE, ssl->options.side);
5038 return WOLFSSL_SUCCESS;
5039}
5040#endif /* !leanpsk */
5041
5042#if defined(OPENSSL_EXTRA) && !defined(WOLFSSL_NO_OPENSSL_RAND_CB)
5043static int wolfSSL_RAND_InitMutex(void);
5044#endif
5045
5046/* If we don't have static mutex initializers, but we do have static atomic
5047 * initializers, activate WOLFSSL_CLEANUP_THREADSAFE_BY_ATOMIC_OPS to leverage
5048 * the latter.
5049 *
5050 * See further explanation below in wolfSSL_Init().
5051 */
5052#ifndef WOLFSSL_CLEANUP_THREADSAFE_BY_ATOMIC_OPS
5053 #if !defined(WOLFSSL_MUTEX_INITIALIZER) && !defined(SINGLE_THREADED) && \
5054 defined(WOLFSSL_ATOMIC_OPS) && defined(WOLFSSL_ATOMIC_INITIALIZER)
5055 #define WOLFSSL_CLEANUP_THREADSAFE_BY_ATOMIC_OPS 1
5056 #else
5057 #define WOLFSSL_CLEANUP_THREADSAFE_BY_ATOMIC_OPS 0
5058 #endif
5059#elif defined(WOLFSSL_MUTEX_INITIALIZER) || defined(SINGLE_THREADED)
5060 #undef WOLFSSL_CLEANUP_THREADSAFE_BY_ATOMIC_OPS
5061 #define WOLFSSL_CLEANUP_THREADSAFE_BY_ATOMIC_OPS 0
5062#endif
5063
5064#if WOLFSSL_CLEANUP_THREADSAFE_BY_ATOMIC_OPS
5065 #ifndef WOLFSSL_ATOMIC_OPS
5066 #error WOLFSSL_CLEANUP_THREADSAFE_BY_ATOMIC_OPS requires WOLFSSL_ATOMIC_OPS
5067 #endif
5068 #ifndef WOLFSSL_ATOMIC_INITIALIZER
5069 #error WOLFSSL_CLEANUP_THREADSAFE_BY_ATOMIC_OPS requires WOLFSSL_ATOMIC_INITIALIZER
5070 #endif
5071 static wolfSSL_Atomic_Int inits_count_mutex_atomic_initing_flag =
5072 WOLFSSL_ATOMIC_INITIALIZER(0);
5073#endif /* WOLFSSL_CLEANUP_THREADSAFE_BY_ATOMIC_OPS && !WOLFSSL_MUTEX_INITIALIZER */
5074
5075#if defined(OPENSSL_EXTRA) && defined(HAVE_ATEXIT)
5076static void AtExitCleanup(void)
5077{
5078 if (initRefCount > 0) {
5079 initRefCount = 1;
5080 (void)wolfSSL_Cleanup();
5081#if WOLFSSL_CLEANUP_THREADSAFE_BY_ATOMIC_OPS
5082 if (inits_count_mutex_valid == 1) {
5083 (void)wc_FreeMutex(&inits_count_mutex);
5084 inits_count_mutex_valid = 0;
5085 inits_count_mutex_atomic_initing_flag = 0;
5086 }
5087#endif
5088 }
5089}
5090#endif
5091
5092WOLFSSL_ABI
5093int wolfSSL_Init(void)
5094{
5095 int ret = WOLFSSL_SUCCESS;
5096#if !defined(NO_SESSION_CACHE) && defined(ENABLE_SESSION_CACHE_ROW_LOCK)
5097 int i;
5098#endif
5099
5100 WOLFSSL_ENTER("wolfSSL_Init");
5101
5102#if defined(LIBWOLFSSL_CMAKE_OUTPUT)
5103 WOLFSSL_MSG(LIBWOLFSSL_CMAKE_OUTPUT);
5104#else
5105 WOLFSSL_MSG("No extra wolfSSL cmake messages found");
5106#endif
5107
5108#ifndef WOLFSSL_MUTEX_INITIALIZER
5109 if (inits_count_mutex_valid == 0) {
5110 #if WOLFSSL_CLEANUP_THREADSAFE_BY_ATOMIC_OPS
5111
5112 /* Without this mitigation, if two threads enter wolfSSL_Init() at the
5113 * same time, and both see zero inits_count_mutex_valid, then both will
5114 * run wc_InitMutex(&inits_count_mutex), leading to process corruption
5115 * or (best case) a resource leak.
5116 *
5117 * When WOLFSSL_ATOMIC_INITIALIZER() is available, we can mitigate this
5118 * by use an atomic counting int as a mutex.
5119 */
5120
5121 if (wolfSSL_Atomic_Int_FetchAdd(&inits_count_mutex_atomic_initing_flag,
5122 1) != 0)
5123 {
5124 (void)wolfSSL_Atomic_Int_FetchSub(
5125 &inits_count_mutex_atomic_initing_flag, 1);
5126 return DEADLOCK_AVERTED_E;
5127 }
5128 #endif /* WOLFSSL_CLEANUP_THREADSAFE_BY_ATOMIC_OPS */
5129 if (wc_InitMutex(&inits_count_mutex) != 0) {
5130 WOLFSSL_MSG("Bad Init Mutex count");
5131 #if WOLFSSL_CLEANUP_THREADSAFE_BY_ATOMIC_OPS
5132 (void)wolfSSL_Atomic_Int_FetchSub(
5133 &inits_count_mutex_atomic_initing_flag, 1);
5134 #endif
5135 return BAD_MUTEX_E;
5136 }
5137 else {
5138 inits_count_mutex_valid = 1;
5139 }
5140 }
5141#endif /* !WOLFSSL_MUTEX_INITIALIZER */
5142
5143 if (wc_LockMutex(&inits_count_mutex) != 0) {
5144 WOLFSSL_MSG("Bad Lock Mutex count");
5145 return BAD_MUTEX_E;
5146 }
5147
5148#if FIPS_VERSION_GE(5,1)
5149 if ((ret == WOLFSSL_SUCCESS) && (initRefCount == 0)) {
5150 ret = wolfCrypt_SetPrivateKeyReadEnable_fips(1, WC_KEYTYPE_ALL);
5151 if (ret == 0)
5152 ret = WOLFSSL_SUCCESS;
5153 }
5154#endif
5155
5156 if ((ret == WOLFSSL_SUCCESS) && (initRefCount == 0)) {
5157 /* Initialize crypto for use with TLS connection */
5158
5159 if (wolfCrypt_Init() != 0) {
5160 WOLFSSL_MSG("Bad wolfCrypt Init");
5161 ret = WC_INIT_E;
5162 }
5163
5164#if defined(HAVE_GLOBAL_RNG) && !defined(WOLFSSL_MUTEX_INITIALIZER)
5165 if (ret == WOLFSSL_SUCCESS) {
5166 if (wc_InitMutex(&globalRNGMutex) != 0) {
5167 WOLFSSL_MSG("Bad Init Mutex rng");
5168 ret = BAD_MUTEX_E;
5169 }
5170 else {
5171 globalRNGMutex_valid = 1;
5172 }
5173 }
5174#endif
5175
5176 #ifdef WC_RNG_SEED_CB
5177 wc_SetSeed_Cb(WC_GENERATE_SEED_DEFAULT);
5178 #endif
5179
5180#ifdef OPENSSL_EXTRA
5181 #ifndef WOLFSSL_NO_OPENSSL_RAND_CB
5182 if ((ret == WOLFSSL_SUCCESS) && (wolfSSL_RAND_InitMutex() != 0)) {
5183 ret = BAD_MUTEX_E;
5184 }
5185 #endif
5186 if ((ret == WOLFSSL_SUCCESS) &&
5187 (wolfSSL_RAND_seed(NULL, 0) != WOLFSSL_SUCCESS)) {
5188 WOLFSSL_MSG("wolfSSL_RAND_seed failed");
5189 ret = WC_INIT_E;
5190 }
5191#endif
5192
5193#ifndef NO_SESSION_CACHE
5194 #ifdef ENABLE_SESSION_CACHE_ROW_LOCK
5195 for (i = 0; i < SESSION_ROWS; ++i) {
5196 SessionCache[i].lock_valid = 0;
5197 }
5198 for (i = 0; (ret == WOLFSSL_SUCCESS) && (i < SESSION_ROWS); ++i) {
5199 if (wc_InitRwLock(&SessionCache[i].row_lock) != 0) {
5200 WOLFSSL_MSG("Bad Init Mutex session");
5201 ret = BAD_MUTEX_E;
5202 }
5203 else {
5204 SessionCache[i].lock_valid = 1;
5205 }
5206 }
5207 #else
5208 if (ret == WOLFSSL_SUCCESS) {
5209 if (wc_InitRwLock(&session_lock) != 0) {
5210 WOLFSSL_MSG("Bad Init Mutex session");
5211 ret = BAD_MUTEX_E;
5212 }
5213 else {
5214 session_lock_valid = 1;
5215 }
5216 }
5217 #endif
5218 #ifndef NO_CLIENT_CACHE
5219 #ifndef WOLFSSL_MUTEX_INITIALIZER
5220 if (ret == WOLFSSL_SUCCESS) {
5221 if (wc_InitMutex(&clisession_mutex) != 0) {
5222 WOLFSSL_MSG("Bad Init Mutex session");
5223 ret = BAD_MUTEX_E;
5224 }
5225 else {
5226 clisession_mutex_valid = 1;
5227 }
5228 }
5229 #endif
5230 #endif
5231#endif
5232#if defined(OPENSSL_EXTRA) && defined(HAVE_ATEXIT)
5233 /* OpenSSL registers cleanup using atexit */
5234 if ((ret == WOLFSSL_SUCCESS) && (atexit(AtExitCleanup) != 0)) {
5235 WOLFSSL_MSG("Bad atexit registration");
5236 ret = WC_INIT_E;
5237 }
5238#endif
5239 }
5240
5241#if defined(WOLFSSL_SYS_CRYPTO_POLICY)
5242 /* System wide crypto policy disabled by default. */
5243 XMEMSET(&crypto_policy, 0, sizeof(crypto_policy));
5244#endif /* WOLFSSL_SYS_CRYPTO_POLICY */
5245
5246 if (ret == WOLFSSL_SUCCESS) {
5247 initRefCount = initRefCount + 1;
5248 }
5249 else {
5250 initRefCount = 1; /* Force cleanup */
5251 }
5252
5253 wc_UnLockMutex(&inits_count_mutex);
5254
5255 if (ret != WOLFSSL_SUCCESS) {
5256 (void)wolfSSL_Cleanup(); /* Ignore any error from cleanup */
5257 }
5258
5259 return ret;
5260}
5261
5262#if defined(WOLFSSL_SYS_CRYPTO_POLICY)
5263/* Helper function for wolfSSL_crypto_policy_enable and
5264 * wolfSSL_crypto_policy_enable_buffer.
5265 *
5266 * Parses the crypto policy string, verifies values,
5267 * and sets in global crypto policy struct. Not thread
5268 * safe. String length has already been verified.
5269 *
5270 * Returns WOLFSSL_SUCCESS on success.
5271 * Returns CRYPTO_POLICY_FORBIDDEN if already enabled.
5272 * Returns < 0 on misc error.
5273 * */
5274static int crypto_policy_parse(void)
5275{
5276 const char * hdr = WOLFSSL_SECLEVEL_STR;
5277 int sec_level = 0;
5278 size_t i = 0;
5279
5280 /* All policies should begin with "@SECLEVEL=<N>" (N={0..5}) followed
5281 * by bulk cipher list. */
5282 if (XMEMCMP(crypto_policy.str, hdr, strlen(hdr)) != 0) {
5283 WOLFSSL_MSG("error: crypto policy: invalid header");
5284 return WOLFSSL_BAD_FILE;
5285 }
5286
5287 {
5288 /* Extract the security level. */
5289 char * policy_mem = crypto_policy.str;
5290 policy_mem += strlen(hdr);
5291 sec_level = (int) (*policy_mem - '0');
5292 }
5293
5294 if (sec_level < MIN_WOLFSSL_SEC_LEVEL ||
5295 sec_level > MAX_WOLFSSL_SEC_LEVEL) {
5296 WOLFSSL_MSG_EX("error: invalid SECLEVEL: %d", sec_level);
5297 return WOLFSSL_BAD_FILE;
5298 }
5299
5300 /* Remove trailing '\r' or '\n'. */
5301 for (i = 0; i < MAX_WOLFSSL_CRYPTO_POLICY_SIZE; ++i) {
5302 if (crypto_policy.str[i] == '\0') {
5303 break;
5304 }
5305
5306 if (crypto_policy.str[i] == '\r' || crypto_policy.str[i] == '\n') {
5307 crypto_policy.str[i] = '\0';
5308 break;
5309 }
5310 }
5311
5312 #if defined(DEBUG_WOLFSSL_VERBOSE)
5313 WOLFSSL_MSG_EX("info: SECLEVEL=%d", sec_level);
5314 WOLFSSL_MSG_EX("info: using crypto-policy file: %s, %ld", policy_file, sz);
5315 #endif /* DEBUG_WOLFSSL_VERBOSE */
5316
5317 crypto_policy.secLevel = sec_level;
5318 crypto_policy.enabled = 1;
5319
5320 return WOLFSSL_SUCCESS;
5321}
5322
5323#ifndef NO_FILESYSTEM
5324/* Enables wolfSSL system wide crypto-policy, using the given policy
5325 * file arg. If NULL is passed, then the default system crypto-policy
5326 * file that was set at configure time will be used instead.
5327 *
5328 * While enabled:
5329 * - TLS methods, min key sizes, and cipher lists are all configured
5330 * automatically by the policy.
5331 * - Attempting to use lesser strength parameters will fail with
5332 * error CRYPTO_POLICY_FORBIDDEN.
5333 *
5334 * Disable with wolfSSL_crypto_policy_disable.
5335 *
5336 * Note: the wolfSSL_crypto_policy_X API are not thread safe, and should
5337 * only be called at program init time.
5338 *
5339 * Returns WOLFSSL_SUCCESS on success.
5340 * Returns CRYPTO_POLICY_FORBIDDEN if already enabled.
5341 * Returns < 0 on misc error.
5342 * */
5343int wolfSSL_crypto_policy_enable(const char * policy_file)
5344{
5345 XFILE file;
5346 long sz = 0;
5347 size_t n_read = 0;
5348
5349 WOLFSSL_ENTER("wolfSSL_crypto_policy_enable");
5350
5351 if (wolfSSL_crypto_policy_is_enabled()) {
5352 WOLFSSL_MSG_EX("error: crypto policy already enabled: %s",
5353 policy_file);
5354 return CRYPTO_POLICY_FORBIDDEN;
5355 }
5356
5357 if (policy_file == NULL) {
5358 /* Use the configure-time default if NULL passed. */
5359 policy_file = WC_STRINGIFY(WOLFSSL_CRYPTO_POLICY_FILE);
5360 }
5361
5362 if (policy_file == NULL || *policy_file == '\0') {
5363 WOLFSSL_MSG("error: crypto policy empty file");
5364 return BAD_FUNC_ARG;
5365 }
5366
5367 XMEMSET(&crypto_policy, 0, sizeof(crypto_policy));
5368
5369 file = XFOPEN(policy_file, "rb");
5370
5371 if (file == XBADFILE) {
5372 WOLFSSL_MSG_EX("error: crypto policy file open failed: %s",
5373 policy_file);
5374 return WOLFSSL_BAD_FILE;
5375 }
5376
5377 if (XFSEEK(file, 0, XSEEK_END) != 0) {
5378 WOLFSSL_MSG_EX("error: crypto policy file seek end failed: %s",
5379 policy_file);
5380 XFCLOSE(file);
5381 return WOLFSSL_BAD_FILE;
5382 }
5383
5384 sz = XFTELL(file);
5385
5386 if (XFSEEK(file, 0, XSEEK_SET) != 0) {
5387 WOLFSSL_MSG_EX("error: crypto policy file seek failed: %s",
5388 policy_file);
5389 XFCLOSE(file);
5390 return WOLFSSL_BAD_FILE;
5391 }
5392
5393 if (sz <= 0 || sz > MAX_WOLFSSL_CRYPTO_POLICY_SIZE) {
5394 WOLFSSL_MSG_EX("error: crypto policy file %s, invalid size: %ld",
5395 policy_file, sz);
5396 XFCLOSE(file);
5397 return WOLFSSL_BAD_FILE;
5398 }
5399
5400 n_read = XFREAD(crypto_policy.str, 1, sz, file);
5401 XFCLOSE(file);
5402
5403 if (n_read != (size_t) sz) {
5404 WOLFSSL_MSG_EX("error: crypto policy file %s: read %zu, "
5405 "expected %ld", policy_file, n_read, sz);
5406 return WOLFSSL_BAD_FILE;
5407 }
5408
5409 crypto_policy.str[n_read] = '\0';
5410
5411 return crypto_policy_parse();
5412}
5413#endif /* ! NO_FILESYSTEM */
5414
5415/* Same behavior as wolfSSL_crypto_policy_enable, but loads
5416 * via memory buf instead of file.
5417 *
5418 * Returns WOLFSSL_SUCCESS on success.
5419 * Returns CRYPTO_POLICY_FORBIDDEN if already enabled.
5420 * Returns < 0 on misc error.
5421 * */
5422int wolfSSL_crypto_policy_enable_buffer(const char * buf)
5423{
5424 size_t sz = 0;
5425
5426 WOLFSSL_ENTER("wolfSSL_crypto_policy_enable_buffer");
5427
5428 if (wolfSSL_crypto_policy_is_enabled()) {
5429 WOLFSSL_MSG_EX("error: crypto policy already enabled");
5430 return CRYPTO_POLICY_FORBIDDEN;
5431 }
5432
5433 if (buf == NULL || *buf == '\0') {
5434 return BAD_FUNC_ARG;
5435 }
5436
5437 sz = XSTRLEN(buf);
5438
5439 if (sz == 0 || sz > MAX_WOLFSSL_CRYPTO_POLICY_SIZE) {
5440 return BAD_FUNC_ARG;
5441 }
5442
5443 XMEMSET(&crypto_policy, 0, sizeof(crypto_policy));
5444 XMEMCPY(crypto_policy.str, buf, sz);
5445
5446 return crypto_policy_parse();
5447}
5448
5449/* Returns whether the system wide crypto-policy is enabled.
5450 *
5451 * Returns 1 if enabled.
5452 * 0 if disabled.
5453 * */
5454int wolfSSL_crypto_policy_is_enabled(void)
5455{
5456 WOLFSSL_ENTER("wolfSSL_crypto_policy_is_enabled");
5457
5458 return crypto_policy.enabled == 1;
5459}
5460
5461/* Disables the system wide crypto-policy.
5462 * note: SSL and CTX structures already instantiated will
5463 * keep their security policy parameters. This will only
5464 * affect new instantiations.
5465 * */
5466void wolfSSL_crypto_policy_disable(void)
5467{
5468 WOLFSSL_ENTER("wolfSSL_crypto_policy_disable");
5469 crypto_policy.enabled = 0;
5470 XMEMSET(&crypto_policy, 0, sizeof(crypto_policy));
5471 return;
5472}
5473
5474/* Get the crypto-policy bulk cipher list string.
5475 * String is not owned by caller, should not be freed.
5476 *
5477 * Returns pointer to bulk cipher list string.
5478 * Returns NULL if NOT enabled, or on error.
5479 * */
5480const char * wolfSSL_crypto_policy_get_ciphers(void)
5481{
5482 WOLFSSL_ENTER("wolfSSL_crypto_policy_get_ciphers");
5483
5484 if (crypto_policy.enabled == 1) {
5485 /* The crypto policy config will have
5486 * this form:
5487 * "@SECLEVEL=2:kEECDH:kRSA..." */
5488 return crypto_policy.str;
5489 }
5490
5491 return NULL;
5492}
5493
5494/* Get the configured crypto-policy security level.
5495 * A security level of 0 does not impose any additional
5496 * restrictions.
5497 *
5498 * Returns 1 - 5 if enabled.
5499 * Returns 0 if NOT enabled.
5500 * */
5501int wolfSSL_crypto_policy_get_level(void)
5502{
5503 if (crypto_policy.enabled == 1) {
5504 return crypto_policy.secLevel;
5505 }
5506
5507 return 0;
5508}
5509
5510/* Get security level from ssl structure.
5511 * @param ssl a pointer to WOLFSSL structure
5512 */
5513int wolfSSL_get_security_level(const WOLFSSL * ssl)
5514{
5515 if (ssl == NULL) {
5516 return BAD_FUNC_ARG;
5517 }
5518
5519 return ssl->secLevel;
5520}
5521
5522#ifndef NO_WOLFSSL_STUB
5523/*
5524 * Set security level (wolfSSL doesn't support setting the security level).
5525 *
5526 * The security level can only be set through a system wide crypto-policy
5527 * with wolfSSL_crypto_policy_enable().
5528 *
5529 * @param ssl a pointer to WOLFSSL structure
5530 * @param level security level
5531 */
5532void wolfSSL_set_security_level(WOLFSSL * ssl, int level)
5533{
5534 WOLFSSL_ENTER("wolfSSL_set_security_level");
5535 (void)ssl;
5536 (void)level;
5537}
5538#endif /* !NO_WOLFSSL_STUB */
5539
5540#endif /* WOLFSSL_SYS_CRYPTO_POLICY */
5541
5542
5543#define WOLFSSL_SSL_LOAD_INCLUDED
5544#include <src/ssl_load.c>
5545
5546#define WOLFSSL_SSL_API_CRL_OCSP_INCLUDED
5547#include "src/ssl_api_crl_ocsp.c"
5548
5549
5550void wolfSSL_load_error_strings(void)
5551{
5552 /* compatibility only */
5553}
5554
5555
5556int wolfSSL_library_init(void)
5557{
5558 WOLFSSL_ENTER("wolfSSL_library_init");
5559 if (wolfSSL_Init() == WOLFSSL_SUCCESS)
5560 return WOLFSSL_SUCCESS;
5561 else
5562 return WOLFSSL_FATAL_ERROR;
5563}
5564
5565
5566#ifdef HAVE_SECRET_CALLBACK
5567
5568int wolfSSL_set_session_secret_cb(WOLFSSL* ssl, SessionSecretCb cb, void* ctx)
5569{
5570 WOLFSSL_ENTER("wolfSSL_set_session_secret_cb");
5571 if (ssl == NULL)
5572 return WOLFSSL_FAILURE;
5573
5574 ssl->sessionSecretCb = cb;
5575 ssl->sessionSecretCtx = ctx;
5576 if (cb != NULL) {
5577 /* If using a pre-set key, assume session resumption. */
5578 ssl->session->sessionIDSz = 0;
5579 ssl->options.resuming = 1;
5580 }
5581
5582 return WOLFSSL_SUCCESS;
5583}
5584
5585int wolfSSL_set_session_ticket_ext_cb(WOLFSSL* ssl, TicketParseCb cb,
5586 void *ctx)
5587{
5588 WOLFSSL_ENTER("wolfSSL_set_session_ticket_ext_cb");
5589 if (ssl == NULL)
5590 return WOLFSSL_FAILURE;
5591
5592 ssl->ticketParseCb = cb;
5593 ssl->ticketParseCtx = ctx;
5594
5595 return WOLFSSL_SUCCESS;
5596}
5597
5598int wolfSSL_set_secret_cb(WOLFSSL* ssl, TlsSecretCb cb, void* ctx)
5599{
5600 WOLFSSL_ENTER("wolfSSL_set_secret_cb");
5601 if (ssl == NULL)
5602 return WOLFSSL_FATAL_ERROR;
5603
5604 ssl->tlsSecretCb = cb;
5605 ssl->tlsSecretCtx = ctx;
5606
5607 return WOLFSSL_SUCCESS;
5608}
5609
5610#ifdef SHOW_SECRETS
5611int tlsShowSecrets(WOLFSSL* ssl, void* secret, int secretSz,
5612 void* ctx)
5613{
5614 /* Wireshark Pre-Master-Secret Format:
5615 * CLIENT_RANDOM <clientrandom> <mastersecret>
5616 */
5617 const char* CLIENT_RANDOM_LABEL = "CLIENT_RANDOM";
5618 int i, pmsPos = 0;
5619 char pmsBuf[13 + 1 + 64 + 1 + 96 + 1 + 1];
5620 byte clientRandom[RAN_LEN];
5621 int clientRandomSz;
5622
5623 (void)ctx;
5624
5625 clientRandomSz = (int)wolfSSL_get_client_random(ssl, clientRandom,
5626 sizeof(clientRandom));
5627
5628 if (clientRandomSz <= 0) {
5629 printf("Error getting server random %d\n", clientRandomSz);
5630 return BAD_FUNC_ARG;
5631 }
5632
5633 XSNPRINTF(&pmsBuf[pmsPos], sizeof(pmsBuf) - pmsPos, "%s ",
5634 CLIENT_RANDOM_LABEL);
5635 pmsPos += XSTRLEN(CLIENT_RANDOM_LABEL) + 1;
5636 for (i = 0; i < clientRandomSz; i++) {
5637 XSNPRINTF(&pmsBuf[pmsPos], sizeof(pmsBuf) - pmsPos, "%02x",
5638 clientRandom[i]);
5639 pmsPos += 2;
5640 }
5641 XSNPRINTF(&pmsBuf[pmsPos], sizeof(pmsBuf) - pmsPos, " ");
5642 pmsPos += 1;
5643 for (i = 0; i < secretSz; i++) {
5644 XSNPRINTF(&pmsBuf[pmsPos], sizeof(pmsBuf) - pmsPos, "%02x",
5645 ((byte*)secret)[i]);
5646 pmsPos += 2;
5647 }
5648 XSNPRINTF(&pmsBuf[pmsPos], sizeof(pmsBuf) - pmsPos, "\n");
5649 pmsPos += 1;
5650
5651 /* print master secret */
5652 puts(pmsBuf);
5653
5654 #if !defined(NO_FILESYSTEM) && defined(WOLFSSL_SSLKEYLOGFILE)
5655 {
5656 FILE* f = XFOPEN(WOLFSSL_SSLKEYLOGFILE_OUTPUT, "a");
5657 if (f != XBADFILE) {
5658 XFWRITE(pmsBuf, 1, pmsPos, f);
5659 XFCLOSE(f);
5660 }
5661 }
5662 #endif
5663 return 0;
5664}
5665#endif /* SHOW_SECRETS */
5666
5667#endif
5668
5669
5670#ifdef OPENSSL_EXTRA
5671
5672/*
5673 * check if the list has TLS13 and pre-TLS13 suites
5674 * @param list cipher suite list that user want to set
5675 * (caller required to check for NULL)
5676 * @return mixed: 0, only pre-TLS13: 1, only TLS13: 2
5677 */
5678static int CheckcipherList(const char* list)
5679{
5680 int ret;
5681 int findTLSv13Suites = 0;
5682 int findbeforeSuites = 0;
5683 byte cipherSuite0;
5684 byte cipherSuite1;
5685 int flags;
5686 char* next = (char*)list;
5687
5688 do {
5689 char* current = next;
5690 char name[MAX_SUITE_NAME + 1];
5691 word32 length = MAX_SUITE_NAME;
5692 word32 current_length;
5693 byte major = INVALID_BYTE;
5694 byte minor = INVALID_BYTE;
5695
5696 next = XSTRSTR(next, ":");
5697
5698 if (next) {
5699 current_length = (word32)(next - current);
5700 ++next; /* increment to skip ':' */
5701 }
5702 else {
5703 current_length = (word32)XSTRLEN(current);
5704 }
5705
5706 if (current_length == 0) {
5707 break;
5708 }
5709
5710 if (current_length < length) {
5711 length = current_length;
5712 }
5713 XMEMCPY(name, current, length);
5714 name[length] = 0;
5715
5716 if (XSTRCMP(name, "ALL") == 0 ||
5717 XSTRCMP(name, "DEFAULT") == 0 ||
5718 XSTRCMP(name, "HIGH") == 0)
5719 {
5720 findTLSv13Suites = 1;
5721 findbeforeSuites = 1;
5722 break;
5723 }
5724
5725 ret = GetCipherSuiteFromName(name, &cipherSuite0,
5726 &cipherSuite1, &major, &minor, &flags);
5727 if (ret == 0) {
5728 if (cipherSuite0 == TLS13_BYTE || minor == TLSv1_3_MINOR) {
5729 /* TLSv13 suite */
5730 findTLSv13Suites = 1;
5731 }
5732 else {
5733 findbeforeSuites = 1;
5734 }
5735 }
5736
5737 #if defined(OPENSSL_EXTRA) || defined(OPENSSL_ALL)
5738 /* check if mixed due to names like RSA:ECDHE+AESGCM etc. */
5739 if (ret != 0) {
5740 char* subStr = name;
5741 char* subStrNext;
5742
5743 do {
5744 subStrNext = XSTRSTR(subStr, "+");
5745
5746 if ((XSTRCMP(subStr, "ECDHE") == 0) ||
5747 (XSTRCMP(subStr, "RSA") == 0)) {
5748 return 0;
5749 }
5750
5751 if (subStrNext && (XSTRLEN(subStrNext) > 0)) {
5752 subStr = subStrNext + 1; /* +1 to skip past '+' */
5753 }
5754 } while (subStrNext != NULL);
5755 }
5756 #endif
5757
5758 if (findTLSv13Suites == 1 && findbeforeSuites == 1) {
5759 /* list has mixed suites */
5760 return 0;
5761 }
5762 } while (next);
5763
5764 if (findTLSv13Suites == 0 && findbeforeSuites == 1) {
5765 ret = 1;/* only before TLSv13 suites */
5766 }
5767 else if (findTLSv13Suites == 1 && findbeforeSuites == 0) {
5768 ret = 2;/* only TLSv13 suties */
5769 }
5770 else {
5771 ret = 0;/* handle as mixed */
5772 }
5773 return ret;
5774}
5775
5776/* parse some bulk lists like !eNULL / !aNULL
5777 *
5778 * returns WOLFSSL_SUCCESS on success and sets the cipher suite list
5779 */
5780static int wolfSSL_parse_cipher_list(WOLFSSL_CTX* ctx, WOLFSSL* ssl,
5781 Suites* suites, const char* list)
5782{
5783 int ret = 0;
5784 int listattribute = 0;
5785 int tls13Only = 0;
5786 WC_DECLARE_VAR(suitesCpy, byte, WOLFSSL_MAX_SUITE_SZ, 0);
5787 word16 suitesCpySz = 0;
5788 word16 i = 0;
5789 word16 j = 0;
5790
5791 if (suites == NULL || list == NULL) {
5792 WOLFSSL_MSG("NULL argument");
5793 return WOLFSSL_FAILURE;
5794 }
5795
5796 listattribute = CheckcipherList(list);
5797
5798 if (listattribute == 0) {
5799 /* list has mixed(pre-TLSv13 and TLSv13) suites
5800 * update cipher suites the same as before
5801 */
5802 return (SetCipherList_ex(ctx, ssl, suites, list)) ? WOLFSSL_SUCCESS :
5803 WOLFSSL_FAILURE;
5804 }
5805 else if (listattribute == 1) {
5806 /* list has only pre-TLSv13 suites.
5807 * Only update before TLSv13 suites.
5808 */
5809 tls13Only = 0;
5810 }
5811 else if (listattribute == 2) {
5812 /* list has only TLSv13 suites. Only update TLv13 suites
5813 * simulate set_ciphersuites() compatibility layer API
5814 */
5815 tls13Only = 1;
5816 if ((ctx != NULL && !IsAtLeastTLSv1_3(ctx->method->version)) ||
5817 (ssl != NULL && !IsAtLeastTLSv1_3(ssl->version))) {
5818 /* Silently ignore TLS 1.3 ciphers if we don't support it. */
5819 return WOLFSSL_SUCCESS;
5820 }
5821 }
5822
5823 /* list contains ciphers either only for TLS 1.3 or <= TLS 1.2 */
5824#ifdef WOLFSSL_SMALL_STACK
5825 if (suites->suiteSz > 0) {
5826 suitesCpy = (byte*)XMALLOC(suites->suiteSz, NULL,
5827 DYNAMIC_TYPE_TMP_BUFFER);
5828 if (suitesCpy == NULL) {
5829 return WOLFSSL_FAILURE;
5830 }
5831
5832 XMEMSET(suitesCpy, 0, suites->suiteSz);
5833 }
5834#else
5835 XMEMSET(suitesCpy, 0, sizeof(suitesCpy));
5836#endif
5837
5838 if (suites->suiteSz > 0)
5839 XMEMCPY(suitesCpy, suites->suites, suites->suiteSz);
5840 suitesCpySz = suites->suiteSz;
5841
5842 ret = SetCipherList_ex(ctx, ssl, suites, list);
5843 if (ret != 1) {
5844 WC_FREE_VAR_EX(suitesCpy, NULL, DYNAMIC_TYPE_TMP_BUFFER);
5845 return WOLFSSL_FAILURE;
5846 }
5847
5848 /* The idea in this section is that OpenSSL has two API to set ciphersuites.
5849 * - SSL_CTX_set_cipher_list for setting TLS <= 1.2 suites
5850 * - SSL_CTX_set_ciphersuites for setting TLS 1.3 suites
5851 * Since we direct both API here we attempt to provide API compatibility. If
5852 * we only get suites from <= 1.2 or == 1.3 then we will only update those
5853 * suites and keep the suites from the other group.
5854 * If downgrade is disabled, skip preserving the other group's suites. */
5855 if ((ssl != NULL && !ssl->options.downgrade) ||
5856 (ctx != NULL && !ctx->method->downgrade)) {
5857 /* Downgrade disabled - don't preserve other group's suites */
5858 WC_FREE_VAR_EX(suitesCpy, NULL, DYNAMIC_TYPE_TMP_BUFFER);
5859 return ret;
5860 }
5861
5862 for (i = 0; i < suitesCpySz &&
5863 suites->suiteSz <= (WOLFSSL_MAX_SUITE_SZ - SUITE_LEN); i += 2) {
5864 /* Check for duplicates */
5865 int duplicate = 0;
5866 for (j = 0; j < suites->suiteSz; j += 2) {
5867 if (suitesCpy[i] == suites->suites[j] &&
5868 suitesCpy[i+1] == suites->suites[j+1]) {
5869 duplicate = 1;
5870 break;
5871 }
5872 }
5873 if (!duplicate) {
5874 if (tls13Only) {
5875 /* Updating TLS 1.3 ciphers */
5876 if (suitesCpy[i] != TLS13_BYTE) {
5877 /* Only copy over <= TLS 1.2 ciphers */
5878 /* TLS 1.3 ciphers take precedence */
5879 suites->suites[suites->suiteSz++] = suitesCpy[i];
5880 suites->suites[suites->suiteSz++] = suitesCpy[i+1];
5881 }
5882 }
5883 else {
5884 /* Updating <= TLS 1.2 ciphers */
5885 if (suitesCpy[i] == TLS13_BYTE) {
5886 /* Only copy over TLS 1.3 ciphers */
5887 /* TLS 1.3 ciphers take precedence */
5888 XMEMMOVE(suites->suites + SUITE_LEN, suites->suites,
5889 suites->suiteSz);
5890 suites->suites[0] = suitesCpy[i];
5891 suites->suites[1] = suitesCpy[i+1];
5892 suites->suiteSz += 2;
5893 }
5894 }
5895 }
5896 }
5897
5898 WC_FREE_VAR_EX(suitesCpy, NULL, DYNAMIC_TYPE_TMP_BUFFER);
5899 return ret;
5900}
5901
5902#endif
5903
5904
5905int wolfSSL_CTX_set_cipher_list(WOLFSSL_CTX* ctx, const char* list)
5906{
5907 WOLFSSL_ENTER("wolfSSL_CTX_set_cipher_list");
5908
5909 if (ctx == NULL)
5910 return WOLFSSL_FAILURE;
5911
5912 if (AllocateCtxSuites(ctx) != 0)
5913 return WOLFSSL_FAILURE;
5914
5915#ifdef OPENSSL_EXTRA
5916 return wolfSSL_parse_cipher_list(ctx, NULL, ctx->suites, list);
5917#else
5918 return (SetCipherList(ctx, ctx->suites, list)) ?
5919 WOLFSSL_SUCCESS : WOLFSSL_FAILURE;
5920#endif
5921}
5922
5923#if defined(OPENSSL_EXTRA) || defined(WOLFSSL_SET_CIPHER_BYTES)
5924int wolfSSL_CTX_set_cipher_list_bytes(WOLFSSL_CTX* ctx, const byte* list,
5925 const int listSz)
5926{
5927 WOLFSSL_ENTER("wolfSSL_CTX_set_cipher_list_bytes");
5928
5929 if (ctx == NULL)
5930 return WOLFSSL_FAILURE;
5931
5932 if (AllocateCtxSuites(ctx) != 0)
5933 return WOLFSSL_FAILURE;
5934
5935 return (SetCipherListFromBytes(ctx, ctx->suites, list, listSz)) ?
5936 WOLFSSL_SUCCESS : WOLFSSL_FAILURE;
5937}
5938#endif /* OPENSSL_EXTRA || WOLFSSL_SET_CIPHER_BYTES */
5939
5940int wolfSSL_set_cipher_list(WOLFSSL* ssl, const char* list)
5941{
5942 WOLFSSL_ENTER("wolfSSL_set_cipher_list");
5943
5944 if (ssl == NULL || ssl->ctx == NULL) {
5945 return WOLFSSL_FAILURE;
5946 }
5947
5948 if (AllocateSuites(ssl) != 0)
5949 return WOLFSSL_FAILURE;
5950
5951#ifdef OPENSSL_EXTRA
5952 return wolfSSL_parse_cipher_list(NULL, ssl, ssl->suites, list);
5953#else
5954 return (SetCipherList_ex(NULL, ssl, ssl->suites, list)) ?
5955 WOLFSSL_SUCCESS :
5956 WOLFSSL_FAILURE;
5957#endif
5958}
5959
5960#if defined(OPENSSL_EXTRA) || defined(WOLFSSL_SET_CIPHER_BYTES)
5961int wolfSSL_set_cipher_list_bytes(WOLFSSL* ssl, const byte* list,
5962 const int listSz)
5963{
5964 WOLFSSL_ENTER("wolfSSL_set_cipher_list_bytes");
5965
5966 if (ssl == NULL || ssl->ctx == NULL) {
5967 return WOLFSSL_FAILURE;
5968 }
5969
5970 if (AllocateSuites(ssl) != 0)
5971 return WOLFSSL_FAILURE;
5972
5973 return (SetCipherListFromBytes(ssl->ctx, ssl->suites, list, listSz))
5974 ? WOLFSSL_SUCCESS
5975 : WOLFSSL_FAILURE;
5976}
5977#endif /* OPENSSL_EXTRA || WOLFSSL_SET_CIPHER_BYTES */
5978
5979
5980#ifdef HAVE_KEYING_MATERIAL
5981
5982#define TLS_PRF_LABEL_CLIENT_FINISHED "client finished"
5983#define TLS_PRF_LABEL_SERVER_FINISHED "server finished"
5984#define TLS_PRF_LABEL_MASTER_SECRET "master secret"
5985#define TLS_PRF_LABEL_EXT_MASTER_SECRET "extended master secret"
5986#define TLS_PRF_LABEL_KEY_EXPANSION "key expansion"
5987
5988static const struct ForbiddenLabels {
5989 const char* label;
5990 size_t labelLen;
5991} forbiddenLabels[] = {
5992 {TLS_PRF_LABEL_CLIENT_FINISHED, XSTR_SIZEOF(TLS_PRF_LABEL_CLIENT_FINISHED)},
5993 {TLS_PRF_LABEL_SERVER_FINISHED, XSTR_SIZEOF(TLS_PRF_LABEL_SERVER_FINISHED)},
5994 {TLS_PRF_LABEL_MASTER_SECRET, XSTR_SIZEOF(TLS_PRF_LABEL_MASTER_SECRET)},
5995 {TLS_PRF_LABEL_EXT_MASTER_SECRET,
5996 XSTR_SIZEOF(TLS_PRF_LABEL_EXT_MASTER_SECRET)},
5997 {TLS_PRF_LABEL_KEY_EXPANSION, XSTR_SIZEOF(TLS_PRF_LABEL_KEY_EXPANSION)},
5998 {NULL, 0},
5999};
6000
6001/**
6002 * Implement RFC 5705
6003 * TLS 1.3 uses a different exporter definition (section 7.5 of RFC 8446)
6004 * @return WOLFSSL_SUCCESS on success and WOLFSSL_FAILURE on error
6005 */
6006int wolfSSL_export_keying_material(WOLFSSL *ssl,
6007 unsigned char *out, size_t outLen,
6008 const char *label, size_t labelLen,
6009 const unsigned char *context, size_t contextLen,
6010 int use_context)
6011{
6012 byte* seed = NULL;
6013 word32 seedLen;
6014 const struct ForbiddenLabels* fl;
6015
6016 WOLFSSL_ENTER("wolfSSL_export_keying_material");
6017
6018 if (ssl == NULL || out == NULL || label == NULL ||
6019 (use_context && contextLen && context == NULL)) {
6020 WOLFSSL_MSG("Bad argument");
6021 return WOLFSSL_FAILURE;
6022 }
6023
6024 /* Sanity check contextLen to prevent integer overflow when cast to word32
6025 * and to ensure it fits in the 2-byte length encoding (max 65535). */
6026 if (use_context && contextLen > WOLFSSL_MAX_16BIT) {
6027 WOLFSSL_MSG("contextLen too large");
6028 return WOLFSSL_FAILURE;
6029 }
6030
6031 /* clientRandom + serverRandom
6032 * OR
6033 * clientRandom + serverRandom + ctx len encoding + ctx */
6034 seedLen = !use_context ? (word32)SEED_LEN :
6035 (word32)SEED_LEN + 2 + (word32)contextLen;
6036
6037 if (ssl->options.saveArrays == 0 || ssl->arrays == NULL) {
6038 WOLFSSL_MSG("To export keying material wolfSSL needs to keep handshake "
6039 "data. Call wolfSSL_KeepArrays before attempting to "
6040 "export keyid material.");
6041 return WOLFSSL_FAILURE;
6042 }
6043
6044 /* check forbidden labels */
6045 for (fl = &forbiddenLabels[0]; fl->label != NULL; fl++) {
6046 if (labelLen >= fl->labelLen &&
6047 XMEMCMP(label, fl->label, fl->labelLen) == 0) {
6048 WOLFSSL_MSG("Forbidden label");
6049 return WOLFSSL_FAILURE;
6050 }
6051 }
6052
6053#ifdef WOLFSSL_TLS13
6054 if (IsAtLeastTLSv1_3(ssl->version)) {
6055 /* Path for TLS 1.3 */
6056 if (!use_context) {
6057 contextLen = 0;
6058 context = (byte*)""; /* Give valid pointer for 0 length memcpy */
6059 }
6060
6061 if (Tls13_Exporter(ssl, out, (word32)outLen, label, labelLen,
6062 context, contextLen) != 0) {
6063 WOLFSSL_MSG("Tls13_Exporter error");
6064 return WOLFSSL_FAILURE;
6065 }
6066 return WOLFSSL_SUCCESS;
6067 }
6068#endif
6069
6070 /* Path for <=TLS 1.2 */
6071 seed = (byte*)XMALLOC(seedLen, NULL, DYNAMIC_TYPE_TMP_BUFFER);
6072 if (seed == NULL) {
6073 WOLFSSL_MSG("malloc error");
6074 return WOLFSSL_FAILURE;
6075 }
6076
6077 XMEMCPY(seed, ssl->arrays->clientRandom, RAN_LEN);
6078 XMEMCPY(seed + RAN_LEN, ssl->arrays->serverRandom, RAN_LEN);
6079
6080 if (use_context) {
6081 /* Encode len in big endian */
6082 seed[SEED_LEN ] = (contextLen >> 8) & 0xFF;
6083 seed[SEED_LEN + 1] = (contextLen) & 0xFF;
6084 if (contextLen) {
6085 /* 0 length context is allowed */
6086 XMEMCPY(seed + SEED_LEN + 2, context, contextLen);
6087 }
6088 }
6089
6090 PRIVATE_KEY_UNLOCK();
6091 if (wc_PRF_TLS(out, (word32)outLen, ssl->arrays->masterSecret, SECRET_LEN,
6092 (byte*)label, (word32)labelLen, seed, seedLen,
6093 IsAtLeastTLSv1_2(ssl), ssl->specs.mac_algorithm, ssl->heap,
6094 ssl->devId) != 0) {
6095 WOLFSSL_MSG("wc_PRF_TLS error");
6096 PRIVATE_KEY_LOCK();
6097 XFREE(seed, NULL, DYNAMIC_TYPE_TMP_BUFFER);
6098 return WOLFSSL_FAILURE;
6099 }
6100 PRIVATE_KEY_LOCK();
6101
6102 XFREE(seed, NULL, DYNAMIC_TYPE_TMP_BUFFER);
6103 return WOLFSSL_SUCCESS;
6104}
6105#endif /* HAVE_KEYING_MATERIAL */
6106
6107int wolfSSL_dtls_get_using_nonblock(WOLFSSL* ssl)
6108{
6109 int useNb = 0;
6110
6111 if (ssl == NULL)
6112 return WOLFSSL_FAILURE;
6113
6114 WOLFSSL_ENTER("wolfSSL_dtls_get_using_nonblock");
6115 if (ssl->options.dtls) {
6116#ifdef WOLFSSL_DTLS
6117 useNb = ssl->options.dtlsUseNonblock;
6118#endif
6119 }
6120 else {
6121 WOLFSSL_MSG("wolfSSL_dtls_get_using_nonblock() is "
6122 "DEPRECATED for non-DTLS use.");
6123 }
6124 return useNb;
6125}
6126
6127
6128#ifndef WOLFSSL_LEANPSK
6129
6130void wolfSSL_dtls_set_using_nonblock(WOLFSSL* ssl, int nonblock)
6131{
6132 (void)nonblock;
6133
6134 WOLFSSL_ENTER("wolfSSL_dtls_set_using_nonblock");
6135
6136 if (ssl == NULL)
6137 return;
6138
6139 if (ssl->options.dtls) {
6140#ifdef WOLFSSL_DTLS
6141 ssl->options.dtlsUseNonblock = (nonblock != 0);
6142#endif
6143 }
6144 else {
6145 WOLFSSL_MSG("wolfSSL_dtls_set_using_nonblock() is "
6146 "DEPRECATED for non-DTLS use.");
6147 }
6148}
6149
6150
6151#ifdef WOLFSSL_DTLS
6152
6153int wolfSSL_dtls_get_current_timeout(WOLFSSL* ssl)
6154{
6155 int timeout = 0;
6156 if (ssl)
6157 timeout = ssl->dtls_timeout;
6158
6159 WOLFSSL_LEAVE("wolfSSL_dtls_get_current_timeout", timeout);
6160 return timeout;
6161}
6162
6163#ifdef WOLFSSL_DTLS13
6164
6165/*
6166 * This API returns 1 when the user should set a short timeout for receiving
6167 * data. It is recommended that it is at most 1/4 the value returned by
6168 * wolfSSL_dtls_get_current_timeout().
6169 */
6170int wolfSSL_dtls13_use_quick_timeout(WOLFSSL* ssl)
6171{
6172 return ssl != NULL && ssl->dtls13FastTimeout;
6173}
6174
6175/*
6176 * When this is set, a DTLS 1.3 connection will send acks immediately when a
6177 * disruption is detected to shortcut timeouts. This results in potentially
6178 * more traffic but may make the handshake quicker.
6179 */
6180void wolfSSL_dtls13_set_send_more_acks(WOLFSSL* ssl, int value)
6181{
6182 if (ssl != NULL)
6183 ssl->options.dtls13SendMoreAcks = !!value;
6184}
6185#endif /* WOLFSSL_DTLS13 */
6186
6187int wolfSSL_DTLSv1_get_timeout(WOLFSSL* ssl, WOLFSSL_TIMEVAL* timeleft)
6188{
6189 if (ssl && timeleft) {
6190 XMEMSET(timeleft, 0, sizeof(WOLFSSL_TIMEVAL));
6191 timeleft->tv_sec = ssl->dtls_timeout;
6192 }
6193 return 0;
6194}
6195
6196#ifndef NO_WOLFSSL_STUB
6197int wolfSSL_DTLSv1_handle_timeout(WOLFSSL* ssl)
6198{
6199 WOLFSSL_STUB("SSL_DTLSv1_handle_timeout");
6200 (void)ssl;
6201 return 0;
6202}
6203#endif
6204
6205#ifndef NO_WOLFSSL_STUB
6206void wolfSSL_DTLSv1_set_initial_timeout_duration(WOLFSSL* ssl,
6207 word32 duration_ms)
6208{
6209 WOLFSSL_STUB("SSL_DTLSv1_set_initial_timeout_duration");
6210 (void)ssl;
6211 (void)duration_ms;
6212}
6213#endif
6214
6215/* user may need to alter init dtls recv timeout, WOLFSSL_SUCCESS on ok */
6216int wolfSSL_dtls_set_timeout_init(WOLFSSL* ssl, int timeout)
6217{
6218 if (ssl == NULL || timeout < 0)
6219 return BAD_FUNC_ARG;
6220
6221 if (timeout > ssl->dtls_timeout_max) {
6222 WOLFSSL_MSG("Can't set dtls timeout init greater than dtls timeout "
6223 "max");
6224 return BAD_FUNC_ARG;
6225 }
6226
6227 ssl->dtls_timeout_init = timeout;
6228 ssl->dtls_timeout = timeout;
6229
6230 return WOLFSSL_SUCCESS;
6231}
6232
6233
6234/* user may need to alter max dtls recv timeout, WOLFSSL_SUCCESS on ok */
6235int wolfSSL_dtls_set_timeout_max(WOLFSSL* ssl, int timeout)
6236{
6237 if (ssl == NULL || timeout < 0)
6238 return BAD_FUNC_ARG;
6239
6240 if (timeout < ssl->dtls_timeout_init) {
6241 WOLFSSL_MSG("Can't set dtls timeout max less than dtls timeout init");
6242 return BAD_FUNC_ARG;
6243 }
6244
6245 ssl->dtls_timeout_max = timeout;
6246
6247 return WOLFSSL_SUCCESS;
6248}
6249
6250
6251int wolfSSL_dtls_got_timeout(WOLFSSL* ssl)
6252{
6253 int result = WOLFSSL_SUCCESS;
6254 WOLFSSL_ENTER("wolfSSL_dtls_got_timeout");
6255
6256 if (ssl == NULL || !ssl->options.dtls)
6257 return WOLFSSL_FATAL_ERROR;
6258
6259#ifdef WOLFSSL_DTLS13
6260 if (IsAtLeastTLSv1_3(ssl->version)) {
6261 result = Dtls13RtxTimeout(ssl);
6262 if (result < 0) {
6263 if (result == WC_NO_ERR_TRACE(WANT_WRITE))
6264 ssl->dtls13SendingAckOrRtx = 1;
6265 ssl->error = result;
6266 WOLFSSL_ERROR(result);
6267 return WOLFSSL_FATAL_ERROR;
6268 }
6269
6270 return WOLFSSL_SUCCESS;
6271 }
6272#endif /* WOLFSSL_DTLS13 */
6273
6274 /* Do we have any 1.2 messages stored? */
6275 if (ssl->dtls_tx_msg_list != NULL || ssl->dtls_tx_msg != NULL) {
6276 if (DtlsMsgPoolTimeout(ssl) < 0){
6277 ssl->error = SOCKET_ERROR_E;
6278 WOLFSSL_ERROR(ssl->error);
6279 result = WOLFSSL_FATAL_ERROR;
6280 }
6281 else if ((result = DtlsMsgPoolSend(ssl, 0)) < 0) {
6282 ssl->error = result;
6283 WOLFSSL_ERROR(result);
6284 result = WOLFSSL_FATAL_ERROR;
6285 }
6286 else {
6287 /* Reset return value to success */
6288 result = WOLFSSL_SUCCESS;
6289 }
6290 }
6291
6292 WOLFSSL_LEAVE("wolfSSL_dtls_got_timeout", result);
6293 return result;
6294}
6295
6296
6297/* retransmit all the saves messages, WOLFSSL_SUCCESS on ok */
6298int wolfSSL_dtls_retransmit(WOLFSSL* ssl)
6299{
6300 WOLFSSL_ENTER("wolfSSL_dtls_retransmit");
6301
6302 if (ssl == NULL)
6303 return WOLFSSL_FATAL_ERROR;
6304
6305 if (!ssl->options.handShakeDone) {
6306 int result;
6307#ifdef WOLFSSL_DTLS13
6308 if (IsAtLeastTLSv1_3(ssl->version))
6309 result = Dtls13DoScheduledWork(ssl);
6310 else
6311#endif
6312 result = DtlsMsgPoolSend(ssl, 0);
6313 if (result < 0) {
6314 ssl->error = result;
6315 WOLFSSL_ERROR(result);
6316 return WOLFSSL_FATAL_ERROR;
6317 }
6318 }
6319
6320 return WOLFSSL_SUCCESS;
6321}
6322
6323#endif /* DTLS */
6324#endif /* LEANPSK */
6325
6326
6327#if defined(WOLFSSL_DTLS) && !defined(NO_WOLFSSL_SERVER)
6328
6329/* Not an SSL function, return 0 for success, error code otherwise */
6330/* Prereq: ssl's RNG needs to be initialized. */
6331int wolfSSL_DTLS_SetCookieSecret(WOLFSSL* ssl,
6332 const byte* secret, word32 secretSz)
6333{
6334 int ret = 0;
6335
6336 WOLFSSL_ENTER("wolfSSL_DTLS_SetCookieSecret");
6337
6338 if (ssl == NULL) {
6339 WOLFSSL_MSG("need a SSL object");
6340 return BAD_FUNC_ARG;
6341 }
6342
6343 if (secret != NULL && secretSz == 0) {
6344 WOLFSSL_MSG("can't have a new secret without a size");
6345 return BAD_FUNC_ARG;
6346 }
6347
6348 /* If secretSz is 0, use the default size. */
6349 if (secretSz == 0)
6350 secretSz = COOKIE_SECRET_SZ;
6351
6352 if (secretSz != ssl->buffers.dtlsCookieSecret.length) {
6353 byte* newSecret;
6354
6355 if (ssl->buffers.dtlsCookieSecret.buffer != NULL) {
6356 ForceZero(ssl->buffers.dtlsCookieSecret.buffer,
6357 ssl->buffers.dtlsCookieSecret.length);
6358 XFREE(ssl->buffers.dtlsCookieSecret.buffer,
6359 ssl->heap, DYNAMIC_TYPE_COOKIE_PWD);
6360 }
6361
6362 newSecret = (byte*)XMALLOC(secretSz, ssl->heap,DYNAMIC_TYPE_COOKIE_PWD);
6363 if (newSecret == NULL) {
6364 ssl->buffers.dtlsCookieSecret.buffer = NULL;
6365 ssl->buffers.dtlsCookieSecret.length = 0;
6366 WOLFSSL_MSG("couldn't allocate new cookie secret");
6367 return MEMORY_ERROR;
6368 }
6369 ssl->buffers.dtlsCookieSecret.buffer = newSecret;
6370 ssl->buffers.dtlsCookieSecret.length = secretSz;
6371 #ifdef WOLFSSL_CHECK_MEM_ZERO
6372 wc_MemZero_Add("wolfSSL_DTLS_SetCookieSecret secret",
6373 ssl->buffers.dtlsCookieSecret.buffer,
6374 ssl->buffers.dtlsCookieSecret.length);
6375 #endif
6376 }
6377
6378 /* If the supplied secret is NULL, randomly generate a new secret. */
6379 if (secret == NULL) {
6380 ret = wc_RNG_GenerateBlock(ssl->rng,
6381 ssl->buffers.dtlsCookieSecret.buffer, secretSz);
6382 }
6383 else
6384 XMEMCPY(ssl->buffers.dtlsCookieSecret.buffer, secret, secretSz);
6385
6386 WOLFSSL_LEAVE("wolfSSL_DTLS_SetCookieSecret", 0);
6387 return ret;
6388}
6389
6390#endif /* WOLFSSL_DTLS && !NO_WOLFSSL_SERVER */
6391
6392
6393/* EITHER SIDE METHODS */
6394#if !defined(NO_TLS) && (defined(OPENSSL_EXTRA) || defined(WOLFSSL_EITHER_SIDE))
6395 WOLFSSL_METHOD* wolfSSLv23_method(void)
6396 {
6397 return wolfSSLv23_method_ex(NULL);
6398 }
6399 WOLFSSL_METHOD* wolfSSLv23_method_ex(void* heap)
6400 {
6401 WOLFSSL_METHOD* m = NULL;
6402 WOLFSSL_ENTER("wolfSSLv23_method");
6403 #if !defined(NO_WOLFSSL_CLIENT)
6404 m = wolfSSLv23_client_method_ex(heap);
6405 #elif !defined(NO_WOLFSSL_SERVER)
6406 m = wolfSSLv23_server_method_ex(heap);
6407 #else
6408 (void)heap;
6409 #endif
6410 if (m != NULL) {
6411 m->side = WOLFSSL_NEITHER_END;
6412 }
6413
6414 return m;
6415 }
6416
6417 #ifndef NO_OLD_TLS
6418 #ifdef WOLFSSL_ALLOW_SSLV3
6419 WOLFSSL_METHOD* wolfSSLv3_method(void)
6420 {
6421 return wolfSSLv3_method_ex(NULL);
6422 }
6423 WOLFSSL_METHOD* wolfSSLv3_method_ex(void* heap)
6424 {
6425 WOLFSSL_METHOD* m = NULL;
6426 WOLFSSL_ENTER("wolfSSLv3_method_ex");
6427 #if !defined(NO_WOLFSSL_CLIENT)
6428 m = wolfSSLv3_client_method_ex(heap);
6429 #elif !defined(NO_WOLFSSL_SERVER)
6430 m = wolfSSLv3_server_method_ex(heap);
6431 #endif
6432 if (m != NULL) {
6433 m->side = WOLFSSL_NEITHER_END;
6434 }
6435
6436 return m;
6437 }
6438 #endif
6439 #endif
6440#endif /* !NO_TLS && (OPENSSL_EXTRA || WOLFSSL_EITHER_SIDE) */
6441
6442/* client only parts */
6443#if !defined(NO_WOLFSSL_CLIENT) && !defined(NO_TLS)
6444
6445 #if defined(OPENSSL_EXTRA) && !defined(NO_OLD_TLS)
6446 WOLFSSL_METHOD* wolfSSLv2_client_method(void)
6447 {
6448 WOLFSSL_STUB("wolfSSLv2_client_method");
6449 return NULL;
6450 }
6451 #endif
6452
6453 #if defined(WOLFSSL_ALLOW_SSLV3) && !defined(NO_OLD_TLS)
6454 WOLFSSL_METHOD* wolfSSLv3_client_method(void)
6455 {
6456 return wolfSSLv3_client_method_ex(NULL);
6457 }
6458 WOLFSSL_METHOD* wolfSSLv3_client_method_ex(void* heap)
6459 {
6460 WOLFSSL_METHOD* method =
6461 (WOLFSSL_METHOD*) XMALLOC(sizeof(WOLFSSL_METHOD),
6462 heap, DYNAMIC_TYPE_METHOD);
6463 (void)heap;
6464 WOLFSSL_ENTER("wolfSSLv3_client_method_ex");
6465 if (method)
6466 InitSSL_Method(method, MakeSSLv3());
6467 return method;
6468 }
6469 #endif /* WOLFSSL_ALLOW_SSLV3 && !NO_OLD_TLS */
6470
6471
6472 WOLFSSL_METHOD* wolfSSLv23_client_method(void)
6473 {
6474 return wolfSSLv23_client_method_ex(NULL);
6475 }
6476 WOLFSSL_METHOD* wolfSSLv23_client_method_ex(void* heap)
6477 {
6478 WOLFSSL_METHOD* method =
6479 (WOLFSSL_METHOD*) XMALLOC(sizeof(WOLFSSL_METHOD),
6480 heap, DYNAMIC_TYPE_METHOD);
6481 (void)heap;
6482 WOLFSSL_ENTER("wolfSSLv23_client_method_ex");
6483 if (method) {
6484 #if !defined(NO_SHA256) || defined(WOLFSSL_SHA384) || \
6485 defined(WOLFSSL_SHA512)
6486 #if defined(WOLFSSL_TLS13)
6487 InitSSL_Method(method, MakeTLSv1_3());
6488 #elif !defined(WOLFSSL_NO_TLS12)
6489 InitSSL_Method(method, MakeTLSv1_2());
6490 #elif !defined(NO_OLD_TLS)
6491 InitSSL_Method(method, MakeTLSv1_1());
6492 #endif
6493 #else
6494 #ifndef NO_OLD_TLS
6495 InitSSL_Method(method, MakeTLSv1_1());
6496 #endif
6497 #endif
6498 #if !defined(NO_OLD_TLS) || defined(WOLFSSL_TLS13)
6499 method->downgrade = 1;
6500 #endif
6501 }
6502 return method;
6503 }
6504
6505 /* please see note at top of README if you get an error from connect */
6506 WOLFSSL_ABI
6507 int wolfSSL_connect(WOLFSSL* ssl)
6508 {
6509 #if !(defined(WOLFSSL_NO_TLS12) && defined(NO_OLD_TLS) && \
6510 defined(WOLFSSL_TLS13))
6511 int neededState;
6512 byte advanceState;
6513 #endif
6514 int ret = 0;
6515
6516 (void)ret;
6517
6518 #ifdef HAVE_ERRNO_H
6519 errno = 0;
6520 #endif
6521
6522 if (ssl == NULL)
6523 return BAD_FUNC_ARG;
6524
6525 #if defined(OPENSSL_EXTRA) || defined(WOLFSSL_EITHER_SIDE)
6526 if (ssl->options.side == WOLFSSL_NEITHER_END) {
6527 ssl->error = InitSSL_Side(ssl, WOLFSSL_CLIENT_END);
6528 if (ssl->error != WOLFSSL_SUCCESS) {
6529 WOLFSSL_ERROR(ssl->error);
6530 return WOLFSSL_FATAL_ERROR;
6531 }
6532 ssl->error = 0; /* expected to be zero here */
6533 }
6534
6535 #ifdef OPENSSL_EXTRA
6536 if (ssl->CBIS != NULL) {
6537 ssl->CBIS(ssl, WOLFSSL_ST_CONNECT, WOLFSSL_SUCCESS);
6538 ssl->cbmode = WOLFSSL_CB_WRITE;
6539 }
6540 #endif
6541 #endif /* OPENSSL_EXTRA || WOLFSSL_EITHER_SIDE */
6542
6543 #if defined(WOLFSSL_NO_TLS12) && defined(NO_OLD_TLS) && \
6544 defined(WOLFSSL_TLS13)
6545 return wolfSSL_connect_TLSv13(ssl);
6546 #else
6547 #ifdef WOLFSSL_TLS13
6548 if (ssl->options.tls1_3) {
6549 WOLFSSL_MSG("TLS 1.3");
6550 return wolfSSL_connect_TLSv13(ssl);
6551 }
6552 #endif
6553
6554 WOLFSSL_MSG("TLS 1.2 or lower");
6555 WOLFSSL_ENTER("wolfSSL_connect");
6556
6557 /* make sure this wolfSSL object has arrays and rng setup. Protects
6558 * case where the WOLFSSL object is reused via wolfSSL_clear() */
6559 if ((ret = ReinitSSL(ssl, ssl->ctx, 0)) != 0) {
6560 return ret;
6561 }
6562
6563#ifdef WOLFSSL_WOLFSENTRY_HOOKS
6564 if ((ssl->ConnectFilter != NULL) &&
6565 (ssl->options.connectState == CONNECT_BEGIN)) {
6566 wolfSSL_netfilter_decision_t res;
6567 if ((ssl->ConnectFilter(ssl, ssl->ConnectFilter_arg, &res) ==
6568 WOLFSSL_SUCCESS) &&
6569 (res == WOLFSSL_NETFILTER_REJECT)) {
6570 ssl->error = SOCKET_FILTERED_E;
6571 WOLFSSL_ERROR(ssl->error);
6572 return WOLFSSL_FATAL_ERROR;
6573 }
6574 }
6575#endif /* WOLFSSL_WOLFSENTRY_HOOKS */
6576
6577 if (ssl->options.side != WOLFSSL_CLIENT_END) {
6578 ssl->error = SIDE_ERROR;
6579 WOLFSSL_ERROR(ssl->error);
6580 return WOLFSSL_FATAL_ERROR;
6581 }
6582
6583 #ifdef WOLFSSL_DTLS
6584 if (ssl->version.major == DTLS_MAJOR) {
6585 ssl->options.dtls = 1;
6586 ssl->options.tls = 1;
6587 ssl->options.tls1_1 = 1;
6588 ssl->options.dtlsStateful = 1;
6589 }
6590 #endif
6591
6592 /* fragOffset is non-zero when sending fragments. On the last
6593 * fragment, fragOffset is zero again, and the state can be
6594 * advanced. */
6595 advanceState = ssl->fragOffset == 0 &&
6596 (ssl->options.connectState == CONNECT_BEGIN ||
6597 ssl->options.connectState == HELLO_AGAIN ||
6598 (ssl->options.connectState >= FIRST_REPLY_DONE &&
6599 ssl->options.connectState <= FIRST_REPLY_FOURTH));
6600
6601#ifdef WOLFSSL_DTLS13
6602 if (ssl->options.dtls && IsAtLeastTLSv1_3(ssl->version))
6603 advanceState = advanceState && !ssl->dtls13SendingAckOrRtx;
6604#endif /* WOLFSSL_DTLS13 */
6605
6606 if (ssl->buffers.outputBuffer.length > 0
6607 #ifdef WOLFSSL_ASYNC_CRYPT
6608 /* do not send buffered or advance state if last error was an
6609 async pending operation */
6610 && ssl->error != WC_NO_ERR_TRACE(WC_PENDING_E)
6611 #endif
6612 ) {
6613 ret = SendBuffered(ssl);
6614 if (ret == 0) {
6615 if (ssl->fragOffset == 0 && !ssl->options.buildingMsg) {
6616 if (advanceState) {
6617 ssl->options.connectState++;
6618 WOLFSSL_MSG("connect state: Advanced from last "
6619 "buffered fragment send");
6620 #ifdef WOLFSSL_ASYNC_IO
6621 /* Cleanup async */
6622 FreeAsyncCtx(ssl, 0);
6623 #endif
6624 }
6625 }
6626 else {
6627 WOLFSSL_MSG("connect state: "
6628 "Not advanced, more fragments to send");
6629 }
6630 }
6631 else {
6632 ssl->error = ret;
6633 WOLFSSL_ERROR(ssl->error);
6634 return WOLFSSL_FATAL_ERROR;
6635 }
6636#ifdef WOLFSSL_DTLS13
6637 if (ssl->options.dtls)
6638 ssl->dtls13SendingAckOrRtx = 0;
6639#endif /* WOLFSSL_DTLS13 */
6640 }
6641
6642 ret = RetrySendAlert(ssl);
6643 if (ret != 0) {
6644 ssl->error = ret;
6645 WOLFSSL_ERROR(ssl->error);
6646 return WOLFSSL_FATAL_ERROR;
6647 }
6648
6649 switch (ssl->options.connectState) {
6650
6651 case CONNECT_BEGIN :
6652 /* always send client hello first */
6653 if ( (ssl->error = SendClientHello(ssl)) != 0) {
6654 WOLFSSL_ERROR(ssl->error);
6655 return WOLFSSL_FATAL_ERROR;
6656 }
6657 ssl->options.connectState = CLIENT_HELLO_SENT;
6658 WOLFSSL_MSG("connect state: CLIENT_HELLO_SENT");
6659 FALL_THROUGH;
6660
6661 case CLIENT_HELLO_SENT :
6662 neededState = ssl->options.resuming ? SERVER_FINISHED_COMPLETE :
6663 SERVER_HELLODONE_COMPLETE;
6664 #ifdef WOLFSSL_DTLS
6665 /* In DTLS, when resuming, we can go straight to FINISHED,
6666 * or do a cookie exchange and then skip to FINISHED, assume
6667 * we need the cookie exchange first. */
6668 if (IsDtlsNotSctpMode(ssl))
6669 neededState = SERVER_HELLOVERIFYREQUEST_COMPLETE;
6670 #endif
6671 /* get response */
6672 WOLFSSL_MSG("Server state up to needed state.");
6673 while (ssl->options.serverState < neededState) {
6674 WOLFSSL_MSG("Progressing server state...");
6675 #ifdef WOLFSSL_TLS13
6676 if (ssl->options.tls1_3)
6677 return wolfSSL_connect_TLSv13(ssl);
6678 #endif
6679 WOLFSSL_MSG("ProcessReply...");
6680 if ( (ssl->error = ProcessReply(ssl)) < 0) {
6681 WOLFSSL_ERROR(ssl->error);
6682 return WOLFSSL_FATAL_ERROR;
6683 }
6684 /* if resumption failed, reset needed state */
6685 else if (neededState == SERVER_FINISHED_COMPLETE) {
6686 if (!ssl->options.resuming) {
6687 #ifdef WOLFSSL_DTLS
6688 if (IsDtlsNotSctpMode(ssl))
6689 neededState = SERVER_HELLOVERIFYREQUEST_COMPLETE;
6690 else
6691 #endif
6692 neededState = SERVER_HELLODONE_COMPLETE;
6693 }
6694 }
6695 WOLFSSL_MSG("ProcessReply done.");
6696
6697#ifdef WOLFSSL_DTLS13
6698 if (ssl->options.dtls && IsAtLeastTLSv1_3(ssl->version)
6699 && ssl->dtls13Rtx.sendAcks == 1
6700 && ssl->options.seenUnifiedHdr) {
6701 /* we aren't negotiated the version yet, so we aren't sure
6702 * the other end can speak v1.3. On the other side we have
6703 * received a unified records, assuming that the
6704 * ServerHello got lost, we will send an empty ACK. In case
6705 * the server is a DTLS with version less than 1.3, it
6706 * should just ignore the message */
6707 ssl->dtls13Rtx.sendAcks = 0;
6708 if ((ssl->error = SendDtls13Ack(ssl)) < 0) {
6709 if (ssl->error == WC_NO_ERR_TRACE(WANT_WRITE))
6710 ssl->dtls13SendingAckOrRtx = 1;
6711 WOLFSSL_ERROR(ssl->error);
6712 return WOLFSSL_FATAL_ERROR;
6713 }
6714 }
6715#endif /* WOLFSSL_DTLS13 */
6716 }
6717
6718 ssl->options.connectState = HELLO_AGAIN;
6719 WOLFSSL_MSG("connect state: HELLO_AGAIN");
6720 FALL_THROUGH;
6721
6722 case HELLO_AGAIN :
6723
6724 #ifdef WOLFSSL_TLS13
6725 if (ssl->options.tls1_3)
6726 return wolfSSL_connect_TLSv13(ssl);
6727 #endif
6728
6729 #ifdef WOLFSSL_DTLS
6730 if (ssl->options.serverState ==
6731 SERVER_HELLOVERIFYREQUEST_COMPLETE) {
6732 if (IsDtlsNotSctpMode(ssl)) {
6733 /* re-init hashes, exclude first hello and verify request */
6734 if ((ssl->error = InitHandshakeHashes(ssl)) != 0) {
6735 WOLFSSL_ERROR(ssl->error);
6736 return WOLFSSL_FATAL_ERROR;
6737 }
6738 if ( (ssl->error = SendClientHello(ssl)) != 0) {
6739 WOLFSSL_ERROR(ssl->error);
6740 return WOLFSSL_FATAL_ERROR;
6741 }
6742 }
6743 }
6744 #endif
6745
6746 ssl->options.connectState = HELLO_AGAIN_REPLY;
6747 WOLFSSL_MSG("connect state: HELLO_AGAIN_REPLY");
6748 FALL_THROUGH;
6749
6750 case HELLO_AGAIN_REPLY :
6751 #ifdef WOLFSSL_DTLS
6752 if (IsDtlsNotSctpMode(ssl)) {
6753 neededState = ssl->options.resuming ?
6754 SERVER_FINISHED_COMPLETE : SERVER_HELLODONE_COMPLETE;
6755
6756 /* get response */
6757 while (ssl->options.serverState < neededState) {
6758 if ( (ssl->error = ProcessReply(ssl)) < 0) {
6759 WOLFSSL_ERROR(ssl->error);
6760 return WOLFSSL_FATAL_ERROR;
6761 }
6762 /* if resumption failed, reset needed state */
6763 if (neededState == SERVER_FINISHED_COMPLETE) {
6764 if (!ssl->options.resuming)
6765 neededState = SERVER_HELLODONE_COMPLETE;
6766 }
6767 }
6768 }
6769 #endif
6770
6771 ssl->options.connectState = FIRST_REPLY_DONE;
6772 WOLFSSL_MSG("connect state: FIRST_REPLY_DONE");
6773 FALL_THROUGH;
6774
6775 case FIRST_REPLY_DONE :
6776 if (ssl->options.certOnly)
6777 return WOLFSSL_SUCCESS;
6778 #if !defined(NO_CERTS) && !defined(WOLFSSL_NO_CLIENT_AUTH)
6779 #ifdef WOLFSSL_TLS13
6780 if (ssl->options.tls1_3)
6781 return wolfSSL_connect_TLSv13(ssl);
6782 #endif
6783 if (ssl->options.sendVerify) {
6784 if ( (ssl->error = SendCertificate(ssl)) != 0) {
6785 wolfssl_local_MaybeCheckAlertOnErr(ssl, ssl->error);
6786 WOLFSSL_ERROR(ssl->error);
6787 return WOLFSSL_FATAL_ERROR;
6788 }
6789 WOLFSSL_MSG("sent: certificate");
6790 }
6791
6792 #endif
6793 ssl->options.connectState = FIRST_REPLY_FIRST;
6794 WOLFSSL_MSG("connect state: FIRST_REPLY_FIRST");
6795 FALL_THROUGH;
6796
6797 case FIRST_REPLY_FIRST :
6798 #ifdef WOLFSSL_TLS13
6799 if (ssl->options.tls1_3)
6800 return wolfSSL_connect_TLSv13(ssl);
6801 #endif
6802 if (!ssl->options.resuming) {
6803 if ( (ssl->error = SendClientKeyExchange(ssl)) != 0) {
6804 wolfssl_local_MaybeCheckAlertOnErr(ssl, ssl->error);
6805#ifdef WOLFSSL_EXTRA_ALERTS
6806 if (ssl->error == WC_NO_ERR_TRACE(NO_PEER_KEY) ||
6807 ssl->error == WC_NO_ERR_TRACE(PSK_KEY_ERROR)) {
6808 SendAlert(ssl, alert_fatal, handshake_failure);
6809 }
6810#endif
6811 WOLFSSL_ERROR(ssl->error);
6812 return WOLFSSL_FATAL_ERROR;
6813 }
6814 WOLFSSL_MSG("sent: client key exchange");
6815 }
6816
6817 ssl->options.connectState = FIRST_REPLY_SECOND;
6818 WOLFSSL_MSG("connect state: FIRST_REPLY_SECOND");
6819 FALL_THROUGH;
6820
6821 #if !defined(WOLFSSL_NO_TLS12) || !defined(NO_OLD_TLS)
6822 case FIRST_REPLY_SECOND :
6823 /* CLIENT: Fail-safe for Server Authentication. */
6824 if (!ssl->options.peerAuthGood) {
6825 WOLFSSL_MSG("Server authentication did not happen");
6826 ssl->error = NO_PEER_VERIFY;
6827 return WOLFSSL_FATAL_ERROR;
6828 }
6829
6830 #if !defined(NO_CERTS) && !defined(WOLFSSL_NO_CLIENT_AUTH)
6831 if (ssl->options.sendVerify) {
6832 if ( (ssl->error = SendCertificateVerify(ssl)) != 0) {
6833 wolfssl_local_MaybeCheckAlertOnErr(ssl, ssl->error);
6834 WOLFSSL_ERROR(ssl->error);
6835 return WOLFSSL_FATAL_ERROR;
6836 }
6837 WOLFSSL_MSG("sent: certificate verify");
6838 }
6839 #endif /* !NO_CERTS && !WOLFSSL_NO_CLIENT_AUTH */
6840 ssl->options.connectState = FIRST_REPLY_THIRD;
6841 WOLFSSL_MSG("connect state: FIRST_REPLY_THIRD");
6842 FALL_THROUGH;
6843
6844 case FIRST_REPLY_THIRD :
6845 if ( (ssl->error = SendChangeCipher(ssl)) != 0) {
6846 wolfssl_local_MaybeCheckAlertOnErr(ssl, ssl->error);
6847 WOLFSSL_ERROR(ssl->error);
6848 return WOLFSSL_FATAL_ERROR;
6849 }
6850 WOLFSSL_MSG("sent: change cipher spec");
6851 ssl->options.connectState = FIRST_REPLY_FOURTH;
6852 WOLFSSL_MSG("connect state: FIRST_REPLY_FOURTH");
6853 FALL_THROUGH;
6854
6855 case FIRST_REPLY_FOURTH :
6856 if ( (ssl->error = SendFinished(ssl)) != 0) {
6857 wolfssl_local_MaybeCheckAlertOnErr(ssl, ssl->error);
6858 WOLFSSL_ERROR(ssl->error);
6859 return WOLFSSL_FATAL_ERROR;
6860 }
6861 WOLFSSL_MSG("sent: finished");
6862 ssl->options.connectState = FINISHED_DONE;
6863 WOLFSSL_MSG("connect state: FINISHED_DONE");
6864 FALL_THROUGH;
6865
6866#ifdef WOLFSSL_DTLS13
6867 case WAIT_FINISHED_ACK:
6868 ssl->options.connectState = FINISHED_DONE;
6869 FALL_THROUGH;
6870#endif /* WOLFSSL_DTLS13 */
6871
6872 case FINISHED_DONE :
6873 /* get response */
6874 while (ssl->options.serverState < SERVER_FINISHED_COMPLETE)
6875 if ( (ssl->error = ProcessReply(ssl)) < 0) {
6876 WOLFSSL_ERROR(ssl->error);
6877 return WOLFSSL_FATAL_ERROR;
6878 }
6879
6880 ssl->options.connectState = SECOND_REPLY_DONE;
6881 WOLFSSL_MSG("connect state: SECOND_REPLY_DONE");
6882 FALL_THROUGH;
6883
6884 case SECOND_REPLY_DONE:
6885 #ifndef NO_HANDSHAKE_DONE_CB
6886 if (ssl->hsDoneCb) {
6887 int cbret = ssl->hsDoneCb(ssl, ssl->hsDoneCtx);
6888 if (cbret < 0) {
6889 ssl->error = cbret;
6890 WOLFSSL_MSG("HandShake Done Cb don't continue error");
6891 return WOLFSSL_FATAL_ERROR;
6892 }
6893 }
6894 #endif /* NO_HANDSHAKE_DONE_CB */
6895
6896 if (!ssl->options.dtls) {
6897 if (!ssl->options.keepResources) {
6898 FreeHandshakeResources(ssl);
6899 }
6900 }
6901 #ifdef WOLFSSL_DTLS
6902 else {
6903 ssl->options.dtlsHsRetain = 1;
6904 }
6905 #endif /* WOLFSSL_DTLS */
6906
6907 #if defined(WOLFSSL_ASYNC_CRYPT) && defined(HAVE_SECURE_RENEGOTIATION)
6908 /* This may be necessary in async so that we don't try to
6909 * renegotiate again */
6910 if (ssl->secure_renegotiation &&
6911 ssl->secure_renegotiation->startScr) {
6912 ssl->secure_renegotiation->startScr = 0;
6913 }
6914 #endif /* WOLFSSL_ASYNC_CRYPT && HAVE_SECURE_RENEGOTIATION */
6915 #if defined(WOLFSSL_ASYNC_IO) && !defined(WOLFSSL_ASYNC_CRYPT)
6916 /* Free the remaining async context if not using it for crypto */
6917 FreeAsyncCtx(ssl, 1);
6918 #endif
6919
6920 ssl->error = 0; /* clear the error */
6921
6922 WOLFSSL_LEAVE("wolfSSL_connect", WOLFSSL_SUCCESS);
6923 return WOLFSSL_SUCCESS;
6924 #endif /* !WOLFSSL_NO_TLS12 || !NO_OLD_TLS */
6925
6926 default:
6927 WOLFSSL_MSG("Unknown connect state ERROR");
6928 return WOLFSSL_FATAL_ERROR; /* unknown connect state */
6929 }
6930 #endif /* !WOLFSSL_NO_TLS12 || !NO_OLD_TLS || !WOLFSSL_TLS13 */
6931 }
6932
6933#endif /* !NO_WOLFSSL_CLIENT && !NO_TLS */
6934/* end client only parts */
6935
6936/* server only parts */
6937#if !defined(NO_WOLFSSL_SERVER) && !defined(NO_TLS)
6938
6939 #if defined(OPENSSL_EXTRA) && !defined(NO_OLD_TLS)
6940 WOLFSSL_METHOD* wolfSSLv2_server_method(void)
6941 {
6942 WOLFSSL_STUB("wolfSSLv2_server_method");
6943 return 0;
6944 }
6945 #endif
6946
6947 #if defined(WOLFSSL_ALLOW_SSLV3) && !defined(NO_OLD_TLS)
6948 WOLFSSL_METHOD* wolfSSLv3_server_method(void)
6949 {
6950 return wolfSSLv3_server_method_ex(NULL);
6951 }
6952 WOLFSSL_METHOD* wolfSSLv3_server_method_ex(void* heap)
6953 {
6954 WOLFSSL_METHOD* method =
6955 (WOLFSSL_METHOD*) XMALLOC(sizeof(WOLFSSL_METHOD),
6956 heap, DYNAMIC_TYPE_METHOD);
6957 (void)heap;
6958 WOLFSSL_ENTER("wolfSSLv3_server_method_ex");
6959 if (method) {
6960 InitSSL_Method(method, MakeSSLv3());
6961 method->side = WOLFSSL_SERVER_END;
6962 }
6963 return method;
6964 }
6965 #endif /* WOLFSSL_ALLOW_SSLV3 && !NO_OLD_TLS */
6966
6967 WOLFSSL_METHOD* wolfSSLv23_server_method(void)
6968 {
6969 return wolfSSLv23_server_method_ex(NULL);
6970 }
6971
6972 WOLFSSL_METHOD* wolfSSLv23_server_method_ex(void* heap)
6973 {
6974 WOLFSSL_METHOD* method =
6975 (WOLFSSL_METHOD*) XMALLOC(sizeof(WOLFSSL_METHOD),
6976 heap, DYNAMIC_TYPE_METHOD);
6977 (void)heap;
6978 WOLFSSL_ENTER("wolfSSLv23_server_method_ex");
6979 if (method) {
6980 #if !defined(NO_SHA256) || defined(WOLFSSL_SHA384) || \
6981 defined(WOLFSSL_SHA512)
6982 #ifdef WOLFSSL_TLS13
6983 InitSSL_Method(method, MakeTLSv1_3());
6984 #elif !defined(WOLFSSL_NO_TLS12)
6985 InitSSL_Method(method, MakeTLSv1_2());
6986 #elif !defined(NO_OLD_TLS)
6987 InitSSL_Method(method, MakeTLSv1_1());
6988 #endif
6989 #else
6990 #ifndef NO_OLD_TLS
6991 InitSSL_Method(method, MakeTLSv1_1());
6992 #else
6993 #error Must have SHA256, SHA384 or SHA512 enabled for TLS 1.2
6994 #endif
6995 #endif
6996 #if !defined(NO_OLD_TLS) || defined(WOLFSSL_TLS13)
6997 method->downgrade = 1;
6998 #endif
6999 method->side = WOLFSSL_SERVER_END;
7000 }
7001 return method;
7002 }
7003
7004
7005 WOLFSSL_ABI
7006 int wolfSSL_accept(WOLFSSL* ssl)
7007 {
7008#if !(defined(WOLFSSL_NO_TLS12) && defined(NO_OLD_TLS) && \
7009 defined(WOLFSSL_TLS13))
7010 word16 havePSK = 0;
7011 word16 haveAnon = 0;
7012 word16 haveMcast = 0;
7013#endif
7014 int ret = 0;
7015
7016 (void)ret;
7017
7018 if (ssl == NULL)
7019 return WOLFSSL_FATAL_ERROR;
7020
7021 #if defined(OPENSSL_EXTRA) || defined(WOLFSSL_EITHER_SIDE)
7022 if (ssl->options.side == WOLFSSL_NEITHER_END) {
7023 WOLFSSL_MSG("Setting WOLFSSL_SSL to be server side");
7024 ssl->error = InitSSL_Side(ssl, WOLFSSL_SERVER_END);
7025 if (ssl->error != WOLFSSL_SUCCESS) {
7026 WOLFSSL_ERROR(ssl->error);
7027 return WOLFSSL_FATAL_ERROR;
7028 }
7029 ssl->error = 0; /* expected to be zero here */
7030 }
7031 #endif /* OPENSSL_EXTRA || WOLFSSL_EITHER_SIDE */
7032
7033#if defined(WOLFSSL_NO_TLS12) && defined(NO_OLD_TLS) && defined(WOLFSSL_TLS13)
7034 return wolfSSL_accept_TLSv13(ssl);
7035#else
7036 #ifdef WOLFSSL_TLS13
7037 if (ssl->options.tls1_3)
7038 return wolfSSL_accept_TLSv13(ssl);
7039 #endif
7040 WOLFSSL_ENTER("wolfSSL_accept");
7041
7042 /* make sure this wolfSSL object has arrays and rng setup. Protects
7043 * case where the WOLFSSL object is reused via wolfSSL_clear() */
7044 if ((ret = ReinitSSL(ssl, ssl->ctx, 0)) != 0) {
7045 return ret;
7046 }
7047
7048#ifdef WOLFSSL_WOLFSENTRY_HOOKS
7049 if ((ssl->AcceptFilter != NULL) &&
7050 ((ssl->options.acceptState == ACCEPT_BEGIN)
7051#ifdef HAVE_SECURE_RENEGOTIATION
7052 || (ssl->options.acceptState == ACCEPT_BEGIN_RENEG)
7053#endif
7054 ))
7055 {
7056 wolfSSL_netfilter_decision_t res;
7057 if ((ssl->AcceptFilter(ssl, ssl->AcceptFilter_arg, &res) ==
7058 WOLFSSL_SUCCESS) &&
7059 (res == WOLFSSL_NETFILTER_REJECT)) {
7060 ssl->error = SOCKET_FILTERED_E;
7061 WOLFSSL_ERROR(ssl->error);
7062 return WOLFSSL_FATAL_ERROR;
7063 }
7064 }
7065#endif /* WOLFSSL_WOLFSENTRY_HOOKS */
7066
7067 #ifdef HAVE_ERRNO_H
7068 errno = 0;
7069 #endif
7070
7071 #ifndef NO_PSK
7072 havePSK = ssl->options.havePSK;
7073 #endif
7074 (void)havePSK;
7075
7076 #ifdef HAVE_ANON
7077 haveAnon = ssl->options.useAnon;
7078 #endif
7079 (void)haveAnon;
7080
7081 #ifdef WOLFSSL_MULTICAST
7082 haveMcast = ssl->options.haveMcast;
7083 #endif
7084 (void)haveMcast;
7085
7086 if (ssl->options.side != WOLFSSL_SERVER_END) {
7087 ssl->error = SIDE_ERROR;
7088 WOLFSSL_ERROR(ssl->error);
7089 return WOLFSSL_FATAL_ERROR;
7090 }
7091
7092 #ifndef NO_CERTS
7093 /* in case used set_accept_state after init */
7094 if (!havePSK && !haveAnon && !haveMcast) {
7095 #ifdef WOLFSSL_CERT_SETUP_CB
7096 if (ssl->ctx->certSetupCb != NULL) {
7097 WOLFSSL_MSG("CertSetupCb set. server cert and "
7098 "key not checked");
7099 }
7100 else
7101 #endif
7102 {
7103 if (!ssl->buffers.certificate ||
7104 !ssl->buffers.certificate->buffer) {
7105
7106 WOLFSSL_MSG("accept error: server cert required");
7107 ssl->error = NO_PRIVATE_KEY;
7108 WOLFSSL_ERROR(ssl->error);
7109 return WOLFSSL_FATAL_ERROR;
7110 }
7111
7112 if (!ssl->buffers.key || !ssl->buffers.key->buffer) {
7113 /* allow no private key if using existing key */
7114 #ifdef WOLF_PRIVATE_KEY_ID
7115 if (ssl->devId != INVALID_DEVID
7116 #ifdef HAVE_PK_CALLBACKS
7117 || wolfSSL_CTX_IsPrivatePkSet(ssl->ctx)
7118 #endif
7119 ) {
7120 WOLFSSL_MSG("Allowing no server private key "
7121 "(external)");
7122 }
7123 else
7124 #endif
7125 {
7126 WOLFSSL_MSG("accept error: server key required");
7127 ssl->error = NO_PRIVATE_KEY;
7128 WOLFSSL_ERROR(ssl->error);
7129 return WOLFSSL_FATAL_ERROR;
7130 }
7131 }
7132 }
7133 }
7134 #endif
7135
7136 #ifdef WOLFSSL_DTLS
7137 if (ssl->version.major == DTLS_MAJOR) {
7138 ssl->options.dtls = 1;
7139 ssl->options.tls = 1;
7140 ssl->options.tls1_1 = 1;
7141 if (!IsDtlsNotSctpMode(ssl) || IsSCR(ssl))
7142 ssl->options.dtlsStateful = 1;
7143 }
7144 #endif
7145
7146 if (ssl->buffers.outputBuffer.length > 0
7147 #ifdef WOLFSSL_ASYNC_CRYPT
7148 /* do not send buffered or advance state if last error was an
7149 async pending operation */
7150 && ssl->error != WC_NO_ERR_TRACE(WC_PENDING_E)
7151 #endif
7152 ) {
7153 ret = SendBuffered(ssl);
7154 if (ret == 0) {
7155 /* fragOffset is non-zero when sending fragments. On the last
7156 * fragment, fragOffset is zero again, and the state can be
7157 * advanced. */
7158 if (ssl->fragOffset == 0 && !ssl->options.buildingMsg) {
7159 if (ssl->options.acceptState == ACCEPT_FIRST_REPLY_DONE ||
7160 ssl->options.acceptState == SERVER_HELLO_SENT ||
7161 ssl->options.acceptState == CERT_SENT ||
7162 ssl->options.acceptState == CERT_STATUS_SENT ||
7163 ssl->options.acceptState == KEY_EXCHANGE_SENT ||
7164 ssl->options.acceptState == CERT_REQ_SENT ||
7165 ssl->options.acceptState == ACCEPT_SECOND_REPLY_DONE ||
7166 ssl->options.acceptState == TICKET_SENT ||
7167 ssl->options.acceptState == CHANGE_CIPHER_SENT) {
7168 ssl->options.acceptState++;
7169 WOLFSSL_MSG("accept state: Advanced from last "
7170 "buffered fragment send");
7171 #ifdef WOLFSSL_ASYNC_IO
7172 /* Cleanup async */
7173 FreeAsyncCtx(ssl, 0);
7174 #endif
7175 }
7176 }
7177 else {
7178 WOLFSSL_MSG("accept state: "
7179 "Not advanced, more fragments to send");
7180 }
7181 }
7182 else {
7183 ssl->error = ret;
7184 WOLFSSL_ERROR(ssl->error);
7185 return WOLFSSL_FATAL_ERROR;
7186 }
7187#ifdef WOLFSSL_DTLS13
7188 if (ssl->options.dtls)
7189 ssl->dtls13SendingAckOrRtx = 0;
7190#endif /* WOLFSSL_DTLS13 */
7191 }
7192
7193 ret = RetrySendAlert(ssl);
7194 if (ret != 0) {
7195 ssl->error = ret;
7196 WOLFSSL_ERROR(ssl->error);
7197 return WOLFSSL_FATAL_ERROR;
7198 }
7199
7200 switch (ssl->options.acceptState) {
7201
7202 case ACCEPT_BEGIN :
7203#ifdef HAVE_SECURE_RENEGOTIATION
7204 case ACCEPT_BEGIN_RENEG:
7205#endif
7206 /* get response */
7207 while (ssl->options.clientState < CLIENT_HELLO_COMPLETE)
7208 if ( (ssl->error = ProcessReply(ssl)) < 0) {
7209 WOLFSSL_ERROR(ssl->error);
7210 return WOLFSSL_FATAL_ERROR;
7211 }
7212#ifdef WOLFSSL_TLS13
7213 ssl->options.acceptState = ACCEPT_CLIENT_HELLO_DONE;
7214 WOLFSSL_MSG("accept state ACCEPT_CLIENT_HELLO_DONE");
7215 FALL_THROUGH;
7216
7217 case ACCEPT_CLIENT_HELLO_DONE :
7218 if (ssl->options.tls1_3) {
7219 return wolfSSL_accept_TLSv13(ssl);
7220 }
7221#endif
7222
7223 ssl->options.acceptState = ACCEPT_FIRST_REPLY_DONE;
7224 WOLFSSL_MSG("accept state ACCEPT_FIRST_REPLY_DONE");
7225 FALL_THROUGH;
7226
7227 case ACCEPT_FIRST_REPLY_DONE :
7228 if (ssl->options.returnOnGoodCh) {
7229 /* Higher level in stack wants us to return. Simulate a
7230 * WANT_WRITE to accomplish this. */
7231 ssl->error = WANT_WRITE;
7232 return WOLFSSL_FATAL_ERROR;
7233 }
7234 if ( (ssl->error = SendServerHello(ssl)) != 0) {
7235 wolfssl_local_MaybeCheckAlertOnErr(ssl, ssl->error);
7236 WOLFSSL_ERROR(ssl->error);
7237 return WOLFSSL_FATAL_ERROR;
7238 }
7239 ssl->options.acceptState = SERVER_HELLO_SENT;
7240 WOLFSSL_MSG("accept state SERVER_HELLO_SENT");
7241 FALL_THROUGH;
7242
7243 case SERVER_HELLO_SENT :
7244 #ifdef WOLFSSL_TLS13
7245 if (ssl->options.tls1_3) {
7246 return wolfSSL_accept_TLSv13(ssl);
7247 }
7248 #endif
7249 #ifndef NO_CERTS
7250 if (!ssl->options.resuming)
7251 if ( (ssl->error = SendCertificate(ssl)) != 0) {
7252 wolfssl_local_MaybeCheckAlertOnErr(ssl, ssl->error);
7253 WOLFSSL_ERROR(ssl->error);
7254 return WOLFSSL_FATAL_ERROR;
7255 }
7256 #endif
7257 ssl->options.acceptState = CERT_SENT;
7258 WOLFSSL_MSG("accept state CERT_SENT");
7259 FALL_THROUGH;
7260
7261 case CERT_SENT :
7262 #ifndef NO_CERTS
7263 if (!ssl->options.resuming)
7264 if ( (ssl->error = SendCertificateStatus(ssl)) != 0) {
7265 wolfssl_local_MaybeCheckAlertOnErr(ssl, ssl->error);
7266 WOLFSSL_ERROR(ssl->error);
7267 return WOLFSSL_FATAL_ERROR;
7268 }
7269 #endif
7270 ssl->options.acceptState = CERT_STATUS_SENT;
7271 WOLFSSL_MSG("accept state CERT_STATUS_SENT");
7272 FALL_THROUGH;
7273
7274 case CERT_STATUS_SENT :
7275 #ifdef WOLFSSL_TLS13
7276 if (ssl->options.tls1_3) {
7277 return wolfSSL_accept_TLSv13(ssl);
7278 }
7279 #endif
7280 if (!ssl->options.resuming)
7281 if ( (ssl->error = SendServerKeyExchange(ssl)) != 0) {
7282 wolfssl_local_MaybeCheckAlertOnErr(ssl, ssl->error);
7283 WOLFSSL_ERROR(ssl->error);
7284 return WOLFSSL_FATAL_ERROR;
7285 }
7286 ssl->options.acceptState = KEY_EXCHANGE_SENT;
7287 WOLFSSL_MSG("accept state KEY_EXCHANGE_SENT");
7288 FALL_THROUGH;
7289
7290 case KEY_EXCHANGE_SENT :
7291 #ifndef NO_CERTS
7292 if (!ssl->options.resuming) {
7293 if (ssl->options.verifyPeer) {
7294 if ( (ssl->error = SendCertificateRequest(ssl)) != 0) {
7295 wolfssl_local_MaybeCheckAlertOnErr(ssl, ssl->error);
7296 WOLFSSL_ERROR(ssl->error);
7297 return WOLFSSL_FATAL_ERROR;
7298 }
7299 }
7300 else {
7301 /* SERVER: Peer auth good if not verifying client. */
7302 ssl->options.peerAuthGood = 1;
7303 }
7304 }
7305 #endif
7306 ssl->options.acceptState = CERT_REQ_SENT;
7307 WOLFSSL_MSG("accept state CERT_REQ_SENT");
7308 FALL_THROUGH;
7309
7310 case CERT_REQ_SENT :
7311 if (!ssl->options.resuming)
7312 if ( (ssl->error = SendServerHelloDone(ssl)) != 0) {
7313 wolfssl_local_MaybeCheckAlertOnErr(ssl, ssl->error);
7314 WOLFSSL_ERROR(ssl->error);
7315 return WOLFSSL_FATAL_ERROR;
7316 }
7317 ssl->options.acceptState = SERVER_HELLO_DONE;
7318 WOLFSSL_MSG("accept state SERVER_HELLO_DONE");
7319 FALL_THROUGH;
7320
7321 case SERVER_HELLO_DONE :
7322 if (!ssl->options.resuming) {
7323 while (ssl->options.clientState < CLIENT_FINISHED_COMPLETE)
7324 if ( (ssl->error = ProcessReply(ssl)) < 0) {
7325 WOLFSSL_ERROR(ssl->error);
7326 return WOLFSSL_FATAL_ERROR;
7327 }
7328 }
7329 ssl->options.acceptState = ACCEPT_SECOND_REPLY_DONE;
7330 WOLFSSL_MSG("accept state ACCEPT_SECOND_REPLY_DONE");
7331 FALL_THROUGH;
7332
7333 case ACCEPT_SECOND_REPLY_DONE :
7334 #ifndef NO_CERTS
7335 /* SERVER: When not resuming and verifying peer but no certificate
7336 * received and not failing when not received then peer auth good.
7337 */
7338 if (!ssl->options.resuming && ssl->options.verifyPeer &&
7339 !ssl->options.havePeerCert && !ssl->options.failNoCert) {
7340 ssl->options.peerAuthGood = 1;
7341 }
7342 #endif /* !NO_CERTS */
7343 #ifdef WOLFSSL_NO_CLIENT_AUTH
7344 if (!ssl->options.resuming) {
7345 ssl->options.peerAuthGood = 1;
7346 }
7347 #endif
7348
7349#ifdef HAVE_SESSION_TICKET
7350 if (ssl->options.createTicket && !ssl->options.noTicketTls12) {
7351 if ( (ssl->error = SendTicket(ssl)) != 0) {
7352 wolfssl_local_MaybeCheckAlertOnErr(ssl, ssl->error);
7353 WOLFSSL_MSG("Thought we need ticket but failed");
7354 WOLFSSL_ERROR(ssl->error);
7355 return WOLFSSL_FATAL_ERROR;
7356 }
7357 }
7358#endif /* HAVE_SESSION_TICKET */
7359 ssl->options.acceptState = TICKET_SENT;
7360 WOLFSSL_MSG("accept state TICKET_SENT");
7361 FALL_THROUGH;
7362
7363 case TICKET_SENT:
7364 /* SERVER: Fail-safe for CLient Authentication. */
7365 if (!ssl->options.peerAuthGood) {
7366 WOLFSSL_MSG("Client authentication did not happen");
7367 return WOLFSSL_FATAL_ERROR;
7368 }
7369
7370 if ( (ssl->error = SendChangeCipher(ssl)) != 0) {
7371 wolfssl_local_MaybeCheckAlertOnErr(ssl, ssl->error);
7372 WOLFSSL_ERROR(ssl->error);
7373 return WOLFSSL_FATAL_ERROR;
7374 }
7375 ssl->options.acceptState = CHANGE_CIPHER_SENT;
7376 WOLFSSL_MSG("accept state CHANGE_CIPHER_SENT");
7377 FALL_THROUGH;
7378
7379 case CHANGE_CIPHER_SENT :
7380 if ( (ssl->error = SendFinished(ssl)) != 0) {
7381 wolfssl_local_MaybeCheckAlertOnErr(ssl, ssl->error);
7382 WOLFSSL_ERROR(ssl->error);
7383 return WOLFSSL_FATAL_ERROR;
7384 }
7385
7386 ssl->options.acceptState = ACCEPT_FINISHED_DONE;
7387 WOLFSSL_MSG("accept state ACCEPT_FINISHED_DONE");
7388 FALL_THROUGH;
7389
7390 case ACCEPT_FINISHED_DONE :
7391 if (ssl->options.resuming) {
7392 while (ssl->options.clientState < CLIENT_FINISHED_COMPLETE) {
7393 if ( (ssl->error = ProcessReply(ssl)) < 0) {
7394 WOLFSSL_ERROR(ssl->error);
7395 return WOLFSSL_FATAL_ERROR;
7396 }
7397 }
7398 }
7399 ssl->options.acceptState = ACCEPT_THIRD_REPLY_DONE;
7400 WOLFSSL_MSG("accept state ACCEPT_THIRD_REPLY_DONE");
7401 FALL_THROUGH;
7402
7403 case ACCEPT_THIRD_REPLY_DONE :
7404#ifndef NO_HANDSHAKE_DONE_CB
7405 if (ssl->hsDoneCb) {
7406 int cbret = ssl->hsDoneCb(ssl, ssl->hsDoneCtx);
7407 if (cbret < 0) {
7408 ssl->error = cbret;
7409 WOLFSSL_MSG("HandShake Done Cb don't continue error");
7410 return WOLFSSL_FATAL_ERROR;
7411 }
7412 }
7413#endif /* NO_HANDSHAKE_DONE_CB */
7414
7415 if (!ssl->options.dtls) {
7416 if (!ssl->options.keepResources) {
7417 FreeHandshakeResources(ssl);
7418 }
7419 }
7420#ifdef WOLFSSL_DTLS
7421 else {
7422 ssl->options.dtlsHsRetain = 1;
7423 }
7424#endif /* WOLFSSL_DTLS */
7425
7426#if defined(WOLFSSL_ASYNC_CRYPT) && defined(HAVE_SECURE_RENEGOTIATION)
7427 /* This may be necessary in async so that we don't try to
7428 * renegotiate again */
7429 if (ssl->secure_renegotiation &&
7430 ssl->secure_renegotiation->startScr) {
7431 ssl->secure_renegotiation->startScr = 0;
7432 }
7433#endif /* WOLFSSL_ASYNC_CRYPT && HAVE_SECURE_RENEGOTIATION */
7434#if defined(WOLFSSL_ASYNC_IO) && !defined(WOLFSSL_ASYNC_CRYPT)
7435 /* Free the remaining async context if not using it for crypto */
7436 FreeAsyncCtx(ssl, 1);
7437#endif
7438
7439#if defined(WOLFSSL_SESSION_EXPORT) && defined(WOLFSSL_DTLS)
7440 if (ssl->dtls_export) {
7441 if ((ssl->error = wolfSSL_send_session(ssl)) != 0) {
7442 WOLFSSL_MSG("Export DTLS session error");
7443 WOLFSSL_ERROR(ssl->error);
7444 return WOLFSSL_FATAL_ERROR;
7445 }
7446 }
7447#endif
7448 ssl->error = 0; /* clear the error */
7449
7450 WOLFSSL_LEAVE("wolfSSL_accept", WOLFSSL_SUCCESS);
7451 return WOLFSSL_SUCCESS;
7452
7453 default:
7454 WOLFSSL_MSG("Unknown accept state ERROR");
7455 return WOLFSSL_FATAL_ERROR;
7456 }
7457#endif /* !WOLFSSL_NO_TLS12 */
7458 }
7459
7460#endif /* !NO_WOLFSSL_SERVER && !NO_TLS */
7461/* end server only parts */
7462
7463
7464#if defined(WOLFSSL_DTLS) && !defined(NO_WOLFSSL_SERVER)
7465struct chGoodDisableReadCbCtx {
7466 ClientHelloGoodCb userCb;
7467 void* userCtx;
7468};
7469
7470static int chGoodDisableReadCB(WOLFSSL* ssl, void* ctx)
7471{
7472 struct chGoodDisableReadCbCtx* cb = (struct chGoodDisableReadCbCtx*)ctx;
7473 int ret = 0;
7474 if (cb->userCb != NULL)
7475 ret = cb->userCb(ssl, cb->userCtx);
7476 if (ret >= 0)
7477 wolfSSL_SSLDisableRead(ssl);
7478 return ret;
7479}
7480
7481/**
7482 * Statelessly listen for a connection
7483 * @param ssl The ssl object to use for listening to connections
7484 * @return WOLFSSL_SUCCESS - ClientHello containing a valid cookie was received
7485 * The connection can be continued with wolfSSL_accept
7486 * WOLFSSL_FAILURE - The I/O layer returned WANT_READ. This is either
7487 * because there is no data to read and we are using
7488 * non-blocking sockets or we sent a cookie request
7489 * and we are waiting for a reply. The user should
7490 * call wolfDTLS_accept_stateless again after data
7491 * becomes available in the I/O layer.
7492 * WOLFSSL_FATAL_ERROR - A fatal error occurred. The ssl object should
7493 * be free'd and allocated again to continue.
7494 */
7495int wolfDTLS_accept_stateless(WOLFSSL* ssl)
7496{
7497 byte disableRead;
7498 int ret = WC_NO_ERR_TRACE(WOLFSSL_FATAL_ERROR);
7499 struct chGoodDisableReadCbCtx cb;
7500
7501 WOLFSSL_ENTER("wolfDTLS_SetChGoodCb");
7502
7503 if (ssl == NULL)
7504 return WOLFSSL_FATAL_ERROR;
7505
7506 /* Save this to restore it later */
7507 disableRead = (byte)ssl->options.disableRead;
7508 cb.userCb = ssl->chGoodCb;
7509 cb.userCtx = ssl->chGoodCtx;
7510
7511 /* Register our own callback so that we can disable reading */
7512 if (wolfDTLS_SetChGoodCb(ssl, chGoodDisableReadCB, &cb) != WOLFSSL_SUCCESS)
7513 return WOLFSSL_FATAL_ERROR;
7514
7515 ssl->options.returnOnGoodCh = 1;
7516 ret = wolfSSL_accept(ssl);
7517 ssl->options.returnOnGoodCh = 0;
7518 /* restore user options */
7519 ssl->options.disableRead = disableRead;
7520 (void)wolfDTLS_SetChGoodCb(ssl, cb.userCb, cb.userCtx);
7521 if (ret == WOLFSSL_SUCCESS) {
7522 WOLFSSL_MSG("should not happen. maybe the user called "
7523 "wolfDTLS_accept_stateless instead of wolfSSL_accept");
7524 }
7525 else if (ssl->error == WC_NO_ERR_TRACE(WANT_READ) ||
7526 ssl->error == WC_NO_ERR_TRACE(WANT_WRITE)) {
7527 ssl->error = 0;
7528 if (ssl->options.dtlsStateful)
7529 ret = WOLFSSL_SUCCESS;
7530 else
7531 ret = WOLFSSL_FAILURE;
7532 }
7533 else {
7534 ret = WOLFSSL_FATAL_ERROR;
7535 }
7536 return ret;
7537}
7538
7539int wolfDTLS_SetChGoodCb(WOLFSSL* ssl, ClientHelloGoodCb cb, void* user_ctx)
7540{
7541 WOLFSSL_ENTER("wolfDTLS_SetChGoodCb");
7542
7543 if (ssl == NULL)
7544 return BAD_FUNC_ARG;
7545
7546 ssl->chGoodCb = cb;
7547 ssl->chGoodCtx = user_ctx;
7548
7549 return WOLFSSL_SUCCESS;
7550}
7551#endif
7552
7553#ifndef NO_HANDSHAKE_DONE_CB
7554
7555int wolfSSL_SetHsDoneCb(WOLFSSL* ssl, HandShakeDoneCb cb, void* user_ctx)
7556{
7557 WOLFSSL_ENTER("wolfSSL_SetHsDoneCb");
7558
7559 if (ssl == NULL)
7560 return BAD_FUNC_ARG;
7561
7562 ssl->hsDoneCb = cb;
7563 ssl->hsDoneCtx = user_ctx;
7564
7565 return WOLFSSL_SUCCESS;
7566}
7567
7568#endif /* NO_HANDSHAKE_DONE_CB */
7569
7570WOLFSSL_ABI
7571int wolfSSL_Cleanup(void)
7572{
7573 int ret = WOLFSSL_SUCCESS; /* Only the first error will be returned */
7574 int release = 0;
7575#if !defined(NO_SESSION_CACHE)
7576 int i;
7577 int j;
7578#endif
7579
7580 WOLFSSL_ENTER("wolfSSL_Cleanup");
7581
7582#ifndef WOLFSSL_MUTEX_INITIALIZER
7583 if (inits_count_mutex_valid == 1) {
7584#endif
7585 if (wc_LockMutex(&inits_count_mutex) != 0) {
7586 WOLFSSL_MSG("Bad Lock Mutex count");
7587 return BAD_MUTEX_E;
7588 }
7589#ifndef WOLFSSL_MUTEX_INITIALIZER
7590 }
7591#endif
7592
7593 if (initRefCount > 0) {
7594 initRefCount = initRefCount - 1;
7595 if (initRefCount == 0)
7596 release = 1;
7597 }
7598
7599#ifndef WOLFSSL_MUTEX_INITIALIZER
7600 if (inits_count_mutex_valid == 1) {
7601#endif
7602 wc_UnLockMutex(&inits_count_mutex);
7603#ifndef WOLFSSL_MUTEX_INITIALIZER
7604 }
7605#endif
7606
7607 if (!release)
7608 return ret;
7609
7610#if defined(WOLFSSL_SYS_CRYPTO_POLICY)
7611 wolfSSL_crypto_policy_disable();
7612#endif /* WOLFSSL_SYS_CRYPTO_POLICY */
7613
7614#ifdef OPENSSL_EXTRA
7615 wolfSSL_BN_free_one();
7616#endif
7617
7618#ifndef NO_SESSION_CACHE
7619 #ifdef ENABLE_SESSION_CACHE_ROW_LOCK
7620 for (i = 0; i < SESSION_ROWS; ++i) {
7621 if ((SessionCache[i].lock_valid == 1) &&
7622 (wc_FreeRwLock(&SessionCache[i].row_lock) != 0)) {
7623 if (ret == WOLFSSL_SUCCESS)
7624 ret = BAD_MUTEX_E;
7625 }
7626 SessionCache[i].lock_valid = 0;
7627 }
7628 #else
7629 if ((session_lock_valid == 1) && (wc_FreeRwLock(&session_lock) != 0)) {
7630 if (ret == WOLFSSL_SUCCESS)
7631 ret = BAD_MUTEX_E;
7632 }
7633 session_lock_valid = 0;
7634 #endif
7635 for (i = 0; i < SESSION_ROWS; i++) {
7636 for (j = 0; j < SESSIONS_PER_ROW; j++) {
7637 #ifdef SESSION_CACHE_DYNAMIC_MEM
7638 if (SessionCache[i].Sessions[j]) {
7639 EvictSessionFromCache(SessionCache[i].Sessions[j]);
7640 XFREE(SessionCache[i].Sessions[j], SessionCache[i].heap,
7641 DYNAMIC_TYPE_SESSION);
7642 SessionCache[i].Sessions[j] = NULL;
7643 }
7644 #else
7645 EvictSessionFromCache(&SessionCache[i].Sessions[j]);
7646 #endif
7647 }
7648 }
7649 #ifndef NO_CLIENT_CACHE
7650 #ifndef WOLFSSL_MUTEX_INITIALIZER
7651 if ((clisession_mutex_valid == 1) &&
7652 (wc_FreeMutex(&clisession_mutex) != 0)) {
7653 if (ret == WOLFSSL_SUCCESS)
7654 ret = BAD_MUTEX_E;
7655 }
7656 clisession_mutex_valid = 0;
7657 #endif
7658 #endif
7659#endif /* !NO_SESSION_CACHE */
7660
7661#if !defined(WOLFSSL_MUTEX_INITIALIZER) && \
7662 !WOLFSSL_CLEANUP_THREADSAFE_BY_ATOMIC_OPS
7663 if ((inits_count_mutex_valid == 1) &&
7664 (wc_FreeMutex(&inits_count_mutex) != 0)) {
7665 if (ret == WOLFSSL_SUCCESS)
7666 ret = BAD_MUTEX_E;
7667 }
7668 inits_count_mutex_valid = 0;
7669#endif
7670
7671#ifdef OPENSSL_EXTRA
7672 wolfSSL_RAND_Cleanup();
7673#endif
7674
7675 if (wolfCrypt_Cleanup() != 0) {
7676 WOLFSSL_MSG("Error with wolfCrypt_Cleanup call");
7677 if (ret == WOLFSSL_SUCCESS)
7678 ret = WC_CLEANUP_E;
7679 }
7680
7681#if FIPS_VERSION_GE(5,1)
7682 if (wolfCrypt_SetPrivateKeyReadEnable_fips(0, WC_KEYTYPE_ALL) < 0) {
7683 if (ret == WOLFSSL_SUCCESS)
7684 ret = WC_CLEANUP_E;
7685 }
7686#endif
7687
7688#ifdef HAVE_GLOBAL_RNG
7689#ifndef WOLFSSL_MUTEX_INITIALIZER
7690 if ((globalRNGMutex_valid == 1) && (wc_FreeMutex(&globalRNGMutex) != 0)) {
7691 if (ret == WOLFSSL_SUCCESS)
7692 ret = BAD_MUTEX_E;
7693 }
7694 globalRNGMutex_valid = 0;
7695#endif /* !WOLFSSL_MUTEX_INITIALIZER */
7696
7697 #if defined(OPENSSL_EXTRA) && defined(HAVE_HASHDRBG)
7698 wolfSSL_FIPS_drbg_free(gDrbgDefCtx);
7699 gDrbgDefCtx = NULL;
7700 #endif
7701#endif
7702
7703#ifdef HAVE_EX_DATA_CRYPTO
7704 crypto_ex_cb_free(crypto_ex_cb_ctx_session);
7705 crypto_ex_cb_ctx_session = NULL;
7706#endif
7707
7708#ifdef WOLFSSL_MEM_FAIL_COUNT
7709 wc_MemFailCount_Free();
7710#endif
7711
7712 return ret;
7713}
7714
7715/* Returns 1 if name is a syntactically valid DNS FQDN per RFC 952/1123.
7716 *
7717 * Rules enforced:
7718 * - Total effective length (excluding optional trailing dot) in [1, 253]
7719 * - Each label is 1-63 octets of [a-zA-Z0-9-], with _ allowed in all but
7720 * the last label.
7721 * - No label starts or ends with '-'
7722 * - At least two labels (single-label names are not "fully qualified")
7723 * - Final label (TLD) contains at least one letter (rejects all-numeric
7724 * strings that could be confused with IPv4 literals, and matches the
7725 * ICANN constraint that TLDs are alphabetic)
7726 * - Optional trailing dot is accepted (absolute FQDN form)
7727 * - Internationalized names are valid in their ACE/punycode (xn--) form
7728 */
7729int wolfssl_local_IsValidFQDN(const char* name, word32 nameSz)
7730{
7731 word32 i;
7732 int labelLen = 0;
7733 int labelCount = 0;
7734 int curLabelHasAlpha = 0;
7735 int curLabelHasUnderscore = 0;
7736
7737 if (name == NULL || nameSz == 0)
7738 return 0;
7739
7740 /* Strip a single optional trailing dot before measuring. "example.com."
7741 * is the absolute form of the same FQDN.
7742 */
7743 if (name[nameSz - 1] == '.')
7744 --nameSz;
7745
7746 if (nameSz < 1 || nameSz > 253)
7747 return 0;
7748
7749 for (i = 0; i < nameSz; i++) {
7750 byte c = (byte)name[i];
7751
7752 if (c == '.') {
7753 if (labelLen == 0 || name[i - 1] == '-')
7754 return 0;
7755 ++labelCount;
7756 labelLen = 0;
7757 curLabelHasAlpha = 0;
7758 curLabelHasUnderscore = 0;
7759 continue;
7760 }
7761
7762 if (++labelLen > 63)
7763 return 0;
7764
7765 if (c == '-') {
7766 if (labelLen == 1)
7767 return 0;
7768 }
7769 else if (((c | 0x20) >= 'a') && ((c | 0x20) <= 'z')) {
7770 curLabelHasAlpha = 1;
7771 }
7772 else if (c == '_') {
7773 curLabelHasUnderscore = 1;
7774 }
7775 else if ((c < '0') || (c > '9')) {
7776 return 0;
7777 }
7778 }
7779
7780 /* Final label (no trailing dot in the effective range to close it) */
7781 if ((labelLen == 0) || (name[nameSz - 1] == '-') || curLabelHasUnderscore)
7782 return 0;
7783 ++labelCount;
7784
7785 return ((labelCount > 1) && curLabelHasAlpha);
7786}
7787
7788/* call before SSL_connect, if verifying will add name check to
7789 date check and signature check */
7790WOLFSSL_ABI
7791int wolfSSL_check_domain_name(WOLFSSL* ssl, const char* dn)
7792{
7793 size_t dn_len;
7794
7795 WOLFSSL_ENTER("wolfSSL_check_domain_name");
7796
7797 if (ssl == NULL || dn == NULL) {
7798 WOLFSSL_MSG("Bad function argument: NULL");
7799 return WOLFSSL_FAILURE;
7800 }
7801
7802 dn_len = XSTRLEN(dn);
7803
7804 if ((! wolfssl_local_IsValidFQDN(dn, (word32)dn_len)) &&
7805 (XSTRCMP(dn, "localhost") != 0))
7806 {
7807 WOLFSSL_MSG("Bad function argument: fails wolfssl_local_IsValidFQDN");
7808 return WOLFSSL_FAILURE;
7809 }
7810
7811 if (ssl->buffers.domainName.buffer)
7812 XFREE(ssl->buffers.domainName.buffer, ssl->heap, DYNAMIC_TYPE_DOMAIN);
7813
7814 ssl->buffers.domainName.length = (word32)XSTRLEN(dn);
7815 ssl->buffers.domainName.buffer = (byte*)XMALLOC(
7816 ssl->buffers.domainName.length + 1, ssl->heap, DYNAMIC_TYPE_DOMAIN);
7817
7818 if (ssl->buffers.domainName.buffer) {
7819 unsigned char* domainName = ssl->buffers.domainName.buffer;
7820 XMEMCPY(domainName, dn, ssl->buffers.domainName.length);
7821 domainName[ssl->buffers.domainName.length] = '\0';
7822 return WOLFSSL_SUCCESS;
7823 }
7824 else {
7825 ssl->error = MEMORY_ERROR;
7826 return WOLFSSL_FAILURE;
7827 }
7828}
7829
7830/* call before SSL_connect, if verifying will add IP SAN check to
7831 date check and signature check */
7832WOLFSSL_ABI
7833int wolfSSL_check_ip_address(WOLFSSL* ssl, const char* ipaddr)
7834{
7835 WOLFSSL_ENTER("wolfSSL_check_ip_address");
7836
7837 if (ssl == NULL || ipaddr == NULL) {
7838 WOLFSSL_MSG("Bad function argument: NULL");
7839 return WOLFSSL_FAILURE;
7840 }
7841
7842 if (ssl->buffers.ipasc.buffer != NULL) {
7843 XFREE(ssl->buffers.ipasc.buffer, ssl->heap, DYNAMIC_TYPE_DOMAIN);
7844 ssl->buffers.ipasc.buffer = NULL;
7845 ssl->buffers.ipasc.length = 0;
7846 }
7847
7848 ssl->buffers.ipasc.length = (word32)XSTRLEN(ipaddr);
7849 ssl->buffers.ipasc.buffer = (byte*)XMALLOC(ssl->buffers.ipasc.length + 1,
7850 ssl->heap, DYNAMIC_TYPE_DOMAIN);
7851 if (ssl->buffers.ipasc.buffer == NULL) {
7852 ssl->error = MEMORY_ERROR;
7853 return WOLFSSL_FAILURE;
7854 }
7855
7856 XMEMCPY(ssl->buffers.ipasc.buffer, ipaddr, ssl->buffers.ipasc.length);
7857 ssl->buffers.ipasc.buffer[ssl->buffers.ipasc.length] = '\0';
7858
7859#ifdef OPENSSL_EXTRA
7860 if (ssl->param == NULL) {
7861 return WOLFSSL_FAILURE;
7862 }
7863 if (wolfSSL_X509_VERIFY_PARAM_set1_ip_asc(ssl->param, ipaddr) !=
7864 WOLFSSL_SUCCESS) {
7865 return WOLFSSL_FAILURE;
7866 }
7867#endif
7868
7869 return WOLFSSL_SUCCESS;
7870}
7871
7872#if defined(SESSION_CERTS) && defined(OPENSSL_EXTRA)
7873const char *wolfSSL_get0_peername(WOLFSSL *ssl) {
7874 if (ssl == NULL) {
7875 return NULL;
7876 }
7877
7878 if (ssl->buffers.domainName.buffer)
7879 return (const char *)ssl->buffers.domainName.buffer;
7880 else if (ssl->session && ssl->session->peer)
7881 return ssl->session->peer->subjectCN;
7882#ifdef KEEP_PEER_CERT
7883 else if (ssl->peerCert.subjectCN[0])
7884 return ssl->peerCert.subjectCN;
7885#endif
7886 else {
7887 ssl->error = NO_PEER_CERT;
7888 return NULL;
7889 }
7890}
7891
7892#endif /* SESSION_CERTS && OPENSSL_EXTRA */
7893
7894/* turn on wolfSSL zlib compression
7895 returns WOLFSSL_SUCCESS for success, else error (not built in)
7896*/
7897int wolfSSL_set_compression(WOLFSSL* ssl)
7898{
7899 WOLFSSL_ENTER("wolfSSL_set_compression");
7900 (void)ssl;
7901#ifdef HAVE_LIBZ
7902 ssl->options.usingCompression = 1;
7903 return WOLFSSL_SUCCESS;
7904#else
7905 return NOT_COMPILED_IN;
7906#endif
7907}
7908
7909
7910#ifndef USE_WINDOWS_API
7911 #if !defined(NO_WRITEV) && !defined(NO_TLS)
7912
7913 /* simulate writev semantics, doesn't actually do block at a time though
7914 because of SSL_write behavior and because front adds may be small */
7915 int wolfSSL_writev(WOLFSSL* ssl, const struct iovec* iov, int iovcnt)
7916 {
7917 #ifdef WOLFSSL_SMALL_STACK
7918 byte staticBuffer[1]; /* force heap usage */
7919 #else
7920 byte staticBuffer[FILE_BUFFER_SIZE];
7921 #endif
7922 byte* myBuffer = staticBuffer;
7923 int dynamic = 0;
7924 size_t sending = 0;
7925 size_t idx = 0;
7926 int i;
7927 int ret;
7928
7929 WOLFSSL_ENTER("wolfSSL_writev");
7930
7931 for (i = 0; i < iovcnt; i++)
7932 if (! WC_SAFE_SUM_UNSIGNED(size_t, sending, iov[i].iov_len,
7933 sending))
7934 return BUFFER_E;
7935
7936 if (sending > sizeof(staticBuffer)) {
7937 myBuffer = (byte*)XMALLOC(sending, ssl->heap,
7938 DYNAMIC_TYPE_WRITEV);
7939 if (!myBuffer)
7940 return MEMORY_ERROR;
7941
7942 dynamic = 1;
7943 }
7944
7945 for (i = 0; i < iovcnt; i++) {
7946 XMEMCPY(&myBuffer[idx], iov[i].iov_base, iov[i].iov_len);
7947 idx += (int)iov[i].iov_len;
7948 }
7949
7950 /* myBuffer may not be initialized fully, but the span up to the
7951 * sending length will be.
7952 */
7953 PRAGMA_GCC_DIAG_PUSH
7954 PRAGMA_GCC("GCC diagnostic ignored \"-Wmaybe-uninitialized\"")
7955 ret = wolfSSL_write_internal(ssl, myBuffer, sending);
7956 PRAGMA_GCC_DIAG_POP
7957
7958 if (dynamic)
7959 XFREE(myBuffer, ssl->heap, DYNAMIC_TYPE_WRITEV);
7960
7961 return ret;
7962 }
7963 #endif
7964#endif
7965
7966
7967#ifdef WOLFSSL_CALLBACKS
7968
7969 typedef struct itimerval Itimerval;
7970
7971 /* don't keep calling simple functions while setting up timer and signals
7972 if no inlining these are the next best */
7973
7974 #define AddTimes(a, b, c) \
7975 do { \
7976 (c).tv_sec = (a).tv_sec + (b).tv_sec; \
7977 (c).tv_usec = (a).tv_usec + (b).tv_usec;\
7978 if ((c).tv_usec >= 1000000) { \
7979 (c).tv_sec++; \
7980 (c).tv_usec -= 1000000; \
7981 } \
7982 } while (0)
7983
7984
7985 #define SubtractTimes(a, b, c) \
7986 do { \
7987 (c).tv_sec = (a).tv_sec - (b).tv_sec; \
7988 (c).tv_usec = (a).tv_usec - (b).tv_usec;\
7989 if ((c).tv_usec < 0) { \
7990 (c).tv_sec--; \
7991 (c).tv_usec += 1000000; \
7992 } \
7993 } while (0)
7994
7995 #define CmpTimes(a, b, cmp) \
7996 (((a).tv_sec == (b).tv_sec) ? \
7997 ((a).tv_usec cmp (b).tv_usec) : \
7998 ((a).tv_sec cmp (b).tv_sec)) \
7999
8000
8001 /* do nothing handler */
8002 static void myHandler(int signo)
8003 {
8004 (void)signo;
8005 return;
8006 }
8007
8008
8009 static int wolfSSL_ex_wrapper(WOLFSSL* ssl, HandShakeCallBack hsCb,
8010 TimeoutCallBack toCb, WOLFSSL_TIMEVAL timeout)
8011 {
8012 int ret = WC_NO_ERR_TRACE(WOLFSSL_FATAL_ERROR);
8013 int oldTimerOn = 0; /* was timer already on */
8014 WOLFSSL_TIMEVAL startTime;
8015 WOLFSSL_TIMEVAL endTime;
8016 WOLFSSL_TIMEVAL totalTime;
8017 Itimerval myTimeout;
8018 Itimerval oldTimeout; /* if old timer adjust from total time to reset */
8019 struct sigaction act, oact;
8020
8021 #define ERR_OUT(x) { ssl->hsInfoOn = 0; ssl->toInfoOn = 0; return x; }
8022
8023 if (hsCb) {
8024 ssl->hsInfoOn = 1;
8025 InitHandShakeInfo(&ssl->handShakeInfo, ssl);
8026 }
8027 if (toCb) {
8028 ssl->toInfoOn = 1;
8029 InitTimeoutInfo(&ssl->timeoutInfo);
8030
8031 if (gettimeofday(&startTime, 0) < 0)
8032 ERR_OUT(GETTIME_ERROR);
8033
8034 /* use setitimer to simulate getitimer, init 0 myTimeout */
8035 myTimeout.it_interval.tv_sec = 0;
8036 myTimeout.it_interval.tv_usec = 0;
8037 myTimeout.it_value.tv_sec = 0;
8038 myTimeout.it_value.tv_usec = 0;
8039 if (setitimer(ITIMER_REAL, &myTimeout, &oldTimeout) < 0)
8040 ERR_OUT(SETITIMER_ERROR);
8041
8042 if (oldTimeout.it_value.tv_sec || oldTimeout.it_value.tv_usec) {
8043 oldTimerOn = 1;
8044
8045 /* is old timer going to expire before ours */
8046 if (CmpTimes(oldTimeout.it_value, timeout, <)) {
8047 timeout.tv_sec = oldTimeout.it_value.tv_sec;
8048 timeout.tv_usec = oldTimeout.it_value.tv_usec;
8049 }
8050 }
8051 myTimeout.it_value.tv_sec = timeout.tv_sec;
8052 myTimeout.it_value.tv_usec = timeout.tv_usec;
8053
8054 /* set up signal handler, don't restart socket send/recv */
8055 act.sa_handler = myHandler;
8056 sigemptyset(&act.sa_mask);
8057 act.sa_flags = 0;
8058#ifdef SA_INTERRUPT
8059 act.sa_flags |= SA_INTERRUPT;
8060#endif
8061 if (sigaction(SIGALRM, &act, &oact) < 0)
8062 ERR_OUT(SIGACT_ERROR);
8063
8064 if (setitimer(ITIMER_REAL, &myTimeout, 0) < 0)
8065 ERR_OUT(SETITIMER_ERROR);
8066 }
8067
8068 /* do main work */
8069#ifndef NO_WOLFSSL_CLIENT
8070 if (ssl->options.side == WOLFSSL_CLIENT_END)
8071 ret = wolfSSL_connect(ssl);
8072#endif
8073#ifndef NO_WOLFSSL_SERVER
8074 if (ssl->options.side == WOLFSSL_SERVER_END)
8075 ret = wolfSSL_accept(ssl);
8076#endif
8077
8078 /* do callbacks */
8079 if (toCb) {
8080 if (oldTimerOn) {
8081 if (gettimeofday(&endTime, 0) < 0)
8082 ERR_OUT(SYSLIB_FAILED_E);
8083 SubtractTimes(endTime, startTime, totalTime);
8084 /* adjust old timer for elapsed time */
8085 if (CmpTimes(totalTime, oldTimeout.it_value, <))
8086 SubtractTimes(oldTimeout.it_value, totalTime,
8087 oldTimeout.it_value);
8088 else {
8089 /* reset value to interval, may be off */
8090 oldTimeout.it_value.tv_sec = oldTimeout.it_interval.tv_sec;
8091 oldTimeout.it_value.tv_usec =oldTimeout.it_interval.tv_usec;
8092 }
8093 /* keep iter the same whether there or not */
8094 }
8095 /* restore old handler */
8096 if (sigaction(SIGALRM, &oact, 0) < 0)
8097 ret = SIGACT_ERROR; /* more pressing error, stomp */
8098 else
8099 /* use old settings which may turn off (expired or not there) */
8100 if (setitimer(ITIMER_REAL, &oldTimeout, 0) < 0)
8101 ret = SETITIMER_ERROR;
8102
8103 /* if we had a timeout call callback */
8104 if (ssl->timeoutInfo.timeoutName[0]) {
8105 ssl->timeoutInfo.timeoutValue.tv_sec = timeout.tv_sec;
8106 ssl->timeoutInfo.timeoutValue.tv_usec = timeout.tv_usec;
8107 (toCb)(&ssl->timeoutInfo);
8108 }
8109 ssl->toInfoOn = 0;
8110 }
8111
8112 /* clean up buffers allocated by AddPacketInfo */
8113 FreeTimeoutInfo(&ssl->timeoutInfo, ssl->heap);
8114
8115 if (hsCb) {
8116 FinishHandShakeInfo(&ssl->handShakeInfo);
8117 (hsCb)(&ssl->handShakeInfo);
8118 ssl->hsInfoOn = 0;
8119 }
8120 return ret;
8121 }
8122
8123
8124#ifndef NO_WOLFSSL_CLIENT
8125
8126 int wolfSSL_connect_ex(WOLFSSL* ssl, HandShakeCallBack hsCb,
8127 TimeoutCallBack toCb, WOLFSSL_TIMEVAL timeout)
8128 {
8129 WOLFSSL_ENTER("wolfSSL_connect_ex");
8130 return wolfSSL_ex_wrapper(ssl, hsCb, toCb, timeout);
8131 }
8132
8133#endif
8134
8135
8136#ifndef NO_WOLFSSL_SERVER
8137
8138 int wolfSSL_accept_ex(WOLFSSL* ssl, HandShakeCallBack hsCb,
8139 TimeoutCallBack toCb, WOLFSSL_TIMEVAL timeout)
8140 {
8141 WOLFSSL_ENTER("wolfSSL_accept_ex");
8142 return wolfSSL_ex_wrapper(ssl, hsCb, toCb, timeout);
8143 }
8144
8145#endif
8146
8147#endif /* WOLFSSL_CALLBACKS */
8148
8149
8150#ifndef NO_PSK
8151
8152 void wolfSSL_CTX_set_psk_client_callback(WOLFSSL_CTX* ctx,
8153 wc_psk_client_callback cb)
8154 {
8155 WOLFSSL_ENTER("wolfSSL_CTX_set_psk_client_callback");
8156
8157 if (ctx == NULL)
8158 return;
8159
8160 ctx->havePSK = 1;
8161 ctx->client_psk_cb = cb;
8162 }
8163
8164 void wolfSSL_set_psk_client_callback(WOLFSSL* ssl,wc_psk_client_callback cb)
8165 {
8166 byte haveRSA = 1;
8167 int keySz = 0;
8168
8169 WOLFSSL_ENTER("wolfSSL_set_psk_client_callback");
8170
8171 if (ssl == NULL)
8172 return;
8173
8174 ssl->options.havePSK = 1;
8175 ssl->options.client_psk_cb = cb;
8176
8177 #ifdef NO_RSA
8178 haveRSA = 0;
8179 #endif
8180 #ifndef NO_CERTS
8181 keySz = ssl->buffers.keySz;
8182 #endif
8183 if (AllocateSuites(ssl) != 0)
8184 return;
8185 InitSuites(ssl->suites, ssl->version, keySz, haveRSA, TRUE,
8186 ssl->options.haveDH, ssl->options.haveECDSAsig,
8187 ssl->options.haveECC, TRUE, ssl->options.haveStaticECC,
8188 ssl->options.useAnon, TRUE, TRUE, TRUE, TRUE, ssl->options.side);
8189 }
8190
8191#if defined(WOLFSSL_TLS13) && defined(WOLFSSL_CERT_WITH_EXTERN_PSK)
8192 int wolfSSL_CTX_set_cert_with_extern_psk(WOLFSSL_CTX* ctx, int state)
8193 {
8194 WOLFSSL_ENTER("wolfSSL_CTX_set_cert_with_extern_psk");
8195 if (ctx == NULL)
8196 return WOLFSSL_FAILURE;
8197 ctx->certWithExternPsk = (byte)(state != 0);
8198 return WOLFSSL_SUCCESS;
8199 }
8200
8201 int wolfSSL_set_cert_with_extern_psk(WOLFSSL* ssl, int state)
8202 {
8203 WOLFSSL_ENTER("wolfSSL_set_cert_with_extern_psk");
8204 if (ssl == NULL)
8205 return WOLFSSL_FAILURE;
8206 ssl->options.certWithExternPsk = (word16)(state != 0);
8207 return WOLFSSL_SUCCESS;
8208 }
8209#endif
8210
8211 #ifdef OPENSSL_EXTRA
8212 /**
8213 * set call back function for psk session use
8214 * @param ssl a pointer to WOLFSSL structure
8215 * @param cb a function pointer to wc_psk_use_session_cb
8216 * @return none
8217 */
8218 void wolfSSL_set_psk_use_session_callback(WOLFSSL* ssl,
8219 wc_psk_use_session_cb_func cb)
8220 {
8221 WOLFSSL_ENTER("wolfSSL_set_psk_use_session_callback");
8222
8223 if (ssl != NULL) {
8224 ssl->options.havePSK = 1;
8225 ssl->options.session_psk_cb = cb;
8226 }
8227
8228 WOLFSSL_LEAVE("wolfSSL_set_psk_use_session_callback", WOLFSSL_SUCCESS);
8229 }
8230 #endif
8231
8232 void wolfSSL_CTX_set_psk_server_callback(WOLFSSL_CTX* ctx,
8233 wc_psk_server_callback cb)
8234 {
8235 WOLFSSL_ENTER("wolfSSL_CTX_set_psk_server_callback");
8236 if (ctx == NULL)
8237 return;
8238 ctx->havePSK = 1;
8239 ctx->server_psk_cb = cb;
8240 }
8241
8242 void wolfSSL_set_psk_server_callback(WOLFSSL* ssl,wc_psk_server_callback cb)
8243 {
8244 byte haveRSA = 1;
8245 int keySz = 0;
8246
8247 WOLFSSL_ENTER("wolfSSL_set_psk_server_callback");
8248 if (ssl == NULL)
8249 return;
8250
8251 ssl->options.havePSK = 1;
8252 ssl->options.server_psk_cb = cb;
8253
8254 #ifdef NO_RSA
8255 haveRSA = 0;
8256 #endif
8257 #ifndef NO_CERTS
8258 keySz = ssl->buffers.keySz;
8259 #endif
8260 if (AllocateSuites(ssl) != 0)
8261 return;
8262 InitSuites(ssl->suites, ssl->version, keySz, haveRSA, TRUE,
8263 ssl->options.haveDH, ssl->options.haveECDSAsig,
8264 ssl->options.haveECC, TRUE, ssl->options.haveStaticECC,
8265 ssl->options.useAnon, TRUE, TRUE, TRUE, TRUE, ssl->options.side);
8266 }
8267
8268 const char* wolfSSL_get_psk_identity_hint(const WOLFSSL* ssl)
8269 {
8270 WOLFSSL_ENTER("wolfSSL_get_psk_identity_hint");
8271
8272 if (ssl == NULL || ssl->arrays == NULL)
8273 return NULL;
8274
8275 return ssl->arrays->server_hint;
8276 }
8277
8278
8279 const char* wolfSSL_get_psk_identity(const WOLFSSL* ssl)
8280 {
8281 WOLFSSL_ENTER("wolfSSL_get_psk_identity");
8282
8283 if (ssl == NULL || ssl->arrays == NULL)
8284 return NULL;
8285
8286 return ssl->arrays->client_identity;
8287 }
8288
8289 int wolfSSL_CTX_use_psk_identity_hint(WOLFSSL_CTX* ctx, const char* hint)
8290 {
8291 WOLFSSL_ENTER("wolfSSL_CTX_use_psk_identity_hint");
8292 if (hint == 0)
8293 ctx->server_hint[0] = '\0';
8294 else {
8295 /* Qt does not call CTX_set_*_psk_callbacks where havePSK is set */
8296 #ifdef WOLFSSL_QT
8297 ctx->havePSK=1;
8298 #endif
8299 XSTRNCPY(ctx->server_hint, hint, MAX_PSK_ID_LEN);
8300 ctx->server_hint[MAX_PSK_ID_LEN] = '\0'; /* null term */
8301 }
8302 return WOLFSSL_SUCCESS;
8303 }
8304
8305 int wolfSSL_use_psk_identity_hint(WOLFSSL* ssl, const char* hint)
8306 {
8307 WOLFSSL_ENTER("wolfSSL_use_psk_identity_hint");
8308
8309 if (ssl == NULL || ssl->arrays == NULL)
8310 return WOLFSSL_FAILURE;
8311
8312 if (hint == 0)
8313 ssl->arrays->server_hint[0] = 0;
8314 else {
8315 XSTRNCPY(ssl->arrays->server_hint, hint,
8316 sizeof(ssl->arrays->server_hint)-1);
8317 ssl->arrays->server_hint[sizeof(ssl->arrays->server_hint)-1] = '\0';
8318 }
8319 return WOLFSSL_SUCCESS;
8320 }
8321
8322 void* wolfSSL_get_psk_callback_ctx(WOLFSSL* ssl)
8323 {
8324 return ssl ? ssl->options.psk_ctx : NULL;
8325 }
8326 void* wolfSSL_CTX_get_psk_callback_ctx(WOLFSSL_CTX* ctx)
8327 {
8328 return ctx ? ctx->psk_ctx : NULL;
8329 }
8330 int wolfSSL_set_psk_callback_ctx(WOLFSSL* ssl, void* psk_ctx)
8331 {
8332 if (ssl == NULL)
8333 return WOLFSSL_FAILURE;
8334 ssl->options.psk_ctx = psk_ctx;
8335 return WOLFSSL_SUCCESS;
8336 }
8337 int wolfSSL_CTX_set_psk_callback_ctx(WOLFSSL_CTX* ctx, void* psk_ctx)
8338 {
8339 if (ctx == NULL)
8340 return WOLFSSL_FAILURE;
8341 ctx->psk_ctx = psk_ctx;
8342 return WOLFSSL_SUCCESS;
8343 }
8344#endif /* NO_PSK */
8345
8346
8347#ifdef HAVE_ANON
8348
8349 int wolfSSL_CTX_allow_anon_cipher(WOLFSSL_CTX* ctx)
8350 {
8351 WOLFSSL_ENTER("wolfSSL_CTX_allow_anon_cipher");
8352
8353 if (ctx == NULL)
8354 return WOLFSSL_FAILURE;
8355
8356 ctx->useAnon = 1;
8357
8358 return WOLFSSL_SUCCESS;
8359 }
8360
8361#endif /* HAVE_ANON */
8362
8363#ifdef OPENSSL_EXTRA
8364
8365 int wolfSSL_add_all_algorithms(void)
8366 {
8367 WOLFSSL_ENTER("wolfSSL_add_all_algorithms");
8368 if (initRefCount != 0 || wolfSSL_Init() == WOLFSSL_SUCCESS)
8369 return WOLFSSL_SUCCESS;
8370 else
8371 return WOLFSSL_FATAL_ERROR;
8372 }
8373
8374 int wolfSSL_OpenSSL_add_all_algorithms_noconf(void)
8375 {
8376 WOLFSSL_ENTER("wolfSSL_OpenSSL_add_all_algorithms_noconf");
8377
8378 if (wolfSSL_add_all_algorithms() ==
8379 WC_NO_ERR_TRACE(WOLFSSL_FATAL_ERROR))
8380 {
8381 return WOLFSSL_FATAL_ERROR;
8382 }
8383
8384 return WOLFSSL_SUCCESS;
8385 }
8386
8387 int wolfSSL_OpenSSL_add_all_algorithms_conf(void)
8388 {
8389 WOLFSSL_ENTER("wolfSSL_OpenSSL_add_all_algorithms_conf");
8390 /* This function is currently the same as
8391 wolfSSL_OpenSSL_add_all_algorithms_noconf since we do not employ
8392 the use of a wolfssl.cnf type configuration file and is only used for
8393 OpenSSL compatibility. */
8394
8395 if (wolfSSL_add_all_algorithms() ==
8396 WC_NO_ERR_TRACE(WOLFSSL_FATAL_ERROR))
8397 {
8398 return WOLFSSL_FATAL_ERROR;
8399 }
8400 return WOLFSSL_SUCCESS;
8401 }
8402
8403#endif
8404
8405#if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL) || \
8406 defined(WOLFSSL_EXTRA) || defined(WOLFSSL_WPAS_SMALL)
8407 void wolfSSL_CTX_set_quiet_shutdown(WOLFSSL_CTX* ctx, int mode)
8408 {
8409 WOLFSSL_ENTER("wolfSSL_CTX_set_quiet_shutdown");
8410 if (mode)
8411 ctx->quietShutdown = 1;
8412 }
8413
8414
8415 void wolfSSL_set_quiet_shutdown(WOLFSSL* ssl, int mode)
8416 {
8417 WOLFSSL_ENTER("wolfSSL_set_quiet_shutdown");
8418 if (mode)
8419 ssl->options.quietShutdown = 1;
8420 }
8421#endif /* OPENSSL_EXTRA || OPENSSL_EXTRA_X509_SMALL ||
8422 WOLFSSL_EXTRA || WOLFSSL_WPAS_SMALL */
8423
8424#ifdef OPENSSL_EXTRA
8425#ifndef NO_BIO
8426 static void ssl_set_bio(WOLFSSL* ssl, WOLFSSL_BIO* rd, WOLFSSL_BIO* wr, int flags)
8427 {
8428 WOLFSSL_ENTER("wolfSSL_set_bio");
8429
8430 if (ssl == NULL) {
8431 WOLFSSL_MSG("Bad argument, ssl was NULL");
8432 return;
8433 }
8434
8435 /* free any existing WOLFSSL_BIOs in use but don't free those in
8436 * a chain */
8437 if ((flags & WOLFSSL_BIO_FLAG_READ) && (ssl->biord != NULL)) {
8438 if ((flags & WOLFSSL_BIO_FLAG_WRITE) && (ssl->biord != ssl->biowr)) {
8439 if (ssl->biowr != NULL && ssl->biowr->prev != NULL)
8440 wolfSSL_BIO_free(ssl->biowr);
8441 ssl->biowr = NULL;
8442 }
8443 if (ssl->biord->prev != NULL)
8444 wolfSSL_BIO_free(ssl->biord);
8445 ssl->biord = NULL;
8446 }
8447 else if ((flags & WOLFSSL_BIO_FLAG_WRITE) && (ssl->biowr != NULL)) {
8448 if (ssl->biowr->prev != NULL)
8449 wolfSSL_BIO_free(ssl->biowr);
8450 ssl->biowr = NULL;
8451 }
8452
8453 /* set flag obviously */
8454 if (rd && !(rd->flags & WOLFSSL_BIO_FLAG_READ))
8455 rd->flags |= WOLFSSL_BIO_FLAG_READ;
8456 if (wr && !(wr->flags & WOLFSSL_BIO_FLAG_WRITE))
8457 wr->flags |= WOLFSSL_BIO_FLAG_WRITE;
8458
8459 if (flags & WOLFSSL_BIO_FLAG_READ)
8460 ssl->biord = rd;
8461 if (flags & WOLFSSL_BIO_FLAG_WRITE)
8462 ssl->biowr = wr;
8463
8464 /* set SSL to use BIO callbacks instead */
8465 if ((flags & WOLFSSL_BIO_FLAG_READ) &&
8466 (((ssl->cbioFlag & WOLFSSL_CBIO_RECV) == 0)))
8467 {
8468 ssl->CBIORecv = SslBioReceive;
8469 }
8470 if ((flags & WOLFSSL_BIO_FLAG_WRITE) &&
8471 (((ssl->cbioFlag & WOLFSSL_CBIO_SEND) == 0)))
8472 {
8473 ssl->CBIOSend = SslBioSend;
8474 }
8475
8476 /* User programs should always retry reading from these BIOs */
8477 if (rd) {
8478 /* User writes to rd */
8479 wolfSSL_BIO_set_retry_write(rd);
8480 }
8481 if (wr) {
8482 /* User reads from wr */
8483 wolfSSL_BIO_set_retry_read(wr);
8484 }
8485 }
8486
8487 void wolfSSL_set_bio(WOLFSSL* ssl, WOLFSSL_BIO* rd, WOLFSSL_BIO* wr)
8488 {
8489 ssl_set_bio(ssl, rd, wr, WOLFSSL_BIO_FLAG_READ | WOLFSSL_BIO_FLAG_WRITE);
8490 }
8491
8492 void wolfSSL_set_rbio(WOLFSSL* ssl, WOLFSSL_BIO* rd)
8493 {
8494 ssl_set_bio(ssl, rd, NULL, WOLFSSL_BIO_FLAG_READ);
8495 }
8496
8497 void wolfSSL_set_wbio(WOLFSSL* ssl, WOLFSSL_BIO* wr)
8498 {
8499 ssl_set_bio(ssl, NULL, wr, WOLFSSL_BIO_FLAG_WRITE);
8500 }
8501
8502#endif /* !NO_BIO */
8503#endif /* OPENSSL_EXTRA */
8504
8505#ifdef WOLFSSL_CERT_SETUP_CB
8506#if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)
8507 /* registers client cert callback, called during handshake if server
8508 requests client auth but user has not loaded client cert/key */
8509 void wolfSSL_CTX_set_client_cert_cb(WOLFSSL_CTX *ctx, client_cert_cb cb)
8510 {
8511 WOLFSSL_ENTER("wolfSSL_CTX_set_client_cert_cb");
8512
8513 if (ctx != NULL) {
8514 ctx->CBClientCert = cb;
8515 }
8516 }
8517#endif
8518
8519 void wolfSSL_CTX_set_cert_cb(WOLFSSL_CTX* ctx,
8520 CertSetupCallback cb, void *arg)
8521 {
8522 WOLFSSL_ENTER("wolfSSL_CTX_set_cert_cb");
8523 if (ctx == NULL)
8524 return;
8525
8526 ctx->certSetupCb = cb;
8527 ctx->certSetupCbArg = arg;
8528 }
8529
8530 int wolfSSL_get_client_suites_sigalgs(const WOLFSSL* ssl,
8531 const byte** suites, word16* suiteSz,
8532 const byte** hashSigAlgo, word16* hashSigAlgoSz)
8533 {
8534 WOLFSSL_ENTER("wolfSSL_get_client_suites_sigalgs");
8535
8536 if (suites != NULL)
8537 *suites = NULL;
8538 if (suiteSz != NULL)
8539 *suiteSz = 0;
8540 if (hashSigAlgo != NULL)
8541 *hashSigAlgo = NULL;
8542 if (hashSigAlgoSz != NULL)
8543 *hashSigAlgoSz = 0;
8544
8545 if (ssl != NULL && ssl->clSuites != NULL) {
8546 if (suites != NULL && suiteSz != NULL) {
8547 *suites = ssl->clSuites->suites;
8548 *suiteSz = ssl->clSuites->suiteSz;
8549 }
8550 if (hashSigAlgo != NULL && hashSigAlgoSz != NULL) {
8551 *hashSigAlgo = ssl->clSuites->hashSigAlgo;
8552 *hashSigAlgoSz = ssl->clSuites->hashSigAlgoSz;
8553 }
8554 return WOLFSSL_SUCCESS;
8555 }
8556 return WOLFSSL_FAILURE;
8557 }
8558
8559#ifndef NO_TLS
8560 WOLFSSL_CIPHERSUITE_INFO wolfSSL_get_ciphersuite_info(byte first,
8561 byte second)
8562 {
8563 WOLFSSL_CIPHERSUITE_INFO info;
8564 info.rsaAuth = (byte)(CipherRequires(first, second, REQUIRES_RSA) ||
8565 CipherRequires(first, second, REQUIRES_RSA_SIG));
8566 info.eccAuth = (byte)(CipherRequires(first, second, REQUIRES_ECC) ||
8567 /* Static ECC ciphers may require RSA for authentication */
8568 (CipherRequires(first, second, REQUIRES_ECC_STATIC) &&
8569 !CipherRequires(first, second, REQUIRES_RSA_SIG)));
8570 info.eccStatic =
8571 (byte)CipherRequires(first, second, REQUIRES_ECC_STATIC);
8572 info.psk = (byte)CipherRequires(first, second, REQUIRES_PSK);
8573 return info;
8574 }
8575#endif
8576
8577 /**
8578 * @param first First byte of the hash and signature algorithm
8579 * @param second Second byte of the hash and signature algorithm
8580 * @param hashAlgo The enum wc_HashType of the MAC algorithm
8581 * @param sigAlgo The enum Key_Sum of the authentication algorithm
8582 */
8583 int wolfSSL_get_sigalg_info(byte first, byte second,
8584 int* hashAlgo, int* sigAlgo)
8585 {
8586 byte input[2];
8587 byte hashType;
8588 byte sigType;
8589
8590 if (hashAlgo == NULL || sigAlgo == NULL)
8591 return BAD_FUNC_ARG;
8592
8593 input[0] = first;
8594 input[1] = second;
8595 DecodeSigAlg(input, &hashType, &sigType);
8596
8597 /* cast so that compiler reminds us of unimplemented values */
8598 switch ((enum SignatureAlgorithm)sigType) {
8599 case anonymous_sa_algo:
8600 *sigAlgo = ANONk;
8601 break;
8602 case rsa_sa_algo:
8603 *sigAlgo = RSAk;
8604 break;
8605 case dsa_sa_algo:
8606 *sigAlgo = DSAk;
8607 break;
8608 case ecc_dsa_sa_algo:
8609 case ecc_brainpool_sa_algo:
8610 *sigAlgo = ECDSAk;
8611 break;
8612 case rsa_pss_sa_algo:
8613 *sigAlgo = RSAPSSk;
8614 break;
8615 case ed25519_sa_algo:
8616 *sigAlgo = ED25519k;
8617 break;
8618 case rsa_pss_pss_algo:
8619 *sigAlgo = RSAPSSk;
8620 break;
8621 case ed448_sa_algo:
8622 *sigAlgo = ED448k;
8623 break;
8624 case falcon_level1_sa_algo:
8625 *sigAlgo = FALCON_LEVEL1k;
8626 break;
8627 case falcon_level5_sa_algo:
8628 *sigAlgo = FALCON_LEVEL5k;
8629 break;
8630 case dilithium_level2_sa_algo:
8631 *sigAlgo = ML_DSA_LEVEL2k;
8632 break;
8633 case dilithium_level3_sa_algo:
8634 *sigAlgo = ML_DSA_LEVEL3k;
8635 break;
8636 case dilithium_level5_sa_algo:
8637 *sigAlgo = ML_DSA_LEVEL5k;
8638 break;
8639 case sm2_sa_algo:
8640 *sigAlgo = SM2k;
8641 break;
8642 case invalid_sa_algo:
8643 case any_sa_algo:
8644 default:
8645 *hashAlgo = WC_HASH_TYPE_NONE;
8646 *sigAlgo = 0;
8647 return BAD_FUNC_ARG;
8648 }
8649
8650 /* cast so that compiler reminds us of unimplemented values */
8651 switch((enum wc_MACAlgorithm)hashType) {
8652 case no_mac:
8653 case rmd_mac: /* Don't have a RIPEMD type in wc_HashType */
8654 *hashAlgo = WC_HASH_TYPE_NONE;
8655 break;
8656 case md5_mac:
8657 *hashAlgo = WC_HASH_TYPE_MD5;
8658 break;
8659 case sha_mac:
8660 *hashAlgo = WC_HASH_TYPE_SHA;
8661 break;
8662 case sha224_mac:
8663 *hashAlgo = WC_HASH_TYPE_SHA224;
8664 break;
8665 case sha256_mac:
8666 *hashAlgo = WC_HASH_TYPE_SHA256;
8667 break;
8668 case sha384_mac:
8669 *hashAlgo = WC_HASH_TYPE_SHA384;
8670 break;
8671 case sha512_mac:
8672 *hashAlgo = WC_HASH_TYPE_SHA512;
8673 break;
8674 case blake2b_mac:
8675 *hashAlgo = WC_HASH_TYPE_BLAKE2B;
8676 break;
8677 case sm3_mac:
8678#ifdef WOLFSSL_SM3
8679 *hashAlgo = WC_HASH_TYPE_SM3;
8680#else
8681 *hashAlgo = WC_HASH_TYPE_NONE;
8682#endif
8683 break;
8684 default:
8685 *hashAlgo = WC_HASH_TYPE_NONE;
8686 *sigAlgo = 0;
8687 return BAD_FUNC_ARG;
8688 }
8689 return 0;
8690 }
8691
8692 /**
8693 * Internal wrapper for calling certSetupCb
8694 * @param ssl The SSL/TLS Object
8695 * @return 0 on success
8696 */
8697 int CertSetupCbWrapper(WOLFSSL* ssl)
8698 {
8699 int ret = 0;
8700 if (ssl->ctx->certSetupCb != NULL) {
8701 WOLFSSL_MSG("Calling user cert setup callback");
8702 ret = ssl->ctx->certSetupCb(ssl, ssl->ctx->certSetupCbArg);
8703 if (ret == 1) {
8704 WOLFSSL_MSG("User cert callback returned success");
8705 ret = 0;
8706 }
8707 else if (ret == 0) {
8708 SendAlert(ssl, alert_fatal, internal_error);
8709 ret = CLIENT_CERT_CB_ERROR;
8710 }
8711 else if (ret < 0) {
8712 ret = WOLFSSL_ERROR_WANT_X509_LOOKUP;
8713 }
8714 else {
8715 WOLFSSL_MSG("Unexpected user callback return");
8716 ret = CLIENT_CERT_CB_ERROR;
8717 }
8718 }
8719 return ret;
8720 }
8721#endif /* WOLFSSL_CERT_SETUP_CB */
8722
8723#ifdef OPENSSL_EXTRA
8724
8725 #if defined(WOLFCRYPT_HAVE_SRP) && !defined(NO_SHA256) \
8726 && !defined(WC_NO_RNG)
8727 static const byte srp_N[] = {
8728 0xEE, 0xAF, 0x0A, 0xB9, 0xAD, 0xB3, 0x8D, 0xD6, 0x9C, 0x33, 0xF8,
8729 0x0A, 0xFA, 0x8F, 0xC5, 0xE8, 0x60, 0x72, 0x61, 0x87, 0x75, 0xFF,
8730 0x3C, 0x0B, 0x9E, 0xA2, 0x31, 0x4C, 0x9C, 0x25, 0x65, 0x76, 0xD6,
8731 0x74, 0xDF, 0x74, 0x96, 0xEA, 0x81, 0xD3, 0x38, 0x3B, 0x48, 0x13,
8732 0xD6, 0x92, 0xC6, 0xE0, 0xE0, 0xD5, 0xD8, 0xE2, 0x50, 0xB9, 0x8B,
8733 0xE4, 0x8E, 0x49, 0x5C, 0x1D, 0x60, 0x89, 0xDA, 0xD1, 0x5D, 0xC7,
8734 0xD7, 0xB4, 0x61, 0x54, 0xD6, 0xB6, 0xCE, 0x8E, 0xF4, 0xAD, 0x69,
8735 0xB1, 0x5D, 0x49, 0x82, 0x55, 0x9B, 0x29, 0x7B, 0xCF, 0x18, 0x85,
8736 0xC5, 0x29, 0xF5, 0x66, 0x66, 0x0E, 0x57, 0xEC, 0x68, 0xED, 0xBC,
8737 0x3C, 0x05, 0x72, 0x6C, 0xC0, 0x2F, 0xD4, 0xCB, 0xF4, 0x97, 0x6E,
8738 0xAA, 0x9A, 0xFD, 0x51, 0x38, 0xFE, 0x83, 0x76, 0x43, 0x5B, 0x9F,
8739 0xC6, 0x1D, 0x2F, 0xC0, 0xEB, 0x06, 0xE3
8740 };
8741 static const byte srp_g[] = {
8742 0x02
8743 };
8744
8745 int wolfSSL_CTX_set_srp_username(WOLFSSL_CTX* ctx, char* username)
8746 {
8747 int r = 0;
8748 SrpSide srp_side = SRP_CLIENT_SIDE;
8749
8750 WOLFSSL_ENTER("wolfSSL_CTX_set_srp_username");
8751 if (ctx == NULL || ctx->srp == NULL || username==NULL)
8752 return WOLFSSL_FAILURE;
8753
8754 if (ctx->method->side == WOLFSSL_SERVER_END){
8755 srp_side = SRP_SERVER_SIDE;
8756 } else if (ctx->method->side == WOLFSSL_CLIENT_END){
8757 srp_side = SRP_CLIENT_SIDE;
8758 } else {
8759 WOLFSSL_MSG("Init CTX failed");
8760 return WOLFSSL_FAILURE;
8761 }
8762
8763 if (wc_SrpInit(ctx->srp, SRP_TYPE_SHA256, srp_side) < 0) {
8764 WOLFSSL_MSG("Init SRP CTX failed");
8765 XFREE(ctx->srp, ctx->heap, DYNAMIC_TYPE_SRP);
8766 ctx->srp = NULL;
8767 return WOLFSSL_FAILURE;
8768 }
8769 r = wc_SrpSetUsername(ctx->srp, (const byte*)username,
8770 (word32)XSTRLEN(username));
8771 if (r < 0) {
8772 WOLFSSL_MSG("fail to set srp username.");
8773 return WOLFSSL_FAILURE;
8774 }
8775
8776 /* if wolfSSL_CTX_set_srp_password has already been called, */
8777 /* use saved password here */
8778 if (ctx->srp_password != NULL) {
8779 if (ctx->srp->user == NULL)
8780 return WOLFSSL_FAILURE;
8781 return wolfSSL_CTX_set_srp_password(ctx, (char*)ctx->srp_password);
8782 }
8783
8784 return WOLFSSL_SUCCESS;
8785 }
8786
8787 int wolfSSL_CTX_set_srp_password(WOLFSSL_CTX* ctx, char* password)
8788 {
8789 int r;
8790 byte salt[SRP_SALT_SIZE];
8791
8792 WOLFSSL_ENTER("wolfSSL_CTX_set_srp_password");
8793 if (ctx == NULL || ctx->srp == NULL || password == NULL)
8794 return WOLFSSL_FAILURE;
8795
8796 if (ctx->srp->user != NULL) {
8797 WC_RNG rng;
8798 if (wc_InitRng(&rng) < 0) {
8799 WOLFSSL_MSG("wc_InitRng failed");
8800 return WOLFSSL_FAILURE;
8801 }
8802 XMEMSET(salt, 0, sizeof(salt)/sizeof(salt[0]));
8803 r = wc_RNG_GenerateBlock(&rng, salt, sizeof(salt)/sizeof(salt[0]));
8804 wc_FreeRng(&rng);
8805 if (r < 0) {
8806 WOLFSSL_MSG("wc_RNG_GenerateBlock failed");
8807 return WOLFSSL_FAILURE;
8808 }
8809 if (wc_SrpSetParams(ctx->srp, srp_N, sizeof(srp_N)/sizeof(srp_N[0]),
8810 srp_g, sizeof(srp_g)/sizeof(srp_g[0]),
8811 salt, sizeof(salt)/sizeof(salt[0])) < 0){
8812 WOLFSSL_MSG("wc_SrpSetParam failed");
8813 return WOLFSSL_FAILURE;
8814 }
8815 r = wc_SrpSetPassword(ctx->srp, (const byte*)password,
8816 (word32)XSTRLEN(password));
8817 if (r < 0) {
8818 WOLFSSL_MSG("wc_SrpSetPassword failed.");
8819 return WOLFSSL_FAILURE;
8820 }
8821 XFREE(ctx->srp_password, NULL, DYNAMIC_TYPE_SRP);
8822 ctx->srp_password = NULL;
8823 } else {
8824 /* save password for wolfSSL_set_srp_username */
8825 XFREE(ctx->srp_password, ctx->heap, DYNAMIC_TYPE_SRP);
8826
8827 ctx->srp_password = (byte*)XMALLOC(XSTRLEN(password) + 1, ctx->heap,
8828 DYNAMIC_TYPE_SRP);
8829 if (ctx->srp_password == NULL){
8830 WOLFSSL_MSG("memory allocation error");
8831 return WOLFSSL_FAILURE;
8832 }
8833 XMEMCPY(ctx->srp_password, password, XSTRLEN(password) + 1);
8834 }
8835 return WOLFSSL_SUCCESS;
8836 }
8837
8838 /**
8839 * The modulus passed to wc_SrpSetParams in ssl.c is constant so check
8840 * that the requested strength is less than or equal to the size of the
8841 * static modulus size.
8842 * @param ctx Not used
8843 * @param strength Minimum number of bits for the modulus
8844 * @return 1 if strength is less than or equal to static modulus
8845 * 0 if strength is greater than static modulus
8846 */
8847 int wolfSSL_CTX_set_srp_strength(WOLFSSL_CTX *ctx, int strength)
8848 {
8849 (void)ctx;
8850 WOLFSSL_ENTER("wolfSSL_CTX_set_srp_strength");
8851 if (strength > (int)(sizeof(srp_N)*8)) {
8852 WOLFSSL_MSG("Bad Parameter");
8853 return WOLFSSL_FAILURE;
8854 }
8855 return WOLFSSL_SUCCESS;
8856 }
8857
8858 char* wolfSSL_get_srp_username(WOLFSSL *ssl)
8859 {
8860 if (ssl && ssl->ctx && ssl->ctx->srp) {
8861 return (char*) ssl->ctx->srp->user;
8862 }
8863 return NULL;
8864 }
8865 #endif /* WOLFCRYPT_HAVE_SRP && !NO_SHA256 && !WC_NO_RNG */
8866
8867 /* keyblock size in bytes or -1 */
8868 int wolfSSL_get_keyblock_size(WOLFSSL* ssl)
8869 {
8870 if (ssl == NULL)
8871 return WOLFSSL_FATAL_ERROR;
8872
8873 return 2 * (ssl->specs.key_size + ssl->specs.iv_size +
8874 ssl->specs.hash_size);
8875 }
8876
8877#endif /* OPENSSL_EXTRA */
8878
8879#if defined(OPENSSL_EXTRA) || defined(WOLFSSL_EXTRA) || \
8880 defined(WOLFSSL_WPAS_SMALL)
8881
8882 /* store keys returns WOLFSSL_SUCCESS or -1 on error */
8883 int wolfSSL_get_keys(WOLFSSL* ssl, unsigned char** ms, unsigned int* msLen,
8884 unsigned char** sr, unsigned int* srLen,
8885 unsigned char** cr, unsigned int* crLen)
8886 {
8887 if (ssl == NULL || ssl->arrays == NULL)
8888 return WOLFSSL_FATAL_ERROR;
8889
8890 *ms = ssl->arrays->masterSecret;
8891 *sr = ssl->arrays->serverRandom;
8892 *cr = ssl->arrays->clientRandom;
8893
8894 *msLen = SECRET_LEN;
8895 *srLen = RAN_LEN;
8896 *crLen = RAN_LEN;
8897
8898 return WOLFSSL_SUCCESS;
8899 }
8900
8901 void wolfSSL_set_accept_state(WOLFSSL* ssl)
8902 {
8903 WOLFSSL_ENTER("wolfSSL_set_accept_state");
8904
8905 if (ssl == NULL)
8906 return;
8907
8908 if (ssl->options.side == WOLFSSL_CLIENT_END) {
8909 #ifdef HAVE_ECC
8910 WC_DECLARE_VAR(key, ecc_key, 1, 0);
8911 word32 idx = 0;
8912
8913 #ifdef WOLFSSL_SMALL_STACK
8914 key = (ecc_key*)XMALLOC(sizeof(ecc_key), ssl->heap,
8915 DYNAMIC_TYPE_ECC);
8916 if (key == NULL) {
8917 WOLFSSL_MSG("Error allocating memory for ecc_key");
8918 }
8919 #endif
8920 if (ssl->options.haveStaticECC && ssl->buffers.key != NULL) {
8921 if (wc_ecc_init(key) >= 0) {
8922 if (wc_EccPrivateKeyDecode(ssl->buffers.key->buffer, &idx,
8923 key, ssl->buffers.key->length) != 0) {
8924 ssl->options.haveECDSAsig = 0;
8925 ssl->options.haveECC = 0;
8926 ssl->options.haveStaticECC = 0;
8927 }
8928 wc_ecc_free(key);
8929 }
8930 }
8931 WC_FREE_VAR_EX(key, ssl->heap, DYNAMIC_TYPE_ECC);
8932 #endif
8933
8934 #ifndef NO_DH
8935 if (!ssl->options.haveDH && ssl->ctx->haveDH) {
8936 ssl->buffers.serverDH_P = ssl->ctx->serverDH_P;
8937 ssl->buffers.serverDH_G = ssl->ctx->serverDH_G;
8938 ssl->options.haveDH = 1;
8939 }
8940 #endif
8941 }
8942
8943 if (InitSSL_Side(ssl, WOLFSSL_SERVER_END) != WOLFSSL_SUCCESS) {
8944 WOLFSSL_MSG("Error initializing server side");
8945 }
8946 }
8947
8948#endif /* OPENSSL_EXTRA || WOLFSSL_EXTRA || WOLFSSL_WPAS_SMALL */
8949
8950 /* return true if connection established */
8951 /* this works for TLS and DTLS */
8952 int wolfSSL_is_init_finished(const WOLFSSL* ssl)
8953 {
8954 if (ssl == NULL)
8955 return 0;
8956
8957#if defined(WOLFSSL_DTLS13) && !defined(NO_WOLFSSL_CLIENT)
8958 if (ssl->options.side == WOLFSSL_CLIENT_END && ssl->options.dtls
8959 && IsAtLeastTLSv1_3(ssl->version)) {
8960 return ssl->options.serverState == SERVER_FINISHED_ACKED;
8961 }
8962#endif /* WOLFSSL_DTLS13 && !NO_WOLFSSL_CLIENT */
8963
8964 /* Can't use ssl->options.connectState and ssl->options.acceptState
8965 * because they differ in meaning for TLS <=1.2 and 1.3 */
8966 if (ssl->options.handShakeState == HANDSHAKE_DONE)
8967 return 1;
8968
8969 return 0;
8970 }
8971
8972#ifdef OPENSSL_EXTRA
8973 void wolfSSL_CTX_set_tmp_rsa_callback(WOLFSSL_CTX* ctx,
8974 WOLFSSL_RSA*(*f)(WOLFSSL*, int, int))
8975 {
8976 /* wolfSSL verifies all these internally */
8977 (void)ctx;
8978 (void)f;
8979 }
8980
8981
8982 void wolfSSL_set_shutdown(WOLFSSL* ssl, int opt)
8983 {
8984 WOLFSSL_ENTER("wolfSSL_set_shutdown");
8985 if(ssl==NULL) {
8986 WOLFSSL_MSG("Shutdown not set. ssl is null");
8987 return;
8988 }
8989
8990 ssl->options.sentNotify = (opt&WOLFSSL_SENT_SHUTDOWN) > 0;
8991 ssl->options.closeNotify = (opt&WOLFSSL_RECEIVED_SHUTDOWN) > 0;
8992 }
8993#endif
8994
8995 long wolfSSL_CTX_get_options(WOLFSSL_CTX* ctx)
8996 {
8997 WOLFSSL_ENTER("wolfSSL_CTX_get_options");
8998 WOLFSSL_MSG("wolfSSL options are set through API calls and macros");
8999 if(ctx == NULL)
9000 return BAD_FUNC_ARG;
9001 return (long)ctx->mask;
9002 }
9003
9004 /* forward declaration */
9005 static long wolf_set_options(long old_op, long op);
9006
9007 long wolfSSL_CTX_set_options(WOLFSSL_CTX* ctx, long opt)
9008 {
9009 WOLFSSL_ENTER("wolfSSL_CTX_set_options");
9010
9011 if (ctx == NULL)
9012 return BAD_FUNC_ARG;
9013
9014 ctx->mask = (unsigned long)wolf_set_options((long)ctx->mask, opt);
9015#if defined(HAVE_SESSION_TICKET) && (defined(OPENSSL_EXTRA) \
9016 || defined(HAVE_WEBSERVER) || defined(WOLFSSL_WPAS_SMALL))
9017 if ((ctx->mask & WOLFSSL_OP_NO_TICKET) == WOLFSSL_OP_NO_TICKET) {
9018 ctx->noTicketTls12 = 1;
9019 }
9020 /* This code is here for documentation purpose. You must not turn off
9021 * session tickets with the WOLFSSL_OP_NO_TICKET option for TLSv1.3.
9022 * Because we need to support both stateful and stateless tickets.
9023 #ifdef WOLFSSL_TLS13
9024 if ((ctx->mask & WOLFSSL_OP_NO_TICKET) == WOLFSSL_OP_NO_TICKET) {
9025 ctx->noTicketTls13 = 1;
9026 }
9027 #endif
9028 */
9029#endif
9030 return (long)ctx->mask;
9031 }
9032
9033 long wolfSSL_CTX_clear_options(WOLFSSL_CTX* ctx, long opt)
9034 {
9035 WOLFSSL_ENTER("wolfSSL_CTX_clear_options");
9036 if(ctx == NULL)
9037 return BAD_FUNC_ARG;
9038 ctx->mask &= (unsigned long)~opt;
9039 return (long)ctx->mask;
9040 }
9041
9042#ifdef OPENSSL_EXTRA
9043
9044 int wolfSSL_set_rfd(WOLFSSL* ssl, int rfd)
9045 {
9046 WOLFSSL_ENTER("wolfSSL_set_rfd");
9047 ssl->rfd = rfd; /* not used directly to allow IO callbacks */
9048
9049 ssl->IOCB_ReadCtx = &ssl->rfd;
9050
9051 #ifdef WOLFSSL_DTLS
9052 if (ssl->options.dtls) {
9053 ssl->IOCB_ReadCtx = &ssl->buffers.dtlsCtx;
9054 ssl->buffers.dtlsCtx.rfd = rfd;
9055 }
9056 #endif
9057
9058 return WOLFSSL_SUCCESS;
9059 }
9060
9061
9062 int wolfSSL_set_wfd(WOLFSSL* ssl, int wfd)
9063 {
9064 WOLFSSL_ENTER("wolfSSL_set_wfd");
9065 ssl->wfd = wfd; /* not used directly to allow IO callbacks */
9066
9067 ssl->IOCB_WriteCtx = &ssl->wfd;
9068
9069 return WOLFSSL_SUCCESS;
9070 }
9071#endif /* OPENSSL_EXTRA */
9072
9073#ifdef WOLFSSL_ENCRYPTED_KEYS
9074
9075 void wolfSSL_CTX_set_default_passwd_cb_userdata(WOLFSSL_CTX* ctx,
9076 void* userdata)
9077 {
9078 WOLFSSL_ENTER("wolfSSL_CTX_set_default_passwd_cb_userdata");
9079 if (ctx)
9080 ctx->passwd_userdata = userdata;
9081 }
9082
9083
9084 void wolfSSL_CTX_set_default_passwd_cb(WOLFSSL_CTX* ctx, wc_pem_password_cb*
9085 cb)
9086 {
9087 WOLFSSL_ENTER("wolfSSL_CTX_set_default_passwd_cb");
9088 if (ctx)
9089 ctx->passwd_cb = cb;
9090 }
9091
9092 wc_pem_password_cb* wolfSSL_CTX_get_default_passwd_cb(WOLFSSL_CTX *ctx)
9093 {
9094 if (ctx == NULL || ctx->passwd_cb == NULL) {
9095 return NULL;
9096 }
9097
9098 return ctx->passwd_cb;
9099 }
9100
9101
9102 void* wolfSSL_CTX_get_default_passwd_cb_userdata(WOLFSSL_CTX *ctx)
9103 {
9104 if (ctx == NULL) {
9105 return NULL;
9106 }
9107
9108 return ctx->passwd_userdata;
9109 }
9110
9111#endif /* WOLFSSL_ENCRYPTED_KEYS */
9112
9113
9114#if defined(OPENSSL_EXTRA) || defined(HAVE_WEBSERVER) || defined(HAVE_MEMCACHED)
9115 unsigned long wolfSSL_ERR_get_error(void)
9116 {
9117 WOLFSSL_ENTER("wolfSSL_ERR_get_error");
9118#ifdef WOLFSSL_HAVE_ERROR_QUEUE
9119 return (unsigned long)wc_GetErrorNodeErr();
9120#else
9121 return (unsigned long)(0 - NOT_COMPILED_IN);
9122#endif
9123 }
9124#endif
9125
9126#if defined(OPENSSL_EXTRA) || defined(HAVE_WEBSERVER)
9127
9128 int wolfSSL_num_locks(void)
9129 {
9130 return 0;
9131 }
9132
9133 void wolfSSL_set_locking_callback(mutex_cb* f)
9134 {
9135 WOLFSSL_ENTER("wolfSSL_set_locking_callback");
9136
9137 if (wc_SetMutexCb(f) != 0) {
9138 WOLFSSL_MSG("Error when setting mutex call back");
9139 }
9140 }
9141
9142 mutex_cb* wolfSSL_get_locking_callback(void)
9143 {
9144 WOLFSSL_ENTER("wolfSSL_get_locking_callback");
9145
9146 return wc_GetMutexCb();
9147 }
9148
9149
9150 typedef unsigned long (idCb)(void);
9151 static idCb* inner_idCb = NULL;
9152
9153 unsigned long wolfSSL_thread_id(void)
9154 {
9155 if (inner_idCb != NULL) {
9156 return inner_idCb();
9157 }
9158 else {
9159 return 0;
9160 }
9161 }
9162
9163
9164 void wolfSSL_set_id_callback(unsigned long (*f)(void))
9165 {
9166 inner_idCb = f;
9167 }
9168
9169#ifdef WOLFSSL_HAVE_ERROR_QUEUE
9170#ifndef NO_BIO
9171 /* print out and clear all errors */
9172 void wolfSSL_ERR_print_errors(WOLFSSL_BIO* bio)
9173 {
9174 const char* file = NULL;
9175 const char* reason = NULL;
9176 int ret;
9177 int line = 0;
9178 char buf[WOLFSSL_MAX_ERROR_SZ * 2];
9179
9180 WOLFSSL_ENTER("wolfSSL_ERR_print_errors");
9181
9182 if (bio == NULL) {
9183 WOLFSSL_MSG("BIO passed in was null");
9184 return;
9185 }
9186
9187 do {
9188 ret = wc_PeekErrorNode(0, &file, &reason, &line);
9189 if (ret >= 0) {
9190 const char* r = wolfSSL_ERR_reason_error_string(
9191 (unsigned long)(0 - ret));
9192 if (XSNPRINTF(buf, sizeof(buf),
9193 "error:%d:wolfSSL library:%s:%s:%d\n",
9194 ret, r, file, line)
9195 >= (int)sizeof(buf))
9196 {
9197 WOLFSSL_MSG("Buffer overrun formatting error message");
9198 }
9199 wolfSSL_BIO_write(bio, buf, (int)XSTRLEN(buf));
9200 wc_RemoveErrorNode(0);
9201 }
9202 } while (ret >= 0);
9203 if (wolfSSL_BIO_write(bio, "", 1) != 1) {
9204 WOLFSSL_MSG("Issue writing final string terminator");
9205 }
9206 }
9207#endif /* !NO_BIO */
9208#endif /* WOLFSSL_HAVE_ERROR_QUEUE */
9209
9210#endif /* OPENSSL_EXTRA || HAVE_WEBSERVER */
9211
9212#if defined(OPENSSL_EXTRA) || defined(WOLFSSL_WPAS_SMALL) || \
9213 defined(HAVE_SECRET_CALLBACK)
9214#if !defined(NO_WOLFSSL_SERVER)
9215/* Return the amount of random bytes copied over or error case.
9216 * ssl : ssl struct after handshake
9217 * out : buffer to hold random bytes
9218 * outSz : either 0 (return max buffer sz) or size of out buffer
9219 */
9220size_t wolfSSL_get_server_random(const WOLFSSL *ssl, unsigned char *out,
9221 size_t outSz)
9222{
9223 size_t size;
9224
9225 /* return max size of buffer */
9226 if (outSz == 0) {
9227 return RAN_LEN;
9228 }
9229
9230 if (ssl == NULL || out == NULL) {
9231 return 0;
9232 }
9233
9234 if (ssl->arrays == NULL) {
9235 WOLFSSL_MSG("Arrays struct not saved after handshake");
9236 return 0;
9237 }
9238
9239 if (outSz > RAN_LEN) {
9240 size = RAN_LEN;
9241 }
9242 else {
9243 size = outSz;
9244 }
9245
9246 XMEMCPY(out, ssl->arrays->serverRandom, size);
9247 return size;
9248}
9249#endif /* !NO_WOLFSSL_SERVER */
9250#endif /* OPENSSL_EXTRA || WOLFSSL_WPAS_SMALL || HAVE_SECRET_CALLBACK */
9251
9252#ifdef OPENSSL_EXTRA
9253#if !defined(NO_WOLFSSL_SERVER)
9254/* Used to get the peer ephemeral public key sent during the connection
9255 * NOTE: currently wolfSSL_KeepHandshakeResources(WOLFSSL* ssl) must be called
9256 * before the ephemeral key is stored.
9257 * return WOLFSSL_SUCCESS on success */
9258int wolfSSL_get_peer_tmp_key(const WOLFSSL* ssl, WOLFSSL_EVP_PKEY** pkey)
9259{
9260 WOLFSSL_EVP_PKEY* ret = NULL;
9261
9262 WOLFSSL_ENTER("wolfSSL_get_server_tmp_key");
9263
9264 if (ssl == NULL || pkey == NULL) {
9265 WOLFSSL_MSG("Bad argument passed in");
9266 return WOLFSSL_FAILURE;
9267 }
9268
9269#ifdef HAVE_ECC
9270 if (ssl->peerEccKey != NULL) {
9271 unsigned char* der;
9272 const unsigned char* pt;
9273 unsigned int derSz = 0;
9274 int sz;
9275
9276 PRIVATE_KEY_UNLOCK();
9277 if (wc_ecc_export_x963(ssl->peerEccKey, NULL, &derSz)
9278 != WC_NO_ERR_TRACE(LENGTH_ONLY_E))
9279 {
9280 WOLFSSL_MSG("get ecc der size failed");
9281 PRIVATE_KEY_LOCK();
9282 return WOLFSSL_FAILURE;
9283 }
9284 PRIVATE_KEY_LOCK();
9285
9286 derSz += MAX_SEQ_SZ + (2 * MAX_ALGO_SZ) + MAX_SEQ_SZ + TRAILING_ZERO;
9287 der = (unsigned char*)XMALLOC(derSz, ssl->heap, DYNAMIC_TYPE_KEY);
9288 if (der == NULL) {
9289 WOLFSSL_MSG("Memory error");
9290 return WOLFSSL_FAILURE;
9291 }
9292
9293 if ((sz = wc_EccPublicKeyToDer(ssl->peerEccKey, der, derSz, 1)) <= 0) {
9294 WOLFSSL_MSG("get ecc der failed");
9295 XFREE(der, ssl->heap, DYNAMIC_TYPE_KEY);
9296 return WOLFSSL_FAILURE;
9297 }
9298 pt = der; /* in case pointer gets advanced */
9299 ret = wolfSSL_d2i_PUBKEY(NULL, &pt, sz);
9300 XFREE(der, ssl->heap, DYNAMIC_TYPE_KEY);
9301 }
9302#endif
9303
9304 *pkey = ret;
9305#ifdef HAVE_ECC
9306 if (ret != NULL)
9307 return WOLFSSL_SUCCESS;
9308 else
9309#endif
9310 return WOLFSSL_FAILURE;
9311}
9312
9313#endif /* !NO_WOLFSSL_SERVER */
9314
9315/**
9316 * This function checks if any compiled in protocol versions are
9317 * left enabled after calls to set_min or set_max API.
9318 * @param major The SSL/TLS major version
9319 * @return WOLFSSL_SUCCESS on valid settings and WOLFSSL_FAILURE when no
9320 * protocol versions are left enabled.
9321 */
9322static int CheckSslMethodVersion(byte major, unsigned long options)
9323{
9324 int sanityConfirmed = 0;
9325
9326 (void)options;
9327
9328 switch (major) {
9329 #ifndef NO_TLS
9330 case SSLv3_MAJOR:
9331 #ifdef WOLFSSL_ALLOW_SSLV3
9332 if (!(options & WOLFSSL_OP_NO_SSLv3)) {
9333 sanityConfirmed = 1;
9334 }
9335 #endif
9336 #ifndef NO_OLD_TLS
9337 if (!(options & WOLFSSL_OP_NO_TLSv1))
9338 sanityConfirmed = 1;
9339 if (!(options & WOLFSSL_OP_NO_TLSv1_1))
9340 sanityConfirmed = 1;
9341 #endif
9342 #ifndef WOLFSSL_NO_TLS12
9343 if (!(options & WOLFSSL_OP_NO_TLSv1_2))
9344 sanityConfirmed = 1;
9345 #endif
9346 #ifdef WOLFSSL_TLS13
9347 if (!(options & WOLFSSL_OP_NO_TLSv1_3))
9348 sanityConfirmed = 1;
9349 #endif
9350 break;
9351 #endif
9352 #ifdef WOLFSSL_DTLS
9353 case DTLS_MAJOR:
9354 sanityConfirmed = 1;
9355 break;
9356 #endif
9357 default:
9358 WOLFSSL_MSG("Invalid major version");
9359 return WOLFSSL_FAILURE;
9360 }
9361 if (!sanityConfirmed) {
9362 WOLFSSL_MSG("All compiled in TLS versions disabled");
9363 return WOLFSSL_FAILURE;
9364 }
9365 return WOLFSSL_SUCCESS;
9366}
9367
9368/**
9369 * protoVerTbl holds (D)TLS version numbers in ascending order.
9370 * Except DTLS versions, the newer version is located in the latter part of
9371 * the table. This table is referred by wolfSSL_CTX_set_min_proto_version and
9372 * wolfSSL_CTX_set_max_proto_version.
9373 */
9374static const int protoVerTbl[] = {
9375 SSL3_VERSION,
9376 TLS1_VERSION,
9377 TLS1_1_VERSION,
9378 TLS1_2_VERSION,
9379 TLS1_3_VERSION,
9380 DTLS1_VERSION,
9381 DTLS1_2_VERSION
9382};
9383/* number of protocol versions listed in protoVerTbl */
9384#define NUMBER_OF_PROTOCOLS (sizeof(protoVerTbl)/sizeof(int))
9385
9386/**
9387 * wolfSSL_CTX_set_min_proto_version attempts to set the minimum protocol
9388 * version to use by SSL objects created from this WOLFSSL_CTX.
9389 * This API guarantees that a version of SSL/TLS lower than specified
9390 * here will not be allowed. If the version specified is not compiled in
9391 * then this API sets the lowest compiled in protocol version.
9392 * This API also accept 0 as version, to set the minimum version automatically.
9393 * CheckSslMethodVersion() is called to check if any remaining protocol versions
9394 * are enabled.
9395 * @param ctx The wolfSSL CONTEXT factory for spawning SSL/TLS objects
9396 * @param version Any of the following
9397 * * 0
9398 * * SSL3_VERSION
9399 * * TLS1_VERSION
9400 * * TLS1_1_VERSION
9401 * * TLS1_2_VERSION
9402 * * TLS1_3_VERSION
9403 * * DTLS1_VERSION
9404 * * DTLS1_2_VERSION
9405 * @return WOLFSSL_SUCCESS on valid settings and WOLFSSL_FAILURE when no
9406 * protocol versions are left enabled.
9407 */
9408static int Set_CTX_min_proto_version(WOLFSSL_CTX* ctx, int version)
9409{
9410 WOLFSSL_ENTER("wolfSSL_CTX_set_min_proto_version_ex");
9411
9412 if (ctx == NULL) {
9413 return WOLFSSL_FAILURE;
9414 }
9415
9416 switch (version) {
9417#ifndef NO_TLS
9418 case SSL3_VERSION:
9419#if defined(WOLFSSL_ALLOW_SSLV3) && !defined(NO_OLD_TLS)
9420 ctx->minDowngrade = SSLv3_MINOR;
9421 break;
9422#endif
9423 case TLS1_VERSION:
9424 #ifdef WOLFSSL_ALLOW_TLSV10
9425 ctx->minDowngrade = TLSv1_MINOR;
9426 break;
9427 #endif
9428 case TLS1_1_VERSION:
9429 #ifndef NO_OLD_TLS
9430 ctx->minDowngrade = TLSv1_1_MINOR;
9431 break;
9432 #endif
9433 case TLS1_2_VERSION:
9434 #ifndef WOLFSSL_NO_TLS12
9435 ctx->minDowngrade = TLSv1_2_MINOR;
9436 break;
9437 #endif
9438 case TLS1_3_VERSION:
9439 #ifdef WOLFSSL_TLS13
9440 ctx->minDowngrade = TLSv1_3_MINOR;
9441 break;
9442 #endif
9443#endif
9444#ifdef WOLFSSL_DTLS
9445 case DTLS1_VERSION:
9446 #ifndef NO_OLD_TLS
9447 ctx->minDowngrade = DTLS_MINOR;
9448 break;
9449 #endif
9450 case DTLS1_2_VERSION:
9451 ctx->minDowngrade = DTLSv1_2_MINOR;
9452 break;
9453#endif
9454 default:
9455 WOLFSSL_MSG("Unrecognized protocol version or not compiled in");
9456 return WOLFSSL_FAILURE;
9457 }
9458
9459 switch (version) {
9460#ifndef NO_TLS
9461 case TLS1_3_VERSION:
9462 wolfSSL_CTX_set_options(ctx, WOLFSSL_OP_NO_TLSv1_2);
9463 FALL_THROUGH;
9464 case TLS1_2_VERSION:
9465 wolfSSL_CTX_set_options(ctx, WOLFSSL_OP_NO_TLSv1_1);
9466 FALL_THROUGH;
9467 case TLS1_1_VERSION:
9468 wolfSSL_CTX_set_options(ctx, WOLFSSL_OP_NO_TLSv1);
9469 FALL_THROUGH;
9470 case TLS1_VERSION:
9471 wolfSSL_CTX_set_options(ctx, WOLFSSL_OP_NO_SSLv3);
9472 break;
9473 case SSL3_VERSION:
9474 case SSL2_VERSION:
9475 /* Nothing to do here */
9476 break;
9477#endif
9478#ifdef WOLFSSL_DTLS
9479 case DTLS1_VERSION:
9480 case DTLS1_2_VERSION:
9481 break;
9482#endif
9483 default:
9484 WOLFSSL_MSG("Unrecognized protocol version or not compiled in");
9485 return WOLFSSL_FAILURE;
9486 }
9487
9488 return CheckSslMethodVersion(ctx->method->version.major, ctx->mask);
9489}
9490
9491/* Sets the min protocol version allowed with WOLFSSL_CTX
9492 * returns WOLFSSL_SUCCESS on success */
9493int wolfSSL_CTX_set_min_proto_version(WOLFSSL_CTX* ctx, int version)
9494{
9495 int ret;
9496 int proto = 0;
9497 int maxProto = 0;
9498 int i;
9499 int idx = 0;
9500
9501 WOLFSSL_ENTER("wolfSSL_CTX_set_min_proto_version");
9502
9503 if (ctx == NULL) {
9504 return WOLFSSL_FAILURE;
9505 }
9506
9507 if (version != 0) {
9508 proto = version;
9509 ctx->minProto = 0; /* turn min proto flag off */
9510 for (i = 0; (unsigned)i < NUMBER_OF_PROTOCOLS; i++) {
9511 if (protoVerTbl[i] == version) {
9512 break;
9513 }
9514 }
9515 }
9516 else {
9517 /* when 0 is specified as version, try to find out the min version */
9518 for (i = 0; (unsigned)i < NUMBER_OF_PROTOCOLS; i++) {
9519 ret = Set_CTX_min_proto_version(ctx, protoVerTbl[i]);
9520 if (ret == WOLFSSL_SUCCESS) {
9521 proto = protoVerTbl[i];
9522 ctx->minProto = 1; /* turn min proto flag on */
9523 break;
9524 }
9525 }
9526 }
9527
9528 /* check case where max > min , if so then clear the NO_* options
9529 * i is the index into the table for proto version used, see if the max
9530 * proto version index found is smaller */
9531 maxProto = wolfSSL_CTX_get_max_proto_version(ctx);
9532 for (idx = 0; (unsigned)idx < NUMBER_OF_PROTOCOLS; idx++) {
9533 if (protoVerTbl[idx] == maxProto) {
9534 break;
9535 }
9536 }
9537 if (idx < i) {
9538 wolfSSL_CTX_clear_options(ctx, WOLFSSL_OP_NO_TLSv1 |
9539 WOLFSSL_OP_NO_TLSv1_1 | WOLFSSL_OP_NO_TLSv1_2 |
9540 WOLFSSL_OP_NO_TLSv1_3);
9541 }
9542
9543 ret = Set_CTX_min_proto_version(ctx, proto);
9544 return ret;
9545}
9546
9547/**
9548 * wolfSSL_CTX_set_max_proto_version attempts to set the maximum protocol
9549 * version to use by SSL objects created from this WOLFSSL_CTX.
9550 * This API guarantees that a version of SSL/TLS higher than specified
9551 * here will not be allowed. If the version specified is not compiled in
9552 * then this API sets the highest compiled in protocol version.
9553 * This API also accept 0 as version, to set the maximum version automatically.
9554 * CheckSslMethodVersion() is called to check if any remaining protocol versions
9555 * are enabled.
9556 * @param ctx The wolfSSL CONTEXT factory for spawning SSL/TLS objects
9557 * @param ver Any of the following
9558 * * 0
9559 * * SSL3_VERSION
9560 * * TLS1_VERSION
9561 * * TLS1_1_VERSION
9562 * * TLS1_2_VERSION
9563 * * TLS1_3_VERSION
9564 * * DTLS1_VERSION
9565 * * DTLS1_2_VERSION
9566 * @return WOLFSSL_SUCCESS on valid settings and WOLFSSL_FAILURE when no
9567 * protocol versions are left enabled.
9568 */
9569static int Set_CTX_max_proto_version(WOLFSSL_CTX* ctx, int ver)
9570{
9571 int ret;
9572 WOLFSSL_ENTER("Set_CTX_max_proto_version");
9573
9574 if (!ctx || !ctx->method) {
9575 WOLFSSL_MSG("Bad parameter");
9576 return WOLFSSL_FAILURE;
9577 }
9578
9579 switch (ver) {
9580#ifndef NO_TLS
9581#ifndef NO_OLD_TLS
9582 case SSL2_VERSION:
9583 WOLFSSL_MSG("wolfSSL does not support SSLv2");
9584 return WOLFSSL_FAILURE;
9585#endif
9586 case SSL3_VERSION:
9587 wolfSSL_CTX_set_options(ctx, WOLFSSL_OP_NO_TLSv1);
9588 FALL_THROUGH;
9589 case TLS1_VERSION:
9590 wolfSSL_CTX_set_options(ctx, WOLFSSL_OP_NO_TLSv1_1);
9591 FALL_THROUGH;
9592 case TLS1_1_VERSION:
9593 wolfSSL_CTX_set_options(ctx, WOLFSSL_OP_NO_TLSv1_2);
9594 FALL_THROUGH;
9595 case TLS1_2_VERSION:
9596 wolfSSL_CTX_set_options(ctx, WOLFSSL_OP_NO_TLSv1_3);
9597 FALL_THROUGH;
9598 case TLS1_3_VERSION:
9599 /* Nothing to do here */
9600 break;
9601#endif
9602#ifdef WOLFSSL_DTLS
9603 case DTLS1_VERSION:
9604 case DTLS1_2_VERSION:
9605 break;
9606#endif
9607 default:
9608 WOLFSSL_MSG("Unrecognized protocol version or not compiled in");
9609 return WOLFSSL_FAILURE;
9610 }
9611
9612 ret = CheckSslMethodVersion(ctx->method->version.major, ctx->mask);
9613 if (ret == WOLFSSL_SUCCESS) {
9614 /* Check the major */
9615 switch (ver) {
9616 #ifndef NO_TLS
9617 case SSL3_VERSION:
9618 case TLS1_VERSION:
9619 case TLS1_1_VERSION:
9620 case TLS1_2_VERSION:
9621 case TLS1_3_VERSION:
9622 if (ctx->method->version.major != SSLv3_MAJOR) {
9623 WOLFSSL_MSG("Mismatched protocol version");
9624 return WOLFSSL_FAILURE;
9625 }
9626 break;
9627 #endif
9628 #ifdef WOLFSSL_DTLS
9629 case DTLS1_VERSION:
9630 case DTLS1_2_VERSION:
9631 if (ctx->method->version.major != DTLS_MAJOR) {
9632 WOLFSSL_MSG("Mismatched protocol version");
9633 return WOLFSSL_FAILURE;
9634 }
9635 break;
9636 #endif
9637 }
9638 /* Update the method */
9639 switch (ver) {
9640 #ifndef NO_TLS
9641 case SSL3_VERSION:
9642 ctx->method->version.minor = SSLv3_MINOR;
9643 break;
9644 case TLS1_VERSION:
9645 ctx->method->version.minor = TLSv1_MINOR;
9646 break;
9647 case TLS1_1_VERSION:
9648 ctx->method->version.minor = TLSv1_1_MINOR;
9649 break;
9650 case TLS1_2_VERSION:
9651 ctx->method->version.minor = TLSv1_2_MINOR;
9652 break;
9653 case TLS1_3_VERSION:
9654 ctx->method->version.minor = TLSv1_3_MINOR;
9655 break;
9656 #endif
9657 #ifdef WOLFSSL_DTLS
9658 case DTLS1_VERSION:
9659 ctx->method->version.minor = DTLS_MINOR;
9660 break;
9661 case DTLS1_2_VERSION:
9662 ctx->method->version.minor = DTLSv1_2_MINOR;
9663 break;
9664 #endif
9665 default:
9666 WOLFSSL_MSG("Unrecognized protocol version or not compiled in");
9667 return WOLFSSL_FAILURE;
9668 }
9669 }
9670 return ret;
9671}
9672
9673
9674/* Sets the max protocol version allowed with WOLFSSL_CTX
9675 * returns WOLFSSL_SUCCESS on success */
9676int wolfSSL_CTX_set_max_proto_version(WOLFSSL_CTX* ctx, int version)
9677{
9678 int i;
9679 int ret = WC_NO_ERR_TRACE(WOLFSSL_FAILURE);
9680 int minProto;
9681
9682 WOLFSSL_ENTER("wolfSSL_CTX_set_max_proto_version");
9683
9684 if (ctx == NULL) {
9685 return ret;
9686 }
9687
9688 /* clear out flags and reset min protocol version */
9689 minProto = wolfSSL_CTX_get_min_proto_version(ctx);
9690 wolfSSL_CTX_clear_options(ctx,
9691 WOLFSSL_OP_NO_TLSv1 | WOLFSSL_OP_NO_TLSv1_1 |
9692 WOLFSSL_OP_NO_TLSv1_2 | WOLFSSL_OP_NO_TLSv1_3);
9693 wolfSSL_CTX_set_min_proto_version(ctx, minProto);
9694 if (version != 0) {
9695 ctx->maxProto = 0; /* turn max proto flag off */
9696 return Set_CTX_max_proto_version(ctx, version);
9697 }
9698
9699 /* when 0 is specified as version, try to find out the min version from
9700 * the bottom to top of the protoverTbl.
9701 */
9702 for (i = NUMBER_OF_PROTOCOLS -1; i >= 0; i--) {
9703 ret = Set_CTX_max_proto_version(ctx, protoVerTbl[i]);
9704 if (ret == WOLFSSL_SUCCESS) {
9705 ctx->maxProto = 1; /* turn max proto flag on */
9706 break;
9707 }
9708 }
9709
9710 return ret;
9711}
9712
9713
9714static int Set_SSL_min_proto_version(WOLFSSL* ssl, int ver)
9715{
9716 WOLFSSL_ENTER("Set_SSL_min_proto_version");
9717
9718 if (ssl == NULL) {
9719 return WOLFSSL_FAILURE;
9720 }
9721
9722 switch (ver) {
9723#ifndef NO_TLS
9724 case SSL3_VERSION:
9725#if defined(WOLFSSL_ALLOW_SSLV3) && !defined(NO_OLD_TLS)
9726 ssl->options.minDowngrade = SSLv3_MINOR;
9727 break;
9728#endif
9729 case TLS1_VERSION:
9730 #ifdef WOLFSSL_ALLOW_TLSV10
9731 ssl->options.minDowngrade = TLSv1_MINOR;
9732 break;
9733 #endif
9734 case TLS1_1_VERSION:
9735 #ifndef NO_OLD_TLS
9736 ssl->options.minDowngrade = TLSv1_1_MINOR;
9737 break;
9738 #endif
9739 case TLS1_2_VERSION:
9740 #ifndef WOLFSSL_NO_TLS12
9741 ssl->options.minDowngrade = TLSv1_2_MINOR;
9742 break;
9743 #endif
9744 case TLS1_3_VERSION:
9745 #ifdef WOLFSSL_TLS13
9746 ssl->options.minDowngrade = TLSv1_3_MINOR;
9747 break;
9748 #endif
9749#endif
9750#ifdef WOLFSSL_DTLS
9751 case DTLS1_VERSION:
9752 #ifndef NO_OLD_TLS
9753 ssl->options.minDowngrade = DTLS_MINOR;
9754 break;
9755 #endif
9756 case DTLS1_2_VERSION:
9757 ssl->options.minDowngrade = DTLSv1_2_MINOR;
9758 break;
9759#endif
9760 default:
9761 WOLFSSL_MSG("Unrecognized protocol version or not compiled in");
9762 return WOLFSSL_FAILURE;
9763 }
9764
9765 switch (ver) {
9766#ifndef NO_TLS
9767 case TLS1_3_VERSION:
9768 ssl->options.mask |= WOLFSSL_OP_NO_TLSv1_2;
9769 FALL_THROUGH;
9770 case TLS1_2_VERSION:
9771 ssl->options.mask |= WOLFSSL_OP_NO_TLSv1_1;
9772 FALL_THROUGH;
9773 case TLS1_1_VERSION:
9774 ssl->options.mask |= WOLFSSL_OP_NO_TLSv1;
9775 FALL_THROUGH;
9776 case TLS1_VERSION:
9777 ssl->options.mask |= WOLFSSL_OP_NO_SSLv3;
9778 break;
9779 case SSL3_VERSION:
9780 case SSL2_VERSION:
9781 /* Nothing to do here */
9782 break;
9783#endif
9784#ifdef WOLFSSL_DTLS
9785 case DTLS1_VERSION:
9786 case DTLS1_2_VERSION:
9787 break;
9788#endif
9789 default:
9790 WOLFSSL_MSG("Unrecognized protocol version or not compiled in");
9791 return WOLFSSL_FAILURE;
9792 }
9793
9794 return CheckSslMethodVersion(ssl->version.major, ssl->options.mask);
9795}
9796
9797int wolfSSL_set_min_proto_version(WOLFSSL* ssl, int version)
9798{
9799 int i;
9800 int ret = WC_NO_ERR_TRACE(WOLFSSL_FAILURE);;
9801
9802 WOLFSSL_ENTER("wolfSSL_set_min_proto_version");
9803
9804 if (ssl == NULL) {
9805 return WOLFSSL_FAILURE;
9806 }
9807 if (version != 0) {
9808 return Set_SSL_min_proto_version(ssl, version);
9809 }
9810
9811 /* when 0 is specified as version, try to find out the min version */
9812 for (i= 0; (unsigned)i < NUMBER_OF_PROTOCOLS; i++) {
9813 ret = Set_SSL_min_proto_version(ssl, protoVerTbl[i]);
9814 if (ret == WOLFSSL_SUCCESS)
9815 break;
9816 }
9817
9818 return ret;
9819}
9820
9821static int Set_SSL_max_proto_version(WOLFSSL* ssl, int ver)
9822{
9823
9824 WOLFSSL_ENTER("Set_SSL_max_proto_version");
9825
9826 if (!ssl) {
9827 WOLFSSL_MSG("Bad parameter");
9828 return WOLFSSL_FAILURE;
9829 }
9830
9831 switch (ver) {
9832 case SSL2_VERSION:
9833 WOLFSSL_MSG("wolfSSL does not support SSLv2");
9834 return WOLFSSL_FAILURE;
9835#ifndef NO_TLS
9836 case SSL3_VERSION:
9837 ssl->options.mask |= WOLFSSL_OP_NO_TLSv1;
9838 FALL_THROUGH;
9839 case TLS1_VERSION:
9840 ssl->options.mask |= WOLFSSL_OP_NO_TLSv1_1;
9841 FALL_THROUGH;
9842 case TLS1_1_VERSION:
9843 ssl->options.mask |= WOLFSSL_OP_NO_TLSv1_2;
9844 FALL_THROUGH;
9845 case TLS1_2_VERSION:
9846 ssl->options.mask |= WOLFSSL_OP_NO_TLSv1_3;
9847 FALL_THROUGH;
9848 case TLS1_3_VERSION:
9849 /* Nothing to do here */
9850 break;
9851#endif
9852#ifdef WOLFSSL_DTLS
9853 case DTLS1_VERSION:
9854 case DTLS1_2_VERSION:
9855 break;
9856#endif
9857 default:
9858 WOLFSSL_MSG("Unrecognized protocol version or not compiled in");
9859 return WOLFSSL_FAILURE;
9860 }
9861
9862 return CheckSslMethodVersion(ssl->version.major, ssl->options.mask);
9863}
9864
9865int wolfSSL_set_max_proto_version(WOLFSSL* ssl, int version)
9866{
9867 int i;
9868 int ret = WC_NO_ERR_TRACE(WOLFSSL_FAILURE);;
9869
9870 WOLFSSL_ENTER("wolfSSL_set_max_proto_version");
9871
9872 if (ssl == NULL) {
9873 return WOLFSSL_FAILURE;
9874 }
9875 if (version != 0) {
9876 return Set_SSL_max_proto_version(ssl, version);
9877 }
9878
9879 /* when 0 is specified as version, try to find out the min version from
9880 * the bottom to top of the protoverTbl.
9881 */
9882 for (i = NUMBER_OF_PROTOCOLS -1; i >= 0; i--) {
9883 ret = Set_SSL_max_proto_version(ssl, protoVerTbl[i]);
9884 if (ret == WOLFSSL_SUCCESS)
9885 break;
9886 }
9887
9888 return ret;
9889}
9890
9891static int GetMinProtoVersion(int minDowngrade)
9892{
9893 int ret;
9894
9895 switch (minDowngrade) {
9896#ifndef NO_OLD_TLS
9897 #ifdef WOLFSSL_ALLOW_SSLV3
9898 case SSLv3_MINOR:
9899 ret = SSL3_VERSION;
9900 break;
9901 #endif
9902 #ifdef WOLFSSL_ALLOW_TLSV10
9903 case TLSv1_MINOR:
9904 ret = TLS1_VERSION;
9905 break;
9906 #endif
9907 case TLSv1_1_MINOR:
9908 ret = TLS1_1_VERSION;
9909 break;
9910#endif
9911#ifndef WOLFSSL_NO_TLS12
9912 case TLSv1_2_MINOR:
9913 ret = TLS1_2_VERSION;
9914 break;
9915#endif
9916#ifdef WOLFSSL_TLS13
9917 case TLSv1_3_MINOR:
9918 ret = TLS1_3_VERSION;
9919 break;
9920#endif
9921 default:
9922 ret = 0;
9923 break;
9924 }
9925
9926 return ret;
9927}
9928
9929int wolfSSL_CTX_get_min_proto_version(WOLFSSL_CTX* ctx)
9930{
9931 int ret = 0;
9932
9933 WOLFSSL_ENTER("wolfSSL_CTX_get_min_proto_version");
9934
9935 if (ctx != NULL) {
9936 if (ctx->minProto) {
9937 ret = 0;
9938 }
9939 else {
9940 ret = GetMinProtoVersion(ctx->minDowngrade);
9941 }
9942 }
9943 else {
9944 ret = GetMinProtoVersion(WOLFSSL_MIN_DOWNGRADE);
9945 }
9946
9947 WOLFSSL_LEAVE("wolfSSL_CTX_get_min_proto_version", ret);
9948
9949 return ret;
9950}
9951
9952
9953/* returns the maximum allowed protocol version given the 'options' used
9954 * returns WOLFSSL_FATAL_ERROR on no match */
9955static int GetMaxProtoVersion(long options)
9956{
9957#ifndef NO_TLS
9958#ifdef WOLFSSL_TLS13
9959 if (!(options & WOLFSSL_OP_NO_TLSv1_3))
9960 return TLS1_3_VERSION;
9961#endif
9962#ifndef WOLFSSL_NO_TLS12
9963 if (!(options & WOLFSSL_OP_NO_TLSv1_2))
9964 return TLS1_2_VERSION;
9965#endif
9966#ifndef NO_OLD_TLS
9967 if (!(options & WOLFSSL_OP_NO_TLSv1_1))
9968 return TLS1_1_VERSION;
9969 #ifdef WOLFSSL_ALLOW_TLSV10
9970 if (!(options & WOLFSSL_OP_NO_TLSv1))
9971 return TLS1_VERSION;
9972 #endif
9973 #ifdef WOLFSSL_ALLOW_SSLV3
9974 if (!(options & WOLFSSL_OP_NO_SSLv3))
9975 return SSL3_VERSION;
9976 #endif
9977#endif
9978#else
9979 (void)options;
9980#endif /* NO_TLS */
9981 return WOLFSSL_FATAL_ERROR;
9982}
9983
9984
9985/* returns the maximum protocol version for 'ctx' */
9986int wolfSSL_CTX_get_max_proto_version(WOLFSSL_CTX* ctx)
9987{
9988 int ret = 0;
9989 long options = 0; /* default to nothing set */
9990
9991 WOLFSSL_ENTER("wolfSSL_CTX_get_max_proto_version");
9992
9993 if (ctx != NULL) {
9994 options = wolfSSL_CTX_get_options(ctx);
9995 }
9996
9997 if ((ctx != NULL) && ctx->maxProto) {
9998 ret = 0;
9999 }
10000 else {
10001 ret = GetMaxProtoVersion(options);
10002 }
10003
10004 WOLFSSL_LEAVE("wolfSSL_CTX_get_max_proto_version", ret);
10005
10006 if (ret == WC_NO_ERR_TRACE(WOLFSSL_FATAL_ERROR)) {
10007 WOLFSSL_MSG("Error getting max proto version");
10008 ret = 0; /* setting ret to 0 to match compat return */
10009 }
10010 return ret;
10011}
10012#endif /* OPENSSL_EXTRA */
10013
10014#if defined(OPENSSL_EXTRA) || defined(WOLFSSL_WPAS_SMALL) || \
10015 defined(HAVE_SECRET_CALLBACK)
10016#if !defined(NO_WOLFSSL_CLIENT)
10017/* Return the amount of random bytes copied over or error case.
10018 * ssl : ssl struct after handshake
10019 * out : buffer to hold random bytes
10020 * outSz : either 0 (return max buffer sz) or size of out buffer
10021 */
10022size_t wolfSSL_get_client_random(const WOLFSSL* ssl, unsigned char* out,
10023 size_t outSz)
10024{
10025 size_t size;
10026
10027 /* return max size of buffer */
10028 if (outSz == 0) {
10029 return RAN_LEN;
10030 }
10031
10032 if (ssl == NULL || out == NULL) {
10033 return 0;
10034 }
10035
10036 if (ssl->arrays == NULL) {
10037 WOLFSSL_MSG("Arrays struct not saved after handshake");
10038 return 0;
10039 }
10040
10041 if (outSz > RAN_LEN) {
10042 size = RAN_LEN;
10043 }
10044 else {
10045 size = outSz;
10046 }
10047
10048 XMEMCPY(out, ssl->arrays->clientRandom, size);
10049 return size;
10050}
10051#endif /* !NO_WOLFSSL_CLIENT */
10052#endif /* OPENSSL_EXTRA || WOLFSSL_WPAS_SMALL || HAVE_SECRET_CALLBACK */
10053
10054#ifdef OPENSSL_EXTRA
10055
10056 unsigned long wolfSSLeay(void)
10057 {
10058#ifdef SSLEAY_VERSION_NUMBER
10059 return SSLEAY_VERSION_NUMBER;
10060#else
10061 return OPENSSL_VERSION_NUMBER;
10062#endif
10063 }
10064
10065 unsigned long wolfSSL_OpenSSL_version_num(void)
10066 {
10067 return OPENSSL_VERSION_NUMBER;
10068 }
10069
10070 const char* wolfSSLeay_version(int type)
10071 {
10072 (void)type;
10073#if defined(OPENSSL_VERSION_NUMBER) && OPENSSL_VERSION_NUMBER >= 0x10100000L
10074 return wolfSSL_OpenSSL_version(type);
10075#else
10076 return wolfSSL_OpenSSL_version();
10077#endif
10078 }
10079#endif /* OPENSSL_EXTRA */
10080
10081#ifdef OPENSSL_EXTRA
10082 void wolfSSL_ERR_free_strings(void)
10083 {
10084 /* handled internally */
10085 }
10086
10087 void wolfSSL_cleanup_all_ex_data(void)
10088 {
10089 /* nothing to do here */
10090 }
10091
10092#endif /* OPENSSL_EXTRA */
10093
10094#if defined(OPENSSL_EXTRA) || defined(DEBUG_WOLFSSL_VERBOSE) || \
10095 defined(HAVE_CURL)
10096 void wolfSSL_ERR_clear_error(void)
10097 {
10098 WOLFSSL_ENTER("wolfSSL_ERR_clear_error");
10099 #if defined(OPENSSL_EXTRA) || defined(DEBUG_WOLFSSL_VERBOSE)
10100 wc_ClearErrorNodes();
10101 #endif
10102 }
10103#endif
10104
10105#if defined(OPENSSL_EXTRA) || defined(WOLFSSL_WPAS_SMALL)
10106 int wolfSSL_clear(WOLFSSL* ssl)
10107 {
10108 WOLFSSL_ENTER("wolfSSL_clear");
10109
10110 if (ssl == NULL) {
10111 return WOLFSSL_FAILURE;
10112 }
10113
10114 if (!ssl->options.handShakeDone) {
10115 /* Only reset the session if we didn't complete a handshake */
10116 wolfSSL_FreeSession(ssl->ctx, ssl->session);
10117 ssl->session = wolfSSL_NewSession(ssl->heap);
10118 if (ssl->session == NULL) {
10119 return WOLFSSL_FAILURE;
10120 }
10121 }
10122
10123 /* reset error */
10124 ssl->error = 0;
10125
10126 /* reset option bits */
10127 ssl->options.isClosed = 0;
10128 ssl->options.connReset = 0;
10129 ssl->options.sentNotify = 0;
10130 ssl->options.closeNotify = 0;
10131 ssl->options.sendVerify = 0;
10132 ssl->options.serverState = NULL_STATE;
10133 ssl->options.clientState = NULL_STATE;
10134 ssl->options.connectState = CONNECT_BEGIN;
10135 ssl->options.acceptState = ACCEPT_BEGIN;
10136 ssl->options.handShakeState = NULL_STATE;
10137 ssl->options.handShakeDone = 0;
10138 ssl->options.processReply = 0; /* doProcessInit */
10139 ssl->options.havePeerVerify = 0;
10140 ssl->options.havePeerCert = 0;
10141 ssl->options.peerAuthGood = 0;
10142 ssl->options.tls1_3 = 0;
10143 ssl->options.haveSessionId = 0;
10144 ssl->options.tls = 0;
10145 ssl->options.tls1_1 = 0;
10146 #ifdef WOLFSSL_TLS13
10147 #ifdef WOLFSSL_SEND_HRR_COOKIE
10148 ssl->options.hrrSentCookie = 0;
10149 #endif
10150 ssl->options.hrrSentKeyShare = 0;
10151 #endif
10152 #ifdef WOLFSSL_DTLS
10153 ssl->options.dtlsStateful = 0;
10154 #endif
10155 #ifdef WOLFSSL_TLS13
10156 #if defined(HAVE_SESSION_TICKET) || !defined(NO_PSK)
10157 if (ssl->ctx != NULL) {
10158 ssl->options.noPskDheKe = ssl->ctx->noPskDheKe;
10159 #ifdef HAVE_SUPPORTED_CURVES
10160 ssl->options.onlyPskDheKe = ssl->ctx->onlyPskDheKe;
10161 #endif
10162 }
10163 else {
10164 ssl->options.noPskDheKe = 0;
10165 #ifdef HAVE_SUPPORTED_CURVES
10166 ssl->options.onlyPskDheKe = 0;
10167 #endif
10168 }
10169 #endif
10170 #endif
10171 #ifdef HAVE_SESSION_TICKET
10172 #ifdef WOLFSSL_TLS13
10173 ssl->options.ticketsSent = 0;
10174 #endif
10175 ssl->options.rejectTicket = 0;
10176 #endif
10177 #ifdef WOLFSSL_EARLY_DATA
10178 ssl->earlyData = no_early_data;
10179 ssl->earlyDataSz = 0;
10180 #endif
10181
10182 #if defined(HAVE_TLS_EXTENSIONS) && !defined(NO_TLS)
10183 TLSX_FreeAll(ssl->extensions, ssl->heap);
10184 ssl->extensions = NULL;
10185 #if defined(HAVE_SECURE_RENEGOTIATION) \
10186 || defined(HAVE_SERVER_RENEGOTIATION_INFO)
10187 ssl->secure_renegotiation = NULL;
10188 #endif
10189 #endif
10190
10191 if (ssl->keys.encryptionOn) {
10192 ForceZero(ssl->buffers.inputBuffer.buffer -
10193 ssl->buffers.inputBuffer.offset,
10194 ssl->buffers.inputBuffer.bufferSize);
10195 #ifdef WOLFSSL_CHECK_MEM_ZERO
10196 wc_MemZero_Check(ssl->buffers.inputBuffer.buffer -
10197 ssl->buffers.inputBuffer.offset,
10198 ssl->buffers.inputBuffer.bufferSize);
10199 #endif
10200 }
10201 ssl->keys.encryptionOn = 0;
10202 XMEMSET(&ssl->msgsReceived, 0, sizeof(ssl->msgsReceived));
10203
10204 FreeCiphers(ssl);
10205 InitCiphers(ssl);
10206 InitCipherSpecs(&ssl->specs);
10207
10208 if (InitSSL_Suites(ssl) != WOLFSSL_SUCCESS)
10209 return WOLFSSL_FAILURE;
10210
10211 if (InitHandshakeHashes(ssl) != 0)
10212 return WOLFSSL_FAILURE;
10213
10214#ifdef KEEP_PEER_CERT
10215 FreeX509(&ssl->peerCert);
10216 InitX509(&ssl->peerCert, 0, ssl->heap);
10217#endif
10218
10219#ifdef WOLFSSL_QUIC
10220 wolfSSL_quic_clear(ssl);
10221#endif
10222#ifdef HAVE_OCSP
10223#if defined(WOLFSSL_TLS13) && defined(HAVE_CERTIFICATE_STATUS_REQUEST)
10224 ssl->response_idx = 0;
10225#endif
10226#endif
10227 return WOLFSSL_SUCCESS;
10228 }
10229
10230#endif /* OPENSSL_EXTRA || WOLFSSL_WPAS_SMALL */
10231
10232#if defined(OPENSSL_EXTRA) || defined(HAVE_WEBSERVER) || defined(HAVE_MEMCACHED)
10233 long wolfSSL_CTX_set_mode(WOLFSSL_CTX* ctx, long mode)
10234 {
10235 /* WOLFSSL_MODE_ACCEPT_MOVING_WRITE_BUFFER is wolfSSL default mode */
10236
10237 WOLFSSL_ENTER("wolfSSL_CTX_set_mode");
10238 switch(mode) {
10239 case WOLFSSL_MODE_ENABLE_PARTIAL_WRITE:
10240 ctx->partialWrite = 1;
10241 break;
10242 #if defined(OPENSSL_ALL) || defined(WOLFSSL_QT)
10243 case SSL_MODE_RELEASE_BUFFERS:
10244 WOLFSSL_MSG("SSL_MODE_RELEASE_BUFFERS not implemented.");
10245 break;
10246 #endif
10247 case WOLFSSL_MODE_AUTO_RETRY:
10248 ctx->autoRetry = 1;
10249 break;
10250 default:
10251 WOLFSSL_MSG("Mode Not Implemented");
10252 }
10253
10254 /* WOLFSSL_MODE_AUTO_RETRY
10255 * Should not return WOLFSSL_FATAL_ERROR with renegotiation on read/write */
10256
10257 return mode;
10258 }
10259
10260 long wolfSSL_CTX_clear_mode(WOLFSSL_CTX* ctx, long mode)
10261 {
10262 /* WOLFSSL_MODE_ACCEPT_MOVING_WRITE_BUFFER is wolfSSL default mode */
10263
10264 WOLFSSL_ENTER("wolfSSL_CTX_clear_mode");
10265 switch(mode) {
10266 case WOLFSSL_MODE_ENABLE_PARTIAL_WRITE:
10267 ctx->partialWrite = 0;
10268 break;
10269 #if defined(OPENSSL_ALL) || defined(WOLFSSL_QT)
10270 case SSL_MODE_RELEASE_BUFFERS:
10271 WOLFSSL_MSG("SSL_MODE_RELEASE_BUFFERS not implemented.");
10272 break;
10273 #endif
10274 case WOLFSSL_MODE_AUTO_RETRY:
10275 ctx->autoRetry = 0;
10276 break;
10277 default:
10278 WOLFSSL_MSG("Mode Not Implemented");
10279 }
10280
10281 /* WOLFSSL_MODE_AUTO_RETRY
10282 * Should not return WOLFSSL_FATAL_ERROR with renegotiation on read/write */
10283
10284 return 0;
10285 }
10286#endif
10287
10288#ifdef OPENSSL_EXTRA
10289
10290 #ifndef NO_WOLFSSL_STUB
10291 long wolfSSL_SSL_get_mode(WOLFSSL* ssl)
10292 {
10293 /* TODO: */
10294 (void)ssl;
10295 WOLFSSL_STUB("SSL_get_mode");
10296 return 0;
10297 }
10298 #endif
10299
10300 #ifndef NO_WOLFSSL_STUB
10301 long wolfSSL_CTX_get_mode(WOLFSSL_CTX* ctx)
10302 {
10303 /* TODO: */
10304 (void)ctx;
10305 WOLFSSL_STUB("SSL_CTX_get_mode");
10306 return 0;
10307 }
10308 #endif
10309
10310 #ifndef NO_WOLFSSL_STUB
10311 void wolfSSL_CTX_set_default_read_ahead(WOLFSSL_CTX* ctx, int m)
10312 {
10313 /* TODO: maybe? */
10314 (void)ctx;
10315 (void)m;
10316 WOLFSSL_STUB("SSL_CTX_set_default_read_ahead");
10317 }
10318 #endif
10319
10320
10321 /* returns the unsigned error value and increments the pointer into the
10322 * error queue.
10323 *
10324 * file pointer to file name
10325 * line gets set to line number of error when not NULL
10326 */
10327 unsigned long wolfSSL_ERR_get_error_line(const char** file, int* line)
10328 {
10329 #ifdef WOLFSSL_HAVE_ERROR_QUEUE
10330 int ret = wc_PullErrorNode(file, NULL, line);
10331 if (ret < 0) {
10332 if (ret == WC_NO_ERR_TRACE(BAD_STATE_E))
10333 return 0; /* no errors in queue */
10334 WOLFSSL_MSG("Issue getting error node");
10335 WOLFSSL_LEAVE("wolfSSL_ERR_get_error_line", ret);
10336 ret = 0 - ret; /* return absolute value of error */
10337
10338 /* panic and try to clear out nodes */
10339 wc_ClearErrorNodes();
10340 }
10341 return (unsigned long)ret;
10342 #else
10343 (void)file;
10344 (void)line;
10345
10346 return 0;
10347 #endif
10348 }
10349
10350
10351#if (defined(DEBUG_WOLFSSL) || defined(OPENSSL_EXTRA)) && \
10352 (!defined(_WIN32) && !defined(NO_ERROR_QUEUE))
10353 static const char WOLFSSL_SYS_ACCEPT_T[] = "accept";
10354 static const char WOLFSSL_SYS_BIND_T[] = "bind";
10355 static const char WOLFSSL_SYS_CONNECT_T[] = "connect";
10356 static const char WOLFSSL_SYS_FOPEN_T[] = "fopen";
10357 static const char WOLFSSL_SYS_FREAD_T[] = "fread";
10358 static const char WOLFSSL_SYS_GETADDRINFO_T[] = "getaddrinfo";
10359 static const char WOLFSSL_SYS_GETSOCKOPT_T[] = "getsockopt";
10360 static const char WOLFSSL_SYS_GETSOCKNAME_T[] = "getsockname";
10361 static const char WOLFSSL_SYS_GETHOSTBYNAME_T[] = "gethostbyname";
10362 static const char WOLFSSL_SYS_GETNAMEINFO_T[] = "getnameinfo";
10363 static const char WOLFSSL_SYS_GETSERVBYNAME_T[] = "getservbyname";
10364 static const char WOLFSSL_SYS_IOCTLSOCKET_T[] = "ioctlsocket";
10365 static const char WOLFSSL_SYS_LISTEN_T[] = "listen";
10366 static const char WOLFSSL_SYS_OPENDIR_T[] = "opendir";
10367 static const char WOLFSSL_SYS_SETSOCKOPT_T[] = "setsockopt";
10368 static const char WOLFSSL_SYS_SOCKET_T[] = "socket";
10369
10370 /* switch with int mapped to function name for compatibility */
10371 static const char* wolfSSL_ERR_sys_func(int fun)
10372 {
10373 switch (fun) {
10374 case WOLFSSL_SYS_ACCEPT: return WOLFSSL_SYS_ACCEPT_T;
10375 case WOLFSSL_SYS_BIND: return WOLFSSL_SYS_BIND_T;
10376 case WOLFSSL_SYS_CONNECT: return WOLFSSL_SYS_CONNECT_T;
10377 case WOLFSSL_SYS_FOPEN: return WOLFSSL_SYS_FOPEN_T;
10378 case WOLFSSL_SYS_FREAD: return WOLFSSL_SYS_FREAD_T;
10379 case WOLFSSL_SYS_GETADDRINFO: return WOLFSSL_SYS_GETADDRINFO_T;
10380 case WOLFSSL_SYS_GETSOCKOPT: return WOLFSSL_SYS_GETSOCKOPT_T;
10381 case WOLFSSL_SYS_GETSOCKNAME: return WOLFSSL_SYS_GETSOCKNAME_T;
10382 case WOLFSSL_SYS_GETHOSTBYNAME: return WOLFSSL_SYS_GETHOSTBYNAME_T;
10383 case WOLFSSL_SYS_GETNAMEINFO: return WOLFSSL_SYS_GETNAMEINFO_T;
10384 case WOLFSSL_SYS_GETSERVBYNAME: return WOLFSSL_SYS_GETSERVBYNAME_T;
10385 case WOLFSSL_SYS_IOCTLSOCKET: return WOLFSSL_SYS_IOCTLSOCKET_T;
10386 case WOLFSSL_SYS_LISTEN: return WOLFSSL_SYS_LISTEN_T;
10387 case WOLFSSL_SYS_OPENDIR: return WOLFSSL_SYS_OPENDIR_T;
10388 case WOLFSSL_SYS_SETSOCKOPT: return WOLFSSL_SYS_SETSOCKOPT_T;
10389 case WOLFSSL_SYS_SOCKET: return WOLFSSL_SYS_SOCKET_T;
10390 default:
10391 return "NULL";
10392 }
10393 }
10394#endif /* DEBUG_WOLFSSL */
10395
10396
10397 void wolfSSL_ERR_put_error(int lib, int fun, int err, const char* file,
10398 int line)
10399 {
10400 WOLFSSL_ENTER("wolfSSL_ERR_put_error");
10401
10402 #if !defined(DEBUG_WOLFSSL) && !defined(OPENSSL_EXTRA)
10403 (void)fun;
10404 (void)err;
10405 (void)file;
10406 (void)line;
10407 WOLFSSL_MSG("Not compiled in debug mode");
10408 #elif defined(OPENSSL_EXTRA) && \
10409 (defined(_WIN32) || defined(NO_ERROR_QUEUE))
10410 (void)fun;
10411 (void)file;
10412 (void)line;
10413 WOLFSSL_ERROR(err);
10414 #else
10415 WOLFSSL_ERROR_LINE(err, wolfSSL_ERR_sys_func(fun), (unsigned int)line,
10416 file, NULL);
10417 #endif
10418 (void)lib;
10419 }
10420
10421
10422 /* Similar to wolfSSL_ERR_get_error_line but takes in a flags argument for
10423 * more flexibility.
10424 *
10425 * file output pointer to file where error happened
10426 * line output to line number of error
10427 * data output data. Is a string if WOLFSSL_ERR_TXT_STRING flag is used
10428 * flags output format of output
10429 *
10430 * Returns the error value or 0 if no errors are in the queue
10431 */
10432 unsigned long wolfSSL_ERR_get_error_line_data(const char** file, int* line,
10433 const char** data, int *flags)
10434 {
10435#ifdef WOLFSSL_HAVE_ERROR_QUEUE
10436 int ret;
10437
10438 WOLFSSL_ENTER("wolfSSL_ERR_get_error_line_data");
10439
10440 if (flags != NULL)
10441 *flags = WOLFSSL_ERR_TXT_STRING; /* Clear the flags */
10442
10443 ret = wc_PullErrorNode(file, data, line);
10444 if (ret < 0) {
10445 if (ret == WC_NO_ERR_TRACE(BAD_STATE_E))
10446 return 0; /* no errors in queue */
10447 WOLFSSL_MSG("Error with pulling error node!");
10448 WOLFSSL_LEAVE("wolfSSL_ERR_get_error_line_data", ret);
10449 ret = 0 - ret; /* return absolute value of error */
10450
10451 /* panic and try to clear out nodes */
10452 wc_ClearErrorNodes();
10453 }
10454
10455 return (unsigned long)ret;
10456#else
10457 WOLFSSL_ENTER("wolfSSL_ERR_get_error_line_data");
10458 WOLFSSL_MSG("Error queue turned off, can not get error line");
10459 (void)file;
10460 (void)line;
10461 (void)data;
10462 (void)flags;
10463 return 0;
10464#endif
10465 }
10466
10467#endif /* OPENSSL_EXTRA */
10468
10469
10470#if (defined(KEEP_PEER_CERT) && defined(SESSION_CERTS)) || \
10471 (defined(OPENSSL_EXTRA) && defined(SESSION_CERTS))
10472 /* Decode the X509 DER encoded certificate into a WOLFSSL_X509 object.
10473 *
10474 * x509 WOLFSSL_X509 object to decode into.
10475 * in X509 DER data.
10476 * len Length of the X509 DER data.
10477 * returns the new certificate on success, otherwise NULL.
10478 */
10479 static int DecodeToX509(WOLFSSL_X509* x509, const byte* in, int len)
10480 {
10481 int ret;
10482 WC_DECLARE_VAR(cert, DecodedCert, 1, 0);
10483 if (x509 == NULL || in == NULL || len <= 0)
10484 return BAD_FUNC_ARG;
10485
10486 WC_ALLOC_VAR_EX(cert, DecodedCert, 1, NULL, DYNAMIC_TYPE_DCERT,
10487 return MEMORY_E);
10488
10489 /* Create a DecodedCert object and copy fields into WOLFSSL_X509 object.
10490 */
10491 InitDecodedCert(cert, (byte*)in, (word32)len, NULL);
10492 if ((ret = ParseCertRelative(cert, CERT_TYPE, 0, NULL, NULL)) == 0) {
10493 /* Check if x509 was not previously initialized by wolfSSL_X509_new() */
10494 if (x509->dynamicMemory != TRUE)
10495 InitX509(x509, 0, NULL);
10496 ret = CopyDecodedToX509(x509, cert);
10497 }
10498 FreeDecodedCert(cert);
10499 WC_FREE_VAR_EX(cert, NULL, DYNAMIC_TYPE_DCERT);
10500
10501 return ret;
10502 }
10503#endif /* (KEEP_PEER_CERT & SESSION_CERTS) || (OPENSSL_EXTRA & SESSION_CERTS) */
10504
10505
10506#ifdef KEEP_PEER_CERT
10507 WOLFSSL_ABI
10508 WOLFSSL_X509* wolfSSL_get_peer_certificate(WOLFSSL* ssl)
10509 {
10510 WOLFSSL_X509* ret = NULL;
10511 WOLFSSL_ENTER("wolfSSL_get_peer_certificate");
10512 if (ssl != NULL) {
10513 if (ssl->peerCert.issuer.sz)
10514 ret = wolfSSL_X509_dup(&ssl->peerCert);
10515#ifdef SESSION_CERTS
10516 else if (ssl->session->chain.count > 0) {
10517 if (DecodeToX509(&ssl->peerCert,
10518 ssl->session->chain.certs[0].buffer,
10519 ssl->session->chain.certs[0].length) == 0) {
10520 ret = wolfSSL_X509_dup(&ssl->peerCert);
10521 }
10522 }
10523#endif
10524 }
10525 WOLFSSL_LEAVE("wolfSSL_get_peer_certificate", ret != NULL);
10526 return ret;
10527 }
10528
10529#endif /* KEEP_PEER_CERT */
10530
10531#if defined(SESSION_CERTS) && defined(OPENSSL_EXTRA)
10532/* Return stack of peer certs.
10533 * Caller does not need to free return. The stack is Free'd when WOLFSSL* ssl
10534 * is.
10535 */
10536WOLF_STACK_OF(WOLFSSL_X509)* wolfSSL_get_peer_cert_chain(const WOLFSSL* ssl)
10537{
10538 WOLFSSL_ENTER("wolfSSL_get_peer_cert_chain");
10539
10540 if (ssl == NULL)
10541 return NULL;
10542
10543 /* Try to populate if NULL or empty */
10544 if (ssl->peerCertChain == NULL ||
10545 wolfSSL_sk_X509_num(ssl->peerCertChain) == 0) {
10546 wolfSSL_set_peer_cert_chain((WOLFSSL*) ssl);
10547 }
10548 return ssl->peerCertChain;
10549}
10550
10551
10552static int x509GetIssuerFromCM(WOLFSSL_X509 **issuer, WOLFSSL_CERT_MANAGER* cm,
10553 WOLFSSL_X509 *x);
10554/**
10555 * Recursively push the issuer CA chain onto the stack
10556 * @param cm The cert manager that is queried for the issuer
10557 * @param x This cert's issuer will be queried in cm
10558 * @param sk The issuer is pushed onto this stack
10559 * @return 0 on success or no issuer found
10560 * WOLFSSL_FATAL_ERROR on a fatal error
10561 */
10562static int PushCAx509Chain(WOLFSSL_CERT_MANAGER* cm,
10563 WOLFSSL_X509 *x, WOLFSSL_STACK* sk)
10564{
10565 int i;
10566 for (i = 0; i < MAX_CHAIN_DEPTH; i++) {
10567 WOLFSSL_X509* issuer = NULL;
10568 if (x509GetIssuerFromCM(&issuer, cm, x) != WOLFSSL_SUCCESS)
10569 break;
10570 if (wolfSSL_sk_X509_push(sk, issuer) <= 0) {
10571 wolfSSL_X509_free(issuer);
10572 issuer = NULL;
10573 return WOLFSSL_FATAL_ERROR;
10574 }
10575 x = issuer;
10576 }
10577 return 0;
10578}
10579
10580
10581/* Builds up and creates a stack of peer certificates for ssl->peerCertChain
10582 or ssl->verifiedChain based off of the ssl session chain. Attempts to place
10583 CA certificates at the bottom of the stack for a verified chain. Returns
10584 stack of WOLFSSL_X509 certs or NULL on failure */
10585static WOLF_STACK_OF(WOLFSSL_X509)* CreatePeerCertChain(const WOLFSSL* ssl,
10586 int verifiedFlag)
10587{
10588 WOLFSSL_STACK* sk;
10589 WOLFSSL_X509* x509;
10590 int i = 0;
10591 int err;
10592
10593 WOLFSSL_ENTER("wolfSSL_set_peer_cert_chain");
10594 if ((ssl == NULL) || (ssl->session->chain.count == 0))
10595 return NULL;
10596
10597 sk = wolfSSL_sk_X509_new_null();
10598 for (i = 0; i < ssl->session->chain.count; i++) {
10599 x509 = wolfSSL_X509_new_ex(ssl->heap);
10600 if (x509 == NULL) {
10601 WOLFSSL_MSG("Error Creating X509");
10602 wolfSSL_sk_X509_pop_free(sk, NULL);
10603 return NULL;
10604 }
10605 err = DecodeToX509(x509, ssl->session->chain.certs[i].buffer,
10606 ssl->session->chain.certs[i].length);
10607 if (err == 0 && wolfSSL_sk_X509_push(sk, x509) <= 0)
10608 err = WOLFSSL_FATAL_ERROR;
10609 if (err == 0 && i == ssl->session->chain.count-1 && verifiedFlag) {
10610 /* On the last element in the verified chain try to add the CA chain
10611 * if we have one for this cert */
10612 SSL_CM_WARNING(ssl);
10613 err = PushCAx509Chain(SSL_CM(ssl), x509, sk);
10614 }
10615 if (err != 0) {
10616 WOLFSSL_MSG("Error decoding cert");
10617 wolfSSL_X509_free(x509);
10618 x509 = NULL;
10619 wolfSSL_sk_X509_pop_free(sk, NULL);
10620 return NULL;
10621 }
10622 }
10623
10624 if (sk == NULL) {
10625 WOLFSSL_MSG("Null session chain");
10626 }
10627 return sk;
10628}
10629
10630
10631/* Builds up and creates a stack of peer certificates for ssl->peerCertChain
10632 returns the stack on success and NULL on failure */
10633WOLF_STACK_OF(WOLFSSL_X509)* wolfSSL_set_peer_cert_chain(WOLFSSL* ssl)
10634{
10635 WOLFSSL_STACK* sk;
10636
10637 WOLFSSL_ENTER("wolfSSL_set_peer_cert_chain");
10638 if ((ssl == NULL) || (ssl->session->chain.count == 0))
10639 return NULL;
10640
10641 sk = CreatePeerCertChain(ssl, 0);
10642
10643 if (sk != NULL) {
10644 if (ssl->options.side == WOLFSSL_SERVER_END) {
10645 if (ssl->session->peer)
10646 wolfSSL_X509_free(ssl->session->peer);
10647
10648 ssl->session->peer = wolfSSL_sk_X509_shift(sk);
10649 ssl->session->peerVerifyRet = ssl->peerVerifyRet;
10650 }
10651 if (ssl->peerCertChain != NULL)
10652 wolfSSL_sk_X509_pop_free(ssl->peerCertChain, NULL);
10653 /* This is Free'd when ssl is Free'd */
10654 ssl->peerCertChain = sk;
10655 }
10656 return sk;
10657}
10658
10659#ifdef KEEP_PEER_CERT
10660/**
10661 * Implemented in a similar way that ngx_ssl_ocsp_validate does it when
10662 * SSL_get0_verified_chain is not available.
10663 * @param ssl WOLFSSL object to extract certs from
10664 * @return Stack of verified certs
10665 */
10666WOLF_STACK_OF(WOLFSSL_X509) *wolfSSL_get0_verified_chain(const WOLFSSL *ssl)
10667{
10668 WOLF_STACK_OF(WOLFSSL_X509)* chain = NULL;
10669 WOLFSSL_X509_STORE_CTX* storeCtx = NULL;
10670 WOLFSSL_X509* peerCert = NULL;
10671
10672 WOLFSSL_ENTER("wolfSSL_get0_verified_chain");
10673
10674 if (ssl == NULL || ssl->ctx == NULL) {
10675 WOLFSSL_MSG("Bad parameter");
10676 return NULL;
10677 }
10678
10679 peerCert = wolfSSL_get_peer_certificate((WOLFSSL*)ssl);
10680 if (peerCert == NULL) {
10681 WOLFSSL_MSG("wolfSSL_get_peer_certificate error");
10682 return NULL;
10683 }
10684 /* wolfSSL_get_peer_certificate returns a copy. We want the internal
10685 * member so that we don't have to worry about free'ing it. We call
10686 * wolfSSL_get_peer_certificate so that we don't have to worry about
10687 * setting up the internal pointer. */
10688 wolfSSL_X509_free(peerCert);
10689 peerCert = (WOLFSSL_X509*)&ssl->peerCert;
10690 chain = CreatePeerCertChain((WOLFSSL*)ssl, 1);
10691 if (chain == NULL) {
10692 WOLFSSL_MSG("wolfSSL_get_peer_cert_chain error");
10693 return NULL;
10694 }
10695
10696 if (ssl->verifiedChain != NULL) {
10697 wolfSSL_sk_X509_pop_free(ssl->verifiedChain, NULL);
10698 }
10699 ((WOLFSSL*)ssl)->verifiedChain = chain;
10700
10701 storeCtx = wolfSSL_X509_STORE_CTX_new();
10702 if (storeCtx == NULL) {
10703 WOLFSSL_MSG("wolfSSL_X509_STORE_CTX_new error");
10704 return NULL;
10705 }
10706 if (wolfSSL_X509_STORE_CTX_init(storeCtx, SSL_STORE(ssl),
10707 peerCert, chain) != WOLFSSL_SUCCESS) {
10708 WOLFSSL_MSG("wolfSSL_X509_STORE_CTX_init error");
10709 wolfSSL_X509_STORE_CTX_free(storeCtx);
10710 return NULL;
10711 }
10712 if (wolfSSL_X509_verify_cert(storeCtx) <= 0) {
10713 WOLFSSL_MSG("wolfSSL_X509_verify_cert error");
10714 wolfSSL_X509_STORE_CTX_free(storeCtx);
10715 return NULL;
10716 }
10717 wolfSSL_X509_STORE_CTX_free(storeCtx);
10718 return chain;
10719}
10720#endif /* KEEP_PEER_CERT */
10721#endif /* SESSION_CERTS && OPENSSL_EXTRA */
10722
10723#if defined(OPENSSL_EXTRA) || defined(WOLFSSL_WPAS_SMALL)
10724void wolfSSL_set_connect_state(WOLFSSL* ssl)
10725{
10726 WOLFSSL_ENTER("wolfSSL_set_connect_state");
10727 if (ssl == NULL) {
10728 WOLFSSL_MSG("WOLFSSL struct pointer passed in was null");
10729 return;
10730 }
10731
10732 #ifndef NO_DH
10733 /* client creates its own DH parameters on handshake */
10734 if (ssl->buffers.serverDH_P.buffer && ssl->buffers.weOwnDH) {
10735 XFREE(ssl->buffers.serverDH_P.buffer, ssl->heap,
10736 DYNAMIC_TYPE_PUBLIC_KEY);
10737 }
10738 ssl->buffers.serverDH_P.buffer = NULL;
10739 if (ssl->buffers.serverDH_G.buffer && ssl->buffers.weOwnDH) {
10740 XFREE(ssl->buffers.serverDH_G.buffer, ssl->heap,
10741 DYNAMIC_TYPE_PUBLIC_KEY);
10742 }
10743 ssl->buffers.serverDH_G.buffer = NULL;
10744 #endif
10745
10746 if (InitSSL_Side(ssl, WOLFSSL_CLIENT_END) != WOLFSSL_SUCCESS) {
10747 WOLFSSL_MSG("Error initializing client side");
10748 }
10749}
10750#endif /* OPENSSL_EXTRA || WOLFSSL_WPAS_SMALL */
10751
10752
10753int wolfSSL_get_shutdown(const WOLFSSL* ssl)
10754{
10755 int isShutdown = 0;
10756
10757 WOLFSSL_ENTER("wolfSSL_get_shutdown");
10758
10759 if (ssl) {
10760#if defined(OPENSSL_EXTRA) || defined(WOLFSSL_WPAS_SMALL)
10761 if (ssl->options.shutdownDone) {
10762 /* The SSL object was possibly cleared with wolfSSL_clear after
10763 * a successful shutdown. Simulate a response for a full
10764 * bidirectional shutdown. */
10765 isShutdown = WOLFSSL_SENT_SHUTDOWN | WOLFSSL_RECEIVED_SHUTDOWN;
10766 }
10767 else
10768#endif
10769 {
10770 /* in OpenSSL, WOLFSSL_SENT_SHUTDOWN = 1, when closeNotifySent *
10771 * WOLFSSL_RECEIVED_SHUTDOWN = 2, from close notify or fatal err */
10772 if (ssl->options.sentNotify)
10773 isShutdown |= WOLFSSL_SENT_SHUTDOWN;
10774 if (ssl->options.closeNotify||ssl->options.connReset)
10775 isShutdown |= WOLFSSL_RECEIVED_SHUTDOWN;
10776 }
10777
10778 }
10779
10780 WOLFSSL_LEAVE("wolfSSL_get_shutdown", isShutdown);
10781 return isShutdown;
10782}
10783
10784
10785int wolfSSL_session_reused(WOLFSSL* ssl)
10786{
10787 int resuming = 0;
10788 WOLFSSL_ENTER("wolfSSL_session_reused");
10789 if (ssl) {
10790#ifndef HAVE_SECURE_RENEGOTIATION
10791 resuming = ssl->options.resuming;
10792#else
10793 resuming = ssl->options.resuming || ssl->options.resumed;
10794#endif
10795 }
10796 WOLFSSL_LEAVE("wolfSSL_session_reused", resuming);
10797 return resuming;
10798}
10799
10800/* helper function that takes in a protocol version struct and returns string */
10801static const char* wolfSSL_internal_get_version(const ProtocolVersion* version)
10802{
10803 WOLFSSL_ENTER("wolfSSL_get_version");
10804
10805 if (version == NULL) {
10806 return "Bad arg";
10807 }
10808
10809 if (version->major == SSLv3_MAJOR) {
10810 switch (version->minor) {
10811 case SSLv3_MINOR :
10812 return "SSLv3";
10813 case TLSv1_MINOR :
10814 return "TLSv1";
10815 case TLSv1_1_MINOR :
10816 return "TLSv1.1";
10817 case TLSv1_2_MINOR :
10818 return "TLSv1.2";
10819 case TLSv1_3_MINOR :
10820 return "TLSv1.3";
10821 default:
10822 return "unknown";
10823 }
10824 }
10825#ifdef WOLFSSL_DTLS
10826 else if (version->major == DTLS_MAJOR) {
10827 switch (version->minor) {
10828 case DTLS_MINOR :
10829 return "DTLS";
10830 case DTLSv1_2_MINOR :
10831 return "DTLSv1.2";
10832 case DTLSv1_3_MINOR :
10833 return "DTLSv1.3";
10834 default:
10835 return "unknown";
10836 }
10837 }
10838#endif /* WOLFSSL_DTLS */
10839 return "unknown";
10840}
10841
10842
10843const char* wolfSSL_get_version(const WOLFSSL* ssl)
10844{
10845 if (ssl == NULL) {
10846 WOLFSSL_MSG("Bad argument");
10847 return "unknown";
10848 }
10849
10850 return wolfSSL_internal_get_version(&ssl->version);
10851}
10852
10853
10854/* current library version */
10855const char* wolfSSL_lib_version(void)
10856{
10857 return LIBWOLFSSL_VERSION_STRING;
10858}
10859
10860#ifdef OPENSSL_EXTRA
10861#if defined(OPENSSL_VERSION_NUMBER) && OPENSSL_VERSION_NUMBER >= 0x10100000L
10862const char* wolfSSL_OpenSSL_version(int a)
10863{
10864 (void)a;
10865 return "wolfSSL " LIBWOLFSSL_VERSION_STRING;
10866}
10867#else
10868const char* wolfSSL_OpenSSL_version(void)
10869{
10870 return "wolfSSL " LIBWOLFSSL_VERSION_STRING;
10871}
10872#endif /* WOLFSSL_QT */
10873#endif
10874
10875
10876/* current library version in hex */
10877word32 wolfSSL_lib_version_hex(void)
10878{
10879 return LIBWOLFSSL_VERSION_HEX;
10880}
10881
10882
10883int wolfSSL_get_current_cipher_suite(WOLFSSL* ssl)
10884{
10885 WOLFSSL_ENTER("wolfSSL_get_current_cipher_suite");
10886 if (ssl)
10887 return (ssl->options.cipherSuite0 << 8) | ssl->options.cipherSuite;
10888 return 0;
10889}
10890
10891WOLFSSL_CIPHER* wolfSSL_get_current_cipher(WOLFSSL* ssl)
10892{
10893 WOLFSSL_ENTER("wolfSSL_get_current_cipher");
10894 if (ssl) {
10895 ssl->cipher.cipherSuite0 = ssl->options.cipherSuite0;
10896 ssl->cipher.cipherSuite = ssl->options.cipherSuite;
10897#if defined(OPENSSL_ALL) || defined(WOLFSSL_QT)
10898 ssl->cipher.bits = ssl->specs.key_size * 8;
10899#endif
10900 return &ssl->cipher;
10901 }
10902 else
10903 return NULL;
10904}
10905
10906
10907const char* wolfSSL_CIPHER_get_name(const WOLFSSL_CIPHER* cipher)
10908{
10909 WOLFSSL_ENTER("wolfSSL_CIPHER_get_name");
10910
10911 if (cipher == NULL) {
10912 return NULL;
10913 }
10914
10915 #if !defined(WOLFSSL_CIPHER_INTERNALNAME) && !defined(NO_ERROR_STRINGS) && \
10916 !defined(WOLFSSL_QT)
10917 return GetCipherNameIana(cipher->cipherSuite0, cipher->cipherSuite);
10918 #else
10919 return wolfSSL_get_cipher_name_from_suite(cipher->cipherSuite0,
10920 cipher->cipherSuite);
10921 #endif
10922}
10923
10924const char* wolfSSL_CIPHER_get_version(const WOLFSSL_CIPHER* cipher)
10925{
10926 WOLFSSL_ENTER("wolfSSL_CIPHER_get_version");
10927
10928 if (cipher == NULL || cipher->ssl == NULL) {
10929 return NULL;
10930 }
10931
10932 return wolfSSL_get_version(cipher->ssl);
10933}
10934
10935const char* wolfSSL_get_cipher(WOLFSSL* ssl)
10936{
10937 WOLFSSL_ENTER("wolfSSL_get_cipher");
10938 return wolfSSL_CIPHER_get_name(wolfSSL_get_current_cipher(ssl));
10939}
10940
10941/* gets cipher name in the format DHE-RSA-... rather then TLS_DHE... */
10942const char* wolfSSL_get_cipher_name(WOLFSSL* ssl)
10943{
10944 /* get access to cipher_name_idx in internal.c */
10945 return wolfSSL_get_cipher_name_internal(ssl);
10946}
10947
10948const char* wolfSSL_get_cipher_name_from_suite(byte cipherSuite0,
10949 byte cipherSuite)
10950{
10951 return GetCipherNameInternal(cipherSuite0, cipherSuite);
10952}
10953
10954const char* wolfSSL_get_cipher_name_iana_from_suite(byte cipherSuite0,
10955 byte cipherSuite)
10956{
10957 return GetCipherNameIana(cipherSuite0, cipherSuite);
10958}
10959
10960int wolfSSL_get_cipher_suite_from_name(const char* name, byte* cipherSuite0,
10961 byte* cipherSuite, int *flags) {
10962 if ((name == NULL) ||
10963 (cipherSuite0 == NULL) ||
10964 (cipherSuite == NULL) ||
10965 (flags == NULL))
10966 return BAD_FUNC_ARG;
10967 return GetCipherSuiteFromName(name, cipherSuite0, cipherSuite, NULL, NULL,
10968 flags);
10969}
10970
10971
10972word32 wolfSSL_CIPHER_get_id(const WOLFSSL_CIPHER* cipher)
10973{
10974 word16 cipher_id = 0;
10975
10976 WOLFSSL_ENTER("wolfSSL_CIPHER_get_id");
10977
10978 if (cipher && cipher->ssl) {
10979 cipher_id = (word16)(cipher->ssl->options.cipherSuite0 << 8) |
10980 cipher->ssl->options.cipherSuite;
10981 }
10982
10983 return cipher_id;
10984}
10985
10986const WOLFSSL_CIPHER* wolfSSL_get_cipher_by_value(word16 value)
10987{
10988 const WOLFSSL_CIPHER* cipher = NULL;
10989 byte cipherSuite0, cipherSuite;
10990 WOLFSSL_ENTER("wolfSSL_get_cipher_by_value");
10991
10992 /* extract cipher id information */
10993 cipherSuite = (value & 0xFF);
10994 cipherSuite0 = ((value >> 8) & 0xFF);
10995
10996 /* TODO: lookup by cipherSuite0 / cipherSuite */
10997 (void)cipherSuite0;
10998 (void)cipherSuite;
10999
11000 return cipher;
11001}
11002
11003
11004#if defined(HAVE_ECC) || defined(HAVE_CURVE25519) || defined(HAVE_CURVE448) || \
11005 !defined(NO_DH) || (defined(WOLFSSL_TLS13) && defined(WOLFSSL_HAVE_MLKEM))
11006#ifdef HAVE_FFDHE
11007static const char* wolfssl_ffdhe_name(word16 group)
11008{
11009 const char* str = NULL;
11010 switch (group) {
11011 case WOLFSSL_FFDHE_2048:
11012 str = "FFDHE_2048";
11013 break;
11014 case WOLFSSL_FFDHE_3072:
11015 str = "FFDHE_3072";
11016 break;
11017 case WOLFSSL_FFDHE_4096:
11018 str = "FFDHE_4096";
11019 break;
11020 case WOLFSSL_FFDHE_6144:
11021 str = "FFDHE_6144";
11022 break;
11023 case WOLFSSL_FFDHE_8192:
11024 str = "FFDHE_8192";
11025 break;
11026 default:
11027 break;
11028 }
11029 return str;
11030}
11031#endif
11032/* Return the name of the curve used for key exchange as a printable string.
11033 *
11034 * ssl The SSL/TLS object.
11035 * returns NULL if ECDH was not used, otherwise the name as a string.
11036 */
11037const char* wolfSSL_get_curve_name(WOLFSSL* ssl)
11038{
11039 const char* cName = NULL;
11040
11041 WOLFSSL_ENTER("wolfSSL_get_curve_name");
11042
11043 if (ssl == NULL)
11044 return NULL;
11045
11046#if defined(WOLFSSL_TLS13) && defined(WOLFSSL_HAVE_MLKEM)
11047 /* Check for post-quantum groups. Return now because we do not want the ECC
11048 * check to override this result in the case of a hybrid. */
11049 if (IsAtLeastTLSv1_3(ssl->version)) {
11050 switch (ssl->namedGroup) {
11051#ifndef WOLFSSL_NO_ML_KEM
11052 #ifndef WOLFSSL_NO_ML_KEM_512
11053 case WOLFSSL_ML_KEM_512:
11054 return "ML_KEM_512";
11055 #ifdef WOLFSSL_EXTRA_PQC_HYBRIDS
11056 #ifdef WOLFSSL_ML_KEM_USE_OLD_IDS
11057 case WOLFSSL_P256_ML_KEM_512_OLD:
11058 return "P256_ML_KEM_512_OLD";
11059 #endif /* WOLFSSL_ML_KEM_USE_OLD_IDS */
11060 case WOLFSSL_SECP256R1MLKEM512:
11061 return "SecP256r1MLKEM512";
11062 #ifdef HAVE_CURVE25519
11063 case WOLFSSL_X25519MLKEM512:
11064 return "X25519MLKEM512";
11065 #endif /* HAVE_CURVE25519 */
11066 #endif /* WOLFSSL_EXTRA_PQC_HYBRIDS */
11067 #endif /* WOLFSSL_NO_ML_KEM_512 */
11068 #ifndef WOLFSSL_NO_ML_KEM_768
11069 case WOLFSSL_ML_KEM_768:
11070 return "ML_KEM_768";
11071 #ifdef WOLFSSL_PQC_HYBRIDS
11072 case WOLFSSL_SECP256R1MLKEM768:
11073 return "SecP256r1MLKEM768";
11074 #ifdef HAVE_CURVE25519
11075 case WOLFSSL_X25519MLKEM768:
11076 return "X25519MLKEM768";
11077 #endif
11078 #endif /* WOLFSSL_PQC_HYBRIDS */
11079 #ifdef WOLFSSL_EXTRA_PQC_HYBRIDS
11080 #ifdef WOLFSSL_ML_KEM_USE_OLD_IDS
11081 case WOLFSSL_P384_ML_KEM_768_OLD:
11082 return "P384_ML_KEM_768_OLD";
11083 #endif /* WOLFSSL_ML_KEM_USE_OLD_IDS */
11084 case WOLFSSL_SECP384R1MLKEM768:
11085 return "SecP384r1MLKEM768";
11086 #ifdef HAVE_CURVE448
11087 case WOLFSSL_X448MLKEM768:
11088 return "X448MLKEM768";
11089 #endif /* HAVE_CURVE448 */
11090 #endif /* WOLFSSL_EXTRA_PQC_HYBRIDS */
11091 #endif /* WOLFSSL_NO_ML_KEM_768 */
11092 #ifndef WOLFSSL_NO_ML_KEM_1024
11093 case WOLFSSL_ML_KEM_1024:
11094 return "ML_KEM_1024";
11095 #ifdef WOLFSSL_PQC_HYBRIDS
11096 case WOLFSSL_SECP384R1MLKEM1024:
11097 return "SecP384r1MLKEM1024";
11098 #endif /* WOLFSSL_PQC_HYBRIDS */
11099 #ifdef WOLFSSL_EXTRA_PQC_HYBRIDS
11100 #ifdef WOLFSSL_ML_KEM_USE_OLD_IDS
11101 case WOLFSSL_P521_ML_KEM_1024_OLD:
11102 return "P521_ML_KEM_1024_OLD";
11103 #endif /* WOLFSSL_ML_KEM_USE_OLD_IDS */
11104 case WOLFSSL_SECP521R1MLKEM1024:
11105 return "SecP521r1MLKEM1024";
11106 #endif /* WOLFSSL_EXTRA_PQC_HYBRIDS */
11107 #endif /* WOLFSSL_NO_ML_KEM_1024 */
11108#endif /* WOLFSSL_NO_ML_KEM */
11109#ifdef WOLFSSL_MLKEM_KYBER
11110 #ifndef WOLFSSL_NO_KYBER512
11111 case WOLFSSL_KYBER_LEVEL1:
11112 return "KYBER_LEVEL1";
11113 case WOLFSSL_P256_KYBER_LEVEL1:
11114 return "P256_KYBER_LEVEL1";
11115 #ifdef HAVE_CURVE25519
11116 case WOLFSSL_X25519_KYBER_LEVEL1:
11117 return "X25519_KYBER_LEVEL1";
11118 #endif
11119 #endif
11120 #ifndef WOLFSSL_NO_KYBER768
11121 case WOLFSSL_KYBER_LEVEL3:
11122 return "KYBER_LEVEL3";
11123 case WOLFSSL_P384_KYBER_LEVEL3:
11124 return "P384_KYBER_LEVEL3";
11125 case WOLFSSL_P256_KYBER_LEVEL3:
11126 return "P256_KYBER_LEVEL3";
11127 #ifdef HAVE_CURVE25519
11128 case WOLFSSL_X25519_KYBER_LEVEL3:
11129 return "X25519_KYBER_LEVEL3";
11130 #endif
11131 #ifdef HAVE_CURVE448
11132 case WOLFSSL_X448_KYBER_LEVEL3:
11133 return "X448_KYBER_LEVEL3";
11134 #endif
11135 #endif
11136 #ifndef WOLFSSL_NO_KYBER1024
11137 case WOLFSSL_KYBER_LEVEL5:
11138 return "KYBER_LEVEL5";
11139 case WOLFSSL_P521_KYBER_LEVEL5:
11140 return "P521_KYBER_LEVEL5";
11141 #endif
11142#endif /* WOLFSSL_MLKEM_KYBER */
11143 }
11144 }
11145#endif /* WOLFSSL_TLS13 && WOLFSSL_HAVE_MLKEM */
11146
11147#ifdef HAVE_FFDHE
11148 if (ssl->namedGroup != 0) {
11149 cName = wolfssl_ffdhe_name(ssl->namedGroup);
11150 }
11151#endif
11152
11153#ifdef HAVE_CURVE25519
11154 if (ssl->ecdhCurveOID == ECC_X25519_OID && cName == NULL) {
11155 cName = "X25519";
11156 }
11157#endif
11158
11159#ifdef HAVE_CURVE448
11160 if (ssl->ecdhCurveOID == ECC_X448_OID && cName == NULL) {
11161 cName = "X448";
11162 }
11163#endif
11164
11165#ifdef HAVE_ECC
11166 if (ssl->ecdhCurveOID != 0 && cName == NULL) {
11167 cName = wc_ecc_get_name(wc_ecc_get_oid(ssl->ecdhCurveOID, NULL,
11168 NULL));
11169 }
11170#endif
11171
11172 return cName;
11173}
11174#endif
11175
11176#ifdef OPENSSL_EXTRA
11177#if defined(OPENSSL_ALL) || defined(WOLFSSL_QT)
11178/* return authentication NID corresponding to cipher suite
11179 * @param cipher a pointer to WOLFSSL_CIPHER
11180 * return NID if found, WC_NID_undef if not found
11181 */
11182int wolfSSL_CIPHER_get_auth_nid(const WOLFSSL_CIPHER* cipher)
11183{
11184 static const struct authnid {
11185 const char* alg_name;
11186 const int nid;
11187 } authnid_tbl[] = {
11188 {"RSA", WC_NID_auth_rsa},
11189 {"PSK", WC_NID_auth_psk},
11190 {"SRP", WC_NID_auth_srp},
11191 {"ECDSA", WC_NID_auth_ecdsa},
11192 {"None", WC_NID_auth_null},
11193 {NULL, WC_NID_undef}
11194 };
11195
11196 const char* authStr;
11197 char n[MAX_SEGMENTS][MAX_SEGMENT_SZ] = {{0}};
11198
11199 if (GetCipherSegment(cipher, n) == NULL) {
11200 WOLFSSL_MSG("no suitable cipher name found");
11201 return WC_NID_undef;
11202 }
11203
11204 authStr = GetCipherAuthStr(n);
11205
11206 if (authStr != NULL) {
11207 const struct authnid* sa;
11208 for(sa = authnid_tbl; sa->alg_name != NULL; sa++) {
11209 if (XSTRCMP(sa->alg_name, authStr) == 0) {
11210 return sa->nid;
11211 }
11212 }
11213 }
11214
11215 return WC_NID_undef;
11216}
11217/* return cipher NID corresponding to cipher suite
11218 * @param cipher a pointer to WOLFSSL_CIPHER
11219 * return NID if found, WC_NID_undef if not found
11220 */
11221int wolfSSL_CIPHER_get_cipher_nid(const WOLFSSL_CIPHER* cipher)
11222{
11223 static const struct ciphernid {
11224 const char* alg_name;
11225 const int nid;
11226 } ciphernid_tbl[] = {
11227 {"AESGCM(256)", WC_NID_aes_256_gcm},
11228 {"AESGCM(128)", WC_NID_aes_128_gcm},
11229 {"AESCCM(128)", WC_NID_aes_128_ccm},
11230 {"AES(128)", WC_NID_aes_128_cbc},
11231 {"AES(256)", WC_NID_aes_256_cbc},
11232 {"CAMELLIA(256)", WC_NID_camellia_256_cbc},
11233 {"CAMELLIA(128)", WC_NID_camellia_128_cbc},
11234 {"RC4", WC_NID_rc4},
11235 {"3DES", WC_NID_des_ede3_cbc},
11236 {"CHACHA20/POLY1305(256)", WC_NID_chacha20_poly1305},
11237 {"None", WC_NID_undef},
11238 {NULL, WC_NID_undef}
11239 };
11240
11241 const char* encStr;
11242 char n[MAX_SEGMENTS][MAX_SEGMENT_SZ] = {{0}};
11243
11244 WOLFSSL_ENTER("wolfSSL_CIPHER_get_cipher_nid");
11245
11246 if (GetCipherSegment(cipher, n) == NULL) {
11247 WOLFSSL_MSG("no suitable cipher name found");
11248 return WC_NID_undef;
11249 }
11250
11251 encStr = GetCipherEncStr(n);
11252
11253 if (encStr != NULL) {
11254 const struct ciphernid* c;
11255 for(c = ciphernid_tbl; c->alg_name != NULL; c++) {
11256 if (XSTRCMP(c->alg_name, encStr) == 0) {
11257 return c->nid;
11258 }
11259 }
11260 }
11261
11262 return WC_NID_undef;
11263}
11264/* return digest NID corresponding to cipher suite
11265 * @param cipher a pointer to WOLFSSL_CIPHER
11266 * return NID if found, WC_NID_undef if not found
11267 */
11268int wolfSSL_CIPHER_get_digest_nid(const WOLFSSL_CIPHER* cipher)
11269{
11270 static const struct macnid {
11271 const char* alg_name;
11272 const int nid;
11273 } macnid_tbl[] = {
11274 {"SHA1", WC_NID_sha1},
11275 {"SHA256", WC_NID_sha256},
11276 {"SHA384", WC_NID_sha384},
11277 {NULL, WC_NID_undef}
11278 };
11279
11280 const char* name;
11281 const char* macStr;
11282 char n[MAX_SEGMENTS][MAX_SEGMENT_SZ] = {{0}};
11283 (void)name;
11284
11285 WOLFSSL_ENTER("wolfSSL_CIPHER_get_digest_nid");
11286
11287 if ((name = GetCipherSegment(cipher, n)) == NULL) {
11288 WOLFSSL_MSG("no suitable cipher name found");
11289 return WC_NID_undef;
11290 }
11291
11292 /* in MD5 case, NID will be WC_NID_md5 */
11293 if (XSTRSTR(name, "MD5") != NULL) {
11294 return WC_NID_md5;
11295 }
11296
11297 macStr = GetCipherMacStr(n);
11298
11299 if (macStr != NULL) {
11300 const struct macnid* mc;
11301 for(mc = macnid_tbl; mc->alg_name != NULL; mc++) {
11302 if (XSTRCMP(mc->alg_name, macStr) == 0) {
11303 return mc->nid;
11304 }
11305 }
11306 }
11307
11308 return WC_NID_undef;
11309}
11310/* return key exchange NID corresponding to cipher suite
11311 * @param cipher a pointer to WOLFSSL_CIPHER
11312 * return NID if found, WC_NID_undef if not found
11313 */
11314int wolfSSL_CIPHER_get_kx_nid(const WOLFSSL_CIPHER* cipher)
11315{
11316 static const struct kxnid {
11317 const char* name;
11318 const int nid;
11319 } kxnid_table[] = {
11320 {"ECDHEPSK", WC_NID_kx_ecdhe_psk},
11321 {"ECDH", WC_NID_kx_ecdhe},
11322 {"DHEPSK", WC_NID_kx_dhe_psk},
11323 {"DH", WC_NID_kx_dhe},
11324 {"RSAPSK", WC_NID_kx_rsa_psk},
11325 {"SRP", WC_NID_kx_srp},
11326 {"EDH", WC_NID_kx_dhe},
11327 {"RSA", WC_NID_kx_rsa},
11328 {NULL, WC_NID_undef}
11329 };
11330
11331 const char* keaStr;
11332 char n[MAX_SEGMENTS][MAX_SEGMENT_SZ] = {{0}};
11333
11334 WOLFSSL_ENTER("wolfSSL_CIPHER_get_kx_nid");
11335
11336 if (GetCipherSegment(cipher, n) == NULL) {
11337 WOLFSSL_MSG("no suitable cipher name found");
11338 return WC_NID_undef;
11339 }
11340
11341 /* in TLS 1.3 case, NID will be WC_NID_kx_any */
11342 if (XSTRCMP(n[0], "TLS13") == 0) {
11343 return WC_NID_kx_any;
11344 }
11345
11346 keaStr = GetCipherKeaStr(n);
11347
11348 if (keaStr != NULL) {
11349 const struct kxnid* k;
11350 for(k = kxnid_table; k->name != NULL; k++) {
11351 if (XSTRCMP(k->name, keaStr) == 0) {
11352 return k->nid;
11353 }
11354 }
11355 }
11356
11357 return WC_NID_undef;
11358}
11359/* check if cipher suite is AEAD
11360 * @param cipher a pointer to WOLFSSL_CIPHER
11361 * return 1 if cipher is AEAD, 0 otherwise
11362 */
11363int wolfSSL_CIPHER_is_aead(const WOLFSSL_CIPHER* cipher)
11364{
11365 char n[MAX_SEGMENTS][MAX_SEGMENT_SZ] = {{0}};
11366
11367 WOLFSSL_ENTER("wolfSSL_CIPHER_is_aead");
11368
11369 if (GetCipherSegment(cipher, n) == NULL) {
11370 WOLFSSL_MSG("no suitable cipher name found");
11371 return WC_NID_undef;
11372 }
11373
11374 return IsCipherAEAD(n);
11375}
11376/* Creates cipher->description based on cipher->offset
11377 * cipher->offset is set in wolfSSL_get_ciphers_compat when it is added
11378 * to a stack of ciphers.
11379 * @param [in] cipher: A cipher from a stack of ciphers.
11380 * return WOLFSSL_SUCCESS if cipher->description is set, else WOLFSSL_FAILURE
11381 */
11382int wolfSSL_sk_CIPHER_description(WOLFSSL_CIPHER* cipher)
11383{
11384 int strLen;
11385 unsigned long offset;
11386 char* dp;
11387 const char* name;
11388 const char *keaStr, *authStr, *encStr, *macStr, *protocol;
11389 char n[MAX_SEGMENTS][MAX_SEGMENT_SZ] = {{0}};
11390 int len = MAX_DESCRIPTION_SZ-1;
11391 const CipherSuiteInfo* cipher_names;
11392 ProtocolVersion pv;
11393 WOLFSSL_ENTER("wolfSSL_sk_CIPHER_description");
11394
11395 if (cipher == NULL)
11396 return WOLFSSL_FAILURE;
11397
11398 dp = cipher->description;
11399 if (dp == NULL)
11400 return WOLFSSL_FAILURE;
11401
11402 cipher_names = GetCipherNames();
11403
11404 offset = cipher->offset;
11405 if (offset >= (unsigned long)GetCipherNamesSize())
11406 return WOLFSSL_FAILURE;
11407 pv.major = cipher_names[offset].major;
11408 pv.minor = cipher_names[offset].minor;
11409 protocol = wolfSSL_internal_get_version(&pv);
11410
11411 if ((name = GetCipherSegment(cipher, n)) == NULL) {
11412 WOLFSSL_MSG("no suitable cipher name found");
11413 return WOLFSSL_FAILURE;
11414 }
11415
11416 /* keaStr */
11417 keaStr = GetCipherKeaStr(n);
11418 /* authStr */
11419 authStr = GetCipherAuthStr(n);
11420 /* encStr */
11421 encStr = GetCipherEncStr(n);
11422 if ((cipher->bits = SetCipherBits(encStr)) ==
11423 WC_NO_ERR_TRACE(WOLFSSL_FAILURE))
11424 {
11425 WOLFSSL_MSG("Cipher Bits Not Set.");
11426 }
11427 /* macStr */
11428 macStr = GetCipherMacStr(n);
11429
11430
11431 /* Build up the string by copying onto the end. */
11432 XSTRNCPY(dp, name, (size_t)len);
11433 dp[len-1] = '\0'; strLen = (int)XSTRLEN(dp);
11434 len -= strLen; dp += strLen;
11435
11436 XSTRNCPY(dp, " ", (size_t)len);
11437 dp[len-1] = '\0'; strLen = (int)XSTRLEN(dp);
11438 len -= strLen; dp += strLen;
11439 XSTRNCPY(dp, protocol, (size_t)len);
11440 dp[len-1] = '\0'; strLen = (int)XSTRLEN(dp);
11441 len -= strLen; dp += strLen;
11442
11443 XSTRNCPY(dp, " Kx=", (size_t)len);
11444 dp[len-1] = '\0'; strLen = (int)XSTRLEN(dp);
11445 len -= strLen; dp += strLen;
11446 XSTRNCPY(dp, keaStr, (size_t)len);
11447 dp[len-1] = '\0'; strLen = (int)XSTRLEN(dp);
11448 len -= strLen; dp += strLen;
11449
11450 XSTRNCPY(dp, " Au=", (size_t)len);
11451 dp[len-1] = '\0'; strLen = (int)XSTRLEN(dp);
11452 len -= strLen; dp += strLen;
11453 XSTRNCPY(dp, authStr, (size_t)len);
11454 dp[len-1] = '\0'; strLen = (int)XSTRLEN(dp);
11455 len -= strLen; dp += strLen;
11456
11457 XSTRNCPY(dp, " Enc=", (size_t)len);
11458 dp[len-1] = '\0'; strLen = (int)XSTRLEN(dp);
11459 len -= strLen; dp += strLen;
11460 XSTRNCPY(dp, encStr, (size_t)len);
11461 dp[len-1] = '\0'; strLen = (int)XSTRLEN(dp);
11462 len -= strLen; dp += strLen;
11463
11464 XSTRNCPY(dp, " Mac=", (size_t)len);
11465 dp[len-1] = '\0'; strLen = (int)XSTRLEN(dp);
11466 len -= strLen; dp += (size_t)strLen;
11467 XSTRNCPY(dp, macStr, (size_t)len);
11468 dp[len-1] = '\0';
11469
11470 return WOLFSSL_SUCCESS;
11471}
11472#endif /* OPENSSL_ALL || WOLFSSL_QT */
11473
11474static WC_INLINE const char* wolfssl_kea_to_string(int kea)
11475{
11476 const char* keaStr;
11477
11478 switch (kea) {
11479 case no_kea:
11480 keaStr = "None";
11481 break;
11482#ifndef NO_RSA
11483 case rsa_kea:
11484 keaStr = "RSA";
11485 break;
11486#endif
11487#ifndef NO_DH
11488 case diffie_hellman_kea:
11489 keaStr = "DHE";
11490 break;
11491#endif
11492 case fortezza_kea:
11493 keaStr = "FZ";
11494 break;
11495#ifndef NO_PSK
11496 case psk_kea:
11497 keaStr = "PSK";
11498 break;
11499 #ifndef NO_DH
11500 case dhe_psk_kea:
11501 keaStr = "DHEPSK";
11502 break;
11503 #endif
11504 #ifdef HAVE_ECC
11505 case ecdhe_psk_kea:
11506 keaStr = "ECDHEPSK";
11507 break;
11508 #endif
11509#endif
11510#ifdef HAVE_ECC
11511 case ecc_diffie_hellman_kea:
11512 keaStr = "ECDHE";
11513 break;
11514 case ecc_static_diffie_hellman_kea:
11515 keaStr = "ECDH";
11516 break;
11517#endif
11518 case any_kea:
11519 keaStr = "any";
11520 break;
11521 default:
11522 keaStr = "unknown";
11523 break;
11524 }
11525
11526 return keaStr;
11527}
11528
11529static WC_INLINE const char* wolfssl_sigalg_to_string(int sig_algo)
11530{
11531 const char* authStr;
11532
11533 switch (sig_algo) {
11534 case anonymous_sa_algo:
11535 authStr = "None";
11536 break;
11537#ifndef NO_RSA
11538 case rsa_sa_algo:
11539 authStr = "RSA";
11540 break;
11541 #ifdef WC_RSA_PSS
11542 case rsa_pss_sa_algo:
11543 authStr = "RSA-PSS";
11544 break;
11545 #endif
11546#endif
11547#ifndef NO_DSA
11548 case dsa_sa_algo:
11549 authStr = "DSA";
11550 break;
11551#endif
11552#ifdef HAVE_ECC
11553 case ecc_dsa_sa_algo:
11554 authStr = "ECDSA";
11555 break;
11556#endif
11557#ifdef WOLFSSL_SM2
11558 case sm2_sa_algo:
11559 authStr = "SM2";
11560 break;
11561#endif
11562#ifdef HAVE_ED25519
11563 case ed25519_sa_algo:
11564 authStr = "Ed25519";
11565 break;
11566#endif
11567#ifdef HAVE_ED448
11568 case ed448_sa_algo:
11569 authStr = "Ed448";
11570 break;
11571#endif
11572 case any_sa_algo:
11573 authStr = "any";
11574 break;
11575 default:
11576 authStr = "unknown";
11577 break;
11578 }
11579
11580 return authStr;
11581}
11582
11583static WC_INLINE const char* wolfssl_cipher_to_string(int cipher, int key_size)
11584{
11585 const char* encStr;
11586
11587 (void)key_size;
11588
11589 switch (cipher) {
11590 case wolfssl_cipher_null:
11591 encStr = "None";
11592 break;
11593#ifndef NO_RC4
11594 case wolfssl_rc4:
11595 encStr = "RC4(128)";
11596 break;
11597#endif
11598#ifndef NO_DES3
11599 case wolfssl_triple_des:
11600 encStr = "3DES(168)";
11601 break;
11602#endif
11603#ifndef NO_AES
11604 case wolfssl_aes:
11605 if (key_size == AES_128_KEY_SIZE)
11606 encStr = "AES(128)";
11607 else if (key_size == AES_256_KEY_SIZE)
11608 encStr = "AES(256)";
11609 else
11610 encStr = "AES(?)";
11611 break;
11612 #ifdef HAVE_AESGCM
11613 case wolfssl_aes_gcm:
11614 if (key_size == AES_128_KEY_SIZE)
11615 encStr = "AESGCM(128)";
11616 else if (key_size == AES_256_KEY_SIZE)
11617 encStr = "AESGCM(256)";
11618 else
11619 encStr = "AESGCM(?)";
11620 break;
11621 #endif
11622 #ifdef HAVE_AESCCM
11623 case wolfssl_aes_ccm:
11624 if (key_size == AES_128_KEY_SIZE)
11625 encStr = "AESCCM(128)";
11626 else if (key_size == AES_256_KEY_SIZE)
11627 encStr = "AESCCM(256)";
11628 else
11629 encStr = "AESCCM(?)";
11630 break;
11631 #endif
11632#endif
11633#ifdef HAVE_CHACHA
11634 case wolfssl_chacha:
11635 encStr = "CHACHA20/POLY1305(256)";
11636 break;
11637#endif
11638#ifdef HAVE_ARIA
11639 case wolfssl_aria_gcm:
11640 if (key_size == ARIA_128_KEY_SIZE)
11641 encStr = "Aria(128)";
11642 else if (key_size == ARIA_192_KEY_SIZE)
11643 encStr = "Aria(192)";
11644 else if (key_size == ARIA_256_KEY_SIZE)
11645 encStr = "Aria(256)";
11646 else
11647 encStr = "Aria(?)";
11648 break;
11649#endif
11650#ifdef HAVE_CAMELLIA
11651 case wolfssl_camellia:
11652 if (key_size == CAMELLIA_128_KEY_SIZE)
11653 encStr = "Camellia(128)";
11654 else if (key_size == CAMELLIA_256_KEY_SIZE)
11655 encStr = "Camellia(256)";
11656 else
11657 encStr = "Camellia(?)";
11658 break;
11659#endif
11660 default:
11661 encStr = "unknown";
11662 break;
11663 }
11664
11665 return encStr;
11666}
11667
11668static WC_INLINE const char* wolfssl_mac_to_string(int mac)
11669{
11670 const char* macStr;
11671
11672 switch (mac) {
11673 case no_mac:
11674 macStr = "None";
11675 break;
11676#ifndef NO_MD5
11677 case md5_mac:
11678 macStr = "MD5";
11679 break;
11680#endif
11681#ifndef NO_SHA
11682 case sha_mac:
11683 macStr = "SHA1";
11684 break;
11685#endif
11686#ifdef WOLFSSL_SHA224
11687 case sha224_mac:
11688 macStr = "SHA224";
11689 break;
11690#endif
11691#ifndef NO_SHA256
11692 case sha256_mac:
11693 macStr = "SHA256";
11694 break;
11695#endif
11696#ifdef WOLFSSL_SHA384
11697 case sha384_mac:
11698 macStr = "SHA384";
11699 break;
11700#endif
11701#ifdef WOLFSSL_SHA512
11702 case sha512_mac:
11703 macStr = "SHA512";
11704 break;
11705#endif
11706 default:
11707 macStr = "unknown";
11708 break;
11709 }
11710
11711 return macStr;
11712}
11713
11714char* wolfSSL_CIPHER_description(const WOLFSSL_CIPHER* cipher, char* in,
11715 int len)
11716{
11717 char *ret = in;
11718 const char *keaStr, *authStr, *encStr, *macStr;
11719 size_t strLen;
11720 WOLFSSL_ENTER("wolfSSL_CIPHER_description");
11721
11722 if (cipher == NULL || in == NULL)
11723 return NULL;
11724
11725#if defined(WOLFSSL_QT) || defined(OPENSSL_ALL)
11726 /* if cipher is in the stack from wolfSSL_get_ciphers_compat then
11727 * Return the description based on cipher_names[cipher->offset]
11728 */
11729 if (cipher->in_stack == TRUE) {
11730 wolfSSL_sk_CIPHER_description((WOLFSSL_CIPHER*)cipher);
11731 XSTRNCPY(in,cipher->description,(size_t)len);
11732 return ret;
11733 }
11734#endif
11735
11736 /* Get the cipher description based on the SSL session cipher */
11737 keaStr = wolfssl_kea_to_string(cipher->ssl->specs.kea);
11738 authStr = wolfssl_sigalg_to_string(cipher->ssl->specs.sig_algo);
11739 encStr = wolfssl_cipher_to_string(cipher->ssl->specs.bulk_cipher_algorithm,
11740 cipher->ssl->specs.key_size);
11741 if (cipher->ssl->specs.cipher_type == aead)
11742 macStr = "AEAD";
11743 else
11744 macStr = wolfssl_mac_to_string(cipher->ssl->specs.mac_algorithm);
11745
11746 /* Build up the string by copying onto the end. */
11747 XSTRNCPY(in, wolfSSL_CIPHER_get_name(cipher), (size_t)len);
11748 in[len-1] = '\0'; strLen = XSTRLEN(in); len -= (int)strLen; in += strLen;
11749
11750 XSTRNCPY(in, " ", (size_t)len);
11751 in[len-1] = '\0'; strLen = XSTRLEN(in); len -= (int)strLen; in += strLen;
11752 XSTRNCPY(in, wolfSSL_get_version(cipher->ssl), (size_t)len);
11753 in[len-1] = '\0'; strLen = XSTRLEN(in); len -= (int)strLen; in += strLen;
11754
11755 XSTRNCPY(in, " Kx=", (size_t)len);
11756 in[len-1] = '\0'; strLen = XSTRLEN(in); len -= (int)strLen; in += strLen;
11757 XSTRNCPY(in, keaStr, (size_t)len);
11758 in[len-1] = '\0'; strLen = XSTRLEN(in); len -= (int)strLen; in += strLen;
11759
11760 XSTRNCPY(in, " Au=", (size_t)len);
11761 in[len-1] = '\0'; strLen = XSTRLEN(in); len -= (int)strLen; in += strLen;
11762 XSTRNCPY(in, authStr, (size_t)len);
11763 in[len-1] = '\0'; strLen = XSTRLEN(in); len -= (int)strLen; in += strLen;
11764
11765 XSTRNCPY(in, " Enc=", (size_t)len);
11766 in[len-1] = '\0'; strLen = XSTRLEN(in); len -= (int)strLen; in += strLen;
11767 XSTRNCPY(in, encStr, (size_t)len);
11768 in[len-1] = '\0'; strLen = XSTRLEN(in); len -= (int)strLen; in += strLen;
11769
11770 XSTRNCPY(in, " Mac=", (size_t)len);
11771 in[len-1] = '\0'; strLen = XSTRLEN(in); len -= (int)strLen; in += strLen;
11772 XSTRNCPY(in, macStr, (size_t)len);
11773 in[len-1] = '\0';
11774
11775 return ret;
11776}
11777
11778int wolfSSL_OCSP_parse_url(const char* url, char** host, char** port,
11779 char** path, int* ssl)
11780{
11781 const char* u;
11782 const char* upath; /* path in u */
11783 const char* uport; /* port in u */
11784 const char* hostEnd;
11785
11786 WOLFSSL_ENTER("OCSP_parse_url");
11787
11788 if (url == NULL || host == NULL || port == NULL || path == NULL ||
11789 ssl == NULL) {
11790 return WOLFSSL_FAILURE;
11791 }
11792
11793 u = url;
11794 *host = NULL;
11795 *port = NULL;
11796 *path = NULL;
11797 *ssl = 0;
11798
11799 if (*(u++) != 'h') goto err;
11800 if (*(u++) != 't') goto err;
11801 if (*(u++) != 't') goto err;
11802 if (*(u++) != 'p') goto err;
11803 if (*u == 's') {
11804 *ssl = 1;
11805 u++;
11806 *port = CopyString("443", -1, NULL, DYNAMIC_TYPE_OPENSSL);
11807 }
11808 else if (*u == ':') {
11809 *ssl = 0;
11810 *port = CopyString("80", -1, NULL, DYNAMIC_TYPE_OPENSSL);
11811 }
11812 else
11813 goto err;
11814 if (*port == NULL)
11815 goto err;
11816 if (*(u++) != ':') goto err;
11817 if (*(u++) != '/') goto err;
11818 if (*(u++) != '/') goto err;
11819
11820 /* Look for path */
11821 upath = XSTRSTR(u, "/");
11822 *path = CopyString(upath == NULL ? "/" : upath, -1, NULL,
11823 DYNAMIC_TYPE_OPENSSL);
11824
11825 /* Look for port */
11826 uport = XSTRSTR(u, ":");
11827 if (uport != NULL) {
11828 if (*(++uport) == '\0')
11829 goto err;
11830 /* port must be before path */
11831 if (upath != NULL && uport >= upath)
11832 goto err;
11833 XFREE(*port, NULL, DYNAMIC_TYPE_OPENSSL);
11834 if (upath)
11835 *port = CopyString(uport, (int)(upath - uport), NULL,
11836 DYNAMIC_TYPE_OPENSSL);
11837 else
11838 *port = CopyString(uport, -1, NULL, DYNAMIC_TYPE_OPENSSL);
11839 if (*port == NULL)
11840 goto err;
11841 hostEnd = uport - 1;
11842 }
11843 else
11844 hostEnd = upath;
11845
11846 if (hostEnd)
11847 *host = CopyString(u, (int)(hostEnd - u), NULL, DYNAMIC_TYPE_OPENSSL);
11848 else
11849 *host = CopyString(u, -1, NULL, DYNAMIC_TYPE_OPENSSL);
11850
11851 if (*host == NULL)
11852 goto err;
11853
11854 return WOLFSSL_SUCCESS;
11855err:
11856 XFREE(*host, NULL, DYNAMIC_TYPE_OPENSSL);
11857 *host = NULL;
11858 XFREE(*port, NULL, DYNAMIC_TYPE_OPENSSL);
11859 *port = NULL;
11860 XFREE(*path, NULL, DYNAMIC_TYPE_OPENSSL);
11861 *path = NULL;
11862 return WOLFSSL_FAILURE;
11863}
11864
11865#ifndef NO_WOLFSSL_STUB
11866WOLFSSL_COMP_METHOD* wolfSSL_COMP_zlib(void)
11867{
11868 WOLFSSL_STUB("COMP_zlib");
11869 return 0;
11870}
11871
11872WOLFSSL_COMP_METHOD* wolfSSL_COMP_rle(void)
11873{
11874 WOLFSSL_STUB("COMP_rle");
11875 return 0;
11876}
11877
11878int wolfSSL_COMP_add_compression_method(int method, void* data)
11879{
11880 (void)method;
11881 (void)data;
11882 WOLFSSL_STUB("COMP_add_compression_method");
11883 return 0;
11884}
11885
11886const WOLFSSL_COMP_METHOD* wolfSSL_get_current_compression(const WOLFSSL *ssl) {
11887 (void)ssl;
11888 return NULL;
11889}
11890
11891const WOLFSSL_COMP_METHOD* wolfSSL_get_current_expansion(const WOLFSSL *ssl) {
11892 (void)ssl;
11893 return NULL;
11894}
11895
11896const char* wolfSSL_COMP_get_name(const WOLFSSL_COMP_METHOD *comp)
11897{
11898 static const char ret[] = "not supported";
11899
11900 (void)comp;
11901 WOLFSSL_STUB("wolfSSL_COMP_get_name");
11902 return ret;
11903}
11904#endif
11905
11906/* wolfSSL_set_dynlock_create_callback
11907 * CRYPTO_set_dynlock_create_callback has been deprecated since openSSL 1.0.1.
11908 * This function exists for compatibility purposes because wolfSSL satisfies
11909 * thread safety without relying on the callback.
11910 */
11911void wolfSSL_set_dynlock_create_callback(WOLFSSL_dynlock_value* (*f)(
11912 const char*, int))
11913{
11914 WOLFSSL_STUB("CRYPTO_set_dynlock_create_callback");
11915 (void)f;
11916}
11917/* wolfSSL_set_dynlock_lock_callback
11918 * CRYPTO_set_dynlock_lock_callback has been deprecated since openSSL 1.0.1.
11919 * This function exists for compatibility purposes because wolfSSL satisfies
11920 * thread safety without relying on the callback.
11921 */
11922void wolfSSL_set_dynlock_lock_callback(
11923 void (*f)(int, WOLFSSL_dynlock_value*, const char*, int))
11924{
11925 WOLFSSL_STUB("CRYPTO_set_set_dynlock_lock_callback");
11926 (void)f;
11927}
11928/* wolfSSL_set_dynlock_destroy_callback
11929 * CRYPTO_set_dynlock_destroy_callback has been deprecated since openSSL 1.0.1.
11930 * This function exists for compatibility purposes because wolfSSL satisfies
11931 * thread safety without relying on the callback.
11932 */
11933void wolfSSL_set_dynlock_destroy_callback(
11934 void (*f)(WOLFSSL_dynlock_value*, const char*, int))
11935{
11936 WOLFSSL_STUB("CRYPTO_set_set_dynlock_destroy_callback");
11937 (void)f;
11938}
11939
11940/* Sets the DNS hostname to name.
11941 * Hostname is cleared if name is NULL or empty. */
11942int wolfSSL_set1_host(WOLFSSL * ssl, const char* name)
11943{
11944 if (ssl == NULL) {
11945 return WOLFSSL_FAILURE;
11946 }
11947
11948 return wolfSSL_X509_VERIFY_PARAM_set1_host(ssl->param, name, 0);
11949}
11950
11951/******************************************************************************
11952* wolfSSL_CTX_set1_param - set a pointer to the SSL verification parameters
11953*
11954* RETURNS:
11955* WOLFSSL_SUCCESS on success, otherwise returns WOLFSSL_FAILURE
11956* Note: Returns WOLFSSL_SUCCESS, in case either parameter is NULL,
11957* same as openssl.
11958*/
11959int wolfSSL_CTX_set1_param(WOLFSSL_CTX* ctx, WOLFSSL_X509_VERIFY_PARAM *vpm)
11960{
11961 if (ctx == NULL || vpm == NULL)
11962 return WOLFSSL_SUCCESS;
11963
11964 return wolfSSL_X509_VERIFY_PARAM_set1(ctx->param, vpm);
11965}
11966
11967/******************************************************************************
11968* wolfSSL_CTX/_get0_param - return a pointer to the SSL verification parameters
11969*
11970* RETURNS:
11971* returns pointer to the SSL verification parameters on success,
11972* otherwise returns NULL
11973*/
11974WOLFSSL_X509_VERIFY_PARAM* wolfSSL_CTX_get0_param(WOLFSSL_CTX* ctx)
11975{
11976 if (ctx == NULL) {
11977 return NULL;
11978 }
11979
11980 return ctx->param;
11981}
11982
11983WOLFSSL_X509_VERIFY_PARAM* wolfSSL_get0_param(WOLFSSL* ssl)
11984{
11985 if (ssl == NULL) {
11986 return NULL;
11987 }
11988 return ssl->param;
11989}
11990
11991#endif /* OPENSSL_EXTRA */
11992
11993#if defined(OPENSSL_EXTRA) || defined(WOLFSSL_WPAS_SMALL)
11994/* Gets an index to store SSL structure at.
11995 *
11996 * Returns positive index on success and negative values on failure
11997 */
11998int wolfSSL_get_ex_data_X509_STORE_CTX_idx(void)
11999{
12000 WOLFSSL_ENTER("wolfSSL_get_ex_data_X509_STORE_CTX_idx");
12001
12002 /* store SSL at index 0 */
12003 return 0;
12004}
12005#endif /* OPENSSL_EXTRA || WOLFSSL_WPAS_SMALL */
12006
12007#ifdef OPENSSL_EXTRA
12008/* Sets a function callback that will send information about the state of all
12009 * WOLFSSL objects that have been created by the WOLFSSL_CTX structure passed
12010 * in.
12011 *
12012 * ctx WOLFSSL_CTX structure to set callback function in
12013 * f callback function to use
12014 */
12015void wolfSSL_CTX_set_info_callback(WOLFSSL_CTX* ctx,
12016 void (*f)(const WOLFSSL* ssl, int type, int val))
12017{
12018 WOLFSSL_ENTER("wolfSSL_CTX_set_info_callback");
12019 if (ctx == NULL) {
12020 WOLFSSL_MSG("Bad function argument");
12021 }
12022 else {
12023 ctx->CBIS = f;
12024 }
12025}
12026
12027void wolfSSL_set_info_callback(WOLFSSL* ssl,
12028 void (*f)(const WOLFSSL* ssl, int type, int val))
12029{
12030 WOLFSSL_ENTER("wolfSSL_set_info_callback");
12031 if (ssl == NULL) {
12032 WOLFSSL_MSG("Bad function argument");
12033 }
12034 else {
12035 ssl->CBIS = f;
12036 }
12037}
12038
12039
12040unsigned long wolfSSL_ERR_peek_error(void)
12041{
12042 WOLFSSL_ENTER("wolfSSL_ERR_peek_error");
12043
12044 return wolfSSL_ERR_peek_error_line_data(NULL, NULL, NULL, NULL);
12045}
12046
12047#ifdef WOLFSSL_DEBUG_TRACE_ERROR_CODES_H
12048#include <wolfssl/debug-untrace-error-codes.h>
12049#endif
12050
12051int wolfSSL_ERR_GET_LIB(unsigned long err)
12052{
12053 unsigned long value;
12054
12055 value = (err & 0xFFFFFFL);
12056 switch (value) {
12057 case -PARSE_ERROR:
12058 return WOLFSSL_ERR_LIB_SSL;
12059 case -ASN_NO_PEM_HEADER:
12060 case -WOLFSSL_PEM_R_NO_START_LINE_E:
12061 case -WOLFSSL_PEM_R_PROBLEMS_GETTING_PASSWORD_E:
12062 case -WOLFSSL_PEM_R_BAD_PASSWORD_READ_E:
12063 case -WOLFSSL_PEM_R_BAD_DECRYPT_E:
12064 return WOLFSSL_ERR_LIB_PEM;
12065 case -WOLFSSL_EVP_R_BAD_DECRYPT_E:
12066 case -WOLFSSL_EVP_R_BN_DECODE_ERROR:
12067 case -WOLFSSL_EVP_R_DECODE_ERROR:
12068 case -WOLFSSL_EVP_R_PRIVATE_KEY_DECODE_ERROR:
12069 return WOLFSSL_ERR_LIB_EVP;
12070 case -WOLFSSL_ASN1_R_HEADER_TOO_LONG_E:
12071 return WOLFSSL_ERR_LIB_ASN1;
12072 default:
12073 return 0;
12074 }
12075}
12076
12077#ifdef WOLFSSL_DEBUG_TRACE_ERROR_CODES
12078#include <wolfssl/debug-trace-error-codes.h>
12079#endif
12080
12081/* This function is to find global error values that are the same through out
12082 * all library version. With wolfSSL having only one set of error codes the
12083 * return value is pretty straight forward. The only thing needed is all wolfSSL
12084 * error values are typically negative.
12085 *
12086 * Returns the error reason
12087 */
12088int wolfSSL_ERR_GET_REASON(unsigned long err)
12089{
12090 int ret = (int)err;
12091
12092 WOLFSSL_ENTER("wolfSSL_ERR_GET_REASON");
12093
12094#if defined(OPENSSL_ALL) || defined(WOLFSSL_NGINX) || defined(WOLFSSL_HAPROXY)
12095 /* Nginx looks for this error to know to stop parsing certificates.
12096 * Same for HAProxy. */
12097 if ((err == (unsigned long)((ERR_LIB_PEM << 24) | PEM_R_NO_START_LINE)) ||
12098 ((err & 0xFFFFFFL) == (unsigned long)(-WC_NO_ERR_TRACE(ASN_NO_PEM_HEADER))) ||
12099 ((err & 0xFFFL) == (unsigned long)PEM_R_NO_START_LINE))
12100 return PEM_R_NO_START_LINE;
12101 if (err == (unsigned long)((ERR_LIB_SSL << 24) | -SSL_R_HTTP_REQUEST))
12102 return SSL_R_HTTP_REQUEST;
12103#endif
12104#if defined(OPENSSL_ALL) && defined(WOLFSSL_PYTHON)
12105 if (err == (unsigned long)((ERR_LIB_ASN1 << 24) | ASN1_R_HEADER_TOO_LONG))
12106 return ASN1_R_HEADER_TOO_LONG;
12107#endif
12108
12109 /* check if error value is in range of wolfCrypt or wolfSSL errors */
12110 ret = 0 - ret; /* setting as negative value */
12111
12112 if ((ret <= WC_SPAN1_FIRST_E && ret >= WC_SPAN1_LAST_E) ||
12113 (ret <= WC_SPAN2_FIRST_E && ret >= WC_SPAN2_LAST_E) ||
12114 (ret <= WOLFSSL_FIRST_E && ret >= WOLFSSL_LAST_E))
12115 {
12116 return ret;
12117 }
12118 else {
12119 WOLFSSL_MSG("Not in range of typical error values");
12120 ret = (int)err;
12121 }
12122
12123 return ret;
12124}
12125
12126#ifndef NO_TLS
12127/* returns a string that describes the alert
12128 *
12129 * alertID the alert value to look up
12130 */
12131const char* wolfSSL_alert_type_string_long(int alertID)
12132{
12133 WOLFSSL_ENTER("wolfSSL_alert_type_string_long");
12134
12135 return AlertTypeToString(alertID);
12136}
12137
12138const char* wolfSSL_alert_desc_string_long(int alertID)
12139{
12140 WOLFSSL_ENTER("wolfSSL_alert_desc_string_long");
12141
12142 return AlertTypeToString(alertID);
12143}
12144#endif /* !NO_TLS */
12145
12146#define STATE_STRINGS_PROTO(s) \
12147 { \
12148 {"SSLv3 " s, \
12149 "SSLv3 " s, \
12150 "SSLv3 " s}, \
12151 {"TLSv1 " s, \
12152 "TLSv1 " s, \
12153 "TLSv1 " s}, \
12154 {"TLSv1_1 " s, \
12155 "TLSv1_1 " s, \
12156 "TLSv1_1 " s}, \
12157 {"TLSv1_2 " s, \
12158 "TLSv1_2 " s, \
12159 "TLSv1_2 " s}, \
12160 {"TLSv1_3 " s, \
12161 "TLSv1_3 " s, \
12162 "TLSv1_3 " s}, \
12163 {"DTLSv1 " s, \
12164 "DTLSv1 " s, \
12165 "DTLSv1 " s}, \
12166 {"DTLSv1_2 " s, \
12167 "DTLSv1_2 " s, \
12168 "DTLSv1_2 " s}, \
12169 {"DTLSv1_3 " s, \
12170 "DTLSv1_3 " s, \
12171 "DTLSv1_3 " s}, \
12172 }
12173
12174#define STATE_STRINGS_PROTO_RW(s) \
12175 { \
12176 {"SSLv3 read " s, \
12177 "SSLv3 write " s, \
12178 "SSLv3 " s}, \
12179 {"TLSv1 read " s, \
12180 "TLSv1 write " s, \
12181 "TLSv1 " s}, \
12182 {"TLSv1_1 read " s, \
12183 "TLSv1_1 write " s, \
12184 "TLSv1_1 " s}, \
12185 {"TLSv1_2 read " s, \
12186 "TLSv1_2 write " s, \
12187 "TLSv1_2 " s}, \
12188 {"TLSv1_3 read " s, \
12189 "TLSv1_3 write " s, \
12190 "TLSv1_3 " s}, \
12191 {"DTLSv1 read " s, \
12192 "DTLSv1 write " s, \
12193 "DTLSv1 " s}, \
12194 {"DTLSv1_2 read " s, \
12195 "DTLSv1_2 write " s, \
12196 "DTLSv1_2 " s}, \
12197 {"DTLSv1_3 read " s, \
12198 "DTLSv1_3 write " s, \
12199 "DTLSv1_3 " s}, \
12200 }
12201
12202/* Gets the current state of the WOLFSSL structure
12203 *
12204 * ssl WOLFSSL structure to get state of
12205 *
12206 * Returns a human readable string of the WOLFSSL structure state
12207 */
12208const char* wolfSSL_state_string_long(const WOLFSSL* ssl)
12209{
12210
12211 static const char* OUTPUT_STR[24][8][3] = {
12212 STATE_STRINGS_PROTO("Initialization"),
12213 STATE_STRINGS_PROTO_RW("Server Hello Request"),
12214 STATE_STRINGS_PROTO_RW("Server Hello Verify Request"),
12215 STATE_STRINGS_PROTO_RW("Server Hello Retry Request"),
12216 STATE_STRINGS_PROTO_RW("Server Hello"),
12217 STATE_STRINGS_PROTO_RW("Server Certificate Status"),
12218 STATE_STRINGS_PROTO_RW("Server Encrypted Extensions"),
12219 STATE_STRINGS_PROTO_RW("Server Session Ticket"),
12220 STATE_STRINGS_PROTO_RW("Server Certificate Request"),
12221 STATE_STRINGS_PROTO_RW("Server Cert"),
12222 STATE_STRINGS_PROTO_RW("Server Key Exchange"),
12223 STATE_STRINGS_PROTO_RW("Server Hello Done"),
12224 STATE_STRINGS_PROTO_RW("Server Change CipherSpec"),
12225 STATE_STRINGS_PROTO_RW("Server Finished"),
12226 STATE_STRINGS_PROTO_RW("server Key Update"),
12227 STATE_STRINGS_PROTO_RW("Client Hello"),
12228 STATE_STRINGS_PROTO_RW("Client Key Exchange"),
12229 STATE_STRINGS_PROTO_RW("Client Cert"),
12230 STATE_STRINGS_PROTO_RW("Client Change CipherSpec"),
12231 STATE_STRINGS_PROTO_RW("Client Certificate Verify"),
12232 STATE_STRINGS_PROTO_RW("Client End Of Early Data"),
12233 STATE_STRINGS_PROTO_RW("Client Finished"),
12234 STATE_STRINGS_PROTO_RW("Client Key Update"),
12235 STATE_STRINGS_PROTO("Handshake Done"),
12236 };
12237 enum ProtocolVer {
12238 SSL_V3 = 0,
12239 TLS_V1,
12240 TLS_V1_1,
12241 TLS_V1_2,
12242 TLS_V1_3,
12243 DTLS_V1,
12244 DTLS_V1_2,
12245 DTLS_V1_3,
12246 UNKNOWN = 100
12247 };
12248
12249 enum IOMode {
12250 SS_READ = 0,
12251 SS_WRITE,
12252 SS_NEITHER
12253 };
12254
12255 enum SslState {
12256 ss_null_state = 0,
12257 ss_server_hellorequest,
12258 ss_server_helloverify,
12259 ss_server_helloretryrequest,
12260 ss_server_hello,
12261 ss_server_certificatestatus,
12262 ss_server_encryptedextensions,
12263 ss_server_sessionticket,
12264 ss_server_certrequest,
12265 ss_server_cert,
12266 ss_server_keyexchange,
12267 ss_server_hellodone,
12268 ss_server_changecipherspec,
12269 ss_server_finished,
12270 ss_server_keyupdate,
12271 ss_client_hello,
12272 ss_client_keyexchange,
12273 ss_client_cert,
12274 ss_client_changecipherspec,
12275 ss_client_certverify,
12276 ss_client_endofearlydata,
12277 ss_client_finished,
12278 ss_client_keyupdate,
12279 ss_handshake_done
12280 };
12281
12282 int protocol = 0;
12283 int cbmode = 0;
12284 int state = 0;
12285
12286 WOLFSSL_ENTER("wolfSSL_state_string_long");
12287 if (ssl == NULL) {
12288 WOLFSSL_MSG("Null argument passed in");
12289 return NULL;
12290 }
12291
12292 /* Get state of callback */
12293 if (ssl->cbmode == WOLFSSL_CB_MODE_WRITE) {
12294 cbmode = SS_WRITE;
12295 }
12296 else if (ssl->cbmode == WOLFSSL_CB_MODE_READ) {
12297 cbmode = SS_READ;
12298 }
12299 else {
12300 cbmode = SS_NEITHER;
12301 }
12302
12303 /* Get protocol version */
12304 switch (ssl->version.major) {
12305 case SSLv3_MAJOR:
12306 switch (ssl->version.minor) {
12307 case SSLv3_MINOR:
12308 protocol = SSL_V3;
12309 break;
12310 case TLSv1_MINOR:
12311 protocol = TLS_V1;
12312 break;
12313 case TLSv1_1_MINOR:
12314 protocol = TLS_V1_1;
12315 break;
12316 case TLSv1_2_MINOR:
12317 protocol = TLS_V1_2;
12318 break;
12319 case TLSv1_3_MINOR:
12320 protocol = TLS_V1_3;
12321 break;
12322 default:
12323 protocol = UNKNOWN;
12324 }
12325 break;
12326 case DTLS_MAJOR:
12327 switch (ssl->version.minor) {
12328 case DTLS_MINOR:
12329 protocol = DTLS_V1;
12330 break;
12331 case DTLSv1_2_MINOR:
12332 protocol = DTLS_V1_2;
12333 break;
12334 case DTLSv1_3_MINOR:
12335 protocol = DTLS_V1_3;
12336 break;
12337 default:
12338 protocol = UNKNOWN;
12339 }
12340 break;
12341 default:
12342 protocol = UNKNOWN;
12343 }
12344
12345 /* accept process */
12346 if (ssl->cbmode == WOLFSSL_CB_MODE_READ) {
12347 state = ssl->cbtype;
12348 switch (state) {
12349 case hello_request:
12350 state = ss_server_hellorequest;
12351 break;
12352 case client_hello:
12353 state = ss_client_hello;
12354 break;
12355 case server_hello:
12356 state = ss_server_hello;
12357 break;
12358 case hello_verify_request:
12359 state = ss_server_helloverify;
12360 break;
12361 case session_ticket:
12362 state = ss_server_sessionticket;
12363 break;
12364 case end_of_early_data:
12365 state = ss_client_endofearlydata;
12366 break;
12367 case hello_retry_request:
12368 state = ss_server_helloretryrequest;
12369 break;
12370 case encrypted_extensions:
12371 state = ss_server_encryptedextensions;
12372 break;
12373 case certificate:
12374 if (ssl->options.side == WOLFSSL_SERVER_END)
12375 state = ss_client_cert;
12376 else if (ssl->options.side == WOLFSSL_CLIENT_END)
12377 state = ss_server_cert;
12378 else {
12379 WOLFSSL_MSG("Unknown State");
12380 state = ss_null_state;
12381 }
12382 break;
12383 case server_key_exchange:
12384 state = ss_server_keyexchange;
12385 break;
12386 case certificate_request:
12387 state = ss_server_certrequest;
12388 break;
12389 case server_hello_done:
12390 state = ss_server_hellodone;
12391 break;
12392 case certificate_verify:
12393 state = ss_client_certverify;
12394 break;
12395 case client_key_exchange:
12396 state = ss_client_keyexchange;
12397 break;
12398 case finished:
12399 if (ssl->options.side == WOLFSSL_SERVER_END)
12400 state = ss_client_finished;
12401 else if (ssl->options.side == WOLFSSL_CLIENT_END)
12402 state = ss_server_finished;
12403 else {
12404 WOLFSSL_MSG("Unknown State");
12405 state = ss_null_state;
12406 }
12407 break;
12408 case certificate_status:
12409 state = ss_server_certificatestatus;
12410 break;
12411 case key_update:
12412 if (ssl->options.side == WOLFSSL_SERVER_END)
12413 state = ss_client_keyupdate;
12414 else if (ssl->options.side == WOLFSSL_CLIENT_END)
12415 state = ss_server_keyupdate;
12416 else {
12417 WOLFSSL_MSG("Unknown State");
12418 state = ss_null_state;
12419 }
12420 break;
12421 case change_cipher_hs:
12422 if (ssl->options.side == WOLFSSL_SERVER_END)
12423 state = ss_client_changecipherspec;
12424 else if (ssl->options.side == WOLFSSL_CLIENT_END)
12425 state = ss_server_changecipherspec;
12426 else {
12427 WOLFSSL_MSG("Unknown State");
12428 state = ss_null_state;
12429 }
12430 break;
12431 default:
12432 WOLFSSL_MSG("Unknown State");
12433 state = ss_null_state;
12434 }
12435 }
12436 else {
12437 /* Send process */
12438 if (ssl->options.side == WOLFSSL_SERVER_END)
12439 state = ssl->options.serverState;
12440 else
12441 state = ssl->options.clientState;
12442
12443 switch (state) {
12444 case SERVER_HELLOVERIFYREQUEST_COMPLETE:
12445 state = ss_server_helloverify;
12446 break;
12447 case SERVER_HELLO_RETRY_REQUEST_COMPLETE:
12448 state = ss_server_helloretryrequest;
12449 break;
12450 case SERVER_HELLO_COMPLETE:
12451 state = ss_server_hello;
12452 break;
12453 case SERVER_ENCRYPTED_EXTENSIONS_COMPLETE:
12454 state = ss_server_encryptedextensions;
12455 break;
12456 case SERVER_CERT_COMPLETE:
12457 state = ss_server_cert;
12458 break;
12459 case SERVER_KEYEXCHANGE_COMPLETE:
12460 state = ss_server_keyexchange;
12461 break;
12462 case SERVER_HELLODONE_COMPLETE:
12463 state = ss_server_hellodone;
12464 break;
12465 case SERVER_CHANGECIPHERSPEC_COMPLETE:
12466 state = ss_server_changecipherspec;
12467 break;
12468 case SERVER_FINISHED_COMPLETE:
12469 state = ss_server_finished;
12470 break;
12471 case CLIENT_HELLO_RETRY:
12472 case CLIENT_HELLO_COMPLETE:
12473 state = ss_client_hello;
12474 break;
12475 case CLIENT_KEYEXCHANGE_COMPLETE:
12476 state = ss_client_keyexchange;
12477 break;
12478 case CLIENT_CHANGECIPHERSPEC_COMPLETE:
12479 state = ss_client_changecipherspec;
12480 break;
12481 case CLIENT_FINISHED_COMPLETE:
12482 state = ss_client_finished;
12483 break;
12484 case HANDSHAKE_DONE:
12485 state = ss_handshake_done;
12486 break;
12487 default:
12488 WOLFSSL_MSG("Unknown State");
12489 state = ss_null_state;
12490 }
12491 }
12492
12493 if (protocol == UNKNOWN) {
12494 WOLFSSL_MSG("Unknown protocol");
12495 return "";
12496 }
12497 else {
12498 return OUTPUT_STR[state][protocol][cbmode];
12499 }
12500}
12501
12502#endif /* OPENSSL_EXTRA */
12503
12504static long wolf_set_options(long old_op, long op)
12505{
12506 /* if SSL_OP_ALL then turn all bug workarounds on */
12507 if ((op & WOLFSSL_OP_ALL) == WOLFSSL_OP_ALL) {
12508 WOLFSSL_MSG("\tSSL_OP_ALL");
12509 }
12510
12511 /* by default cookie exchange is on with DTLS */
12512 if ((op & WOLFSSL_OP_COOKIE_EXCHANGE) == WOLFSSL_OP_COOKIE_EXCHANGE) {
12513 WOLFSSL_MSG("\tSSL_OP_COOKIE_EXCHANGE : on by default");
12514 }
12515
12516 if ((op & WOLFSSL_OP_NO_SSLv2) == WOLFSSL_OP_NO_SSLv2) {
12517 WOLFSSL_MSG("\tWOLFSSL_OP_NO_SSLv2 : wolfSSL does not support SSLv2");
12518 }
12519
12520#ifdef SSL_OP_NO_TLSv1_3
12521 if ((op & WOLFSSL_OP_NO_TLSv1_3) == WOLFSSL_OP_NO_TLSv1_3) {
12522 WOLFSSL_MSG("\tSSL_OP_NO_TLSv1_3");
12523 }
12524#endif
12525
12526 if ((op & WOLFSSL_OP_NO_TLSv1_2) == WOLFSSL_OP_NO_TLSv1_2) {
12527 WOLFSSL_MSG("\tSSL_OP_NO_TLSv1_2");
12528 }
12529
12530 if ((op & WOLFSSL_OP_NO_TLSv1_1) == WOLFSSL_OP_NO_TLSv1_1) {
12531 WOLFSSL_MSG("\tSSL_OP_NO_TLSv1_1");
12532 }
12533
12534 if ((op & WOLFSSL_OP_NO_TLSv1) == WOLFSSL_OP_NO_TLSv1) {
12535 WOLFSSL_MSG("\tSSL_OP_NO_TLSv1");
12536 }
12537
12538 if ((op & WOLFSSL_OP_NO_SSLv3) == WOLFSSL_OP_NO_SSLv3) {
12539 WOLFSSL_MSG("\tSSL_OP_NO_SSLv3");
12540 }
12541
12542 if ((op & WOLFSSL_OP_CIPHER_SERVER_PREFERENCE) ==
12543 WOLFSSL_OP_CIPHER_SERVER_PREFERENCE) {
12544 WOLFSSL_MSG("\tWOLFSSL_OP_CIPHER_SERVER_PREFERENCE");
12545 }
12546
12547 if ((op & WOLFSSL_OP_NO_COMPRESSION) == WOLFSSL_OP_NO_COMPRESSION) {
12548 #ifdef HAVE_LIBZ
12549 WOLFSSL_MSG("SSL_OP_NO_COMPRESSION");
12550 #else
12551 WOLFSSL_MSG("SSL_OP_NO_COMPRESSION: compression not compiled in");
12552 #endif
12553 }
12554
12555 return old_op | op;
12556}
12557
12558static int FindHashSig(const Suites* suites, byte first, byte second)
12559{
12560 word16 i;
12561
12562 if (suites == NULL || suites->hashSigAlgoSz == 0) {
12563 WOLFSSL_MSG("Suites pointer error or suiteSz 0");
12564 return SUITES_ERROR;
12565 }
12566
12567 for (i = 0; i < suites->hashSigAlgoSz-1; i += 2) {
12568 if (suites->hashSigAlgo[i] == first &&
12569 suites->hashSigAlgo[i+1] == second )
12570 return i;
12571 }
12572
12573 return MATCH_SUITE_ERROR;
12574}
12575
12576long wolfSSL_set_options(WOLFSSL* ssl, long op)
12577{
12578 word16 haveRSA = 1;
12579 word16 havePSK = 0;
12580 int keySz = 0;
12581
12582 WOLFSSL_ENTER("wolfSSL_set_options");
12583
12584 if (ssl == NULL) {
12585 return 0;
12586 }
12587
12588 ssl->options.mask = (unsigned long)wolf_set_options((long)ssl->options.mask, op);
12589
12590 if ((ssl->options.mask & WOLFSSL_OP_NO_TLSv1_3) == WOLFSSL_OP_NO_TLSv1_3) {
12591 WOLFSSL_MSG("Disabling TLS 1.3");
12592 if (ssl->version.minor == TLSv1_3_MINOR)
12593 ssl->version.minor = TLSv1_2_MINOR;
12594 }
12595
12596 if ((ssl->options.mask & WOLFSSL_OP_NO_TLSv1_2) == WOLFSSL_OP_NO_TLSv1_2) {
12597 WOLFSSL_MSG("Disabling TLS 1.2");
12598 if (ssl->version.minor == TLSv1_2_MINOR)
12599 ssl->version.minor = TLSv1_1_MINOR;
12600 }
12601
12602 if ((ssl->options.mask & WOLFSSL_OP_NO_TLSv1_1) == WOLFSSL_OP_NO_TLSv1_1) {
12603 WOLFSSL_MSG("Disabling TLS 1.1");
12604 if (ssl->version.minor == TLSv1_1_MINOR)
12605 ssl->version.minor = TLSv1_MINOR;
12606 }
12607
12608 if ((ssl->options.mask & WOLFSSL_OP_NO_TLSv1) == WOLFSSL_OP_NO_TLSv1) {
12609 WOLFSSL_MSG("Disabling TLS 1.0");
12610 if (ssl->version.minor == TLSv1_MINOR)
12611 ssl->version.minor = SSLv3_MINOR;
12612 }
12613
12614 if ((ssl->options.mask & WOLFSSL_OP_NO_COMPRESSION)
12615 == WOLFSSL_OP_NO_COMPRESSION) {
12616 #ifdef HAVE_LIBZ
12617 ssl->options.usingCompression = 0;
12618 #endif
12619 }
12620
12621#if defined(HAVE_SESSION_TICKET) && (defined(OPENSSL_EXTRA) \
12622 || defined(HAVE_WEBSERVER) || defined(WOLFSSL_WPAS_SMALL))
12623 if ((ssl->options.mask & WOLFSSL_OP_NO_TICKET) == WOLFSSL_OP_NO_TICKET) {
12624 ssl->options.noTicketTls12 = 1;
12625 }
12626#endif
12627
12628
12629 /* in the case of a version change the cipher suites should be reset */
12630#ifndef NO_PSK
12631 havePSK = ssl->options.havePSK;
12632#endif
12633#ifdef NO_RSA
12634 haveRSA = 0;
12635#endif
12636#ifndef NO_CERTS
12637 keySz = ssl->buffers.keySz;
12638#endif
12639
12640 if (ssl->options.side != WOLFSSL_NEITHER_END) {
12641 if (AllocateSuites(ssl) != 0)
12642 return 0;
12643 if (!ssl->suites->setSuites) {
12644 /* Client side won't set DH params, so it needs haveDH set to TRUE. */
12645 if (ssl->options.side == WOLFSSL_CLIENT_END)
12646 InitSuites(ssl->suites, ssl->version, keySz, haveRSA,
12647 havePSK, TRUE, ssl->options.haveECDSAsig,
12648 ssl->options.haveECC, TRUE, ssl->options.haveStaticECC,
12649 ssl->options.useAnon,
12650 TRUE, TRUE, TRUE, TRUE, ssl->options.side);
12651 else
12652 InitSuites(ssl->suites, ssl->version, keySz, haveRSA,
12653 havePSK, ssl->options.haveDH, ssl->options.haveECDSAsig,
12654 ssl->options.haveECC, TRUE, ssl->options.haveStaticECC,
12655 ssl->options.useAnon,
12656 TRUE, TRUE, TRUE, TRUE, ssl->options.side);
12657 }
12658 else {
12659 /* Only preserve overlapping suites */
12660 Suites tmpSuites;
12661 word16 in, out;
12662 word16 haveECDSAsig, haveStaticECC;
12663#ifdef NO_RSA
12664 haveECDSAsig = 1;
12665 haveStaticECC = 1;
12666#else
12667 haveECDSAsig = 0;
12668 haveStaticECC = ssl->options.haveStaticECC;
12669#endif
12670 XMEMSET(&tmpSuites, 0, sizeof(Suites));
12671 /* Get all possible ciphers and sigalgs for the version. Following
12672 * options limit the allowed ciphers so let's try to get as many as
12673 * possible.
12674 * - haveStaticECC turns off haveRSA
12675 * - haveECDSAsig turns off haveRSAsig */
12676 InitSuites(&tmpSuites, ssl->version, 0, 1, 1, 1, haveECDSAsig, 1, 1,
12677 haveStaticECC, 1, 1, 1, 1, 1, ssl->options.side);
12678 for (in = 0, out = 0; in < ssl->suites->suiteSz; in += SUITE_LEN) {
12679 if (FindSuite(&tmpSuites, ssl->suites->suites[in],
12680 ssl->suites->suites[in+1]) >= 0) {
12681 ssl->suites->suites[out] = ssl->suites->suites[in];
12682 ssl->suites->suites[out+1] = ssl->suites->suites[in+1];
12683 out += SUITE_LEN;
12684 }
12685 }
12686 ssl->suites->suiteSz = out;
12687 for (in = 0, out = 0; in < ssl->suites->hashSigAlgoSz; in += 2) {
12688 if (FindHashSig(&tmpSuites, ssl->suites->hashSigAlgo[in],
12689 ssl->suites->hashSigAlgo[in+1]) >= 0) {
12690 ssl->suites->hashSigAlgo[out] =
12691 ssl->suites->hashSigAlgo[in];
12692 ssl->suites->hashSigAlgo[out+1] =
12693 ssl->suites->hashSigAlgo[in+1];
12694 out += 2;
12695 }
12696 }
12697 ssl->suites->hashSigAlgoSz = out;
12698 }
12699 }
12700
12701 return (long)ssl->options.mask;
12702}
12703
12704
12705long wolfSSL_get_options(const WOLFSSL* ssl)
12706{
12707 WOLFSSL_ENTER("wolfSSL_get_options");
12708 if(ssl == NULL)
12709 return WOLFSSL_FAILURE;
12710 return (long)ssl->options.mask;
12711}
12712
12713#if defined(HAVE_SECURE_RENEGOTIATION) \
12714 || defined(HAVE_SERVER_RENEGOTIATION_INFO)
12715/* clears the counter for number of renegotiations done
12716 * returns the current count before it is cleared */
12717long wolfSSL_clear_num_renegotiations(WOLFSSL *s)
12718{
12719 long total;
12720
12721 WOLFSSL_ENTER("wolfSSL_clear_num_renegotiations");
12722 if (s == NULL)
12723 return 0;
12724
12725 total = s->secure_rene_count;
12726 s->secure_rene_count = 0;
12727 return total;
12728}
12729
12730
12731/* return the number of renegotiations since wolfSSL_new */
12732long wolfSSL_total_renegotiations(WOLFSSL *s)
12733{
12734 WOLFSSL_ENTER("wolfSSL_total_renegotiations");
12735 return wolfSSL_num_renegotiations(s);
12736}
12737
12738
12739/* return the number of renegotiations since wolfSSL_new */
12740long wolfSSL_num_renegotiations(WOLFSSL* s)
12741{
12742 if (s == NULL) {
12743 return 0;
12744 }
12745
12746 return s->secure_rene_count;
12747}
12748
12749
12750/* Is there a renegotiation currently in progress? */
12751int wolfSSL_SSL_renegotiate_pending(WOLFSSL *s)
12752{
12753 return s && s->options.handShakeDone &&
12754 s->options.handShakeState != HANDSHAKE_DONE ? 1 : 0;
12755}
12756#endif /* HAVE_SECURE_RENEGOTIATION || HAVE_SERVER_RENEGOTIATION_INFO */
12757
12758#ifdef OPENSSL_EXTRA
12759
12760long wolfSSL_clear_options(WOLFSSL* ssl, long opt)
12761{
12762 WOLFSSL_ENTER("wolfSSL_clear_options");
12763 if(ssl == NULL)
12764 return WOLFSSL_FAILURE;
12765 ssl->options.mask &= (unsigned long)~opt;
12766 return (long)ssl->options.mask;
12767}
12768
12769#ifdef HAVE_PK_CALLBACKS
12770long wolfSSL_set_tlsext_debug_arg(WOLFSSL* ssl, void *arg)
12771{
12772 if (ssl == NULL) {
12773 return WOLFSSL_FAILURE;
12774 }
12775
12776 ssl->loggingCtx = arg;
12777 return WOLFSSL_SUCCESS;
12778}
12779#endif /* HAVE_PK_CALLBACKS */
12780
12781#ifndef NO_WOLFSSL_STUB
12782long wolfSSL_get_tlsext_status_exts(WOLFSSL *s, void *arg)
12783{
12784 (void)s;
12785 (void)arg;
12786 WOLFSSL_STUB("wolfSSL_get_tlsext_status_exts");
12787 return WOLFSSL_FAILURE;
12788}
12789#endif
12790
12791/*** TBD ***/
12792#ifndef NO_WOLFSSL_STUB
12793long wolfSSL_set_tlsext_status_exts(WOLFSSL *s, void *arg)
12794{
12795 (void)s;
12796 (void)arg;
12797 WOLFSSL_STUB("wolfSSL_set_tlsext_status_exts");
12798 return WOLFSSL_FAILURE;
12799}
12800#endif
12801
12802/*** TBD ***/
12803#ifndef NO_WOLFSSL_STUB
12804long wolfSSL_get_tlsext_status_ids(WOLFSSL *s, void *arg)
12805{
12806 (void)s;
12807 (void)arg;
12808 WOLFSSL_STUB("wolfSSL_get_tlsext_status_ids");
12809 return WOLFSSL_FAILURE;
12810}
12811#endif
12812
12813/*** TBD ***/
12814#ifndef NO_WOLFSSL_STUB
12815long wolfSSL_set_tlsext_status_ids(WOLFSSL *s, void *arg)
12816{
12817 (void)s;
12818 (void)arg;
12819 WOLFSSL_STUB("wolfSSL_set_tlsext_status_ids");
12820 return WOLFSSL_FAILURE;
12821}
12822#endif
12823
12824#ifndef NO_WOLFSSL_STUB
12825/*** TBD ***/
12826WOLFSSL_EVP_PKEY *wolfSSL_get_privatekey(const WOLFSSL *ssl)
12827{
12828 (void)ssl;
12829 WOLFSSL_STUB("SSL_get_privatekey");
12830 return NULL;
12831}
12832#endif
12833
12834#ifndef NO_WOLFSSL_STUB
12835/*** TBD ***/
12836void WOLFSSL_CTX_set_tmp_dh_callback(WOLFSSL_CTX *ctx,
12837 WOLFSSL_DH *(*dh) (WOLFSSL *ssl, int is_export, int keylength))
12838{
12839 (void)ctx;
12840 (void)dh;
12841 WOLFSSL_STUB("WOLFSSL_CTX_set_tmp_dh_callback");
12842}
12843#endif
12844
12845#ifndef NO_WOLFSSL_STUB
12846/*** TBD ***/
12847WOLF_STACK_OF(WOLFSSL_COMP) *WOLFSSL_COMP_get_compression_methods(void)
12848{
12849 WOLFSSL_STUB("WOLFSSL_COMP_get_compression_methods");
12850 return NULL;
12851}
12852#endif
12853
12854
12855#if !defined(NETOS)
12856void wolfSSL_ERR_load_SSL_strings(void)
12857{
12858
12859}
12860#endif
12861
12862#ifdef HAVE_MAX_FRAGMENT
12863#if !defined(NO_WOLFSSL_CLIENT) && !defined(NO_TLS)
12864/**
12865 * Set max fragment tls extension
12866 * @param c a pointer to WOLFSSL_CTX object
12867 * @param mode maximum fragment length mode
12868 * @return 1 on success, otherwise 0 or negative error code
12869 */
12870int wolfSSL_CTX_set_tlsext_max_fragment_length(WOLFSSL_CTX *c,
12871 unsigned char mode)
12872{
12873 if (c == NULL || (mode < WOLFSSL_MFL_2_9 || mode > WOLFSSL_MFL_2_12 ))
12874 return BAD_FUNC_ARG;
12875
12876 return wolfSSL_CTX_UseMaxFragment(c, mode);
12877}
12878/**
12879 * Set max fragment tls extension
12880 * @param c a pointer to WOLFSSL object
12881 * @param mode maximum fragment length mode
12882 * @return 1 on success, otherwise 0 or negative error code
12883 */
12884int wolfSSL_set_tlsext_max_fragment_length(WOLFSSL *s, unsigned char mode)
12885{
12886 if (s == NULL || (mode < WOLFSSL_MFL_2_9 || mode > WOLFSSL_MFL_2_12 ))
12887 return BAD_FUNC_ARG;
12888
12889 return wolfSSL_UseMaxFragment(s, mode);
12890}
12891#endif /* !NO_WOLFSSL_CLIENT && !NO_TLS */
12892#endif /* HAVE_MAX_FRAGMENT */
12893
12894#endif /* OPENSSL_EXTRA */
12895
12896#ifdef WOLFSSL_HAVE_TLS_UNIQUE
12897size_t wolfSSL_get_finished(const WOLFSSL *ssl, void *buf, size_t count)
12898{
12899 byte len = 0;
12900
12901 WOLFSSL_ENTER("wolfSSL_get_finished");
12902
12903 if (!ssl || !buf || count < TLS_FINISHED_SZ) {
12904 WOLFSSL_MSG("Bad parameter");
12905 return WOLFSSL_FAILURE;
12906 }
12907
12908 if (ssl->options.side == WOLFSSL_SERVER_END) {
12909 len = ssl->serverFinished_len;
12910 XMEMCPY(buf, ssl->serverFinished, len);
12911 }
12912 else {
12913 len = ssl->clientFinished_len;
12914 XMEMCPY(buf, ssl->clientFinished, len);
12915 }
12916 return len;
12917}
12918
12919size_t wolfSSL_get_peer_finished(const WOLFSSL *ssl, void *buf, size_t count)
12920{
12921 byte len = 0;
12922 WOLFSSL_ENTER("wolfSSL_get_peer_finished");
12923
12924 if (!ssl || !buf || count < TLS_FINISHED_SZ) {
12925 WOLFSSL_MSG("Bad parameter");
12926 return WOLFSSL_FAILURE;
12927 }
12928
12929 if (ssl->options.side == WOLFSSL_CLIENT_END) {
12930 len = ssl->serverFinished_len;
12931 XMEMCPY(buf, ssl->serverFinished, len);
12932 }
12933 else {
12934 len = ssl->clientFinished_len;
12935 XMEMCPY(buf, ssl->clientFinished, len);
12936 }
12937
12938 return len;
12939}
12940#endif /* WOLFSSL_HAVE_TLS_UNIQUE */
12941
12942#if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL) || \
12943 defined(OPENSSL_ALL)
12944long wolfSSL_get_verify_result(const WOLFSSL *ssl)
12945{
12946 if (ssl == NULL) {
12947 return WOLFSSL_FAILURE;
12948 }
12949
12950 return (long)ssl->peerVerifyRet;
12951}
12952#endif
12953
12954#ifdef OPENSSL_EXTRA
12955
12956#ifndef NO_WOLFSSL_STUB
12957/* shows the number of accepts attempted by CTX in it's lifetime */
12958long wolfSSL_CTX_sess_accept(WOLFSSL_CTX* ctx)
12959{
12960 WOLFSSL_STUB("wolfSSL_CTX_sess_accept");
12961 (void)ctx;
12962 return 0;
12963}
12964#endif
12965
12966#ifndef NO_WOLFSSL_STUB
12967/* shows the number of connects attempted CTX in it's lifetime */
12968long wolfSSL_CTX_sess_connect(WOLFSSL_CTX* ctx)
12969{
12970 WOLFSSL_STUB("wolfSSL_CTX_sess_connect");
12971 (void)ctx;
12972 return 0;
12973}
12974#endif
12975
12976
12977#ifndef NO_WOLFSSL_STUB
12978/* shows the number of accepts completed by CTX in it's lifetime */
12979long wolfSSL_CTX_sess_accept_good(WOLFSSL_CTX* ctx)
12980{
12981 WOLFSSL_STUB("wolfSSL_CTX_sess_accept_good");
12982 (void)ctx;
12983 return 0;
12984}
12985#endif
12986
12987
12988#ifndef NO_WOLFSSL_STUB
12989/* shows the number of connects completed by CTX in it's lifetime */
12990long wolfSSL_CTX_sess_connect_good(WOLFSSL_CTX* ctx)
12991{
12992 WOLFSSL_STUB("wolfSSL_CTX_sess_connect_good");
12993 (void)ctx;
12994 return 0;
12995}
12996#endif
12997
12998
12999#ifndef NO_WOLFSSL_STUB
13000/* shows the number of renegotiation accepts attempted by CTX */
13001long wolfSSL_CTX_sess_accept_renegotiate(WOLFSSL_CTX* ctx)
13002{
13003 WOLFSSL_STUB("wolfSSL_CTX_sess_accept_renegotiate");
13004 (void)ctx;
13005 return 0;
13006}
13007#endif
13008
13009
13010#ifndef NO_WOLFSSL_STUB
13011/* shows the number of renegotiation accepts attempted by CTX */
13012long wolfSSL_CTX_sess_connect_renegotiate(WOLFSSL_CTX* ctx)
13013{
13014 WOLFSSL_STUB("wolfSSL_CTX_sess_connect_renegotiate");
13015 (void)ctx;
13016 return 0;
13017}
13018#endif
13019
13020
13021#ifndef NO_WOLFSSL_STUB
13022long wolfSSL_CTX_sess_hits(WOLFSSL_CTX* ctx)
13023{
13024 WOLFSSL_STUB("wolfSSL_CTX_sess_hits");
13025 (void)ctx;
13026 return 0;
13027}
13028#endif
13029
13030
13031#ifndef NO_WOLFSSL_STUB
13032long wolfSSL_CTX_sess_cb_hits(WOLFSSL_CTX* ctx)
13033{
13034 WOLFSSL_STUB("wolfSSL_CTX_sess_cb_hits");
13035 (void)ctx;
13036 return 0;
13037}
13038#endif
13039
13040
13041#ifndef NO_WOLFSSL_STUB
13042long wolfSSL_CTX_sess_cache_full(WOLFSSL_CTX* ctx)
13043{
13044 WOLFSSL_STUB("wolfSSL_CTX_sess_cache_full");
13045 (void)ctx;
13046 return 0;
13047}
13048#endif
13049
13050
13051#ifndef NO_WOLFSSL_STUB
13052long wolfSSL_CTX_sess_misses(WOLFSSL_CTX* ctx)
13053{
13054 WOLFSSL_STUB("wolfSSL_CTX_sess_misses");
13055 (void)ctx;
13056 return 0;
13057}
13058#endif
13059
13060
13061#ifndef NO_WOLFSSL_STUB
13062long wolfSSL_CTX_sess_timeouts(WOLFSSL_CTX* ctx)
13063{
13064 WOLFSSL_STUB("wolfSSL_CTX_sess_timeouts");
13065 (void)ctx;
13066 return 0;
13067}
13068#endif
13069
13070int wolfSSL_get_read_ahead(const WOLFSSL* ssl)
13071{
13072 if (ssl == NULL) {
13073 return WOLFSSL_FAILURE;
13074 }
13075
13076 return ssl->readAhead;
13077}
13078
13079
13080int wolfSSL_set_read_ahead(WOLFSSL* ssl, int v)
13081{
13082 if (ssl == NULL) {
13083 return WOLFSSL_FAILURE;
13084 }
13085
13086 ssl->readAhead = (byte)v;
13087
13088 return WOLFSSL_SUCCESS;
13089}
13090
13091
13092int wolfSSL_CTX_get_read_ahead(WOLFSSL_CTX* ctx)
13093{
13094 if (ctx == NULL) {
13095 return WOLFSSL_FAILURE;
13096 }
13097
13098 return ctx->readAhead;
13099}
13100
13101
13102int wolfSSL_CTX_set_read_ahead(WOLFSSL_CTX* ctx, int v)
13103{
13104 if (ctx == NULL) {
13105 return WOLFSSL_FAILURE;
13106 }
13107
13108 ctx->readAhead = (byte)v;
13109
13110 return WOLFSSL_SUCCESS;
13111}
13112
13113
13114long wolfSSL_CTX_set_tlsext_opaque_prf_input_callback_arg(WOLFSSL_CTX* ctx,
13115 void* arg)
13116{
13117 if (ctx == NULL) {
13118 return WOLFSSL_FAILURE;
13119 }
13120
13121 ctx->userPRFArg = arg;
13122 return WOLFSSL_SUCCESS;
13123}
13124
13125#endif /* OPENSSL_EXTRA */
13126
13127#if defined(OPENSSL_EXTRA) && defined(KEEP_PEER_CERT) && \
13128 defined(HAVE_EX_DATA) && !defined(NO_FILESYSTEM)
13129int wolfSSL_cmp_peer_cert_to_file(WOLFSSL* ssl, const char *fname)
13130{
13131 int ret = WC_NO_ERR_TRACE(WOLFSSL_FATAL_ERROR);
13132
13133 WOLFSSL_ENTER("wolfSSL_cmp_peer_cert_to_file");
13134 if (ssl != NULL && fname != NULL)
13135 {
13136 #ifdef WOLFSSL_SMALL_STACK
13137 byte staticBuffer[1]; /* force heap usage */
13138 #else
13139 byte staticBuffer[FILE_BUFFER_SIZE];
13140 #endif
13141 byte* myBuffer = staticBuffer;
13142 int dynamic = 0;
13143 XFILE file;
13144 long sz = 0;
13145 WOLFSSL_CTX* ctx = ssl->ctx;
13146 WOLFSSL_X509* peer_cert = &ssl->peerCert;
13147 DerBuffer* fileDer = NULL;
13148
13149 file = XFOPEN(fname, "rb");
13150 if (file == XBADFILE)
13151 return WOLFSSL_BAD_FILE;
13152
13153 if (XFSEEK(file, 0, XSEEK_END) != 0) {
13154 XFCLOSE(file);
13155 return WOLFSSL_BAD_FILE;
13156 }
13157 sz = XFTELL(file);
13158 if (XFSEEK(file, 0, XSEEK_SET) != 0) {
13159 XFCLOSE(file);
13160 return WOLFSSL_BAD_FILE;
13161 }
13162
13163 if (sz > MAX_WOLFSSL_FILE_SIZE || sz < 0) {
13164 WOLFSSL_MSG("cmp_peer_cert_to_file size error");
13165 XFCLOSE(file);
13166 return WOLFSSL_BAD_FILE;
13167 }
13168
13169 if (sz > (long)sizeof(staticBuffer)) {
13170 WOLFSSL_MSG("Getting dynamic buffer");
13171 myBuffer = (byte*)XMALLOC((size_t)sz, ctx->heap, DYNAMIC_TYPE_FILE);
13172 dynamic = 1;
13173 }
13174
13175 if ((myBuffer != NULL) &&
13176 (sz > 0) &&
13177 (XFREAD(myBuffer, 1, (size_t)sz, file) == (size_t)sz) &&
13178 (PemToDer(myBuffer, (long)sz, CERT_TYPE,
13179 &fileDer, ctx->heap, NULL, NULL) == 0) &&
13180 (fileDer->length != 0) &&
13181 (fileDer->length == peer_cert->derCert->length) &&
13182 (XMEMCMP(peer_cert->derCert->buffer, fileDer->buffer,
13183 fileDer->length) == 0))
13184 {
13185 ret = 0;
13186 }
13187
13188 FreeDer(&fileDer);
13189
13190 if (dynamic)
13191 XFREE(myBuffer, ctx->heap, DYNAMIC_TYPE_FILE);
13192
13193 XFCLOSE(file);
13194 }
13195
13196 return ret;
13197}
13198#endif
13199
13200#if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)
13201const WOLFSSL_ObjectInfo wolfssl_object_info[] = {
13202#ifndef NO_CERTS
13203 /* oidCertExtType */
13204 { WC_NID_basic_constraints, BASIC_CA_OID, oidCertExtType,
13205 "basicConstraints", "X509v3 Basic Constraints"},
13206 { WC_NID_subject_alt_name, ALT_NAMES_OID, oidCertExtType, "subjectAltName",
13207 "X509v3 Subject Alternative Name"},
13208 { WC_NID_crl_distribution_points, CRL_DIST_OID, oidCertExtType,
13209 "crlDistributionPoints", "X509v3 CRL Distribution Points"},
13210 { WC_NID_info_access, AUTH_INFO_OID, oidCertExtType, "authorityInfoAccess",
13211 "Authority Information Access"},
13212 { WC_NID_authority_key_identifier, AUTH_KEY_OID, oidCertExtType,
13213 "authorityKeyIdentifier", "X509v3 Authority Key Identifier"},
13214 { WC_NID_subject_key_identifier, SUBJ_KEY_OID, oidCertExtType,
13215 "subjectKeyIdentifier", "X509v3 Subject Key Identifier"},
13216 { WC_NID_key_usage, KEY_USAGE_OID, oidCertExtType, "keyUsage",
13217 "X509v3 Key Usage"},
13218 { WC_NID_inhibit_any_policy, INHIBIT_ANY_OID, oidCertExtType,
13219 "inhibitAnyPolicy", "X509v3 Inhibit Any Policy"},
13220 { WC_NID_ext_key_usage, EXT_KEY_USAGE_OID, oidCertExtType,
13221 "extendedKeyUsage", "X509v3 Extended Key Usage"},
13222 { WC_NID_name_constraints, NAME_CONS_OID, oidCertExtType,
13223 "nameConstraints", "X509v3 Name Constraints"},
13224 { WC_NID_certificate_policies, CERT_POLICY_OID, oidCertExtType,
13225 "certificatePolicies", "X509v3 Certificate Policies"},
13226
13227 /* oidCertAuthInfoType */
13228 { WC_NID_ad_OCSP, AIA_OCSP_OID, oidCertAuthInfoType, "OCSP",
13229 "OCSP"},
13230 { WC_NID_ad_ca_issuers, AIA_CA_ISSUER_OID, oidCertAuthInfoType,
13231 "caIssuers", "CA Issuers"},
13232
13233 /* oidCertPolicyType */
13234 { WC_NID_any_policy, CP_ANY_OID, oidCertPolicyType, "anyPolicy",
13235 "X509v3 Any Policy"},
13236
13237 /* oidCertAltNameType */
13238 { WC_NID_hw_name_oid, HW_NAME_OID, oidCertAltNameType, "Hardware name",""},
13239
13240 /* oidCertKeyUseType */
13241 { WC_NID_anyExtendedKeyUsage, EKU_ANY_OID, oidCertKeyUseType,
13242 "anyExtendedKeyUsage", "Any Extended Key Usage"},
13243 { EKU_SERVER_AUTH_OID, EKU_SERVER_AUTH_OID, oidCertKeyUseType,
13244 "serverAuth", "TLS Web Server Authentication"},
13245 { EKU_CLIENT_AUTH_OID, EKU_CLIENT_AUTH_OID, oidCertKeyUseType,
13246 "clientAuth", "TLS Web Client Authentication"},
13247 { EKU_OCSP_SIGN_OID, EKU_OCSP_SIGN_OID, oidCertKeyUseType,
13248 "OCSPSigning", "OCSP Signing"},
13249
13250 /* oidCertNameType */
13251 { WC_NID_commonName, WC_NAME_COMMON_NAME_OID, oidCertNameType,
13252 "CN", "commonName"},
13253#if !defined(WOLFSSL_CERT_REQ)
13254 { WC_NID_surname, WC_NAME_SURNAME_OID, oidCertNameType, "SN", "surname"},
13255#endif
13256 { WC_NID_serialNumber, WC_NAME_SERIAL_NUMBER_OID, oidCertNameType,
13257 "serialNumber", "serialNumber"},
13258 { WC_NID_userId, WC_NID_userId, oidCertNameType, "UID", "userid"},
13259 { WC_NID_countryName, WC_NAME_COUNTRY_NAME_OID, oidCertNameType,
13260 "C", "countryName"},
13261 { WC_NID_localityName, WC_NAME_LOCALITY_NAME_OID, oidCertNameType,
13262 "L", "localityName"},
13263 { WC_NID_stateOrProvinceName, WC_NAME_STATE_NAME_OID, oidCertNameType,
13264 "ST", "stateOrProvinceName"},
13265 { WC_NID_streetAddress, WC_NAME_STREET_ADDRESS_OID, oidCertNameType,
13266 "street", "streetAddress"},
13267 { WC_NID_organizationName, WC_NAME_ORGANIZATION_NAME_OID, oidCertNameType,
13268 "O", "organizationName"},
13269 { WC_NID_organizationalUnitName, WC_NAME_ORGANIZATION_UNIT_NAME_OID,
13270 oidCertNameType, "OU", "organizationalUnitName"},
13271 { WC_NID_title, WC_NAME_TITLE_OID, oidCertNameType, "title", "title"},
13272 { WC_NID_description, WC_NAME_DESCRIPTION_OID, oidCertNameType,
13273 "description", "description"},
13274 { WC_NID_emailAddress, WC_NAME_EMAIL_ADDRESS_OID, oidCertNameType,
13275 "emailAddress", "emailAddress"},
13276 { WC_NID_domainComponent, WC_NAME_DOMAIN_COMPONENT_OID, oidCertNameType,
13277 "DC", "domainComponent"},
13278 { WC_NID_rfc822Mailbox, WC_NAME_RFC822_MAILBOX_OID, oidCertNameType,
13279 "rfc822Mailbox", "rfc822Mailbox"},
13280 { WC_NID_favouriteDrink, WC_NAME_FAVOURITE_DRINK_OID, oidCertNameType,
13281 "favouriteDrink", "favouriteDrink"},
13282 { WC_NID_businessCategory, WC_NAME_BUSINESS_CATEGORY_OID, oidCertNameType,
13283 "businessCategory", "businessCategory"},
13284 { WC_NID_jurisdictionCountryName, WC_NAME_JURIS_COUNTRY_OID,
13285 oidCertNameType, "jurisdictionC", "jurisdictionCountryName"},
13286 { WC_NID_jurisdictionStateOrProvinceName, WC_NAME_JURIS_STATE_PROV_OID,
13287 oidCertNameType, "jurisdictionST", "jurisdictionStateOrProvinceName"},
13288 { WC_NID_postalCode, WC_NAME_POSTAL_CODE_OID, oidCertNameType, "postalCode",
13289 "postalCode"},
13290 { WC_NID_userId, WC_NAME_USER_ID_OID, oidCertNameType, "UID", "userId"},
13291 { WC_NID_netscape_cert_type, NETSCAPE_CT_OID, oidCertNameType,
13292 "nsCertType", "Netscape Cert Type"},
13293
13294#if defined(WOLFSSL_CERT_REQ) || defined(WOLFSSL_CERT_NAME_ALL)
13295 { WC_NID_pkcs9_challengePassword, CHALLENGE_PASSWORD_OID,
13296 oidCsrAttrType, "challengePassword", "challengePassword"},
13297 { WC_NID_pkcs9_contentType, PKCS9_CONTENT_TYPE_OID,
13298 oidCsrAttrType, "contentType", "contentType" },
13299 { WC_NID_pkcs9_unstructuredName, UNSTRUCTURED_NAME_OID,
13300 oidCsrAttrType, "unstructuredName", "unstructuredName" },
13301 { WC_NID_name, WC_NAME_NAME_OID, oidCsrAttrType, "name", "name" },
13302 { WC_NID_surname, SURNAME_OID,
13303 oidCsrAttrType, "surname", "surname" },
13304 { WC_NID_givenName, WC_NAME_GIVEN_NAME_OID,
13305 oidCsrAttrType, "givenName", "givenName" },
13306 { WC_NID_initials, WC_NAME_INITIALIS_OID,
13307 oidCsrAttrType, "initials", "initials" },
13308 { WC_NID_dnQualifier, DNQUALIFIER_OID,
13309 oidCsrAttrType, "dnQualifer", "dnQualifier" },
13310#endif
13311#endif
13312#ifdef OPENSSL_EXTRA /* OPENSSL_EXTRA_X509_SMALL only needs the above */
13313 /* oidHashType */
13314 #ifdef WOLFSSL_MD2
13315 { WC_NID_md2, MD2h, oidHashType, "MD2", "md2"},
13316 #endif
13317 #ifndef NO_MD4
13318 { WC_NID_md4, MD4h, oidHashType, "MD4", "md4"},
13319 #endif
13320 #ifndef NO_MD5
13321 { WC_NID_md5, MD5h, oidHashType, "MD5", "md5"},
13322 #endif
13323 #ifndef NO_SHA
13324 { WC_NID_sha1, SHAh, oidHashType, "SHA1", "sha1"},
13325 #endif
13326 #ifdef WOLFSSL_SHA224
13327 { WC_NID_sha224, SHA224h, oidHashType, "SHA224", "sha224"},
13328 #endif
13329 #ifndef NO_SHA256
13330 { WC_NID_sha256, SHA256h, oidHashType, "SHA256", "sha256"},
13331 #endif
13332 #ifdef WOLFSSL_SHA384
13333 { WC_NID_sha384, SHA384h, oidHashType, "SHA384", "sha384"},
13334 #endif
13335 #ifdef WOLFSSL_SHA512
13336 { WC_NID_sha512, SHA512h, oidHashType, "SHA512", "sha512"},
13337 #endif
13338 #ifdef WOLFSSL_SHA3
13339 #ifndef WOLFSSL_NOSHA3_224
13340 { WC_NID_sha3_224, SHA3_224h, oidHashType, "SHA3-224", "sha3-224"},
13341 #endif
13342 #ifndef WOLFSSL_NOSHA3_256
13343 { WC_NID_sha3_256, SHA3_256h, oidHashType, "SHA3-256", "sha3-256"},
13344 #endif
13345 #ifndef WOLFSSL_NOSHA3_384
13346 { WC_NID_sha3_384, SHA3_384h, oidHashType, "SHA3-384", "sha3-384"},
13347 #endif
13348 #ifndef WOLFSSL_NOSHA3_512
13349 { WC_NID_sha3_512, SHA3_512h, oidHashType, "SHA3-512", "sha3-512"},
13350 #endif
13351 #endif /* WOLFSSL_SHA3 */
13352 #ifdef WOLFSSL_SM3
13353 { WC_NID_sm3, SM3h, oidHashType, "SM3", "sm3"},
13354 #endif
13355 #ifdef WOLFSSL_SHAKE128
13356 { WC_NID_shake128, SHAKE128h, oidHashType, "SHAKE128", "shake128"},
13357 #endif
13358 #ifdef WOLFSSL_SHAKE256
13359 { WC_NID_shake256, SHAKE256h, oidHashType, "SHAKE256", "shake256"},
13360 #endif
13361 /* oidSigType */
13362 #ifndef NO_DSA
13363 #ifndef NO_SHA
13364 { WC_NID_dsaWithSHA1, CTC_SHAwDSA, oidSigType,
13365 "DSA-SHA1", "dsaWithSHA1"},
13366 { WC_NID_dsa_with_SHA256, CTC_SHA256wDSA, oidSigType, "dsa_with_SHA256",
13367 "dsa_with_SHA256"},
13368 #endif
13369 #endif /* NO_DSA */
13370 #ifndef NO_RSA
13371 #ifdef WOLFSSL_MD2
13372 { WC_NID_md2WithRSAEncryption, CTC_MD2wRSA, oidSigType, "RSA-MD2",
13373 "md2WithRSAEncryption"},
13374 #endif
13375 #ifndef NO_MD5
13376 { WC_NID_md5WithRSAEncryption, CTC_MD5wRSA, oidSigType, "RSA-MD5",
13377 "md5WithRSAEncryption"},
13378 #endif
13379 #ifndef NO_SHA
13380 { WC_NID_sha1WithRSAEncryption, CTC_SHAwRSA, oidSigType, "RSA-SHA1",
13381 "sha1WithRSAEncryption"},
13382 #endif
13383 #ifdef WOLFSSL_SHA224
13384 { WC_NID_sha224WithRSAEncryption, CTC_SHA224wRSA, oidSigType,
13385 "RSA-SHA224", "sha224WithRSAEncryption"},
13386 #endif
13387 #ifndef NO_SHA256
13388 { WC_NID_sha256WithRSAEncryption, CTC_SHA256wRSA, oidSigType,
13389 "RSA-SHA256", "sha256WithRSAEncryption"},
13390 #endif
13391 #ifdef WOLFSSL_SHA384
13392 { WC_NID_sha384WithRSAEncryption, CTC_SHA384wRSA, oidSigType,
13393 "RSA-SHA384", "sha384WithRSAEncryption"},
13394 #endif
13395 #ifdef WOLFSSL_SHA512
13396 { WC_NID_sha512WithRSAEncryption, CTC_SHA512wRSA, oidSigType,
13397 "RSA-SHA512", "sha512WithRSAEncryption"},
13398 #endif
13399 #ifdef WOLFSSL_SHA3
13400 #ifndef WOLFSSL_NOSHA3_224
13401 { WC_NID_RSA_SHA3_224, CTC_SHA3_224wRSA, oidSigType, "RSA-SHA3-224",
13402 "sha3-224WithRSAEncryption"},
13403 #endif
13404 #ifndef WOLFSSL_NOSHA3_256
13405 { WC_NID_RSA_SHA3_256, CTC_SHA3_256wRSA, oidSigType, "RSA-SHA3-256",
13406 "sha3-256WithRSAEncryption"},
13407 #endif
13408 #ifndef WOLFSSL_NOSHA3_384
13409 { WC_NID_RSA_SHA3_384, CTC_SHA3_384wRSA, oidSigType, "RSA-SHA3-384",
13410 "sha3-384WithRSAEncryption"},
13411 #endif
13412 #ifndef WOLFSSL_NOSHA3_512
13413 { WC_NID_RSA_SHA3_512, CTC_SHA3_512wRSA, oidSigType, "RSA-SHA3-512",
13414 "sha3-512WithRSAEncryption"},
13415 #endif
13416 #endif
13417 #ifdef WC_RSA_PSS
13418 { WC_NID_rsassaPss, CTC_RSASSAPSS, oidSigType,
13419 "RSASSA-PSS", "rsassaPss" },
13420 #endif
13421 #endif /* NO_RSA */
13422 #ifdef HAVE_ECC
13423 #ifndef NO_SHA
13424 { WC_NID_ecdsa_with_SHA1, CTC_SHAwECDSA, oidSigType, "ecdsa-with-SHA1",
13425 "shaWithECDSA"},
13426 #endif
13427 #ifdef WOLFSSL_SHA224
13428 { WC_NID_ecdsa_with_SHA224, CTC_SHA224wECDSA, oidSigType,
13429 "ecdsa-with-SHA224","sha224WithECDSA"},
13430 #endif
13431 #ifndef NO_SHA256
13432 { WC_NID_ecdsa_with_SHA256, CTC_SHA256wECDSA, oidSigType,
13433 "ecdsa-with-SHA256","sha256WithECDSA"},
13434 #endif
13435 #ifdef WOLFSSL_SHA384
13436 { WC_NID_ecdsa_with_SHA384, CTC_SHA384wECDSA, oidSigType,
13437 "ecdsa-with-SHA384","sha384WithECDSA"},
13438 #endif
13439 #ifdef WOLFSSL_SHA512
13440 { WC_NID_ecdsa_with_SHA512, CTC_SHA512wECDSA, oidSigType,
13441 "ecdsa-with-SHA512","sha512WithECDSA"},
13442 #endif
13443 #ifdef WOLFSSL_SHA3
13444 #ifndef WOLFSSL_NOSHA3_224
13445 { WC_NID_ecdsa_with_SHA3_224, CTC_SHA3_224wECDSA, oidSigType,
13446 "id-ecdsa-with-SHA3-224", "ecdsa_with_SHA3-224"},
13447 #endif
13448 #ifndef WOLFSSL_NOSHA3_256
13449 { WC_NID_ecdsa_with_SHA3_256, CTC_SHA3_256wECDSA, oidSigType,
13450 "id-ecdsa-with-SHA3-256", "ecdsa_with_SHA3-256"},
13451 #endif
13452 #ifndef WOLFSSL_NOSHA3_384
13453 { WC_NID_ecdsa_with_SHA3_384, CTC_SHA3_384wECDSA, oidSigType,
13454 "id-ecdsa-with-SHA3-384", "ecdsa_with_SHA3-384"},
13455 #endif
13456 #ifndef WOLFSSL_NOSHA3_512
13457 { WC_NID_ecdsa_with_SHA3_512, CTC_SHA3_512wECDSA, oidSigType,
13458 "id-ecdsa-with-SHA3-512", "ecdsa_with_SHA3-512"},
13459 #endif
13460 #endif
13461 #endif /* HAVE_ECC */
13462
13463 /* oidKeyType */
13464 #ifndef NO_DSA
13465 { WC_NID_dsa, DSAk, oidKeyType, "DSA", "dsaEncryption"},
13466 #endif /* NO_DSA */
13467 #ifndef NO_RSA
13468 { WC_NID_rsaEncryption, RSAk, oidKeyType, "rsaEncryption",
13469 "rsaEncryption"},
13470 #ifdef WC_RSA_PSS
13471 { WC_NID_rsassaPss, RSAPSSk, oidKeyType, "RSASSA-PSS", "rsassaPss"},
13472 #endif
13473 #endif /* NO_RSA */
13474 #ifdef HAVE_ECC
13475 { WC_NID_X9_62_id_ecPublicKey, ECDSAk, oidKeyType, "id-ecPublicKey",
13476 "id-ecPublicKey"},
13477 #endif /* HAVE_ECC */
13478 #ifndef NO_DH
13479 { WC_NID_dhKeyAgreement, DHk, oidKeyType, "dhKeyAgreement",
13480 "dhKeyAgreement"},
13481 #endif
13482 #ifdef HAVE_ED448
13483 { WC_NID_ED448, ED448k, oidKeyType, "ED448", "ED448"},
13484 #endif
13485 #ifdef HAVE_ED25519
13486 { WC_NID_ED25519, ED25519k, oidKeyType, "ED25519", "ED25519"},
13487 #endif
13488 #ifdef HAVE_FALCON
13489 { CTC_FALCON_LEVEL1, FALCON_LEVEL1k, oidKeyType, "Falcon Level 1",
13490 "Falcon Level 1"},
13491 { CTC_FALCON_LEVEL5, FALCON_LEVEL5k, oidKeyType, "Falcon Level 5",
13492 "Falcon Level 5"},
13493 #endif /* HAVE_FALCON */
13494 #ifdef HAVE_DILITHIUM
13495 #ifdef WOLFSSL_DILITHIUM_FIPS204_DRAFT
13496 { CTC_DILITHIUM_LEVEL2, DILITHIUM_LEVEL2k, oidKeyType,
13497 "Dilithium Level 2", "Dilithium Level 2"},
13498 { CTC_DILITHIUM_LEVEL3, DILITHIUM_LEVEL3k, oidKeyType,
13499 "Dilithium Level 3", "Dilithium Level 3"},
13500 { CTC_DILITHIUM_LEVEL5, DILITHIUM_LEVEL5k, oidKeyType,
13501 "Dilithium Level 5", "Dilithium Level 5"},
13502 #endif /* WOLFSSL_DILITHIUM_FIPS204_DRAFT */
13503 { CTC_ML_DSA_LEVEL2, ML_DSA_LEVEL2k, oidKeyType,
13504 "ML-DSA 44", "ML-DSA 44"},
13505 { CTC_ML_DSA_LEVEL3, ML_DSA_LEVEL3k, oidKeyType,
13506 "ML-DSA 65", "ML-DSA 65"},
13507 { CTC_ML_DSA_LEVEL5, ML_DSA_LEVEL5k, oidKeyType,
13508 "ML-DSA 87", "ML-DSA 87"},
13509 #endif /* HAVE_DILITHIUM */
13510
13511 /* oidCurveType */
13512 #ifdef HAVE_ECC
13513 { WC_NID_X9_62_prime192v1, ECC_SECP192R1_OID, oidCurveType,
13514 "prime192v1", "prime192v1"},
13515 { WC_NID_X9_62_prime192v2, ECC_PRIME192V2_OID, oidCurveType,
13516 "prime192v2", "prime192v2"},
13517 { WC_NID_X9_62_prime192v3, ECC_PRIME192V3_OID, oidCurveType,
13518 "prime192v3", "prime192v3"},
13519
13520 { WC_NID_X9_62_prime239v1, ECC_PRIME239V1_OID, oidCurveType,
13521 "prime239v1", "prime239v1"},
13522 { WC_NID_X9_62_prime239v2, ECC_PRIME239V2_OID, oidCurveType,
13523 "prime239v2", "prime239v2"},
13524 { WC_NID_X9_62_prime239v3, ECC_PRIME239V3_OID, oidCurveType,
13525 "prime239v3", "prime239v3"},
13526
13527 { WC_NID_X9_62_prime256v1, ECC_SECP256R1_OID, oidCurveType,
13528 "prime256v1", "prime256v1"},
13529
13530 { WC_NID_secp112r1, ECC_SECP112R1_OID, oidCurveType, "secp112r1",
13531 "secp112r1"},
13532 { WC_NID_secp112r2, ECC_SECP112R2_OID, oidCurveType, "secp112r2",
13533 "secp112r2"},
13534
13535 { WC_NID_secp128r1, ECC_SECP128R1_OID, oidCurveType, "secp128r1",
13536 "secp128r1"},
13537 { WC_NID_secp128r2, ECC_SECP128R2_OID, oidCurveType, "secp128r2",
13538 "secp128r2"},
13539
13540 { WC_NID_secp160r1, ECC_SECP160R1_OID, oidCurveType, "secp160r1",
13541 "secp160r1"},
13542 { WC_NID_secp160r2, ECC_SECP160R2_OID, oidCurveType, "secp160r2",
13543 "secp160r2"},
13544
13545 { WC_NID_secp224r1, ECC_SECP224R1_OID, oidCurveType, "secp224r1",
13546 "secp224r1"},
13547 { WC_NID_secp384r1, ECC_SECP384R1_OID, oidCurveType, "secp384r1",
13548 "secp384r1"},
13549 { WC_NID_secp521r1, ECC_SECP521R1_OID, oidCurveType, "secp521r1",
13550 "secp521r1"},
13551
13552 { WC_NID_secp160k1, ECC_SECP160K1_OID, oidCurveType, "secp160k1",
13553 "secp160k1"},
13554 { WC_NID_secp192k1, ECC_SECP192K1_OID, oidCurveType, "secp192k1",
13555 "secp192k1"},
13556 { WC_NID_secp224k1, ECC_SECP224K1_OID, oidCurveType, "secp224k1",
13557 "secp224k1"},
13558 { WC_NID_secp256k1, ECC_SECP256K1_OID, oidCurveType, "secp256k1",
13559 "secp256k1"},
13560
13561 { WC_NID_brainpoolP160r1, ECC_BRAINPOOLP160R1_OID, oidCurveType,
13562 "brainpoolP160r1", "brainpoolP160r1"},
13563 { WC_NID_brainpoolP192r1, ECC_BRAINPOOLP192R1_OID, oidCurveType,
13564 "brainpoolP192r1", "brainpoolP192r1"},
13565 { WC_NID_brainpoolP224r1, ECC_BRAINPOOLP224R1_OID, oidCurveType,
13566 "brainpoolP224r1", "brainpoolP224r1"},
13567 { WC_NID_brainpoolP256r1, ECC_BRAINPOOLP256R1_OID, oidCurveType,
13568 "brainpoolP256r1", "brainpoolP256r1"},
13569 { WC_NID_brainpoolP320r1, ECC_BRAINPOOLP320R1_OID, oidCurveType,
13570 "brainpoolP320r1", "brainpoolP320r1"},
13571 { WC_NID_brainpoolP384r1, ECC_BRAINPOOLP384R1_OID, oidCurveType,
13572 "brainpoolP384r1", "brainpoolP384r1"},
13573 { WC_NID_brainpoolP512r1, ECC_BRAINPOOLP512R1_OID, oidCurveType,
13574 "brainpoolP512r1", "brainpoolP512r1"},
13575
13576 #ifdef WOLFSSL_SM2
13577 { WC_NID_sm2, ECC_SM2P256V1_OID, oidCurveType, "sm2", "sm2"},
13578 #endif
13579 #endif /* HAVE_ECC */
13580
13581 /* oidBlkType */
13582 #ifdef WOLFSSL_AES_128
13583 { AES128CBCb, AES128CBCb, oidBlkType, "AES-128-CBC", "aes-128-cbc"},
13584 #endif
13585 #ifdef WOLFSSL_AES_192
13586 { AES192CBCb, AES192CBCb, oidBlkType, "AES-192-CBC", "aes-192-cbc"},
13587 #endif
13588 #ifdef WOLFSSL_AES_256
13589 { AES256CBCb, AES256CBCb, oidBlkType, "AES-256-CBC", "aes-256-cbc"},
13590 #endif
13591 #ifndef NO_DES3
13592 { WC_NID_des, DESb, oidBlkType, "DES-CBC", "des-cbc"},
13593 { WC_NID_des3, DES3b, oidBlkType, "DES-EDE3-CBC", "des-ede3-cbc"},
13594 #endif /* !NO_DES3 */
13595 #if defined(HAVE_CHACHA) && defined(HAVE_POLY1305)
13596 { WC_NID_chacha20_poly1305, WC_NID_chacha20_poly1305, oidBlkType,
13597 "ChaCha20-Poly1305", "chacha20-poly1305"},
13598 #endif
13599
13600 /* oidOcspType */
13601 #ifdef HAVE_OCSP
13602 { WC_NID_id_pkix_OCSP_basic, OCSP_BASIC_OID, oidOcspType,
13603 "basicOCSPResponse", "Basic OCSP Response"},
13604 { OCSP_NONCE_OID, OCSP_NONCE_OID, oidOcspType, "Nonce", "OCSP Nonce"},
13605 #endif /* HAVE_OCSP */
13606
13607 #ifndef NO_PWDBASED
13608 /* oidKdfType */
13609 { PBKDF2_OID, PBKDF2_OID, oidKdfType, "PBKDFv2", "PBKDF2"},
13610
13611 /* oidPBEType */
13612 { PBE_SHA1_RC4_128, PBE_SHA1_RC4_128, oidPBEType,
13613 "PBE-SHA1-RC4-128", "pbeWithSHA1And128BitRC4"},
13614 { PBE_SHA1_DES, PBE_SHA1_DES, oidPBEType, "PBE-SHA1-DES",
13615 "pbeWithSHA1AndDES-CBC"},
13616 { PBE_SHA1_DES3, PBE_SHA1_DES3, oidPBEType, "PBE-SHA1-3DES",
13617 "pbeWithSHA1And3-KeyTripleDES-CBC"},
13618 #endif
13619
13620 /* oidKeyWrapType */
13621 #ifdef WOLFSSL_AES_128
13622 { AES128_WRAP, AES128_WRAP, oidKeyWrapType, "AES-128 wrap",
13623 "aes128-wrap"},
13624 #endif
13625 #ifdef WOLFSSL_AES_192
13626 { AES192_WRAP, AES192_WRAP, oidKeyWrapType, "AES-192 wrap",
13627 "aes192-wrap"},
13628 #endif
13629 #ifdef WOLFSSL_AES_256
13630 { AES256_WRAP, AES256_WRAP, oidKeyWrapType, "AES-256 wrap",
13631 "aes256-wrap"},
13632 #endif
13633
13634 #ifndef NO_PKCS7
13635 #ifndef NO_DH
13636 /* oidCmsKeyAgreeType */
13637 #ifndef NO_SHA
13638 { dhSinglePass_stdDH_sha1kdf_scheme, dhSinglePass_stdDH_sha1kdf_scheme,
13639 oidCmsKeyAgreeType, "dhSinglePass-stdDH-sha1kdf-scheme",
13640 "dhSinglePass-stdDH-sha1kdf-scheme"},
13641 #endif
13642 #ifdef WOLFSSL_SHA224
13643 { dhSinglePass_stdDH_sha224kdf_scheme,
13644 dhSinglePass_stdDH_sha224kdf_scheme, oidCmsKeyAgreeType,
13645 "dhSinglePass-stdDH-sha224kdf-scheme",
13646 "dhSinglePass-stdDH-sha224kdf-scheme"},
13647 #endif
13648 #ifndef NO_SHA256
13649 { dhSinglePass_stdDH_sha256kdf_scheme,
13650 dhSinglePass_stdDH_sha256kdf_scheme, oidCmsKeyAgreeType,
13651 "dhSinglePass-stdDH-sha256kdf-scheme",
13652 "dhSinglePass-stdDH-sha256kdf-scheme"},
13653 #endif
13654 #ifdef WOLFSSL_SHA384
13655 { dhSinglePass_stdDH_sha384kdf_scheme,
13656 dhSinglePass_stdDH_sha384kdf_scheme, oidCmsKeyAgreeType,
13657 "dhSinglePass-stdDH-sha384kdf-scheme",
13658 "dhSinglePass-stdDH-sha384kdf-scheme"},
13659 #endif
13660 #ifdef WOLFSSL_SHA512
13661 { dhSinglePass_stdDH_sha512kdf_scheme,
13662 dhSinglePass_stdDH_sha512kdf_scheme, oidCmsKeyAgreeType,
13663 "dhSinglePass-stdDH-sha512kdf-scheme",
13664 "dhSinglePass-stdDH-sha512kdf-scheme"},
13665 #endif
13666 #endif
13667 #endif
13668 #if defined(WOLFSSL_APACHE_HTTPD)
13669 /* "1.3.6.1.5.5.7.8.7" */
13670 { WC_NID_id_on_dnsSRV, WOLFSSL_DNS_SRV_SUM, oidCertNameType,
13671 WOLFSSL_SN_DNS_SRV, WOLFSSL_LN_DNS_SRV },
13672
13673 /* "1.3.6.1.4.1.311.20.2.3" */
13674 { WC_NID_ms_upn, WOLFSSL_MS_UPN_SUM, oidCertExtType, WOLFSSL_SN_MS_UPN,
13675 WOLFSSL_LN_MS_UPN },
13676
13677 /* "1.3.6.1.5.5.7.1.24" */
13678 { WC_NID_tlsfeature, WOLFSSL_TLS_FEATURE_SUM, oidTlsExtType,
13679 WOLFSSL_SN_TLS_FEATURE, WOLFSSL_LN_TLS_FEATURE },
13680 #endif
13681#endif /* OPENSSL_EXTRA */
13682};
13683
13684#define WOLFSSL_OBJECT_INFO_SZ \
13685 (sizeof(wolfssl_object_info) / sizeof(*wolfssl_object_info))
13686const size_t wolfssl_object_info_sz = WOLFSSL_OBJECT_INFO_SZ;
13687#endif /* OPENSSL_EXTRA || OPENSSL_EXTRA_X509_SMALL */
13688
13689#if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)
13690/* Free the dynamically allocated data.
13691 *
13692 * p Pointer to dynamically allocated memory.
13693 */
13694void wolfSSL_OPENSSL_free(void* p)
13695{
13696 WOLFSSL_MSG("wolfSSL_OPENSSL_free");
13697
13698 XFREE(p, NULL, DYNAMIC_TYPE_OPENSSL);
13699}
13700#endif /* OPENSSL_EXTRA || OPENSSL_EXTRA_X509_SMALL */
13701
13702#ifdef OPENSSL_EXTRA
13703
13704void *wolfSSL_OPENSSL_malloc(size_t a)
13705{
13706 return (void *)XMALLOC(a, NULL, DYNAMIC_TYPE_OPENSSL);
13707}
13708
13709int wolfSSL_OPENSSL_hexchar2int(unsigned char c)
13710{
13711 /* 'char' is unsigned on some platforms. */
13712 return (int)(signed char)HexCharToByte((char)c);
13713}
13714
13715unsigned char *wolfSSL_OPENSSL_hexstr2buf(const char *str, long *len)
13716{
13717 unsigned char* targetBuf;
13718 int srcDigitHigh = 0;
13719 int srcDigitLow = 0;
13720 size_t srcLen;
13721 size_t srcIdx = 0;
13722 long targetIdx = 0;
13723
13724 srcLen = XSTRLEN(str);
13725 targetBuf = (unsigned char*)XMALLOC(srcLen / 2, NULL, DYNAMIC_TYPE_OPENSSL);
13726 if (targetBuf == NULL) {
13727 return NULL;
13728 }
13729
13730 while (srcIdx < srcLen) {
13731 if (str[srcIdx] == ':') {
13732 srcIdx++;
13733 continue;
13734 }
13735
13736 srcDigitHigh = wolfSSL_OPENSSL_hexchar2int((unsigned char)str[srcIdx++]);
13737 srcDigitLow = wolfSSL_OPENSSL_hexchar2int((unsigned char)str[srcIdx++]);
13738 if (srcDigitHigh < 0 || srcDigitLow < 0) {
13739 WOLFSSL_MSG("Invalid hex character.");
13740 XFREE(targetBuf, NULL, DYNAMIC_TYPE_OPENSSL);
13741 return NULL;
13742 }
13743
13744 targetBuf[targetIdx++] = (unsigned char)((srcDigitHigh << 4) |
13745 srcDigitLow );
13746 }
13747
13748 if (len != NULL)
13749 *len = targetIdx;
13750
13751 return targetBuf;
13752}
13753
13754int wolfSSL_OPENSSL_init_ssl(word64 opts, const WOLFSSL_INIT_SETTINGS *settings)
13755{
13756 (void)opts;
13757 (void)settings;
13758 return wolfSSL_library_init();
13759}
13760
13761int wolfSSL_OPENSSL_init_crypto(word64 opts,
13762 const WOLFSSL_INIT_SETTINGS* settings)
13763{
13764 (void)opts;
13765 (void)settings;
13766 return wolfSSL_library_init();
13767}
13768
13769/* Colon separated list of <public key>+<digest> algorithms.
13770 * Replaces list in context.
13771 */
13772int wolfSSL_CTX_set1_sigalgs_list(WOLFSSL_CTX* ctx, const char* list)
13773{
13774 WOLFSSL_MSG("wolfSSL_CTX_set1_sigalg_list");
13775
13776 if (ctx == NULL || list == NULL) {
13777 WOLFSSL_MSG("Bad function arguments");
13778 return WOLFSSL_FAILURE;
13779 }
13780
13781 if (AllocateCtxSuites(ctx) != 0)
13782 return WOLFSSL_FAILURE;
13783
13784 return SetSuitesHashSigAlgo(ctx->suites, list);
13785}
13786
13787/* Colon separated list of <public key>+<digest> algorithms.
13788 * Replaces list in SSL.
13789 */
13790int wolfSSL_set1_sigalgs_list(WOLFSSL* ssl, const char* list)
13791{
13792 WOLFSSL_MSG("wolfSSL_set1_sigalg_list");
13793
13794 if (ssl == NULL || list == NULL) {
13795 WOLFSSL_MSG("Bad function arguments");
13796 return WOLFSSL_FAILURE;
13797 }
13798
13799 if (AllocateSuites(ssl) != 0)
13800 return WOLFSSL_FAILURE;
13801
13802 return SetSuitesHashSigAlgo(ssl->suites, list);
13803}
13804
13805static int HashToNid(byte hashAlgo, int* nid)
13806{
13807 int ret = WOLFSSL_SUCCESS;
13808
13809 /* Cast for compiler to check everything is implemented */
13810 switch ((enum wc_MACAlgorithm)hashAlgo) {
13811 case no_mac:
13812 case rmd_mac:
13813 *nid = WC_NID_undef;
13814 break;
13815 case md5_mac:
13816 *nid = WC_NID_md5;
13817 break;
13818 case sha_mac:
13819 *nid = WC_NID_sha1;
13820 break;
13821 case sha224_mac:
13822 *nid = WC_NID_sha224;
13823 break;
13824 case sha256_mac:
13825 *nid = WC_NID_sha256;
13826 break;
13827 case sha384_mac:
13828 *nid = WC_NID_sha384;
13829 break;
13830 case sha512_mac:
13831 *nid = WC_NID_sha512;
13832 break;
13833 case blake2b_mac:
13834 *nid = WC_NID_blake2b512;
13835 break;
13836 case sm3_mac:
13837 *nid = WC_NID_sm3;
13838 break;
13839 default:
13840 ret = WOLFSSL_FAILURE;
13841 break;
13842 }
13843
13844 return ret;
13845}
13846
13847static int SaToNid(byte sa, int* nid)
13848{
13849 int ret = WOLFSSL_SUCCESS;
13850 /* Cast for compiler to check everything is implemented */
13851 switch ((enum SignatureAlgorithm)sa) {
13852 case anonymous_sa_algo:
13853 *nid = WC_NID_undef;
13854 break;
13855 case rsa_sa_algo:
13856 *nid = WC_NID_rsaEncryption;
13857 break;
13858 case dsa_sa_algo:
13859 *nid = WC_NID_dsa;
13860 break;
13861 case ecc_dsa_sa_algo:
13862 case ecc_brainpool_sa_algo:
13863 *nid = WC_NID_X9_62_id_ecPublicKey;
13864 break;
13865 case rsa_pss_sa_algo:
13866 *nid = WC_NID_rsassaPss;
13867 break;
13868 case ed25519_sa_algo:
13869#ifdef HAVE_ED25519
13870 *nid = WC_NID_ED25519;
13871#else
13872 ret = WOLFSSL_FAILURE;
13873#endif
13874 break;
13875 case rsa_pss_pss_algo:
13876 *nid = WC_NID_rsassaPss;
13877 break;
13878 case ed448_sa_algo:
13879#ifdef HAVE_ED448
13880 *nid = WC_NID_ED448;
13881#else
13882 ret = WOLFSSL_FAILURE;
13883#endif
13884 break;
13885 case falcon_level1_sa_algo:
13886 *nid = CTC_FALCON_LEVEL1;
13887 break;
13888 case falcon_level5_sa_algo:
13889 *nid = CTC_FALCON_LEVEL5;
13890 break;
13891 case dilithium_level2_sa_algo:
13892 *nid = CTC_ML_DSA_LEVEL2;
13893 break;
13894 case dilithium_level3_sa_algo:
13895 *nid = CTC_ML_DSA_LEVEL3;
13896 break;
13897 case dilithium_level5_sa_algo:
13898 *nid = CTC_ML_DSA_LEVEL5;
13899 break;
13900 case sm2_sa_algo:
13901 *nid = WC_NID_sm2;
13902 break;
13903 case invalid_sa_algo:
13904 case any_sa_algo:
13905 default:
13906 ret = WOLFSSL_FAILURE;
13907 break;
13908 }
13909 return ret;
13910}
13911
13912/* This API returns the hash selected. */
13913int wolfSSL_get_signature_nid(WOLFSSL *ssl, int* nid)
13914{
13915 WOLFSSL_MSG("wolfSSL_get_signature_nid");
13916
13917 if (ssl == NULL || nid == NULL) {
13918 WOLFSSL_MSG("Bad function arguments");
13919 return WOLFSSL_FAILURE;
13920 }
13921
13922 return HashToNid(ssl->options.hashAlgo, nid);
13923}
13924
13925/* This API returns the signature selected. */
13926int wolfSSL_get_signature_type_nid(const WOLFSSL* ssl, int* nid)
13927{
13928 WOLFSSL_MSG("wolfSSL_get_signature_type_nid");
13929
13930 if (ssl == NULL || nid == NULL) {
13931 WOLFSSL_MSG("Bad function arguments");
13932 return WOLFSSL_FAILURE;
13933 }
13934
13935 return SaToNid(ssl->options.sigAlgo, nid);
13936}
13937
13938int wolfSSL_get_peer_signature_nid(WOLFSSL* ssl, int* nid)
13939{
13940 WOLFSSL_MSG("wolfSSL_get_peer_signature_nid");
13941
13942 if (ssl == NULL || nid == NULL) {
13943 WOLFSSL_MSG("Bad function arguments");
13944 return WOLFSSL_FAILURE;
13945 }
13946
13947 return HashToNid(ssl->options.peerHashAlgo, nid);
13948}
13949
13950int wolfSSL_get_peer_signature_type_nid(const WOLFSSL* ssl, int* nid)
13951{
13952 WOLFSSL_MSG("wolfSSL_get_peer_signature_type_nid");
13953
13954 if (ssl == NULL || nid == NULL) {
13955 WOLFSSL_MSG("Bad function arguments");
13956 return WOLFSSL_FAILURE;
13957 }
13958
13959 return SaToNid(ssl->options.peerSigAlgo, nid);
13960}
13961
13962#ifdef HAVE_ECC
13963
13964#if defined(WOLFSSL_TLS13) && defined(HAVE_SUPPORTED_CURVES)
13965int wolfSSL_CTX_set1_groups_list(WOLFSSL_CTX *ctx, const char *list)
13966{
13967 if (!ctx || !list) {
13968 return WOLFSSL_FAILURE;
13969 }
13970
13971 return set_curves_list(NULL, ctx, list, 0);
13972}
13973
13974int wolfSSL_set1_groups_list(WOLFSSL *ssl, const char *list)
13975{
13976 if (!ssl || !list) {
13977 return WOLFSSL_FAILURE;
13978 }
13979
13980 return set_curves_list(ssl, NULL, list, 0);
13981}
13982#endif /* WOLFSSL_TLS13 */
13983
13984#endif /* HAVE_ECC */
13985
13986#endif /* OPENSSL_EXTRA */
13987
13988#ifdef WOLFSSL_ALT_CERT_CHAINS
13989int wolfSSL_is_peer_alt_cert_chain(const WOLFSSL* ssl)
13990{
13991 int isUsing = 0;
13992 if (ssl)
13993 isUsing = ssl->options.usingAltCertChain;
13994 return isUsing;
13995}
13996#endif /* WOLFSSL_ALT_CERT_CHAINS */
13997
13998
13999#ifdef SESSION_CERTS
14000
14001#ifdef WOLFSSL_ALT_CERT_CHAINS
14002/* Get peer's alternate certificate chain */
14003WOLFSSL_X509_CHAIN* wolfSSL_get_peer_alt_chain(WOLFSSL* ssl)
14004{
14005 WOLFSSL_ENTER("wolfSSL_get_peer_alt_chain");
14006 if (ssl)
14007 return &ssl->session->altChain;
14008
14009 return 0;
14010}
14011#endif /* WOLFSSL_ALT_CERT_CHAINS */
14012
14013
14014/* Get peer's certificate chain */
14015WOLFSSL_X509_CHAIN* wolfSSL_get_peer_chain(WOLFSSL* ssl)
14016{
14017 WOLFSSL_ENTER("wolfSSL_get_peer_chain");
14018 if (ssl)
14019 return &ssl->session->chain;
14020
14021 return 0;
14022}
14023
14024
14025/* Get peer's certificate chain total count */
14026int wolfSSL_get_chain_count(WOLFSSL_X509_CHAIN* chain)
14027{
14028 WOLFSSL_ENTER("wolfSSL_get_chain_count");
14029 if (chain)
14030 return chain->count;
14031
14032 return 0;
14033}
14034
14035
14036/* Get peer's ASN.1 DER certificate at index (idx) length in bytes */
14037int wolfSSL_get_chain_length(WOLFSSL_X509_CHAIN* chain, int idx)
14038{
14039 WOLFSSL_ENTER("wolfSSL_get_chain_length");
14040 if (chain)
14041 return chain->certs[idx].length;
14042
14043 return 0;
14044}
14045
14046
14047/* Get peer's ASN.1 DER certificate at index (idx) */
14048byte* wolfSSL_get_chain_cert(WOLFSSL_X509_CHAIN* chain, int idx)
14049{
14050 WOLFSSL_ENTER("wolfSSL_get_chain_cert");
14051 if (chain)
14052 return chain->certs[idx].buffer;
14053
14054 return 0;
14055}
14056
14057
14058/* Get peer's wolfSSL X509 certificate at index (idx) */
14059WOLFSSL_X509* wolfSSL_get_chain_X509(WOLFSSL_X509_CHAIN* chain, int idx)
14060{
14061 int ret = 0;
14062 WOLFSSL_X509* x509 = NULL;
14063 WC_DECLARE_VAR(cert, DecodedCert, 1, 0);
14064
14065 WOLFSSL_ENTER("wolfSSL_get_chain_X509");
14066 if (chain != NULL && idx < MAX_CHAIN_DEPTH) {
14067 #ifdef WOLFSSL_SMALL_STACK
14068 cert = (DecodedCert*)XMALLOC(sizeof(DecodedCert), NULL,
14069 DYNAMIC_TYPE_DCERT);
14070 if (cert != NULL)
14071 #endif
14072 {
14073 InitDecodedCert(cert, chain->certs[idx].buffer,
14074 (word32)chain->certs[idx].length, NULL);
14075
14076 if ((ret = ParseCertRelative(cert, CERT_TYPE, 0, NULL, NULL)) != 0) {
14077 WOLFSSL_MSG("Failed to parse cert");
14078 }
14079 else {
14080 x509 = (WOLFSSL_X509*)XMALLOC(sizeof(WOLFSSL_X509), NULL,
14081 DYNAMIC_TYPE_X509);
14082 if (x509 == NULL) {
14083 WOLFSSL_MSG("Failed alloc X509");
14084 }
14085 else {
14086 InitX509(x509, 1, NULL);
14087
14088 if ((ret = CopyDecodedToX509(x509, cert)) != 0) {
14089 WOLFSSL_MSG("Failed to copy decoded");
14090 wolfSSL_X509_free(x509);
14091 x509 = NULL;
14092 }
14093 }
14094 }
14095
14096 FreeDecodedCert(cert);
14097 WC_FREE_VAR_EX(cert, NULL, DYNAMIC_TYPE_DCERT);
14098 }
14099 }
14100 (void)ret;
14101
14102 return x509;
14103}
14104
14105
14106/* Get peer's PEM certificate at index (idx), output to buffer if inLen big
14107 enough else return error (-1). If buffer is NULL only calculate
14108 outLen. Output length is in *outLen WOLFSSL_SUCCESS on ok */
14109int wolfSSL_get_chain_cert_pem(WOLFSSL_X509_CHAIN* chain, int idx,
14110 unsigned char* buf, int inLen, int* outLen)
14111{
14112#if defined(WOLFSSL_PEM_TO_DER) || defined(WOLFSSL_DER_TO_PEM)
14113 const char* header = NULL;
14114 const char* footer = NULL;
14115 int headerLen;
14116 int footerLen;
14117 int i;
14118 int err;
14119 word32 szNeeded = 0;
14120
14121 WOLFSSL_ENTER("wolfSSL_get_chain_cert_pem");
14122 if (!chain || !outLen || idx < 0 || idx >= wolfSSL_get_chain_count(chain))
14123 return BAD_FUNC_ARG;
14124
14125 err = wc_PemGetHeaderFooter(CERT_TYPE, &header, &footer);
14126 if (err != 0)
14127 return err;
14128
14129 headerLen = (int)XSTRLEN(header);
14130 footerLen = (int)XSTRLEN(footer);
14131
14132 /* Null output buffer return size needed in outLen */
14133 if(!buf) {
14134 if(Base64_Encode(chain->certs[idx].buffer,
14135 (word32)chain->certs[idx].length,
14136 NULL, &szNeeded) != WC_NO_ERR_TRACE(LENGTH_ONLY_E))
14137 return WOLFSSL_FAILURE;
14138 *outLen = (int)szNeeded + headerLen + footerLen;
14139 return WC_NO_ERR_TRACE(LENGTH_ONLY_E);
14140 }
14141
14142 /* don't even try if inLen too short */
14143 if (inLen < headerLen + footerLen + chain->certs[idx].length)
14144 return BAD_FUNC_ARG;
14145
14146 /* header */
14147 if (XMEMCPY(buf, header, (size_t)headerLen) == NULL)
14148 return WOLFSSL_FATAL_ERROR;
14149
14150 i = headerLen;
14151
14152 /* body */
14153 *outLen = inLen; /* input to Base64_Encode */
14154 if ( (err = Base64_Encode(chain->certs[idx].buffer,
14155 (word32)chain->certs[idx].length, buf + i,
14156 (word32*)outLen)) < 0)
14157 return err;
14158 i += *outLen;
14159
14160 /* footer */
14161 if ( (i + footerLen) > inLen)
14162 return BAD_FUNC_ARG;
14163 if (XMEMCPY(buf + i, footer, (size_t)footerLen) == NULL)
14164 return WOLFSSL_FATAL_ERROR;
14165 *outLen += headerLen + footerLen;
14166
14167 return WOLFSSL_SUCCESS;
14168#else
14169 (void)chain;
14170 (void)idx;
14171 (void)buf;
14172 (void)inLen;
14173 (void)outLen;
14174 return WOLFSSL_FAILURE;
14175#endif /* WOLFSSL_PEM_TO_DER || WOLFSSL_DER_TO_PEM */
14176}
14177
14178#endif /* SESSION_CERTS */
14179
14180#ifdef HAVE_FUZZER
14181void wolfSSL_SetFuzzerCb(WOLFSSL* ssl, CallbackFuzzer cbf, void* fCtx)
14182{
14183 if (ssl) {
14184 ssl->fuzzerCb = cbf;
14185 ssl->fuzzerCtx = fCtx;
14186 }
14187}
14188#endif
14189
14190#ifndef NO_CERTS
14191#ifdef HAVE_PK_CALLBACKS
14192
14193/* callback for premaster secret generation */
14194void wolfSSL_CTX_SetGenPreMasterCb(WOLFSSL_CTX* ctx, CallbackGenPreMaster cb)
14195{
14196 if (ctx)
14197 ctx->GenPreMasterCb = cb;
14198}
14199/* Set premaster secret generation callback context */
14200void wolfSSL_SetGenPreMasterCtx(WOLFSSL* ssl, void *ctx)
14201{
14202 if (ssl)
14203 ssl->GenPreMasterCtx = ctx;
14204}
14205/* Get premaster secret generation callback context */
14206void* wolfSSL_GetGenPreMasterCtx(WOLFSSL* ssl)
14207{
14208 if (ssl)
14209 return ssl->GenPreMasterCtx;
14210
14211 return NULL;
14212}
14213
14214/* callback for master secret generation */
14215void wolfSSL_CTX_SetGenMasterSecretCb(WOLFSSL_CTX* ctx,
14216 CallbackGenMasterSecret cb)
14217{
14218 if (ctx)
14219 ctx->GenMasterCb = cb;
14220}
14221/* Set master secret generation callback context */
14222void wolfSSL_SetGenMasterSecretCtx(WOLFSSL* ssl, void *ctx)
14223{
14224 if (ssl)
14225 ssl->GenMasterCtx = ctx;
14226}
14227/* Get master secret generation callback context */
14228void* wolfSSL_GetGenMasterSecretCtx(WOLFSSL* ssl)
14229{
14230 if (ssl)
14231 return ssl->GenMasterCtx;
14232
14233 return NULL;
14234}
14235
14236/* callback for extended master secret generation */
14237void wolfSSL_CTX_SetGenExtMasterSecretCb(WOLFSSL_CTX* ctx,
14238 CallbackGenExtMasterSecret cb)
14239{
14240 if (ctx)
14241 ctx->GenExtMasterCb = cb;
14242}
14243/* Set extended master secret generation callback context */
14244void wolfSSL_SetGenExtMasterSecretCtx(WOLFSSL* ssl, void *ctx)
14245{
14246 if (ssl)
14247 ssl->GenExtMasterCtx = ctx;
14248}
14249/* Get extended master secret generation callback context */
14250void* wolfSSL_GetGenExtMasterSecretCtx(WOLFSSL* ssl)
14251{
14252 if (ssl)
14253 return ssl->GenExtMasterCtx;
14254
14255 return NULL;
14256}
14257
14258
14259/* callback for session key generation */
14260void wolfSSL_CTX_SetGenSessionKeyCb(WOLFSSL_CTX* ctx, CallbackGenSessionKey cb)
14261{
14262 if (ctx)
14263 ctx->GenSessionKeyCb = cb;
14264}
14265/* Set session key generation callback context */
14266void wolfSSL_SetGenSessionKeyCtx(WOLFSSL* ssl, void *ctx)
14267{
14268 if (ssl)
14269 ssl->GenSessionKeyCtx = ctx;
14270}
14271/* Get session key generation callback context */
14272void* wolfSSL_GetGenSessionKeyCtx(WOLFSSL* ssl)
14273{
14274 if (ssl)
14275 return ssl->GenSessionKeyCtx;
14276
14277 return NULL;
14278}
14279
14280/* callback for setting encryption keys */
14281void wolfSSL_CTX_SetEncryptKeysCb(WOLFSSL_CTX* ctx, CallbackEncryptKeys cb)
14282{
14283 if (ctx)
14284 ctx->EncryptKeysCb = cb;
14285}
14286/* Set encryption keys callback context */
14287void wolfSSL_SetEncryptKeysCtx(WOLFSSL* ssl, void *ctx)
14288{
14289 if (ssl)
14290 ssl->EncryptKeysCtx = ctx;
14291}
14292/* Get encryption keys callback context */
14293void* wolfSSL_GetEncryptKeysCtx(WOLFSSL* ssl)
14294{
14295 if (ssl)
14296 return ssl->EncryptKeysCtx;
14297
14298 return NULL;
14299}
14300
14301/* callback for Tls finished */
14302/* the callback can be used to build TLS Finished message if enabled */
14303void wolfSSL_CTX_SetTlsFinishedCb(WOLFSSL_CTX* ctx, CallbackTlsFinished cb)
14304{
14305 if (ctx)
14306 ctx->TlsFinishedCb = cb;
14307}
14308/* Set Tls finished callback context */
14309void wolfSSL_SetTlsFinishedCtx(WOLFSSL* ssl, void *ctx)
14310{
14311 if (ssl)
14312 ssl->TlsFinishedCtx = ctx;
14313}
14314/* Get Tls finished callback context */
14315void* wolfSSL_GetTlsFinishedCtx(WOLFSSL* ssl)
14316{
14317 if (ssl)
14318 return ssl->TlsFinishedCtx;
14319
14320 return NULL;
14321}
14322#if !defined(WOLFSSL_NO_TLS12) && !defined(WOLFSSL_AEAD_ONLY)
14323/* callback for verify data */
14324void wolfSSL_CTX_SetVerifyMacCb(WOLFSSL_CTX* ctx, CallbackVerifyMac cb)
14325{
14326 if (ctx)
14327 ctx->VerifyMacCb = cb;
14328}
14329
14330/* Set set keys callback context */
14331void wolfSSL_SetVerifyMacCtx(WOLFSSL* ssl, void *ctx)
14332{
14333 if (ssl)
14334 ssl->VerifyMacCtx = ctx;
14335}
14336/* Get set keys callback context */
14337void* wolfSSL_GetVerifyMacCtx(WOLFSSL* ssl)
14338{
14339 if (ssl)
14340 return ssl->VerifyMacCtx;
14341
14342 return NULL;
14343}
14344#endif /* !WOLFSSL_NO_TLS12 && !WOLFSSL_AEAD_ONLY */
14345
14346void wolfSSL_CTX_SetHKDFExpandLabelCb(WOLFSSL_CTX* ctx,
14347 CallbackHKDFExpandLabel cb)
14348{
14349 if (ctx)
14350 ctx->HKDFExpandLabelCb = cb;
14351}
14352#ifdef WOLFSSL_PUBLIC_ASN
14353void wolfSSL_CTX_SetProcessPeerCertCb(WOLFSSL_CTX* ctx,
14354 CallbackProcessPeerCert cb)
14355{
14356 if (ctx)
14357 ctx->ProcessPeerCertCb = cb;
14358}
14359#endif /* WOLFSSL_PUBLIC_ASN */
14360void wolfSSL_CTX_SetProcessServerSigKexCb(WOLFSSL_CTX* ctx,
14361 CallbackProcessServerSigKex cb)
14362{
14363 if (ctx)
14364 ctx->ProcessServerSigKexCb = cb;
14365}
14366void wolfSSL_CTX_SetPerformTlsRecordProcessingCb(WOLFSSL_CTX* ctx,
14367 CallbackPerformTlsRecordProcessing cb)
14368{
14369 if (ctx)
14370 ctx->PerformTlsRecordProcessingCb = cb;
14371}
14372#endif /* HAVE_PK_CALLBACKS */
14373#endif /* NO_CERTS */
14374
14375#if defined(HAVE_PK_CALLBACKS) && defined(HAVE_HKDF)
14376
14377void wolfSSL_CTX_SetHKDFExtractCb(WOLFSSL_CTX* ctx, CallbackHKDFExtract cb)
14378{
14379 if (ctx)
14380 ctx->HkdfExtractCb = cb;
14381}
14382
14383void wolfSSL_SetHKDFExtractCtx(WOLFSSL* ssl, void *ctx)
14384{
14385 if (ssl)
14386 ssl->HkdfExtractCtx = ctx;
14387}
14388
14389void* wolfSSL_GetHKDFExtractCtx(WOLFSSL* ssl)
14390{
14391 if (ssl)
14392 return ssl->HkdfExtractCtx;
14393
14394 return NULL;
14395}
14396#endif /* HAVE_PK_CALLBACKS && HAVE_HKDF */
14397
14398#ifdef WOLFSSL_HAVE_WOLFSCEP
14399 /* Used by autoconf to see if wolfSCEP is available */
14400 void wolfSSL_wolfSCEP(void) {}
14401#endif
14402
14403
14404#ifdef WOLFSSL_HAVE_CERT_SERVICE
14405 /* Used by autoconf to see if cert service is available */
14406 void wolfSSL_cert_service(void) {}
14407#endif
14408
14409#if (defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)) && \
14410 !defined(WOLFCRYPT_ONLY)
14411
14412 /* NID variables are dependent on compatibility header files currently
14413 *
14414 * returns a pointer to a new WOLFSSL_ASN1_OBJECT struct on success and NULL
14415 * on fail
14416 */
14417
14418 WOLFSSL_ASN1_OBJECT* wolfSSL_OBJ_nid2obj(int id)
14419 {
14420 return wolfSSL_OBJ_nid2obj_ex(id, NULL);
14421 }
14422
14423
14424 WOLFSSL_LOCAL WOLFSSL_ASN1_OBJECT* wolfSSL_OBJ_nid2obj_ex(int id,
14425 WOLFSSL_ASN1_OBJECT* arg_obj)
14426 {
14427 word32 oidSz = 0;
14428 int nid = 0;
14429 const byte* oid;
14430 word32 type = 0;
14431 WOLFSSL_ASN1_OBJECT* obj = arg_obj;
14432 byte objBuf[MAX_OID_SZ + MAX_LENGTH_SZ + 1]; /* +1 for object tag */
14433 word32 objSz = 0;
14434 const char* sName = NULL;
14435 int i;
14436
14437#ifdef WOLFSSL_DEBUG_OPENSSL
14438 WOLFSSL_ENTER("wolfSSL_OBJ_nid2obj");
14439#endif
14440
14441 for (i = 0; i < (int)WOLFSSL_OBJECT_INFO_SZ; i++) {
14442 if (wolfssl_object_info[i].nid == id) {
14443 nid = id;
14444 id = wolfssl_object_info[i].id;
14445 sName = wolfssl_object_info[i].sName;
14446 type = wolfssl_object_info[i].type;
14447 break;
14448 }
14449 }
14450 if (i == (int)WOLFSSL_OBJECT_INFO_SZ) {
14451 WOLFSSL_MSG("NID not in table");
14452 #ifdef WOLFSSL_QT
14453 sName = NULL;
14454 type = (word32)id;
14455 #else
14456 return NULL;
14457 #endif
14458 }
14459
14460 #ifdef HAVE_ECC
14461 if (type == 0 && wc_ecc_get_oid((word32)id, &oid, &oidSz) > 0) {
14462 type = oidCurveType;
14463 }
14464 #endif /* HAVE_ECC */
14465
14466 if (sName != NULL) {
14467 if (XSTRLEN(sName) > WOLFSSL_MAX_SNAME - 1) {
14468 WOLFSSL_MSG("Attempted short name is too large");
14469 return NULL;
14470 }
14471 }
14472
14473 oid = OidFromId((word32)id, type, &oidSz);
14474
14475 /* set object ID to buffer */
14476 if (obj == NULL){
14477 obj = wolfSSL_ASN1_OBJECT_new();
14478 if (obj == NULL) {
14479 WOLFSSL_MSG("Issue creating WOLFSSL_ASN1_OBJECT struct");
14480 return NULL;
14481 }
14482 }
14483 obj->nid = nid;
14484 obj->type = id;
14485 obj->grp = (int)type;
14486
14487 obj->sName[0] = '\0';
14488 if (sName != NULL) {
14489 XMEMCPY(obj->sName, (char*)sName, XSTRLEN((char*)sName));
14490 }
14491
14492 objBuf[0] = ASN_OBJECT_ID; objSz++;
14493 objSz += SetLength(oidSz, objBuf + 1);
14494 if (oidSz) {
14495 XMEMCPY(objBuf + objSz, oid, oidSz);
14496 objSz += oidSz;
14497 }
14498
14499 if (obj->objSz == 0 || objSz != obj->objSz) {
14500 obj->objSz = objSz;
14501 if(((obj->dynamic & WOLFSSL_ASN1_DYNAMIC_DATA) != 0) ||
14502 (obj->obj == NULL)) {
14503 if (obj->obj != NULL)
14504 XFREE((byte*)obj->obj, NULL, DYNAMIC_TYPE_ASN1);
14505 obj->obj = (byte*)XMALLOC(obj->objSz, NULL, DYNAMIC_TYPE_ASN1);
14506 if (obj->obj == NULL) {
14507 wolfSSL_ASN1_OBJECT_free(obj);
14508 return NULL;
14509 }
14510 obj->dynamic |= WOLFSSL_ASN1_DYNAMIC_DATA;
14511 }
14512 else {
14513 obj->dynamic &= (unsigned char)~WOLFSSL_ASN1_DYNAMIC_DATA;
14514 }
14515 }
14516 XMEMCPY((byte*)obj->obj, objBuf, obj->objSz);
14517
14518 (void)type;
14519
14520 return obj;
14521 }
14522
14523 static const char* oid_translate_num_to_str(const char* oid)
14524 {
14525 const struct oid_dict {
14526 const char* num;
14527 const char* desc;
14528 } oid_dict[] = {
14529 { "2.5.29.37.0", "Any Extended Key Usage" },
14530 { "1.3.6.1.5.5.7.3.1", "TLS Web Server Authentication" },
14531 { "1.3.6.1.5.5.7.3.2", "TLS Web Client Authentication" },
14532 { "1.3.6.1.5.5.7.3.3", "Code Signing" },
14533 { "1.3.6.1.5.5.7.3.4", "E-mail Protection" },
14534 { "1.3.6.1.5.5.7.3.8", "Time Stamping" },
14535 { "1.3.6.1.5.5.7.3.9", "OCSP Signing" },
14536 { NULL, NULL }
14537 };
14538 const struct oid_dict* idx;
14539
14540 for (idx = oid_dict; idx->num != NULL; idx++) {
14541 if (!XSTRCMP(oid, idx->num)) {
14542 return idx->desc;
14543 }
14544 }
14545 return NULL;
14546 }
14547
14548 static int wolfssl_obj2txt_numeric(char *buf, int bufLen,
14549 const WOLFSSL_ASN1_OBJECT *a)
14550 {
14551 int bufSz;
14552 int length;
14553 word32 idx = 0;
14554 byte tag;
14555
14556 if (GetASNTag(a->obj, &idx, &tag, a->objSz) != 0) {
14557 return WOLFSSL_FAILURE;
14558 }
14559
14560 if (tag != ASN_OBJECT_ID) {
14561 WOLFSSL_MSG("Bad ASN1 Object");
14562 return WOLFSSL_FAILURE;
14563 }
14564
14565 if (GetLength((const byte*)a->obj, &idx, &length,
14566 a->objSz) < 0 || length < 0) {
14567 return ASN_PARSE_E;
14568 }
14569
14570 if (bufLen < MAX_OID_STRING_SZ) {
14571 bufSz = bufLen - 1;
14572 }
14573 else {
14574 bufSz = MAX_OID_STRING_SZ;
14575 }
14576
14577 if ((bufSz = DecodePolicyOID(buf, (word32)bufSz, a->obj + idx,
14578 (word32)length)) <= 0) {
14579 WOLFSSL_MSG("Error decoding OID");
14580 return WOLFSSL_FAILURE;
14581 }
14582
14583 buf[bufSz] = '\0';
14584
14585 return bufSz;
14586 }
14587
14588 /* If no_name is one then use numerical form, otherwise short name.
14589 *
14590 * Returns the buffer size on success, WOLFSSL_FAILURE on error
14591 */
14592 int wolfSSL_OBJ_obj2txt(char *buf, int bufLen, const WOLFSSL_ASN1_OBJECT *a,
14593 int no_name)
14594 {
14595 int bufSz;
14596 const char* desc;
14597 const char* name;
14598
14599 WOLFSSL_ENTER("wolfSSL_OBJ_obj2txt");
14600
14601 if (buf == NULL || bufLen <= 1 || a == NULL) {
14602 WOLFSSL_MSG("Bad input argument");
14603 return WOLFSSL_FAILURE;
14604 }
14605
14606 if (no_name == 1) {
14607 return wolfssl_obj2txt_numeric(buf, bufLen, a);
14608 }
14609
14610 /* return long name unless using x509small, then return short name */
14611#if defined(OPENSSL_EXTRA_X509_SMALL) && !defined(OPENSSL_EXTRA)
14612 name = a->sName;
14613#else
14614 name = wolfSSL_OBJ_nid2ln(wolfSSL_OBJ_obj2nid(a));
14615#endif
14616
14617 if (name == NULL) {
14618 WOLFSSL_MSG("Name not found");
14619 bufSz = 0;
14620 }
14621 else if (XSTRLEN(name) + 1 < (word32)bufLen - 1) {
14622 bufSz = (int)XSTRLEN(name);
14623 }
14624 else {
14625 bufSz = bufLen - 1;
14626 }
14627 if (bufSz) {
14628 XMEMCPY(buf, name, (size_t)bufSz);
14629 }
14630 else if (a->type == WOLFSSL_GEN_DNS || a->type == WOLFSSL_GEN_EMAIL ||
14631 a->type == WOLFSSL_GEN_URI) {
14632 size_t objLen = XSTRLEN((const char*)a->obj);
14633 if (objLen >= (size_t)bufLen) {
14634 bufSz = bufLen - 1;
14635 }
14636 else {
14637 bufSz = (int)objLen;
14638 }
14639 XMEMCPY(buf, a->obj, (size_t)bufSz);
14640 }
14641 else if ((bufSz = wolfssl_obj2txt_numeric(buf, bufLen, a)) > 0) {
14642 if ((desc = oid_translate_num_to_str(buf))) {
14643 bufSz = (int)XSTRLEN(desc);
14644 bufSz = (int)min((word32)bufSz,(word32) bufLen - 1);
14645 XMEMCPY(buf, desc, (size_t)bufSz);
14646 }
14647 }
14648 else {
14649 bufSz = 0;
14650 }
14651
14652 buf[bufSz] = '\0';
14653
14654 return bufSz;
14655 }
14656#endif /* OPENSSL_EXTRA || OPENSSL_EXTRA_X509_SMALL */
14657
14658#if defined(OPENSSL_EXTRA) || defined(HAVE_LIGHTY) || \
14659 defined(WOLFSSL_MYSQL_COMPATIBLE) || defined(HAVE_STUNNEL) || \
14660 defined(WOLFSSL_NGINX) || defined(HAVE_POCO_LIB) || \
14661 defined(WOLFSSL_HAPROXY) || defined(WOLFSSL_WPAS_SMALL)
14662 /* Returns the long name that corresponds with an ASN1_OBJECT nid value.
14663 * n : NID value of ASN1_OBJECT to search */
14664 const char* wolfSSL_OBJ_nid2ln(int n)
14665 {
14666 const WOLFSSL_ObjectInfo *obj_info = wolfssl_object_info;
14667 size_t i;
14668 WOLFSSL_ENTER("wolfSSL_OBJ_nid2ln");
14669 for (i = 0; i < WOLFSSL_OBJECT_INFO_SZ; i++, obj_info++) {
14670 if (obj_info->nid == n) {
14671 return obj_info->lName;
14672 }
14673 }
14674 WOLFSSL_MSG("NID not found in table");
14675 return NULL;
14676 }
14677#endif /* OPENSSL_EXTRA, HAVE_LIGHTY, WOLFSSL_MYSQL_COMPATIBLE, HAVE_STUNNEL,
14678 WOLFSSL_NGINX, HAVE_POCO_LIB, WOLFSSL_HAPROXY, WOLFSSL_WPAS_SMALL */
14679
14680#if defined(OPENSSL_EXTRA) || defined(HAVE_LIGHTY) || \
14681 defined(WOLFSSL_MYSQL_COMPATIBLE) || defined(HAVE_STUNNEL) || \
14682 defined(WOLFSSL_NGINX) || defined(HAVE_POCO_LIB) || \
14683 defined(WOLFSSL_HAPROXY)
14684 /* Return the corresponding short name for the nid <n>.
14685 * or NULL if short name can't be found.
14686 */
14687 const char * wolfSSL_OBJ_nid2sn(int n) {
14688 const WOLFSSL_ObjectInfo *obj_info = wolfssl_object_info;
14689 size_t i;
14690 WOLFSSL_ENTER("wolfSSL_OBJ_nid2sn");
14691
14692 if (n == WC_NID_md5) {
14693 /* WC_NID_surname == WC_NID_md5 and WC_NID_surname comes before WC_NID_md5 in
14694 * wolfssl_object_info. As a result, the loop below will incorrectly
14695 * return "SN" instead of "MD5." WC_NID_surname isn't the true OpenSSL
14696 * NID, but other functions rely on this table and modifying it to
14697 * conform with OpenSSL's NIDs isn't trivial. */
14698 return "MD5";
14699 }
14700 for (i = 0; i < WOLFSSL_OBJECT_INFO_SZ; i++, obj_info++) {
14701 if (obj_info->nid == n) {
14702 return obj_info->sName;
14703 }
14704 }
14705 WOLFSSL_MSG_EX("SN not found (nid:%d)",n);
14706 return NULL;
14707 }
14708
14709#if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)
14710 int wolfSSL_OBJ_sn2nid(const char *sn) {
14711 WOLFSSL_ENTER("wolfSSL_OBJ_sn2nid");
14712 if (sn == NULL)
14713 return WC_NID_undef;
14714 return wc_OBJ_sn2nid(sn);
14715 }
14716#endif
14717
14718 size_t wolfSSL_OBJ_length(const WOLFSSL_ASN1_OBJECT* o)
14719 {
14720 size_t ret = 0;
14721 int err = 0;
14722 word32 idx = 0;
14723 int len = 0;
14724
14725 WOLFSSL_ENTER("wolfSSL_OBJ_length");
14726
14727 if (o == NULL || o->obj == NULL) {
14728 WOLFSSL_MSG("Bad argument.");
14729 err = 1;
14730 }
14731
14732 if (err == 0 && GetASNObjectId(o->obj, &idx, &len, o->objSz)) {
14733 WOLFSSL_MSG("Error parsing ASN.1 header.");
14734 err = 1;
14735 }
14736 if (err == 0) {
14737 ret = (size_t)len;
14738 }
14739
14740 WOLFSSL_LEAVE("wolfSSL_OBJ_length", (int)ret);
14741
14742 return ret;
14743 }
14744
14745 const unsigned char* wolfSSL_OBJ_get0_data(const WOLFSSL_ASN1_OBJECT* o)
14746 {
14747 const unsigned char* ret = NULL;
14748 int err = 0;
14749 word32 idx = 0;
14750 int len = 0;
14751
14752 WOLFSSL_ENTER("wolfSSL_OBJ_get0_data");
14753
14754 if (o == NULL || o->obj == NULL) {
14755 WOLFSSL_MSG("Bad argument.");
14756 err = 1;
14757 }
14758
14759 if (err == 0 && GetASNObjectId(o->obj, &idx, &len, o->objSz)) {
14760 WOLFSSL_MSG("Error parsing ASN.1 header.");
14761 err = 1;
14762 }
14763 if (err == 0) {
14764 ret = o->obj + idx;
14765 }
14766
14767 return ret;
14768 }
14769
14770
14771 /* Gets the NID value that corresponds with the ASN1 object.
14772 *
14773 * o ASN1 object to get NID of
14774 *
14775 * Return NID on success and a negative value on failure
14776 */
14777 int wolfSSL_OBJ_obj2nid(const WOLFSSL_ASN1_OBJECT *o)
14778 {
14779 word32 oid = 0;
14780 word32 idx = 0;
14781 int ret;
14782
14783#ifdef WOLFSSL_DEBUG_OPENSSL
14784 WOLFSSL_ENTER("wolfSSL_OBJ_obj2nid");
14785#endif
14786
14787 if (o == NULL) {
14788 return WOLFSSL_FATAL_ERROR;
14789 }
14790
14791 #ifdef WOLFSSL_QT
14792 if (o->grp == oidCertExtType) {
14793 /* If nid is an unknown extension, return WC_NID_undef */
14794 if (wolfSSL_OBJ_nid2sn(o->nid) == NULL)
14795 return WC_NID_undef;
14796 }
14797 #endif
14798
14799 if (o->nid > 0)
14800 return o->nid;
14801 if ((ret = GetObjectId(o->obj, &idx, &oid,
14802 (word32)o->grp, o->objSz)) < 0) {
14803 if (ret == WC_NO_ERR_TRACE(ASN_OBJECT_ID_E)) {
14804 /* Put ASN object tag in front and try again */
14805 int len = SetObjectId((int)o->objSz, NULL) + (int)o->objSz;
14806 byte* buf = (byte*)XMALLOC((size_t)len, NULL,
14807 DYNAMIC_TYPE_TMP_BUFFER);
14808 if (!buf) {
14809 WOLFSSL_MSG("malloc error");
14810 return WOLFSSL_FATAL_ERROR;
14811 }
14812 idx = (word32)SetObjectId((int)o->objSz, buf);
14813 XMEMCPY(buf + idx, o->obj, o->objSz);
14814 idx = 0;
14815 ret = GetObjectId(buf, &idx, &oid, (word32)o->grp, (word32)len);
14816 XFREE(buf, NULL, DYNAMIC_TYPE_TMP_BUFFER);
14817 if (ret < 0) {
14818 WOLFSSL_MSG("Issue getting OID of object");
14819 return WOLFSSL_FATAL_ERROR;
14820 }
14821 }
14822 else {
14823 WOLFSSL_MSG("Issue getting OID of object");
14824 return WOLFSSL_FATAL_ERROR;
14825 }
14826 }
14827
14828 return oid2nid(oid, o->grp);
14829 }
14830
14831 /* Return the corresponding NID for the long name <ln>
14832 * or WC_NID_undef if NID can't be found.
14833 */
14834 int wolfSSL_OBJ_ln2nid(const char *ln)
14835 {
14836 const WOLFSSL_ObjectInfo *obj_info = wolfssl_object_info;
14837 size_t lnlen;
14838 WOLFSSL_ENTER("wolfSSL_OBJ_ln2nid");
14839 if (ln && (lnlen = XSTRLEN(ln)) > 0) {
14840 /* Accept input like "/commonName=" */
14841 if (ln[0] == '/') {
14842 ln++;
14843 lnlen--;
14844 }
14845 if (lnlen) {
14846 size_t i;
14847
14848 if (ln[lnlen-1] == '=') {
14849 lnlen--;
14850 }
14851 for (i = 0; i < WOLFSSL_OBJECT_INFO_SZ; i++, obj_info++) {
14852 if (lnlen == XSTRLEN(obj_info->lName) &&
14853 XSTRNCMP(ln, obj_info->lName, lnlen) == 0) {
14854 return obj_info->nid;
14855 }
14856 }
14857 }
14858 }
14859 return WC_NID_undef;
14860 }
14861
14862 /* compares two objects, return 0 if equal */
14863 int wolfSSL_OBJ_cmp(const WOLFSSL_ASN1_OBJECT* a,
14864 const WOLFSSL_ASN1_OBJECT* b)
14865 {
14866 WOLFSSL_ENTER("wolfSSL_OBJ_cmp");
14867
14868 if (a && b && a->obj && b->obj) {
14869 if (a->objSz == b->objSz) {
14870 return XMEMCMP(a->obj, b->obj, a->objSz);
14871 }
14872 else if (a->type == EXT_KEY_USAGE_OID ||
14873 b->type == EXT_KEY_USAGE_OID) {
14874 /* Special case for EXT_KEY_USAGE_OID so that
14875 * cmp will be treated as a substring search */
14876 /* Used in libest to check for id-kp-cmcRA in
14877 * EXT_KEY_USAGE extension */
14878 unsigned int idx;
14879 const byte* s; /* shorter */
14880 unsigned int sLen;
14881 const byte* l; /* longer */
14882 unsigned int lLen;
14883 if (a->objSz > b->objSz) {
14884 s = b->obj; sLen = b->objSz;
14885 l = a->obj; lLen = a->objSz;
14886 }
14887 else {
14888 s = a->obj; sLen = a->objSz;
14889 l = b->obj; lLen = b->objSz;
14890 }
14891 for (idx = 0; idx <= lLen - sLen; idx++) {
14892 if (XMEMCMP(l + idx, s, sLen) == 0) {
14893 /* Found substring */
14894 return 0;
14895 }
14896 }
14897 }
14898 }
14899
14900 return WOLFSSL_FATAL_ERROR;
14901 }
14902#endif /* OPENSSL_EXTRA, HAVE_LIGHTY, WOLFSSL_MYSQL_COMPATIBLE, HAVE_STUNNEL,
14903 WOLFSSL_NGINX, HAVE_POCO_LIB, WOLFSSL_HAPROXY */
14904#if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL) || \
14905 defined(HAVE_LIGHTY) || defined(WOLFSSL_MYSQL_COMPATIBLE) || \
14906 defined(HAVE_STUNNEL) || defined(WOLFSSL_NGINX) || \
14907 defined(HAVE_POCO_LIB) || defined(WOLFSSL_HAPROXY)
14908 /* Gets the NID value that is related to the OID string passed in. Example
14909 * string would be "2.5.29.14" for subject key ID.
14910 *
14911 * returns NID value on success and WC_NID_undef on error
14912 */
14913 int wolfSSL_OBJ_txt2nid(const char* s)
14914 {
14915 unsigned int i;
14916 #ifdef WOLFSSL_CERT_EXT
14917 int ret;
14918 unsigned int sum = 0;
14919 unsigned int outSz = MAX_OID_SZ;
14920 unsigned char out[MAX_OID_SZ];
14921
14922 XMEMSET(out, 0, sizeof(out));
14923 #endif
14924
14925 WOLFSSL_ENTER("wolfSSL_OBJ_txt2nid");
14926
14927 if (s == NULL) {
14928 return WC_NID_undef;
14929 }
14930
14931 #ifdef WOLFSSL_CERT_EXT
14932 ret = EncodePolicyOID(out, &outSz, s, NULL);
14933 if (ret == 0) {
14934 /* sum OID */
14935 sum = wc_oid_sum(out, outSz);
14936 }
14937 #endif /* WOLFSSL_CERT_EXT */
14938
14939 /* get the group that the OID's sum is in
14940 * @TODO possible conflict with multiples */
14941 for (i = 0; i < WOLFSSL_OBJECT_INFO_SZ; i++) {
14942 int len;
14943 #ifdef WOLFSSL_CERT_EXT
14944 if (ret == 0) {
14945 if (wolfssl_object_info[i].id == (int)sum) {
14946 return wolfssl_object_info[i].nid;
14947 }
14948 }
14949 #endif
14950
14951 /* try as a short name */
14952 len = (int)XSTRLEN(s);
14953 if ((int)XSTRLEN(wolfssl_object_info[i].sName) == len &&
14954 XSTRNCMP(wolfssl_object_info[i].sName, s, (word32)len) == 0) {
14955 return wolfssl_object_info[i].nid;
14956 }
14957
14958 /* try as a long name */
14959 if ((int)XSTRLEN(wolfssl_object_info[i].lName) == len &&
14960 XSTRNCMP(wolfssl_object_info[i].lName, s, (word32)len) == 0) {
14961 return wolfssl_object_info[i].nid;
14962 }
14963 }
14964
14965 return WC_NID_undef;
14966 }
14967#endif
14968#if defined(OPENSSL_EXTRA) || defined(HAVE_LIGHTY) || \
14969 defined(WOLFSSL_MYSQL_COMPATIBLE) || defined(HAVE_STUNNEL) || \
14970 defined(WOLFSSL_NGINX) || defined(HAVE_POCO_LIB) || \
14971 defined(WOLFSSL_HAPROXY)
14972
14973 /* Creates new ASN1_OBJECT from short name, long name, or text
14974 * representation of oid. If no_name is 0, then short name, long name, and
14975 * numerical value of oid are interpreted. If no_name is 1, then only the
14976 * numerical value of the oid is interpreted.
14977 *
14978 * Returns pointer to ASN1_OBJECT on success, or NULL on error.
14979 */
14980#if defined(WOLFSSL_CERT_EXT) && defined(WOLFSSL_CERT_GEN)
14981 WOLFSSL_ASN1_OBJECT* wolfSSL_OBJ_txt2obj(const char* s, int no_name)
14982 {
14983 int i, ret;
14984 int nid = WC_NID_undef;
14985 unsigned int outSz = MAX_OID_SZ;
14986 unsigned char out[MAX_OID_SZ];
14987 WOLFSSL_ASN1_OBJECT* obj;
14988
14989 WOLFSSL_ENTER("wolfSSL_OBJ_txt2obj");
14990
14991 if (s == NULL)
14992 return NULL;
14993
14994 /* If s is numerical value, try to sum oid */
14995 ret = EncodePolicyOID(out, &outSz, s, NULL);
14996 if (ret == 0 && outSz > 0) {
14997 /* If numerical encode succeeded then just
14998 * create object from that because sums are
14999 * not unique and can cause confusion. */
15000 obj = wolfSSL_ASN1_OBJECT_new();
15001 if (obj == NULL) {
15002 WOLFSSL_MSG("Issue creating WOLFSSL_ASN1_OBJECT struct");
15003 return NULL;
15004 }
15005 obj->dynamic |= WOLFSSL_ASN1_DYNAMIC;
15006 obj->obj = (byte*)XMALLOC(1 + MAX_LENGTH_SZ + outSz, NULL,
15007 DYNAMIC_TYPE_ASN1);
15008 if (obj->obj == NULL) {
15009 wolfSSL_ASN1_OBJECT_free(obj);
15010 return NULL;
15011 }
15012 obj->dynamic |= WOLFSSL_ASN1_DYNAMIC_DATA;
15013 i = SetObjectId((int)outSz, (byte*)obj->obj);
15014 XMEMCPY((byte*)obj->obj + i, out, outSz);
15015 obj->objSz = (word32)i + outSz;
15016 return obj;
15017 }
15018
15019 /* TODO: update short names in wolfssl_object_info and check OID sums
15020 are correct */
15021 for (i = 0; i < (int)WOLFSSL_OBJECT_INFO_SZ; i++) {
15022 /* Short name, long name, and numerical value are interpreted */
15023 if (no_name == 0 &&
15024 ((XSTRCMP(s, wolfssl_object_info[i].sName) == 0) ||
15025 (XSTRCMP(s, wolfssl_object_info[i].lName) == 0)))
15026 {
15027 nid = wolfssl_object_info[i].nid;
15028 }
15029 }
15030
15031 if (nid != WC_NID_undef)
15032 return wolfSSL_OBJ_nid2obj(nid);
15033
15034 return NULL;
15035 }
15036#endif
15037
15038 /* compatibility function. Its intended use is to remove OID's from an
15039 * internal table that have been added with OBJ_create. wolfSSL manages its
15040 * own internal OID values and does not currently support OBJ_create. */
15041 void wolfSSL_OBJ_cleanup(void)
15042 {
15043 WOLFSSL_ENTER("wolfSSL_OBJ_cleanup");
15044 }
15045
15046 #ifndef NO_WOLFSSL_STUB
15047 int wolfSSL_OBJ_create(const char *oid, const char *sn, const char *ln)
15048 {
15049 (void)oid;
15050 (void)sn;
15051 (void)ln;
15052 WOLFSSL_STUB("wolfSSL_OBJ_create");
15053 return WOLFSSL_FAILURE;
15054 }
15055 #endif
15056
15057 void wolfSSL_set_verify_depth(WOLFSSL *ssl, int depth)
15058 {
15059 #if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)
15060 WOLFSSL_ENTER("wolfSSL_set_verify_depth");
15061 ssl->options.verifyDepth = (byte)depth;
15062 #endif
15063 }
15064
15065#endif /* OPENSSL_ALL || HAVE_LIGHTY || WOLFSSL_MYSQL_COMPATIBLE ||
15066 HAVE_STUNNEL || WOLFSSL_NGINX || HAVE_POCO_LIB || WOLFSSL_HAPROXY */
15067
15068#ifdef OPENSSL_EXTRA
15069
15070/* wolfSSL uses negative values for error states. This function returns an
15071 * unsigned type so the value returned is the absolute value of the error.
15072 */
15073unsigned long wolfSSL_ERR_peek_last_error_line(const char **file, int *line)
15074{
15075 WOLFSSL_ENTER("wolfSSL_ERR_peek_last_error");
15076
15077 (void)line;
15078 (void)file;
15079#ifdef WOLFSSL_HAVE_ERROR_QUEUE
15080 {
15081 int ret;
15082
15083 if ((ret = wc_PeekErrorNode(-1, file, NULL, line)) < 0) {
15084 WOLFSSL_MSG("Issue peeking at error node in queue");
15085 return 0;
15086 }
15087 #if defined(OPENSSL_ALL) || defined(WOLFSSL_NGINX) \
15088 || defined(WOLFSSL_HAPROXY)
15089 if (ret == -WC_NO_ERR_TRACE(ASN_NO_PEM_HEADER))
15090 return (ERR_LIB_PEM << 24) | PEM_R_NO_START_LINE;
15091 #endif
15092 #if defined(OPENSSL_ALL) && defined(WOLFSSL_PYTHON)
15093 if (ret == ASN1_R_HEADER_TOO_LONG) {
15094 return (ERR_LIB_ASN1 << 24) | ASN1_R_HEADER_TOO_LONG;
15095 }
15096 #endif
15097 return (unsigned long)ret;
15098 }
15099#else
15100 return (unsigned long)(0 - NOT_COMPILED_IN);
15101#endif
15102}
15103
15104#endif /* OPENSSL_EXTRA */
15105
15106#ifdef HAVE_EX_DATA_CRYPTO
15107CRYPTO_EX_cb_ctx* crypto_ex_cb_ctx_session = NULL;
15108
15109static int crypto_ex_cb_new(CRYPTO_EX_cb_ctx** dst, long ctx_l, void* ctx_ptr,
15110 WOLFSSL_CRYPTO_EX_new* new_func, WOLFSSL_CRYPTO_EX_dup* dup_func,
15111 WOLFSSL_CRYPTO_EX_free* free_func)
15112{
15113 CRYPTO_EX_cb_ctx* new_ctx = (CRYPTO_EX_cb_ctx*)XMALLOC(
15114 sizeof(CRYPTO_EX_cb_ctx), NULL, DYNAMIC_TYPE_OPENSSL);
15115 if (new_ctx == NULL)
15116 return WOLFSSL_FATAL_ERROR;
15117 new_ctx->ctx_l = ctx_l;
15118 new_ctx->ctx_ptr = ctx_ptr;
15119 new_ctx->new_func = new_func;
15120 new_ctx->free_func = free_func;
15121 new_ctx->dup_func = dup_func;
15122 new_ctx->next = NULL;
15123 /* Push to end of list */
15124 while (*dst != NULL)
15125 dst = &(*dst)->next;
15126 *dst = new_ctx;
15127 return 0;
15128}
15129
15130void crypto_ex_cb_free(CRYPTO_EX_cb_ctx* cb_ctx)
15131{
15132 while (cb_ctx != NULL) {
15133 CRYPTO_EX_cb_ctx* next = cb_ctx->next;
15134 XFREE(cb_ctx, NULL, DYNAMIC_TYPE_OPENSSL);
15135 cb_ctx = next;
15136 }
15137}
15138
15139void crypto_ex_cb_setup_new_data(void *new_obj, CRYPTO_EX_cb_ctx* cb_ctx,
15140 WOLFSSL_CRYPTO_EX_DATA* ex_data)
15141{
15142 int idx = 0;
15143 for (; cb_ctx != NULL; idx++, cb_ctx = cb_ctx->next) {
15144 if (cb_ctx->new_func != NULL)
15145 cb_ctx->new_func(new_obj, NULL, ex_data, idx, cb_ctx->ctx_l,
15146 cb_ctx->ctx_ptr);
15147 }
15148}
15149
15150int crypto_ex_cb_dup_data(const WOLFSSL_CRYPTO_EX_DATA *in,
15151 WOLFSSL_CRYPTO_EX_DATA *out, CRYPTO_EX_cb_ctx* cb_ctx)
15152{
15153 int idx = 0;
15154 for (; cb_ctx != NULL; idx++, cb_ctx = cb_ctx->next) {
15155 if (cb_ctx->dup_func != NULL) {
15156 void* ptr = wolfSSL_CRYPTO_get_ex_data(in, idx);
15157 if (!cb_ctx->dup_func(out, in,
15158 &ptr, idx,
15159 cb_ctx->ctx_l, cb_ctx->ctx_ptr)) {
15160 return WOLFSSL_FAILURE;
15161 }
15162 wolfSSL_CRYPTO_set_ex_data(out, idx, ptr);
15163 }
15164 }
15165 return WOLFSSL_SUCCESS;
15166}
15167
15168void crypto_ex_cb_free_data(void *obj, CRYPTO_EX_cb_ctx* cb_ctx,
15169 WOLFSSL_CRYPTO_EX_DATA* ex_data)
15170{
15171 int idx = 0;
15172 for (; cb_ctx != NULL; idx++, cb_ctx = cb_ctx->next) {
15173 if (cb_ctx->free_func != NULL)
15174 cb_ctx->free_func(obj, NULL, ex_data, idx, cb_ctx->ctx_l,
15175 cb_ctx->ctx_ptr);
15176 }
15177}
15178
15179/**
15180 * wolfssl_local_get_ex_new_index is a helper function for the following
15181 * xx_get_ex_new_index functions:
15182 * - wolfSSL_CRYPTO_get_ex_new_index
15183 * - wolfSSL_CTX_get_ex_new_index
15184 * - wolfSSL_get_ex_new_index
15185 * Issues a unique index number for the specified class-index.
15186 * Returns an index number greater or equal to zero on success,
15187 * -1 on failure.
15188 */
15189int wolfssl_local_get_ex_new_index(int class_index, long ctx_l, void* ctx_ptr,
15190 WOLFSSL_CRYPTO_EX_new* new_func, WOLFSSL_CRYPTO_EX_dup* dup_func,
15191 WOLFSSL_CRYPTO_EX_free* free_func)
15192{
15193 /* index counter for each class index*/
15194 static int ctx_idx = 0;
15195 static int ssl_idx = 0;
15196 static int ssl_session_idx = 0;
15197 static int x509_idx = 0;
15198
15199 int idx = -1;
15200
15201 switch(class_index) {
15202 case WOLF_CRYPTO_EX_INDEX_SSL:
15203 WOLFSSL_CRYPTO_EX_DATA_IGNORE_PARAMS(ctx_l, ctx_ptr, new_func,
15204 dup_func, free_func);
15205 idx = ssl_idx++;
15206 break;
15207 case WOLF_CRYPTO_EX_INDEX_SSL_CTX:
15208 WOLFSSL_CRYPTO_EX_DATA_IGNORE_PARAMS(ctx_l, ctx_ptr, new_func,
15209 dup_func, free_func);
15210 idx = ctx_idx++;
15211 break;
15212 case WOLF_CRYPTO_EX_INDEX_X509:
15213 WOLFSSL_CRYPTO_EX_DATA_IGNORE_PARAMS(ctx_l, ctx_ptr, new_func,
15214 dup_func, free_func);
15215 idx = x509_idx++;
15216 break;
15217 case WOLF_CRYPTO_EX_INDEX_SSL_SESSION:
15218 if (crypto_ex_cb_new(&crypto_ex_cb_ctx_session, ctx_l, ctx_ptr,
15219 new_func, dup_func, free_func) != 0)
15220 return WOLFSSL_FATAL_ERROR;
15221 idx = ssl_session_idx++;
15222 break;
15223
15224 /* following class indexes are not supoprted */
15225 case WOLF_CRYPTO_EX_INDEX_X509_STORE:
15226 case WOLF_CRYPTO_EX_INDEX_X509_STORE_CTX:
15227 case WOLF_CRYPTO_EX_INDEX_DH:
15228 case WOLF_CRYPTO_EX_INDEX_DSA:
15229 case WOLF_CRYPTO_EX_INDEX_EC_KEY:
15230 case WOLF_CRYPTO_EX_INDEX_RSA:
15231 case WOLF_CRYPTO_EX_INDEX_ENGINE:
15232 case WOLF_CRYPTO_EX_INDEX_UI:
15233 case WOLF_CRYPTO_EX_INDEX_BIO:
15234 case WOLF_CRYPTO_EX_INDEX_APP:
15235 case WOLF_CRYPTO_EX_INDEX_UI_METHOD:
15236 case WOLF_CRYPTO_EX_INDEX_DRBG:
15237 default:
15238 break;
15239 }
15240 if (idx >= MAX_EX_DATA)
15241 return WOLFSSL_FATAL_ERROR;
15242 return idx;
15243}
15244#endif /* HAVE_EX_DATA_CRYPTO */
15245
15246#ifdef HAVE_EX_DATA_CRYPTO
15247int wolfSSL_CTX_get_ex_new_index(long idx, void* arg,
15248 WOLFSSL_CRYPTO_EX_new* new_func,
15249 WOLFSSL_CRYPTO_EX_dup* dup_func,
15250 WOLFSSL_CRYPTO_EX_free* free_func)
15251{
15252
15253 WOLFSSL_ENTER("wolfSSL_CTX_get_ex_new_index");
15254
15255 return wolfssl_local_get_ex_new_index(WOLF_CRYPTO_EX_INDEX_SSL_CTX, idx,
15256 arg, new_func, dup_func, free_func);
15257}
15258
15259/* Return the index that can be used for the WOLFSSL structure to store
15260 * application data.
15261 *
15262 */
15263int wolfSSL_get_ex_new_index(long argValue, void* arg,
15264 WOLFSSL_CRYPTO_EX_new* cb1, WOLFSSL_CRYPTO_EX_dup* cb2,
15265 WOLFSSL_CRYPTO_EX_free* cb3)
15266{
15267 WOLFSSL_ENTER("wolfSSL_get_ex_new_index");
15268
15269 return wolfssl_local_get_ex_new_index(WOLF_CRYPTO_EX_INDEX_SSL, argValue,
15270 arg, cb1, cb2, cb3);
15271}
15272#endif /* HAVE_EX_DATA_CRYPTO */
15273
15274#ifdef OPENSSL_EXTRA
15275void* wolfSSL_CTX_get_ex_data(const WOLFSSL_CTX* ctx, int idx)
15276{
15277 WOLFSSL_ENTER("wolfSSL_CTX_get_ex_data");
15278#ifdef HAVE_EX_DATA
15279 if (ctx != NULL) {
15280 return wolfSSL_CRYPTO_get_ex_data(&ctx->ex_data, idx);
15281 }
15282#else
15283 (void)ctx;
15284 (void)idx;
15285#endif
15286 return NULL;
15287}
15288
15289int wolfSSL_CTX_set_ex_data(WOLFSSL_CTX* ctx, int idx, void* data)
15290{
15291 WOLFSSL_ENTER("wolfSSL_CTX_set_ex_data");
15292#ifdef HAVE_EX_DATA
15293 if (ctx != NULL) {
15294 return wolfSSL_CRYPTO_set_ex_data(&ctx->ex_data, idx, data);
15295 }
15296#else
15297 (void)ctx;
15298 (void)idx;
15299 (void)data;
15300#endif
15301 return WOLFSSL_FAILURE;
15302}
15303
15304#ifdef HAVE_EX_DATA_CLEANUP_HOOKS
15305int wolfSSL_CTX_set_ex_data_with_cleanup(
15306 WOLFSSL_CTX* ctx,
15307 int idx,
15308 void* data,
15309 wolfSSL_ex_data_cleanup_routine_t cleanup_routine)
15310{
15311 WOLFSSL_ENTER("wolfSSL_CTX_set_ex_data_with_cleanup");
15312 if (ctx != NULL) {
15313 return wolfSSL_CRYPTO_set_ex_data_with_cleanup(&ctx->ex_data, idx, data,
15314 cleanup_routine);
15315 }
15316 return WOLFSSL_FAILURE;
15317}
15318#endif /* HAVE_EX_DATA_CLEANUP_HOOKS */
15319#endif /* OPENSSL_EXTRA */
15320
15321#if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)
15322
15323/* Returns char* to app data stored in ex[0].
15324 *
15325 * ssl WOLFSSL structure to get app data from
15326 */
15327void* wolfSSL_get_app_data(const WOLFSSL *ssl)
15328{
15329 /* checkout exdata stuff... */
15330 WOLFSSL_ENTER("wolfSSL_get_app_data");
15331
15332 return wolfSSL_get_ex_data(ssl, 0);
15333}
15334
15335
15336/* Set ex array 0 to have app data
15337 *
15338 * ssl WOLFSSL struct to set app data in
15339 * arg data to be stored
15340 *
15341 * Returns WOLFSSL_SUCCESS on success and WOLFSSL_FAILURE on failure
15342 */
15343int wolfSSL_set_app_data(WOLFSSL *ssl, void* arg) {
15344 WOLFSSL_ENTER("wolfSSL_set_app_data");
15345
15346 return wolfSSL_set_ex_data(ssl, 0, arg);
15347}
15348
15349#endif /* OPENSSL_EXTRA || OPENSSL_EXTRA_X509_SMALL */
15350
15351int wolfSSL_set_ex_data(WOLFSSL* ssl, int idx, void* data)
15352{
15353 WOLFSSL_ENTER("wolfSSL_set_ex_data");
15354#ifdef HAVE_EX_DATA
15355 if (ssl != NULL) {
15356 return wolfSSL_CRYPTO_set_ex_data(&ssl->ex_data, idx, data);
15357 }
15358#else
15359 WOLFSSL_MSG("HAVE_EX_DATA macro is not defined");
15360 (void)ssl;
15361 (void)idx;
15362 (void)data;
15363#endif
15364 return WOLFSSL_FAILURE;
15365}
15366
15367#ifdef HAVE_EX_DATA_CLEANUP_HOOKS
15368int wolfSSL_set_ex_data_with_cleanup(
15369 WOLFSSL* ssl,
15370 int idx,
15371 void* data,
15372 wolfSSL_ex_data_cleanup_routine_t cleanup_routine)
15373{
15374 WOLFSSL_ENTER("wolfSSL_set_ex_data_with_cleanup");
15375 if (ssl != NULL)
15376 {
15377 return wolfSSL_CRYPTO_set_ex_data_with_cleanup(&ssl->ex_data, idx, data,
15378 cleanup_routine);
15379 }
15380 return WOLFSSL_FAILURE;
15381}
15382#endif /* HAVE_EX_DATA_CLEANUP_HOOKS */
15383
15384void* wolfSSL_get_ex_data(const WOLFSSL* ssl, int idx)
15385{
15386 WOLFSSL_ENTER("wolfSSL_get_ex_data");
15387#ifdef HAVE_EX_DATA
15388 if (ssl != NULL) {
15389 return wolfSSL_CRYPTO_get_ex_data(&ssl->ex_data, idx);
15390 }
15391#else
15392 WOLFSSL_MSG("HAVE_EX_DATA macro is not defined");
15393 (void)ssl;
15394 (void)idx;
15395#endif
15396 return 0;
15397}
15398
15399#if defined(HAVE_LIGHTY) || defined(HAVE_STUNNEL) \
15400 || defined(WOLFSSL_MYSQL_COMPATIBLE) || defined(OPENSSL_EXTRA)
15401
15402/* returns the enum value associated with handshake state
15403 *
15404 * ssl the WOLFSSL structure to get state of
15405 */
15406int wolfSSL_get_state(const WOLFSSL* ssl)
15407{
15408 WOLFSSL_ENTER("wolfSSL_get_state");
15409
15410 if (ssl == NULL) {
15411 WOLFSSL_MSG("Null argument passed in");
15412 return WOLFSSL_FAILURE;
15413 }
15414
15415 return ssl->options.handShakeState;
15416}
15417#endif /* HAVE_LIGHTY || HAVE_STUNNEL || WOLFSSL_MYSQL_COMPATIBLE */
15418
15419#ifdef OPENSSL_EXTRA
15420void wolfSSL_certs_clear(WOLFSSL* ssl)
15421{
15422 WOLFSSL_ENTER("wolfSSL_certs_clear");
15423
15424 if (ssl == NULL)
15425 return;
15426
15427 /* ctx still owns certificate, certChain, key, dh, and cm */
15428 if (ssl->buffers.weOwnCert) {
15429 FreeDer(&ssl->buffers.certificate);
15430 ssl->buffers.weOwnCert = 0;
15431 }
15432 ssl->buffers.certificate = NULL;
15433 if (ssl->buffers.weOwnCertChain) {
15434 FreeDer(&ssl->buffers.certChain);
15435 ssl->buffers.weOwnCertChain = 0;
15436 }
15437 ssl->buffers.certChain = NULL;
15438#ifdef WOLFSSL_TLS13
15439 ssl->buffers.certChainCnt = 0;
15440#endif
15441 if (ssl->buffers.weOwnKey) {
15442 FreeDer(&ssl->buffers.key);
15443 #ifdef WOLFSSL_BLIND_PRIVATE_KEY
15444 FreeDer(&ssl->buffers.keyMask);
15445 #endif
15446 ssl->buffers.weOwnKey = 0;
15447 }
15448 ssl->buffers.key = NULL;
15449#ifdef WOLFSSL_BLIND_PRIVATE_KEY
15450 ssl->buffers.keyMask = NULL;
15451#endif
15452 ssl->buffers.keyType = 0;
15453 ssl->buffers.keyId = 0;
15454 ssl->buffers.keyLabel = 0;
15455 ssl->buffers.keySz = 0;
15456 ssl->buffers.keyDevId = 0;
15457#ifdef WOLFSSL_DUAL_ALG_CERTS
15458 if (ssl->buffers.weOwnAltKey) {
15459 FreeDer(&ssl->buffers.altKey);
15460 #ifdef WOLFSSL_BLIND_PRIVATE_KEY
15461 FreeDer(&ssl->buffers.altKeyMask);
15462 #endif
15463 ssl->buffers.weOwnAltKey = 0;
15464 }
15465 ssl->buffers.altKey = NULL;
15466#ifdef WOLFSSL_BLIND_PRIVATE_KEY
15467 ssl->buffers.altKeyMask = NULL;
15468#endif
15469#endif /* WOLFSSL_DUAL_ALG_CERTS */
15470}
15471#endif
15472
15473#if defined(OPENSSL_ALL) || defined(WOLFSSL_ASIO) || defined(WOLFSSL_HAPROXY) \
15474 || defined(WOLFSSL_NGINX) || defined(WOLFSSL_QT)
15475
15476long wolfSSL_ctrl(WOLFSSL* ssl, int cmd, long opt, void* pt)
15477{
15478 WOLFSSL_ENTER("wolfSSL_ctrl");
15479 if (ssl == NULL)
15480 return BAD_FUNC_ARG;
15481
15482 switch (cmd) {
15483 #if defined(WOLFSSL_NGINX) || defined(WOLFSSL_QT) || \
15484 defined(OPENSSL_ALL)
15485 #ifdef HAVE_SNI
15486 case SSL_CTRL_SET_TLSEXT_HOSTNAME:
15487 WOLFSSL_MSG("Entering Case: SSL_CTRL_SET_TLSEXT_HOSTNAME.");
15488 if (pt == NULL) {
15489 WOLFSSL_MSG("Passed in NULL Host Name.");
15490 break;
15491 }
15492 return wolfSSL_set_tlsext_host_name(ssl, (const char*) pt);
15493 #endif /* HAVE_SNI */
15494 #endif /* WOLFSSL_NGINX || WOLFSSL_QT || OPENSSL_ALL */
15495 default:
15496 WOLFSSL_MSG("Case not implemented.");
15497 }
15498 (void)opt;
15499 (void)pt;
15500 return WOLFSSL_FAILURE;
15501}
15502
15503long wolfSSL_CTX_ctrl(WOLFSSL_CTX* ctx, int cmd, long opt, void* pt)
15504{
15505#if defined(OPENSSL_EXTRA) || defined(HAVE_WEBSERVER)
15506 long ctrl_opt;
15507#endif
15508 long ret = WOLFSSL_SUCCESS;
15509
15510 WOLFSSL_ENTER("wolfSSL_CTX_ctrl");
15511 if (ctx == NULL)
15512 return WOLFSSL_FAILURE;
15513
15514 switch (cmd) {
15515 case SSL_CTRL_CHAIN:
15516#ifdef SESSION_CERTS
15517 {
15518 /*
15519 * We don't care about opt here because a copy of the certificate is
15520 * stored anyway so increasing the reference counter is not necessary.
15521 * Just check to make sure that it is set to one of the correct values.
15522 */
15523 WOLF_STACK_OF(WOLFSSL_X509)* sk = (WOLF_STACK_OF(WOLFSSL_X509)*) pt;
15524 WOLFSSL_X509* x509;
15525 int i;
15526 if (opt != 0 && opt != 1) {
15527 ret = WOLFSSL_FAILURE;
15528 break;
15529 }
15530 /* Clear certificate chain */
15531 FreeDer(&ctx->certChain);
15532 if (sk) {
15533 for (i = 0; i < wolfSSL_sk_X509_num(sk); i++) {
15534 x509 = wolfSSL_sk_X509_value(sk, i);
15535 /* Prevent wolfSSL_CTX_add_extra_chain_cert from freeing cert */
15536 if (wolfSSL_X509_up_ref(x509) != 1) {
15537 WOLFSSL_MSG("Error increasing reference count");
15538 continue;
15539 }
15540 if (wolfSSL_CTX_add_extra_chain_cert(ctx, x509) !=
15541 WOLFSSL_SUCCESS) {
15542 WOLFSSL_MSG("Error adding certificate to context");
15543 /* Decrease reference count on failure */
15544 wolfSSL_X509_free(x509);
15545 x509 = NULL;
15546 }
15547 }
15548 }
15549 /* Free previous chain */
15550 wolfSSL_sk_X509_pop_free(ctx->x509Chain, NULL);
15551 ctx->x509Chain = sk;
15552 if (sk && opt == 1) {
15553 /* up all refs when opt == 1 */
15554 for (i = 0; i < wolfSSL_sk_X509_num(sk); i++) {
15555 x509 = wolfSSL_sk_X509_value(sk, i);
15556 if (wolfSSL_X509_up_ref(x509) != 1) {
15557 WOLFSSL_MSG("Error increasing reference count");
15558 continue;
15559 }
15560 }
15561 }
15562 }
15563#else
15564 WOLFSSL_MSG("Session certificates not compiled in");
15565 ret = WOLFSSL_FAILURE;
15566#endif
15567 break;
15568
15569#if defined(OPENSSL_EXTRA) || defined(HAVE_WEBSERVER)
15570 case SSL_CTRL_OPTIONS:
15571 WOLFSSL_MSG("Entering Case: SSL_CTRL_OPTIONS.");
15572 ctrl_opt = wolfSSL_CTX_set_options(ctx, opt);
15573
15574 #ifdef WOLFSSL_QT
15575 /* Set whether to use client or server cipher preference */
15576 if ((ctrl_opt & WOLFSSL_OP_CIPHER_SERVER_PREFERENCE)
15577 == WOLFSSL_OP_CIPHER_SERVER_PREFERENCE) {
15578 WOLFSSL_MSG("Using Server's Cipher Preference.");
15579 ctx->useClientOrder = 0;
15580 } else {
15581 WOLFSSL_MSG("Using Client's Cipher Preference.");
15582 ctx->useClientOrder = 1;
15583 }
15584 #endif /* WOLFSSL_QT */
15585
15586 return ctrl_opt;
15587#endif /* OPENSSL_EXTRA || HAVE_WEBSERVER */
15588 case SSL_CTRL_EXTRA_CHAIN_CERT:
15589 WOLFSSL_MSG("Entering Case: SSL_CTRL_EXTRA_CHAIN_CERT.");
15590 if (pt == NULL) {
15591 WOLFSSL_MSG("Passed in x509 pointer NULL.");
15592 ret = WOLFSSL_FAILURE;
15593 break;
15594 }
15595 return wolfSSL_CTX_add_extra_chain_cert(ctx, (WOLFSSL_X509*)pt);
15596
15597#ifndef NO_DH
15598 case SSL_CTRL_SET_TMP_DH:
15599 WOLFSSL_MSG("Entering Case: SSL_CTRL_SET_TMP_DH.");
15600 if (pt == NULL) {
15601 WOLFSSL_MSG("Passed in DH pointer NULL.");
15602 ret = WOLFSSL_FAILURE;
15603 break;
15604 }
15605 return wolfSSL_CTX_set_tmp_dh(ctx, (WOLFSSL_DH*)pt);
15606#endif
15607
15608#ifdef HAVE_ECC
15609 case SSL_CTRL_SET_TMP_ECDH:
15610 WOLFSSL_MSG("Entering Case: SSL_CTRL_SET_TMP_ECDH.");
15611 if (pt == NULL) {
15612 WOLFSSL_MSG("Passed in ECDH pointer NULL.");
15613 ret = WOLFSSL_FAILURE;
15614 break;
15615 }
15616 return wolfSSL_SSL_CTX_set_tmp_ecdh(ctx, (WOLFSSL_EC_KEY*)pt);
15617#endif
15618 case SSL_CTRL_MODE:
15619 wolfSSL_CTX_set_mode(ctx,opt);
15620 break;
15621 case SSL_CTRL_SET_MIN_PROTO_VERSION:
15622 WOLFSSL_MSG("set min proto version");
15623 return wolfSSL_CTX_set_min_proto_version(ctx, (int)opt);
15624 case SSL_CTRL_SET_MAX_PROTO_VERSION:
15625 WOLFSSL_MSG("set max proto version");
15626 return wolfSSL_CTX_set_max_proto_version(ctx, (int)opt);
15627 case SSL_CTRL_GET_MIN_PROTO_VERSION:
15628 WOLFSSL_MSG("get min proto version");
15629 return wolfSSL_CTX_get_min_proto_version(ctx);
15630 case SSL_CTRL_GET_MAX_PROTO_VERSION:
15631 WOLFSSL_MSG("get max proto version");
15632 return wolfSSL_CTX_get_max_proto_version(ctx);
15633 default:
15634 WOLFSSL_MSG("CTX_ctrl cmd not implemented");
15635 ret = WOLFSSL_FAILURE;
15636 break;
15637 }
15638
15639 (void)ctx;
15640 (void)cmd;
15641 (void)opt;
15642 (void)pt;
15643 WOLFSSL_LEAVE("wolfSSL_CTX_ctrl", (int)ret);
15644 return ret;
15645}
15646
15647#ifndef NO_WOLFSSL_STUB
15648long wolfSSL_CTX_callback_ctrl(WOLFSSL_CTX* ctx, int cmd, void (*fp)(void))
15649{
15650 (void) ctx;
15651 (void) cmd;
15652 (void) fp;
15653 WOLFSSL_STUB("wolfSSL_CTX_callback_ctrl");
15654 return WOLFSSL_FAILURE;
15655
15656}
15657#endif /* NO_WOLFSSL_STUB */
15658
15659#ifndef NO_WOLFSSL_STUB
15660long wolfSSL_CTX_clear_extra_chain_certs(WOLFSSL_CTX* ctx)
15661{
15662 return wolfSSL_CTX_ctrl(ctx, SSL_CTRL_CLEAR_EXTRA_CHAIN_CERTS, 0L, NULL);
15663}
15664#endif
15665
15666/* Returns the verifyCallback from the ssl structure if successful.
15667Returns NULL otherwise. */
15668VerifyCallback wolfSSL_get_verify_callback(WOLFSSL* ssl)
15669{
15670 WOLFSSL_ENTER("wolfSSL_get_verify_callback");
15671 if (ssl) {
15672 return ssl->verifyCallback;
15673 }
15674 return NULL;
15675}
15676
15677#endif /* OPENSSL_ALL || WOLFSSL_ASIO || WOLFSSL_HAPROXY || WOLFSSL_QT */
15678
15679
15680/* stunnel compatibility functions*/
15681#if defined(OPENSSL_ALL) || (defined(OPENSSL_EXTRA) && \
15682 (defined(HAVE_STUNNEL) || defined(WOLFSSL_NGINX) || \
15683 defined(HAVE_LIGHTY) || defined(WOLFSSL_HAPROXY) || \
15684 defined(WOLFSSL_OPENSSH)))
15685void wolfSSL_ERR_remove_thread_state(void* pid)
15686{
15687 (void) pid;
15688 return;
15689}
15690
15691#ifndef NO_FILESYSTEM
15692/***TBD ***/
15693void wolfSSL_print_all_errors_fp(XFILE fp)
15694{
15695 (void)fp;
15696}
15697#endif /* !NO_FILESYSTEM */
15698
15699#endif /* OPENSSL_ALL || OPENSSL_EXTRA || HAVE_STUNNEL || WOLFSSL_NGINX ||
15700 HAVE_LIGHTY || WOLFSSL_HAPROXY || WOLFSSL_OPENSSH */
15701
15702/* Note: This is a huge section of API's - through
15703 * wolfSSL_X509_OBJECT_get0_X509_CRL */
15704#if defined(OPENSSL_ALL) || defined(OPENSSL_EXTRA)
15705
15706#if defined(USE_WOLFSSL_MEMORY) && !defined(WOLFSSL_DEBUG_MEMORY) && \
15707 !defined(WOLFSSL_STATIC_MEMORY)
15708static wolfSSL_OSSL_Malloc_cb ossl_malloc = NULL;
15709static wolfSSL_OSSL_Free_cb ossl_free = NULL;
15710static wolfSSL_OSSL_Realloc_cb ossl_realloc = NULL;
15711
15712static void* OSSL_Malloc(size_t size)
15713{
15714 if (ossl_malloc != NULL)
15715 return ossl_malloc(size, NULL, 0);
15716 else
15717 return NULL;
15718}
15719
15720static void OSSL_Free(void *ptr)
15721{
15722 if (ossl_free != NULL)
15723 ossl_free(ptr, NULL, 0);
15724}
15725
15726static void* OSSL_Realloc(void *ptr, size_t size)
15727{
15728 if (ossl_realloc != NULL)
15729 return ossl_realloc(ptr, size, NULL, 0);
15730 else
15731 return NULL;
15732}
15733#endif /* USE_WOLFSSL_MEMORY && !WOLFSSL_DEBUG_MEMORY &&
15734 * !WOLFSSL_STATIC_MEMORY */
15735
15736int wolfSSL_CRYPTO_set_mem_functions(
15737 wolfSSL_OSSL_Malloc_cb m,
15738 wolfSSL_OSSL_Realloc_cb r,
15739 wolfSSL_OSSL_Free_cb f)
15740{
15741#if defined(USE_WOLFSSL_MEMORY) && !defined(WOLFSSL_STATIC_MEMORY)
15742#ifdef WOLFSSL_DEBUG_MEMORY
15743 WOLFSSL_MSG("mem functions will receive function name instead of "
15744 "file name");
15745 if (wolfSSL_SetAllocators((wolfSSL_Malloc_cb)m, (wolfSSL_Free_cb)f,
15746 (wolfSSL_Realloc_cb)r) == 0)
15747 return WOLFSSL_SUCCESS;
15748#else
15749 WOLFSSL_MSG("wolfSSL was compiled without WOLFSSL_DEBUG_MEMORY mem "
15750 "functions will receive a NULL file name and 0 for the "
15751 "line number.");
15752 if (wolfSSL_SetAllocators((wolfSSL_Malloc_cb)OSSL_Malloc,
15753 (wolfSSL_Free_cb)OSSL_Free, (wolfSSL_Realloc_cb)OSSL_Realloc) == 0) {
15754 ossl_malloc = m;
15755 ossl_free = f;
15756 ossl_realloc = r;
15757 return WOLFSSL_SUCCESS;
15758 }
15759#endif
15760 else
15761 return WOLFSSL_FAILURE;
15762#else
15763 (void)m;
15764 (void)r;
15765 (void)f;
15766 WOLFSSL_MSG("wolfSSL allocator callback functions not compiled in");
15767 return WOLFSSL_FAILURE;
15768#endif
15769}
15770
15771int wolfSSL_ERR_load_ERR_strings(void)
15772{
15773 return WOLFSSL_SUCCESS;
15774}
15775
15776void wolfSSL_ERR_load_crypto_strings(void)
15777{
15778 WOLFSSL_ENTER("wolfSSL_ERR_load_crypto_strings");
15779 /* Do nothing */
15780 return;
15781}
15782
15783int wolfSSL_FIPS_mode(void)
15784{
15785#ifdef HAVE_FIPS
15786 return 1;
15787#else
15788 return 0;
15789#endif
15790}
15791
15792int wolfSSL_FIPS_mode_set(int r)
15793{
15794#ifdef HAVE_FIPS
15795 if (r == 0) {
15796 WOLFSSL_MSG("Cannot disable FIPS at runtime.");
15797 return WOLFSSL_FAILURE;
15798 }
15799 return WOLFSSL_SUCCESS;
15800#else
15801 if (r == 0) {
15802 return WOLFSSL_SUCCESS;
15803 }
15804 WOLFSSL_MSG("Cannot enable FIPS. This isn't the wolfSSL FIPS code.");
15805 return WOLFSSL_FAILURE;
15806#endif
15807}
15808
15809int wolfSSL_CIPHER_get_bits(const WOLFSSL_CIPHER *c, int *alg_bits)
15810{
15811 int ret = WC_NO_ERR_TRACE(WOLFSSL_FAILURE);
15812 WOLFSSL_ENTER("wolfSSL_CIPHER_get_bits");
15813
15814 #if defined(WOLFSSL_QT) || defined(OPENSSL_ALL)
15815 (void)alg_bits;
15816 if (c!= NULL)
15817 ret = c->bits;
15818 #else
15819 if (c != NULL && c->ssl != NULL) {
15820 ret = 8 * c->ssl->specs.key_size;
15821 if (alg_bits != NULL) {
15822 *alg_bits = ret;
15823 }
15824 }
15825 #endif
15826 return ret;
15827}
15828
15829#ifdef HAVE_SNI
15830int wolfSSL_set_tlsext_host_name(WOLFSSL* ssl, const char* host_name)
15831{
15832 int ret;
15833 WOLFSSL_ENTER("wolfSSL_set_tlsext_host_name");
15834 ret = wolfSSL_UseSNI(ssl, WOLFSSL_SNI_HOST_NAME,
15835 host_name, (word16)XSTRLEN(host_name));
15836 WOLFSSL_LEAVE("wolfSSL_set_tlsext_host_name", ret);
15837 return ret;
15838}
15839
15840#ifndef NO_WOLFSSL_SERVER
15841/* May be called by server to get the requested accepted name and by the client
15842 * to get the requested name. */
15843const char * wolfSSL_get_servername(WOLFSSL* ssl, byte type)
15844{
15845 void * serverName = NULL;
15846 if (ssl == NULL)
15847 return NULL;
15848 TLSX_SNI_GetRequest(ssl->extensions, type, &serverName,
15849 !wolfSSL_is_server(ssl));
15850 return (const char *)serverName;
15851}
15852#endif
15853
15854#endif /* HAVE_SNI */
15855
15856WOLFSSL_CTX* wolfSSL_set_SSL_CTX(WOLFSSL* ssl, WOLFSSL_CTX* ctx)
15857{
15858 int ret;
15859 /* This method requires some explanation. Its sibling is
15860 * int SetSSL_CTX(WOLFSSL* ssl, WOLFSSL_CTX* ctx, int writeDup)
15861 * which re-inits the WOLFSSL* with all settings in the new CTX.
15862 * That one is the right one to use *before* a handshake is started.
15863 *
15864 * This method was added by OpenSSL to be used *during* the handshake, e.g.
15865 * when a server inspects the SNI in a ClientHello callback and
15866 * decides which set of certificates to use.
15867 *
15868 * Since, at the time the SNI callback is run, some decisions on
15869 * Extensions or the ServerHello might already have been taken, this
15870 * method is very restricted in what it does:
15871 * - changing the server certificate(s)
15872 * - changing the server id for session handling
15873 * and everything else in WOLFSSL* needs to remain untouched.
15874 */
15875 WOLFSSL_ENTER("wolfSSL_set_SSL_CTX");
15876 if (ssl == NULL || ctx == NULL)
15877 return NULL;
15878 if (ssl->ctx == ctx)
15879 return ssl->ctx;
15880
15881 if (ctx->suites == NULL) {
15882 /* suites */
15883 if (AllocateCtxSuites(ctx) != 0)
15884 return NULL;
15885 InitSSL_CTX_Suites(ctx);
15886 }
15887
15888 wolfSSL_RefWithMutexInc(&ctx->ref, &ret);
15889#ifdef WOLFSSL_REFCNT_ERROR_RETURN
15890 if (ret != 0) {
15891 /* can only fail on serious stuff, like mutex not working
15892 * or ctx refcount out of whack. */
15893 return NULL;
15894 }
15895#else
15896 (void)ret;
15897#endif
15898 if (ssl->ctx != NULL)
15899 wolfSSL_CTX_free(ssl->ctx);
15900 ssl->ctx = ctx;
15901
15902#ifndef NO_CERTS
15903#ifdef WOLFSSL_COPY_CERT
15904 /* If WOLFSSL_COPY_CERT defined, always make new copy of cert from ctx */
15905 if (ctx->certificate != NULL) {
15906 if (ssl->buffers.certificate != NULL) {
15907 FreeDer(&ssl->buffers.certificate);
15908 ssl->buffers.certificate = NULL;
15909 }
15910 ret = AllocCopyDer(&ssl->buffers.certificate, ctx->certificate->buffer,
15911 ctx->certificate->length, ctx->certificate->type,
15912 ctx->certificate->heap);
15913 if (ret != 0) {
15914 ssl->buffers.weOwnCert = 0;
15915 return NULL;
15916 }
15917
15918 ssl->buffers.weOwnCert = 1;
15919 }
15920 if (ctx->certChain != NULL) {
15921 if (ssl->buffers.certChain != NULL) {
15922 FreeDer(&ssl->buffers.certChain);
15923 ssl->buffers.certChain = NULL;
15924 }
15925 ret = AllocCopyDer(&ssl->buffers.certChain, ctx->certChain->buffer,
15926 ctx->certChain->length, ctx->certChain->type,
15927 ctx->certChain->heap);
15928 if (ret != 0) {
15929 ssl->buffers.weOwnCertChain = 0;
15930 return NULL;
15931 }
15932
15933 ssl->buffers.weOwnCertChain = 1;
15934 }
15935#else
15936 /* ctx owns certificate, certChain and key */
15937 ssl->buffers.certificate = ctx->certificate;
15938 ssl->buffers.certChain = ctx->certChain;
15939#endif
15940#ifdef WOLFSSL_TLS13
15941 ssl->buffers.certChainCnt = ctx->certChainCnt;
15942#endif
15943#ifndef WOLFSSL_BLIND_PRIVATE_KEY
15944#ifdef WOLFSSL_COPY_KEY
15945 if (ssl->buffers.key != NULL && ssl->buffers.weOwnKey) {
15946 FreeDer(&ssl->buffers.key);
15947 }
15948 if (ctx->privateKey != NULL) {
15949 ret = AllocCopyDer(&ssl->buffers.key, ctx->privateKey->buffer,
15950 ctx->privateKey->length, ctx->privateKey->type,
15951 ctx->privateKey->heap);
15952 if (ret != 0) {
15953 ssl->buffers.weOwnKey = 0;
15954 return NULL;
15955 }
15956 ssl->buffers.weOwnKey = 1;
15957 }
15958 else {
15959 ssl->buffers.key = ctx->privateKey;
15960 }
15961#else
15962 ssl->buffers.key = ctx->privateKey;
15963#endif
15964#else
15965 if (ctx->privateKey != NULL) {
15966 ret = AllocCopyDer(&ssl->buffers.key, ctx->privateKey->buffer,
15967 ctx->privateKey->length, ctx->privateKey->type,
15968 ctx->privateKey->heap);
15969 if (ret != 0) {
15970 return NULL;
15971 }
15972 /* Blind the private key for the SSL with new random mask. */
15973 wolfssl_priv_der_blind_toggle(ssl->buffers.key, ctx->privateKeyMask);
15974 ret = wolfssl_priv_der_blind(ssl->rng, ssl->buffers.key,
15975 &ssl->buffers.keyMask);
15976 if (ret != 0) {
15977 return NULL;
15978 }
15979 }
15980#endif
15981 ssl->buffers.keyType = ctx->privateKeyType;
15982 ssl->buffers.keyId = ctx->privateKeyId;
15983 ssl->buffers.keyLabel = ctx->privateKeyLabel;
15984 ssl->buffers.keySz = ctx->privateKeySz;
15985 ssl->buffers.keyDevId = ctx->privateKeyDevId;
15986 /* flags indicating what certs/keys are available */
15987 ssl->options.haveRSA = ctx->haveRSA;
15988 ssl->options.haveDH = ctx->haveDH;
15989 ssl->options.haveECDSAsig = ctx->haveECDSAsig;
15990 ssl->options.haveECC = ctx->haveECC;
15991 ssl->options.haveStaticECC = ctx->haveStaticECC;
15992 ssl->options.haveFalconSig = ctx->haveFalconSig;
15993 ssl->options.haveDilithiumSig = ctx->haveDilithiumSig;
15994#ifdef WOLFSSL_DUAL_ALG_CERTS
15995#ifndef WOLFSSL_BLIND_PRIVATE_KEY
15996 ssl->buffers.altKey = ctx->altPrivateKey;
15997#else
15998 if (ctx->altPrivateKey != NULL) {
15999 ret = AllocCopyDer(&ssl->buffers.altKey, ctx->altPrivateKey->buffer,
16000 ctx->altPrivateKey->length, ctx->altPrivateKey->type,
16001 ctx->altPrivateKey->heap);
16002 if (ret != 0) {
16003 return NULL;
16004 }
16005 /* Blind the private key for the SSL with new random mask. */
16006 wolfssl_priv_der_blind_toggle(ssl->buffers.altKey,
16007 ctx->altPrivateKeyMask);
16008 ret = wolfssl_priv_der_blind(ssl->rng, ssl->buffers.altKey,
16009 &ssl->buffers.altKeyMask);
16010 if (ret != 0) {
16011 return NULL;
16012 }
16013 }
16014#endif
16015 ssl->buffers.altKeySz = ctx->altPrivateKeySz;
16016 ssl->buffers.altKeyType = ctx->altPrivateKeyType;
16017#endif /* WOLFSSL_DUAL_ALG_CERTS */
16018#endif
16019
16020#ifdef WOLFSSL_SESSION_ID_CTX
16021 /* copy over application session context ID */
16022 ssl->sessionCtxSz = ctx->sessionCtxSz;
16023 XMEMCPY(ssl->sessionCtx, ctx->sessionCtx, ctx->sessionCtxSz);
16024#endif
16025
16026 return ssl->ctx;
16027}
16028
16029
16030VerifyCallback wolfSSL_CTX_get_verify_callback(WOLFSSL_CTX* ctx)
16031{
16032 WOLFSSL_ENTER("wolfSSL_CTX_get_verify_callback");
16033 if(ctx)
16034 return ctx->verifyCallback;
16035 return NULL;
16036}
16037
16038#ifdef HAVE_SNI
16039/* this is a compatibility function, consider using
16040 * wolfSSL_CTX_set_servername_callback */
16041int wolfSSL_CTX_set_tlsext_servername_callback(WOLFSSL_CTX* ctx,
16042 CallbackSniRecv cb)
16043{
16044 WOLFSSL_ENTER("wolfSSL_CTX_set_tlsext_servername_callback");
16045 if (ctx) {
16046 ctx->sniRecvCb = cb;
16047 return WOLFSSL_SUCCESS;
16048 }
16049 return WOLFSSL_FAILURE;
16050}
16051
16052#endif /* HAVE_SNI */
16053
16054#ifndef NO_BIO
16055void wolfSSL_ERR_load_BIO_strings(void) {
16056 WOLFSSL_ENTER("wolfSSL_ERR_load_BIO_strings");
16057 /* do nothing */
16058}
16059#endif
16060
16061#ifndef NO_WOLFSSL_STUB
16062/* Set THREADID callback, return 1 on success, 0 on error */
16063int wolfSSL_THREADID_set_callback(
16064 void(*threadid_func)(WOLFSSL_CRYPTO_THREADID*))
16065{
16066 WOLFSSL_ENTER("wolfSSL_THREADID_set_callback");
16067 WOLFSSL_STUB("CRYPTO_THREADID_set_callback");
16068 (void)threadid_func;
16069 return 1;
16070}
16071#endif
16072
16073#ifndef NO_WOLFSSL_STUB
16074void wolfSSL_THREADID_set_numeric(void* id, unsigned long val)
16075{
16076 WOLFSSL_ENTER("wolfSSL_THREADID_set_numeric");
16077 WOLFSSL_STUB("CRYPTO_THREADID_set_numeric");
16078 (void)id;
16079 (void)val;
16080 return;
16081}
16082#endif
16083
16084#endif /* OPENSSL_ALL || OPENSSL_EXTRA */
16085
16086#ifdef HAVE_SNI
16087
16088void wolfSSL_CTX_set_servername_callback(WOLFSSL_CTX* ctx, CallbackSniRecv cb)
16089{
16090 WOLFSSL_ENTER("wolfSSL_CTX_set_servername_callback");
16091 if (ctx)
16092 ctx->sniRecvCb = cb;
16093}
16094
16095
16096int wolfSSL_CTX_set_servername_arg(WOLFSSL_CTX* ctx, void* arg)
16097{
16098 WOLFSSL_ENTER("wolfSSL_CTX_set_servername_arg");
16099 if (ctx) {
16100 ctx->sniRecvCbArg = arg;
16101 return WOLFSSL_SUCCESS;
16102 }
16103 return WOLFSSL_FAILURE;
16104}
16105
16106#endif /* HAVE_SNI */
16107
16108#if defined(OPENSSL_EXTRA)
16109
16110int wolfSSL_CRYPTO_memcmp(const void *a, const void *b, size_t size)
16111{
16112 if (!a || !b)
16113 return -1;
16114 return ConstantCompare((const byte*)a, (const byte*)b, (int)size);
16115}
16116
16117unsigned long wolfSSL_ERR_peek_last_error(void)
16118{
16119 WOLFSSL_ENTER("wolfSSL_ERR_peek_last_error");
16120
16121#ifdef WOLFSSL_HAVE_ERROR_QUEUE
16122 {
16123 int ret;
16124
16125 if ((ret = wc_PeekErrorNode(-1, NULL, NULL, NULL)) < 0) {
16126 WOLFSSL_MSG("Issue peeking at error node in queue");
16127 return 0;
16128 }
16129 if (ret == -WC_NO_ERR_TRACE(ASN_NO_PEM_HEADER))
16130 return (WOLFSSL_ERR_LIB_PEM << 24) | -WC_NO_ERR_TRACE(WOLFSSL_PEM_R_NO_START_LINE_E);
16131 #if defined(WOLFSSL_PYTHON)
16132 if (ret == ASN1_R_HEADER_TOO_LONG)
16133 return (WOLFSSL_ERR_LIB_ASN1 << 24) | -WC_NO_ERR_TRACE(WOLFSSL_ASN1_R_HEADER_TOO_LONG_E);
16134 #endif
16135 return (unsigned long)ret;
16136 }
16137#else
16138 return (unsigned long)(0 - NOT_COMPILED_IN);
16139#endif
16140}
16141
16142#endif /* OPENSSL_EXTRA */
16143
16144int wolfSSL_version(WOLFSSL* ssl)
16145{
16146 WOLFSSL_ENTER("wolfSSL_version");
16147 if (ssl->version.major == SSLv3_MAJOR) {
16148 switch (ssl->version.minor) {
16149 case SSLv3_MINOR :
16150 return SSL3_VERSION;
16151 case TLSv1_MINOR :
16152 return TLS1_VERSION;
16153 case TLSv1_1_MINOR :
16154 return TLS1_1_VERSION;
16155 case TLSv1_2_MINOR :
16156 return TLS1_2_VERSION;
16157 case TLSv1_3_MINOR :
16158 return TLS1_3_VERSION;
16159 default:
16160 return WOLFSSL_FAILURE;
16161 }
16162 }
16163 else if (ssl->version.major == DTLS_MAJOR) {
16164 switch (ssl->version.minor) {
16165 case DTLS_MINOR :
16166 return DTLS1_VERSION;
16167 case DTLSv1_2_MINOR :
16168 return DTLS1_2_VERSION;
16169 case DTLSv1_3_MINOR:
16170 return DTLS1_3_VERSION;
16171 default:
16172 return WOLFSSL_FAILURE;
16173 }
16174 }
16175 return WOLFSSL_FAILURE;
16176}
16177
16178WOLFSSL_CTX* wolfSSL_get_SSL_CTX(const WOLFSSL* ssl)
16179{
16180 WOLFSSL_ENTER("wolfSSL_get_SSL_CTX");
16181 return ssl->ctx;
16182}
16183
16184#if defined(OPENSSL_ALL) || defined(OPENSSL_EXTRA) || defined(HAVE_STUNNEL) || \
16185 defined(WOLFSSL_MYSQL_COMPATIBLE) || defined(WOLFSSL_NGINX)
16186
16187/* TODO: Doesn't currently track SSL_VERIFY_CLIENT_ONCE */
16188int wolfSSL_get_verify_mode(const WOLFSSL* ssl)
16189{
16190 int mode = 0;
16191 WOLFSSL_ENTER("wolfSSL_get_verify_mode");
16192
16193 if (!ssl) {
16194 return WOLFSSL_FAILURE;
16195 }
16196
16197 if (ssl->options.verifyNone) {
16198 mode = WOLFSSL_VERIFY_NONE;
16199 }
16200 else {
16201 if (ssl->options.verifyPeer) {
16202 mode |= WOLFSSL_VERIFY_PEER;
16203 }
16204 if (ssl->options.failNoCert) {
16205 mode |= WOLFSSL_VERIFY_FAIL_IF_NO_PEER_CERT;
16206 }
16207 if (ssl->options.failNoCertxPSK) {
16208 mode |= WOLFSSL_VERIFY_FAIL_EXCEPT_PSK;
16209 }
16210#if defined(WOLFSSL_TLS13) && defined(WOLFSSL_POST_HANDSHAKE_AUTH)
16211 if (ssl->options.verifyPostHandshake) {
16212 mode |= WOLFSSL_VERIFY_POST_HANDSHAKE;
16213 }
16214#endif
16215 }
16216
16217 WOLFSSL_LEAVE("wolfSSL_get_verify_mode", mode);
16218 return mode;
16219}
16220
16221int wolfSSL_CTX_get_verify_mode(const WOLFSSL_CTX* ctx)
16222{
16223 int mode = 0;
16224 WOLFSSL_ENTER("wolfSSL_CTX_get_verify_mode");
16225
16226 if (!ctx) {
16227 return WOLFSSL_FAILURE;
16228 }
16229
16230 if (ctx->verifyNone) {
16231 mode = WOLFSSL_VERIFY_NONE;
16232 }
16233 else {
16234 if (ctx->verifyPeer) {
16235 mode |= WOLFSSL_VERIFY_PEER;
16236 }
16237 if (ctx->failNoCert) {
16238 mode |= WOLFSSL_VERIFY_FAIL_IF_NO_PEER_CERT;
16239 }
16240 if (ctx->failNoCertxPSK) {
16241 mode |= WOLFSSL_VERIFY_FAIL_EXCEPT_PSK;
16242 }
16243#if defined(WOLFSSL_TLS13) && defined(WOLFSSL_POST_HANDSHAKE_AUTH)
16244 if (ctx->verifyPostHandshake) {
16245 mode |= WOLFSSL_VERIFY_POST_HANDSHAKE;
16246 }
16247#endif
16248 }
16249
16250 WOLFSSL_LEAVE("wolfSSL_CTX_get_verify_mode", mode);
16251 return mode;
16252}
16253
16254#endif
16255
16256#ifdef WOLFSSL_JNI
16257
16258int wolfSSL_set_jobject(WOLFSSL* ssl, void* objPtr)
16259{
16260 WOLFSSL_ENTER("wolfSSL_set_jobject");
16261 if (ssl != NULL)
16262 {
16263 ssl->jObjectRef = objPtr;
16264 return WOLFSSL_SUCCESS;
16265 }
16266 return WOLFSSL_FAILURE;
16267}
16268
16269void* wolfSSL_get_jobject(WOLFSSL* ssl)
16270{
16271 WOLFSSL_ENTER("wolfSSL_get_jobject");
16272 if (ssl != NULL)
16273 return ssl->jObjectRef;
16274 return NULL;
16275}
16276
16277#endif /* WOLFSSL_JNI */
16278
16279
16280#ifdef WOLFSSL_ASYNC_CRYPT
16281int wolfSSL_CTX_AsyncPoll(WOLFSSL_CTX* ctx, WOLF_EVENT** events, int maxEvents,
16282 WOLF_EVENT_FLAG flags, int* eventCount)
16283{
16284 if (ctx == NULL) {
16285 return BAD_FUNC_ARG;
16286 }
16287
16288 return wolfAsync_EventQueuePoll(&ctx->event_queue, NULL,
16289 events, maxEvents, flags, eventCount);
16290}
16291
16292int wolfSSL_AsyncPoll(WOLFSSL* ssl, WOLF_EVENT_FLAG flags)
16293{
16294 int ret, eventCount = 0;
16295 WOLF_EVENT* events[1];
16296
16297 if (ssl == NULL) {
16298 return BAD_FUNC_ARG;
16299 }
16300
16301 ret = wolfAsync_EventQueuePoll(&ssl->ctx->event_queue, ssl,
16302 events, sizeof(events)/sizeof(events[0]), flags, &eventCount);
16303 if (ret == 0) {
16304 ret = eventCount;
16305 }
16306
16307 return ret;
16308}
16309#endif /* WOLFSSL_ASYNC_CRYPT */
16310
16311#ifdef OPENSSL_EXTRA
16312
16313static int peek_ignore_err(int err)
16314{
16315 switch(err) {
16316 case -WC_NO_ERR_TRACE(WANT_READ):
16317 case -WC_NO_ERR_TRACE(WANT_WRITE):
16318 case -WC_NO_ERR_TRACE(ZERO_RETURN):
16319 case -WOLFSSL_ERROR_ZERO_RETURN:
16320 case -WC_NO_ERR_TRACE(SOCKET_PEER_CLOSED_E):
16321 case -WC_NO_ERR_TRACE(SOCKET_ERROR_E):
16322 return 1;
16323 default:
16324 return 0;
16325 }
16326}
16327
16328unsigned long wolfSSL_ERR_peek_error_line_data(const char **file, int *line,
16329 const char **data, int *flags)
16330{
16331 unsigned long err;
16332
16333 WOLFSSL_ENTER("wolfSSL_ERR_peek_error_line_data");
16334 err = wc_PeekErrorNodeLineData(file, line, data, flags, peek_ignore_err);
16335
16336 if (err == -WC_NO_ERR_TRACE(ASN_NO_PEM_HEADER))
16337 return (WOLFSSL_ERR_LIB_PEM << 24) | -WC_NO_ERR_TRACE(WOLFSSL_PEM_R_NO_START_LINE_E);
16338#ifdef OPENSSL_ALL
16339 /* PARSE_ERROR is returned if an HTTP request is detected. */
16340 else if (err == -WC_NO_ERR_TRACE(PARSE_ERROR))
16341 return (WOLFSSL_ERR_LIB_SSL << 24) | -WC_NO_ERR_TRACE(PARSE_ERROR) /* SSL_R_HTTP_REQUEST */;
16342#endif
16343#if defined(OPENSSL_ALL) && defined(WOLFSSL_PYTHON)
16344 else if (err == ASN1_R_HEADER_TOO_LONG)
16345 return (WOLFSSL_ERR_LIB_ASN1 << 24) | -WC_NO_ERR_TRACE(WOLFSSL_ASN1_R_HEADER_TOO_LONG_E);
16346#endif
16347 return err;
16348}
16349#endif
16350
16351#if defined(OPENSSL_EXTRA) || defined(OPENSSL_ALL) || \
16352 defined(WOLFSSL_NGINX) || defined(WOLFSSL_HAPROXY)
16353
16354#if !defined(WOLFSSL_USER_IO)
16355/* converts an IPv6 or IPv4 address into an octet string for use with rfc3280
16356 * example input would be "127.0.0.1" and the returned value would be 7F000001
16357 */
16358WOLFSSL_ASN1_STRING* wolfSSL_a2i_IPADDRESS(const char* ipa)
16359{
16360 int ipaSz = WOLFSSL_IP4_ADDR_LEN;
16361 char buf[WOLFSSL_IP6_ADDR_LEN + 1]; /* plus 1 for terminator */
16362 int af = WOLFSSL_IP4;
16363 WOLFSSL_ASN1_STRING *ret = NULL;
16364
16365 if (ipa == NULL)
16366 return NULL;
16367
16368 if (XSTRSTR(ipa, ":") != NULL) {
16369 af = WOLFSSL_IP6;
16370 ipaSz = WOLFSSL_IP6_ADDR_LEN;
16371 }
16372
16373 buf[WOLFSSL_IP6_ADDR_LEN] = '\0';
16374#ifdef FREESCALE_MQX
16375 if (XINET_PTON(af, ipa, (void*)buf, sizeof(buf)) != RTCS_OK) {
16376#else
16377 if (XINET_PTON(af, ipa, (void*)buf) != 1) {
16378#endif
16379 WOLFSSL_MSG("Error parsing IP address");
16380 return NULL;
16381 }
16382
16383 ret = wolfSSL_ASN1_STRING_new();
16384 if (ret != NULL) {
16385 if (wolfSSL_ASN1_STRING_set(ret, buf, ipaSz) != WOLFSSL_SUCCESS) {
16386 WOLFSSL_MSG("Error setting the string");
16387 wolfSSL_ASN1_STRING_free(ret);
16388 ret = NULL;
16389 }
16390 }
16391
16392 return ret;
16393}
16394#endif /* !WOLFSSL_USER_IO */
16395
16396/* Is the specified cipher suite a fake one used an an extension proxy? */
16397static WC_INLINE int SCSV_Check(byte suite0, byte suite)
16398{
16399 (void)suite0;
16400 (void)suite;
16401#ifdef HAVE_RENEGOTIATION_INDICATION
16402 if (suite0 == CIPHER_BYTE && suite == TLS_EMPTY_RENEGOTIATION_INFO_SCSV)
16403 return 1;
16404#endif
16405 return 0;
16406}
16407
16408static WC_INLINE int sslCipherMinMaxCheck(const WOLFSSL *ssl, byte suite0,
16409 byte suite)
16410{
16411 const CipherSuiteInfo* cipher_names = GetCipherNames();
16412 int cipherSz = GetCipherNamesSize();
16413 int i;
16414 for (i = 0; i < cipherSz; i++)
16415 if (cipher_names[i].cipherSuite0 == suite0 &&
16416 cipher_names[i].cipherSuite == suite)
16417 break;
16418 if (i == cipherSz)
16419 return 1;
16420 /* Check min version */
16421 if (cipher_names[i].minor < ssl->options.minDowngrade) {
16422 if (ssl->options.minDowngrade <= TLSv1_2_MINOR &&
16423 cipher_names[i].minor >= TLSv1_MINOR)
16424 /* 1.0 ciphersuites are in general available in 1.1 and
16425 * 1.1 ciphersuites are in general available in 1.2 */
16426 return 0;
16427 return 1;
16428 }
16429 /* Check max version */
16430 switch (cipher_names[i].minor) {
16431 case SSLv3_MINOR :
16432 return ssl->options.mask & WOLFSSL_OP_NO_SSLv3;
16433 case TLSv1_MINOR :
16434 return ssl->options.mask & WOLFSSL_OP_NO_TLSv1;
16435 case TLSv1_1_MINOR :
16436 return ssl->options.mask & WOLFSSL_OP_NO_TLSv1_1;
16437 case TLSv1_2_MINOR :
16438 return ssl->options.mask & WOLFSSL_OP_NO_TLSv1_2;
16439 case TLSv1_3_MINOR :
16440 return ssl->options.mask & WOLFSSL_OP_NO_TLSv1_3;
16441 default:
16442 WOLFSSL_MSG("Unrecognized minor version");
16443 return 1;
16444 }
16445}
16446
16447/* returns a pointer to internal cipher suite list. Should not be free'd by
16448 * caller.
16449 */
16450WOLF_STACK_OF(WOLFSSL_CIPHER) *wolfSSL_get_ciphers_compat(const WOLFSSL *ssl)
16451{
16452 const Suites* suites;
16453#if defined(OPENSSL_ALL)
16454 const CipherSuiteInfo* cipher_names = GetCipherNames();
16455 int cipherSz = GetCipherNamesSize();
16456#endif
16457
16458 WOLFSSL_ENTER("wolfSSL_get_ciphers_compat");
16459 if (ssl == NULL)
16460 return NULL;
16461
16462 suites = WOLFSSL_SUITES(ssl);
16463 if (suites == NULL)
16464 return NULL;
16465
16466 /* check if stack needs populated */
16467 if (ssl->suitesStack == NULL) {
16468 int i;
16469
16470 ((WOLFSSL*)ssl)->suitesStack =
16471 wolfssl_sk_new_type_ex(STACK_TYPE_CIPHER, ssl->heap);
16472 if (ssl->suitesStack == NULL)
16473 return NULL;
16474
16475 /* higher priority of cipher suite will be on top of stack */
16476#if defined(OPENSSL_ALL)
16477 for (i = suites->suiteSz - 2; i >=0; i-=2)
16478#else
16479 for (i = 0; i < suites->suiteSz; i+=2)
16480#endif
16481 {
16482 struct WOLFSSL_CIPHER cipher;
16483
16484 /* A couple of suites are placeholders for special options,
16485 * skip those. */
16486 if (SCSV_Check(suites->suites[i], suites->suites[i+1])
16487 || sslCipherMinMaxCheck(ssl, suites->suites[i],
16488 suites->suites[i+1])) {
16489 continue;
16490 }
16491
16492 XMEMSET(&cipher, 0, sizeof(cipher));
16493 cipher.cipherSuite0 = suites->suites[i];
16494 cipher.cipherSuite = suites->suites[i+1];
16495 cipher.ssl = ssl;
16496#if defined(OPENSSL_ALL)
16497 cipher.in_stack = 1;
16498 {
16499 int j;
16500 for (j = 0; j < cipherSz; j++) {
16501 if (cipher_names[j].cipherSuite0 == cipher.cipherSuite0 &&
16502 cipher_names[j].cipherSuite == cipher.cipherSuite) {
16503 cipher.offset = (unsigned long)j;
16504 break;
16505 }
16506 }
16507 }
16508#endif
16509 if (wolfSSL_sk_insert(ssl->suitesStack, &cipher, 0) <= 0) {
16510 WOLFSSL_MSG("Error inserting cipher onto stack");
16511 wolfSSL_sk_CIPHER_free(ssl->suitesStack);
16512 ((WOLFSSL*)ssl)->suitesStack = NULL;
16513 break;
16514 }
16515 }
16516
16517 /* If no ciphers were added, free empty stack and return NULL */
16518 if (ssl->suitesStack != NULL && wolfSSL_sk_num(ssl->suitesStack) == 0) {
16519 wolfSSL_sk_CIPHER_free(ssl->suitesStack);
16520 ((WOLFSSL*)ssl)->suitesStack = NULL;
16521 }
16522 }
16523 return ssl->suitesStack;
16524}
16525#endif /* OPENSSL_EXTRA || OPENSSL_ALL || WOLFSSL_NGINX || WOLFSSL_HAPROXY */
16526#ifdef OPENSSL_ALL
16527/* returned pointer is to an internal element in WOLFSSL struct and should not
16528 * be free'd. It gets free'd when the WOLFSSL struct is free'd. */
16529WOLF_STACK_OF(WOLFSSL_CIPHER)* wolfSSL_get_client_ciphers(WOLFSSL* ssl)
16530{
16531 WOLF_STACK_OF(WOLFSSL_CIPHER)* ret = NULL;
16532 const CipherSuiteInfo* cipher_names = GetCipherNames();
16533 int cipherSz = GetCipherNamesSize();
16534 const Suites* suites;
16535
16536 WOLFSSL_ENTER("wolfSSL_get_client_ciphers");
16537
16538 if (ssl == NULL) {
16539 return NULL;
16540 }
16541
16542 /* return NULL if is client side */
16543 if (wolfSSL_is_server(ssl) == 0) {
16544 return NULL;
16545 }
16546
16547 suites = ssl->clSuites;
16548 if (suites == NULL) {
16549 WOLFSSL_MSG("No client suites stored");
16550 }
16551 else if (ssl->clSuitesStack != NULL) {
16552 ret = ssl->clSuitesStack;
16553 }
16554 else { /* generate cipher suites stack if not already done */
16555 int i;
16556 int j;
16557
16558 ret = wolfSSL_sk_new_node(ssl->heap);
16559 if (ret != NULL) {
16560 ret->type = STACK_TYPE_CIPHER;
16561
16562 /* higher priority of cipher suite will be on top of stack */
16563 for (i = suites->suiteSz - 2; i >= 0; i -= 2) {
16564 WOLFSSL_CIPHER cipher;
16565
16566 /* A couple of suites are placeholders for special options,
16567 * skip those. */
16568 if (SCSV_Check(suites->suites[i], suites->suites[i+1])
16569 || sslCipherMinMaxCheck(ssl, suites->suites[i],
16570 suites->suites[i+1])) {
16571 continue;
16572 }
16573
16574 cipher.cipherSuite0 = suites->suites[i];
16575 cipher.cipherSuite = suites->suites[i+1];
16576 cipher.ssl = ssl;
16577 for (j = 0; j < cipherSz; j++) {
16578 if (cipher_names[j].cipherSuite0 ==
16579 cipher.cipherSuite0 &&
16580 cipher_names[j].cipherSuite ==
16581 cipher.cipherSuite) {
16582 cipher.offset = (unsigned long)j;
16583 break;
16584 }
16585 }
16586
16587 /* in_stack is checked in wolfSSL_CIPHER_description */
16588 cipher.in_stack = 1;
16589
16590 if (wolfSSL_sk_CIPHER_push(ret, &cipher) <= 0) {
16591 WOLFSSL_MSG("Error pushing client cipher onto stack");
16592 wolfSSL_sk_CIPHER_free(ret);
16593 ret = NULL;
16594 break;
16595 }
16596 }
16597 }
16598 ssl->clSuitesStack = ret;
16599 }
16600 return ret;
16601}
16602#endif /* OPENSSL_ALL */
16603
16604#if defined(OPENSSL_EXTRA) || defined(HAVE_SECRET_CALLBACK)
16605long wolfSSL_SSL_CTX_get_timeout(const WOLFSSL_CTX *ctx)
16606{
16607 WOLFSSL_ENTER("wolfSSL_SSL_CTX_get_timeout");
16608
16609 if (ctx == NULL)
16610 return 0;
16611
16612 return ctx->timeout;
16613}
16614
16615
16616/* returns the time in seconds of the current timeout */
16617long wolfSSL_get_timeout(WOLFSSL* ssl)
16618{
16619 WOLFSSL_ENTER("wolfSSL_get_timeout");
16620
16621 if (ssl == NULL)
16622 return 0;
16623 return ssl->timeout;
16624}
16625#endif
16626
16627#if defined(OPENSSL_ALL) || defined(WOLFSSL_NGINX) || defined(WOLFSSL_HAPROXY) \
16628 || defined(OPENSSL_EXTRA) || defined(HAVE_LIGHTY)
16629
16630#ifdef HAVE_ECC
16631int wolfSSL_SSL_CTX_set_tmp_ecdh(WOLFSSL_CTX *ctx, WOLFSSL_EC_KEY *ecdh)
16632{
16633 WOLFSSL_ENTER("wolfSSL_SSL_CTX_set_tmp_ecdh");
16634
16635 if (ctx == NULL || ecdh == NULL)
16636 return BAD_FUNC_ARG;
16637
16638 ctx->ecdhCurveOID = (word32)ecdh->group->curve_oid;
16639
16640 return WOLFSSL_SUCCESS;
16641}
16642#endif
16643#ifndef NO_BIO
16644WOLFSSL_BIO *wolfSSL_SSL_get_rbio(const WOLFSSL *s)
16645{
16646 WOLFSSL_ENTER("wolfSSL_SSL_get_rbio");
16647 /* Nginx sets the buffer size if the read BIO is different to write BIO.
16648 * The setting buffer size doesn't do anything so return NULL for both.
16649 */
16650 if (s == NULL)
16651 return NULL;
16652
16653 return s->biord;
16654}
16655WOLFSSL_BIO *wolfSSL_SSL_get_wbio(const WOLFSSL *s)
16656{
16657 WOLFSSL_ENTER("wolfSSL_SSL_get_wbio");
16658 (void)s;
16659 /* Nginx sets the buffer size if the read BIO is different to write BIO.
16660 * The setting buffer size doesn't do anything so return NULL for both.
16661 */
16662 if (s == NULL)
16663 return NULL;
16664
16665 return s->biowr;
16666}
16667#endif /* !NO_BIO */
16668
16669#ifndef NO_TLS
16670int wolfSSL_SSL_do_handshake_internal(WOLFSSL *s)
16671{
16672 WOLFSSL_ENTER("wolfSSL_SSL_do_handshake_internal");
16673 if (s == NULL)
16674 return WOLFSSL_FAILURE;
16675
16676 if (s->options.side == WOLFSSL_CLIENT_END) {
16677 #ifndef NO_WOLFSSL_CLIENT
16678 return wolfSSL_connect(s);
16679 #else
16680 WOLFSSL_MSG("Client not compiled in");
16681 return WOLFSSL_FAILURE;
16682 #endif
16683 }
16684
16685#ifndef NO_WOLFSSL_SERVER
16686 return wolfSSL_accept(s);
16687#else
16688 WOLFSSL_MSG("Server not compiled in");
16689 return WOLFSSL_FAILURE;
16690#endif
16691}
16692
16693int wolfSSL_SSL_do_handshake(WOLFSSL *s)
16694{
16695 WOLFSSL_ENTER("wolfSSL_SSL_do_handshake");
16696#ifdef WOLFSSL_QUIC
16697 if (WOLFSSL_IS_QUIC(s)) {
16698 return wolfSSL_quic_do_handshake(s);
16699 }
16700#endif
16701 return wolfSSL_SSL_do_handshake_internal(s);
16702}
16703#endif /* !NO_TLS */
16704
16705#if defined(OPENSSL_VERSION_NUMBER) && OPENSSL_VERSION_NUMBER >= 0x10100000L
16706int wolfSSL_SSL_in_init(const WOLFSSL *ssl)
16707#else
16708int wolfSSL_SSL_in_init(WOLFSSL *ssl)
16709#endif
16710{
16711 WOLFSSL_ENTER("wolfSSL_SSL_in_init");
16712
16713 return !wolfSSL_is_init_finished(ssl);
16714}
16715
16716int wolfSSL_SSL_in_before(const WOLFSSL *ssl)
16717{
16718 WOLFSSL_ENTER("wolfSSL_SSL_in_before");
16719
16720 if (ssl == NULL)
16721 return WOLFSSL_FAILURE;
16722
16723 return ssl->options.handShakeState == NULL_STATE;
16724}
16725
16726int wolfSSL_SSL_in_connect_init(WOLFSSL* ssl)
16727{
16728 WOLFSSL_ENTER("wolfSSL_SSL_in_connect_init");
16729
16730 if (ssl == NULL)
16731 return WOLFSSL_FAILURE;
16732
16733 if (ssl->options.side == WOLFSSL_CLIENT_END) {
16734 return ssl->options.connectState > CONNECT_BEGIN &&
16735 ssl->options.connectState < SECOND_REPLY_DONE;
16736 }
16737
16738 return ssl->options.acceptState > ACCEPT_BEGIN &&
16739 ssl->options.acceptState < ACCEPT_THIRD_REPLY_DONE;
16740}
16741
16742#if defined(HAVE_SESSION_TICKET) && !defined(NO_WOLFSSL_SERVER)
16743/* Expected return values from implementations of OpenSSL ticket key callback.
16744 */
16745#define TICKET_KEY_CB_RET_FAILURE (-1)
16746#define TICKET_KEY_CB_RET_NOT_FOUND 0
16747#define TICKET_KEY_CB_RET_OK 1
16748#define TICKET_KEY_CB_RET_RENEW 2
16749
16750/* Implementation of session ticket encryption/decryption using OpenSSL
16751 * callback to initialize the cipher and HMAC.
16752 *
16753 * ssl The SSL/TLS object.
16754 * keyName The key name - used to identify the key to be used.
16755 * iv The IV to use.
16756 * mac The MAC of the encrypted data.
16757 * enc Encrypt ticket.
16758 * encTicket The ticket data.
16759 * encTicketLen The length of the ticket data.
16760 * encLen The encrypted/decrypted ticket length - output length.
16761 * ctx Ignored. Application specific data.
16762 * returns WOLFSSL_TICKET_RET_OK to indicate success,
16763 * WOLFSSL_TICKET_RET_CREATE if a new ticket is required and
16764 * WOLFSSL_TICKET_RET_FATAL on error.
16765 */
16766static int wolfSSL_TicketKeyCb(WOLFSSL* ssl,
16767 unsigned char keyName[WOLFSSL_TICKET_NAME_SZ],
16768 unsigned char iv[WOLFSSL_TICKET_IV_SZ],
16769 unsigned char mac[WOLFSSL_TICKET_MAC_SZ],
16770 int enc, unsigned char* encTicket,
16771 int encTicketLen, int* encLen, void* ctx)
16772{
16773 byte digest[WC_MAX_DIGEST_SIZE];
16774 WC_DECLARE_VAR(evpCtx, WOLFSSL_EVP_CIPHER_CTX, 1, 0);
16775 WOLFSSL_HMAC_CTX hmacCtx;
16776 unsigned int mdSz = 0;
16777 int len = 0;
16778 int ret = WOLFSSL_TICKET_RET_FATAL;
16779 int res;
16780 int totalSz = 0;
16781
16782 (void)ctx;
16783
16784 WOLFSSL_ENTER("wolfSSL_TicketKeyCb");
16785
16786 if (ssl == NULL || ssl->ctx == NULL || ssl->ctx->ticketEncWrapCb == NULL) {
16787 WOLFSSL_MSG("Bad parameter");
16788 return WOLFSSL_TICKET_RET_FATAL;
16789 }
16790
16791#ifdef WOLFSSL_SMALL_STACK
16792 evpCtx = (WOLFSSL_EVP_CIPHER_CTX *)XMALLOC(sizeof(*evpCtx), ssl->heap,
16793 DYNAMIC_TYPE_TMP_BUFFER);
16794 if (evpCtx == NULL) {
16795 WOLFSSL_MSG("out of memory");
16796 return WOLFSSL_TICKET_RET_FATAL;
16797 }
16798#endif
16799
16800 /* Initialize the cipher and HMAC. */
16801 wolfSSL_EVP_CIPHER_CTX_init(evpCtx);
16802 if (wolfSSL_HMAC_CTX_Init(&hmacCtx) != WOLFSSL_SUCCESS) {
16803 WOLFSSL_MSG("wolfSSL_HMAC_CTX_Init error");
16804 WC_FREE_VAR_EX(evpCtx, ssl->heap, DYNAMIC_TYPE_TMP_BUFFER);
16805 return WOLFSSL_TICKET_RET_FATAL;
16806 }
16807 res = ssl->ctx->ticketEncWrapCb(ssl, keyName,
16808 iv, evpCtx, &hmacCtx, enc);
16809 if (res != TICKET_KEY_CB_RET_OK && res != TICKET_KEY_CB_RET_RENEW) {
16810 WOLFSSL_MSG("Ticket callback error");
16811 ret = WOLFSSL_TICKET_RET_FATAL;
16812 goto end;
16813 }
16814
16815 if (wolfSSL_HMAC_size(&hmacCtx) > WOLFSSL_TICKET_MAC_SZ) {
16816 WOLFSSL_MSG("Ticket cipher MAC size error");
16817 goto end;
16818 }
16819
16820 if (enc)
16821 {
16822 /* Encrypt in place. */
16823 if (!wolfSSL_EVP_CipherUpdate(evpCtx, encTicket, &len,
16824 encTicket, encTicketLen))
16825 goto end;
16826 totalSz = len;
16827 if (totalSz > *encLen)
16828 goto end;
16829 if (!wolfSSL_EVP_EncryptFinal(evpCtx, &encTicket[len], &len))
16830 goto end;
16831 /* Total length of encrypted data. */
16832 totalSz += len;
16833 if (totalSz > *encLen)
16834 goto end;
16835
16836 /* HMAC the encrypted data into the parameter 'mac'. */
16837 if (!wolfSSL_HMAC_Update(&hmacCtx, encTicket, totalSz))
16838 goto end;
16839 if (!wolfSSL_HMAC_Final(&hmacCtx, mac, &mdSz))
16840 goto end;
16841 }
16842 else
16843 {
16844 /* HMAC the encrypted data and compare it to the passed in data. */
16845 if (!wolfSSL_HMAC_Update(&hmacCtx, encTicket, encTicketLen))
16846 goto end;
16847 if (!wolfSSL_HMAC_Final(&hmacCtx, digest, &mdSz))
16848 goto end;
16849 if (ConstantCompare(mac, digest, (int)mdSz) != 0)
16850 goto end;
16851
16852 /* Decrypt the ticket data in place. */
16853 if (!wolfSSL_EVP_CipherUpdate(evpCtx, encTicket, &len,
16854 encTicket, encTicketLen))
16855 goto end;
16856 totalSz = len;
16857 if (totalSz > encTicketLen)
16858 goto end;
16859 if (!wolfSSL_EVP_DecryptFinal(evpCtx, &encTicket[len], &len))
16860 goto end;
16861 /* Total length of decrypted data. */
16862 totalSz += len;
16863 if (totalSz > encTicketLen)
16864 goto end;
16865 }
16866 *encLen = totalSz;
16867
16868 if (res == TICKET_KEY_CB_RET_RENEW && !IsAtLeastTLSv1_3(ssl->version)
16869 && !enc)
16870 ret = WOLFSSL_TICKET_RET_CREATE;
16871 else
16872 ret = WOLFSSL_TICKET_RET_OK;
16873end:
16874
16875 (void)wc_HmacFree(&hmacCtx.hmac);
16876 (void)wolfSSL_EVP_CIPHER_CTX_cleanup(evpCtx);
16877
16878 WC_FREE_VAR_EX(evpCtx, ssl->heap, DYNAMIC_TYPE_TMP_BUFFER);
16879
16880 return ret;
16881}
16882
16883/* Set the callback to use when encrypting/decrypting tickets.
16884 *
16885 * ctx The SSL/TLS context object.
16886 * cb The OpenSSL session ticket callback.
16887 * returns WOLFSSL_SUCCESS to indicate success.
16888 */
16889int wolfSSL_CTX_set_tlsext_ticket_key_cb(WOLFSSL_CTX *ctx, ticketCompatCb cb)
16890{
16891
16892 /* Set the ticket encryption callback to be a wrapper around OpenSSL
16893 * callback.
16894 */
16895 ctx->ticketEncCb = wolfSSL_TicketKeyCb;
16896 ctx->ticketEncWrapCb = cb;
16897
16898 return WOLFSSL_SUCCESS;
16899}
16900
16901#endif /* HAVE_SESSION_TICKET */
16902
16903#endif /* OPENSSL_ALL || WOLFSSL_NGINX || WOLFSSL_HAPROXY ||
16904 OPENSSL_EXTRA || HAVE_LIGHTY */
16905
16906#if defined(HAVE_SESSION_TICKET) && !defined(WOLFSSL_NO_DEF_TICKET_ENC_CB) && \
16907 !defined(NO_WOLFSSL_SERVER)
16908/* Serialize the session ticket encryption keys.
16909 *
16910 * @param [in] ctx SSL/TLS context object.
16911 * @param [in] keys Buffer to hold session ticket keys.
16912 * @param [in] keylen Length of buffer.
16913 * @return WOLFSSL_SUCCESS on success.
16914 * @return WOLFSSL_FAILURE when ctx is NULL, keys is NULL or keylen is not the
16915 * correct length.
16916 */
16917long wolfSSL_CTX_get_tlsext_ticket_keys(WOLFSSL_CTX *ctx,
16918 unsigned char *keys, int keylen)
16919{
16920 if (ctx == NULL || keys == NULL) {
16921 return WOLFSSL_FAILURE;
16922 }
16923 if (keylen != WOLFSSL_TICKET_KEYS_SZ) {
16924 return WOLFSSL_FAILURE;
16925 }
16926
16927 XMEMCPY(keys, ctx->ticketKeyCtx.name, WOLFSSL_TICKET_NAME_SZ);
16928 keys += WOLFSSL_TICKET_NAME_SZ;
16929 XMEMCPY(keys, ctx->ticketKeyCtx.key[0], WOLFSSL_TICKET_KEY_SZ);
16930 keys += WOLFSSL_TICKET_KEY_SZ;
16931 XMEMCPY(keys, ctx->ticketKeyCtx.key[1], WOLFSSL_TICKET_KEY_SZ);
16932 keys += WOLFSSL_TICKET_KEY_SZ;
16933 c32toa(ctx->ticketKeyCtx.expirary[0], keys);
16934 keys += OPAQUE32_LEN;
16935 c32toa(ctx->ticketKeyCtx.expirary[1], keys);
16936
16937 return WOLFSSL_SUCCESS;
16938}
16939
16940/* Deserialize the session ticket encryption keys.
16941 *
16942 * @param [in] ctx SSL/TLS context object.
16943 * @param [in] keys Session ticket keys.
16944 * @param [in] keylen Length of data.
16945 * @return WOLFSSL_SUCCESS on success.
16946 * @return WOLFSSL_FAILURE when ctx is NULL, keys is NULL or keylen is not the
16947 * correct length.
16948 */
16949long wolfSSL_CTX_set_tlsext_ticket_keys(WOLFSSL_CTX *ctx,
16950 const void *keys_vp, int keylen)
16951{
16952 const byte* keys = (const byte*)keys_vp;
16953 if (ctx == NULL || keys == NULL) {
16954 return WOLFSSL_FAILURE;
16955 }
16956 if (keylen != WOLFSSL_TICKET_KEYS_SZ) {
16957 return WOLFSSL_FAILURE;
16958 }
16959
16960 XMEMCPY(ctx->ticketKeyCtx.name, keys, WOLFSSL_TICKET_NAME_SZ);
16961 keys += WOLFSSL_TICKET_NAME_SZ;
16962 XMEMCPY(ctx->ticketKeyCtx.key[0], keys, WOLFSSL_TICKET_KEY_SZ);
16963 keys += WOLFSSL_TICKET_KEY_SZ;
16964 XMEMCPY(ctx->ticketKeyCtx.key[1], keys, WOLFSSL_TICKET_KEY_SZ);
16965 keys += WOLFSSL_TICKET_KEY_SZ;
16966 ato32(keys, &ctx->ticketKeyCtx.expirary[0]);
16967 keys += OPAQUE32_LEN;
16968 ato32(keys, &ctx->ticketKeyCtx.expirary[1]);
16969
16970 return WOLFSSL_SUCCESS;
16971}
16972#endif
16973
16974#if defined(WOLFSSL_NGINX) || defined(WOLFSSL_HAPROXY) || \
16975 defined(OPENSSL_EXTRA) || defined(OPENSSL_ALL)
16976int wolfSSL_CTX_get_extra_chain_certs(WOLFSSL_CTX* ctx,
16977 WOLF_STACK_OF(X509)** chain)
16978{
16979 word32 idx;
16980 word32 length;
16981 WOLFSSL_STACK* node;
16982 WOLFSSL_STACK* last = NULL;
16983
16984 if (ctx == NULL || chain == NULL) {
16985 chain = NULL;
16986 return WOLFSSL_FAILURE;
16987 }
16988 if (ctx->x509Chain != NULL) {
16989 *chain = ctx->x509Chain;
16990 return WOLFSSL_SUCCESS;
16991 }
16992
16993 /* If there are no chains then success! */
16994 *chain = NULL;
16995 if (ctx->certChain == NULL || ctx->certChain->length == 0) {
16996 return WOLFSSL_SUCCESS;
16997 }
16998
16999 /* Create a new stack of WOLFSSL_X509 object from chain buffer. */
17000 for (idx = 0; idx < ctx->certChain->length; ) {
17001 node = wolfSSL_sk_X509_new_null();
17002 if (node == NULL)
17003 return WOLFSSL_FAILURE;
17004 node->next = NULL;
17005
17006 /* 3 byte length | X509 DER data */
17007 ato24(ctx->certChain->buffer + idx, &length);
17008 idx += 3;
17009
17010 /* Create a new X509 from DER encoded data. */
17011 node->data.x509 = wolfSSL_X509_d2i_ex(NULL,
17012 ctx->certChain->buffer + idx, (int)length, ctx->heap);
17013 if (node->data.x509 == NULL) {
17014 XFREE(node, NULL, DYNAMIC_TYPE_OPENSSL);
17015 /* Return as much of the chain as we created. */
17016 ctx->x509Chain = *chain;
17017 return WOLFSSL_FAILURE;
17018 }
17019 idx += length;
17020
17021 /* Add object to the end of the stack. */
17022 if (last == NULL) {
17023 node->num = 1;
17024 *chain = node;
17025 }
17026 else {
17027 (*chain)->num++;
17028 last->next = node;
17029 }
17030
17031 last = node;
17032 }
17033
17034 ctx->x509Chain = *chain;
17035
17036 return WOLFSSL_SUCCESS;
17037}
17038
17039int wolfSSL_CTX_get0_chain_certs(WOLFSSL_CTX *ctx,
17040 WOLF_STACK_OF(WOLFSSL_X509) **sk)
17041{
17042 WOLFSSL_ENTER("wolfSSL_CTX_get0_chain_certs");
17043 if (ctx == NULL || sk == NULL) {
17044 WOLFSSL_MSG("Bad parameter");
17045 return WOLFSSL_FAILURE;
17046 }
17047
17048 /* This function should return ctx->x509Chain if it is populated, otherwise
17049 it should be populated from ctx->certChain. This matches the behavior of
17050 wolfSSL_CTX_get_extra_chain_certs, so it is used directly. */
17051 return wolfSSL_CTX_get_extra_chain_certs(ctx, sk);
17052}
17053
17054#ifdef KEEP_OUR_CERT
17055int wolfSSL_get0_chain_certs(WOLFSSL *ssl,
17056 WOLF_STACK_OF(WOLFSSL_X509) **sk)
17057{
17058 WOLFSSL_ENTER("wolfSSL_get0_chain_certs");
17059 if (ssl == NULL || sk == NULL) {
17060 WOLFSSL_MSG("Bad parameter");
17061 return WOLFSSL_FAILURE;
17062 }
17063 *sk = ssl->ourCertChain;
17064 return WOLFSSL_SUCCESS;
17065}
17066#endif
17067
17068void wolfSSL_WOLFSSL_STRING_free(WOLFSSL_STRING s)
17069{
17070 WOLFSSL_ENTER("wolfSSL_WOLFSSL_STRING_free");
17071
17072 XFREE(s, NULL, DYNAMIC_TYPE_OPENSSL);
17073}
17074
17075#endif /* WOLFSSL_NGINX || WOLFSSL_HAPROXY || OPENSSL_EXTRA || OPENSSL_ALL */
17076
17077#if defined(OPENSSL_ALL) || defined(WOLFSSL_NGINX) || \
17078 defined(WOLFSSL_HAPROXY) || defined(HAVE_LIGHTY) || \
17079 defined(WOLFSSL_QUIC)
17080#ifdef HAVE_ALPN
17081void wolfSSL_get0_alpn_selected(const WOLFSSL *ssl, const unsigned char **data,
17082 unsigned int *len)
17083{
17084 word16 nameLen = 0;
17085
17086 if (ssl != NULL && data != NULL && len != NULL) {
17087 TLSX_ALPN_GetRequest(ssl->extensions, (void **)data, &nameLen);
17088 *len = nameLen;
17089 }
17090}
17091
17092int wolfSSL_select_next_proto(unsigned char **out, unsigned char *outLen,
17093 const unsigned char *in, unsigned int inLen,
17094 const unsigned char *clientNames,
17095 unsigned int clientLen)
17096{
17097 unsigned int i, j;
17098 byte lenIn, lenClient;
17099
17100 if (out == NULL || outLen == NULL || in == NULL || clientNames == NULL)
17101 return WOLFSSL_NPN_UNSUPPORTED;
17102
17103 for (i = 0; i < inLen; i += lenIn) {
17104 lenIn = in[i++];
17105 if (lenIn == 0 || i + lenIn > inLen)
17106 break;
17107 for (j = 0; j < clientLen; j += lenClient) {
17108 lenClient = clientNames[j++];
17109 if (lenClient == 0 || j + lenClient > clientLen)
17110 break;
17111
17112 if (lenIn != lenClient)
17113 continue;
17114
17115 if (XMEMCMP(in + i, clientNames + j, lenIn) == 0) {
17116 *out = (unsigned char *)(in + i);
17117 *outLen = lenIn;
17118 return WOLFSSL_NPN_NEGOTIATED;
17119 }
17120 }
17121 }
17122
17123 if (clientLen > 0 && (unsigned int)clientNames[0] + 1 <= clientLen) {
17124 *out = (unsigned char *)clientNames + 1;
17125 *outLen = clientNames[0];
17126 }
17127 else {
17128 *out = (unsigned char *)clientNames;
17129 *outLen = 0;
17130 }
17131 return WOLFSSL_NPN_NO_OVERLAP;
17132}
17133
17134void wolfSSL_set_alpn_select_cb(WOLFSSL *ssl,
17135 int (*cb) (WOLFSSL *ssl,
17136 const unsigned char **out,
17137 unsigned char *outlen,
17138 const unsigned char *in,
17139 unsigned int inlen,
17140 void *arg), void *arg)
17141{
17142 if (ssl != NULL) {
17143 ssl->alpnSelect = cb;
17144 ssl->alpnSelectArg = arg;
17145 }
17146}
17147
17148void wolfSSL_CTX_set_alpn_select_cb(WOLFSSL_CTX *ctx,
17149 int (*cb) (WOLFSSL *ssl,
17150 const unsigned char **out,
17151 unsigned char *outlen,
17152 const unsigned char *in,
17153 unsigned int inlen,
17154 void *arg), void *arg)
17155{
17156 if (ctx != NULL) {
17157 ctx->alpnSelect = cb;
17158 ctx->alpnSelectArg = arg;
17159 }
17160}
17161
17162void wolfSSL_CTX_set_next_protos_advertised_cb(WOLFSSL_CTX *s,
17163 int (*cb) (WOLFSSL *ssl,
17164 const unsigned char
17165 **out,
17166 unsigned int *outlen,
17167 void *arg), void *arg)
17168{
17169 (void)s;
17170 (void)cb;
17171 (void)arg;
17172 WOLFSSL_STUB("wolfSSL_CTX_set_next_protos_advertised_cb");
17173}
17174
17175void wolfSSL_CTX_set_next_proto_select_cb(WOLFSSL_CTX *s,
17176 int (*cb) (WOLFSSL *ssl,
17177 unsigned char **out,
17178 unsigned char *outlen,
17179 const unsigned char *in,
17180 unsigned int inlen,
17181 void *arg), void *arg)
17182{
17183 (void)s;
17184 (void)cb;
17185 (void)arg;
17186 WOLFSSL_STUB("wolfSSL_CTX_set_next_proto_select_cb");
17187}
17188
17189void wolfSSL_get0_next_proto_negotiated(const WOLFSSL *s,
17190 const unsigned char **data, unsigned *len)
17191{
17192 (void)s;
17193 (void)data;
17194 (void)len;
17195 WOLFSSL_STUB("wolfSSL_get0_next_proto_negotiated");
17196}
17197#endif /* HAVE_ALPN */
17198
17199#endif /* WOLFSSL_NGINX / WOLFSSL_HAPROXY */
17200
17201#if defined(OPENSSL_EXTRA) || defined(HAVE_CURL)
17202int wolfSSL_curve_is_disabled(const WOLFSSL* ssl, word16 curve_id)
17203{
17204 int ret = 0;
17205
17206 WOLFSSL_ENTER("wolfSSL_curve_is_disabled");
17207 WOLFSSL_MSG_EX("wolfSSL_curve_is_disabled checking for %d", curve_id);
17208
17209 /* (curve_id >= WOLFSSL_FFDHE_START) - DH parameters are never disabled. */
17210 if (curve_id < WOLFSSL_FFDHE_START) {
17211 if (curve_id > WOLFSSL_ECC_MAX_AVAIL) {
17212 WOLFSSL_MSG("Curve id out of supported range");
17213 /* Disabled if not in valid range. */
17214 ret = 1;
17215 }
17216 else if (curve_id >= 32) {
17217 /* 0 is for invalid and 1-14 aren't used otherwise. */
17218 ret = (ssl->disabledCurves & (1U << (curve_id - 32))) != 0;
17219 }
17220 else {
17221 ret = (ssl->disabledCurves & (1U << curve_id)) != 0;
17222 }
17223 }
17224
17225 WOLFSSL_LEAVE("wolfSSL_curve_is_disabled", ret);
17226 return ret;
17227}
17228
17229#if (defined(HAVE_ECC) || \
17230 defined(HAVE_CURVE25519) || defined(HAVE_CURVE448))
17231#define CURVE_NAME(c) XSTR_SIZEOF((c)), (c)
17232
17233const WOLF_EC_NIST_NAME kNistCurves[] = {
17234#ifdef HAVE_ECC
17235 {CURVE_NAME("P-160"), WC_NID_secp160r1, WOLFSSL_ECC_SECP160R1},
17236 {CURVE_NAME("P-160-2"), WC_NID_secp160r2, WOLFSSL_ECC_SECP160R2},
17237 {CURVE_NAME("P-192"), WC_NID_X9_62_prime192v1, WOLFSSL_ECC_SECP192R1},
17238 {CURVE_NAME("P-224"), WC_NID_secp224r1, WOLFSSL_ECC_SECP224R1},
17239 {CURVE_NAME("P-256"), WC_NID_X9_62_prime256v1, WOLFSSL_ECC_SECP256R1},
17240 {CURVE_NAME("P-384"), WC_NID_secp384r1, WOLFSSL_ECC_SECP384R1},
17241 {CURVE_NAME("P-521"), WC_NID_secp521r1, WOLFSSL_ECC_SECP521R1},
17242 {CURVE_NAME("K-160"), WC_NID_secp160k1, WOLFSSL_ECC_SECP160K1},
17243 {CURVE_NAME("K-192"), WC_NID_secp192k1, WOLFSSL_ECC_SECP192K1},
17244 {CURVE_NAME("K-224"), WC_NID_secp224k1, WOLFSSL_ECC_SECP224K1},
17245 {CURVE_NAME("K-256"), WC_NID_secp256k1, WOLFSSL_ECC_SECP256K1},
17246 {CURVE_NAME("B-256"), WC_NID_brainpoolP256r1,
17247 WOLFSSL_ECC_BRAINPOOLP256R1},
17248 {CURVE_NAME("B-384"), WC_NID_brainpoolP384r1,
17249 WOLFSSL_ECC_BRAINPOOLP384R1},
17250 {CURVE_NAME("B-512"), WC_NID_brainpoolP512r1,
17251 WOLFSSL_ECC_BRAINPOOLP512R1},
17252#endif
17253#ifdef HAVE_CURVE25519
17254 {CURVE_NAME("X25519"), WC_NID_X25519, WOLFSSL_ECC_X25519},
17255#endif
17256#ifdef HAVE_CURVE448
17257 {CURVE_NAME("X448"), WC_NID_X448, WOLFSSL_ECC_X448},
17258#endif
17259#ifdef WOLFSSL_HAVE_MLKEM
17260#ifndef WOLFSSL_NO_ML_KEM
17261 {CURVE_NAME("ML_KEM_512"), WOLFSSL_ML_KEM_512, WOLFSSL_ML_KEM_512},
17262 {CURVE_NAME("ML_KEM_768"), WOLFSSL_ML_KEM_768, WOLFSSL_ML_KEM_768},
17263 {CURVE_NAME("ML_KEM_1024"), WOLFSSL_ML_KEM_1024, WOLFSSL_ML_KEM_1024},
17264#if defined(HAVE_ECC)
17265 #ifdef WOLFSSL_PQC_HYBRIDS
17266 {CURVE_NAME("SecP256r1MLKEM768"), WOLFSSL_SECP256R1MLKEM768,
17267 WOLFSSL_SECP256R1MLKEM768},
17268 {CURVE_NAME("SecP384r1MLKEM1024"), WOLFSSL_SECP384R1MLKEM1024,
17269 WOLFSSL_SECP384R1MLKEM1024},
17270 {CURVE_NAME("X25519MLKEM768"), WOLFSSL_X25519MLKEM768,
17271 WOLFSSL_X25519MLKEM768},
17272 #endif /* WOLFSSL_PQC_HYBRIDS */
17273 #ifdef WOLFSSL_EXTRA_PQC_HYBRIDS
17274 {CURVE_NAME("SecP256r1MLKEM512"), WOLFSSL_SECP256R1MLKEM512,
17275 WOLFSSL_SECP256R1MLKEM512},
17276 {CURVE_NAME("SecP384r1MLKEM768"), WOLFSSL_SECP384R1MLKEM768,
17277 WOLFSSL_SECP384R1MLKEM768},
17278 {CURVE_NAME("SecP521r1MLKEM1024"), WOLFSSL_SECP521R1MLKEM1024,
17279 WOLFSSL_SECP521R1MLKEM1024},
17280 {CURVE_NAME("X25519MLKEM512"), WOLFSSL_X25519MLKEM512,
17281 WOLFSSL_X25519MLKEM512},
17282 {CURVE_NAME("X448MLKEM768"), WOLFSSL_X448MLKEM768,
17283 WOLFSSL_X448MLKEM768},
17284 #endif /* WOLFSSL_EXTRA_PQC_HYBRIDS */
17285#endif
17286#endif /* !WOLFSSL_NO_ML_KEM */
17287#ifdef WOLFSSL_MLKEM_KYBER
17288 {CURVE_NAME("KYBER_LEVEL1"), WOLFSSL_KYBER_LEVEL1, WOLFSSL_KYBER_LEVEL1},
17289 {CURVE_NAME("KYBER_LEVEL3"), WOLFSSL_KYBER_LEVEL3, WOLFSSL_KYBER_LEVEL3},
17290 {CURVE_NAME("KYBER_LEVEL5"), WOLFSSL_KYBER_LEVEL5, WOLFSSL_KYBER_LEVEL5},
17291#if defined(HAVE_ECC)
17292 {CURVE_NAME("P256_KYBER_LEVEL1"), WOLFSSL_P256_KYBER_LEVEL1,
17293 WOLFSSL_P256_KYBER_LEVEL1},
17294 {CURVE_NAME("P384_KYBER_LEVEL3"), WOLFSSL_P384_KYBER_LEVEL3,
17295 WOLFSSL_P384_KYBER_LEVEL3},
17296 {CURVE_NAME("P256_KYBER_LEVEL3"), WOLFSSL_P256_KYBER_LEVEL3,
17297 WOLFSSL_P256_KYBER_LEVEL3},
17298 {CURVE_NAME("P521_KYBER_LEVEL5"), WOLFSSL_P521_KYBER_LEVEL5,
17299 WOLFSSL_P521_KYBER_LEVEL5},
17300 {CURVE_NAME("X25519_KYBER_LEVEL1"), WOLFSSL_X25519_KYBER_LEVEL1,
17301 WOLFSSL_X25519_KYBER_LEVEL1},
17302 {CURVE_NAME("X448_KYBER_LEVEL3"), WOLFSSL_X448_KYBER_LEVEL3,
17303 WOLFSSL_X448_KYBER_LEVEL3},
17304 {CURVE_NAME("X25519_KYBER_LEVEL3"), WOLFSSL_X25519_KYBER_LEVEL3,
17305 WOLFSSL_X25519_KYBER_LEVEL3},
17306#endif
17307#endif /* WOLFSSL_MLKEM_KYBER */
17308#endif /* WOLFSSL_HAVE_MLKEM */
17309#ifdef WOLFSSL_SM2
17310 {CURVE_NAME("SM2"), WC_NID_sm2, WOLFSSL_ECC_SM2P256V1},
17311#endif
17312#ifdef HAVE_ECC
17313 /* Alternative curve names */
17314 {CURVE_NAME("prime256v1"), WC_NID_X9_62_prime256v1, WOLFSSL_ECC_SECP256R1},
17315 {CURVE_NAME("secp256r1"), WC_NID_X9_62_prime256v1, WOLFSSL_ECC_SECP256R1},
17316 {CURVE_NAME("secp384r1"), WC_NID_secp384r1, WOLFSSL_ECC_SECP384R1},
17317 {CURVE_NAME("secp521r1"), WC_NID_secp521r1, WOLFSSL_ECC_SECP521R1},
17318#endif
17319#ifdef WOLFSSL_SM2
17320 {CURVE_NAME("sm2p256v1"), WC_NID_sm2, WOLFSSL_ECC_SM2P256V1},
17321#endif
17322 {0, NULL, 0, 0},
17323};
17324
17325int set_curves_list(WOLFSSL* ssl, WOLFSSL_CTX *ctx, const char* names,
17326 byte curves_only)
17327{
17328 int idx, start = 0, len, i, ret = WOLFSSL_FAILURE;
17329 word16 curve;
17330 word32 disabled;
17331 char name[MAX_CURVE_NAME_SZ];
17332 byte groups_len = 0;
17333#ifdef WOLFSSL_SMALL_STACK
17334 void *heap = ssl? ssl->heap : ctx ? ctx->heap : NULL;
17335 int *groups;
17336#else
17337 int groups[WOLFSSL_MAX_GROUP_COUNT];
17338#endif
17339 const WOLF_EC_NIST_NAME* nist_name;
17340
17341 WC_ALLOC_VAR_EX(groups, int, WOLFSSL_MAX_GROUP_COUNT, heap,
17342 DYNAMIC_TYPE_TMP_BUFFER,
17343 {
17344 ret=MEMORY_E;
17345 goto leave;
17346 });
17347
17348 for (idx = 1; names[idx-1] != '\0'; idx++) {
17349 if (names[idx] != ':' && names[idx] != '\0')
17350 continue;
17351
17352 len = idx - start;
17353 if (len > MAX_CURVE_NAME_SZ - 1)
17354 goto leave;
17355
17356 XMEMCPY(name, names + start, (size_t)len);
17357 name[len] = 0;
17358 curve = WOLFSSL_NAMED_GROUP_INVALID;
17359
17360 for (nist_name = kNistCurves; nist_name->name != NULL; nist_name++) {
17361 if (len == nist_name->name_len &&
17362 XSTRNCMP(name, nist_name->name, (size_t)len) == 0) {
17363 curve = nist_name->curve;
17364 break;
17365 }
17366 }
17367
17368 if (curve == WOLFSSL_NAMED_GROUP_INVALID) {
17369 #if !defined(HAVE_FIPS) && !defined(HAVE_SELFTEST) && defined(HAVE_ECC)
17370 int nret;
17371 const ecc_set_type *eccSet;
17372
17373 nret = wc_ecc_get_curve_idx_from_name(name);
17374 if (nret < 0) {
17375 WOLFSSL_MSG("Could not find name in set");
17376 goto leave;
17377 }
17378
17379 eccSet = wc_ecc_get_curve_params(nret);
17380 if (eccSet == NULL) {
17381 WOLFSSL_MSG("NULL set returned");
17382 goto leave;
17383 }
17384
17385 curve = GetCurveByOID((int)eccSet->oidSum);
17386 #else
17387 WOLFSSL_MSG("API not present to search farther using name");
17388 goto leave;
17389 #endif
17390 }
17391
17392 if ((curves_only && curve >= WOLFSSL_ECC_MAX_AVAIL) ||
17393 curve == WOLFSSL_NAMED_GROUP_INVALID) {
17394 WOLFSSL_MSG("curve value is not supported");
17395 goto leave;
17396 }
17397
17398 for (i = 0; i < groups_len; ++i) {
17399 if (groups[i] == curve) {
17400 /* silently drop duplicates */
17401 break;
17402 }
17403 }
17404 if (i >= groups_len) {
17405 if (groups_len >= WOLFSSL_MAX_GROUP_COUNT) {
17406 WOLFSSL_MSG_EX("setting %d or more supported "
17407 "curves is not permitted", groups_len);
17408 goto leave;
17409 }
17410 groups[groups_len++] = (int)curve;
17411 }
17412
17413 start = idx + 1;
17414 }
17415
17416 /* Disable all curves so that only the ones the user wants are enabled. */
17417 disabled = 0xFFFFFFFFUL;
17418 for (i = 0; i < groups_len; ++i) {
17419 /* Switch the bit to off and therefore is enabled. */
17420 curve = (word16)groups[i];
17421 if (curve >= 64) {
17422 WC_DO_NOTHING;
17423 }
17424 else if (curve >= 32) {
17425 /* 0 is for invalid and 1-14 aren't used otherwise. */
17426 disabled &= ~(1U << (curve - 32));
17427 }
17428 else {
17429 disabled &= ~(1U << curve);
17430 }
17431 #if defined(HAVE_SUPPORTED_CURVES) && !defined(NO_TLS)
17432 #if !defined(WOLFSSL_OLD_SET_CURVES_LIST)
17433 /* using the wolfSSL API to set the groups, this will populate
17434 * (ssl|ctx)->groups and reset any TLSX_SUPPORTED_GROUPS.
17435 * The order in (ssl|ctx)->groups will then be respected
17436 * when TLSX_KEY_SHARE needs to be established */
17437 if ((ssl && wolfSSL_set_groups(ssl, groups, groups_len)
17438 != WOLFSSL_SUCCESS)
17439 || (ctx && wolfSSL_CTX_set_groups(ctx, groups, groups_len)
17440 != WOLFSSL_SUCCESS)) {
17441 WOLFSSL_MSG("Unable to set supported curve");
17442 goto leave;
17443 }
17444 #elif !defined(NO_WOLFSSL_CLIENT)
17445 /* set the supported curve so client TLS extension contains only the
17446 * desired curves */
17447 if ((ssl && wolfSSL_UseSupportedCurve(ssl, curve) != WOLFSSL_SUCCESS)
17448 || (ctx && wolfSSL_CTX_UseSupportedCurve(ctx, curve)
17449 != WOLFSSL_SUCCESS)) {
17450 WOLFSSL_MSG("Unable to set supported curve");
17451 goto leave;
17452 }
17453 #endif
17454 #endif /* HAVE_SUPPORTED_CURVES && !NO_TLS */
17455 }
17456
17457 if (ssl != NULL)
17458 ssl->disabledCurves = disabled;
17459 else if (ctx != NULL)
17460 ctx->disabledCurves = disabled;
17461 ret = WOLFSSL_SUCCESS;
17462
17463leave:
17464#ifdef WOLFSSL_SMALL_STACK
17465 if (groups)
17466 XFREE((void*)groups, heap, DYNAMIC_TYPE_TMP_BUFFER);
17467#endif
17468 return ret;
17469}
17470
17471int wolfSSL_CTX_set1_curves_list(WOLFSSL_CTX* ctx, const char* names)
17472{
17473 WOLFSSL_ENTER("wolfSSL_CTX_set1_curves_list");
17474 if (ctx == NULL || names == NULL) {
17475 WOLFSSL_MSG("ctx or names was NULL");
17476 return WOLFSSL_FAILURE;
17477 }
17478 return set_curves_list(NULL, ctx, names, 1);
17479}
17480
17481int wolfSSL_set1_curves_list(WOLFSSL* ssl, const char* names)
17482{
17483 WOLFSSL_ENTER("wolfSSL_set1_curves_list");
17484 if (ssl == NULL || names == NULL) {
17485 WOLFSSL_MSG("ssl or names was NULL");
17486 return WOLFSSL_FAILURE;
17487 }
17488 return set_curves_list(ssl, NULL, names, 1);
17489}
17490#endif /* (HAVE_ECC || HAVE_CURVE25519 || HAVE_CURVE448) */
17491#endif /* OPENSSL_EXTRA || HAVE_CURL */
17492
17493
17494#ifdef OPENSSL_EXTRA
17495/* Sets a callback for when sending and receiving protocol messages.
17496 * This callback is copied to all WOLFSSL objects created from the ctx.
17497 *
17498 * ctx WOLFSSL_CTX structure to set callback in
17499 * cb callback to use
17500 *
17501 * return WOLFSSL_SUCCESS on success and WOLFSSL_FAILURE with error case
17502 */
17503int wolfSSL_CTX_set_msg_callback(WOLFSSL_CTX *ctx, SSL_Msg_Cb cb)
17504{
17505 WOLFSSL_ENTER("wolfSSL_CTX_set_msg_callback");
17506 if (ctx == NULL) {
17507 WOLFSSL_MSG("Null ctx passed in");
17508 return WOLFSSL_FAILURE;
17509 }
17510
17511 ctx->protoMsgCb = cb;
17512 return WOLFSSL_SUCCESS;
17513}
17514
17515
17516/* Sets a callback for when sending and receiving protocol messages.
17517 *
17518 * ssl WOLFSSL structure to set callback in
17519 * cb callback to use
17520 *
17521 * return WOLFSSL_SUCCESS on success and WOLFSSL_FAILURE with error case
17522 */
17523int wolfSSL_set_msg_callback(WOLFSSL *ssl, SSL_Msg_Cb cb)
17524{
17525 WOLFSSL_ENTER("wolfSSL_set_msg_callback");
17526
17527 if (ssl == NULL) {
17528 return WOLFSSL_FAILURE;
17529 }
17530
17531 if (cb != NULL) {
17532 ssl->toInfoOn = 1;
17533 }
17534
17535 ssl->protoMsgCb = cb;
17536 return WOLFSSL_SUCCESS;
17537}
17538
17539
17540/* set the user argument to pass to the msg callback when called
17541 * return WOLFSSL_SUCCESS on success */
17542int wolfSSL_CTX_set_msg_callback_arg(WOLFSSL_CTX *ctx, void* arg)
17543{
17544 WOLFSSL_ENTER("wolfSSL_CTX_set_msg_callback_arg");
17545 if (ctx == NULL) {
17546 WOLFSSL_MSG("Null WOLFSSL_CTX passed in");
17547 return WOLFSSL_FAILURE;
17548 }
17549
17550 ctx->protoMsgCtx = arg;
17551 return WOLFSSL_SUCCESS;
17552}
17553
17554
17555int wolfSSL_set_msg_callback_arg(WOLFSSL *ssl, void* arg)
17556{
17557 WOLFSSL_ENTER("wolfSSL_set_msg_callback_arg");
17558 if (ssl == NULL)
17559 return WOLFSSL_FAILURE;
17560
17561 ssl->protoMsgCtx = arg;
17562 return WOLFSSL_SUCCESS;
17563}
17564
17565void *wolfSSL_OPENSSL_memdup(const void *data, size_t siz, const char* file,
17566 int line)
17567{
17568 void *ret;
17569 (void)file;
17570 (void)line;
17571
17572 if (data == NULL || siz >= INT_MAX)
17573 return NULL;
17574
17575 ret = wolfSSL_OPENSSL_malloc(siz);
17576 if (ret == NULL) {
17577 return NULL;
17578 }
17579 return XMEMCPY(ret, data, siz);
17580}
17581
17582void wolfSSL_OPENSSL_cleanse(void *ptr, size_t len)
17583{
17584 if (ptr)
17585 ForceZero(ptr, (word32)len);
17586}
17587
17588int wolfSSL_CTX_set_alpn_protos(WOLFSSL_CTX *ctx, const unsigned char *p,
17589 unsigned int p_len)
17590{
17591 WOLFSSL_ENTER("wolfSSL_CTX_set_alpn_protos");
17592 if (ctx == NULL || p == NULL)
17593 return BAD_FUNC_ARG;
17594 if (ctx->alpn_cli_protos != NULL) {
17595 XFREE((void*)ctx->alpn_cli_protos, ctx->heap, DYNAMIC_TYPE_OPENSSL);
17596 }
17597
17598 ctx->alpn_cli_protos = (const unsigned char*)XMALLOC(p_len,
17599 ctx->heap, DYNAMIC_TYPE_OPENSSL);
17600 if (ctx->alpn_cli_protos == NULL) {
17601#if defined(WOLFSSL_ERROR_CODE_OPENSSL)
17602 /* 0 on success in OpenSSL, non-0 on failure in OpenSSL
17603 * the function reverses the return value convention.
17604 */
17605 return 1;
17606#else
17607 return WOLFSSL_FAILURE;
17608#endif
17609 }
17610 XMEMCPY((void*)ctx->alpn_cli_protos, p, p_len);
17611 ctx->alpn_cli_protos_len = p_len;
17612
17613#if defined(WOLFSSL_ERROR_CODE_OPENSSL)
17614 /* 0 on success in OpenSSL, non-0 on failure in OpenSSL
17615 * the function reverses the return value convention.
17616 */
17617 return 0;
17618#else
17619 return WOLFSSL_SUCCESS;
17620#endif
17621}
17622
17623
17624#ifdef HAVE_ALPN
17625#ifndef NO_BIO
17626/* Sets the ALPN extension protos
17627 *
17628 * example format is
17629 * unsigned char p[] = {
17630 * 8, 'h', 't', 't', 'p', '/', '1', '.', '1'
17631 * };
17632 *
17633 * returns WOLFSSL_SUCCESS on success */
17634int wolfSSL_set_alpn_protos(WOLFSSL* ssl,
17635 const unsigned char* p, unsigned int p_len)
17636{
17637 char* pt = NULL;
17638 unsigned int ptIdx;
17639 unsigned int sz;
17640 unsigned int idx = 0;
17641 /* RFC 7301: a server that does not select any of the client's offered
17642 * protocols MUST send no_application_protocol. Match that contract on
17643 * the OpenSSL-compat surface rather than silently continuing. */
17644 int alpn_opt = WOLFSSL_ALPN_FAILED_ON_MISMATCH;
17645 int ret;
17646
17647 WOLFSSL_ENTER("wolfSSL_set_alpn_protos");
17648
17649 if (ssl == NULL || p_len <= 1 || p == NULL) {
17650#if defined(WOLFSSL_ERROR_CODE_OPENSSL)
17651 /* 0 on success in OpenSSL, non-0 on failure in OpenSSL
17652 * the function reverses the return value convention.
17653 */
17654 return 1;
17655#else
17656 return WOLFSSL_FAILURE;
17657#endif
17658 }
17659
17660 /* Replacing leading number with trailing ',' and adding '\0'. */
17661 pt = (char*)XMALLOC(p_len + 1, ssl->heap, DYNAMIC_TYPE_OPENSSL);
17662 if (pt == NULL) {
17663#if defined(WOLFSSL_ERROR_CODE_OPENSSL)
17664 /* 0 on success in OpenSSL, non-0 on failure in OpenSSL
17665 * the function reverses the return value convention.
17666 */
17667 return 1;
17668#else
17669 return WOLFSSL_FAILURE;
17670#endif
17671 }
17672
17673 ptIdx = 0;
17674 /* convert into comma separated list */
17675 while (idx < p_len - 1) {
17676 unsigned int i;
17677
17678 sz = p[idx++];
17679 if (idx + sz > p_len) {
17680 WOLFSSL_MSG("Bad list format");
17681 XFREE(pt, ssl->heap, DYNAMIC_TYPE_OPENSSL);
17682 #if defined(WOLFSSL_ERROR_CODE_OPENSSL)
17683 /* 0 on success in OpenSSL, non-0 on failure in OpenSSL
17684 * the function reverses the return value convention.
17685 */
17686 return 1;
17687 #else
17688 return WOLFSSL_FAILURE;
17689 #endif
17690 }
17691 if (sz > 0) {
17692 for (i = 0; i < sz; i++) {
17693 pt[ptIdx++] = p[idx++];
17694 }
17695 if (idx < p_len - 1) {
17696 pt[ptIdx++] = ',';
17697 }
17698 }
17699 }
17700 pt[ptIdx++] = '\0';
17701
17702 /* clears out all current ALPN extensions set */
17703 TLSX_Remove(&ssl->extensions, TLSX_APPLICATION_LAYER_PROTOCOL, ssl->heap);
17704
17705 ret = wolfSSL_UseALPN(ssl, pt, ptIdx, (byte)alpn_opt);
17706 XFREE(pt, ssl->heap, DYNAMIC_TYPE_OPENSSL);
17707#if defined(WOLFSSL_ERROR_CODE_OPENSSL)
17708 /* 0 on success in OpenSSL, non-0 on failure in OpenSSL
17709 * the function reverses the return value convention.
17710 */
17711 if (ret != WOLFSSL_SUCCESS)
17712 return 1;
17713 return 0;
17714#else
17715 if (ret != WOLFSSL_SUCCESS)
17716 return WOLFSSL_FAILURE;
17717 return WOLFSSL_SUCCESS;
17718#endif
17719}
17720#endif /* !NO_BIO */
17721#endif /* HAVE_ALPN */
17722#endif /* OPENSSL_EXTRA */
17723
17724#if defined(OPENSSL_EXTRA)
17725
17726#ifndef NO_BIO
17727#define WOLFSSL_BIO_INCLUDED
17728#include "src/bio.c"
17729#endif
17730
17731#endif /* OPENSSL_EXTRA */
17732
17733#if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)
17734
17735word32 nid2oid(int nid, int grp)
17736{
17737 /* get OID type */
17738 switch (grp) {
17739 /* oidHashType */
17740 case oidHashType:
17741 switch (nid) {
17742 #ifdef WOLFSSL_MD2
17743 case WC_NID_md2:
17744 return MD2h;
17745 #endif
17746 #ifndef NO_MD5
17747 case WC_NID_md5:
17748 return MD5h;
17749 #endif
17750 #ifndef NO_SHA
17751 case WC_NID_sha1:
17752 return SHAh;
17753 #endif
17754 case WC_NID_sha224:
17755 return SHA224h;
17756 #ifndef NO_SHA256
17757 case WC_NID_sha256:
17758 return SHA256h;
17759 #endif
17760 #ifdef WOLFSSL_SHA384
17761 case WC_NID_sha384:
17762 return SHA384h;
17763 #endif
17764 #ifdef WOLFSSL_SHA512
17765 case WC_NID_sha512:
17766 return SHA512h;
17767 #endif
17768 #ifndef WOLFSSL_NOSHA3_224
17769 case WC_NID_sha3_224:
17770 return SHA3_224h;
17771 #endif
17772 #ifndef WOLFSSL_NOSHA3_256
17773 case WC_NID_sha3_256:
17774 return SHA3_256h;
17775 #endif
17776 #ifndef WOLFSSL_NOSHA3_384
17777 case WC_NID_sha3_384:
17778 return SHA3_384h;
17779 #endif
17780 #ifndef WOLFSSL_NOSHA3_512
17781 case WC_NID_sha3_512:
17782 return SHA3_512h;
17783 #endif
17784 }
17785 break;
17786
17787 /* oidSigType */
17788 case oidSigType:
17789 switch (nid) {
17790 #ifndef NO_DSA
17791 case WC_NID_dsaWithSHA1:
17792 return CTC_SHAwDSA;
17793 case WC_NID_dsa_with_SHA256:
17794 return CTC_SHA256wDSA;
17795 #endif /* NO_DSA */
17796 #ifndef NO_RSA
17797 case WC_NID_md2WithRSAEncryption:
17798 return CTC_MD2wRSA;
17799 case WC_NID_md5WithRSAEncryption:
17800 return CTC_MD5wRSA;
17801 case WC_NID_sha1WithRSAEncryption:
17802 return CTC_SHAwRSA;
17803 case WC_NID_sha224WithRSAEncryption:
17804 return CTC_SHA224wRSA;
17805 case WC_NID_sha256WithRSAEncryption:
17806 return CTC_SHA256wRSA;
17807 case WC_NID_sha384WithRSAEncryption:
17808 return CTC_SHA384wRSA;
17809 case WC_NID_sha512WithRSAEncryption:
17810 return CTC_SHA512wRSA;
17811 #ifdef WOLFSSL_SHA3
17812 case WC_NID_RSA_SHA3_224:
17813 return CTC_SHA3_224wRSA;
17814 case WC_NID_RSA_SHA3_256:
17815 return CTC_SHA3_256wRSA;
17816 case WC_NID_RSA_SHA3_384:
17817 return CTC_SHA3_384wRSA;
17818 case WC_NID_RSA_SHA3_512:
17819 return CTC_SHA3_512wRSA;
17820 #endif
17821 #endif /* NO_RSA */
17822 #ifdef HAVE_ECC
17823 case WC_NID_ecdsa_with_SHA1:
17824 return CTC_SHAwECDSA;
17825 case WC_NID_ecdsa_with_SHA224:
17826 return CTC_SHA224wECDSA;
17827 case WC_NID_ecdsa_with_SHA256:
17828 return CTC_SHA256wECDSA;
17829 case WC_NID_ecdsa_with_SHA384:
17830 return CTC_SHA384wECDSA;
17831 case WC_NID_ecdsa_with_SHA512:
17832 return CTC_SHA512wECDSA;
17833 #ifdef WOLFSSL_SHA3
17834 case WC_NID_ecdsa_with_SHA3_224:
17835 return CTC_SHA3_224wECDSA;
17836 case WC_NID_ecdsa_with_SHA3_256:
17837 return CTC_SHA3_256wECDSA;
17838 case WC_NID_ecdsa_with_SHA3_384:
17839 return CTC_SHA3_384wECDSA;
17840 case WC_NID_ecdsa_with_SHA3_512:
17841 return CTC_SHA3_512wECDSA;
17842 #endif
17843 #endif /* HAVE_ECC */
17844 #ifdef HAVE_ED25519
17845 case WC_NID_ED25519:
17846 return CTC_ED25519;
17847 #endif /* HAVE_ED25519 */
17848 #ifdef HAVE_ED448
17849 case WC_NID_ED448:
17850 return CTC_ED448;
17851 #endif /* HAVE_ED448 */
17852 }
17853 break;
17854
17855 /* oidKeyType */
17856 case oidKeyType:
17857 switch (nid) {
17858 #ifndef NO_DSA
17859 case WC_NID_dsa:
17860 return DSAk;
17861 #endif /* NO_DSA */
17862 #ifndef NO_RSA
17863 case WC_NID_rsaEncryption:
17864 return RSAk;
17865 #endif /* NO_RSA */
17866 #ifdef HAVE_ECC
17867 case WC_NID_X9_62_id_ecPublicKey:
17868 return ECDSAk;
17869 #endif /* HAVE_ECC */
17870 #ifdef HAVE_ED25519
17871 case WC_NID_ED25519:
17872 return ED25519k;
17873 #endif /* HAVE_ED25519 */
17874 #ifdef HAVE_ED448
17875 case WC_NID_ED448:
17876 return ED448k;
17877 #endif /* HAVE_ED448 */
17878 }
17879 break;
17880
17881
17882 #ifdef HAVE_ECC
17883 case oidCurveType:
17884 switch (nid) {
17885 case WC_NID_X9_62_prime192v1:
17886 return ECC_SECP192R1_OID;
17887 case WC_NID_X9_62_prime192v2:
17888 return ECC_PRIME192V2_OID;
17889 case WC_NID_X9_62_prime192v3:
17890 return ECC_PRIME192V3_OID;
17891 case WC_NID_X9_62_prime239v1:
17892 return ECC_PRIME239V1_OID;
17893 case WC_NID_X9_62_prime239v2:
17894 return ECC_PRIME239V2_OID;
17895 case WC_NID_X9_62_prime239v3:
17896 return ECC_PRIME239V3_OID;
17897 case WC_NID_X9_62_prime256v1:
17898 return ECC_SECP256R1_OID;
17899 case WC_NID_secp112r1:
17900 return ECC_SECP112R1_OID;
17901 case WC_NID_secp112r2:
17902 return ECC_SECP112R2_OID;
17903 case WC_NID_secp128r1:
17904 return ECC_SECP128R1_OID;
17905 case WC_NID_secp128r2:
17906 return ECC_SECP128R2_OID;
17907 case WC_NID_secp160r1:
17908 return ECC_SECP160R1_OID;
17909 case WC_NID_secp160r2:
17910 return ECC_SECP160R2_OID;
17911 case WC_NID_secp224r1:
17912 return ECC_SECP224R1_OID;
17913 case WC_NID_secp384r1:
17914 return ECC_SECP384R1_OID;
17915 case WC_NID_secp521r1:
17916 return ECC_SECP521R1_OID;
17917 case WC_NID_secp160k1:
17918 return ECC_SECP160K1_OID;
17919 case WC_NID_secp192k1:
17920 return ECC_SECP192K1_OID;
17921 case WC_NID_secp224k1:
17922 return ECC_SECP224K1_OID;
17923 case WC_NID_secp256k1:
17924 return ECC_SECP256K1_OID;
17925 case WC_NID_brainpoolP160r1:
17926 return ECC_BRAINPOOLP160R1_OID;
17927 case WC_NID_brainpoolP192r1:
17928 return ECC_BRAINPOOLP192R1_OID;
17929 case WC_NID_brainpoolP224r1:
17930 return ECC_BRAINPOOLP224R1_OID;
17931 case WC_NID_brainpoolP256r1:
17932 return ECC_BRAINPOOLP256R1_OID;
17933 case WC_NID_brainpoolP320r1:
17934 return ECC_BRAINPOOLP320R1_OID;
17935 case WC_NID_brainpoolP384r1:
17936 return ECC_BRAINPOOLP384R1_OID;
17937 case WC_NID_brainpoolP512r1:
17938 return ECC_BRAINPOOLP512R1_OID;
17939 }
17940 break;
17941 #endif /* HAVE_ECC */
17942
17943 /* oidBlkType */
17944 case oidBlkType:
17945 switch (nid) {
17946 #ifdef WOLFSSL_AES_128
17947 case AES128CBCb:
17948 return AES128CBCb;
17949 #endif
17950 #ifdef WOLFSSL_AES_192
17951 case AES192CBCb:
17952 return AES192CBCb;
17953 #endif
17954 #ifdef WOLFSSL_AES_256
17955 case AES256CBCb:
17956 return AES256CBCb;
17957 #endif
17958 #ifndef NO_DES3
17959 case WC_NID_des:
17960 return DESb;
17961 case WC_NID_des3:
17962 return DES3b;
17963 #endif
17964 }
17965 break;
17966
17967 #ifdef HAVE_OCSP
17968 case oidOcspType:
17969 switch (nid) {
17970 case WC_NID_id_pkix_OCSP_basic:
17971 return OCSP_BASIC_OID;
17972 case OCSP_NONCE_OID:
17973 return OCSP_NONCE_OID;
17974 }
17975 break;
17976 #endif /* HAVE_OCSP */
17977
17978 /* oidCertExtType */
17979 case oidCertExtType:
17980 switch (nid) {
17981 case WC_NID_basic_constraints:
17982 return BASIC_CA_OID;
17983 case WC_NID_subject_alt_name:
17984 return ALT_NAMES_OID;
17985 case WC_NID_crl_distribution_points:
17986 return CRL_DIST_OID;
17987 case WC_NID_info_access:
17988 return AUTH_INFO_OID;
17989 case WC_NID_authority_key_identifier:
17990 return AUTH_KEY_OID;
17991 case WC_NID_subject_key_identifier:
17992 return SUBJ_KEY_OID;
17993 case WC_NID_inhibit_any_policy:
17994 return INHIBIT_ANY_OID;
17995 case WC_NID_key_usage:
17996 return KEY_USAGE_OID;
17997 case WC_NID_name_constraints:
17998 return NAME_CONS_OID;
17999 case WC_NID_certificate_policies:
18000 return CERT_POLICY_OID;
18001 case WC_NID_ext_key_usage:
18002 return EXT_KEY_USAGE_OID;
18003 }
18004 break;
18005
18006 /* oidCertAuthInfoType */
18007 case oidCertAuthInfoType:
18008 switch (nid) {
18009 case WC_NID_ad_OCSP:
18010 return AIA_OCSP_OID;
18011 case WC_NID_ad_ca_issuers:
18012 return AIA_CA_ISSUER_OID;
18013 }
18014 break;
18015
18016 /* oidCertPolicyType */
18017 case oidCertPolicyType:
18018 switch (nid) {
18019 case WC_NID_any_policy:
18020 return CP_ANY_OID;
18021 }
18022 break;
18023
18024 /* oidCertAltNameType */
18025 case oidCertAltNameType:
18026 switch (nid) {
18027 case WC_NID_hw_name_oid:
18028 return HW_NAME_OID;
18029 }
18030 break;
18031
18032 /* oidCertKeyUseType */
18033 case oidCertKeyUseType:
18034 switch (nid) {
18035 case WC_NID_anyExtendedKeyUsage:
18036 return EKU_ANY_OID;
18037 case EKU_SERVER_AUTH_OID:
18038 return EKU_SERVER_AUTH_OID;
18039 case EKU_CLIENT_AUTH_OID:
18040 return EKU_CLIENT_AUTH_OID;
18041 case EKU_OCSP_SIGN_OID:
18042 return EKU_OCSP_SIGN_OID;
18043 }
18044 break;
18045
18046 /* oidKdfType */
18047 case oidKdfType:
18048 switch (nid) {
18049 case PBKDF2_OID:
18050 return PBKDF2_OID;
18051 }
18052 break;
18053
18054 /* oidPBEType */
18055 case oidPBEType:
18056 switch (nid) {
18057 case PBE_SHA1_RC4_128:
18058 return PBE_SHA1_RC4_128;
18059 case PBE_SHA1_DES:
18060 return PBE_SHA1_DES;
18061 case PBE_SHA1_DES3:
18062 return PBE_SHA1_DES3;
18063 }
18064 break;
18065
18066 /* oidKeyWrapType */
18067 case oidKeyWrapType:
18068 switch (nid) {
18069 #ifdef WOLFSSL_AES_128
18070 case AES128_WRAP:
18071 return AES128_WRAP;
18072 #endif
18073 #ifdef WOLFSSL_AES_192
18074 case AES192_WRAP:
18075 return AES192_WRAP;
18076 #endif
18077 #ifdef WOLFSSL_AES_256
18078 case AES256_WRAP:
18079 return AES256_WRAP;
18080 #endif
18081 }
18082 break;
18083
18084 /* oidCmsKeyAgreeType */
18085 case oidCmsKeyAgreeType:
18086 switch (nid) {
18087 #ifndef NO_SHA
18088 case dhSinglePass_stdDH_sha1kdf_scheme:
18089 return dhSinglePass_stdDH_sha1kdf_scheme;
18090 #endif
18091 #ifdef WOLFSSL_SHA224
18092 case dhSinglePass_stdDH_sha224kdf_scheme:
18093 return dhSinglePass_stdDH_sha224kdf_scheme;
18094 #endif
18095 #ifndef NO_SHA256
18096 case dhSinglePass_stdDH_sha256kdf_scheme:
18097 return dhSinglePass_stdDH_sha256kdf_scheme;
18098 #endif
18099 #ifdef WOLFSSL_SHA384
18100 case dhSinglePass_stdDH_sha384kdf_scheme:
18101 return dhSinglePass_stdDH_sha384kdf_scheme;
18102 #endif
18103 #ifdef WOLFSSL_SHA512
18104 case dhSinglePass_stdDH_sha512kdf_scheme:
18105 return dhSinglePass_stdDH_sha512kdf_scheme;
18106 #endif
18107 }
18108 break;
18109
18110 /* oidCmsKeyAgreeType */
18111 #ifdef WOLFSSL_CERT_REQ
18112 case oidCsrAttrType:
18113 switch (nid) {
18114 case WC_NID_pkcs9_contentType:
18115 return PKCS9_CONTENT_TYPE_OID;
18116 case WC_NID_pkcs9_challengePassword:
18117 return CHALLENGE_PASSWORD_OID;
18118 case WC_NID_serialNumber:
18119 return SERIAL_NUMBER_OID;
18120 case WC_NID_userId:
18121 return USER_ID_OID;
18122 case WC_NID_surname:
18123 return SURNAME_OID;
18124 }
18125 break;
18126 #endif
18127
18128 default:
18129 WOLFSSL_MSG("NID not in table");
18130 /* MSVC warns without the cast */
18131 return (word32)-1;
18132 }
18133
18134 /* MSVC warns without the cast */
18135 return (word32)-1;
18136}
18137
18138int oid2nid(word32 oid, int grp)
18139{
18140 size_t i;
18141 /* get OID type */
18142 switch (grp) {
18143 /* oidHashType */
18144 case oidHashType:
18145 switch (oid) {
18146 #ifdef WOLFSSL_MD2
18147 case MD2h:
18148 return WC_NID_md2;
18149 #endif
18150 #ifndef NO_MD5
18151 case MD5h:
18152 return WC_NID_md5;
18153 #endif
18154 #ifndef NO_SHA
18155 case SHAh:
18156 return WC_NID_sha1;
18157 #endif
18158 case SHA224h:
18159 return WC_NID_sha224;
18160 #ifndef NO_SHA256
18161 case SHA256h:
18162 return WC_NID_sha256;
18163 #endif
18164 #ifdef WOLFSSL_SHA384
18165 case SHA384h:
18166 return WC_NID_sha384;
18167 #endif
18168 #ifdef WOLFSSL_SHA512
18169 case SHA512h:
18170 return WC_NID_sha512;
18171 #endif
18172 }
18173 break;
18174
18175 /* oidSigType */
18176 case oidSigType:
18177 switch (oid) {
18178 #ifndef NO_DSA
18179 case CTC_SHAwDSA:
18180 return WC_NID_dsaWithSHA1;
18181 case CTC_SHA256wDSA:
18182 return WC_NID_dsa_with_SHA256;
18183 #endif /* NO_DSA */
18184 #ifndef NO_RSA
18185 case CTC_MD2wRSA:
18186 return WC_NID_md2WithRSAEncryption;
18187 case CTC_MD5wRSA:
18188 return WC_NID_md5WithRSAEncryption;
18189 case CTC_SHAwRSA:
18190 return WC_NID_sha1WithRSAEncryption;
18191 case CTC_SHA224wRSA:
18192 return WC_NID_sha224WithRSAEncryption;
18193 case CTC_SHA256wRSA:
18194 return WC_NID_sha256WithRSAEncryption;
18195 case CTC_SHA384wRSA:
18196 return WC_NID_sha384WithRSAEncryption;
18197 case CTC_SHA512wRSA:
18198 return WC_NID_sha512WithRSAEncryption;
18199 #ifdef WOLFSSL_SHA3
18200 case CTC_SHA3_224wRSA:
18201 return WC_NID_RSA_SHA3_224;
18202 case CTC_SHA3_256wRSA:
18203 return WC_NID_RSA_SHA3_256;
18204 case CTC_SHA3_384wRSA:
18205 return WC_NID_RSA_SHA3_384;
18206 case CTC_SHA3_512wRSA:
18207 return WC_NID_RSA_SHA3_512;
18208 #endif
18209 #ifdef WC_RSA_PSS
18210 case CTC_RSASSAPSS:
18211 return WC_NID_rsassaPss;
18212 #endif
18213 #endif /* NO_RSA */
18214 #ifdef HAVE_ECC
18215 case CTC_SHAwECDSA:
18216 return WC_NID_ecdsa_with_SHA1;
18217 case CTC_SHA224wECDSA:
18218 return WC_NID_ecdsa_with_SHA224;
18219 case CTC_SHA256wECDSA:
18220 return WC_NID_ecdsa_with_SHA256;
18221 case CTC_SHA384wECDSA:
18222 return WC_NID_ecdsa_with_SHA384;
18223 case CTC_SHA512wECDSA:
18224 return WC_NID_ecdsa_with_SHA512;
18225 #ifdef WOLFSSL_SHA3
18226 case CTC_SHA3_224wECDSA:
18227 return WC_NID_ecdsa_with_SHA3_224;
18228 case CTC_SHA3_256wECDSA:
18229 return WC_NID_ecdsa_with_SHA3_256;
18230 case CTC_SHA3_384wECDSA:
18231 return WC_NID_ecdsa_with_SHA3_384;
18232 case CTC_SHA3_512wECDSA:
18233 return WC_NID_ecdsa_with_SHA3_512;
18234 #endif
18235 #endif /* HAVE_ECC */
18236 #ifdef HAVE_ED25519
18237 case CTC_ED25519:
18238 return WC_NID_ED25519;
18239 #endif /* HAVE_ED25519 */
18240 #ifdef HAVE_ED448
18241 case CTC_ED448:
18242 return WC_NID_ED448;
18243 #endif /* HAVE_ED448 */
18244 }
18245 break;
18246
18247 /* oidKeyType */
18248 case oidKeyType:
18249 switch (oid) {
18250 #ifndef NO_DSA
18251 case DSAk:
18252 return WC_NID_dsa;
18253 #endif /* NO_DSA */
18254 #ifndef NO_RSA
18255 case RSAk:
18256 return WC_NID_rsaEncryption;
18257 #ifdef WC_RSA_PSS
18258 case RSAPSSk:
18259 return WC_NID_rsassaPss;
18260 #endif
18261 #endif /* NO_RSA */
18262 #ifdef HAVE_ECC
18263 case ECDSAk:
18264 return WC_NID_X9_62_id_ecPublicKey;
18265 #endif /* HAVE_ECC */
18266 #ifdef HAVE_ED25519
18267 case ED25519k:
18268 return WC_NID_ED25519;
18269 #endif /* HAVE_ED25519 */
18270 #ifdef HAVE_ED448
18271 case ED448k:
18272 return WC_NID_ED448;
18273 #endif /* HAVE_ED448 */
18274 }
18275 break;
18276
18277
18278 #ifdef HAVE_ECC
18279 case oidCurveType:
18280 switch (oid) {
18281 case ECC_SECP192R1_OID:
18282 return WC_NID_X9_62_prime192v1;
18283 case ECC_PRIME192V2_OID:
18284 return WC_NID_X9_62_prime192v2;
18285 case ECC_PRIME192V3_OID:
18286 return WC_NID_X9_62_prime192v3;
18287 case ECC_PRIME239V1_OID:
18288 return WC_NID_X9_62_prime239v1;
18289 case ECC_PRIME239V2_OID:
18290 return WC_NID_X9_62_prime239v2;
18291 case ECC_PRIME239V3_OID:
18292 return WC_NID_X9_62_prime239v3;
18293 case ECC_SECP256R1_OID:
18294 return WC_NID_X9_62_prime256v1;
18295 case ECC_SECP112R1_OID:
18296 return WC_NID_secp112r1;
18297 case ECC_SECP112R2_OID:
18298 return WC_NID_secp112r2;
18299 case ECC_SECP128R1_OID:
18300 return WC_NID_secp128r1;
18301 case ECC_SECP128R2_OID:
18302 return WC_NID_secp128r2;
18303 case ECC_SECP160R1_OID:
18304 return WC_NID_secp160r1;
18305 case ECC_SECP160R2_OID:
18306 return WC_NID_secp160r2;
18307 case ECC_SECP224R1_OID:
18308 return WC_NID_secp224r1;
18309 case ECC_SECP384R1_OID:
18310 return WC_NID_secp384r1;
18311 case ECC_SECP521R1_OID:
18312 return WC_NID_secp521r1;
18313 case ECC_SECP160K1_OID:
18314 return WC_NID_secp160k1;
18315 case ECC_SECP192K1_OID:
18316 return WC_NID_secp192k1;
18317 case ECC_SECP224K1_OID:
18318 return WC_NID_secp224k1;
18319 case ECC_SECP256K1_OID:
18320 return WC_NID_secp256k1;
18321 case ECC_BRAINPOOLP160R1_OID:
18322 return WC_NID_brainpoolP160r1;
18323 case ECC_BRAINPOOLP192R1_OID:
18324 return WC_NID_brainpoolP192r1;
18325 case ECC_BRAINPOOLP224R1_OID:
18326 return WC_NID_brainpoolP224r1;
18327 case ECC_BRAINPOOLP256R1_OID:
18328 return WC_NID_brainpoolP256r1;
18329 case ECC_BRAINPOOLP320R1_OID:
18330 return WC_NID_brainpoolP320r1;
18331 case ECC_BRAINPOOLP384R1_OID:
18332 return WC_NID_brainpoolP384r1;
18333 case ECC_BRAINPOOLP512R1_OID:
18334 return WC_NID_brainpoolP512r1;
18335 }
18336 break;
18337 #endif /* HAVE_ECC */
18338
18339 /* oidBlkType */
18340 case oidBlkType:
18341 switch (oid) {
18342 #ifdef WOLFSSL_AES_128
18343 case AES128CBCb:
18344 return AES128CBCb;
18345 #endif
18346 #ifdef WOLFSSL_AES_192
18347 case AES192CBCb:
18348 return AES192CBCb;
18349 #endif
18350 #ifdef WOLFSSL_AES_256
18351 case AES256CBCb:
18352 return AES256CBCb;
18353 #endif
18354 #ifndef NO_DES3
18355 case DESb:
18356 return WC_NID_des;
18357 case DES3b:
18358 return WC_NID_des3;
18359 #endif
18360 }
18361 break;
18362
18363 #ifdef HAVE_OCSP
18364 case oidOcspType:
18365 switch (oid) {
18366 case OCSP_BASIC_OID:
18367 return WC_NID_id_pkix_OCSP_basic;
18368 case OCSP_NONCE_OID:
18369 return OCSP_NONCE_OID;
18370 }
18371 break;
18372 #endif /* HAVE_OCSP */
18373
18374 /* oidCertExtType */
18375 case oidCertExtType:
18376 switch (oid) {
18377 case BASIC_CA_OID:
18378 return WC_NID_basic_constraints;
18379 case ALT_NAMES_OID:
18380 return WC_NID_subject_alt_name;
18381 case CRL_DIST_OID:
18382 return WC_NID_crl_distribution_points;
18383 case AUTH_INFO_OID:
18384 return WC_NID_info_access;
18385 case AUTH_KEY_OID:
18386 return WC_NID_authority_key_identifier;
18387 case SUBJ_KEY_OID:
18388 return WC_NID_subject_key_identifier;
18389 case INHIBIT_ANY_OID:
18390 return WC_NID_inhibit_any_policy;
18391 case KEY_USAGE_OID:
18392 return WC_NID_key_usage;
18393 case NAME_CONS_OID:
18394 return WC_NID_name_constraints;
18395 case CERT_POLICY_OID:
18396 return WC_NID_certificate_policies;
18397 case EXT_KEY_USAGE_OID:
18398 return WC_NID_ext_key_usage;
18399 }
18400 break;
18401
18402 /* oidCertAuthInfoType */
18403 case oidCertAuthInfoType:
18404 switch (oid) {
18405 case AIA_OCSP_OID:
18406 return WC_NID_ad_OCSP;
18407 case AIA_CA_ISSUER_OID:
18408 return WC_NID_ad_ca_issuers;
18409 }
18410 break;
18411
18412 /* oidCertPolicyType */
18413 case oidCertPolicyType:
18414 switch (oid) {
18415 case CP_ANY_OID:
18416 return WC_NID_any_policy;
18417 }
18418 break;
18419
18420 /* oidCertAltNameType */
18421 case oidCertAltNameType:
18422 switch (oid) {
18423 case HW_NAME_OID:
18424 return WC_NID_hw_name_oid;
18425 }
18426 break;
18427
18428 /* oidCertKeyUseType */
18429 case oidCertKeyUseType:
18430 switch (oid) {
18431 case EKU_ANY_OID:
18432 return WC_NID_anyExtendedKeyUsage;
18433 case EKU_SERVER_AUTH_OID:
18434 return EKU_SERVER_AUTH_OID;
18435 case EKU_CLIENT_AUTH_OID:
18436 return EKU_CLIENT_AUTH_OID;
18437 case EKU_OCSP_SIGN_OID:
18438 return EKU_OCSP_SIGN_OID;
18439 }
18440 break;
18441
18442 /* oidKdfType */
18443 case oidKdfType:
18444 switch (oid) {
18445 case PBKDF2_OID:
18446 return PBKDF2_OID;
18447 }
18448 break;
18449
18450 /* oidPBEType */
18451 case oidPBEType:
18452 switch (oid) {
18453 case PBE_SHA1_RC4_128:
18454 return PBE_SHA1_RC4_128;
18455 case PBE_SHA1_DES:
18456 return PBE_SHA1_DES;
18457 case PBE_SHA1_DES3:
18458 return PBE_SHA1_DES3;
18459 }
18460 break;
18461
18462 /* oidKeyWrapType */
18463 case oidKeyWrapType:
18464 switch (oid) {
18465 #ifdef WOLFSSL_AES_128
18466 case AES128_WRAP:
18467 return AES128_WRAP;
18468 #endif
18469 #ifdef WOLFSSL_AES_192
18470 case AES192_WRAP:
18471 return AES192_WRAP;
18472 #endif
18473 #ifdef WOLFSSL_AES_256
18474 case AES256_WRAP:
18475 return AES256_WRAP;
18476 #endif
18477 }
18478 break;
18479
18480 /* oidCmsKeyAgreeType */
18481 case oidCmsKeyAgreeType:
18482 switch (oid) {
18483 #ifndef NO_SHA
18484 case dhSinglePass_stdDH_sha1kdf_scheme:
18485 return dhSinglePass_stdDH_sha1kdf_scheme;
18486 #endif
18487 #ifdef WOLFSSL_SHA224
18488 case dhSinglePass_stdDH_sha224kdf_scheme:
18489 return dhSinglePass_stdDH_sha224kdf_scheme;
18490 #endif
18491 #ifndef NO_SHA256
18492 case dhSinglePass_stdDH_sha256kdf_scheme:
18493 return dhSinglePass_stdDH_sha256kdf_scheme;
18494 #endif
18495 #ifdef WOLFSSL_SHA384
18496 case dhSinglePass_stdDH_sha384kdf_scheme:
18497 return dhSinglePass_stdDH_sha384kdf_scheme;
18498 #endif
18499 #ifdef WOLFSSL_SHA512
18500 case dhSinglePass_stdDH_sha512kdf_scheme:
18501 return dhSinglePass_stdDH_sha512kdf_scheme;
18502 #endif
18503 }
18504 break;
18505
18506#ifdef WOLFSSL_CERT_REQ
18507 case oidCsrAttrType:
18508 switch (oid) {
18509 case PKCS9_CONTENT_TYPE_OID:
18510 return WC_NID_pkcs9_contentType;
18511 case CHALLENGE_PASSWORD_OID:
18512 return WC_NID_pkcs9_challengePassword;
18513 case SERIAL_NUMBER_OID:
18514 return WC_NID_serialNumber;
18515 case USER_ID_OID:
18516 return WC_NID_userId;
18517 }
18518 break;
18519#endif
18520
18521 default:
18522 WOLFSSL_MSG("OID not in table");
18523 }
18524 /* If not found in above switch then try the table */
18525 for (i = 0; i < WOLFSSL_OBJECT_INFO_SZ; i++) {
18526 if (wolfssl_object_info[i].id == (int)oid) {
18527 return wolfssl_object_info[i].nid;
18528 }
18529 }
18530
18531 return WOLFSSL_FATAL_ERROR;
18532}
18533
18534#endif /* OPENSSL_EXTRA || OPENSSL_EXTRA_X509_SMALL */
18535
18536#if defined(OPENSSL_EXTRA)
18537
18538/* frees all nodes in the current threads error queue
18539 *
18540 * id thread id. ERR_remove_state is depreciated and id is ignored. The
18541 * current threads queue will be free'd.
18542 */
18543void wolfSSL_ERR_remove_state(unsigned long id)
18544{
18545 WOLFSSL_ENTER("wolfSSL_ERR_remove_state");
18546 (void)id;
18547 if (wc_ERR_remove_state() != 0) {
18548 WOLFSSL_MSG("Error with removing the state");
18549 }
18550}
18551
18552#endif /* OPENSSL_EXTRA */
18553
18554#ifdef WOLFSSL_STATIC_EPHEMERAL
18555int wolfSSL_StaticEphemeralKeyLoad(WOLFSSL* ssl, int keyAlgo, void* keyPtr)
18556{
18557 int ret;
18558 word32 idx = 0;
18559 DerBuffer* der = NULL;
18560
18561 if (ssl == NULL || ssl->ctx == NULL || keyPtr == NULL) {
18562 return BAD_FUNC_ARG;
18563 }
18564
18565#ifndef SINGLE_THREADED
18566 if (!ssl->ctx->staticKELockInit) {
18567 return BUFFER_E; /* no keys set */
18568 }
18569 ret = wc_LockMutex(&ssl->ctx->staticKELock);
18570 if (ret != 0) {
18571 return ret;
18572 }
18573#endif
18574
18575 ret = BUFFER_E; /* set default error */
18576 switch (keyAlgo) {
18577 #ifndef NO_DH
18578 case WC_PK_TYPE_DH:
18579 if (ssl != NULL)
18580 der = ssl->staticKE.dhKey;
18581 if (der == NULL)
18582 der = ssl->ctx->staticKE.dhKey;
18583 if (der != NULL) {
18584 DhKey* key = (DhKey*)keyPtr;
18585 WOLFSSL_MSG("Using static DH key");
18586 ret = wc_DhKeyDecode(der->buffer, &idx, key, der->length);
18587 }
18588 break;
18589 #endif
18590 #ifdef HAVE_ECC
18591 case WC_PK_TYPE_ECDH:
18592 if (ssl != NULL)
18593 der = ssl->staticKE.ecKey;
18594 if (der == NULL)
18595 der = ssl->ctx->staticKE.ecKey;
18596 if (der != NULL) {
18597 ecc_key* key = (ecc_key*)keyPtr;
18598 WOLFSSL_MSG("Using static ECDH key");
18599 ret = wc_EccPrivateKeyDecode(der->buffer, &idx, key,
18600 der->length);
18601 }
18602 break;
18603 #endif
18604 #ifdef HAVE_CURVE25519
18605 case WC_PK_TYPE_CURVE25519:
18606 if (ssl != NULL)
18607 der = ssl->staticKE.x25519Key;
18608 if (der == NULL)
18609 der = ssl->ctx->staticKE.x25519Key;
18610 if (der != NULL) {
18611 curve25519_key* key = (curve25519_key*)keyPtr;
18612 WOLFSSL_MSG("Using static X25519 key");
18613
18614 #ifdef WOLFSSL_CURVE25519_BLINDING
18615 ret = wc_curve25519_set_rng(key, ssl->rng);
18616 if (ret == 0)
18617 #endif
18618 ret = wc_Curve25519PrivateKeyDecode(der->buffer, &idx, key,
18619 der->length);
18620 }
18621 break;
18622 #endif
18623 #ifdef HAVE_CURVE448
18624 case WC_PK_TYPE_CURVE448:
18625 if (ssl != NULL)
18626 der = ssl->staticKE.x448Key;
18627 if (der == NULL)
18628 der = ssl->ctx->staticKE.x448Key;
18629 if (der != NULL) {
18630 curve448_key* key = (curve448_key*)keyPtr;
18631 WOLFSSL_MSG("Using static X448 key");
18632 ret = wc_Curve448PrivateKeyDecode(der->buffer, &idx, key,
18633 der->length);
18634 }
18635 break;
18636 #endif
18637 default:
18638 /* not supported */
18639 ret = NOT_COMPILED_IN;
18640 break;
18641 }
18642
18643#ifndef SINGLE_THREADED
18644 wc_UnLockMutex(&ssl->ctx->staticKELock);
18645#endif
18646 return ret;
18647}
18648
18649static int SetStaticEphemeralKey(WOLFSSL_CTX* ctx,
18650 StaticKeyExchangeInfo_t* staticKE, int keyAlgo, const char* key,
18651 unsigned int keySz, int format, void* heap)
18652{
18653 int ret = 0;
18654 DerBuffer* der = NULL;
18655 byte* keyBuf = NULL;
18656#ifndef NO_FILESYSTEM
18657 const char* keyFile = NULL;
18658#endif
18659
18660 /* allow empty key to free buffer */
18661 if (staticKE == NULL || (key == NULL && keySz > 0)) {
18662 return BAD_FUNC_ARG;
18663 }
18664
18665 WOLFSSL_ENTER("SetStaticEphemeralKey");
18666
18667 /* if just free'ing key then skip loading */
18668 if (key != NULL) {
18669 #ifndef NO_FILESYSTEM
18670 /* load file from filesystem */
18671 if (key != NULL && keySz == 0) {
18672 size_t keyBufSz = 0;
18673 keyFile = (const char*)key;
18674 ret = wc_FileLoad(keyFile, &keyBuf, &keyBufSz, heap);
18675 if (ret != 0) {
18676 return ret;
18677 }
18678 keySz = (unsigned int)keyBufSz;
18679 }
18680 else
18681 #endif
18682 {
18683 /* use as key buffer directly */
18684 keyBuf = (byte*)key;
18685 }
18686
18687 if (format == WOLFSSL_FILETYPE_PEM) {
18688 #ifdef WOLFSSL_PEM_TO_DER
18689 int keyFormat = 0;
18690 ret = PemToDer(keyBuf, keySz, PRIVATEKEY_TYPE, &der,
18691 heap, NULL, &keyFormat);
18692 /* auto detect key type */
18693 if (ret == 0 && keyAlgo == WC_PK_TYPE_NONE) {
18694 if (keyFormat == ECDSAk)
18695 keyAlgo = WC_PK_TYPE_ECDH;
18696 else if (keyFormat == X25519k)
18697 keyAlgo = WC_PK_TYPE_CURVE25519;
18698 else
18699 keyAlgo = WC_PK_TYPE_DH;
18700 }
18701 #else
18702 ret = NOT_COMPILED_IN;
18703 #endif
18704 }
18705 else {
18706 /* Detect PK type (if required) */
18707 #ifdef HAVE_ECC
18708 if (keyAlgo == WC_PK_TYPE_NONE) {
18709 word32 idx = 0;
18710 WC_DECLARE_VAR(eccKey, ecc_key, 1, heap);
18711 WC_ALLOC_VAR_EX(eccKey, ecc_key, 1, heap, DYNAMIC_TYPE_ECC,
18712 ret = MEMORY_E);
18713 if (ret == 0)
18714 ret = wc_ecc_init_ex(eccKey, heap, INVALID_DEVID);
18715 if (ret == 0) {
18716 ret = wc_EccPrivateKeyDecode(keyBuf, &idx, eccKey, keySz);
18717 if (ret == 0)
18718 keyAlgo = WC_PK_TYPE_ECDH;
18719 wc_ecc_free(eccKey);
18720 ret = 0; /* clear error to enable key-type detect cascade */
18721 }
18722 WC_FREE_VAR_EX(eccKey, heap, DYNAMIC_TYPE_ECC);
18723 }
18724 #endif
18725 #if !defined(NO_DH) && defined(WOLFSSL_DH_EXTRA)
18726 if (keyAlgo == WC_PK_TYPE_NONE) {
18727 word32 idx = 0;
18728 WC_DECLARE_VAR(dhKey, DhKey, 1, heap);
18729 WC_ALLOC_VAR_EX(dhKey, DhKey, 1, heap, DYNAMIC_TYPE_DH,
18730 ret = MEMORY_E);
18731 if (ret == 0)
18732 ret = wc_InitDhKey_ex(dhKey, heap, INVALID_DEVID);
18733 if (ret == 0) {
18734 ret = wc_DhKeyDecode(keyBuf, &idx, dhKey, keySz);
18735 if (ret == 0)
18736 keyAlgo = WC_PK_TYPE_DH;
18737 wc_FreeDhKey(dhKey);
18738 ret = 0; /* clear error to enable key-type detect cascade */
18739 }
18740 WC_FREE_VAR_EX(dhKey, heap, DYNAMIC_TYPE_DH);
18741 }
18742 #endif
18743 #ifdef HAVE_CURVE25519
18744 if (keyAlgo == WC_PK_TYPE_NONE) {
18745 word32 idx = 0;
18746 WC_DECLARE_VAR(x25519Key, curve25519_key, 1, heap);
18747 WC_ALLOC_VAR_EX(x25519Key, curve25519_key, 1, heap,
18748 DYNAMIC_TYPE_CURVE25519, ret = MEMORY_E);
18749 if (ret == 0)
18750 ret = wc_curve25519_init_ex(x25519Key, heap, INVALID_DEVID);
18751 if (ret == 0) {
18752 ret = wc_Curve25519PrivateKeyDecode(keyBuf, &idx,
18753 x25519Key, keySz);
18754 if (ret == 0)
18755 keyAlgo = WC_PK_TYPE_CURVE25519;
18756 wc_curve25519_free(x25519Key);
18757 ret = 0; /* clear error to enable key-type detect cascade */
18758 }
18759 WC_FREE_VAR_EX(x25519Key, heap, DYNAMIC_TYPE_CURVE25519);
18760 }
18761 #endif
18762 #ifdef HAVE_CURVE448
18763 if (keyAlgo == WC_PK_TYPE_NONE) {
18764 word32 idx = 0;
18765 WC_DECLARE_VAR(x448Key, curve448_key, 1, heap);
18766 WC_ALLOC_VAR_EX(x448Key, curve448_key, 1, heap,
18767 DYNAMIC_TYPE_CURVE448, ret = MEMORY_E);
18768 if (ret == 0)
18769 ret = wc_curve448_init(x448Key);
18770 if (ret == 0) {
18771 ret = wc_Curve448PrivateKeyDecode(keyBuf, &idx, x448Key,
18772 keySz);
18773 if (ret == 0)
18774 keyAlgo = WC_PK_TYPE_CURVE448;
18775 wc_curve448_free(x448Key);
18776 ret = 0; /* clear error to enable key-type detect cascade */
18777 }
18778 WC_FREE_VAR_EX(x448Key, heap, DYNAMIC_TYPE_CURVE448);
18779 }
18780 #endif
18781
18782 if (keyAlgo != WC_PK_TYPE_NONE) {
18783 ret = AllocDer(&der, keySz, PRIVATEKEY_TYPE, heap);
18784 if (ret == 0) {
18785 XMEMCPY(der->buffer, keyBuf, keySz);
18786 }
18787 }
18788 }
18789 }
18790
18791#ifndef NO_FILESYSTEM
18792 /* done with keyFile buffer */
18793 if (keyFile && keyBuf) {
18794 ForceZero(keyBuf, keySz);
18795 XFREE(keyBuf, heap, DYNAMIC_TYPE_TMP_BUFFER);
18796 }
18797#endif
18798
18799#ifndef SINGLE_THREADED
18800 if (ret == 0 && !ctx->staticKELockInit) {
18801 ret = wc_InitMutex(&ctx->staticKELock);
18802 if (ret == 0) {
18803 ctx->staticKELockInit = 1;
18804 }
18805 }
18806#endif
18807 if (ret == 0
18808 #ifndef SINGLE_THREADED
18809 && (ret = wc_LockMutex(&ctx->staticKELock)) == 0
18810 #endif
18811 ) {
18812 switch (keyAlgo) {
18813 #ifndef NO_DH
18814 case WC_PK_TYPE_DH:
18815 FreeDer(&staticKE->dhKey);
18816 staticKE->dhKey = der; der = NULL;
18817 break;
18818 #endif
18819 #ifdef HAVE_ECC
18820 case WC_PK_TYPE_ECDH:
18821 FreeDer(&staticKE->ecKey);
18822 staticKE->ecKey = der; der = NULL;
18823 break;
18824 #endif
18825 #ifdef HAVE_CURVE25519
18826 case WC_PK_TYPE_CURVE25519:
18827 FreeDer(&staticKE->x25519Key);
18828 staticKE->x25519Key = der; der = NULL;
18829 break;
18830 #endif
18831 #ifdef HAVE_CURVE448
18832 case WC_PK_TYPE_CURVE448:
18833 FreeDer(&staticKE->x448Key);
18834 staticKE->x448Key = der; der = NULL;
18835 break;
18836 #endif
18837 default:
18838 /* not supported */
18839 ret = NOT_COMPILED_IN;
18840 break;
18841 }
18842
18843 #ifndef SINGLE_THREADED
18844 wc_UnLockMutex(&ctx->staticKELock);
18845 #endif
18846 }
18847
18848 if (ret != 0) {
18849 FreeDer(&der);
18850 }
18851
18852 (void)ctx; /* not used for single threaded */
18853
18854 WOLFSSL_LEAVE("SetStaticEphemeralKey", ret);
18855
18856 return ret;
18857}
18858
18859int wolfSSL_CTX_set_ephemeral_key(WOLFSSL_CTX* ctx, int keyAlgo,
18860 const char* key, unsigned int keySz, int format)
18861{
18862 if (ctx == NULL) {
18863 return BAD_FUNC_ARG;
18864 }
18865 return SetStaticEphemeralKey(ctx, &ctx->staticKE, keyAlgo,
18866 key, keySz, format, ctx->heap);
18867}
18868int wolfSSL_set_ephemeral_key(WOLFSSL* ssl, int keyAlgo,
18869 const char* key, unsigned int keySz, int format)
18870{
18871 if (ssl == NULL || ssl->ctx == NULL) {
18872 return BAD_FUNC_ARG;
18873 }
18874 return SetStaticEphemeralKey(ssl->ctx, &ssl->staticKE, keyAlgo,
18875 key, keySz, format, ssl->heap);
18876}
18877
18878static int GetStaticEphemeralKey(WOLFSSL_CTX* ctx, WOLFSSL* ssl,
18879 int keyAlgo, const unsigned char** key, unsigned int* keySz)
18880{
18881 int ret = 0;
18882 DerBuffer* der = NULL;
18883
18884 if (key) *key = NULL;
18885 if (keySz) *keySz = 0;
18886
18887#ifndef SINGLE_THREADED
18888 if (ctx->staticKELockInit &&
18889 (ret = wc_LockMutex(&ctx->staticKELock)) != 0) {
18890 return ret;
18891 }
18892#endif
18893
18894 switch (keyAlgo) {
18895 #ifndef NO_DH
18896 case WC_PK_TYPE_DH:
18897 if (ssl != NULL)
18898 der = ssl->staticKE.dhKey;
18899 if (der == NULL)
18900 der = ctx->staticKE.dhKey;
18901 break;
18902 #endif
18903 #ifdef HAVE_ECC
18904 case WC_PK_TYPE_ECDH:
18905 if (ssl != NULL)
18906 der = ssl->staticKE.ecKey;
18907 if (der == NULL)
18908 der = ctx->staticKE.ecKey;
18909 break;
18910 #endif
18911 #ifdef HAVE_CURVE25519
18912 case WC_PK_TYPE_CURVE25519:
18913 if (ssl != NULL)
18914 der = ssl->staticKE.x25519Key;
18915 if (der == NULL)
18916 der = ctx->staticKE.x25519Key;
18917 break;
18918 #endif
18919 #ifdef HAVE_CURVE448
18920 case WC_PK_TYPE_CURVE448:
18921 if (ssl != NULL)
18922 der = ssl->staticKE.x448Key;
18923 if (der == NULL)
18924 der = ctx->staticKE.x448Key;
18925 break;
18926 #endif
18927 default:
18928 /* not supported */
18929 ret = NOT_COMPILED_IN;
18930 break;
18931 }
18932
18933 if (der) {
18934 if (key)
18935 *key = der->buffer;
18936 if (keySz)
18937 *keySz = der->length;
18938 }
18939
18940#ifndef SINGLE_THREADED
18941 wc_UnLockMutex(&ctx->staticKELock);
18942#endif
18943
18944 return ret;
18945}
18946
18947/* returns pointer to currently loaded static ephemeral as ASN.1 */
18948/* this can be converted to PEM using wc_DerToPem */
18949int wolfSSL_CTX_get_ephemeral_key(WOLFSSL_CTX* ctx, int keyAlgo,
18950 const unsigned char** key, unsigned int* keySz)
18951{
18952 if (ctx == NULL) {
18953 return BAD_FUNC_ARG;
18954 }
18955
18956 return GetStaticEphemeralKey(ctx, NULL, keyAlgo, key, keySz);
18957}
18958int wolfSSL_get_ephemeral_key(WOLFSSL* ssl, int keyAlgo,
18959 const unsigned char** key, unsigned int* keySz)
18960{
18961 if (ssl == NULL || ssl->ctx == NULL) {
18962 return BAD_FUNC_ARG;
18963 }
18964
18965 return GetStaticEphemeralKey(ssl->ctx, ssl, keyAlgo, key, keySz);
18966}
18967
18968#endif /* WOLFSSL_STATIC_EPHEMERAL */
18969
18970#if defined(OPENSSL_EXTRA)
18971/* wolfSSL_THREADID_current is provided as a compat API with
18972 * CRYPTO_THREADID_current to register current thread id into given id object.
18973 * However, CRYPTO_THREADID_current API has been deprecated and no longer
18974 * exists in the OpenSSL 1.0.0 or later.This API only works as a stub
18975 * like as existing wolfSSL_THREADID_set_numeric.
18976 */
18977void wolfSSL_THREADID_current(WOLFSSL_CRYPTO_THREADID* id)
18978{
18979 (void)id;
18980 return;
18981}
18982/* wolfSSL_THREADID_hash is provided as a compatible API with
18983 * CRYPTO_THREADID_hash which returns a hash value calculated from the
18984 * specified thread id. However, CRYPTO_THREADID_hash API has been
18985 * deprecated and no longer exists in the OpenSSL 1.0.0 or later.
18986 * This API only works as a stub to returns 0. This behavior is
18987 * equivalent to the latest OpenSSL CRYPTO_THREADID_hash.
18988 */
18989unsigned long wolfSSL_THREADID_hash(const WOLFSSL_CRYPTO_THREADID* id)
18990{
18991 (void)id;
18992 return 0UL;
18993}
18994/* wolfSSL_set_ecdh_auto is provided as compatible API with
18995 * SSL_set_ecdh_auto to enable auto ecdh curve selection functionality.
18996 * Since this functionality is enabled by default in wolfSSL,
18997 * this API exists as a stub.
18998 */
18999int wolfSSL_set_ecdh_auto(WOLFSSL* ssl, int onoff)
19000{
19001 (void)ssl;
19002 (void)onoff;
19003 return WOLFSSL_SUCCESS;
19004}
19005/* wolfSSL_CTX_set_ecdh_auto is provided as compatible API with
19006 * SSL_CTX_set_ecdh_auto to enable auto ecdh curve selection functionality.
19007 * Since this functionality is enabled by default in wolfSSL,
19008 * this API exists as a stub.
19009 */
19010int wolfSSL_CTX_set_ecdh_auto(WOLFSSL_CTX* ctx, int onoff)
19011{
19012 (void)ctx;
19013 (void)onoff;
19014 return WOLFSSL_SUCCESS;
19015}
19016
19017/* wolfSSL_CTX_set_dh_auto is provided as compatible API with
19018 * SSL_CTX_set_dh_auto to enable auto dh selection functionality.
19019 * Since this functionality is enabled by default in wolfSSL,
19020 * this API exists as a stub.
19021 */
19022int wolfSSL_CTX_set_dh_auto(WOLFSSL_CTX* ctx, int onoff)
19023{
19024 (void)ctx;
19025 (void)onoff;
19026 return WOLFSSL_SUCCESS;
19027}
19028
19029/**
19030 * Set security level (wolfSSL doesn't support setting the security level).
19031 *
19032 * The security level can only be set through a system wide crypto-policy
19033 * with wolfSSL_crypto_policy_enable().
19034 *
19035 * @param ctx a pointer to WOLFSSL_CTX structure
19036 * @param level security level
19037 */
19038void wolfSSL_CTX_set_security_level(WOLFSSL_CTX* ctx, int level)
19039{
19040 WOLFSSL_ENTER("wolfSSL_CTX_set_security_level");
19041 (void)ctx;
19042 (void)level;
19043}
19044
19045int wolfSSL_CTX_get_security_level(const WOLFSSL_CTX * ctx)
19046{
19047 WOLFSSL_ENTER("wolfSSL_CTX_get_security_level");
19048 #if defined(WOLFSSL_SYS_CRYPTO_POLICY)
19049 if (ctx == NULL) {
19050 return BAD_FUNC_ARG;
19051 }
19052
19053 return ctx->secLevel;
19054 #else
19055 (void)ctx;
19056 return 0;
19057 #endif /* WOLFSSL_SYS_CRYPTO_POLICY */
19058}
19059
19060#if defined(OPENSSL_EXTRA) && defined(HAVE_SECRET_CALLBACK)
19061/*
19062 * This API accepts a user callback which puts key-log records into
19063 * a KEY LOGFILE. The callback is stored into a CTX and propagated to
19064 * each SSL object on its creation timing.
19065 */
19066void wolfSSL_CTX_set_keylog_callback(WOLFSSL_CTX* ctx,
19067 wolfSSL_CTX_keylog_cb_func cb)
19068{
19069 WOLFSSL_ENTER("wolfSSL_CTX_set_keylog_callback");
19070 /* stores the callback into WOLFSSL_CTX */
19071 if (ctx != NULL) {
19072 ctx->keyLogCb = cb;
19073 }
19074}
19075wolfSSL_CTX_keylog_cb_func wolfSSL_CTX_get_keylog_callback(
19076 const WOLFSSL_CTX* ctx)
19077{
19078 WOLFSSL_ENTER("wolfSSL_CTX_get_keylog_callback");
19079 if (ctx != NULL)
19080 return ctx->keyLogCb;
19081 return NULL;
19082}
19083#endif /* OPENSSL_EXTRA && HAVE_SECRET_CALLBACK */
19084
19085#endif /* OPENSSL_EXTRA */
19086
19087#ifdef WOLFSSL_THREADED_CRYPT
19088int wolfSSL_AsyncEncryptReady(WOLFSSL* ssl, int idx)
19089{
19090 ThreadCrypt* encrypt;
19091
19092 if (ssl == NULL) {
19093 return 0;
19094 }
19095
19096 encrypt = &ssl->buffers.encrypt[idx];
19097 return (encrypt->avail == 0) && (encrypt->done == 0);
19098}
19099
19100int wolfSSL_AsyncEncryptStop(WOLFSSL* ssl, int idx)
19101{
19102 ThreadCrypt* encrypt;
19103
19104 if (ssl == NULL) {
19105 return 1;
19106 }
19107
19108 encrypt = &ssl->buffers.encrypt[idx];
19109 return encrypt->stop;
19110}
19111
19112int wolfSSL_AsyncEncrypt(WOLFSSL* ssl, int idx)
19113{
19114 int ret = WC_NO_ERR_TRACE(NOT_COMPILED_IN);
19115 ThreadCrypt* encrypt = &ssl->buffers.encrypt[idx];
19116
19117 if (ssl->specs.bulk_cipher_algorithm == wolfssl_aes_gcm) {
19118 unsigned char* out = encrypt->buffer.buffer + encrypt->offset;
19119 unsigned char* input = encrypt->buffer.buffer + encrypt->offset;
19120 word32 encSz = encrypt->buffer.length - encrypt->offset;
19121
19122 ret =
19123#if !defined(NO_GCM_ENCRYPT_EXTRA) && \
19124 ((!defined(HAVE_FIPS) && !defined(HAVE_SELFTEST)) || \
19125 (defined(HAVE_FIPS_VERSION) && (HAVE_FIPS_VERSION >= 2)))
19126 wc_AesGcmEncrypt_ex
19127#else
19128 wc_AesGcmEncrypt
19129#endif
19130 (encrypt->encrypt.aes,
19131 out + AESGCM_EXP_IV_SZ, input + AESGCM_EXP_IV_SZ,
19132 encSz - AESGCM_EXP_IV_SZ - ssl->specs.aead_mac_size,
19133 encrypt->nonce, AESGCM_NONCE_SZ,
19134 out + encSz - ssl->specs.aead_mac_size,
19135 ssl->specs.aead_mac_size,
19136 encrypt->additional, AEAD_AUTH_DATA_SZ);
19137#if !defined(NO_PUBLIC_GCM_SET_IV) && \
19138 ((!defined(HAVE_FIPS) && !defined(HAVE_SELFTEST)) || \
19139 (defined(HAVE_FIPS_VERSION) && (HAVE_FIPS_VERSION >= 2)))
19140 XMEMCPY(out, encrypt->nonce + AESGCM_IMP_IV_SZ, AESGCM_EXP_IV_SZ);
19141#endif
19142 encrypt->done = 1;
19143 }
19144
19145 return ret;
19146}
19147
19148int wolfSSL_AsyncEncryptSetSignal(WOLFSSL* ssl, int idx,
19149 WOLFSSL_THREAD_SIGNAL signal, void* ctx)
19150{
19151 int ret = 0;
19152
19153 if (ssl == NULL) {
19154 ret = BAD_FUNC_ARG;
19155 }
19156 else {
19157 ssl->buffers.encrypt[idx].signal = signal;
19158 ssl->buffers.encrypt[idx].signalCtx = ctx;
19159 }
19160
19161 return ret;
19162}
19163#endif
19164
19165
19166#ifndef NO_CERT
19167#define WOLFSSL_X509_INCLUDED
19168#include "src/x509.c"
19169#endif
19170
19171/*******************************************************************************
19172 * START OF standard C library wrapping APIs
19173 ******************************************************************************/
19174#if defined(OPENSSL_ALL) || (defined(OPENSSL_EXTRA) && \
19175 (defined(HAVE_STUNNEL) || defined(WOLFSSL_NGINX) || \
19176 defined(HAVE_LIGHTY) || defined(WOLFSSL_HAPROXY) || \
19177 defined(WOLFSSL_OPENSSH)))
19178#ifndef NO_WOLFSSL_STUB
19179int wolfSSL_CRYPTO_set_mem_ex_functions(void *(*m) (size_t, const char *, int),
19180 void *(*r) (void *, size_t, const char *,
19181 int), void (*f) (void *))
19182{
19183 (void) m;
19184 (void) r;
19185 (void) f;
19186 WOLFSSL_ENTER("wolfSSL_CRYPTO_set_mem_ex_functions");
19187 WOLFSSL_STUB("CRYPTO_set_mem_ex_functions");
19188
19189 return WOLFSSL_FAILURE;
19190}
19191#endif
19192#endif
19193
19194#if defined(OPENSSL_EXTRA)
19195
19196/**
19197 * free allocated memory resource
19198 * @param str a pointer to resource to be freed
19199 * @param file dummy argument
19200 * @param line dummy argument
19201 */
19202void wolfSSL_CRYPTO_free(void *str, const char *file, int line)
19203{
19204 (void)file;
19205 (void)line;
19206 XFREE(str, 0, DYNAMIC_TYPE_TMP_BUFFER);
19207}
19208/**
19209 * allocate memory with size of num
19210 * @param num size of memory allocation to be malloced
19211 * @param file dummy argument
19212 * @param line dummy argument
19213 * @return a pointer to allocated memory on succssesful, otherwise NULL
19214 */
19215void *wolfSSL_CRYPTO_malloc(size_t num, const char *file, int line)
19216{
19217 (void)file;
19218 (void)line;
19219 return XMALLOC(num, 0, DYNAMIC_TYPE_TMP_BUFFER);
19220}
19221
19222#endif
19223
19224/*******************************************************************************
19225 * END OF standard C library wrapping APIs
19226 ******************************************************************************/
19227
19228/*******************************************************************************
19229 * START OF EX_DATA APIs
19230 ******************************************************************************/
19231#ifdef HAVE_EX_DATA
19232void wolfSSL_CRYPTO_cleanup_all_ex_data(void)
19233{
19234 WOLFSSL_ENTER("wolfSSL_CRYPTO_cleanup_all_ex_data");
19235}
19236
19237void* wolfSSL_CRYPTO_get_ex_data(const WOLFSSL_CRYPTO_EX_DATA* ex_data, int idx)
19238{
19239 WOLFSSL_ENTER("wolfSSL_CRYPTO_get_ex_data");
19240#ifdef MAX_EX_DATA
19241 if (ex_data && idx < MAX_EX_DATA && idx >= 0) {
19242 return ex_data->ex_data[idx];
19243 }
19244#else
19245 (void)ex_data;
19246 (void)idx;
19247#endif
19248 return NULL;
19249}
19250
19251int wolfSSL_CRYPTO_set_ex_data(WOLFSSL_CRYPTO_EX_DATA* ex_data, int idx,
19252 void *data)
19253{
19254 WOLFSSL_ENTER("wolfSSL_CRYPTO_set_ex_data");
19255#ifdef MAX_EX_DATA
19256 if (ex_data && idx < MAX_EX_DATA && idx >= 0) {
19257#ifdef HAVE_EX_DATA_CLEANUP_HOOKS
19258 if (ex_data->ex_data_cleanup_routines[idx]) {
19259 /* call cleanup then remove cleanup callback,
19260 * since different value is being set */
19261 if (ex_data->ex_data[idx])
19262 ex_data->ex_data_cleanup_routines[idx](ex_data->ex_data[idx]);
19263 ex_data->ex_data_cleanup_routines[idx] = NULL;
19264 }
19265#endif
19266 ex_data->ex_data[idx] = data;
19267 return WOLFSSL_SUCCESS;
19268 }
19269#else
19270 (void)ex_data;
19271 (void)idx;
19272 (void)data;
19273#endif
19274 return WOLFSSL_FAILURE;
19275}
19276
19277#ifdef HAVE_EX_DATA_CLEANUP_HOOKS
19278int wolfSSL_CRYPTO_set_ex_data_with_cleanup(
19279 WOLFSSL_CRYPTO_EX_DATA* ex_data,
19280 int idx,
19281 void *data,
19282 wolfSSL_ex_data_cleanup_routine_t cleanup_routine)
19283{
19284 WOLFSSL_ENTER("wolfSSL_CRYPTO_set_ex_data_with_cleanup");
19285 if (ex_data && idx < MAX_EX_DATA && idx >= 0) {
19286 if (ex_data->ex_data_cleanup_routines[idx] && ex_data->ex_data[idx])
19287 ex_data->ex_data_cleanup_routines[idx](ex_data->ex_data[idx]);
19288 ex_data->ex_data[idx] = data;
19289 ex_data->ex_data_cleanup_routines[idx] = cleanup_routine;
19290 return WOLFSSL_SUCCESS;
19291 }
19292 return WOLFSSL_FAILURE;
19293}
19294#endif /* HAVE_EX_DATA_CLEANUP_HOOKS */
19295#endif /* HAVE_EX_DATA */
19296
19297#ifdef HAVE_EX_DATA_CRYPTO
19298/**
19299 * Issues unique index for the class specified by class_index.
19300 * Other parameter except class_index are ignored.
19301 * Currently, following class_index are accepted:
19302 * - WOLF_CRYPTO_EX_INDEX_SSL
19303 * - WOLF_CRYPTO_EX_INDEX_SSL_CTX
19304 * - WOLF_CRYPTO_EX_INDEX_X509
19305 * @param class_index index one of CRYPTO_EX_INDEX_xxx
19306 * @param argp parameters to be saved
19307 * @param argl parameters to be saved
19308 * @param new_func a pointer to WOLFSSL_CRYPTO_EX_new
19309 * @param dup_func a pointer to WOLFSSL_CRYPTO_EX_dup
19310 * @param free_func a pointer to WOLFSSL_CRYPTO_EX_free
19311 * @return index value grater or equal to zero on success, -1 on failure.
19312 */
19313int wolfSSL_CRYPTO_get_ex_new_index(int class_index, long argl, void *argp,
19314 WOLFSSL_CRYPTO_EX_new* new_func,
19315 WOLFSSL_CRYPTO_EX_dup* dup_func,
19316 WOLFSSL_CRYPTO_EX_free* free_func)
19317{
19318 WOLFSSL_ENTER("wolfSSL_CRYPTO_get_ex_new_index");
19319
19320 return wolfssl_local_get_ex_new_index(class_index, argl, argp, new_func,
19321 dup_func, free_func);
19322}
19323#endif /* HAVE_EX_DATA_CRYPTO */
19324
19325/*******************************************************************************
19326 * END OF EX_DATA APIs
19327 ******************************************************************************/
19328
19329/*******************************************************************************
19330 * START OF BUF_MEM API
19331 ******************************************************************************/
19332
19333#if defined(OPENSSL_EXTRA)
19334
19335/* Begin functions for openssl/buffer.h */
19336WOLFSSL_BUF_MEM* wolfSSL_BUF_MEM_new(void)
19337{
19338 WOLFSSL_BUF_MEM* buf;
19339 buf = (WOLFSSL_BUF_MEM*)XMALLOC(sizeof(WOLFSSL_BUF_MEM), NULL,
19340 DYNAMIC_TYPE_OPENSSL);
19341 if (buf) {
19342 XMEMSET(buf, 0, sizeof(WOLFSSL_BUF_MEM));
19343 }
19344 return buf;
19345}
19346
19347/* non-compat API returns length of buffer on success */
19348int wolfSSL_BUF_MEM_grow_ex(WOLFSSL_BUF_MEM* buf, size_t len,
19349 char zeroFill)
19350{
19351
19352 int len_int = (int)len;
19353 int mx;
19354 char* tmp;
19355
19356 /* verify provided arguments */
19357 if (buf == NULL || len_int < 0) {
19358 return 0; /* BAD_FUNC_ARG; */
19359 }
19360
19361 /* check to see if fits in existing length */
19362 if (buf->length > len) {
19363 buf->length = len;
19364 return len_int;
19365 }
19366
19367 /* check to see if fits in max buffer */
19368 if (buf->max >= len) {
19369 if (buf->data != NULL && zeroFill) {
19370 XMEMSET(&buf->data[buf->length], 0, len - buf->length);
19371 }
19372 buf->length = len;
19373 return len_int;
19374 }
19375
19376 /* expand size, to handle growth */
19377 mx = (len_int + 3) / 3 * 4;
19378
19379#ifdef WOLFSSL_NO_REALLOC
19380 tmp = (char*)XMALLOC(mx, NULL, DYNAMIC_TYPE_OPENSSL);
19381 if (tmp != NULL && buf->data != NULL) {
19382 XMEMCPY(tmp, buf->data, len_int);
19383 XFREE(buf->data, NULL, DYNAMIC_TYPE_OPENSSL);
19384 buf->data = NULL;
19385 }
19386#else
19387 /* use realloc */
19388 tmp = (char*)XREALLOC(buf->data, mx, NULL, DYNAMIC_TYPE_OPENSSL);
19389#endif
19390
19391 if (tmp == NULL) {
19392 return 0; /* ERR_R_MALLOC_FAILURE; */
19393 }
19394 buf->data = tmp;
19395
19396 buf->max = (size_t)mx;
19397 if (zeroFill)
19398 XMEMSET(&buf->data[buf->length], 0, len - buf->length);
19399 buf->length = len;
19400
19401 return len_int;
19402
19403}
19404
19405/* returns length of buffer on success */
19406int wolfSSL_BUF_MEM_grow(WOLFSSL_BUF_MEM* buf, size_t len)
19407{
19408 return wolfSSL_BUF_MEM_grow_ex(buf, len, 1);
19409}
19410
19411/* non-compat API returns length of buffer on success */
19412int wolfSSL_BUF_MEM_resize(WOLFSSL_BUF_MEM* buf, size_t len)
19413{
19414 char* tmp;
19415 int mx;
19416
19417 /* verify provided arguments */
19418 if (buf == NULL || len == 0 || (int)len <= 0) {
19419 return 0; /* BAD_FUNC_ARG; */
19420 }
19421
19422 if (len == buf->length)
19423 return (int)len;
19424
19425 if (len > buf->length)
19426 return wolfSSL_BUF_MEM_grow_ex(buf, len, 0);
19427
19428 /* expand size, to handle growth */
19429 mx = ((int)len + 3) / 3 * 4;
19430
19431 /* We want to shrink the internal buffer */
19432#ifdef WOLFSSL_NO_REALLOC
19433 tmp = (char*)XMALLOC(mx, NULL, DYNAMIC_TYPE_OPENSSL);
19434 if (tmp != NULL && buf->data != NULL)
19435 {
19436 XMEMCPY(tmp, buf->data, len);
19437 XFREE(buf->data,NULL,DYNAMIC_TYPE_OPENSSL);
19438 buf->data = NULL;
19439 }
19440#else
19441 tmp = (char*)XREALLOC(buf->data, mx, NULL, DYNAMIC_TYPE_OPENSSL);
19442#endif
19443
19444 if (tmp == NULL)
19445 return 0;
19446
19447 buf->data = tmp;
19448 buf->length = len;
19449 buf->max = (size_t)mx;
19450
19451 return (int)len;
19452}
19453
19454void wolfSSL_BUF_MEM_free(WOLFSSL_BUF_MEM* buf)
19455{
19456 if (buf) {
19457 XFREE(buf->data, NULL, DYNAMIC_TYPE_OPENSSL);
19458 buf->data = NULL;
19459 buf->max = 0;
19460 buf->length = 0;
19461 XFREE(buf, NULL, DYNAMIC_TYPE_OPENSSL);
19462 }
19463}
19464/* End Functions for openssl/buffer.h */
19465
19466#endif /* OPENSSL_EXTRA */
19467
19468/*******************************************************************************
19469 * END OF BUF_MEM API
19470 ******************************************************************************/
19471
19472#define WOLFSSL_CONF_INCLUDED
19473#include <src/conf.c>
19474
19475/*******************************************************************************
19476 * START OF RAND API
19477 ******************************************************************************/
19478
19479#if defined(OPENSSL_EXTRA) && !defined(WOLFSSL_NO_OPENSSL_RAND_CB)
19480static int wolfSSL_RAND_InitMutex(void)
19481{
19482#ifndef WOLFSSL_MUTEX_INITIALIZER
19483 if (gRandMethodsInit == 0) {
19484 if (wc_InitMutex(&gRandMethodMutex) != 0) {
19485 WOLFSSL_MSG("Bad Init Mutex rand methods");
19486 return BAD_MUTEX_E;
19487 }
19488 gRandMethodsInit = 1;
19489 }
19490#endif
19491 return 0;
19492}
19493#endif
19494
19495#ifdef OPENSSL_EXTRA
19496
19497#if defined(HAVE_GETPID) && !defined(WOLFSSL_NO_GETPID) && \
19498 ((defined(HAVE_FIPS) && FIPS_VERSION3_LE(6,0,0)) || defined(HAVE_SELFTEST))
19499/* In older FIPS bundles add check for reseed here since it does not exist in
19500 * the older random.c certified files. */
19501static pid_t currentRandPid = 0;
19502#endif
19503
19504/* Checks if the global RNG has been created. If not then one is created.
19505 *
19506 * Returns WOLFSSL_SUCCESS when no error is encountered.
19507 */
19508int wolfSSL_RAND_Init(void)
19509{
19510 int ret = WC_NO_ERR_TRACE(WOLFSSL_FAILURE);
19511#ifdef HAVE_GLOBAL_RNG
19512 if (wc_LockMutex(&globalRNGMutex) == 0) {
19513 if (initGlobalRNG == 0) {
19514 ret = wc_InitRng(&globalRNG);
19515 if (ret == 0) {
19516 #if defined(HAVE_GETPID) && !defined(WOLFSSL_NO_GETPID) && \
19517 ((defined(HAVE_FIPS) && FIPS_VERSION3_LE(6,0,0)) || \
19518 defined(HAVE_SELFTEST))
19519
19520 currentRandPid = getpid();
19521 #endif
19522 initGlobalRNG = 1;
19523 ret = WOLFSSL_SUCCESS;
19524 }
19525 }
19526 else {
19527 /* GlobalRNG is already initialized */
19528 ret = WOLFSSL_SUCCESS;
19529 }
19530
19531 wc_UnLockMutex(&globalRNGMutex);
19532 }
19533#endif
19534 return ret;
19535}
19536
19537
19538/* WOLFSSL_SUCCESS on ok */
19539int wolfSSL_RAND_seed(const void* seed, int len)
19540{
19541#ifndef WOLFSSL_NO_OPENSSL_RAND_CB
19542 if (wolfSSL_RAND_InitMutex() == 0 && wc_LockMutex(&gRandMethodMutex) == 0) {
19543 if (gRandMethods && gRandMethods->seed) {
19544 int ret = gRandMethods->seed(seed, len);
19545 wc_UnLockMutex(&gRandMethodMutex);
19546 return ret;
19547 }
19548 wc_UnLockMutex(&gRandMethodMutex);
19549 }
19550#else
19551 (void)seed;
19552 (void)len;
19553#endif
19554
19555 /* Make sure global shared RNG (globalRNG) is initialized */
19556 return wolfSSL_RAND_Init();
19557}
19558
19559
19560/* Returns the path for reading seed data from.
19561 * Uses the env variable $RANDFILE first if set, if not then used $HOME/.rnd
19562 *
19563 * Note uses stdlib by default unless XGETENV macro is overwritten
19564 *
19565 * fname buffer to hold path
19566 * len length of fname buffer
19567 *
19568 * Returns a pointer to fname on success and NULL on failure
19569 */
19570const char* wolfSSL_RAND_file_name(char* fname, unsigned long len)
19571{
19572#if !defined(NO_FILESYSTEM) && defined(XGETENV) && !defined(NO_GETENV)
19573 char* rt;
19574
19575 WOLFSSL_ENTER("wolfSSL_RAND_file_name");
19576
19577 if (fname == NULL) {
19578 return NULL;
19579 }
19580
19581 XMEMSET(fname, 0, len);
19582
19583/* // NOLINTBEGIN(concurrency-mt-unsafe) */
19584 if ((rt = XGETENV("RANDFILE")) != NULL) {
19585 if (len > XSTRLEN(rt)) {
19586 XMEMCPY(fname, rt, XSTRLEN(rt));
19587 }
19588 else {
19589 WOLFSSL_MSG("RANDFILE too large for buffer");
19590 rt = NULL;
19591 }
19592 }
19593/* // NOLINTEND(concurrency-mt-unsafe) */
19594
19595 /* $RANDFILE was not set or is too large, check $HOME */
19596 if (rt == NULL) {
19597 const char ap[] = "/.rnd";
19598
19599 WOLFSSL_MSG("Environment variable RANDFILE not set");
19600
19601/* // NOLINTBEGIN(concurrency-mt-unsafe) */
19602 if ((rt = XGETENV("HOME")) == NULL) {
19603 #ifdef XALTHOMEVARNAME
19604 if ((rt = XGETENV(XALTHOMEVARNAME)) == NULL) {
19605 WOLFSSL_MSG("Environment variable HOME and " XALTHOMEVARNAME
19606 " not set");
19607 return NULL;
19608 }
19609 #else
19610 WOLFSSL_MSG("Environment variable HOME not set");
19611 return NULL;
19612 #endif
19613 }
19614/* // NOLINTEND(concurrency-mt-unsafe) */
19615
19616 if (len > XSTRLEN(rt) + XSTRLEN(ap)) {
19617 fname[0] = '\0';
19618 XSTRNCAT(fname, rt, len);
19619 XSTRNCAT(fname, ap, len - XSTRLEN(rt));
19620 return fname;
19621 }
19622 else {
19623 WOLFSSL_MSG("Path too large for buffer");
19624 return NULL;
19625 }
19626 }
19627
19628 return fname;
19629#else
19630 WOLFSSL_ENTER("wolfSSL_RAND_file_name");
19631 WOLFSSL_MSG("RAND_file_name requires filesystem and getenv support, "
19632 "not compiled in");
19633 (void)fname;
19634 (void)len;
19635 return NULL;
19636#endif
19637}
19638
19639
19640/* Writes 1024 bytes from the RNG to the given file name.
19641 *
19642 * fname name of file to write to
19643 *
19644 * Returns the number of bytes written
19645 */
19646int wolfSSL_RAND_write_file(const char* fname)
19647{
19648 int bytes = 0;
19649
19650 WOLFSSL_ENTER("wolfSSL_RAND_write_file");
19651
19652 if (fname == NULL) {
19653 return WOLFSSL_FAILURE;
19654 }
19655
19656#ifndef NO_FILESYSTEM
19657 {
19658 #ifndef WOLFSSL_SMALL_STACK
19659 unsigned char buf[1024];
19660 #else
19661 unsigned char* buf = (unsigned char *)XMALLOC(1024, NULL,
19662 DYNAMIC_TYPE_TMP_BUFFER);
19663 if (buf == NULL) {
19664 WOLFSSL_MSG("malloc failed");
19665 return WOLFSSL_FAILURE;
19666 }
19667 #endif
19668 bytes = 1024; /* default size of buf */
19669
19670 if (initGlobalRNG == 0 && wolfSSL_RAND_Init() != WOLFSSL_SUCCESS) {
19671 WOLFSSL_MSG("No RNG to use");
19672 WC_FREE_VAR_EX(buf, NULL, DYNAMIC_TYPE_TMP_BUFFER);
19673 return 0;
19674 }
19675
19676 if (wc_RNG_GenerateBlock(&globalRNG, buf, (word32)bytes) != 0) {
19677 WOLFSSL_MSG("Error generating random buffer");
19678 bytes = 0;
19679 }
19680 else {
19681 XFILE f;
19682
19683 #ifdef WOLFSSL_CHECK_MEM_ZERO
19684 wc_MemZero_Add("wolfSSL_RAND_write_file buf", buf, bytes);
19685 #endif
19686
19687 f = XFOPEN(fname, "wb");
19688 if (f == XBADFILE) {
19689 WOLFSSL_MSG("Error opening the file");
19690 bytes = 0;
19691 }
19692 else {
19693 size_t bytes_written = XFWRITE(buf, 1, (size_t)bytes, f);
19694 bytes = (int)bytes_written;
19695 XFCLOSE(f);
19696 }
19697 }
19698 ForceZero(buf, (word32)bytes);
19699 #ifdef WOLFSSL_SMALL_STACK
19700 XFREE(buf, NULL, DYNAMIC_TYPE_TMP_BUFFER);
19701 #elif defined(WOLFSSL_CHECK_MEM_ZERO)
19702 wc_MemZero_Check(buf, sizeof(buf));
19703 #endif
19704 }
19705#endif
19706
19707 return bytes;
19708}
19709
19710#ifndef FREERTOS_TCP
19711
19712/* These constant values are protocol values made by egd */
19713#if defined(USE_WOLFSSL_IO) && !defined(USE_WINDOWS_API) && \
19714 !defined(HAVE_FIPS) && defined(HAVE_HASHDRBG) && !defined(NETOS) && \
19715 defined(HAVE_SYS_UN_H)
19716 #define WOLFSSL_EGD_NBLOCK 0x01
19717 #include <sys/un.h>
19718#endif
19719
19720/* This collects entropy from the path nm and seeds the global PRNG with it.
19721 *
19722 * nm is the file path to the egd server
19723 *
19724 * Returns the number of bytes read.
19725 */
19726int wolfSSL_RAND_egd(const char* nm)
19727{
19728#ifdef WOLFSSL_EGD_NBLOCK
19729 struct sockaddr_un rem;
19730 int fd;
19731 int ret = WOLFSSL_SUCCESS;
19732 word32 bytes = 0;
19733 word32 idx = 0;
19734#ifndef WOLFSSL_SMALL_STACK
19735 unsigned char buf[256];
19736#else
19737 unsigned char* buf;
19738 buf = (unsigned char*)XMALLOC(256, NULL, DYNAMIC_TYPE_TMP_BUFFER);
19739 if (buf == NULL) {
19740 WOLFSSL_MSG("Not enough memory");
19741 return WOLFSSL_FATAL_ERROR;
19742 }
19743#endif
19744
19745 XMEMSET(&rem, 0, sizeof(struct sockaddr_un));
19746 if (nm == NULL) {
19747 WC_FREE_VAR_EX(buf, NULL, DYNAMIC_TYPE_TMP_BUFFER);
19748 return WOLFSSL_FATAL_ERROR;
19749 }
19750
19751 fd = wc_socket_cloexec(AF_UNIX, SOCK_STREAM, 0);
19752 if (fd < 0) {
19753 WOLFSSL_MSG("Error creating socket");
19754 WC_FREE_VAR_EX(buf, NULL, DYNAMIC_TYPE_TMP_BUFFER);
19755 return WOLFSSL_FATAL_ERROR;
19756 }
19757 rem.sun_family = AF_UNIX;
19758 XSTRNCPY(rem.sun_path, nm, sizeof(rem.sun_path) - 1);
19759 rem.sun_path[sizeof(rem.sun_path)-1] = '\0';
19760
19761 /* connect to egd server */
19762 if (connect(fd, (struct sockaddr*)&rem, sizeof(struct sockaddr_un)) == -1) {
19763 WOLFSSL_MSG("error connecting to egd server");
19764 ret = WOLFSSL_FATAL_ERROR;
19765 }
19766
19767#ifdef WOLFSSL_CHECK_MEM_ZERO
19768 if (ret == WOLFSSL_SUCCESS) {
19769 wc_MemZero_Add("wolfSSL_RAND_egd buf", buf, 256);
19770 }
19771#endif
19772 while (ret == WOLFSSL_SUCCESS && bytes < 255 && idx + 2 < 256) {
19773 buf[idx] = WOLFSSL_EGD_NBLOCK;
19774 buf[idx + 1] = 255 - bytes; /* request 255 bytes from server */
19775 ret = (int)write(fd, buf + idx, 2);
19776 if (ret != 2) {
19777 if (errno == EAGAIN) {
19778 ret = WOLFSSL_SUCCESS;
19779 continue;
19780 }
19781 WOLFSSL_MSG("error requesting entropy from egd server");
19782 ret = WOLFSSL_FATAL_ERROR;
19783 break;
19784 }
19785
19786 /* attempting to read */
19787 buf[idx] = 0;
19788 ret = (int)read(fd, buf + idx, 256 - bytes);
19789 if (ret == 0) {
19790 WOLFSSL_MSG("error reading entropy from egd server");
19791 ret = WOLFSSL_FATAL_ERROR;
19792 break;
19793 }
19794 if (ret > 0 && buf[idx] > 0) {
19795 bytes += buf[idx]; /* egd stores amount sent in first byte */
19796 if (bytes + idx > 255 || buf[idx] > ret) {
19797 WOLFSSL_MSG("Buffer error");
19798 ret = WOLFSSL_FATAL_ERROR;
19799 break;
19800 }
19801 XMEMMOVE(buf + idx, buf + idx + 1, buf[idx]);
19802 idx = bytes;
19803 ret = WOLFSSL_SUCCESS;
19804 if (bytes >= 255) {
19805 break;
19806 }
19807 }
19808 else {
19809 if (errno == EAGAIN || errno == EINTR) {
19810 WOLFSSL_MSG("EGD would read");
19811 ret = WOLFSSL_SUCCESS; /* try again */
19812 }
19813 else if (buf[idx] == 0) {
19814 /* if egd returned 0 then there is no more entropy to be had.
19815 Do not try more reads. */
19816 ret = WOLFSSL_SUCCESS;
19817 break;
19818 }
19819 else {
19820 WOLFSSL_MSG("Error with read");
19821 ret = WOLFSSL_FATAL_ERROR;
19822 }
19823 }
19824 }
19825
19826 if (bytes > 0 && ret == WOLFSSL_SUCCESS) {
19827 /* call to check global RNG is created */
19828 if (wolfSSL_RAND_Init() != WOLFSSL_SUCCESS) {
19829 WOLFSSL_MSG("Error with initializing global RNG structure");
19830 ret = WOLFSSL_FATAL_ERROR;
19831 }
19832 else if (wc_RNG_DRBG_Reseed(&globalRNG, (const byte*) buf, bytes)
19833 != 0) {
19834 WOLFSSL_MSG("Error with reseeding DRBG structure");
19835 ret = WOLFSSL_FATAL_ERROR;
19836 }
19837 #ifdef SHOW_SECRETS
19838 else { /* print out entropy found only when no error occurred */
19839 word32 i;
19840 printf("EGD Entropy = ");
19841 for (i = 0; i < bytes; i++) {
19842 printf("%02X", buf[i]);
19843 }
19844 printf("\n");
19845 }
19846 #endif
19847 }
19848
19849 ForceZero(buf, bytes);
19850#ifdef WOLFSSL_SMALL_STACK
19851 XFREE(buf, NULL, DYNAMIC_TYPE_TMP_BUFFER);
19852#elif defined(WOLFSSL_CHECK_MEM_ZERO)
19853 wc_MemZero_Check(buf, 256);
19854#endif
19855 close(fd);
19856
19857 if (ret == WOLFSSL_SUCCESS) {
19858 return (int)bytes;
19859 }
19860 else {
19861 return ret;
19862 }
19863#else
19864 WOLFSSL_MSG("Type of socket needed is not available");
19865 WOLFSSL_MSG("\tor using mode where DRBG API is not available");
19866 (void)nm;
19867
19868 return WOLFSSL_FATAL_ERROR;
19869#endif /* WOLFSSL_EGD_NBLOCK */
19870}
19871
19872#endif /* !FREERTOS_TCP */
19873
19874void wolfSSL_RAND_Cleanup(void)
19875{
19876#ifndef WOLFSSL_NO_OPENSSL_RAND_CB
19877 if (wolfSSL_RAND_InitMutex() == 0 && wc_LockMutex(&gRandMethodMutex) == 0) {
19878 if (gRandMethods && gRandMethods->cleanup)
19879 gRandMethods->cleanup();
19880 wc_UnLockMutex(&gRandMethodMutex);
19881 }
19882
19883 #ifndef WOLFSSL_MUTEX_INITIALIZER
19884 if (wc_FreeMutex(&gRandMethodMutex) == 0)
19885 gRandMethodsInit = 0;
19886 #endif
19887#endif
19888#ifdef HAVE_GLOBAL_RNG
19889 if (wc_LockMutex(&globalRNGMutex) == 0) {
19890 if (initGlobalRNG) {
19891 wc_FreeRng(&globalRNG);
19892 initGlobalRNG = 0;
19893 }
19894 wc_UnLockMutex(&globalRNGMutex);
19895 }
19896#endif
19897}
19898
19899/* returns WOLFSSL_SUCCESS if the bytes generated are valid otherwise
19900 * WOLFSSL_FAILURE */
19901int wolfSSL_RAND_pseudo_bytes(unsigned char* buf, int num)
19902{
19903 int ret;
19904 int hash;
19905 byte secret[DRBG_SEED_LEN]; /* secret length arbitrarily chosen */
19906
19907#ifndef WOLFSSL_NO_OPENSSL_RAND_CB
19908 if (wolfSSL_RAND_InitMutex() == 0 && wc_LockMutex(&gRandMethodMutex) == 0) {
19909 if (gRandMethods && gRandMethods->pseudorand) {
19910 ret = gRandMethods->pseudorand(buf, num);
19911 wc_UnLockMutex(&gRandMethodMutex);
19912 return ret;
19913 }
19914 wc_UnLockMutex(&gRandMethodMutex);
19915 }
19916#endif
19917
19918#ifdef WOLFSSL_HAVE_PRF
19919 #ifndef NO_SHA256
19920 hash = WC_SHA256;
19921 #elif defined(WOLFSSL_SHA384)
19922 hash = WC_SHA384;
19923 #elif !defined(NO_SHA)
19924 hash = WC_SHA;
19925 #elif !defined(NO_MD5)
19926 hash = WC_MD5;
19927 #endif
19928
19929 /* get secret value from source of entropy */
19930 ret = wolfSSL_RAND_bytes(secret, DRBG_SEED_LEN);
19931
19932 /* uses input buffer to seed for pseudo random number generation, each
19933 * thread will potentially have different results this way */
19934 if (ret == WOLFSSL_SUCCESS) {
19935 PRIVATE_KEY_UNLOCK();
19936 ret = wc_PRF(buf, num, secret, DRBG_SEED_LEN, (const byte*)buf, num,
19937 hash, NULL, INVALID_DEVID);
19938 PRIVATE_KEY_LOCK();
19939 ret = (ret == 0) ? WOLFSSL_SUCCESS: WOLFSSL_FAILURE;
19940 }
19941#else
19942 /* fall back to just doing wolfSSL_RAND_bytes if PRF not avialbale */
19943 ret = wolfSSL_RAND_bytes(buf, num);
19944 (void)hash;
19945 (void)secret;
19946#endif
19947 return ret;
19948}
19949
19950/* returns WOLFSSL_SUCCESS (1) if the bytes generated are valid otherwise 0
19951 * on failure */
19952int wolfSSL_RAND_bytes(unsigned char* buf, int num)
19953{
19954 int ret = 0;
19955 WC_RNG* rng = NULL;
19956 WC_DECLARE_VAR(tmpRNG, WC_RNG, 1, 0);
19957 int initTmpRng = 0;
19958#ifdef HAVE_GLOBAL_RNG
19959 int used_global = 0;
19960#endif
19961
19962 WOLFSSL_ENTER("wolfSSL_RAND_bytes");
19963 /* sanity check */
19964 if (buf == NULL || num < 0)
19965 /* return code compliant with OpenSSL */
19966 return 0;
19967
19968 /* if a RAND callback has been set try and use it */
19969#ifndef WOLFSSL_NO_OPENSSL_RAND_CB
19970 if (wolfSSL_RAND_InitMutex() == 0 && wc_LockMutex(&gRandMethodMutex) == 0) {
19971 if (gRandMethods && gRandMethods->bytes) {
19972 ret = gRandMethods->bytes(buf, num);
19973 wc_UnLockMutex(&gRandMethodMutex);
19974 return ret;
19975 }
19976 wc_UnLockMutex(&gRandMethodMutex);
19977 }
19978#endif
19979#ifdef HAVE_GLOBAL_RNG
19980 if (initGlobalRNG) {
19981 if (wc_LockMutex(&globalRNGMutex) != 0) {
19982 WOLFSSL_MSG("Bad Lock Mutex rng");
19983 return ret;
19984 }
19985 /* the above access to initGlobalRNG is racey -- recheck it now that we
19986 * have the lock.
19987 */
19988 if (initGlobalRNG) {
19989 #if defined(HAVE_GETPID) && !defined(WOLFSSL_NO_GETPID) && \
19990 ((defined(HAVE_FIPS) && FIPS_VERSION3_LE(6,0,0)) || \
19991 defined(HAVE_SELFTEST))
19992 pid_t p;
19993
19994 p = getpid();
19995 if (p != currentRandPid) {
19996 wc_UnLockMutex(&globalRNGMutex);
19997 if (wolfSSL_RAND_poll() != WOLFSSL_SUCCESS) {
19998 WOLFSSL_MSG("Issue with check pid and reseed");
19999 ret = WOLFSSL_FAILURE;
20000 }
20001
20002 /* reclaim lock after wolfSSL_RAND_poll */
20003 if (wc_LockMutex(&globalRNGMutex) != 0) {
20004 WOLFSSL_MSG("Bad Lock Mutex rng");
20005 return ret;
20006 }
20007 currentRandPid = p;
20008 }
20009 #endif
20010 rng = &globalRNG;
20011 used_global = 1;
20012 }
20013 else {
20014 wc_UnLockMutex(&globalRNGMutex);
20015 }
20016 }
20017
20018 if (used_global == 0)
20019#endif
20020 {
20021 WC_ALLOC_VAR_EX(tmpRNG, WC_RNG, 1, NULL, DYNAMIC_TYPE_RNG,
20022 return ret);
20023 if (wc_InitRng(tmpRNG) == 0) {
20024 rng = tmpRNG;
20025 initTmpRng = 1;
20026 }
20027 }
20028 if (rng) {
20029 /* handles size greater than RNG_MAX_BLOCK_LEN */
20030 int blockCount = num / RNG_MAX_BLOCK_LEN;
20031
20032 while (blockCount--) {
20033 ret = wc_RNG_GenerateBlock(rng, buf, RNG_MAX_BLOCK_LEN);
20034 if (ret != 0) {
20035 WOLFSSL_MSG("Bad wc_RNG_GenerateBlock");
20036 break;
20037 }
20038 num -= RNG_MAX_BLOCK_LEN;
20039 buf += RNG_MAX_BLOCK_LEN;
20040 }
20041
20042 if (ret == 0 && num)
20043 ret = wc_RNG_GenerateBlock(rng, buf, (word32)num);
20044
20045 if (ret != 0)
20046 WOLFSSL_MSG("Bad wc_RNG_GenerateBlock");
20047 else
20048 ret = WOLFSSL_SUCCESS;
20049 }
20050
20051#ifdef HAVE_GLOBAL_RNG
20052 if (used_global == 1)
20053 wc_UnLockMutex(&globalRNGMutex);
20054#endif
20055 if (initTmpRng)
20056 wc_FreeRng(tmpRNG);
20057 WC_FREE_VAR_EX(tmpRNG, NULL, DYNAMIC_TYPE_RNG);
20058
20059 return ret;
20060}
20061
20062
20063int wolfSSL_RAND_poll(void)
20064{
20065 byte entropy[16];
20066 int ret = 0;
20067 word32 entropy_sz = 16;
20068
20069 WOLFSSL_ENTER("wolfSSL_RAND_poll");
20070 if (initGlobalRNG == 0){
20071 WOLFSSL_MSG("Global RNG no Init");
20072 return WOLFSSL_FAILURE;
20073 }
20074 ret = wc_GenerateSeed(&globalRNG.seed, entropy, entropy_sz);
20075 if (ret != 0) {
20076 WOLFSSL_MSG("Bad wc_RNG_GenerateBlock");
20077 ret = WOLFSSL_FAILURE;
20078 }
20079 else {
20080#ifdef HAVE_HASHDRBG
20081 if (wc_LockMutex(&globalRNGMutex) != 0) {
20082 WOLFSSL_MSG("Bad Lock Mutex rng");
20083 return ret;
20084 }
20085
20086 ret = wc_RNG_DRBG_Reseed(&globalRNG, entropy, entropy_sz);
20087 if (ret != 0) {
20088 WOLFSSL_MSG("Error reseeding DRBG");
20089 ret = WOLFSSL_FAILURE;
20090 }
20091 else {
20092 ret = WOLFSSL_SUCCESS;
20093 }
20094 wc_UnLockMutex(&globalRNGMutex);
20095#elif defined(HAVE_INTEL_RDRAND)
20096 WOLFSSL_MSG("Not polling with RAND_poll, RDRAND used without "
20097 "HAVE_HASHDRBG");
20098 ret = WOLFSSL_SUCCESS;
20099#else
20100 WOLFSSL_MSG("RAND_poll called with HAVE_HASHDRBG not set");
20101 ret = WOLFSSL_FAILURE;
20102#endif
20103 }
20104
20105 return ret;
20106}
20107
20108 /* If a valid struct is provided with function pointers, will override
20109 RAND_seed, bytes, cleanup, add, pseudo_bytes and status. If a NULL
20110 pointer is passed in, it will cancel any previous function overrides.
20111
20112 Returns WOLFSSL_SUCCESS on success, WOLFSSL_FAILURE on failure. */
20113 int wolfSSL_RAND_set_rand_method(const WOLFSSL_RAND_METHOD *methods)
20114 {
20115 #ifndef WOLFSSL_NO_OPENSSL_RAND_CB
20116 if (wolfSSL_RAND_InitMutex() == 0 &&
20117 wc_LockMutex(&gRandMethodMutex) == 0) {
20118 gRandMethods = methods;
20119 wc_UnLockMutex(&gRandMethodMutex);
20120 return WOLFSSL_SUCCESS;
20121 }
20122 #else
20123 (void)methods;
20124 #endif
20125 return WOLFSSL_FAILURE;
20126 }
20127
20128 /* Returns WOLFSSL_SUCCESS if the RNG has been seeded with enough data */
20129 int wolfSSL_RAND_status(void)
20130 {
20131 int ret = WOLFSSL_SUCCESS;
20132 #ifndef WOLFSSL_NO_OPENSSL_RAND_CB
20133 if (wolfSSL_RAND_InitMutex() == 0 &&
20134 wc_LockMutex(&gRandMethodMutex) == 0) {
20135 if (gRandMethods && gRandMethods->status)
20136 ret = gRandMethods->status();
20137 wc_UnLockMutex(&gRandMethodMutex);
20138 }
20139 else {
20140 ret = WOLFSSL_FAILURE;
20141 }
20142 #else
20143 /* wolfCrypt provides enough seed internally, so return success */
20144 #endif
20145 return ret;
20146 }
20147
20148 void wolfSSL_RAND_add(const void* add, int len, double entropy)
20149 {
20150 #ifndef WOLFSSL_NO_OPENSSL_RAND_CB
20151 if (wolfSSL_RAND_InitMutex() == 0 &&
20152 wc_LockMutex(&gRandMethodMutex) == 0) {
20153 if (gRandMethods && gRandMethods->add) {
20154 /* callback has return code, but RAND_add does not */
20155 (void)gRandMethods->add(add, len, entropy);
20156 }
20157 wc_UnLockMutex(&gRandMethodMutex);
20158 }
20159 #else
20160 /* wolfSSL seeds/adds internally, use explicit RNG if you want
20161 to take control */
20162 (void)add;
20163 (void)len;
20164 (void)entropy;
20165 #endif
20166 }
20167
20168
20169#ifndef NO_WOLFSSL_STUB
20170void wolfSSL_RAND_screen(void)
20171{
20172 WOLFSSL_STUB("RAND_screen");
20173}
20174#endif
20175
20176int wolfSSL_RAND_load_file(const char* fname, long len)
20177{
20178 (void)fname;
20179 /* wolfCrypt provides enough entropy internally or will report error */
20180 if (len == -1)
20181 return 1024;
20182 else
20183 return (int)len;
20184}
20185
20186#endif /* OPENSSL_EXTRA */
20187
20188/*******************************************************************************
20189 * END OF RAND API
20190 ******************************************************************************/
20191
20192/*******************************************************************************
20193 * START OF EVP_CIPHER API
20194 ******************************************************************************/
20195
20196#ifdef OPENSSL_EXTRA
20197
20198 /* store for external read of iv, WOLFSSL_SUCCESS on success */
20199 int wolfSSL_StoreExternalIV(WOLFSSL_EVP_CIPHER_CTX* ctx)
20200 {
20201 WOLFSSL_ENTER("wolfSSL_StoreExternalIV");
20202
20203 if (ctx == NULL) {
20204 WOLFSSL_MSG("Bad function argument");
20205 return WOLFSSL_FATAL_ERROR;
20206 }
20207
20208 switch (ctx->cipherType) {
20209#ifndef NO_AES
20210#if defined(HAVE_AES_CBC) || defined(WOLFSSL_AES_DIRECT)
20211 case WC_AES_128_CBC_TYPE :
20212 case WC_AES_192_CBC_TYPE :
20213 case WC_AES_256_CBC_TYPE :
20214 WOLFSSL_MSG("AES CBC");
20215 XMEMCPY(ctx->iv, &ctx->cipher.aes.reg, ctx->ivSz);
20216 break;
20217#endif
20218#ifdef HAVE_AESGCM
20219 case WC_AES_128_GCM_TYPE :
20220 case WC_AES_192_GCM_TYPE :
20221 case WC_AES_256_GCM_TYPE :
20222 WOLFSSL_MSG("AES GCM");
20223 XMEMCPY(ctx->iv, &ctx->cipher.aes.reg, ctx->ivSz);
20224 break;
20225#endif /* HAVE_AESGCM */
20226#ifdef HAVE_AESCCM
20227 case WC_AES_128_CCM_TYPE :
20228 case WC_AES_192_CCM_TYPE :
20229 case WC_AES_256_CCM_TYPE :
20230 WOLFSSL_MSG("AES CCM");
20231 XMEMCPY(ctx->iv, &ctx->cipher.aes.reg, ctx->ivSz);
20232 break;
20233#endif /* HAVE_AESCCM */
20234#ifdef HAVE_AES_ECB
20235 case WC_AES_128_ECB_TYPE :
20236 case WC_AES_192_ECB_TYPE :
20237 case WC_AES_256_ECB_TYPE :
20238 WOLFSSL_MSG("AES ECB");
20239 break;
20240#endif
20241#ifdef WOLFSSL_AES_COUNTER
20242 case WC_AES_128_CTR_TYPE :
20243 case WC_AES_192_CTR_TYPE :
20244 case WC_AES_256_CTR_TYPE :
20245 WOLFSSL_MSG("AES CTR");
20246 XMEMCPY(ctx->iv, &ctx->cipher.aes.reg, WC_AES_BLOCK_SIZE);
20247 break;
20248#endif /* WOLFSSL_AES_COUNTER */
20249#ifdef WOLFSSL_AES_CFB
20250#if !defined(HAVE_SELFTEST) && !defined(HAVE_FIPS)
20251 case WC_AES_128_CFB1_TYPE:
20252 case WC_AES_192_CFB1_TYPE:
20253 case WC_AES_256_CFB1_TYPE:
20254 WOLFSSL_MSG("AES CFB1");
20255 break;
20256 case WC_AES_128_CFB8_TYPE:
20257 case WC_AES_192_CFB8_TYPE:
20258 case WC_AES_256_CFB8_TYPE:
20259 WOLFSSL_MSG("AES CFB8");
20260 break;
20261#endif /* !HAVE_SELFTEST && !HAVE_FIPS */
20262 case WC_AES_128_CFB128_TYPE:
20263 case WC_AES_192_CFB128_TYPE:
20264 case WC_AES_256_CFB128_TYPE:
20265 WOLFSSL_MSG("AES CFB128");
20266 break;
20267#endif /* WOLFSSL_AES_CFB */
20268#if defined(WOLFSSL_AES_OFB)
20269 case WC_AES_128_OFB_TYPE:
20270 case WC_AES_192_OFB_TYPE:
20271 case WC_AES_256_OFB_TYPE:
20272 WOLFSSL_MSG("AES OFB");
20273 break;
20274#endif /* WOLFSSL_AES_OFB */
20275#ifdef WOLFSSL_AES_XTS
20276 case WC_AES_128_XTS_TYPE:
20277 case WC_AES_256_XTS_TYPE:
20278 WOLFSSL_MSG("AES XTS");
20279 break;
20280#endif /* WOLFSSL_AES_XTS */
20281#endif /* NO_AES */
20282
20283#ifdef HAVE_ARIA
20284 case WC_ARIA_128_GCM_TYPE :
20285 case WC_ARIA_192_GCM_TYPE :
20286 case WC_ARIA_256_GCM_TYPE :
20287 WOLFSSL_MSG("ARIA GCM");
20288 XMEMCPY(ctx->iv, &ctx->cipher.aria.nonce, ARIA_BLOCK_SIZE);
20289 break;
20290#endif /* HAVE_ARIA */
20291
20292#ifndef NO_DES3
20293 case WC_DES_CBC_TYPE :
20294 WOLFSSL_MSG("DES CBC");
20295 XMEMCPY(ctx->iv, &ctx->cipher.des.reg, DES_BLOCK_SIZE);
20296 break;
20297
20298 case WC_DES_EDE3_CBC_TYPE :
20299 WOLFSSL_MSG("DES EDE3 CBC");
20300 XMEMCPY(ctx->iv, &ctx->cipher.des3.reg, DES_BLOCK_SIZE);
20301 break;
20302#endif
20303#ifdef WOLFSSL_DES_ECB
20304 case WC_DES_ECB_TYPE :
20305 WOLFSSL_MSG("DES ECB");
20306 break;
20307 case WC_DES_EDE3_ECB_TYPE :
20308 WOLFSSL_MSG("DES3 ECB");
20309 break;
20310#endif
20311 case WC_ARC4_TYPE :
20312 WOLFSSL_MSG("ARC4");
20313 break;
20314
20315#if defined(HAVE_CHACHA) && defined(HAVE_POLY1305)
20316 case WC_CHACHA20_POLY1305_TYPE:
20317 break;
20318#endif
20319
20320#ifdef HAVE_CHACHA
20321 case WC_CHACHA20_TYPE:
20322 break;
20323#endif
20324
20325#ifdef WOLFSSL_SM4_ECB
20326 case WC_SM4_ECB_TYPE:
20327 break;
20328#endif
20329#ifdef WOLFSSL_SM4_CBC
20330 case WC_SM4_CBC_TYPE:
20331 WOLFSSL_MSG("SM4 CBC");
20332 XMEMCPY(&ctx->cipher.sm4.iv, ctx->iv, SM4_BLOCK_SIZE);
20333 break;
20334#endif
20335#ifdef WOLFSSL_SM4_CTR
20336 case WC_SM4_CTR_TYPE:
20337 WOLFSSL_MSG("SM4 CTR");
20338 XMEMCPY(&ctx->cipher.sm4.iv, ctx->iv, SM4_BLOCK_SIZE);
20339 break;
20340#endif
20341#ifdef WOLFSSL_SM4_GCM
20342 case WC_SM4_GCM_TYPE:
20343 WOLFSSL_MSG("SM4 GCM");
20344 XMEMCPY(&ctx->cipher.sm4.iv, ctx->iv, SM4_BLOCK_SIZE);
20345 break;
20346#endif
20347#ifdef WOLFSSL_SM4_CCM
20348 case WC_SM4_CCM_TYPE:
20349 WOLFSSL_MSG("SM4 CCM");
20350 XMEMCPY(&ctx->cipher.sm4.iv, ctx->iv, SM4_BLOCK_SIZE);
20351 break;
20352#endif
20353
20354 case WC_NULL_CIPHER_TYPE :
20355 WOLFSSL_MSG("NULL");
20356 break;
20357
20358 default: {
20359 WOLFSSL_MSG("bad type");
20360 return WOLFSSL_FATAL_ERROR;
20361 }
20362 }
20363 return WOLFSSL_SUCCESS;
20364 }
20365
20366 /* set internal IV from external, WOLFSSL_SUCCESS on success */
20367 int wolfSSL_SetInternalIV(WOLFSSL_EVP_CIPHER_CTX* ctx)
20368 {
20369
20370 WOLFSSL_ENTER("wolfSSL_SetInternalIV");
20371
20372 if (ctx == NULL) {
20373 WOLFSSL_MSG("Bad function argument");
20374 return WOLFSSL_FATAL_ERROR;
20375 }
20376
20377 switch (ctx->cipherType) {
20378
20379#ifndef NO_AES
20380#if defined(HAVE_AES_CBC) || defined(WOLFSSL_AES_DIRECT)
20381 case WC_AES_128_CBC_TYPE :
20382 case WC_AES_192_CBC_TYPE :
20383 case WC_AES_256_CBC_TYPE :
20384 WOLFSSL_MSG("AES CBC");
20385 XMEMCPY(&ctx->cipher.aes.reg, ctx->iv, WC_AES_BLOCK_SIZE);
20386 break;
20387#endif
20388#ifdef HAVE_AESGCM
20389 case WC_AES_128_GCM_TYPE :
20390 case WC_AES_192_GCM_TYPE :
20391 case WC_AES_256_GCM_TYPE :
20392 WOLFSSL_MSG("AES GCM");
20393 XMEMCPY(&ctx->cipher.aes.reg, ctx->iv, WC_AES_BLOCK_SIZE);
20394 break;
20395#endif
20396#ifdef HAVE_AES_ECB
20397 case WC_AES_128_ECB_TYPE :
20398 case WC_AES_192_ECB_TYPE :
20399 case WC_AES_256_ECB_TYPE :
20400 WOLFSSL_MSG("AES ECB");
20401 break;
20402#endif
20403#ifdef WOLFSSL_AES_COUNTER
20404 case WC_AES_128_CTR_TYPE :
20405 case WC_AES_192_CTR_TYPE :
20406 case WC_AES_256_CTR_TYPE :
20407 WOLFSSL_MSG("AES CTR");
20408 XMEMCPY(&ctx->cipher.aes.reg, ctx->iv, WC_AES_BLOCK_SIZE);
20409 break;
20410#endif
20411
20412#endif /* NO_AES */
20413
20414#ifdef HAVE_ARIA
20415 case WC_ARIA_128_GCM_TYPE :
20416 case WC_ARIA_192_GCM_TYPE :
20417 case WC_ARIA_256_GCM_TYPE :
20418 WOLFSSL_MSG("ARIA GCM");
20419 XMEMCPY(&ctx->cipher.aria.nonce, ctx->iv, ARIA_BLOCK_SIZE);
20420 break;
20421#endif /* HAVE_ARIA */
20422
20423#ifndef NO_DES3
20424 case WC_DES_CBC_TYPE :
20425 WOLFSSL_MSG("DES CBC");
20426 XMEMCPY(&ctx->cipher.des.reg, ctx->iv, DES_BLOCK_SIZE);
20427 break;
20428
20429 case WC_DES_EDE3_CBC_TYPE :
20430 WOLFSSL_MSG("DES EDE3 CBC");
20431 XMEMCPY(&ctx->cipher.des3.reg, ctx->iv, DES_BLOCK_SIZE);
20432 break;
20433#endif
20434#ifdef WOLFSSL_DES_ECB
20435 case WC_DES_ECB_TYPE :
20436 WOLFSSL_MSG("DES ECB");
20437 break;
20438 case WC_DES_EDE3_ECB_TYPE :
20439 WOLFSSL_MSG("DES3 ECB");
20440 break;
20441#endif
20442
20443 case WC_ARC4_TYPE :
20444 WOLFSSL_MSG("ARC4");
20445 break;
20446
20447#if defined(HAVE_CHACHA) && defined(HAVE_POLY1305)
20448 case WC_CHACHA20_POLY1305_TYPE:
20449 break;
20450#endif
20451
20452#ifdef HAVE_CHACHA
20453 case WC_CHACHA20_TYPE:
20454 break;
20455#endif
20456
20457#ifdef WOLFSSL_SM4_ECB
20458 case WC_SM4_ECB_TYPE:
20459 break;
20460#endif
20461#ifdef WOLFSSL_SM4_CBC
20462 case WC_SM4_CBC_TYPE:
20463 WOLFSSL_MSG("SM4 CBC");
20464 XMEMCPY(ctx->iv, &ctx->cipher.sm4.iv, ctx->ivSz);
20465 break;
20466#endif
20467#ifdef WOLFSSL_SM4_CTR
20468 case WC_SM4_CTR_TYPE:
20469 WOLFSSL_MSG("SM4 CTR");
20470 XMEMCPY(ctx->iv, &ctx->cipher.sm4.iv, ctx->ivSz);
20471 break;
20472#endif
20473#ifdef WOLFSSL_SM4_GCM
20474 case WC_SM4_GCM_TYPE:
20475 WOLFSSL_MSG("SM4 GCM");
20476 XMEMCPY(ctx->iv, &ctx->cipher.sm4.iv, ctx->ivSz);
20477 break;
20478#endif
20479#ifdef WOLFSSL_SM4_CCM
20480 case WC_SM4_CCM_TYPE:
20481 WOLFSSL_MSG("SM4 CCM");
20482 XMEMCPY(ctx->iv, &ctx->cipher.sm4.iv, ctx->ivSz);
20483 break;
20484#endif
20485
20486 case WC_NULL_CIPHER_TYPE :
20487 WOLFSSL_MSG("NULL");
20488 break;
20489
20490 default: {
20491 WOLFSSL_MSG("bad type");
20492 return WOLFSSL_FATAL_ERROR;
20493 }
20494 }
20495 return WOLFSSL_SUCCESS;
20496 }
20497
20498#ifndef NO_DES3
20499
20500void wolfSSL_3des_iv(WOLFSSL_EVP_CIPHER_CTX* ctx, int doset,
20501 unsigned char* iv, int len)
20502{
20503 (void)len;
20504
20505 WOLFSSL_MSG("wolfSSL_3des_iv");
20506
20507 if (ctx == NULL || iv == NULL) {
20508 WOLFSSL_MSG("Bad function argument");
20509 return;
20510 }
20511
20512 if (doset)
20513 wc_Des3_SetIV(&ctx->cipher.des3, iv); /* OpenSSL compat, no ret */
20514 else
20515 XMEMCPY(iv, &ctx->cipher.des3.reg, DES_BLOCK_SIZE);
20516}
20517
20518#endif /* NO_DES3 */
20519
20520
20521#ifndef NO_AES
20522
20523void wolfSSL_aes_ctr_iv(WOLFSSL_EVP_CIPHER_CTX* ctx, int doset,
20524 unsigned char* iv, int len)
20525{
20526 (void)len;
20527
20528 WOLFSSL_MSG("wolfSSL_aes_ctr_iv");
20529
20530 if (ctx == NULL || iv == NULL) {
20531 WOLFSSL_MSG("Bad function argument");
20532 return;
20533 }
20534
20535 if (doset)
20536 (void)wc_AesSetIV(&ctx->cipher.aes, iv); /* OpenSSL compat, no ret */
20537 else
20538 XMEMCPY(iv, &ctx->cipher.aes.reg, WC_AES_BLOCK_SIZE);
20539}
20540
20541#endif /* NO_AES */
20542
20543#endif /* OPENSSL_EXTRA */
20544
20545/*******************************************************************************
20546 * END OF EVP_CIPHER API
20547 ******************************************************************************/
20548
20549#ifndef NO_CERTS
20550
20551#define WOLFSSL_X509_STORE_INCLUDED
20552#include <src/x509_str.c>
20553
20554#define WOLFSSL_SSL_P7P12_INCLUDED
20555#include <src/ssl_p7p12.c>
20556
20557#endif /* !NO_CERTS */
20558
20559
20560/*******************************************************************************
20561 * BEGIN OPENSSL FIPS DRBG APIs
20562 ******************************************************************************/
20563#if defined(OPENSSL_EXTRA) && !defined(WC_NO_RNG) && defined(HAVE_HASHDRBG)
20564int wolfSSL_FIPS_drbg_init(WOLFSSL_DRBG_CTX *ctx, int type, unsigned int flags)
20565{
20566 int ret = WC_NO_ERR_TRACE(WOLFSSL_FAILURE);
20567 if (ctx != NULL) {
20568 XMEMSET(ctx, 0, sizeof(WOLFSSL_DRBG_CTX));
20569 ctx->type = type;
20570 ctx->xflags = (int)flags;
20571 ctx->status = DRBG_STATUS_UNINITIALISED;
20572 ret = WOLFSSL_SUCCESS;
20573 }
20574 return ret;
20575}
20576WOLFSSL_DRBG_CTX* wolfSSL_FIPS_drbg_new(int type, unsigned int flags)
20577{
20578 int ret = WC_NO_ERR_TRACE(WOLFSSL_FAILURE);
20579 WOLFSSL_DRBG_CTX* ctx = (WOLFSSL_DRBG_CTX*)XMALLOC(sizeof(WOLFSSL_DRBG_CTX),
20580 NULL, DYNAMIC_TYPE_OPENSSL);
20581 ret = wolfSSL_FIPS_drbg_init(ctx, type, flags);
20582 if (ret == WOLFSSL_SUCCESS && type != 0) {
20583 ret = wolfSSL_FIPS_drbg_instantiate(ctx, NULL, 0);
20584 }
20585 if (ret != WOLFSSL_SUCCESS) {
20586 WOLFSSL_ERROR(ret);
20587 wolfSSL_FIPS_drbg_free(ctx);
20588 ctx = NULL;
20589 }
20590 return ctx;
20591}
20592int wolfSSL_FIPS_drbg_instantiate(WOLFSSL_DRBG_CTX* ctx,
20593 const unsigned char* pers, size_t perslen)
20594{
20595 int ret = WC_NO_ERR_TRACE(WOLFSSL_FAILURE);
20596 if (ctx != NULL && ctx->rng == NULL) {
20597 #if !defined(HAVE_SELFTEST) && (!defined(HAVE_FIPS) || \
20598 (defined(HAVE_FIPS) && FIPS_VERSION_GE(5,0)))
20599 ctx->rng = wc_rng_new((byte*)pers, (word32)perslen, NULL);
20600 #else
20601 ctx->rng = (WC_RNG*)XMALLOC(sizeof(WC_RNG), NULL, DYNAMIC_TYPE_RNG);
20602 if (ctx->rng != NULL) {
20603 #if defined(HAVE_FIPS) && FIPS_VERSION_GE(2,0)
20604 ret = wc_InitRngNonce(ctx->rng, (byte*)pers, (word32)perslen);
20605 #else
20606 ret = wc_InitRng(ctx->rng);
20607 (void)pers;
20608 (void)perslen;
20609 #endif
20610 if (ret != 0) {
20611 WOLFSSL_ERROR(ret);
20612 XFREE(ctx->rng, NULL, DYNAMIC_TYPE_RNG);
20613 ctx->rng = NULL;
20614 }
20615 }
20616 #endif
20617 }
20618 if (ctx != NULL && ctx->rng != NULL) {
20619 ctx->status = DRBG_STATUS_READY;
20620 ret = WOLFSSL_SUCCESS;
20621 }
20622 return ret;
20623}
20624int wolfSSL_FIPS_drbg_set_callbacks(WOLFSSL_DRBG_CTX* ctx,
20625 drbg_entropy_get entropy_get, drbg_entropy_clean entropy_clean,
20626 size_t entropy_blocklen,
20627 drbg_nonce_get none_get, drbg_nonce_clean nonce_clean)
20628{
20629 int ret = WC_NO_ERR_TRACE(WOLFSSL_FAILURE);
20630 if (ctx != NULL) {
20631 ctx->entropy_get = entropy_get;
20632 ctx->entropy_clean = entropy_clean;
20633 ctx->entropy_blocklen = entropy_blocklen;
20634 ctx->none_get = none_get;
20635 ctx->nonce_clean = nonce_clean;
20636 ret = WOLFSSL_SUCCESS;
20637 }
20638 return ret;
20639}
20640void wolfSSL_FIPS_rand_add(const void* buf, int num, double entropy)
20641{
20642 /* not implemented */
20643 (void)buf;
20644 (void)num;
20645 (void)entropy;
20646}
20647int wolfSSL_FIPS_drbg_reseed(WOLFSSL_DRBG_CTX* ctx, const unsigned char* adin,
20648 size_t adinlen)
20649{
20650 int ret = WC_NO_ERR_TRACE(WOLFSSL_FAILURE);
20651 if (ctx != NULL && ctx->rng != NULL) {
20652 #if !defined(HAVE_SELFTEST) && (!defined(HAVE_FIPS) || \
20653 (defined(HAVE_FIPS) && FIPS_VERSION_GE(2,0)))
20654 if (wc_RNG_DRBG_Reseed(ctx->rng, adin, (word32)adinlen) == 0) {
20655 ret = WOLFSSL_SUCCESS;
20656 }
20657 #else
20658 ret = WOLFSSL_SUCCESS;
20659 (void)adin;
20660 (void)adinlen;
20661 #endif
20662 }
20663 return ret;
20664}
20665int wolfSSL_FIPS_drbg_generate(WOLFSSL_DRBG_CTX* ctx, unsigned char* out,
20666 size_t outlen, int prediction_resistance, const unsigned char* adin,
20667 size_t adinlen)
20668{
20669 int ret = WC_NO_ERR_TRACE(WOLFSSL_FAILURE);
20670 if (ctx != NULL && ctx->rng != NULL) {
20671 ret = wc_RNG_GenerateBlock(ctx->rng, out, (word32)outlen);
20672 if (ret == 0) {
20673 ret = WOLFSSL_SUCCESS;
20674 }
20675 }
20676 (void)prediction_resistance;
20677 (void)adin;
20678 (void)adinlen;
20679 return ret;
20680}
20681int wolfSSL_FIPS_drbg_uninstantiate(WOLFSSL_DRBG_CTX *ctx)
20682{
20683 if (ctx != NULL && ctx->rng != NULL) {
20684 #if !defined(HAVE_SELFTEST) && (!defined(HAVE_FIPS) || \
20685 (defined(HAVE_FIPS) && FIPS_VERSION_GE(5,0)))
20686 wc_rng_free(ctx->rng);
20687 #else
20688 wc_FreeRng(ctx->rng);
20689 XFREE(ctx->rng, NULL, DYNAMIC_TYPE_RNG);
20690 #endif
20691 ctx->rng = NULL;
20692 ctx->status = DRBG_STATUS_UNINITIALISED;
20693 }
20694 return WOLFSSL_SUCCESS;
20695}
20696void wolfSSL_FIPS_drbg_free(WOLFSSL_DRBG_CTX *ctx)
20697{
20698 if (ctx != NULL) {
20699 /* As safety check if free'ing the default drbg, then mark global NULL.
20700 * Technically the user should not call free on the default drbg. */
20701 if (ctx == gDrbgDefCtx) {
20702 gDrbgDefCtx = NULL;
20703 }
20704 wolfSSL_FIPS_drbg_uninstantiate(ctx);
20705 XFREE(ctx, NULL, DYNAMIC_TYPE_OPENSSL);
20706 }
20707}
20708WOLFSSL_DRBG_CTX* wolfSSL_FIPS_get_default_drbg(void)
20709{
20710 if (gDrbgDefCtx == NULL) {
20711 gDrbgDefCtx = wolfSSL_FIPS_drbg_new(0, 0);
20712 }
20713 return gDrbgDefCtx;
20714}
20715void wolfSSL_FIPS_get_timevec(unsigned char* buf, unsigned long* pctr)
20716{
20717 /* not implemented */
20718 (void)buf;
20719 (void)pctr;
20720}
20721void* wolfSSL_FIPS_drbg_get_app_data(WOLFSSL_DRBG_CTX *ctx)
20722{
20723 if (ctx != NULL) {
20724 return ctx->app_data;
20725 }
20726 return NULL;
20727}
20728void wolfSSL_FIPS_drbg_set_app_data(WOLFSSL_DRBG_CTX *ctx, void *app_data)
20729{
20730 if (ctx != NULL) {
20731 ctx->app_data = app_data;
20732 }
20733}
20734#endif
20735/*******************************************************************************
20736 * END OF OPENSSL FIPS DRBG APIs
20737 ******************************************************************************/
20738
20739
20740#endif /* !WOLFCRYPT_ONLY */